doublecmd-0.8.2/0000775000175000017500000000000013244011206012476 5ustar alexxalexxdoublecmd-0.8.2/tools/0000775000175000017500000000000013244011206013636 5ustar alexxalexxdoublecmd-0.8.2/tools/extractdwrflnfo.lpr0000775000175000017500000000440112045752321017603 0ustar alexxalexx{ This file is part of the chelinfo library. Copyright (c) 2008 by Anton Rzheshevski Dwarf LineInfo Extractor See the file COPYING.FPC, included in this distribution, for details about the copyright. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **********************************************************************} { 2008, Anton Rzheshevski aka Cheb: Like dr. Frankenshtein I sewn this library together from the dead meat of the the FPC RTL modules lineinfo.pp and lnfodwrf.pp. These (as of Jan. 2008 / FPC 2.2.0) both didn't work and had several limitations (e.g. inability to be used from a DLL) } {note: DON'T FORGET to compile your program with the -gw key Lazarus: you must type it in Project -> Compiler Options -> Other -> User parameters } {$mode delphi} {$longstrings on} {$ifndef unix} {$apptype console} {$endif} //extracts the line info in the dwarf format from the executable program extractdwrflnfo; uses SysUtils, Classes, un_xtrctdwrflnfo, zstream; var _dwarf: pointer; DwarfSize, CompressedDwarfSize: QWord; base_addr: QWord; f: TFileStream; CS: TCompressionStream; dllname, iname: ansistring; begin if Paramcount = 0 then begin WriteLn('Usage: ' + ExtractFileName(GetModuleName(0)) + ' '); exit; end; dllname:= ParamStr(1); WriteLn('Extracting Dwarf line info from ', dllname); try iname:= DlnNameByExename(dllname); if ExtractDwarfLineInfo(dllname, _dwarf, DwarfSize, base_addr) then begin f:= TFileStream.Create(iname , fmCreate); CS:= TCompressionStream.Create(clMax, f); CS.Write(dwarfsize, sizeof(dwarfsize)); // 8 bytes (QWORD) CS.Write(base_addr, sizeof(base_addr)); // 8 bytes (QWORD) CS.Write(_dwarf^, dwarfsize); CS.Free; CompressedDwarfSize := f.Size; f.free; WriteLn('Ok, saved ', CompressedDwarfSize, ' bytes to ', iname); end else begin if FileExists(iname) then DeleteFile(iname); WriteLn('Error: ' + ExtractDwarfLineInfoError); end; except WriteLn((ExceptObject as Exception).Message); end; end. doublecmd-0.8.2/tools/extractdwrflnfo.lpi0000664000175000017500000000357212561625464017611 0ustar alexxalexx doublecmd-0.8.2/tools/fsgenerator/0000775000175000017500000000000013244011206016155 5ustar alexxalexxdoublecmd-0.8.2/tools/fsgenerator/fsgenerator.lpr0000664000175000017500000000637612046303231021230 0ustar alexxalexx{ Filesystem traffic generator ------------------------------------------------------------------------- Creates, modifies, removes files, quickly and in large quantities. Useful for testing how a program behaves when there's a lot of traffic happening on the file system. Copyright (C) 2010-2012 Przemysław Nagay (cobines@gmail.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } program fsgenerator; {$mode objfpc}{$H+} uses SysUtils, Classes, Windows; var Path: UTF8String; fs: TFileStream; filenames: TStringList; nr: Integer; buffer: array[0..16383] of byte; procedure GenNames; var i, j: Integer; name: String; begin for i := 0 to Random(1000) do begin name := ''; for j := 0 to random(100) do name := name + chr(random(ord('z') - ord('a')) + ord('a')); filenames.Add(name); end; end; function RandomName: String; begin Result := Path + filenames[Random(Filenames.Count)]; end; procedure Create(name: String); begin fs := TFileStream.Create(name, fmCreate); fs.Write(buffer, random(sizeof(buffer))); fs.Free; end; procedure Modify(name: String); var P: Int64; count: Int64; Mode: Word; size: int64; begin if not FileExists(name) then mode := fmCreate else mode := fmOpenReadWrite; fs := TFileStream.Create(Name, mode); if mode = fmCreate then begin fs.Write(buffer, random(sizeof(buffer))); fs.Seek(0, soBeginning); end; size := fs.size; p := random(size); fs.Seek(p, soBeginning); count := min(sizeof(buffer),random(size-p)); fs.Write(buffer, count); //writeln('writing ',count, ' p=',p,' size=',size); fs.Free; end; procedure Delete(name: String); begin if FileExists(Name) then Sysutils.DeleteFile(Name); end; begin if Paramcount = 0 then begin WriteLn('File system traffic generator.'); WriteLn('Creates, modifies, removes files, quickly and in large quantities.'); Writeln; WriteLn('Usage:'); WriteLn(ExtractFileName(ParamStr(0)) + ' '); Exit; end; FileNames := TStringList.Create; GenNames; Path := IncludeTrailingPathDelimiter(ParamStr(1)); ForceDirectories(Path); WriteLn('Starting changing ', Path); while True do begin case Random(6) of 0: Sleep(10); 1: Modify(RandomName); 2: Create(RandomName); 3: Modify(RandomName); 4: Delete(RandomName); 5: Modify(RandomName); end; Sleep(10); if (GetKeyState(VK_SPACE) < 0) or (GetKeyState(VK_SHIFT) < 0) or (GetKeyState(VK_ESCAPE) < 0) then Break; end; WriteLn('Finished changing'); Filenames.Free; end. doublecmd-0.8.2/tools/fsgenerator/fsgenerator.lpi0000664000175000017500000000363012046303231021205 0ustar alexxalexx doublecmd-0.8.2/install/0000775000175000017500000000000013244011205014143 5ustar alexxalexxdoublecmd-0.8.2/install/create_packages.bat0000664000175000017500000000413513243754446017763 0ustar alexxalexx rem Set Double Commander version set DC_VER=0.8.2 rem Path to subversion set SVN_EXE="c:\Program Files\SlikSvn\bin\svn.exe" rem Path to Inno Setup compiler set ISCC_EXE="c:\Program Files\Inno Setup 5\ISCC.exe" rem The new package will be created from here set BUILD_PACK_DIR=%TEMP%\doublecmd-%DATE: =% rem The new package will be saved here set PACK_DIR=%CD%\windows\release rem Create temp dir for building set BUILD_DC_TMP_DIR=%TEMP%\doublecmd-%DC_VER% rm -rf %BUILD_DC_TMP_DIR% %SVN_EXE% export ..\ %BUILD_DC_TMP_DIR% rem Save revision number mkdir %BUILD_DC_TMP_DIR%\.svn copy ..\.svn\entries %BUILD_DC_TMP_DIR%\.svn\ rem Prepare package build dir rm -rf %BUILD_PACK_DIR% mkdir %BUILD_PACK_DIR% mkdir %BUILD_PACK_DIR%\release rem Copy needed files copy windows\doublecmd.iss %BUILD_PACK_DIR%\ copy windows\portable.diff %BUILD_PACK_DIR%\ rem Get processor architecture if "%CPU_TARGET%" == "" ( if "%PROCESSOR_ARCHITECTURE%" == "x86" ( set CPU_TARGET=i386 set OS_TARGET=win32 ) else if "%PROCESSOR_ARCHITECTURE%" == "AMD64" ( set CPU_TARGET=x86_64 set OS_TARGET=win64 ) ) rem Copy libraries copy windows\lib\%CPU_TARGET%\*.dll %BUILD_DC_TMP_DIR%\ cd /D %BUILD_DC_TMP_DIR% rem Build all components of Double Commander call build.bat beta rem Prepare install files call %BUILD_DC_TMP_DIR%\install\windows\install.bat cd /D %BUILD_PACK_DIR% rem Create *.exe package %ISCC_EXE% /F"doublecmd-%DC_VER%.%CPU_TARGET%-%OS_TARGET%" doublecmd.iss rem Move created package move release\*.exe %PACK_DIR% rem Create *.zip package patch doublecmd/doublecmd.xml portable.diff zip -9 -Dr %PACK_DIR%\doublecmd-%DC_VER%.%CPU_TARGET%-%OS_TARGET%.zip doublecmd rem Create help packages cd /D %BUILD_DC_TMP_DIR% rem Copy help files call %BUILD_DC_TMP_DIR%\install\windows\install-help.bat rem Create help package for each language cd %BUILD_PACK_DIR%\doublecmd for /D %%f in (doc\*) do zip -9 -Dr %PACK_DIR%\doublecmd-help-%%~nf-%DC_VER%.noarch.zip %%f rem Clean temp directories cd \ rm -rf %BUILD_DC_TMP_DIR% rm -rf %BUILD_PACK_DIR% doublecmd-0.8.2/install/linux/0000775000175000017500000000000013244011205015302 5ustar alexxalexxdoublecmd-0.8.2/install/linux/doublecmd.desktop0000775000175000017500000000102112673234105020643 0ustar alexxalexx[Desktop Entry] Name=Double Commander Comment=Double Commander is a cross platform open source file manager with two panels side by side. Terminal=false Icon=doublecmd Exec=doublecmd %F Type=Application MimeType=inode/directory; Categories=Utility;FileTools;FileManager; Keywords=folder;manager;explore;disk;filesystem;orthodox;copy;queue;queuing;operations; Comment[ru]=Double Commander — это кроссплатформенный двухпанельный файловый менеджер с открытым кодом. doublecmd-0.8.2/install/linux/install-help.sh0000664000175000017500000000157312407307365020257 0ustar alexxalexx#!/bin/sh set -e # Parse input parameters CKNAME=$(basename "$0") args=$(getopt -n $CKNAME -o P:,I: -l portable-prefix:,install-prefix:,default -- "$@") eval set -- $args for A do case "$A" in --) DC_HELP_INSTALL_DIR=/usr/share/doublecmd/doc ;; -P|--portable-prefix) shift DC_HELP_INSTALL_DIR=$(eval echo $1/doublecmd/doc) break ;; -I|--install-prefix) shift DC_INSTALL_PREFIX=$(eval echo $1) DC_HELP_INSTALL_DIR=$DC_INSTALL_PREFIX/usr/share/doublecmd/doc break ;; esac shift done # Clean help directory rm -rf $DC_HELP_INSTALL_DIR/* # Copy English help files cp -r doc/en $DC_HELP_INSTALL_DIR/ # Copy Russian help files cp -r doc/ru $DC_HELP_INSTALL_DIR/ # Copy Ukrainian help files cp -r doc/uk $DC_HELP_INSTALL_DIR/doublecmd-0.8.2/install/linux/update-revision.sh0000775000175000017500000000045212650252770020776 0ustar alexxalexx#!/bin/sh # DC revision number export DC_REVISION=$(svnversion $1 | sed -e 's/\([0-9]*\).*/\1/') # Update dcrevision.inc echo "// Created by Svn2RevisionInc" > $2/units/dcrevision.inc echo "const dcRevision = '$DC_REVISION';" >> $2/units/dcrevision.inc # Return revision echo $DC_REVISION doublecmd-0.8.2/install/linux/update-repo-obs.sh0000775000175000017500000000777313243754446020711 0ustar alexxalexx#!/bin/bash # This script updates Double Commander Open Build Service (OBS) repository # Set Double Commander version DC_VER=0.8.2 # Temp directory DC_TEMP_DIR=/var/tmp/doublecmd-$(date +%y.%m.%d) # Directory for DC source code DC_SOURCE_DIR=$DC_TEMP_DIR/doublecmd-$DC_VER # Directory for DC help DC_HELP_DIR=$DC_TEMP_DIR/doublecmd-help-$DC_VER # Directory for the openSUSE Build Service (OBS) DC_OBS_DIR=$HOME/.obs # OBS project home directory DC_OBS_WEB_DIR=home:Alexx2000 # OBS project directory DC_OBS_PRJ_DIR=$DC_OBS_DIR/$DC_OBS_WEB_DIR # Recreate temp directory rm -rf $DC_TEMP_DIR mkdir -p $DC_TEMP_DIR update_doublecmd() { # Export from SVN svn export ../../ $DC_SOURCE_DIR # Save revision number DC_REVISION=`$(pwd)/update-revision.sh ../../ $DC_SOURCE_DIR` # Prepare doublecmd-*.spec file cp -a rpm/doublecmd-*.spec $DC_TEMP_DIR # Create archive with source code pushd $DC_TEMP_DIR tar -cvzf doublecmd-$DC_VER.tar.gz doublecmd-$DC_VER if [ ! -d "$DC_OBS_DIR" ] then mkdir -p $DC_OBS_DIR cd $DC_OBS_DIR osc checkout $DC_OBS_WEB_DIR else pushd $DC_OBS_PRJ_DIR/doublecmd-gtk osc up popd pushd $DC_OBS_PRJ_DIR/doublecmd-qt osc up popd fi # Upload GTK2 archive to OBS rm -f $DC_OBS_PRJ_DIR/doublecmd-gtk/doublecmd-gtk.spec rm -f $DC_OBS_PRJ_DIR/doublecmd-gtk/doublecmd-$DC_VER.tar.gz mv doublecmd-gtk.spec $DC_OBS_PRJ_DIR/doublecmd-gtk/ cp -a doublecmd-$DC_VER.tar.gz $DC_OBS_PRJ_DIR/doublecmd-gtk/ pushd $DC_OBS_PRJ_DIR/doublecmd-gtk osc commit doublecmd-gtk.spec doublecmd-$DC_VER.tar.gz -m "Update to revision $DC_REVISION" popd # Upload Qt4 archive to OBS rm -f $DC_OBS_PRJ_DIR/doublecmd-qt/doublecmd-qt.spec rm -f $DC_OBS_PRJ_DIR/doublecmd-qt/doublecmd-$DC_VER.tar.gz mv doublecmd-qt.spec $DC_OBS_PRJ_DIR/doublecmd-qt/ cp -a doublecmd-$DC_VER.tar.gz $DC_OBS_PRJ_DIR/doublecmd-qt/ pushd $DC_OBS_PRJ_DIR/doublecmd-qt osc commit doublecmd-qt.spec doublecmd-$DC_VER.tar.gz -m "Update to revision $DC_REVISION" popd popd } update_doublecmd_svn() { trap "stty echo; echo; exit" INT TERM EXIT read -s -p "Enter password: " PASSWORD; echo echo "Update Double Commander (Qt)" curl -u Alexx2000:$PASSWORD -X POST https://api.opensuse.org/source/home:Alexx2000:doublecmd-svn/doublecmd-qt?cmd=runservice echo "Update Double Commander (Qt5)" curl -u Alexx2000:$PASSWORD -X POST https://api.opensuse.org/source/home:Alexx2000:doublecmd-svn/doublecmd-qt5?cmd=runservice echo "Update Double Commander (Gtk)" curl -u Alexx2000:$PASSWORD -X POST https://api.opensuse.org/source/home:Alexx2000:doublecmd-svn/doublecmd-gtk?cmd=runservice echo "Update Double Commander (Debian)" curl -u Alexx2000:$PASSWORD -X POST https://api.opensuse.org/source/home:Alexx2000:doublecmd-svn/doublecmd-deb?cmd=runservice exit 0 } update_doublecmd_help() { # Export from SVN svn export ../../doc $DC_HELP_DIR # Remove text files rm -f $DC_HELP_DIR/*.txt # Prepare doublecmd-help.spec file cp -a rpm/doublecmd-help.spec $DC_TEMP_DIR # Create archive with source code pushd $DC_TEMP_DIR tar -cvzf doublecmd-help-$DC_VER.tar.gz doublecmd-help-$DC_VER if [ ! -d "$DC_OBS_DIR" ] then mkdir -p $DC_OBS_DIR cd $DC_OBS_DIR osc checkout $DC_OBS_WEB_DIR else pushd $DC_OBS_PRJ_DIR/doublecmd-help osc up popd fi # Upload archive to OBS rm -f $DC_OBS_PRJ_DIR/doublecmd-help/doublecmd-help.spec rm -f $DC_OBS_PRJ_DIR/doublecmd-help/doublecmd-help-$DC_VER.tar.gz mv doublecmd-help.spec $DC_OBS_PRJ_DIR/doublecmd-help/ mv doublecmd-help-$DC_VER.tar.gz $DC_OBS_PRJ_DIR/doublecmd-help/ cd $DC_OBS_PRJ_DIR/doublecmd-help osc commit doublecmd-help.spec doublecmd-help-$DC_VER.tar.gz -m "Update to revision $DC_REVISION" popd } update_all() { update_doublecmd update_doublecmd_help } case $1 in doublecmd-help) update_doublecmd_help;; doublecmd-svn) update_doublecmd_svn;; doublecmd) update_doublecmd;; *) update_all;; esac # Clean rm -rf $DC_TEMP_DIR doublecmd-0.8.2/install/linux/doublecmd.10000664000175000017500000000105211646573261017343 0ustar alexxalexx.TH "doublecmd" "1" "16 October 2011" "Double Commander" .SH "NAME" doublecmd \- Twin-panel (commander-style) file manager. .SH "SYNOPSIS" .B doublecmd .I "[options]" .SH "DESCRIPTION" Double Commander is a cross platform open source file manager with two panels side by side. It is inspired by Total Commander and features some new ideas. .SH "OPTIONS" .TP .BI " \-\-config\-dir=" config directory, where Double Commander stores its config files. Default is $HOME/.config/doublecmd. .SH "Websites" .IP .BR http://doublecmd.sourceforge.net doublecmd-0.8.2/install/linux/release/0000775000175000017500000000000013244011205016722 5ustar alexxalexxdoublecmd-0.8.2/install/linux/pkg/0000775000175000017500000000000013244011205016063 5ustar alexxalexxdoublecmd-0.8.2/install/linux/pkg/environmentoptions.xml0000664000175000017500000000036112707472132022602 0ustar alexxalexx doublecmd-0.8.2/install/linux/pkg/doublecmd-svn.install0000664000175000017500000000105512707462472022241 0ustar alexxalexx# doublecmd-svn.install update_icons() { # Setup Menus if which update-desktop-database then update-desktop-database -q /usr/share/applications > /dev/null 2>&1 fi # Setup MIME types if which update-mime-database then update-mime-database /usr/share/mime > /dev/null 2>&1 fi # Setup Icons touch -c /usr/share/icons/hicolor if which gtk-update-icon-cache then gtk-update-icon-cache -tq /usr/share/icons/hicolor > /dev/null 2>&1 fi } post_install() { update_icons } post_upgrade() { update_icons } post_remove() { update_icons } doublecmd-0.8.2/install/linux/pkg/doublecmd-qt.pkgbuild0000664000175000017500000000230212707462472022206 0ustar alexxalexx# Based on AUR doublecmd-qt-svn package # https://aur.archlinux.org/packages/doublecmd-qt-svn # # Maintainer: ValHue # https://github.com/ValHue/AUR-PKGBUILDs # # Contributor: Stanislav GE _pkgname="doublecmd" pkgname=("${_pkgname}-qt-svn") pkgver=r6754 pkgrel=1 pkgdesc="Twin-panel (commander-style) file manager (Qt)" url="http://doublecmd.sourceforge.net/" arch=('i686' 'x86_64') license=('GPL2') depends=('qt4pas') install="${_pkgname}-svn.install" makedepends=('lazarus' 'fpc' 'subversion') optdepends=( 'lua51: scripting' 'p7zip: support for 7zip archives' 'libunrar: support for rar archives' ) options=('!strip') provides=(${_pkgname}-qt) conflicts=('doublecmd-qt' 'doublecmd-gtk2' 'doublecmd-gtk2-svn' 'doublecmd-gtk2-alpha-bin') pkgver() { cd "${srcdir}" local ver="$(cat revision.txt)" printf "r%s" "${ver//[[:alpha:]]}" } prepare() { cd "${srcdir}" sed -e 's/LIB_SUFFIX=.*/LIB_SUFFIX=/g' -i install/linux/install.sh } build() { msg 'Build Qt' cd "${srcdir}" ./build.sh beta qt } package() { cd "${srcdir}" install/linux/install.sh --install-prefix="${pkgdir}" } # vim:set ts=4 sw=2 ft=sh et:doublecmd-0.8.2/install/linux/pkg/doublecmd-gtk2.pkgbuild0000664000175000017500000000231212707462472022432 0ustar alexxalexx# Based on AUR doublecmd-gtk2-svn package # https://aur.archlinux.org/packages/doublecmd-gtk2-svn # # Maintainer: ValHue # https://github.com/ValHue/AUR-PKGBUILDs # # Contributor: Stanislav GE _pkgname="doublecmd" pkgname=("${_pkgname}-gtk2-svn") pkgver=r6754 pkgrel=1 pkgdesc="Twin-panel (commander-style) file manager (GTK)" url="http://doublecmd.sourceforge.net/" arch=('i686' 'x86_64') license=('GPL2') depends=('gtk2') install="${_pkgname}-svn.install" makedepends=('lazarus' 'fpc' 'subversion') optdepends=( 'lua51: scripting' 'p7zip: support for 7zip archives' 'libunrar: support for rar archives' ) options=('!strip') provides=(${_pkgname}-gtk2) conflicts=('doublecmd-gtk2' 'doublecmd-gtk2-alpha-bin' 'doublecmd-qt' 'doublecmd-qt-svn') pkgver() { cd "${srcdir}" local ver="$(cat revision.txt)" printf "r%s" "${ver//[[:alpha:]]}" } prepare() { cd "${srcdir}" sed -e 's/LIB_SUFFIX=.*/LIB_SUFFIX=/g' -i install/linux/install.sh } build() { msg 'Build GTK' cd "${srcdir}" ./build.sh beta gtk2 } package() { cd "${srcdir}" install/linux/install.sh --install-prefix="${pkgdir}" } # vim:set ts=4 sw=2 ft=sh et:doublecmd-0.8.2/install/linux/description-pak0000775000175000017500000000023410774773057020354 0ustar alexxalexxDouble Commander is a cross platform open source file manager with two panels side by side. It is inspired by Total Commander and features some new ideas. doublecmd-0.8.2/install/linux/convert-rpm-txz.sh0000775000175000017500000000375713215022223020754 0ustar alexxalexx#!/bin/bash # This script converts *.rpm package to portable package # Script directory SCRIPT_DIR=$(pwd) # Source directory DC_SOURCE_DIR=$SCRIPT_DIR/../.. # The new package will be saved here PACK_DIR=$SCRIPT_DIR/release # Temp directory DC_TEMP_DIR=/var/tmp/doublecmd-$(date +%y.%m.%d) # Root directory DC_ROOT_DIR=$DC_TEMP_DIR/doublecmd # Base file name BASE_NAME=$(basename $1 .rpm) # Set widgetset LCL_PLATFORM=$(echo $BASE_NAME | grep -Po '(?<=doublecmd-)[^-]+') # Set version DC_VER=$(echo $BASE_NAME | grep -Po "(?<=doublecmd-$LCL_PLATFORM-)[^-]+") # Set processor architecture CPU_TARGET=${BASE_NAME##*.} if [ "$CPU_TARGET" = "i686" ]; then export CPU_TARGET=i386 fi # Update widgetset if [ "$LCL_PLATFORM" = "gtk" ]; then export LCL_PLATFORM=gtk2 fi # Recreate temp directory rm -rf $DC_TEMP_DIR mkdir -p $DC_TEMP_DIR pushd $DC_TEMP_DIR $SCRIPT_DIR/rpm2cpio.sh $1 | cpio -idmv if [ "$CPU_TARGET" = "x86_64" ] then mv usr/lib64/doublecmd ./ else mv usr/lib/doublecmd ./ fi # Remove symlinks rm -f doublecmd/doc rm -f doublecmd/language rm -f doublecmd/pixmaps rm -f doublecmd/highlighters # Move directories and files mv usr/share/doublecmd/doc $DC_ROOT_DIR/ mv usr/share/doublecmd/language $DC_ROOT_DIR/ mv usr/share/doublecmd/pixmaps $DC_ROOT_DIR/ mv usr/share/doublecmd/highlighters $DC_ROOT_DIR/ mv usr/share/pixmaps/doublecmd.png $DC_ROOT_DIR/ # Copy libraries pushd $DC_SOURCE_DIR/install/linux cp -a lib/$CPU_TARGET/*.so* $DC_ROOT_DIR/ cp -a lib/$CPU_TARGET/$LCL_PLATFORM/*.so* $DC_ROOT_DIR/ popd # Copy script for execute portable version install -m 755 $DC_SOURCE_DIR/doublecmd.sh $DC_ROOT_DIR/ # Make portable config file sed -i -e 's/False/True/' $DC_ROOT_DIR/doublecmd.xml # Create archive tar -cJvf $PACK_DIR/doublecmd-$DC_VER.$LCL_PLATFORM.$CPU_TARGET.tar.xz doublecmd popd # Clean rm -rf $DC_TEMP_DIR doublecmd-0.8.2/install/linux/doublecmd.xml0000664000175000017500000000237112562442777020015 0ustar alexxalexx False Pascal sources *.pas;*.pp 32768 Pascal binaries *.ppu;*.o;*.dcu 16711680 Specified Executables * 55758 -rwxrwxr*x Executables * 32768 -*x* wlxMplayer %commander_path%/plugins/wlx/wlxmplayer/wlxmplayer.wlx (EXT="MPG")|(EXT="AVI")|(EXT="MPEG")|(EXT="FLV") doublecmd-0.8.2/install/linux/update-repo-ppa.sh0000775000175000017500000000675413243754446020704 0ustar alexxalexx#!/bin/bash # This script updates Double Commander Personal Package Archive (PPA) repository # Set Double Commander version DC_VER=0.8.2 # Set Ubuntu series DISTRO=( xenial zesty artful ) # Temp directory DC_TEMP_DIR=/var/tmp/doublecmd-$(date +%y.%m.%d) # Directory for DC source code DC_SOURCE_DIR=$DC_TEMP_DIR/doublecmd-$DC_VER # Directory for DC help DC_HELP_DIR=$DC_TEMP_DIR/doublecmd-help-$DC_VER # Recreate temp directory rm -rf $DC_TEMP_DIR mkdir -p $DC_TEMP_DIR update_doublecmd() { # Export from SVN svn export ../../ $DC_SOURCE_DIR # Save revision number DC_REVISION=`$(pwd)/update-revision.sh ../../ $DC_SOURCE_DIR` # Create doublecmd-x.x.x.orig.tar.gz pushd $DC_SOURCE_DIR/.. tar -cvzf $DC_TEMP_DIR/doublecmd_$DC_VER.orig.tar.gz doublecmd-$DC_VER popd # Prepare debian directory mkdir -p $DC_SOURCE_DIR/debian cp -r $DC_SOURCE_DIR/install/linux/deb/doublecmd/* $DC_SOURCE_DIR/debian # Create source package for each distro for DIST in "${DISTRO[@]}" do # Update changelog file pushd $DC_SOURCE_DIR/debian dch -b -D $DIST -v $DC_VER-0+svn$DC_REVISION~$DIST "Non-maintainer upload (revision $DC_REVISION)" popd # Create archive with source code pushd $DC_SOURCE_DIR if [ $DIST = ${DISTRO[0]} ] then debuild -S -sa else debuild -S -sd fi popd done } update_doublecmd_svn() { # Export from SVN svn export ../../ $DC_SOURCE_DIR # Save revision number DC_REVISION=`$(pwd)/update-revision.sh ../../ $DC_SOURCE_DIR` # Prepare debian directory mkdir -p $DC_SOURCE_DIR/debian cp -r $DC_SOURCE_DIR/install/linux/deb/doublecmd/* $DC_SOURCE_DIR/debian echo '1.0' > $DC_SOURCE_DIR/debian/source/format # Create source package for each distro for DIST in "${DISTRO[@]}" do # Update changelog file pushd $DC_SOURCE_DIR/debian dch -D $DIST -v $DC_VER-0+svn$DC_REVISION~$DIST "Non-maintainer upload (revision $DC_REVISION)" popd # Create archive with source code pushd $DC_SOURCE_DIR debuild -S -sa popd done # Upload archives to PPA cd $DC_TEMP_DIR dput -U ppa:alexx2000/doublecmd-svn $(ls -xrt --file-type *.changes) # Clean rm -rf $DC_TEMP_DIR # Exit exit 0 } update_doublecmd_help() { # Create output folder mkdir -p $DC_HELP_DIR # Save revision number DC_REVISION=`$(pwd)/update-revision.sh ../../ $DC_SOURCE_DIR` # Copy help files cp -r ../../doc/en $DC_HELP_DIR/ cp -r ../../doc/ru $DC_HELP_DIR/ cp -r ../../doc/uk $DC_HELP_DIR/ # Create doublecmd-help-x.x.x.orig.tar.gz pushd $DC_HELP_DIR/.. tar -cvzf $DC_TEMP_DIR/doublecmd-help_$DC_VER.orig.tar.gz doublecmd-help-$DC_VER popd # Prepare debian directory svn export deb/doublecmd-help $DC_HELP_DIR/debian # Create source package for each distro for DIST in "${DISTRO[@]}" do # Update changelog file pushd $DC_HELP_DIR/debian dch -m -D $DIST -v $DC_VER-$DC_REVISION~$DIST "Update to revision $DC_REVISION" popd # Create archive with source code pushd $DC_HELP_DIR if [ $DIST = ${DISTRO[0]} ] then debuild -S -sa else debuild -S -sd fi popd done } update_all() { update_doublecmd update_doublecmd_help } case $1 in doublecmd-help) update_doublecmd_help;; doublecmd-svn) update_doublecmd_svn;; doublecmd) update_doublecmd;; *) update_all;; esac # Upload archives to PPA cd $DC_TEMP_DIR dput -U ppa:alexx2000/doublecmd $(ls -xrt --file-type *.changes) # Clean rm -rf $DC_TEMP_DIR doublecmd-0.8.2/install/linux/rpm2cpio.sh0000775000175000017500000000246212523377401017414 0ustar alexxalexx#!/bin/sh # Prevent gawk >= 4.0.x from getting funny ideas wrt UTF in printf() LANG=C pkg=$1 if [ "$pkg" = "" -o ! -e "$pkg" ]; then echo "no package supplied" 1>&2 exit 1 fi leadsize=96 o=`expr $leadsize + 8` set `od -j $o -N 8 -t u1 $pkg` il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5` dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9` # echo "sig il: $il dl: $dl" sigsize=`expr 8 + 16 \* $il + $dl` o=`expr $o + $sigsize + \( 8 - \( $sigsize \% 8 \) \) \% 8 + 8` set `od -j $o -N 8 -t u1 $pkg` il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5` dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9` # echo "hdr il: $il dl: $dl" hdrsize=`expr 8 + 16 \* $il + $dl` o=`expr $o + $hdrsize` comp=`dd if="$pkg" ibs=$o skip=1 count=1 2>/dev/null \ | dd bs=3 count=1 2>/dev/null` gz="`echo . | awk '{ printf("%c%c", 0x1f, 0x8b); }'`" lzma="`echo . | awk '{ printf("%cLZ", 0xff); }'`" xz="`echo . | awk '{ printf("%c7z", 0xfd); }'`" case "$comp" in BZh) dd if="$pkg" ibs=$o skip=1 2>/dev/null | bunzip2 ;; "$gz"*) dd if="$pkg" ibs=$o skip=1 2>/dev/null | gunzip ;; "$xz"*) dd if="$pkg" ibs=$o skip=1 2>/dev/null | xzcat ;; "$lzma"*) dd if="$pkg" ibs=$o skip=1 2>/dev/null | unlzma ;; *) echo "Unrecognized rpm file: $pkg"; exit 1 ;; esac doublecmd-0.8.2/install/linux/install.sh0000775000175000017500000001356413235433350017331 0ustar alexxalexx#!/bin/bash set -e # Set processor architecture if [ -z $CPU_TARGET ]; then export CPU_TARGET=$(fpc -iTP) fi # Determine library directory if [ "$CPU_TARGET" = "x86_64" ] && [ ! -f "/etc/debian_version" ] then LIB_SUFFIX=64 else LIB_SUFFIX= fi # Parse input parameters CKNAME=$(basename "$0") args=$(getopt -n $CKNAME -o P:,I: -l portable-prefix:,install-prefix:,default -- "$@") eval set -- $args for A do case "$A" in --) DC_INSTALL_DIR=/usr/lib$LIB_SUFFIX/doublecmd ;; -P|--portable-prefix) shift CK_PORTABLE=1 DC_INSTALL_DIR=$(eval echo $1/doublecmd) break ;; -I|--install-prefix) shift DC_INSTALL_PREFIX=$(eval echo $1) DC_INSTALL_DIR=$DC_INSTALL_PREFIX/usr/lib$LIB_SUFFIX/doublecmd break ;; esac shift done mkdir -p $DC_INSTALL_DIR mkdir -p $DC_INSTALL_DIR/plugins # WCX plugins directories mkdir -p $DC_INSTALL_DIR/plugins/wcx mkdir -p $DC_INSTALL_DIR/plugins/wcx/cpio mkdir -p $DC_INSTALL_DIR/plugins/wcx/deb mkdir -p $DC_INSTALL_DIR/plugins/wcx/rpm mkdir -p $DC_INSTALL_DIR/plugins/wcx/unrar mkdir -p $DC_INSTALL_DIR/plugins/wcx/zip # WDX plugins directories mkdir -p $DC_INSTALL_DIR/plugins/wdx mkdir -p $DC_INSTALL_DIR/plugins/wdx/scripts mkdir -p $DC_INSTALL_DIR/plugins/wdx/rpm_wdx mkdir -p $DC_INSTALL_DIR/plugins/wdx/deb_wdx mkdir -p $DC_INSTALL_DIR/plugins/wdx/audioinfo # WFX plugins directories mkdir -p $DC_INSTALL_DIR/plugins/wfx mkdir -p $DC_INSTALL_DIR/plugins/wfx/ftp mkdir -p $DC_INSTALL_DIR/plugins/wfx/samba # WLX plugins directories mkdir -p $DC_INSTALL_DIR/plugins/wlx mkdir -p $DC_INSTALL_DIR/plugins/wlx/wlxmplayer # DSX plugins directories mkdir -p $DC_INSTALL_DIR/plugins/dsx mkdir -p $DC_INSTALL_DIR/plugins/dsx/dsxlocate # Copy files cp -a doublecmd $DC_INSTALL_DIR/ cp -a doublecmd.zdli $DC_INSTALL_DIR/ cp -a install/linux/doublecmd.xml $DC_INSTALL_DIR/ cp -a doublecmd.ext.example $DC_INSTALL_DIR/ cp -a pixmaps.txt $DC_INSTALL_DIR/ cp -a multiarc.ini $DC_INSTALL_DIR/ # copy plugins # WCX install -m 644 plugins/wcx/cpio/lib/cpio.wcx $DC_INSTALL_DIR/plugins/wcx/cpio/ install -m 644 plugins/wcx/deb/lib/deb.wcx $DC_INSTALL_DIR/plugins/wcx/deb/ install -m 644 plugins/wcx/rpm/lib/rpm.wcx $DC_INSTALL_DIR/plugins/wcx/rpm/ install -m 644 plugins/wcx/unrar/lib/unrar.wcx $DC_INSTALL_DIR/plugins/wcx/unrar/ install -m 644 plugins/wcx/zip/zip.wcx $DC_INSTALL_DIR/plugins/wcx/zip/ # WDX install -m 644 plugins/wdx/rpm_wdx/lib/rpm_wdx.wdx $DC_INSTALL_DIR/plugins/wdx/rpm_wdx/ install -m 644 plugins/wdx/deb_wdx/lib/deb_wdx.wdx $DC_INSTALL_DIR/plugins/wdx/deb_wdx/ install -m 644 plugins/wdx/scripts/* $DC_INSTALL_DIR/plugins/wdx/scripts/ install -m 644 plugins/wdx/audioinfo/audioinfo.wdx $DC_INSTALL_DIR/plugins/wdx/audioinfo/ # WFX install -m 644 plugins/wfx/ftp/ftp.wfx $DC_INSTALL_DIR/plugins/wfx/ftp/ install -m 644 plugins/wfx/samba/lib/samba.wfx $DC_INSTALL_DIR/plugins/wfx/samba/ # WLX install -m 644 plugins/wlx/WlxMplayer/lib/wlxmplayer.wlx $DC_INSTALL_DIR/plugins/wlx/wlxmplayer/ # DSX install -m 644 plugins/dsx/DSXLocate/lib/dsxlocate.dsx $DC_INSTALL_DIR/plugins/dsx/dsxlocate/ if [ -z $CK_PORTABLE ] then # Copy libraries install -d $DC_INSTALL_PREFIX/usr/lib$LIB_SUFFIX if [ "$(echo *.so*)" != "*.so*" ]; then install -m 644 *.so* $DC_INSTALL_PREFIX/usr/lib$LIB_SUFFIX fi # Create directory for platform independed files install -d $DC_INSTALL_PREFIX/usr/share/doublecmd # Copy man files install -d -m 755 $DC_INSTALL_PREFIX/usr/share/man/man1 install -c -m 644 install/linux/*.1 $DC_INSTALL_PREFIX/usr/share/man/man1 # Copy documentation install -d $DC_INSTALL_PREFIX/usr/share/doublecmd/doc install -m 644 doc/*.txt $DC_INSTALL_PREFIX/usr/share/doublecmd/doc ln -sf ../../share/doublecmd/doc $DC_INSTALL_DIR/doc # Copy scripts install -d $DC_INSTALL_DIR/scripts cp -a scripts/*.py $DC_INSTALL_DIR/scripts/ # Copy languages cp -r language $DC_INSTALL_PREFIX/usr/share/doublecmd ln -sf ../../share/doublecmd/language $DC_INSTALL_DIR/language # Copy pixmaps cp -r pixmaps $DC_INSTALL_PREFIX/usr/share/doublecmd ln -sf ../../share/doublecmd/pixmaps $DC_INSTALL_DIR/pixmaps # Copy highlighters cp -r highlighters $DC_INSTALL_PREFIX/usr/share/doublecmd ln -sf ../../share/doublecmd/highlighters $DC_INSTALL_DIR/highlighters # Create symlink and desktop files install -d $DC_INSTALL_PREFIX/usr/bin install -d $DC_INSTALL_PREFIX/usr/share/pixmaps install -d $DC_INSTALL_PREFIX/usr/share/applications install -d $DC_INSTALL_PREFIX/usr/share/icons/hicolor/scalable/apps ln -sf ../lib$LIB_SUFFIX/doublecmd/doublecmd $DC_INSTALL_PREFIX/usr/bin/doublecmd install -m 644 doublecmd.png $DC_INSTALL_PREFIX/usr/share/pixmaps/doublecmd.png install -m 644 install/linux/doublecmd.desktop $DC_INSTALL_PREFIX/usr/share/applications/doublecmd.desktop ln -sf ../../../../doublecmd/pixmaps/mainicon/alt/dcfinal.svg \ $DC_INSTALL_PREFIX/usr/share/icons/hicolor/scalable/apps/doublecmd.svg else # Copy documentation mkdir -p $DC_INSTALL_DIR/doc cp -a doc/*.txt $DC_INSTALL_DIR/doc/ # Copy script for execute portable version cp -a doublecmd.sh $DC_INSTALL_DIR/ # Copy directories cp -r language $DC_INSTALL_DIR/ cp -r pixmaps $DC_INSTALL_DIR/ cp -r highlighters $DC_INSTALL_DIR/ # Copy scripts install -d $DC_INSTALL_DIR/scripts cp -a scripts/*.py $DC_INSTALL_DIR/scripts/ # Copy libraries install -m 644 *.so* $DC_INSTALL_DIR/ # Copy DC icon cp -a doublecmd.png $DC_INSTALL_DIR/doublecmd.png fi doublecmd-0.8.2/install/linux/deb/0000775000175000017500000000000013244011205016034 5ustar alexxalexxdoublecmd-0.8.2/install/linux/deb/doublecmd-help/0000775000175000017500000000000013244011205020720 5ustar alexxalexxdoublecmd-0.8.2/install/linux/deb/doublecmd-help/doublecmd-help-ru.doc-base0000664000175000017500000000047211516546640025652 0ustar alexxalexxDocument: doublecmd-help-ru Title: Documentation for the Double Commander (Russian) Author: Rustem Rakhimov Abstract: This manual describes how to use Double Commander. Section: File Management Format: HTML Index: /usr/share/doublecmd/doc/ru/index.html Files: /usr/share/doublecmd/doc/ru/*.html doublecmd-0.8.2/install/linux/deb/doublecmd-help/doublecmd-help-en.doc-base0000664000175000017500000000053511516546640025626 0ustar alexxalexxDocument: doublecmd-help-en Title: Documentation for the Double Commander (English) Author: Rustem Rakhimov , Rod J Abstract: This manual describes how to use Double Commander. Section: File Management Format: HTML Index: /usr/share/doublecmd/doc/en/index.html Files: /usr/share/doublecmd/doc/en/*.html doublecmd-0.8.2/install/linux/deb/doublecmd-help/rules0000775000175000017500000000334511610363331022012 0ustar alexxalexx#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. touch build-stamp clean: dh_testdir dh_testroot # Add here commands to clean up after the build process. rm -f build-stamp configure-stamp dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs -A usr/share/doublecmd/doc # Add here commands to install the package. cp -r en $(CURDIR)/debian/doublecmd-help-en/usr/share/doublecmd/doc cp -r ru $(CURDIR)/debian/doublecmd-help-ru/usr/share/doublecmd/doc cp -r uk $(CURDIR)/debian/doublecmd-help-uk/usr/share/doublecmd/doc for pkg in `dh_listpackages` ; do \ find $(CURDIR)/debian/$$pkg/usr/share/ -type f | xargs chmod a-x ; \ done # Build architecture-dependent files here. binary-arch: build install # We have nothing to do by default. # Build architecture-independent files here. binary-indep: build install dh_testdir dh_testroot # dh_movefiles dh_installchangelogs dh_link dh_installdocs dh_installexamples dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_installinit # dh_installcron # dh_installinfo dh_installman dh_strip dh_compress dh_fixperms # dh_perl # dh_python # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install doublecmd-0.8.2/install/linux/deb/doublecmd-help/copyright0000664000175000017500000000213611516300753022666 0ustar alexxalexxFormat-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135 Name: Double Commander Source: http://doublecmd.sourceforge.net/ Maintainer: Alexander Koblov Copyright: © 2006-2010 Alexander Koblov License: GPL-2+ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this package; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA . On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/GPL-2'. doublecmd-0.8.2/install/linux/deb/doublecmd-help/doublecmd-help-uk.doc-base0000664000175000017500000000052711610366102025630 0ustar alexxalexxDocument: doublecmd-help-uk Title: Documentation for the Double Commander (Ukrainian) Author: Rustem Rakhimov , Максим aka Ma$terok Abstract: This manual describes how to use Double Commander. Section: File Management Format: HTML Index: /usr/share/doublecmd/doc/uk/index.html Files: /usr/share/doublecmd/doc/uk/*.html doublecmd-0.8.2/install/linux/deb/doublecmd-help/compat0000664000175000017500000000000211516300753022127 0ustar alexxalexx5 doublecmd-0.8.2/install/linux/deb/doublecmd-help/source/0000775000175000017500000000000013244011205022220 5ustar alexxalexxdoublecmd-0.8.2/install/linux/deb/doublecmd-help/source/format0000664000175000017500000000001411644070300023431 0ustar alexxalexx3.0 (quilt) doublecmd-0.8.2/install/linux/deb/doublecmd-help/control0000664000175000017500000000240411610363331022330 0ustar alexxalexxSource: doublecmd-help Section: doc Priority: optional Maintainer: Alexander Koblov Build-Depends: debhelper (>= 7.0.0) Standards-Version: 3.8.4 Homepage: http://doublecmd.sourceforge.net/ Package: doublecmd-help-en Architecture: all Depends: doublecmd-gtk | doublecmd-qt Suggests: www-browser Description: Documentation for the Double Commander (English) This package contains the documentation files for the Double Commander designed for use with the external web browsers. . This package contains the documentation for the DC in English. Package: doublecmd-help-ru Architecture: all Depends: doublecmd-gtk | doublecmd-qt Suggests: www-browser Description: Documentation for the Double Commander (Russian) This package contains the documentation files for the Double Commander designed for use with the external web browsers. . This package contains the documentation for the DC in Russian. Package: doublecmd-help-uk Architecture: all Depends: doublecmd-gtk | doublecmd-qt Suggests: www-browser Description: Documentation for the Double Commander (Ukrainian) This package contains the documentation files for the Double Commander designed for use with the external web browsers. . This package contains the documentation for the DC in Ukrainian. doublecmd-0.8.2/install/linux/deb/doublecmd-help/changelog0000664000175000017500000000024611516546200022604 0ustar alexxalexxdoublecmd-help (0.4.6-3256~ppa) lucid; urgency=low * Initial release (Closes: #2931241) -- Alexander Koblov Thu, 30 May 2010 21:04:07 -0500 doublecmd-0.8.2/install/linux/deb/doublecmd/0000775000175000017500000000000013244011205017772 5ustar alexxalexxdoublecmd-0.8.2/install/linux/deb/doublecmd/doublecmd-gtk.lintian-overrides0000664000175000017500000000036112561673162026114 0ustar alexxalexx# From names of objects in lcl-units, not visible to the user doublecmd-gtk: spelling-error-in-binary usr/lib/doublecmd/doublecmd Childs Children doublecmd-gtk: shlib-with-non-pic-code usr/lib/doublecmd/plugins/wlx/wlxmplayer/wlxmplayer.wlx doublecmd-0.8.2/install/linux/deb/doublecmd/rules0000775000175000017500000000457612706221352021076 0ustar alexxalexx#!/usr/bin/make -f # Set temporary HOME for lazarus primary config directory export HOME=$(CURDIR)/tmphome %: dh $@ override_dh_install: cd language ;\ if [ -f doublecmd.po ] ; then mv doublecmd.po doublecmd.en.po; fi ; # Remove convenience copy of Free Pascal Qt4 binding, use libqt4pas-dev instead rm -f plugins/wlx/WlxMplayer/src/qt4.pas # Build GTK2 version ./build.sh beta gtk2 ./install/linux/install.sh --install-prefix=$(CURDIR)/debian/doublecmd-common ./clean.sh # Build Qt4 version ./build.sh beta qt ./install/linux/install.sh --install-prefix=$(CURDIR)/debian/doublecmd-qt-temp ./clean.sh # Separate GTK2-specific files mkdir -p $(CURDIR)/debian/doublecmd-gtk/usr/lib/doublecmd/plugins mv $(CURDIR)/debian/doublecmd-common/usr/lib/doublecmd/doublecmd $(CURDIR)/debian/doublecmd-gtk/usr/lib/doublecmd/ mv $(CURDIR)/debian/doublecmd-common/usr/lib/doublecmd/plugins/wlx $(CURDIR)/debian/doublecmd-gtk/usr/lib/doublecmd/plugins/ mv $(CURDIR)/debian/doublecmd-common/usr/lib/doublecmd/doublecmd.zdli $(CURDIR)/debian/doublecmd-gtk/usr/lib/doublecmd/ # Separate Qt4-specific files mkdir -p $(CURDIR)/debian/doublecmd-qt/usr/lib/doublecmd/plugins mv $(CURDIR)/debian/doublecmd-qt-temp/usr/lib/doublecmd/doublecmd $(CURDIR)/debian/doublecmd-qt/usr/lib/doublecmd/ mv $(CURDIR)/debian/doublecmd-qt-temp/usr/lib/doublecmd/plugins/wlx $(CURDIR)/debian/doublecmd-qt/usr/lib/doublecmd/plugins/ mv $(CURDIR)/debian/doublecmd-qt-temp/usr/lib/doublecmd/doublecmd.zdli $(CURDIR)/debian/doublecmd-qt/usr/lib/doublecmd/ rm -rf $(CURDIR)/debian/doublecmd-qt-temp/ # Separate plugins mkdir -p $(CURDIR)/debian/doublecmd-plugins/usr/lib/doublecmd mv $(CURDIR)/debian/doublecmd-common/usr/lib/doublecmd/plugins $(CURDIR)/debian/doublecmd-plugins/usr/lib/doublecmd # Clean up common files rm -rf $(CURDIR)/debian/doublecmd-common/usr/share/doublecmd/doc find $(CURDIR)/debian/doublecmd-common/usr/share/ -type f | xargs chmod a-x ; dh_install override_dh_strip: # Strip plugins because dh_strip cannot handle non-standard extensions (bug #35733) find $(CURDIR)/debian/doublecmd-*/usr/lib/doublecmd/plugins/ -name '*.w?x' -o -name '*.dsx' | \ xargs strip --remove-section=.comment --strip-unneeded ; dh_strip override_dh_clean: ./clean.sh cd language ;\ if [ -f doublecmd.en.po ] ; then mv doublecmd.en.po doublecmd.po; fi ; # Clean up temporary HOME rm -rf $(CURDIR)/tmphome dh_clean doublecmd-0.8.2/install/linux/deb/doublecmd/copyright0000664000175000017500000004373012673235470021755 0ustar alexxalexxFormat: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Double Commander Upstream-Contact: Alexander Koblov Source: http://doublecmd.sourceforge.net/ Files: * Copyright: 2006-2016 Alexander Koblov 2008 Dmitry Kolomiets 2009-2013 Przemysław Nagay License: GPL-2.0+ Files: components/CmdLine/* Copyright: 2007 Julian Schutsch License: GPL-3.0+ Files: components/lclextensions/* Copyright: 2007 Luiz Américo Pereira Câmara License: LGPL-2.0+ Files: components/dcpcrypt/* Copyright: 1999-2002 David Barton License: X11 Files: components/multithreadprocs/* Copyright: 2008 Mattias Gaertner License: LGPL-2.1+ Files: components/gifanim/* Copyright: 2009 Laurent Jacques License: GPL-2.0+ Files: components/virtualtreeview/* Copyright: 2000-2003 Mike Lischke 2002-2004 Ralf Junker 2007 Marco Zehe License: MPL-1.1 or LGPL-2.1+ Files: components/viewer/viewercontrol.pas Copyright: 2003-2004 Radek Červinka 2006-2013 Alexander Koblov License: GPL-2.0+ Files: components/viewer/MappingFile.pas Copyright: 2005 Razumikhin Dmitry License: LGPL-2.0+ Files: components/chsdet/* Copyright: 2006 Nick Yakowlew License: LGPL-2.1+ Files: libraries/src/libbz2/* plugins/wcx/zip/fparchive/abbzip2.pas Copyright: 1996-2010 Julian Seward License: BSD-4-clause~bzip2 Files: plugins/wfx/ftp/synapse/* Copyright: 1999-2012 Lukas Gebauer License: BSD-3-clause Files: plugins/wfx/ftp/synapse/ssl_winssl_lib.pas Copyright: 2008 Boris Krasnovskiy 2013 Alexander Koblov License: GPL-2.0+ Files: plugins/wfx/ftp/synapse/ssl_gnutls_lib.pas Copyright: 2002 Andrew McDonald 2004-2006 Free Software Foundation 2013 Alexander Koblov License: GPL-2.0+ Files: plugins/wfx/ftp/src/* src/platform/unix/ujpegthumb.pas src/platform/unix/ukeyfile.pas src/platform/unix/upython.pas src/platform/win/uNTFSLinks.pas src/platform/win/uthumbnailprovider.pas Copyright: 2009-2016 Alexander Koblov License: LGPL-2.1+ Files: plugins/wdx/deb_wdx/src/minigzip.pas Copyright: 1995-1998 Jean-loup Gailly 1998 Jacques Nomssi Nzali License: Zlib Files: plugins/wdx/deb_wdx/src/deb_wdx_intf.pas Copyright: 2005 Ralgh Young License: GPL-2.0+ Files: plugins/wfx/gvfs/* Copyright: 2008-2009 Tomas Bzatek 2009-2010 Alexander Koblov License: LGPL-2.0+ Files: plugins/wdx/rpm_wdx/* plugins/wcx/rpm/* plugins/wcx/cpio/* Copyright: 2000-2002 Mandryka Yurij 2007 Alexander Koblov License: GPL-2.0+ Files: plugins/wcx/sevenzip/* Copyright: 2014-2015 Alexander Koblov License: LGPL-2.1+ Files: plugins/wcx/sevenzip/src/jcl/common/JclCompression.pas Copyright: 2004-2014 Matthias Thoma, Olivier Sannie (obones), Florent Ouchet (outchy), Jan Goyvaerts (jgsoft), Uwe Schuster (uschuster) License: MPL-1.1 or LGPL-2.1+ Files: plugins/wcx/sevenzip/src/jcl/windows/sevenzip.pas plugins/wcx/zip/lzma/* Copyright: 1999-2008 Igor Pavlov License: LGPL-2.1+ Files: plugins/wcx/unbz2/bzip2/bzip2.pas Copyright: 2002 by Daniel Mantione 2007-2009 Alexander Koblov License: GPL-2.0+ Files: plugins/wcx/zip/fparchive/* plugins/wcx/zip/src/ZipApp.pas Copyright: 1997-2002 TurboPower Software 2007-2012 Alexander Koblov License: MPL-1.1 Files: plugins/wcx/zip/fparchive/abxz.pas Copyright: 2014-2015 Alexander Koblov License: X11 Files: plugins/wlx/WlxMplayer/src/qt4.pas Copyright: 2005-2011 Jan Van hijfte License: LGPL-3.0+ Files: scripts/rabbit-vcs.py Copyright: 2009 Jason Heeris 2009 Bruce van der Kooij 2009 Adam Plumb 2014 Alexander Koblov License: GPL-2.0+ Files: src/platform/unix/uudev.pas Copyright: 2008 David Zeuthen 2014 Alexander Koblov License: GPL-2.0+ Files: src/platform/unix/uusersgroups.pas Copyright: 2003 Martin Matusu License: GPL-2.0+ Files: src/platform/unix/mime/umimetype.pas Copyright: 2007 Houng Jen Yee (PCMan) 2014-2015 Alexander Koblov License: GPL-2.0+ Files: src/platform/win/ugdiplus.pas Copyright: 2008 Alexander Koblov License: LGPL-2.0+ Files: src/fsyncdirsdlg.pas Copyright: 2013 Anton Panferov 2014 Alexander Koblov License: GPL-2.0+ Files: src/uhighlighterprocs.pas Copyright: 2000 Michael Hieke License: MPL-1.1 or GPL-2.0+ Files: src/uparitercontrols.pas Copyright: 2004 Flavio Etrusco 2011 Alexander Koblov License: BSD-2-clause Files: src/ufindthread.pas src/ffileproperties.pas src/uColorExt.pas src/ufindfiles.pas src/uglobs.pas src/fFindDlg.pas src/fmain.pas Copyright: 2002 Peter Cernoch 2003-2004 Radek Červinka 2003 Martin Matusu 2006-2012 Alexander Koblov 2008 Dmitry Kolomiets 2008 Vitaly Zotov 2010 Przemysław Nagay License: GPL-2.0+ Files: src/udiffond.pas src/udiffonp.pas Copyright: 2001-2009 Angus Johnson License: other~tdiff The code in the TDiff component is released as freeware provided you agree to the following terms & conditions: 1. the copyright notice, terms and conditions are left unchanged 2. modifications to the code by other authors must be clearly documented and accompanied by the modifier's name. 3. the TDiff component may be freely compiled into binary format and no acknowledgement is required. However, a discrete acknowledgement would be appreciated (eg. in a program's 'About Box'). Files: src/uresample.pas Copyright: 1997-1998 Anders Melander 2009 Alexander Koblov License: other~uresample This software is copyrighted as noted above. It may be freely copied, modified, and redistributed, provided that the copyright notice(s) is preserved on all copies. . There is no warranty or other guarantee of fitness for this software, it is provided solely "as is". Bug reports or fixes may be sent to the author, who may or may not act on them as he desires. . You may not include this software in a program or other software product without supplying the source, or without informing the end-user that the source is available for no extra charge. . If you modify this software, you should include a notice in the "Revision history" section giving the name of the person performing the modification, the date of modification, and the reason for such modification. Files: debian/* Copyright: 2010-2013 Alexander Koblov 2013-2016 Graham Inggs License: GPL-2.0+ License: GPL-2.0+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". License: GPL-3.0+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". License: LGPL-2.0+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . . On Debian systems, the complete text of the GNU Lesser General Public License can be found in "/usr/share/common-licenses/LGPL-2". License: LGPL-2.1+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . . On Debian systems, the complete text of the GNU Lesser General Public License can be found in "/usr/share/common-licenses/LGPL-2.1". License: LGPL-3.0+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . . On Debian systems, the complete text of the GNU Lesser General Public License can be found in "/usr/share/common-licenses/LGPL-3". License: BSD-2-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. . THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License: BSD-3-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. . 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. . 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License: BSD-4-clause~bzip2 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. . 2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. . 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. . 4. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License: MPL-1.1 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ . Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. License: X11 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. License: Zlib This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. . Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: . 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. doublecmd-0.8.2/install/linux/deb/doublecmd/doublecmd-qt.lintian-overrides0000664000175000017500000000035712561673162025760 0ustar alexxalexx# From names of objects in lcl-units, not visible to the user doublecmd-qt: spelling-error-in-binary usr/lib/doublecmd/doublecmd Childs Children doublecmd-qt: shlib-with-non-pic-code usr/lib/doublecmd/plugins/wlx/wlxmplayer/wlxmplayer.wlx doublecmd-0.8.2/install/linux/deb/doublecmd/watch0000664000175000017500000000014412277451532021042 0ustar alexxalexxversion=3 http://sf.net/doublecmd/doublecmd-(\d\S*)-src\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) doublecmd-0.8.2/install/linux/deb/doublecmd/doublecmd-plugins.lintian-overrides0000664000175000017500000000140513040630040026765 0ustar alexxalexx# These are plugins, not shared libraries doublecmd-plugins: shared-lib-without-dependency-information usr/lib/doublecmd/plugins/dsx/dsxlocate/dsxlocate.dsx doublecmd-plugins: shared-lib-without-dependency-information usr/lib/doublecmd/plugins/wcx/cpio/cpio.wcx doublecmd-plugins: shared-lib-without-dependency-information usr/lib/doublecmd/plugins/wcx/deb/deb.wcx doublecmd-plugins: shared-lib-without-dependency-information usr/lib/doublecmd/plugins/wcx/rpm/rpm.wcx doublecmd-plugins: shared-lib-without-dependency-information usr/lib/doublecmd/plugins/wdx/deb_wdx/deb_wdx.wdx doublecmd-plugins: shared-lib-without-dependency-information usr/lib/doublecmd/plugins/wdx/rpm_wdx/rpm_wdx.wdx doublecmd-plugins: shlib-with-non-pic-code doublecmd-plugins: missing-depends-line doublecmd-0.8.2/install/linux/deb/doublecmd/patches/0000775000175000017500000000000013244011205021421 5ustar alexxalexxdoublecmd-0.8.2/install/linux/deb/doublecmd/patches/series0000664000175000017500000000003212277451532022651 0ustar alexxalexxx-terminal-emulator.patch doublecmd-0.8.2/install/linux/deb/doublecmd/patches/hide-build-info.patch0000664000175000017500000000106112673235470025420 0ustar alexxalexxDescription: Do not display build info in window title Author: Graham Inggs Forwarded: not-needed Last-Update: 2015-02-15 --- a/src/fmain.pas +++ b/src/fmain.pas @@ -913,13 +913,7 @@ if Length(UniqueInstance.ServernameByUser) > 0 then ServernameString := ' [' + UniqueInstance.ServernameByUser + ']'; - Result := Format('%s%s %s build %s; %s', - ['Double Commander', - ServernameString, - dcVersion, - dcRevision, - dcBuildDate] - ); + Result := 'Double Commander'; end; var doublecmd-0.8.2/install/linux/deb/doublecmd/patches/x-terminal-emulator.patch0000664000175000017500000000201212673235470026364 0ustar alexxalexxDescription: Change default terminal command to 'x-terminal-emulator' Author: Graham Inggs Forwarded: not-needed Last-Update: 2016-03-14 --- a/src/platform/uOSUtils.pas +++ b/src/platform/uOSUtils.pas @@ -63,11 +63,11 @@ RunInTermCloseParams = ''; MonoSpaceFont = 'Monaco'; {$ELSE} - RunTermCmd = 'xterm'; // default terminal + RunTermCmd = 'x-terminal-emulator'; // default terminal RunTermParams = ''; - RunInTermStayOpenCmd = 'xterm'; // default run in terminal command AND Stay open after command + RunInTermStayOpenCmd = 'x-terminal-emulator'; // default run in terminal command AND Stay open after command RunInTermStayOpenParams = '-e sh -c ''{command}; echo -n Press ENTER to exit... ; read a'''; - RunInTermCloseCmd = 'xterm'; // default run in terminal command AND Close after command + RunInTermCloseCmd = 'x-terminal-emulator'; // default run in terminal command AND Close after command RunInTermCloseParams = '-e sh -c {command}'; MonoSpaceFont = 'Monospace'; {$ENDIF} doublecmd-0.8.2/install/linux/deb/doublecmd/compat0000664000175000017500000000000212277451532021210 0ustar alexxalexx9 doublecmd-0.8.2/install/linux/deb/doublecmd/source/0000775000175000017500000000000013244011205021272 5ustar alexxalexxdoublecmd-0.8.2/install/linux/deb/doublecmd/source/format0000664000175000017500000000001512277451532022521 0ustar alexxalexx3.0 (quilt) doublecmd-0.8.2/install/linux/deb/doublecmd/control0000664000175000017500000000652213217426530021415 0ustar alexxalexxSource: doublecmd Section: utils Priority: optional Maintainer: Pascal Packaging Team Uploaders: Graham Inggs Build-Depends: debhelper (>= 9), fp-utils (>= 2.6.2), fpc (>= 2.6.2), lcl (>= 1.4), lcl-gtk2, lcl-qt4, libbz2-dev, libdbus-1-dev, libglib2.0-dev, libgtk2.0-dev, libqt4pas-dev (>= 2.1) Standards-Version: 3.9.7 Vcs-Git: https://anonscm.debian.org/git/pkg-pascal/doublecmd.git Vcs-Browser: https://anonscm.debian.org/cgit/pkg-pascal/doublecmd.git Homepage: http://doublecmd.sourceforge.net/ Package: doublecmd-gtk Architecture: any Depends: doublecmd-common (= ${source:Version}), doublecmd-plugins (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Provides: doublecmd Conflicts: doublecmd Replaces: doublecmd, doublecmd-gtk-dbg (<< 0.8.0~0+svn6777), doublecmd-qt-dbg (<< 0.8.0~0+svn6777) Breaks: doublecmd-gtk-dbg (<< 0.8.0~0+svn6777), doublecmd-qt-dbg (<< 0.8.0~0+svn6777) Description: twin-panel (commander-style) file manager (GTK2) Double Commander is a cross platform open source file manager with two panels side by side. It is inspired by Total Commander and features some new ideas. . Support for RAR archives can be enabled by installing the libunrar0 package from non-free. . This package contains the GTK2 user interface. Package: doublecmd-qt Architecture: any Depends: doublecmd-common (= ${source:Version}), doublecmd-plugins (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Provides: doublecmd Conflicts: doublecmd Replaces: doublecmd, doublecmd-gtk-dbg (<< 0.8.0~0+svn6777), doublecmd-qt-dbg (<< 0.8.0~0+svn6777) Breaks: doublecmd-gtk-dbg (<< 0.8.0~0+svn6777), doublecmd-qt-dbg (<< 0.8.0~0+svn6777) Description: twin-panel (commander-style) file manager (Qt4) Double Commander is a cross platform open source file manager with two panels side by side. It is inspired by Total Commander and features some new ideas. . Support for RAR archives can be enabled by installing the libunrar0 package from non-free. . This package contains the Qt4 user interface. Package: doublecmd-plugins Architecture: any Depends: ${misc:Depends} Description: twin-panel (commander-style) file manager (plugins) Double Commander is a cross platform open source file manager with two panels side by side. It is inspired by Total Commander and features some new ideas. . Support for RAR archives can be enabled by installing the libunrar0 package from non-free. . This package contains plugins. Package: doublecmd-common Architecture: all Recommends: doublecmd-gtk | doublecmd-qt Depends: desktop-file-utils, ${misc:Depends} Suggests: doublecmd-help-en | doublecmd-help, libffmpegthumbnailer4, libunrar0, mplayer, rabbitvcs-core, xterm | x-terminal-emulator Description: twin-panel (commander-style) file manager Double Commander is a cross platform open source file manager with two panels side by side. It is inspired by Total Commander and features some new ideas. . Support for RAR archives can be enabled by installing the libunrar0 package from non-free. . This package contains common files. doublecmd-0.8.2/install/linux/deb/doublecmd/changelog0000664000175000017500000001617612706221352021667 0ustar alexxalexxdoublecmd (0.7.1-2) unstable; urgency=medium * Remove doublecmd-*-dbg packages, they contained no debug symbols. * Move doublecmd.zdli files from doublecmd-*-dbg packages. * Add breaks/replaces against old doublecmd-*-dbg packages. * Add plugins/wcx/zip/lib/abresstring.rsj to debian/clean. * Update Lintian overrides. * Fix various spelling and grammar errors reported by Lintian. -- Graham Inggs Thu, 07 Apr 2016 13:04:12 +0200 doublecmd (0.7.1-1) unstable; urgency=medium * New upstream release. * Drop upstream-fix-arm64-ftbfs.patch, included upstream. -- Graham Inggs Tue, 29 Mar 2016 14:56:00 +0200 doublecmd (0.7.0-1) unstable; urgency=medium * New upstream release: - add inode/directory MimeType to doublecmd.desktop (Closes: #807570) - fix scrolling through files with long names is slow (Closes: #807257) - fix FTBFS with FPC 3.0 and Lazarus 1.6 (Closes: #818123) * Fix FTBFS on arm64, thanks Edmund Grimley Evans and Alexander Koblov (Closes: #803984) * Remove doublecmd-common.menu, as per #741573. * Use secure URIs for VCS fields. * Update d/copyright. * Update Lintian overrides for doublecmd-plugins. * Bump Standards-Version to 3.9.7, no further changes. -- Graham Inggs Tue, 15 Mar 2016 13:48:55 +0200 doublecmd (0.6.6-1) unstable; urgency=medium * New upstream release. * Let doublecmd-common suggest libffmpegthumbnailer4 (per upstream). * Do not display splash screen at startup. -- Graham Inggs Tue, 13 Oct 2015 16:27:23 +0200 doublecmd (0.6.5-2) unstable; urgency=medium * Let doublecmd-common recommend doublecmd-gtk | doublecmd-qt for users who install the -common package by mistake. -- Graham Inggs Wed, 07 Oct 2015 16:58:38 +0200 doublecmd (0.6.5-1) unstable; urgency=medium * New upstream release. * Update my email address. -- Graham Inggs Tue, 08 Sep 2015 11:47:54 +0200 doublecmd (0.6.4-1) unstable; urgency=medium * New upstream release. * Convert upstream HTML changelog to text and ship it, add Build-Depends on html2text. -- Graham Inggs Mon, 20 Jul 2015 11:51:00 +0200 doublecmd (0.6.2-1) unstable; urgency=medium * New upstream release. * Upload to unstable. * Refresh d/patches/hide-build-info.patch. * Add comments to Lintian overrides. * Update d/copyright with some missed files, fix some spelling and capitalization errors. -- Graham Inggs Tue, 19 May 2015 16:56:20 +0200 doublecmd (0.6.1-1) experimental; urgency=medium * New upstream release. * Drop patches included upstream: - d/patches/clean-plugins-static-libs.patch - d/patches/disable-pic-on-arm.patch - d/patches/fpc-arm-workaround.patch * Update d/copyright for renamed and new files src/udiff*.pas. -- Graham Inggs Tue, 31 Mar 2015 12:07:48 +0200 doublecmd (0.6.0-3) experimental; urgency=medium * Revert patch to not generate debug line info on big-endian architectures. * Work around ARM code generation bug in fpc < 3.0.1. -- Graham Inggs Fri, 27 Feb 2015 14:26:01 +0200 doublecmd (0.6.0-2) experimental; urgency=low * Disable PIC on ARM architectures. * Do not generate debug line info on big-endian architectures. * Update d/control: add Suggests on rabbitvcs-core. * Update d/copyright: new directory libraries/src/libbz2. * Update Lintian overrides. -- Graham Inggs Wed, 18 Feb 2015 11:09:44 +0200 doublecmd (0.6.0-1) experimental; urgency=medium * New upstream release. * Drop d/patches/hide-lazarus-revision.patch included upstream, refresh remaining patches. * New patch d/patches/clean-plugins-static-libs.patch to clean static libs from plugins directories. * Update d/rules: - do not rename files doublecmd.pb.po and doublecmd.zh.po that no longer exist - strip plugins because dh_strip cannot handle non-standard extensions * Update d/copyright: - update copyright years - add copyright information for new file plugins/wcx/zip/fparchive/abxz.pas - remove copyright information for removed directory libraries/src/libmime/ -- Graham Inggs Mon, 16 Feb 2015 14:09:06 +0200 doublecmd (0.5.11-1) unstable; urgency=medium * New upstream release. * Drop patches included upstream, refresh remaining patches. * Update d/rules: - do not delete symlink for doublecmd-help - remove new convenience copy of qt4.pas before building * Update d/copyright: - update copyright years - add copyright information for newly added qt4.pas - use dh_make copyright templates * Update d/control: add Suggests on mplayer2. * Update Lintian overrides. -- Graham Inggs Tue, 07 Oct 2014 15:58:52 +0200 doublecmd (0.5.10-2) unstable; urgency=medium * Add d/patches/hide-lazarus-revision.patch to build without lazarus-src * Update d/control: - drop build-depends on lazarus-src - clean up build-depends on lcl, lcl-gtk2 and lcl-qt4 -- Graham Inggs Mon, 02 Jun 2014 14:04:06 +0200 doublecmd (0.5.10-1) unstable; urgency=medium [ Graham Inggs ] * New upstream release (Closes: #746015) * Refresh d/patches/hide-build-info.patch. [ Paul Gevers ] * Update d/copyright with newly added file * Drop hack in fix_build.sh*.patch and convert it to not build the lazarus components, as that is fixed in Lazarus now. Renamed patch to dont_build_lazarus_components.patch -- Paul Gevers Sun, 18 May 2014 15:56:14 +0200 doublecmd (0.5.9-2) unstable; urgency=medium * Tweak fix_build.sh_for_lazarus-1.2.patch, fix FTBFS on i386. -- Graham Inggs Tue, 15 Apr 2014 15:00:27 +0200 doublecmd (0.5.9-1) unstable; urgency=medium [ Graham Inggs ] * New upstream. * Update d/control: - add Depends on desktop-file-utils - update Maintainer and Vcs-* fields for Pascal Packaging Team maintenance * Update d/patches: remove link-with-as-needed.patch and add-keywords-to-desktop-file.patch, included upstream. * Remove unnecessary d/doublecmd-*.dir files. * Do not install /usr/lib/doublecmd/doc. [ Paul Gevers ] * Add add_set-e_to_build_scripts.patch to let the build fail on failure * Add fix_build.sh_for_lazarus-1.2.patch and remove_red-haring__dont_install_.so_files.patch to prevent FTBFS (Closes: 741792) -- Paul Gevers Mon, 14 Apr 2014 21:51:22 +0200 doublecmd (0.5.8-1) unstable; urgency=low * New upstream. * Link with '--as-needed' flag to avoid unnecessary linking. * Add Keywords entry to desktop file. * Update d/control: bump Standards-Version to 3.9.5, no changes. -- Graham Inggs Sun, 19 Jan 2014 12:46:33 +0200 doublecmd (0.5.7-2) unstable; urgency=low * Fix FTBFS without writable HOME directory (Closes: #725647) -- Graham Inggs Mon, 07 Oct 2013 11:44:11 +0200 doublecmd (0.5.7-1) unstable; urgency=low * Initial release (Closes: #718778) -- Graham Inggs Wed, 25 Sep 2013 10:48:13 +0200 doublecmd-0.8.2/install/linux/deb/libunrar/0000775000175000017500000000000013244011205017652 5ustar alexxalexxdoublecmd-0.8.2/install/linux/deb/libunrar/postrm0000775000175000017500000000013711556027124021140 0ustar alexxalexx#!/bin/sh set -e if [ "$1" = "remove" ]; then ldconfig /usr/lib/libunrar.so fi #DEBHELPER# doublecmd-0.8.2/install/linux/deb/libunrar/rules0000775000175000017500000000177512222000001020727 0ustar alexxalexx#!/usr/bin/make -f # Made with the aid of dh_make, by Petr Cech. # Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess. # Some lines taken from debmake, by Christoph Lameter. build: dh_testdir make lib CXXFLAGS+="-fPIC -DSILENT" LDFLAGS+="-Wl,-soname,libunrar.so.0" clean: dh_testdir dh_testroot make clean rm -f libunrar.so dh_clean # Build architecture-independent files here. binary-indep: build # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build dh_testdir dh_testroot dh_prep dh_installdirs install -o root -g root -s -m 0644 libunrar.so debian/libunrar/usr/lib install -m 0644 debian/lintian/libunrar debian/libunrar/usr/share/lintian/overrides dh_link usr/lib/libunrar.so usr/lib/libunrar.so.0 dh_installdocs dh_installchangelogs dh_strip dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary doublecmd-0.8.2/install/linux/deb/libunrar/copyright0000664000175000017500000000460211516774223021627 0ustar alexxalexxThis package was debianized by Petr Cech on Thu, 16 Mar 2000 18:51:33 +0100. Further modifications have been made by Chris Anderson on Wed Aug 25 19:03:47 EDT 2004 It was downloaded from http://www.rarlabs.com/rar_add.htm Copyright: Copyright (c) 1993-2005 Alexander L. Roshal NOTE: this software is non-free, therefore carefully read this license before doing anything with it. In particular, this source code may not be used for recreating the rar compression algorithm. Full license follows: ****** ***** ****** UnRAR - free utility for RAR archives ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ****** ******* ****** License for use and distribution of ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ** ** ** ** ** ** FREE portable version ~~~~~~~~~~~~~~~~~~~~~ The source code of UnRAR utility is freeware. This means: 1. All copyrights to RAR and the utility UnRAR are exclusively owned by the author - Alexander Roshal. 2. The UnRAR sources may be used in any software to handle RAR archives without limitations free of charge, but cannot be used to re-create the RAR compression algorithm, which is proprietary. Distribution of modified UnRAR sources in separate form or as a part of other software is permitted, provided that it is clearly stated in the documentation and source comments that the code may not be used to develop a RAR (WinRAR) compatible archiver. 3. The UnRAR utility may be freely distributed. It is allowed to distribute UnRAR inside of other software packages. 4. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS SOFTWARE. 5. Installing and using the UnRAR utility signifies acceptance of these terms and conditions of the license. 6. If you don't agree with terms of the license you must remove UnRAR files from your storage devices and cease to use the utility. Thank you for your interest in RAR and UnRAR. Alexander L. Roshal This package is auto-buildable doublecmd-0.8.2/install/linux/deb/libunrar/shlibs0000664000175000017500000000001411517020145021060 0ustar alexxalexxlibunrar 0 doublecmd-0.8.2/install/linux/deb/libunrar/watch0000664000175000017500000000015511516774223020724 0ustar alexxalexxversion=3 http://www.rarlab.com/rar_add.htm http://www.rarlab.com/rar/unrarsrc-(.*)\.tar\.gz debian uupdate doublecmd-0.8.2/install/linux/deb/libunrar/compat0000664000175000017500000000000211516774223021070 0ustar alexxalexx7 doublecmd-0.8.2/install/linux/deb/libunrar/lintian/0000775000175000017500000000000013244011205021310 5ustar alexxalexxdoublecmd-0.8.2/install/linux/deb/libunrar/lintian/libunrar0000664000175000017500000000005411517020145023054 0ustar alexxalexxlibunrar: package-name-doesnt-match-sonames doublecmd-0.8.2/install/linux/deb/libunrar/postinst0000775000175000017500000000007611556027124021501 0ustar alexxalexx#!/bin/sh set -e ldconfig /usr/lib/libunrar.so #DEBHELPER# doublecmd-0.8.2/install/linux/deb/libunrar/source/0000775000175000017500000000000013244011205021152 5ustar alexxalexxdoublecmd-0.8.2/install/linux/deb/libunrar/source/format0000664000175000017500000000001411516774223022400 0ustar alexxalexx3.0 (quilt) doublecmd-0.8.2/install/linux/deb/libunrar/control0000664000175000017500000000105112436425752021274 0ustar alexxalexxSource: unrar-nonfree Section: non-free/utils Priority: optional Maintainer: Alexander Koblov Homepage: http://www.rarlabs.com Build-Depends: debhelper (>= 7) Standards-Version: 3.8.4 XS-Autobuild: yes Package: libunrar Section: non-free/libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Unarchiver for .rar files (non-free version) - shared library Unrar can extract files from .rar archives. If you want to create .rar archives, install package rar. . This package includes the dynamic library. doublecmd-0.8.2/install/linux/deb/libunrar/changelog0000664000175000017500000000022412436425752021544 0ustar alexxalexxunrar-nonfree (5.2.2-0) unstable; urgency=low * Non-maintainer upload -- Alexander Koblov Sat, 29 Nov 2014 23:04:07 +0300 doublecmd-0.8.2/install/linux/deb/libunrar/dirs0000664000175000017500000000004411517020145020540 0ustar alexxalexxusr/lib usr/share/lintian/overrides doublecmd-0.8.2/install/linux/rpm/0000775000175000017500000000000013244011205016100 5ustar alexxalexxdoublecmd-0.8.2/install/linux/rpm/libunrar.spec0000664000175000017500000001210512436430260020601 0ustar alexxalexxName: libunrar Version: 5.2.2 Release: 1 Summary: Decompress library for RAR v5 archives Source: http://www.rarlab.com/rar/unrarsrc-%{version}.tar.gz Url: http://www.rarlab.com/rar_add.htm License: Freeware Group: System/Libraries BuildRequires: gcc-c++ BuildRoot: %{_tmppath}/%{name}-%{version}-root %description The libunrar library allows programs linking against it to decompress existing RAR v5 archives. %prep %setup -q -n unrar %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %build make lib CXXFLAGS+="-fPIC -DSILENT" STRIP=true %install install -d -m 755 %{buildroot}/%{_libdir} install -m 644 libunrar.so %{buildroot}/%{_libdir} %clean [ %{buildroot} != "/" ] && ( rm -rf %{buildroot} ) %files %defattr(-,root,root) %doc license.txt readme.txt %{_libdir}/libunrar.so %changelog * Sun Jan 23 2011 Alexander Koblov - Initial release of library * Sat Jul 10 2010 Götz Waschk 3.93-1mdv2011.0 + Revision: 550262 - new version * Mon Dec 21 2009 Funda Wang 3.91-1mdv2010.1 + Revision: 480547 - new version 3.91 * Thu Aug 20 2009 Götz Waschk 3.90-2mdv2010.0 + Revision: 418576 - rebuild for broken build system * Thu Aug 20 2009 Götz Waschk 3.90-1mdv2010.0 + Revision: 418546 - new version * Mon Jul 13 2009 Götz Waschk 3.90-0.beta4.1mdv2010.0 + Revision: 395466 - new version * Sat Jun 20 2009 Götz Waschk 3.90-0.beta3.1mdv2010.0 + Revision: 387518 - new version * Mon Jun 08 2009 Götz Waschk 3.90-0.beta2.1mdv2010.0 + Revision: 383871 - new version * Thu May 07 2009 Götz Waschk 3.90-0.beta1.1mdv2010.0 + Revision: 372937 - new version * Tue Feb 03 2009 Guillaume Rousse 3.80-2mdv2009.1 + Revision: 337120 - keep bash completion in its own package * Wed Jan 07 2009 Götz Waschk 3.80-1mdv2009.1 + Revision: 326892 - new version * Sun Oct 12 2008 Funda Wang 3.80-0.beta4.1mdv2009.1 + Revision: 292676 - 3.8.4 - New version 3.8 beta3 * Wed Jun 25 2008 Funda Wang 3.80-0.beta2.1mdv2009.0 + Revision: 228841 - New version 3.80 beta 2 * Tue Jun 10 2008 Götz Waschk 3.80-0.beta1.1mdv2009.0 + Revision: 217391 - new version + Funda Wang - Revert to actual version of program - fix real version * Fri Feb 01 2008 Anssi Hannula 3.71-0.beta1.2mdv2008.1 + Revision: 161265 - move to Mandriva non-free from PLF (license is no longer unclear, it now allows redistribution explicitely) - drop pre-MDK10.0 support - fix license tag capitalization - import unrar * Wed Dec 12 2007 G�tz Waschk 3.71-0.beta1.1plf2008.1 - new version * Tue Nov 6 2007 G�tz Waschk 3.70-1plf2008.1 - new version * Mon Apr 16 2007 G�tz Waschk 3.70-0.beta7.1plf2007.1 - new version * Tue Mar 6 2007 G�tz Waschk 3.70-0.beta4.1plf2007.1 - new version * Tue Feb 6 2007 G�tz Waschk 3.70-0.beta3.1plf2007.1 - drop patch - new version * Wed Jan 24 2007 G�tz Waschk 3.70-0.beta1.1plf2007.1 - don't strip the binary at build stage - new version * Thu Nov 2 2006 G�tz Waschk 3.60-1plf2007.1 - update description - new version * Mon Jul 24 2006 G�tz Waschk 3.60-0.beta7.1plf2007.0 - new version * Wed Jun 28 2006 G�tz Waschk 3.60-0.beta5.1plf2007.0 - new version * Tue Oct 11 2005 G�tz Waschk 3.51-1plf - new version * Tue Aug 9 2005 G�tz Waschk 3.50-1plf - new version * Tue Apr 19 2005 G�tz Waschk 3.50-0.beta1.1plf - mkrel - new version * Mon Sep 20 2004 G�tz Waschk 3.40-1plf - fix description - new version * Sun Jun 6 2004 G�tz Waschk 3.30-2plf - rebuild for new g++ * Wed Apr 21 2004 G�tz Waschk 3.30-1plf - new version * Tue Dec 30 2003 G�tz Waschk 3.20-2plf - add unrar bash-completion for Cooker builds * Fri Jun 20 2003 G�tz Waschk 3.20-1plf - small build patch for gcc 3.3 - new version * Sun Mar 30 2003 G�tz Waschk 3.20-0.beta2.1plf - arrgh, the displayed version is 3.20 beta 2 * Sat Mar 29 2003 G�tz Waschk 3.2.0-0.beta2.1plf - new version * Fri Feb 14 2003 G�tz Waschk 3.10-2plf - use default optimization flags (Francisco Javier Felix) * Wed Jan 8 2003 G�tz Waschk 3.10-1plf * Tue Dec 3 2002 G�tz Waschk 3.10-0.beta3.1plf - 3.10 beta 3 * Tue Oct 22 2002 G�tz Waschk 3.10-0.beta1.1plf - fix url - add some docs - drop patch - quiet tar - set version to 3.10 beta 1, that's the output of the program - new version * Mon Aug 26 2002 Guillaume Rousse 3.0-1plf - first PLF release, with patch from Pascal Terjan doublecmd-0.8.2/install/linux/rpm/doublecmd-qt5.spec0000664000175000017500000000276313243754446021455 0ustar alexxalexx# norootforbuild %define doublecmd doublecmd Name: doublecmd-qt5 Summary: Twin-panel (commander-style) file manager (Qt5) Version: 0.8.2 Release: 1 URL: http://doublecmd.sourceforge.net Source0: %{doublecmd}-%{version}.tar.gz License: GPL Group: Applications/File BuildRequires: fpc >= 3.0.0 fpc-src glib2-devel libQt5Pas6-devel >= 2.6 lazarus >= 1.7.0 %if 0%{?mandriva_version} BuildRequires: libncurses-devel libdbus-1-devel libbzip2-devel %endif %if 0%{?fedora_version} || 0%{?rhel} BuildRequires: dbus-devel bzip2-devel %endif %if 0%{?suse_version} >= 1110 BuildRequires: ncurses-devel dbus-1-devel libbz2-devel %endif Provides: doublecmd Conflicts: doublecmd-gtk doublecmd-qt BuildRoot: %{_tmppath}/%{doublecmd}-%{version}-build %define debug_package %{nil} %description Double Commander is a cross platform open source file manager with two panels side by side. It is inspired by Total Commander and features some new ideas. %prep %setup -q -n %{doublecmd}-%{version} %build ./build.sh beta qt5 %install install/linux/install.sh --install-prefix=%{buildroot} %clean [ %{buildroot} != "/" ] && ( rm -rf %{buildroot} ) %files %defattr(-,root,root) %{_libdir}/%{doublecmd} %{_bindir}/%{doublecmd} %{_datadir}/%{doublecmd} %{_datadir}/man/man1/%{doublecmd}.* %{_datadir}/pixmaps/%{doublecmd}.* %{_datadir}/applications/%{doublecmd}.desktop %{_datadir}/icons/hicolor/scalable/apps/%{doublecmd}.svg %changelog * Sun Jan 01 2017 - Alexander Koblov - 0.8.2 - Initial package, version 0.8.2 doublecmd-0.8.2/install/linux/rpm/doublecmd-gtk.spec0000664000175000017500000000272713243754446021531 0ustar alexxalexx# norootforbuild %define doublecmd doublecmd Name: doublecmd-gtk Summary: Twin-panel (commander-style) file manager (GTK2) Version: 0.8.2 Release: 1 URL: http://doublecmd.sourceforge.net Source0: %{doublecmd}-%{version}.orig.tar.gz License: GPL Group: Applications/File BuildRequires: fpc >= 2.6.0 fpc-src glib2-devel gtk2-devel lazarus >= 1.0.0 %if 0%{?mandriva_version} BuildRequires: libncurses-devel libdbus-1-devel libbzip2-devel %endif %if 0%{?fedora_version} || 0%{?rhel} BuildRequires: xorg-x11-devel ncurses-devel dbus-devel bzip2-devel %endif %if 0%{?suse_version} >= 1110 BuildRequires: ncurses-devel dbus-1-devel libbz2-devel %endif Provides: doublecmd Conflicts: doublecmd-qt BuildRoot: %{_tmppath}/%{doublecmd}-%{version}-build %description Double Commander is a cross platform open source file manager with two panels side by side. It is inspired by Total Commander and features some new ideas. %prep %setup -q -n %{doublecmd}-%{version} %build ./build.sh beta gtk2 %install install/linux/install.sh --install-prefix=%{buildroot} %clean [ %{buildroot} != "/" ] && ( rm -rf %{buildroot} ) %files %defattr(-,root,root) %{_libdir}/%{doublecmd} %{_bindir}/%{doublecmd} %{_datadir}/%{doublecmd} %{_datadir}/man/man1/%{doublecmd}.* %{_datadir}/pixmaps/%{doublecmd}.* %{_datadir}/applications/%{doublecmd}.desktop %{_datadir}/icons/hicolor/scalable/apps/%{doublecmd}.svg %changelog * Fri Jun 11 2010 - Alexander Koblov - Initial package, version 0.4.6 doublecmd-0.8.2/install/linux/rpm/doublecmd-help.spec0000664000175000017500000000410513243754446021664 0ustar alexxalexx# norootforbuild %define doublecmd_help doublecmd-help Name: doublecmd-help-en Summary: Documentation for the Double Commander (English) Version: 0.8.2 Release: 1 Url: http://doublecmd.sourceforge.net/ License: GPL-2+ Source0: %{doublecmd_help}-%{version}.tar.gz Group: Documentation Requires: doublecmd BuildArch: noarch %description This package contains the documentation files for the Double Commander designed for use with the external web browsers. This package contains the documentation for the DC in English. %package -n doublecmd-help-ru Summary: Documentation for the Double Commander (Russian) Group: Documentation Requires: doublecmd BuildArch: noarch %description -n doublecmd-help-ru This package contains the documentation files for the Double Commander designed for use with the external web browsers. This package contains the documentation for the DC in Russian. %package -n doublecmd-help-uk Summary: Documentation for the Double Commander (Ukrainian) Group: Documentation Requires: doublecmd BuildArch: noarch %description -n doublecmd-help-uk This package contains the documentation files for the Double Commander designed for use with the external web browsers. This package contains the documentation for the DC in Ukrainian. %prep %setup -q -n %{doublecmd_help}-%{version} %build %install install -d %{buildroot}/%{_datadir}/doublecmd/doc cp -r en %{buildroot}/%{_datadir}/doublecmd/doc cp -r ru %{buildroot}/%{_datadir}/doublecmd/doc cp -r uk %{buildroot}/%{_datadir}/doublecmd/doc %clean [ %{buildroot} != "/" ] && ( rm -rf %{buildroot} ) %files %defattr(-,root,root) %dir %{_datadir}/doublecmd %dir %{_datadir}/doublecmd/doc %doc %{_datadir}/doublecmd/doc/en %files -n doublecmd-help-ru %defattr(-,root,root) %dir %{_datadir}/doublecmd %dir %{_datadir}/doublecmd/doc %doc %{_datadir}/doublecmd/doc/ru %files -n doublecmd-help-uk %defattr(-,root,root) %dir %{_datadir}/doublecmd %dir %{_datadir}/doublecmd/doc %doc %{_datadir}/doublecmd/doc/uk %changelog * Fri Jan 21 2011 - Alexander Koblov - Initial package, version 0.4.6 doublecmd-0.8.2/install/linux/rpm/doublecmd-qt.spec0000664000175000017500000000266413243754446021370 0ustar alexxalexx# norootforbuild %define doublecmd doublecmd Name: doublecmd-qt Summary: Twin-panel (commander-style) file manager (Qt4) Version: 0.8.2 Release: 1 URL: http://doublecmd.sourceforge.net Source0: %{doublecmd}-%{version}.orig.tar.gz License: GPL Group: Applications/File BuildRequires: fpc >= 2.6.0 fpc-src glib2-devel libQt4Pas5-devel >= 2.1 lazarus >= 1.0.0 %if 0%{?mandriva_version} BuildRequires: libdbus-1-devel libbzip2-devel %endif %if 0%{?fedora_version} || 0%{?rhel} BuildRequires: xorg-x11-devel dbus-devel bzip2-devel %endif %if 0%{?suse_version} >= 1110 BuildRequires: dbus-1-devel libbz2-devel %endif Provides: doublecmd Conflicts: doublecmd-gtk BuildRoot: %{_tmppath}/%{doublecmd}-%{version}-build %description Double Commander is a cross platform open source file manager with two panels side by side. It is inspired by Total Commander and features some new ideas. %prep %setup -q -n %{doublecmd}-%{version} %build ./build.sh beta qt %install install/linux/install.sh --install-prefix=%{buildroot} %clean [ %{buildroot} != "/" ] && ( rm -rf %{buildroot} ) %files %defattr(-,root,root) %{_libdir}/%{doublecmd} %{_bindir}/%{doublecmd} %{_datadir}/%{doublecmd} %{_datadir}/man/man1/%{doublecmd}.* %{_datadir}/pixmaps/%{doublecmd}.* %{_datadir}/applications/%{doublecmd}.desktop %{_datadir}/icons/hicolor/scalable/apps/%{doublecmd}.svg %changelog * Fri Jun 11 2010 - Alexander Koblov - Initial package, version 0.4.6 doublecmd-0.8.2/install/linux/build-install-pkg.sh0000775000175000017500000000174012707472745021214 0ustar alexxalexx#!/bin/bash # This script build and install Double Commander Arch Linux package # Temp directory DC_TEMP_DIR=/var/tmp/doublecmd-$(date +%y.%m.%d) # Directory for DC source code DC_SOURCE_DIR=$DC_TEMP_DIR/src # Widgetset library (gtk2 or qt) LCL_PLATFORM=$1 # Set widgetset if [ -z $LCL_PLATFORM ]; then export LCL_PLATFORM=gtk2 fi # Recreate temp directory rm -rf $DC_TEMP_DIR mkdir -p $DC_TEMP_DIR # Export from SVN svn export ../../ $DC_SOURCE_DIR # Save revision number DC_REVISION=`$(pwd)/update-revision.sh ../../ $DC_SOURCE_DIR` # Prepare PKGBUILD file cp -a pkg/doublecmd-svn.install $DC_TEMP_DIR echo "$DC_REVISION" > $DC_SOURCE_DIR/revision.txt cp -a pkg/doublecmd-$LCL_PLATFORM.pkgbuild $DC_TEMP_DIR/PKGBUILD # Set temporary HOME for lazarus primary config directory export HOME=$DC_TEMP_DIR mkdir -p $DC_TEMP_DIR/.lazarus cp -a pkg/environmentoptions.xml $DC_TEMP_DIR/.lazarus pushd $DC_TEMP_DIR # Build and install makepkg --install popd # Clean rm -rf $DC_TEMP_DIR doublecmd-0.8.2/install/linux/lib/0000775000175000017500000000000013244011205016050 5ustar alexxalexxdoublecmd-0.8.2/install/linux/lib/i386/0000775000175000017500000000000013244011205016541 5ustar alexxalexxdoublecmd-0.8.2/install/linux/lib/i386/qt5/0000775000175000017500000000000013244011205017252 5ustar alexxalexxdoublecmd-0.8.2/install/linux/lib/i386/qt/0000775000175000017500000000000013244011205017165 5ustar alexxalexxdoublecmd-0.8.2/install/linux/lib/readme.txt0000664000175000017500000000031112014201074020040 0ustar alexxalexxBefore create packages (before run create_packages.sh) copy in this directory third-party libraries: - libunrar.so - needed for unrar plugin - libqt4intf.so - needed for qt4 version of Double Commanderdoublecmd-0.8.2/install/linux/lib/x86_64/0000775000175000017500000000000013244011205017006 5ustar alexxalexxdoublecmd-0.8.2/install/linux/lib/x86_64/qt5/0000775000175000017500000000000013244011205017517 5ustar alexxalexxdoublecmd-0.8.2/install/linux/lib/x86_64/qt/0000775000175000017500000000000013244011205017432 5ustar alexxalexxdoublecmd-0.8.2/install/windows/0000775000175000017500000000000013244011205015635 5ustar alexxalexxdoublecmd-0.8.2/install/windows/doublecmd.iss0000664000175000017500000001046313243754446020343 0ustar alexxalexx; Script generated by the Inno Setup Script Wizard. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! [Setup] AppName=Double Commander AppVerName=Double Commander 0.8.2 beta AppPublisherURL=http://doublecmd.sourceforge.net AppSupportURL=http://doublecmd.sourceforge.net AppUpdatesURL=http://doublecmd.sourceforge.net DefaultDirName={pf}\Double Commander DefaultGroupName=Double Commander AllowNoIcons=yes LicenseFile=doublecmd\doc\COPYING.txt OutputDir=release Compression=lzma SolidCompression=yes ; "ArchitecturesInstallIn64BitMode=x64" requests that the install be ; done in "64-bit mode" on x64, meaning it should use the native ; 64-bit Program Files directory and the 64-bit view of the registry. ; On all other architectures it will install in "32-bit mode". ArchitecturesInstallIn64BitMode=x64 [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl" Name: "catalan"; MessagesFile: "compiler:Languages\Catalan.isl" Name: "corsican"; MessagesFile: "compiler:Languages\Corsican.isl" Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl" Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl" Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl" Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl" Name: "french"; MessagesFile: "compiler:Languages\French.isl" Name: "german"; MessagesFile: "compiler:Languages\German.isl" Name: "greek"; MessagesFile: "compiler:Languages\Greek.isl" Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl" Name: "hungarian"; MessagesFile: "compiler:Languages\Hungarian.isl" Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl" Name: "nepali"; MessagesFile: "compiler:Languages\Nepali.islu" Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl" Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl" Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl" Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" Name: "serbiancyrillic"; MessagesFile: "compiler:Languages\SerbianCyrillic.isl" Name: "serbianlatin"; MessagesFile: "compiler:Languages\SerbianLatin.isl" Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl" Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl" Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl" [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked [Files] Source: "doublecmd\doublecmd.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "doublecmd\doublecmd.zdli"; DestDir: "{app}"; Flags: ignoreversion Source: "doublecmd\doublecmd.xml"; DestDir: "{app}"; Flags: onlyifdoesntexist Source: "doublecmd\pixmaps.txt"; DestDir: "{app}"; Flags: onlyifdoesntexist Source: "doublecmd\multiarc.ini"; DestDir: "{app}"; Flags: onlyifdoesntexist Source: "doublecmd\doc\*"; DestDir: "{app}\doc"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "doublecmd\language\*"; DestDir: "{app}\language"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "doublecmd\pixmaps\*"; DestDir: "{app}\pixmaps"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "doublecmd\plugins\*"; DestDir: "{app}\plugins"; Flags: ignoreversion recursesubdirs createallsubdirs ; NOTE: Don't use "Flags: ignoreversion" on any shared system files Source: "doublecmd\*.dll"; DestDir: "{app}"; Flags: skipifsourcedoesntexist [Icons] Name: "{group}\Double Commander"; Filename: "{app}\doublecmd.exe" Name: "{group}\{cm:ProgramOnTheWeb,Double Commander}"; Filename: "http://doublecmd.sourceforge.net" Name: "{group}\{cm:UninstallProgram,Double Commander}"; Filename: "{uninstallexe}" Name: "{commondesktop}\Double Commander"; Filename: "{app}\doublecmd.exe"; Tasks: desktopicon Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\Double Commander"; Filename: "{app}\doublecmd.exe"; Tasks: quicklaunchicon [Run] Filename: "{app}\doublecmd.exe"; Description: "{cm:LaunchProgram,Double Commander}"; Flags: nowait postinstall skipifsilent doublecmd-0.8.2/install/windows/install.bat0000664000175000017500000000455313235433350020013 0ustar alexxalexxrem This script run from create_packages.bat rem If you run it direct, set up %BUILD_PACK_DIR% first rem Prepare all installation files set DC_INSTALL_DIR=%BUILD_PACK_DIR%\doublecmd mkdir %DC_INSTALL_DIR% mkdir %DC_INSTALL_DIR%\plugins rem WCX plugins directories mkdir %DC_INSTALL_DIR%\plugins\wcx mkdir %DC_INSTALL_DIR%\plugins\wcx\deb mkdir %DC_INSTALL_DIR%\plugins\wcx\rpm mkdir %DC_INSTALL_DIR%\plugins\wcx\sevenzip mkdir %DC_INSTALL_DIR%\plugins\wcx\unrar mkdir %DC_INSTALL_DIR%\plugins\wcx\zip rem WDX plugins directories mkdir %DC_INSTALL_DIR%\plugins\wdx mkdir %DC_INSTALL_DIR%\plugins\wdx\scripts mkdir %DC_INSTALL_DIR%\plugins\wdx\rpm_wdx mkdir %DC_INSTALL_DIR%\plugins\wdx\deb_wdx mkdir %DC_INSTALL_DIR%\plugins\wdx\audioinfo rem WFX plugins directories mkdir %DC_INSTALL_DIR%\plugins\wfx mkdir %DC_INSTALL_DIR%\plugins\wfx\ftp mkdir %DC_INSTALL_DIR%\doc rem Copy directories xcopy /E language %DC_INSTALL_DIR%\language\ xcopy /E pixmaps %DC_INSTALL_DIR%\pixmaps\ xcopy /E highlighters %DC_INSTALL_DIR%\highlighters\ rem Copy files copy doc\*.txt %DC_INSTALL_DIR%\doc\ copy doublecmd.exe %DC_INSTALL_DIR%\ copy doublecmd.zdli %DC_INSTALL_DIR%\ copy install\windows\doublecmd.xml %DC_INSTALL_DIR%\ copy doublecmd.ext.example %DC_INSTALL_DIR%\ copy pixmaps.txt %DC_INSTALL_DIR%\ copy multiarc.ini %DC_INSTALL_DIR%\ rem Copy libraries copy *.dll %DC_INSTALL_DIR%\ rem copy plugins rem WCX copy plugins\wcx\deb\lib\deb.wcx %DC_INSTALL_DIR%\plugins\wcx\deb\ copy plugins\wcx\rpm\lib\rpm.wcx %DC_INSTALL_DIR%\plugins\wcx\rpm\ copy plugins\wcx\sevenzip\sevenzip.wcx %DC_INSTALL_DIR%\plugins\wcx\sevenzip\ copy plugins\wcx\unrar\lib\unrar.wcx %DC_INSTALL_DIR%\plugins\wcx\unrar\ copy plugins\wcx\zip\zip.wcx %DC_INSTALL_DIR%\plugins\wcx\zip\ rem WDX copy plugins\wdx\rpm_wdx\lib\rpm_wdx.wdx %DC_INSTALL_DIR%\plugins\wdx\rpm_wdx\ copy plugins\wdx\deb_wdx\lib\deb_wdx.wdx %DC_INSTALL_DIR%\plugins\wdx\deb_wdx\ copy plugins\wdx\scripts\* %DC_INSTALL_DIR%\plugins\wdx\scripts\ copy plugins\wdx\audioinfo\audioinfo.wdx %DC_INSTALL_DIR%\plugins\wdx\audioinfo\ rem WFX copy plugins\wfx\ftp\ftp.wfx %DC_INSTALL_DIR%\plugins\wfx\ftp\ doublecmd-0.8.2/install/windows/portable.diff0000664000175000017500000000020111442624410020276 0ustar alexxalexx4c4 < False --- > True doublecmd-0.8.2/install/windows/release/0000775000175000017500000000000013244011205017255 5ustar alexxalexxdoublecmd-0.8.2/install/windows/license.rtf0000664000175000017500000004675012562436721020030 0ustar alexxalexx{\rtf1\ansi\deff0\nouicompat{\fonttbl{\f0\fnil\fcharset0 Courier New;}} {\*\generator Riched20 10.0.10240}\viewkind4\uc1 \pard\f0\fs22\lang1033 GNU GENERAL PUBLIC LICENSE\par Version 2, June 1991\par \par Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\par 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\par Everyone is permitted to copy and distribute verbatim copies\par of this license document, but changing it is not allowed.\par \par Preamble\par \par The licenses for most software are designed to take away your\par freedom to share and change it. By contrast, the GNU General Public\par License is intended to guarantee your freedom to share and change free\par software--to make sure the software is free for all its users. This\par General Public License applies to most of the Free Software\par Foundation's software and to any other program whose authors commit to\par using it. (Some other Free Software Foundation software is covered by\par the GNU Lesser General Public License instead.) You can apply it to\par your programs, too.\par \par When we speak of free software, we are referring to freedom, not\par price. Our General Public Licenses are designed to make sure that you\par have the freedom to distribute copies of free software (and charge for\par this service if you wish), that you receive source code or can get it\par if you want it, that you can change the software or use pieces of it\par in new free programs; and that you know you can do these things.\par \par To protect your rights, we need to make restrictions that forbid\par anyone to deny you these rights or to ask you to surrender the rights.\par These restrictions translate to certain responsibilities for you if you\par distribute copies of the software, or if you modify it.\par \par For example, if you distribute copies of such a program, whether\par gratis or for a fee, you must give the recipients all the rights that\par you have. You must make sure that they, too, receive or can get the\par source code. And you must show them these terms so they know their\par rights.\par \par We protect your rights with two steps: (1) copyright the software, and\par (2) offer you this license which gives you legal permission to copy,\par distribute and/or modify the software.\par \par Also, for each author's protection and ours, we want to make certain\par that everyone understands that there is no warranty for this free\par software. If the software is modified by someone else and passed on, we\par want its recipients to know that what they have is not the original, so\par that any problems introduced by others will not reflect on the original\par authors' reputations.\par \par Finally, any free program is threatened constantly by software\par patents. We wish to avoid the danger that redistributors of a free\par program will individually obtain patent licenses, in effect making the\par program proprietary. To prevent this, we have made it clear that any\par patent must be licensed for everyone's free use or not licensed at all.\par \par The precise terms and conditions for copying, distribution and\par modification follow.\par \par GNU GENERAL PUBLIC LICENSE\par TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\par \par 0. This License applies to any program or other work which contains\par a notice placed by the copyright holder saying it may be distributed\par under the terms of this General Public License. The "Program", below,\par refers to any such program or work, and a "work based on the Program"\par means either the Program or any derivative work under copyright law:\par that is to say, a work containing the Program or a portion of it,\par either verbatim or with modifications and/or translated into another\par language. (Hereinafter, translation is included without limitation in\par the term "modification".) Each licensee is addressed as "you".\par \par Activities other than copying, distribution and modification are not\par covered by this License; they are outside its scope. The act of\par running the Program is not restricted, and the output from the Program\par is covered only if its contents constitute a work based on the\par Program (independent of having been made by running the Program).\par Whether that is true depends on what the Program does.\par \par 1. You may copy and distribute verbatim copies of the Program's\par source code as you receive it, in any medium, provided that you\par conspicuously and appropriately publish on each copy an appropriate\par copyright notice and disclaimer of warranty; keep intact all the\par notices that refer to this License and to the absence of any warranty;\par and give any other recipients of the Program a copy of this License\par along with the Program.\par \par You may charge a fee for the physical act of transferring a copy, and\par you may at your option offer warranty protection in exchange for a fee.\par \par 2. You may modify your copy or copies of the Program or any portion\par of it, thus forming a work based on the Program, and copy and\par distribute such modifications or work under the terms of Section 1\par above, provided that you also meet all of these conditions:\par \par a) You must cause the modified files to carry prominent notices\par stating that you changed the files and the date of any change.\par \par b) You must cause any work that you distribute or publish, that in\par whole or in part contains or is derived from the Program or any\par part thereof, to be licensed as a whole at no charge to all third\par parties under the terms of this License.\par \par c) If the modified program normally reads commands interactively\par when run, you must cause it, when started running for such\par interactive use in the most ordinary way, to print or display an\par announcement including an appropriate copyright notice and a\par notice that there is no warranty (or else, saying that you provide\par a warranty) and that users may redistribute the program under\par these conditions, and telling the user how to view a copy of this\par License. (Exception: if the Program itself is interactive but\par does not normally print such an announcement, your work based on\par the Program is not required to print an announcement.)\par \par These requirements apply to the modified work as a whole. If\par identifiable sections of that work are not derived from the Program,\par and can be reasonably considered independent and separate works in\par themselves, then this License, and its terms, do not apply to those\par sections when you distribute them as separate works. But when you\par distribute the same sections as part of a whole which is a work based\par on the Program, the distribution of the whole must be on the terms of\par this License, whose permissions for other licensees extend to the\par entire whole, and thus to each and every part regardless of who wrote it.\par \par Thus, it is not the intent of this section to claim rights or contest\par your rights to work written entirely by you; rather, the intent is to\par exercise the right to control the distribution of derivative or\par collective works based on the Program.\par \par In addition, mere aggregation of another work not based on the Program\par with the Program (or with a work based on the Program) on a volume of\par a storage or distribution medium does not bring the other work under\par the scope of this License.\par \par 3. You may copy and distribute the Program (or a work based on it,\par under Section 2) in object code or executable form under the terms of\par Sections 1 and 2 above provided that you also do one of the following:\par \par a) Accompany it with the complete corresponding machine-readable\par source code, which must be distributed under the terms of Sections\par 1 and 2 above on a medium customarily used for software interchange; or,\par \par b) Accompany it with a written offer, valid for at least three\par years, to give any third party, for a charge no more than your\par cost of physically performing source distribution, a complete\par machine-readable copy of the corresponding source code, to be\par distributed under the terms of Sections 1 and 2 above on a medium\par customarily used for software interchange; or,\par \par c) Accompany it with the information you received as to the offer\par to distribute corresponding source code. (This alternative is\par allowed only for noncommercial distribution and only if you\par received the program in object code or executable form with such\par an offer, in accord with Subsection b above.)\par \par The source code for a work means the preferred form of the work for\par making modifications to it. For an executable work, complete source\par code means all the source code for all modules it contains, plus any\par associated interface definition files, plus the scripts used to\par control compilation and installation of the executable. However, as a\par special exception, the source code distributed need not include\par anything that is normally distributed (in either source or binary\par form) with the major components (compiler, kernel, and so on) of the\par operating system on which the executable runs, unless that component\par itself accompanies the executable.\par \par If distribution of executable or object code is made by offering\par access to copy from a designated place, then offering equivalent\par access to copy the source code from the same place counts as\par distribution of the source code, even though third parties are not\par compelled to copy the source along with the object code.\par \par 4. You may not copy, modify, sublicense, or distribute the Program\par except as expressly provided under this License. Any attempt\par otherwise to copy, modify, sublicense or distribute the Program is\par void, and will automatically terminate your rights under this License.\par However, parties who have received copies, or rights, from you under\par this License will not have their licenses terminated so long as such\par parties remain in full compliance.\par \par 5. You are not required to accept this License, since you have not\par signed it. However, nothing else grants you permission to modify or\par distribute the Program or its derivative works. These actions are\par prohibited by law if you do not accept this License. Therefore, by\par modifying or distributing the Program (or any work based on the\par Program), you indicate your acceptance of this License to do so, and\par all its terms and conditions for copying, distributing or modifying\par the Program or works based on it.\par \par 6. Each time you redistribute the Program (or any work based on the\par Program), the recipient automatically receives a license from the\par original licensor to copy, distribute or modify the Program subject to\par these terms and conditions. You may not impose any further\par restrictions on the recipients' exercise of the rights granted herein.\par You are not responsible for enforcing compliance by third parties to\par this License.\par \par 7. If, as a consequence of a court judgment or allegation of patent\par infringement or for any other reason (not limited to patent issues),\par conditions are imposed on you (whether by court order, agreement or\par otherwise) that contradict the conditions of this License, they do not\par excuse you from the conditions of this License. If you cannot\par distribute so as to satisfy simultaneously your obligations under this\par License and any other pertinent obligations, then as a consequence you\par may not distribute the Program at all. For example, if a patent\par license would not permit royalty-free redistribution of the Program by\par all those who receive copies directly or indirectly through you, then\par the only way you could satisfy both it and this License would be to\par refrain entirely from distribution of the Program.\par \par If any portion of this section is held invalid or unenforceable under\par any particular circumstance, the balance of the section is intended to\par apply and the section as a whole is intended to apply in other\par circumstances.\par \par It is not the purpose of this section to induce you to infringe any\par patents or other property right claims or to contest validity of any\par such claims; this section has the sole purpose of protecting the\par integrity of the free software distribution system, which is\par implemented by public license practices. Many people have made\par generous contributions to the wide range of software distributed\par through that system in reliance on consistent application of that\par system; it is up to the author/donor to decide if he or she is willing\par to distribute software through any other system and a licensee cannot\par impose that choice.\par \par This section is intended to make thoroughly clear what is believed to\par be a consequence of the rest of this License.\par \par 8. If the distribution and/or use of the Program is restricted in\par certain countries either by patents or by copyrighted interfaces, the\par original copyright holder who places the Program under this License\par may add an explicit geographical distribution limitation excluding\par those countries, so that distribution is permitted only in or among\par countries not thus excluded. In such case, this License incorporates\par the limitation as if written in the body of this License.\par \par 9. The Free Software Foundation may publish revised and/or new versions\par of the General Public License from time to time. Such new versions will\par be similar in spirit to the present version, but may differ in detail to\par address new problems or concerns.\par \par Each version is given a distinguishing version number. If the Program\par specifies a version number of this License which applies to it and "any\par later version", you have the option of following the terms and conditions\par either of that version or of any later version published by the Free\par Software Foundation. If the Program does not specify a version number of\par this License, you may choose any version ever published by the Free Software\par Foundation.\par \par 10. If you wish to incorporate parts of the Program into other free\par programs whose distribution conditions are different, write to the author\par to ask for permission. For software which is copyrighted by the Free\par Software Foundation, write to the Free Software Foundation; we sometimes\par make exceptions for this. Our decision will be guided by the two goals\par of preserving the free status of all derivatives of our free software and\par of promoting the sharing and reuse of software generally.\par \par NO WARRANTY\par \par 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\par FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\par OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\par PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\par OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\par MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\par TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\par PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\par REPAIR OR CORRECTION.\par \par 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\par WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\par REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\par INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\par OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\par TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\par YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\par PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\par POSSIBILITY OF SUCH DAMAGES.\par \par END OF TERMS AND CONDITIONS\par \par How to Apply These Terms to Your New Programs\par \par If you develop a new program, and you want it to be of the greatest\par possible use to the public, the best way to achieve this is to make it\par free software which everyone can redistribute and change under these terms.\par \par To do so, attach the following notices to the program. It is safest\par to attach them to the start of each source file to most effectively\par convey the exclusion of warranty; and each file should have at least\par the "copyright" line and a pointer to where the full notice is found.\par \par \par Copyright (C) \par \par This program is free software; you can redistribute it and/or modify\par it under the terms of the GNU General Public License as published by\par the Free Software Foundation; either version 2 of the License, or\par (at your option) any later version.\par \par This program is distributed in the hope that it will be useful,\par but WITHOUT ANY WARRANTY; without even the implied warranty of\par MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\par GNU General Public License for more details.\par \par You should have received a copy of the GNU General Public License along\par with this program; if not, write to the Free Software Foundation, Inc.,\par 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\par \par Also add information on how to contact you by electronic and paper mail.\par \par If the program is interactive, make it output a short notice like this\par when it starts in an interactive mode:\par \par Gnomovision version 69, Copyright (C) year name of author\par Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\par This is free software, and you are welcome to redistribute it\par under certain conditions; type `show c' for details.\par \par The hypothetical commands `show w' and `show c' should show the appropriate\par parts of the General Public License. Of course, the commands you use may\par be called something other than `show w' and `show c'; they could even be\par mouse-clicks or menu items--whatever suits your program.\par \par You should also get your employer (if you work as a programmer) or your\par school, if any, to sign a "copyright disclaimer" for the program, if\par necessary. Here is a sample; alter the names:\par \par Yoyodyne, Inc., hereby disclaims all copyright interest in the program\par `Gnomovision' (which makes passes at compilers) written by James Hacker.\par \par , 1 April 1989\par Ty Coon, President of Vice\par \par This General Public License does not permit incorporating your program into\par proprietary programs. If your program is a subroutine library, you may\par consider it more useful to permit linking proprietary applications with the\par library. If this is what you want to do, use the GNU Lesser General\par Public License instead of this License.\par \par } doublecmd-0.8.2/install/windows/doublecmd.xml0000664000175000017500000000115112562442777020343 0ustar alexxalexx False Pascal sources *.pas;*.pp 32768 Pascal binaries *.ppu;*.o;*.dcu 16711680 doublecmd-0.8.2/install/windows/doublecmd.wxs0000664000175000017500000000516712564066701020366 0ustar alexxalexx NOT NEWERVERSIONDETECTED doublecmd-0.8.2/install/windows/install-help.bat0000664000175000017500000000055611610361336020737 0ustar alexxalexxrem This script run from create_packages.bat rem If you run it direct, set up %BUILD_PACK_DIR% first set DC_HELP_INSTALL_DIR=%BUILD_PACK_DIR%\doublecmd\doc rem Clean help directory rm -rf %DC_HELP_INSTALL_DIR%\ rem Copy Russian help files xcopy /E doc\ru %DC_HELP_INSTALL_DIR%\ru\ rem Copy Ukrainian help files xcopy /E doc\uk %DC_HELP_INSTALL_DIR%\uk\doublecmd-0.8.2/install/windows/lib/0000775000175000017500000000000013244011205016403 5ustar alexxalexxdoublecmd-0.8.2/install/windows/lib/i386/0000775000175000017500000000000013244011205017074 5ustar alexxalexxdoublecmd-0.8.2/install/windows/lib/readme.txt0000664000175000017500000000021312014201074020374 0ustar alexxalexxBefore create packages (before run create_packages.bat) copy in this directory third-party libraries: - unrar.dll - needed for unrar plugindoublecmd-0.8.2/install/windows/lib/x86_64/0000775000175000017500000000000013244011205017341 5ustar alexxalexxdoublecmd-0.8.2/install/windows/convert-zip-msi.bat0000664000175000017500000000335412562443722021417 0ustar alexxalexx@echo off rem This script converts portable *.zip package to *.msi package rem Check command arguments if "%1" == "" ( echo. echo Syntax: echo. echo %~nx0 ^ goto :eof ) rem Path to Windows Installer XML (WiX) toolset set PATH=%PATH%;"C:\Program Files (x86)\WiX Toolset v3.9\bin" rem The new package will be created from here set BUILD_PACK_DIR=%TEMP%\doublecmd-%DATE: =% rem The new package will be saved here set PACK_DIR=%~dp0/release rem Determine package file name for /f %%i in ("%1") do set PACKAGE=%%~ni rem Get package version and architecture for /f "tokens=1,2,3,4,5 delims=-." %%a in ("%PACKAGE%") do ( set DC_VER=%%b.%%c.%%d set CPU_TARGET=%%e ) rem Prepare needed variables if "%CPU_TARGET%" == "i386" ( set CPU_TARGET=x86 set PF=ProgramFilesFolder ) else if "%CPU_TARGET%" == "x86_64" ( set CPU_TARGET=x64 set PF=ProgramFiles64Folder ) rem Prepare package build dir mkdir %BUILD_PACK_DIR% rem Extract archive unzip %1 -d %BUILD_PACK_DIR% rem Copy needed files copy license.rtf %BUILD_PACK_DIR%\ copy doublecmd.wxs %BUILD_PACK_DIR%\ copy ..\..\src\doublecmd.ico %BUILD_PACK_DIR%\ pushd %BUILD_PACK_DIR% del /Q doublecmd\doublecmd.xml move doublecmd "Double Commander" heat dir "Double Commander" -ag -cg HeatGroup -dr %PF% -var var.SourcePath -o include.wxs candle -arch %CPU_TARGET% -dProductVersion=%DC_VER% -dSourcePath="Double Commander" -dProgramFiles=%PF% doublecmd.wxs include.wxs light -ext WixUIExtension -cultures:en-us include.wixobj doublecmd.wixobj -o %PACKAGE%.msi rem Move created package move %PACKAGE%.msi %PACK_DIR%/ rem Clean temp directories popd rmdir /S /Q %BUILD_PACK_DIR% doublecmd-0.8.2/install/create_packages.sh0000775000175000017500000001012113243754446017622 0ustar alexxalexx#!/bin/sh # Set Double Commander version DC_VER=0.8.2 # The new package will be saved here PACK_DIR=$(pwd)/linux/release # Temp dir for creating *.tar.bz2 package BUILD_PACK_DIR=/var/tmp/doublecmd-$(date +%y.%m.%d) # Create temp dir for building BUILD_DC_TMP_DIR=/var/tmp/doublecmd-$DC_VER help() { echo 'Usage: create_packages.sh [options]' echo echo "Options:" echo '-A: All packages (by default)' echo '-D: Debian package' echo '-R: RPM package' echo '-S: Slackware package' echo '-P: Portable package' echo '-H: Help package' echo '--cpu=: Target CPU' echo '--ws=: Target widgetset' echo exit 1 } # Parse input parameters CKNAME=$(basename "$0") args=$(getopt -n $CKNAME -o ADRSPHh -l cpu:,ws:,help,default -- "$@") eval set -- $args while [ "$1" != "--" ]; do case "$1" in -h|--help) help;; -A) shift;CK_DEBIAN=1;CK_REDHAT=1;CK_SLACKWARE=1;CK_PORTABLE=1;CK_HELP=1;; -D) shift;CK_DEBIAN=1;; -R) shift;CK_REDHAT=1;; -S) shift;CK_SLACKWARE=1;; -P) shift;CK_PORTABLE=1;; -H) shift;CK_HELP=1;; --cpu) shift;export CPU_TARGET=$(eval echo $1);shift;; --ws) shift;export lcl=$(eval echo $1);shift;; esac done if [ -z "$CK_DEBIAN" ] && [ -z "$CK_REDHAT" ] && [ -z "$CK_SLACKWARE" ] && [ -z "$CK_PORTABLE" ] && [ -z "$CK_HELP" ]; then CK_DEBIAN=1 CK_REDHAT=1 CK_SLACKWARE=1 CK_PORTABLE=1 CK_HELP=1 fi # Export from SVN rm -rf $BUILD_DC_TMP_DIR svn export ../ $BUILD_DC_TMP_DIR # Update revision number linux/update-revision.sh ../ $BUILD_DC_TMP_DIR # Copy package description file cp linux/description-pak $BUILD_DC_TMP_DIR/ # Set widgetset if [ -z $lcl ]; then export lcl=gtk2 fi # Set processor architecture if [ -z $CPU_TARGET ]; then export CPU_TARGET=$(fpc -iTP) fi # Debian package architecture if [ "$CPU_TARGET" = "x86_64" ] then export DEB_ARCH="amd64" else export DEB_ARCH=$CPU_TARGET fi # Copy libraries cp -a linux/lib/$CPU_TARGET/*.so* $BUILD_DC_TMP_DIR/ cp -a linux/lib/$CPU_TARGET/$lcl/*.so* $BUILD_DC_TMP_DIR/ cd $BUILD_DC_TMP_DIR # Build all components of Double Commander ./build.sh beta # Export variables for checkinstall export MAINTAINER="Alexander Koblov " if [ "$CK_REDHAT" ]; then # Create *.rpm package checkinstall -R --default --pkgname=doublecmd --pkgversion=$DC_VER --pkgarch=$CPU_TARGET --pkgrelease=1.$lcl --pkglicense=GPL --pkggroup=Applications/File --nodoc --pakdir=$PACK_DIR $BUILD_DC_TMP_DIR/install/linux/install.sh fi if [ "$CK_DEBIAN" ]; then # Create *.deb package checkinstall -D --default --pkgname=doublecmd --pkgversion=$DC_VER --pkgarch=$DEB_ARCH --pkgrelease=1.$lcl --pkglicense=GPL --pkggroup=contrib/misc --requires=libx11-6 --nodoc --pakdir=$PACK_DIR $BUILD_DC_TMP_DIR/install/linux/install.sh fi if [ "$CK_SLACKWARE" ]; then # Create *.tgz package checkinstall -S --default --pkgname=doublecmd --pkgversion=$DC_VER --pkgarch=$CPU_TARGET --pkgrelease=1.$lcl --pkglicense=GPL --pkggroup=Applications/File --nodoc --pakdir=$PACK_DIR $BUILD_DC_TMP_DIR/install/linux/install.sh fi if [ "$CK_PORTABLE" ]; then # Create *.tar.bz2 package mkdir -p $BUILD_PACK_DIR install/linux/install.sh --portable-prefix=$BUILD_PACK_DIR cp -r doc/en $BUILD_PACK_DIR/doublecmd/doc cd $BUILD_PACK_DIR sed -i -e 's/False/True/' doublecmd/doublecmd.xml tar -cJvf $PACK_DIR/doublecmd-$DC_VER.$lcl.$CPU_TARGET.tar.xz doublecmd fi if [ "$CK_HELP" ]; then # Create help packages cd $BUILD_DC_TMP_DIR # Copy help files install/linux/install-help.sh --portable-prefix=$BUILD_PACK_DIR # Create help package for each language cd $BUILD_PACK_DIR/doublecmd/doc for HELP_LANG in `ls` do cd $BUILD_PACK_DIR/doublecmd tar -cJvf $PACK_DIR/doublecmd-help-$HELP_LANG-$DC_VER.noarch.tar.xz doc/$HELP_LANG done fi # Clean DC build dir rm -rf $BUILD_DC_TMP_DIR rm -rf $BUILD_PACK_DIR doublecmd-0.8.2/install/darwin/0000775000175000017500000000000013244011205015427 5ustar alexxalexxdoublecmd-0.8.2/install/darwin/qt4/0000775000175000017500000000000013244011205016137 5ustar alexxalexxdoublecmd-0.8.2/install/darwin/qt4/qt4pas.patch0000664000175000017500000001150612454266763020426 0ustar alexxalexxIndex: Qt4Pas.pro =================================================================== --- Qt4Pas.pro (revision 1) +++ Qt4Pas.pro (working copy) @@ -12,7 +12,6 @@ VERSION = 5.2.5 -QT += network webkit TARGET = Qt4Pas TEMPLATE = lib DEPENDPATH += src @@ -155,21 +154,7 @@ qprintdialog_hook.h \ qprintpreviewdialog_hook.h \ qsystemtrayicon_hook.h \ - qgraphicsscene_hook.h \ - qabstractsocket_hook.h \ - qudpsocket_hook.h \ - qtcpsocket_hook.h \ - qtcpserver_hook.h \ - qnetworkaccessmanager_hook.h \ - qnetworkreply_hook.h \ - qwebframe_hook.h \ - qwebsecurityorigin_hook.h \ - qwebdatabase_hook.h \ - qwebhistory_hook.h \ - qwebhistoryinterface_hook.h \ - qwebpage_hook.h \ - qwebsettings_hook.h \ - qwebview_hook.h + qgraphicsscene_hook.h SOURCES += qt4pas.cpp \ qobject_hook_c.cpp \ @@ -335,32 +320,6 @@ qstylefactory_c.cpp \ qgraphicsscene_c.cpp \ qgraphicsview_c.cpp \ - qsslcipher_c.cpp \ - qsslkey_c.cpp \ - qsslerror_c.cpp \ - qabstractsocket_c.cpp \ - qudpsocket_c.cpp \ - qtcpsocket_c.cpp \ - qtcpserver_c.cpp \ - qsslconfiguration_c.cpp \ - qsslsocket_c.cpp \ - qnetworkaccessmanager_c.cpp \ - qnetworkrequest_c.cpp \ - qnetworkreply_c.cpp \ - qnetworkcookie_c.cpp \ - qlclnetworkcookie_c.cpp \ - qnetworkproxy_c.cpp \ - qauthenticator_c.cpp \ - qwebframe_c.cpp \ - qwebsecurityorigin_c.cpp \ - qwebdatabase_c.cpp \ - qwebhistory_c.cpp \ - qwebhistoryinterface_c.cpp \ - qwebpage_c.cpp \ - qlclwebpage_c.cpp \ - qwebsettings_c.cpp \ - qwebview_c.cpp \ - qlclwebview_c.cpp \ qcoreapplication_hook_c.cpp \ qtimer_hook_c.cpp \ qabstractitemmodel_hook_c.cpp \ @@ -434,20 +393,6 @@ qprintdialog_hook_c.cpp \ qprintpreviewdialog_hook_c.cpp \ qsystemtrayicon_hook_c.cpp \ - qgraphicsscene_hook_c.cpp \ - qabstractsocket_hook_c.cpp \ - qudpsocket_hook_c.cpp \ - qtcpsocket_hook_c.cpp \ - qtcpserver_hook_c.cpp \ - qnetworkaccessmanager_hook_c.cpp \ - qnetworkreply_hook_c.cpp \ - qwebframe_hook_c.cpp \ - qwebsecurityorigin_hook_c.cpp \ - qwebdatabase_hook_c.cpp \ - qwebhistory_hook_c.cpp \ - qwebhistoryinterface_hook_c.cpp \ - qwebpage_hook_c.cpp \ - qwebsettings_hook_c.cpp \ - qwebview_hook_c.cpp + qgraphicsscene_hook_c.cpp # end of file \ No newline at end of file Index: src/qt4pas.cpp =================================================================== --- src/qt4pas.cpp (revision 1) +++ src/qt4pas.cpp (working copy) @@ -15,8 +15,6 @@ #include #include -#include -#include #include "qobject_hook_c.cpp" @@ -182,32 +180,6 @@ #include "qstylefactory_c.cpp" #include "qgraphicsscene_c.cpp" #include "qgraphicsview_c.cpp" -#include "qsslcipher_c.cpp" -#include "qsslkey_c.cpp" -#include "qsslerror_c.cpp" -#include "qabstractsocket_c.cpp" -#include "qudpsocket_c.cpp" -#include "qtcpsocket_c.cpp" -#include "qtcpserver_c.cpp" -#include "qsslconfiguration_c.cpp" -#include "qsslsocket_c.cpp" -#include "qnetworkaccessmanager_c.cpp" -#include "qnetworkrequest_c.cpp" -#include "qnetworkreply_c.cpp" -#include "qnetworkcookie_c.cpp" -#include "qlclnetworkcookie_c.cpp" -#include "qnetworkproxy_c.cpp" -#include "qauthenticator_c.cpp" -#include "qwebframe_c.cpp" -#include "qwebsecurityorigin_c.cpp" -#include "qwebdatabase_c.cpp" -#include "qwebhistory_c.cpp" -#include "qwebhistoryinterface_c.cpp" -#include "qwebpage_c.cpp" -#include "qlclwebpage_c.cpp" -#include "qwebsettings_c.cpp" -#include "qwebview_c.cpp" -#include "qlclwebview_c.cpp" #include "qcoreapplication_hook_c.cpp" #include "qtimer_hook_c.cpp" #include "qabstractitemmodel_hook_c.cpp" @@ -282,17 +254,3 @@ #include "qprintpreviewdialog_hook_c.cpp" #include "qsystemtrayicon_hook_c.cpp" #include "qgraphicsscene_hook_c.cpp" -#include "qabstractsocket_hook_c.cpp" -#include "qudpsocket_hook_c.cpp" -#include "qtcpsocket_hook_c.cpp" -#include "qtcpserver_hook_c.cpp" -#include "qnetworkaccessmanager_hook_c.cpp" -#include "qnetworkreply_hook_c.cpp" -#include "qwebframe_hook_c.cpp" -#include "qwebsecurityorigin_hook_c.cpp" -#include "qwebdatabase_hook_c.cpp" -#include "qwebhistory_hook_c.cpp" -#include "qwebhistoryinterface_hook_c.cpp" -#include "qwebpage_hook_c.cpp" -#include "qwebsettings_hook_c.cpp" -#include "qwebview_hook_c.cpp" doublecmd-0.8.2/install/darwin/qt4/lcl.patch0000664000175000017500000000641312632341440017745 0ustar alexxalexxIndex: interfaces/qt/qt45.pas =================================================================== --- interfaces/qt/qt45.pas (revision 47328) +++ interfaces/qt/qt45.pas (working copy) @@ -12411,7 +12411,7 @@ procedure QGraphicsView_invalidateScene(handle: QGraphicsViewH; rect: QRectFH = nil; layers: QGraphicsSceneSceneLayers = QGraphicsSceneAllLayers); cdecl; external Qt4PasLib name 'QGraphicsView_invalidateScene'; procedure QGraphicsView_updateSceneRect(handle: QGraphicsViewH; rect: QRectFH); cdecl; external Qt4PasLib name 'QGraphicsView_updateSceneRect'; - +{ type QSslKeyType = ( // QSsl::KeyType (1) QSslPrivateKey, QSslPublicKey ); @@ -13284,7 +13284,7 @@ function QLCLWebView_create(parent: QWidgetH = nil): QLCLWebViewH; cdecl; external Qt4PasLib name 'QLCLWebView_create'; procedure QLCLWebView_destroy(handle: QLCLWebViewH); cdecl; external Qt4PasLib name 'QLCLWebView_destroy'; procedure QLCLWebView_override_createWindow(handle: QLCLWebViewH; hook: QLCLWebView_createWindow_Override); cdecl; external Qt4PasLib name 'QLCLWebView_override_createWindow'; - +} function QCoreApplication_hook_create(handle: QObjectH): QCoreApplication_hookH; cdecl; external Qt4PasLib name 'QCoreApplication_hook_create'; procedure QCoreApplication_hook_destroy(handle: QCoreApplication_hookH); cdecl; external Qt4PasLib name 'QCoreApplication_hook_destroy'; procedure QCoreApplication_hook_hook_aboutToQuit(handle: QCoreApplication_hookH; hook: QCoreApplication_aboutToQuit_Event); cdecl; external Qt4PasLib name 'QCoreApplication_hook_hook_aboutToQuit'; @@ -13797,7 +13797,7 @@ procedure QGraphicsScene_hook_destroy(handle: QGraphicsScene_hookH); cdecl; external Qt4PasLib name 'QGraphicsScene_hook_destroy'; procedure QGraphicsScene_hook_hook_sceneRectChanged(handle: QGraphicsScene_hookH; hook: QGraphicsScene_sceneRectChanged_Event); cdecl; external Qt4PasLib name 'QGraphicsScene_hook_hook_sceneRectChanged'; procedure QGraphicsScene_hook_hook_selectionChanged(handle: QGraphicsScene_hookH; hook: QGraphicsScene_selectionChanged_Event); cdecl; external Qt4PasLib name 'QGraphicsScene_hook_hook_selectionChanged'; - +{ function QAbstractSocket_hook_create(handle: QObjectH): QAbstractSocket_hookH; cdecl; external Qt4PasLib name 'QAbstractSocket_hook_create'; procedure QAbstractSocket_hook_destroy(handle: QAbstractSocket_hookH); cdecl; external Qt4PasLib name 'QAbstractSocket_hook_destroy'; procedure QAbstractSocket_hook_hook_hostFound(handle: QAbstractSocket_hookH; hook: QAbstractSocket_hostFound_Event); cdecl; external Qt4PasLib name 'QAbstractSocket_hook_hook_hostFound'; @@ -13898,9 +13898,9 @@ procedure QWebView_hook_hook_selectionChanged(handle: QWebView_hookH; hook: QWebView_selectionChanged_Event); cdecl; external Qt4PasLib name 'QWebView_hook_hook_selectionChanged'; procedure QWebView_hook_hook_iconChanged(handle: QWebView_hookH; hook: QWebView_iconChanged_Event); cdecl; external Qt4PasLib name 'QWebView_hook_hook_iconChanged'; procedure QWebView_hook_hook_urlChanged(handle: QWebView_hookH; hook: QWebView_urlChanged_Event); cdecl; external Qt4PasLib name 'QWebView_hook_hook_urlChanged'; +} - //======================================================= // Dynamic Qt Version //======================================================= doublecmd-0.8.2/install/darwin/release/0000775000175000017500000000000013244011205017047 5ustar alexxalexxdoublecmd-0.8.2/install/darwin/doublecmd.xml0000664000175000017500000000225012562442777020136 0ustar alexxalexx False False True Pascal sources *.pas;*.pp 32768 Pascal binaries *.ppu;*.o;*.dcu 16711680 Specified Executables * 55758 -rwxrwxr*x Executables * 32768 -*x* 32 True doublecmd-0.8.2/install/darwin/install.sh0000775000175000017500000000474213235433350017454 0ustar alexxalexx#!/bin/bash # Set processor architecture if [ -z $CPU_TARGET ]; then export CPU_TARGET=$(fpc -iTP) fi export DC_APP_DIR=$1/doublecmd.app export DC_INSTALL_DIR=$DC_APP_DIR/Contents/MacOS mkdir -p $DC_INSTALL_DIR mkdir -p $DC_INSTALL_DIR/plugins # WCX plugins directories mkdir -p $DC_INSTALL_DIR/plugins/wcx mkdir -p $DC_INSTALL_DIR/plugins/wcx/cpio mkdir -p $DC_INSTALL_DIR/plugins/wcx/deb mkdir -p $DC_INSTALL_DIR/plugins/wcx/rpm mkdir -p $DC_INSTALL_DIR/plugins/wcx/unrar mkdir -p $DC_INSTALL_DIR/plugins/wcx/zip # WDX plugins directories mkdir -p $DC_INSTALL_DIR/plugins/wdx mkdir -p $DC_INSTALL_DIR/plugins/wdx/scripts mkdir -p $DC_INSTALL_DIR/plugins/wdx/rpm_wdx mkdir -p $DC_INSTALL_DIR/plugins/wdx/deb_wdx mkdir -p $DC_INSTALL_DIR/plugins/wdx/audioinfo # WFX plugins directories mkdir -p $DC_INSTALL_DIR/plugins/wfx mkdir -p $DC_INSTALL_DIR/plugins/wfx/ftp # Copy files cp -r doublecmd.app/* $DC_APP_DIR/ cp -a doublecmd $DC_INSTALL_DIR/ cp -a doublecmd.zdli $DC_INSTALL_DIR/ cp -a install/darwin/doublecmd.xml $DC_INSTALL_DIR/ cp -a doublecmd.ext.example $DC_INSTALL_DIR/ cp -a pixmaps.txt $DC_INSTALL_DIR/ cp -a multiarc.ini $DC_INSTALL_DIR/ # Copy plugins # WCX install -m 644 plugins/wcx/cpio/lib/cpio.wcx $DC_INSTALL_DIR/plugins/wcx/cpio/ install -m 644 plugins/wcx/deb/lib/deb.wcx $DC_INSTALL_DIR/plugins/wcx/deb/ install -m 644 plugins/wcx/rpm/lib/rpm.wcx $DC_INSTALL_DIR/plugins/wcx/rpm/ install -m 644 plugins/wcx/unrar/lib/unrar.wcx $DC_INSTALL_DIR/plugins/wcx/unrar/ install -m 644 plugins/wcx/zip/zip.wcx $DC_INSTALL_DIR/plugins/wcx/zip/ # WDX install -m 644 plugins/wdx/rpm_wdx/lib/rpm_wdx.wdx $DC_INSTALL_DIR/plugins/wdx/rpm_wdx/ install -m 644 plugins/wdx/deb_wdx/lib/deb_wdx.wdx $DC_INSTALL_DIR/plugins/wdx/deb_wdx/ install -m 644 plugins/wdx/scripts/* $DC_INSTALL_DIR/plugins/wdx/scripts/ install -m 644 plugins/wdx/audioinfo/audioinfo.wdx $DC_INSTALL_DIR/plugins/wdx/audioinfo/ # WFX install -m 644 plugins/wfx/ftp/ftp.wfx $DC_INSTALL_DIR/plugins/wfx/ftp/ # Copy documentation mkdir -p $DC_INSTALL_DIR/doc cp -a doc/*.txt $DC_INSTALL_DIR/doc/ # Copy scripts mkdir -p $DC_INSTALL_DIR/scripts cp -a scripts/terminal.sh $DC_INSTALL_DIR/scripts/ # Copy directories cp -r language $DC_INSTALL_DIR/ cp -r pixmaps $DC_INSTALL_DIR/ cp -r highlighters $DC_INSTALL_DIR/ # Copy libraries cp -a *.dylib $DC_INSTALL_DIR/ doublecmd-0.8.2/install/darwin/make-unrar.sh0000775000175000017500000000135012217301130020025 0ustar alexxalexx#!/bin/sh # Show help if [ -z $1 ]; then echo echo "Script for build unrar library" echo echo "Syntax:" echo echo "make-unrar.sh " echo exit 0 fi # Save destination directory DEST_DIR=$(pwd)/lib # Set minimal Mac OS X target version export MACOSX_DEPLOYMENT_TARGET=10.5 # Go to unrar source directory cd $1 # Build 32 bit library rm -f $DEST_DIR/i386/libunrar.dylib make clean lib CXXFLAGS+="-fPIC -DSILENT -m32" LDFLAGS+="-dylib -arch i386" STRIP=true mv libunrar.so $DEST_DIR/i386/libunrar.dylib # Build 64 bit library rm -f $DEST_DIR/x86_64/libunrar.dylib make clean lib CXXFLAGS+="-fPIC -DSILENT -m64" LDFLAGS+="-dylib -arch x86_64" STRIP=true mv libunrar.so $DEST_DIR/x86_64/libunrar.dylib doublecmd-0.8.2/install/darwin/lib/0000775000175000017500000000000013244011205016175 5ustar alexxalexxdoublecmd-0.8.2/install/darwin/lib/i386/0000775000175000017500000000000013244011205016666 5ustar alexxalexxdoublecmd-0.8.2/install/darwin/lib/readme.txt0000664000175000017500000000022012014201074020164 0ustar alexxalexxBefore create packages (before run create_packages.mac) copy in this directory third-party libraries: - libunrar.dylib - needed for unrar plugindoublecmd-0.8.2/install/darwin/lib/x86_64/0000775000175000017500000000000013244011205017133 5ustar alexxalexxdoublecmd-0.8.2/install/create_packages.mac0000775000175000017500000000332613243754446017761 0ustar alexxalexx#!/bin/sh # Set Double Commander version DC_VER=0.8.2 # The new package will be saved here PACK_DIR=$(pwd)/darwin/release # Temp dir for creating *.dmg package BUILD_PACK_DIR=/var/tmp/doublecmd-$(date +%y.%m.%d) # Create temp dir for building BUILD_DC_TMP_DIR=/var/tmp/doublecmd-$DC_VER # Export from SVN rm -rf $BUILD_DC_TMP_DIR svn export ../ $BUILD_DC_TMP_DIR # Save revision number DC_REVISION=$(linux/update-revision.sh ../ $BUILD_DC_TMP_DIR) # Set processor architecture if [ -z $CPU_TARGET ]; then export CPU_TARGET=$(fpc -iTP) fi # Set widgetset if [ -z $lcl ]; then # Use Qt4 when build 64 bit if [ "$CPU_TARGET" = "x86_64" ] then export lcl=qt else export lcl=carbon fi fi # Set minimal Mac OS X target version export MACOSX_DEPLOYMENT_TARGET=10.5 # Copy libraries cp -a darwin/lib/$CPU_TARGET/*.dylib $BUILD_DC_TMP_DIR/ cp -a darwin/lib/$CPU_TARGET/$lcl/*.dylib $BUILD_DC_TMP_DIR/ cd $BUILD_DC_TMP_DIR # Build all components of Double Commander ./build.sh beta # Update application bundle version defaults write $(pwd)/doublecmd.app/Contents/Info CFBundleVersion $DC_REVISION defaults write $(pwd)/doublecmd.app/Contents/Info CFBundleShortVersionString $DC_VER plutil -convert xml1 $(pwd)/doublecmd.app/Contents/Info.plist # Create *.dmg package mkdir -p $BUILD_PACK_DIR install/darwin/install.sh $BUILD_PACK_DIR cd $BUILD_PACK_DIR if [ "$lcl" = "qt" ]; then macdeployqt doublecmd.app fi mv doublecmd.app 'Double Commander.app' hdiutil create -anyowners -volname "Double Commander" -imagekey zlib-level=9 -format UDZO -srcfolder 'Double Commander.app' $PACK_DIR/doublecmd-$DC_VER-$DC_REVISION.$lcl.$CPU_TARGET.dmg # Clean DC build dir rm -rf $BUILD_DC_TMP_DIR rm -rf $BUILD_PACK_DIR doublecmd-0.8.2/doublecmd-noconsole.js0000664000175000017500000000145611525751770017016 0ustar alexxalexx// Use this script to run Double Commander without console debug window // run as logged-in user: // First get the path of this script var script_path = WScript.ScriptFullName; script_path = script_path.substring(0, script_path.lastIndexOf('\\')); var shell = WScript.CreateObject("WScript.Shell"); // Then launch dc(DoubleCommander directory is supposed to be placed besides this script) shell.run("\"" + script_path + "\\doublecmd.exe\"", 0, false); /* // or this one asks for the desired user: var script_path = WScript.ScriptFullName; script_path = script_path.substring(0, script_path.lastIndexOf('\\')); var shell = WScript.CreateObject("WScript.Shell"); var app = WScript.CreateObject("Shell.Application"); app.ShellExecute(script_path + "\\doublecmd.exe", "", "", "runas", 0); */doublecmd-0.8.2/pixmaps/0000775000175000017500000000000013244011205014156 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/folder-link-broken_src.ico0000664000175000017500000001652611361045050021222 0ustar alexxalexx  6  h( @ fddcbba`a_ __ b a a ` _ ^ _ _ ^ ^ ] ^ ] ] \ \ [rT}FlQ{~|wvtqnlifda^[ \rwFv1YPhrxw}|zxwusrpnmkjhg^ \ra"I@b|zyw}|zxvusrpnmkih_ \rT-^+~}{y~|{ywvusqonmjia \r/fZ~~|zywutrpomljc \s6a 05h}{yxwutrpnlke \s68@3gw~|{yxvusqomlh \s6fHow~|{ywutrqomi \sBfWmk4cw}|zxvutrpnk \s>f+jV'z?f4c|!!{z!!tsrpm \s=f"[0k+T:eK4c|!!|z!!vtrqn \s4eZW5e7e>f>f>f;fCK4c{!!}|!!wvtrq \s1X/T@fTQQQQU\E@B4cz!!!!zxwutr \s?f5eTTUQTYL@BB4c|{yxvtu \ss?] ??doublecmd-0.8.2/pixmaps/cursors/ArrowCopy.cur0000664000175000017500000000427612512434150020334 0ustar alexxalexx ( @~> ????doublecmd-0.8.2/pixmaps/cursors/ArrowMove.cur0000664000175000017500000000427612512434150020330 0ustar alexxalexx ( @r~> ???doublecmd-0.8.2/pixmaps/dctheme/0000775000175000017500000000000013244011205015567 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/16x16/0000775000175000017500000000000013244011205016354 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/16x16/apps/0000775000175000017500000000000013244011205017317 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/16x16/apps/utilities-terminal.png0000664000175000017500000000123411323355446023667 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME %F)IDAT8}KTQ?w|3*dA W\E6jA`6JEb-%¢4P#+}_gF-s?{稡81Tbl9qgzǏMzN3uOޱ^,_7O[̦N?M$m=)/!"xqxIyAὣB?BDyYὔ@my uZ465$x%@lח 7 8vD3 y9K!Im&J%x!ë7/Gam~A@m @)]/yVˏP po'' ))W;E:KW/(x7>S:9.JqJBR((n Qo>B]#p67mll4(!aFEkb'Z5hYY)hi 䗾_6d֕Q6 e5FX;$"עMIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/devices/0000775000175000017500000000000013244011205017776 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/16x16/devices/media-optical.png0000664000175000017500000000164311323355446023236 0ustar alexxalexxPNG  IHDRabKGD pHYs B(xtIME55*})K0IDAT8mO\ew8g@R(e. Mim5֔Ru+[(ӈؤlبEع@$,`(0snJb˳xGpↆ/}@L_/NcD۷?xղfz^|21M_~y^.,,R)\\\ rXVCٙcN;v/﹑#@aH)i4"u'mV,hCÃǷ.//K9PP?G5Bt03yyҧw|v7Uq]]7hnn!NkkDJu&ՄO-..n@γJR sͬ/޸αR^&Oygt$3MS)0M! /<#}b1 8a@N?S)E躎mH)?4Lq<! @H`hxJ)R:h;ץRꙮo]{[Ty>t: Оjgwog_$=D"vvwCRrJոi躎eZU/TZS!RŽ{ԏhBi =cXG+"@J ]7Fv)%GGGdYO޿;:P,XMێd2q0 ,L&#_g4Bhs$;;;Kڕi˲'''W ʼne߰_Rt !Dd9 QnJ:IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/devices/drive-virtual.png0000664000175000017500000000137013061022223023301 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<uIDATxڥSkZQ=>JF%ӤM8EBRCY fp-.R!L4`&&jb+m{=R8ZQ(\) `-$wj5 A*2=L }ՌUIAЃN,`߅FH4TSUETQWDCFpˇ`0`804 By^ 0!.^Ib v OL&F!ݿ]č7jA@E?~DS!_YY9O^.a'u]r/~]St:.E>!I߻gUqe/,oT7elnݾsk{nYݹW}-"[o?'IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/devices/network-wired.png0000664000175000017500000000127311323355446023326 0ustar alexxalexxPNG  IHDRagAMA a pHYs B(xtIME/KJIDAT8͒kpƟ蒬a`WuLOjềȆ C/ xqo<ҍR6 hꖮtKC3RePws{}.!"!dZ3}/}LQT,Z' !'G+1o{{K$!d"5!d9ɱ8\y%KW.t2cr33u,#Mif8Jy.d8a0!'`֋1 8ƞ$ۿ& ms혘e##+s'u!3W_NO2b\t;(gcTm $܋4^"DD@\߇ܨАRpnv^#e`nrY;Bчwһ@yBɭD'f@:0EyO>Z]#^E#-~jnVJ "~ Xa3szna[> F]5N~9Z^ wd2j5&7 I(f.em.Jo)"IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/devices/drive-removable-media.png0000664000175000017500000000077611633361331024666 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME PtEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGIDAT8˭JP)b ! v/:7ҡ J3HY:y,p;H 7ws84eO/w䱵*>VKPJA+ttwЩhQT{pBVnq8I4 2?)˲U!Dfw8_a7:{`YI8/޸7۶QJ9qP/ۛ!Q3GWGNP{QIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/devices/drive-harddisk.png0000664000175000017500000000113311323355446023420 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME5|wtEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGPIDAT8˥Mn0@ &j$p7$ ސ'@,Al"(U{~3E6O'Zc9lU(ձL@Cf3bE!}@ *H'D>S=Ы TeYFuLAEQ . 땪0Ɛ)Ʉc@$ btk-{vPv;mmKa<m[=㑪PUT$I8c97*"|2N#hLE ,ZKYwj\2gzվU&l IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/dirhotlist/0000775000175000017500000000000013244011205020541 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/16x16/dirhotlist/submenu.png0000664000175000017500000000147612405254001022736 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڄSKQ3$ZKZJ$؃PRу=T>EEA@RJER؋(HEUd]6ן(0gsa#5MCwK3 `BgқMcϊ\ H !0!@1AWrmi}R2pVMEpUPE%1W Ji/`,to[ 1 4nӶD0}nNJL-jic`^ X=*(s >,.b@Q$U}М*~bs:f 9.* 3HrYǏAd֌>qPQy$9%I[4ɪ0ύ# ,w),"w)7Bs,8`Fz(1JID, ,˽9#Fdz-lF>R'2>km<2@*4v!>ŨPŒi ,{SϹG.7^`uU oc}i)dCcfi$a*ufzC+I-rg!6.7rˊ*{X/Oɤܡ7 V v "m_2=өOyա^?Pz.4TX]9lO4-r8\mXg[.h x~rs%^, &biI0MEaY["VL *aݲD%݅*>oxu<\{ ƪ?9/ Ho ӨCn+OX/$X%Y|lB-< s=Wb;T#!0N@tJgbގ fV6G6fk!!'6+k@GNR?JB$c4c" 'OT151p(# XDB? ݝ]fwvgfjwyy5QةAH=fb2 ؈FGי7 EDtJ\.`ڂNmNXwoov`tT$6l@(ʪKJB['N\UW Â{,kVT/ uR}}Bq'a=O,ix5%vJ{Q=m|{9MP\g/[}C(˧=}$?  il ci1 l22v\ޛБl*gH֡(UmSk繼Pa3. rf_>cvMl/~p0Urs0~d4Ydi1S(e`6H<%A4jF')εbm;M  T -v[7H0t]|TtZ|}OT#[mm:%b@VXF"R AbH 0"duE\6%,V4_=EP ԅ0Z`={QmAP pkk/Ggs]H"/\7ᚩIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/emblems/0000775000175000017500000000000013244011205020000 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/16x16/emblems/emblem-symbolic-link.png0000664000175000017500000000072311312762055024535 0ustar alexxalexxPNG  IHDR(-SsBITO pHYs:tEXtSoftwarewww.inkscape.org<PLTE===_a^fgd  ! !! !!!###$$#'('))(..-000120231785786<=:>?R?JB$c4c" 'OT151p(# XDB? ݝ]fwvgfjwyy5QةAH=fb2 ؈FGי7 EDtJ\.`ڂNmNXwoov`tT$6l@(ʪKJB['N\UW Â{,kVT/ uR}}Bq'a=O,ix5%vJ{Q=m|{9'TpuXMUa?)}[PNeڧt5ɹ={V7c3Xu,O# : 6ĥ,-(靳㓱tw$Z 4nUxEG:=x{ `@fM{Uv"3C0c\@nFȂTbTZL\>{tWwvYk-0U4lQ4l69n7J]HaN3E.En ͽZ65$ݖ/܏nխϯ;v?$#P6$E/K^5IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/places/folder-link.png0000664000175000017500000000122711323355446022557 0ustar alexxalexxPNG  IHDRasRGBbKGD pHYs  tIME $+TZtEXtCommentCreated with GIMPWIDAT8͑KUQG!@(IdPPD D EAҰ'hQ fADP$~ܤ(dfz9g7}*ԤI {ً[KS?6}^^ 0zn_I m~ϮC:>%e abce' <ζFV:{PjS}^6 x7|5u\LL_D0|e6&k#Ͽwïb\#Ob `R,|,9 U'n|Larb¤d L~3L а8F$9A(6ԔKjIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/places/folder.png0000664000175000017500000000100311323355446021614 0ustar alexxalexxPNG  IHDRasRGBbKGD pHYs  tIME 4Ґ tEXtCommentCreated with GIMPW^IDAT8͑jUA A1Z R V yA*䜝s=mlXݝ1bwڟ)K}G0_u'Wħ^//)=gWem"D335MRGa| a!l@7!fs O~}"ӝu P`;|tؐR 7W'žT8eEYxFYU\HZ*JȔ" Ob! GIj, fv]NM@ . 4 NQ.!>Rx@,,fb%%g6_* $00 /. /.  *߱*> =!,#o-&p= sB ʹ)6F²",>N  "'"'.fk%#-,5Ʊ,5Wr;M;MK2Æ=:F)IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_markplus.png0000664000175000017500000000164412110457565023062 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME 7ccs1IDAT8˥Ileߙ6/c;qlƞ6B 8j*U,UġBNMT\XT4RN, TH *j)&d 2;x<ϡ$ 7$wzg},.G\U+AµM:2l'8MznIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_reloadfavoritetabs.png0000664000175000017500000000221612656270711025101 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME-`|IDAT8DHN|GDHhN;  I|GhO<8 bK8IJ X1 v     |F >"% ,(  .@)F:88U)>aD-88  E$mG,"58'ʀN R )JE7 3ع%F漅Á -/M*  'Z$-3!a զГȂգ}.mZWi'_ &"/ok0uk(4 }J4 ))o5&l2P_y4J8Z>IZ>I?EY =IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_filelinker.png0000664000175000017500000000115012110457565023340 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME6fIDAT8˕=hSQ}}EQIAJAQ2dAQH+X7 P:HkMdSY'41]< j9+FDD"]]Z2x::]a:@V!< 8 P%iO`OsUfY-`٤1\yi"(R2̈́ 8C5 Jrkgp]F(VqfqO6Ű,kIxrzat5H mAW-@6ɵ|_n8Ӏ .IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_closetab.png0000664000175000017500000000112212110457565023007 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxSKkSA3;x*ےJ! h W>Iwϖ _R<\thա}fI~B{_E2׭Je J&W17{rY'aTD{0# =Sd6q@D!J /PU`aΧ!Va^ՊMP>%\0 ꆔRh79M"%8ڎVmۇ{Xz uHBQJ4_;;m\4 {L?eM e&[g[*{aŇw%{L7 ^>+|4?[|!VX@&.dm>pdD\7\?v~q}ZXSn3dyKMpϿؕa4 kXP 6e"/ #TI޹s@ԙ P~;sK'G{2}[F~S,)7gC/7@ùw<ֹLE٫DWZb%ùƛ۷m\9}ߖڒ @(t|@*0u8wЋI6ګ7&S?eѪ9{7m2hS(OUجً_tn|9 +-(E~z#٥5 ǘU?>ʿ!nMW];v !E]PMIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rightcolumnsview.png0000664000175000017500000000217413015200640024615 0ustar alexxalexxPNG  IHDRa pHYs  tIME 0IDAT8K2KL6%G" G"%m %%&6?>>0..6679GFE6?>>876<<=@JJI6?>><::RnOGGGIww6?>>//CCGGGI//II:: }4fO||@d?mIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_changedirtoroot.png0000664000175000017500000000217413015446652024416 0ustar alexxalexxPNG  IHDRa pHYs  tIME  $0IDAT8ҘCO/i.Д=/hΔZ.h)ڋS2hі^(әE3-g W6 ҘC\јc3%ސ (4q )#"fа4? HGF  !69X(%$ љW',IHFHGG 521 DԋNIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_helpindex.png0000664000175000017500000000137112110457565023201 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxdSMHTQ{ޝqJ„ZHQdAjF?-مEk"E *~b؀ӌ93doƙ:Z.s}ǪN.q'Wc 6vB6`S5L ^O06+s@&oWO5!DX:0vp1@ }XHf h,ࢗoهw4`6?F^8RuIL%65lo@0 ^,*_3Sm\TF#1|i*83P=Kfh0);hRV[`P+$t!m'ƋOCz\0t %(~?yί6Gvm0",xM&y$dmJ* 0ăc@ MӐQ+ J GK:U 45_I>sqg?;yf塗4 &Lfg㙧xțdx. >983]a?tSryV쬯kw!;l "Ͽ^  Nj2Gׄ'F4˿@I CW&N^$Je^ ZIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_universalsingledirectsort.png0000664000175000017500000000217413015733506026535 0ustar alexxalexxPNG  IHDRa pHYs  tIME  #S IDAT8GL]oGO=DD"DD*&D&D>UapsJGIrGgDDzDDs"&D`&DmQ>9D/w ptFټn߲IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_markcurrentpath.png0000664000175000017500000000217413016303343024423 0ustar alexxalexxPNG  IHDRa pHYs  tIME 5" IDAT8[t;Not /G=k:E1UG- ц/ :=  Κ'xZ/K^%AwK%wF[^P>G#n% :  EKx6Tد Ȥ+(:U 2   " {YߺTTT 84+5/'ڷرٻ*```*YYYϰ 52( A  $  E %H&&&=Nl7BP HA8DDD㑙)M*Q NE=$   ooo(޽SJM+7IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_gotolastfile.png0000664000175000017500000000217413013742760023714 0ustar alexxalexxPNG  IHDRa pHYs  tIME  EIDAT8LOsPFgGߙM:81Ƴs;:jPSF1SF1SiPS:3G75! x4ݼ *fx43KK333^TIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_options.png0000664000175000017500000000151512110457565022714 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڌS]HSq}unMn:Q\9S3 , $z(z)Ȉ >5z2{H7CR3,?pι۽WR ;?BGhE:;k6ވpQ`sl͟D Kј"j]3\":50&_n?'QFZVLvsƢ bR^0(oRR 11*'&P#D녥N|f̞e'aڽE^cT%Cć)|!0qY$3OPk!}={<1L 9贺rBf %$f0 kڊӡPĖP9X H|ǭPnc1 \Yz3y-QB9O=j*p ʃʠFs|R dG d;SCaj'݈(yk@0J$c".ZeD"Jt e"4iwp+/mʖMDCOE07?K J5&WΌ 1zޣR6uNk׻=tfQi8~17_ PNA( 0qBP%iXqTGɊ&e2"]DsW})鑕l7]9*ZYZifUTo% "$!1IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_open.png0000664000175000017500000000217413014355224022155 0ustar alexxalexxPNG  IHDRa pHYs  tIME  96;IDAT8-~IֻELݮ~O'j7Gs`ŕ. : t) G/ՕEݶ 9+/%%;  ׮Rϊ 233(%&ڳ+RρΛդ+z      ѣ*-5?   ',/Q)%?#_xgIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_savetabs.png0000664000175000017500000000217413013742760023030 0ustar alexxalexxPNG  IHDRa pHYs  tIME  ĘZIDAT8DHN|GDHhN;  I|GhO<8 bK8IJ X1 D kH; FOWJD0 <jDB?<c$ 6<@ {F4D?= <:;   d$T0Axz?     XIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_unmarkcurrentextension.png0000664000175000017500000000217413016303343026046 0ustar alexxalexxPNG  IHDRa pHYs  tIME eIDAT8[t;N3i -M*L v: J 4?*hL5و2/>4/*'xZۉ !]K4ALEV-؇#"(VϿ0/ G#n% :ܺ " tKx-G6#&&+,;?)9 2!   9( j7Kڳ8\7֯݉G[&N  67I" ,]h|Xg~3!  !***B ",u-*s E.;` ѿ  zs]ppp\: L؆((('''ά'&$*3((((((CCCśEEEv'IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_markunmarkall.png0000664000175000017500000000217412723431627024065 0ustar alexxalexxPNG  IHDRa pHYs  tIMEѷ8IDAT8y^‚, ہaRD~q}pM?{Q+O8eK7k3^k'0AJ\-h>ejmp AK@J T(q-θ%lh!9P ;D :C 9C 8AP7] 443P]e  7D$N F!O>6_SA;  k0LN֢:K(׸+KNج]   Ab  ^fӇӚc MW h GP%zC q4qD Lµv MIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_viewhistory.png0000664000175000017500000000217413013475730023614 0ustar alexxalexxPNG  IHDRa pHYs  tIME  IDAT8ƱмZ+;H6rBPb(xTO-:G ǩ%  nO  O  . OjO&`N/Jm0󇕡KLLg{g.sKo,Av}G9x[:7 @/Zmq<-IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_gotofirstfile.png0000664000175000017500000000217413013742760024100 0ustar alexxalexxPNG  IHDRa pHYs  tIME   1bIDAT8GGBBDێێDJTrrTJG29%ι|3&3BjD3&C"z\Gׂ]IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_addnewsearch.png0000664000175000017500000000217413014355224023644 0ustar alexxalexxPNG  IHDRa pHYs  tIME   $^IDAT8wy{wy{ai 8&6wh`4;<;866&+&huxyQ4w3p7xЉtuxEFE<."}D &xaa_ rvxzd"d]^Crpo  ddkji  W44  2  2? ? ##]IIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_loadfavoritetabs.png0000664000175000017500000000221612656270711024552 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME!NIDAT8DHN|GDHhN;  I|GhO<8 bK8IJ X1       |F D       FQbHBWJD0       2W3B>,WEm> R y33ғ7*X|5  'D׫$ё2#4"J* "0uo q' 8!Jw ݮ9wJ8Z>IZ>I?E>ӻ*LIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_opendirinnewtab.png0000664000175000017500000000126712110457565024415 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME9H<DIDAT8œMHa~7.̢0E&яT$-0ȨfQҍBe1D$!!V+i")XXI f1N-$Ш,={cX +wƀ:/imWWR-RAlX+KKNb?@dXcA^QR rF#H4\t3cp?A(ıFme@k$'%*0U,/ ʍ>NIpq{rY%|/dl m@, 6ּ8IJ S˾Rz 1*d- F'FkaajPD\(Uxsa.4_Oۈ=h}F}Z_YX.7Y9灬Mس ]ybʰEYD&4@Z0wb՗=VNgK\9lR8` X[͏%;Biyޢ1&-9l+T;=0;INy : &B={M>Js"3xۺP?iqQm@_6 i  _2\dIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_deletesearches.png0000664000175000017500000000217413017704640024177 0ustar alexxalexxPNG  IHDRa pHYs  tIME  1){IDAT8B!ggggV84ggiggggq |wy{yxvPNNM8y!ggx-++) DV;i4gg]^^aa_iggoK$ K$$$ff }|{zwy{yxvPNNMMMK40/.&$#9?]^^aa_]^^#uwy\F+|{z3vt{,JMxIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rename.png0000664000175000017500000000217413015733506022467 0ustar alexxalexxPNG  IHDRa pHYs  tIME  .=U?IDAT8xw{@xw{@yw{A ??÷. wuzTxOO )))xw{A'+IH))) )))~uNNP))) ''(✛XXusxde b`euz|  xv{4\xv{ |yqIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_comparedirectories.png0000664000175000017500000000217412467744673025124 0ustar alexxalexxPNG  IHDRa pHYs  tIME !:wIDAT8 zi $ \5% 9$. s   ) $ ? %Fn~=h$ }u=%-..B  U $'?e' O 7(= KN,-,.-,9 V z'5u ۼIY! &>YA  W )U-# $"Ϲ  Q IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_settaboptionnormal.png0000664000175000017500000000063212110457565025144 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<!>B!B@"` 4VF\ݙ  baoaf!ː82 t 9WN;G"JmI)O`_Ta$3N] iIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rightsortbyattr.png0000664000175000017500000000217413014736012024465 0ustar alexxalexxPNG  IHDRa pHYs  tIME (uIDAT8GvfBVfy_|bDTffTD**JTrrTJ,C*|~|}##&3BjD3&fyy@**+g+|aag//CCC//II::f||En =IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_copynoask.png0000664000175000017500000000217413014355224023222 0ustar alexxalexxPNG  IHDRa pHYs  tIME /ZZIDAT8O0= l.wuzÜELݮ~Gs`ŕQ/81A  (((-wuzԑA JTݶ 9+/%''' _'  ׮,&))))))%EةJ 7Vݠ''' դ!o%/)))l1***&&'l& ))))))Ӗ/ b`eqpu|  xv{4\xv{08KKYIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_sortbyname.png0000664000175000017500000000074212110457565023405 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME36SiTXtCommentCreated with GIMPd.eFIDAT8˽+QU$E 4lemghvJ"+;iJdL"F$y=1󎔜yzίY{嚉`ESw<9 0r V5j9{Lq-ᵡmĴc1VM/; Gn {+'^t=/|ss X VXK97 V2D4b @?נ / PLE*+~I  #ހyш5~}3%~XChSW5NψEe׫Uv8V= &IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_markmarkall.png0000664000175000017500000000163312110457565023520 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<=IDATxdSMlE}3Ďl6IUi+*TC )9 TC/- V j*Q5HP@mU`봻z0bP'=ig{o7r>&~elmePy?8k݄-J dF"i:3&> <4@zyˬ ǃrxfazN(6f > fiS4-.&;97f NNN[66g6g6> 9fffII"b$tIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_runterm.png0000664000175000017500000000077312110457565022722 0ustar alexxalexxPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˥S=KAE@sv ib#RF< ),Ԁ v邠GLvy]\ Yfgw͛UL,}|t5;"${FL촑h1;-~?O[e}O/K^JvO75utlI.j{FhǗ'ۤ* m֡jT`ǩoW*.t:jZ P0th4ZR^wvE;_N6m$IzvCF1M Zt3G| I@tFM-~"{de9}= kZL2#0y4VBWJD0 JD0A_:N;WEOݰI"+*$3J34/*ALEVK4/ E1SLrP<|~UIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_testarchive.png0000664000175000017500000000121412110457565023536 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME 6Ű(IDAT8˝KHQF'g%BEQV "gA4)dh!"Z.ZHAOEW-ʆGLI: 9i1ùp9w8Aw!8{VgI 5QXTXkAddEt!繛e4`x fYx 3_{T Β  #DamL_<IcfLfwHutH} eHEh]Fi0fJQ`wmr sx&Mc7b z\62'O-O|㋳̺n&/iopo,f \y>Ͼ73Pu{B]gW7FS&8ކn *"? 340(;Z c<{э=C`aO4 kt:z D`|C] m؊R |7&`VA$p;Osxi`<۶-P-`e/#KNC&*w@(IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_setalltabsoptionpathlocked.png0000664000175000017500000000217413014736012026640 0ustar alexxalexxPNG  IHDRa pHYs  tIME  1YAIDAT8DHN|GDHhN;hN;hN; I|GbL8bL8bL8bK8    D BWJD0JD0JD0    B>,W?3db^j''&4 lΈ1lYʎݦ^Q>LΓ, ^GnIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/view-sort-descending.png0000664000175000017500000000053611323355446024604 0ustar alexxalexxPNG  IHDRasRGBbKGD pHYs B(xtIMEkIDAT8˝10*,˘ pwYk0!DVٸc0湴 ?iҼ{}eBm}]Fv%Sݤ*sQPٴT6-qQͯuPa^!spQ@ãs3MG2Nv;F"\h{hF# vi e' P! i$ uȵ98)Ĕ<,dW}`ۺIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_sortbyattr.png0000664000175000017500000000102512110457565023432 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME5*&iTXtCommentCreated with GIMPd.eyIDAT8˽һkTQϺ! F$h 2(D(T"_(j+HT"Fs͍q3̜ iW\^kϺ}G'_ϬPvStfF:˷| yWE*THd^֐'{G-ત>\N:R .=;y.<W~̣1l_" YG1H u|%`'x3emj F ># {{Ng\C?̝G}YA"U Fzv_ W@ALcQ i)u][6/X۹Ϸ[5~Ϧ bOIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/view-refresh.png0000664000175000017500000000162011323355446023145 0ustar alexxalexxPNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<"IDAT8mRMlTe={3m[ 3јF7`XDa M ta1L%47!«qВF;̴Yp=''\bfHe4jՄ'¸.ؖp|t&E@O*}]gQ(V02v|g'-lzW6ÌĈdǂЉ  3EW Ŋ 5>.W f43=gOk40ĭCձž _M^l8l?3]X1/23ǕgƧg^hڷuS( wD-HU/<A2e^ۏ^,}?,az  ,Hc$UgnSui&vn{'v>Eq4Akw_?߼''k'W%߼[0j>AX-/?ԩT=eYcJ奎Go@W!'$_ԓSln\{&?3 DV%r=?JeFmXv@x\qqah=Ѿ2;}З|9r-k5tT2>hMA҄ǡ̖MD, z=*];[x 8wyIuI1MN<-I7, #?[FՕD(̗ˣRmcer-0{ W1oR ]!PՑl.UvjeIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/view-sort-ascending.png0000664000175000017500000000054011323355446024427 0ustar alexxalexxPNG  IHDRasRGBbKGD pHYs B(xtIME-8aIDAT8c`%0I]$u5o?sˆKssX} gf07+f|0،v> ͙N ald̈́ a1gP;}_v>X OϊpT뱆 -%J gfǠG%Z3c> 2aI$%8 ̎_d/D`Vfd ,aT;}_ztFrVO[. IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_exit.png0000664000175000017500000000140512110457565022170 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڜSMHQ{EFE.v tEm EQ l@Grk% "#*ZQT{oͽs;w^3a9[wcip0ZѰ~3Ay5RU{WK踥U~IItrw;CLHDo,R [`+#%0] -Avavz /(FZW2^R!S3}*XQ0 ca4Af<;9H d销QL4->ग़ lnP 萛S$݌E E{"ب$&^bna]0ќiI)(6 14 h GEYT+|.ϝYuSCI'MsK dV!1B!B+P]b(55ap#w,V#OY^C2bb]QQCjPM#,+NFt LAF#$*8EaiSKk !. \Ec`~XuTF&#b)iU@^el:j@oDγeG^C"', d,N.#Hs- r]5֗y"X"CqiMr# dIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rightsortbyname.png0000664000175000017500000000217413014736012024433 0ustar alexxalexxPNG  IHDRa pHYs  tIME ' =IDAT8GvfBBfffDێێDf!ffJTrrTJ*!|~|}!L&3BjD3&fflngssg//CCC//II::f||A\VyIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_horizontalfilepanels.png0000664000175000017500000000056112110457565025455 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڤNP *U%U)y+CqU"ULvvXTvz6?زt9t=.ھ76Bp8IzD>&ϋ*4d: 0]}pZeAGj,[z`4'xߟDP~9%wD7j,HfK4QYV漑6*}-6Y肄i[:C?{A8 2|? yTG/z=4>rYIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_setfileproperties.png0000664000175000017500000000131112110457565024763 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME TvVIDAT8ˍMHTa;9#yDA gPAa5YE&@,jŠ ,uc dhqYys>Ppxw4%b "R])l66pH:_llX ?P1W\'zvW:PSY墀۶:6D ѦЀ'%4+>{hY M) ޭlkg"Q˳@b&LzzyK5S-) oUqd7;uXu@]f&%O* XܕrK?Ĕg`{QS[Oͩ 5|Z4=)4INJAtPZqW/|R\tV Pc"2F$"~CIq8$+{ ɻ1MSTA-:82\MjfyO Wt:I;@ͧ2TF{(R(ZE *±L̆NU|*V!d Hlh y- }筥>+Q( Mac lRX;A?(7JIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_renameonly.png0000664000175000017500000000217413014355224023365 0ustar alexxalexxPNG  IHDRa pHYs  tIME   #IDAT8vlf33wkc33${x" yIkyIh  ""F b   j/%!I ) @o=6/igN4pkh3K]DMIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_columnsview.png0000664000175000017500000000111312110457565023566 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڜSNP=o E֭ 貁T^vH(BYQR$BYPZ!~GL !Q6;ӲhfF߹q|v<1bRMLÀ O8m.#C>/R7_J<7b%rSHJBcE*όMc_wޢݾ!~F9{mfETt[[D$*^)B:zt׃a~P2C$U;<iO(qSTXl   h;#q<#j   T0S`@p#UԺM5UҥH ҺpJ4]  L3azן? ӟ A_V"^;Q){4 F&% 6 #ܿ7. 0fH- 2   #Ei!IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_exchange.png0000664000175000017500000000122112110457565022775 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME1*..IDAT8˕;hTA;n6dAI A0F&BY6hea:" FE Z؈7RM ш 1 &K,Ό}C,03s93"UxQL82gb8I!fasf|Byݝ8AEkHͅGÍ*kCnk*a":"t@TeUem9;@ӷ%)V~bldmdC4 V&؛@jup}D~}&a"X T%(pw.iK2lRBRL]7BIe~r]=kR\<ٕd=½WYV~翸Rnh^J>~̹pSQ8*^RjzF1ӖmۋWǮ p({~+hX`Zp;b1pK 4 V.WǮ J)b1rH D IAŘ4;DS=5DPsBIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_comparecontents.png0000664000175000017500000000114712110457565024426 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME4pIDAT8}=hSQsjj-AkE."N j2AtS]5"Pɦt*S0)*DAAlSHCJ{?w;u˟ަ#J}.&F p(~zSْtIYްdyÒ%""g""VْH4PZ23vkK4l7#”h L][*&R{!""jMVkR˯mʾy_4=JȝA<*DzTi $O^W̎nCm2 ǩ:hMIv (`4'^&qrT j ])&N/2l \[m N ryUAskj8}4=qOw}0yK!CG+;sXfb> ыH5)gKuK0n41D-T>IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_addpathtocmdline.png0000664000175000017500000000217413015446652024527 0ustar alexxalexxPNG  IHDRa pHYs  tIME  mIDAT8!$/3H #GJ4/"))tBrQqnms)qnmqnmqnmqnmqnm)))XRAIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_cuttoclipboard.png0000664000175000017500000000217413015200640024222 0ustar alexxalexxPNG  IHDRa pHYs  tIME  # ^]IDAT8WtttXzGO,jMJG Ԗ -~"ˡvCyGA B @ ef><!  ,ө ,;#/gK??;=h;#q<1~~69 69׫T0S??`@p#L;=XԺM5UҥH 69ԺpJ4] ׫9;jik3azN?~69 ӟ ׫9;kS_V"^;A ?? 3333{4_\,**&!K% 344R344F344#ܿ3. 0fH- 2   #D.$IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_openvirtualfilesystemlist.png0000664000175000017500000000134612110457565026574 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxtS]HQfgu@V, DZ{ȂՇYY6bz B ^B]"r!I(EA(?0L5|3w.;;̑8$ sp,d\:O0155Dߒ\!o}쬩<0 `5La~P6Wkv?1@9<2ވ+/ؿ+ò@ipSͩiHOu|b97W@۪, t|8_{-M)0U02eb&Zh*-@{7] (_RE,FhX@ ۀ3 y ^e#kCQ<yRAZ09rϨ{^REKj1Uذ p:ۑpCpwmBaך.XP[6/7 "D{Grfg+, ( ՁiXd\P=@qQRv$ 9)Fo|` K;9.|Ů@>t:r>J=>2.}E8UUMܰ@%Ʌ{ꅒ ) } WIvoii#(%IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_configtreeviewmenus.png0000664000175000017500000000217413016303343025301 0ustar alexxalexxPNG  IHDRa pHYs  tIME $2IDAT8ppqQE8VL?ID>KapKl[IKK@*X5#"!uP0PC3PC3PC3ScJ1 mO1H2Ey- +> ')F:0 ! e-5bI0 +++\\\)(B8#$w!22t\\\*]]]?:m³222 *75?;B$w?a? 9& Uѻ G#)i)c**@Qd!IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/document-open.png0000664000175000017500000000124013110262523023277 0ustar alexxalexxPNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8KQ?}oIkRK?% rjХ7#M+hh!EB-siꛖ`p{9+CCCD͆."@Q""}ݸ\Uo/,-9s@D'&_Lslppp936&N3cxhͳ nTUnH)[fz+D07f cd "BUU]keY"=va#AUM5s}Eιvp5bPRJc MZd;8bL; y/qk"K;ʢX JJ_(H `|LH)YJ pJ[GDY Nq)%SMPPXlb{ט dr4f4ScD$mφI1s̝lNVJa.X33؎l7zԝ, ܉wgm`^Z?q!SKwY^ZôldoKu2IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_search.png0000664000175000017500000000132012110457565022460 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<rIDATx|SKOQf:Ӣ4ADMԍi 5.;\]hBHQ7ƸG/Rmu\}$b<;sr3³/Vj* L|C>Y` 0 x=^r\hxr.01#0iת@-xh4jf3}p^ܳ$Yz(u5lܑL Mޞdt[[?(_*~&0@*B&!b@$ij$Xn`kfm E$Tn蘙ƕy@Qp(-q$QReaAtmu5L;bG%M,l}v E J%D"p?~b$pc7fX,}8Nl$6r1;;Y^*/Hh7cݺ5i{#b;@g767׫@]4W ӊHQFX@ex<.T+f~L'kof>R\^ ׋ÃCsȳerv (VHry5ooM`Y+ˌ3;ӣ{? X\?[IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/edit-cut.png0000664000175000017500000000144713110262523022251 0ustar alexxalexxPNG  IHDRabKGDC pHYs  tIME 1hAd^IDAT8˅]HQǟsw}lhxUtaIWEd"hiXi}J$ 0m36c6uu_vMaZ? <}rG$d F`Jiym7TDb$[cc`5GSz?-"McObbVyb).ں4R: 6;M3}:ZE(Csѫ~+j.VwR*>3lG}L-^uЗǓ8@` \ `:<,o[FIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rightopendrives.png0000664000175000017500000000217413015200640024420 0ustar alexxalexxPNG  IHDRa pHYs  tIME 3 LqIDAT8X/ =Xa@7}6/ r۱4'\=@O'/ r  ^>5    &%%ږj )#$g :ٖj H# ffhxA4xA4    //CCږj///II::RiI_N<AbZHrn]MI?8XVRTNASF4ÀJ4QE8BIL:?7I@9/+,,ƂK4IA5,=B!+.2āK4D?31:($E!4āK4a[Ji!445*,,~H4 lJ+_J5:+.1r`N;3&;#!#4.7?A (#:. $/ ޤj4#:UI;6>|FHLs5IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_delete.png0000664000175000017500000000217413014355224022456 0ustar alexxalexxPNG  IHDRa pHYs  tIME 3":IDAT8-}I$ O'rS[5YaKY    @%]6X'f:"vSSS0S02M63i  ,?<hL54/*"hALEVQ)5?" %?+hILr#OV8IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_savefavoritetabs.png0000664000175000017500000000221612656270711024571 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME IDAT8DHN|GDHhN;  I|GhO<8 bK8IJ X1       |F E ]?5:=;'ryG4 . 2i3~B>,W /" N= R )JE7 3   M~  'Z$<զ#4"J*Ȃ0uo@n6 S"/ok0uk I)οP+ Jw ݮ9w!<  sXZ>*b)YF5=IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_nexttab.png0000664000175000017500000000113712110457565022666 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxSKQ$hk$/(7PRJ%KKoQHHjDIS VMKJ-TEfuƈJ̾o2.c4Vv#{E۞uU )9g$cIT`vߧ;A~3.C!S긮}ЁU=pB3v6?3tn Fj:=KjwZvsSC4xW﫡>4e> 4}dCʲ_6=T2`-Ϝ HXs]̭NPήɣ# +{9'혈?}H8$·!8+x 귩NR\oOf騷`$<~`^^TD܀A/0Z/(8;@ c@[,Om`#b-crtAMlC Ɛ3P6NzƍT9U3Vnirv?F?o7 ~ nCrWLRi\AZWBzQ< G>@`- ԓlq\ƋjMR-E[x0dW_u4j&\'qK[o+ !d}ݹ@g;K!H A՜Af-1>>d*f~>AF,ЂKa/~ö= 0ʼn@^[.^UQ 3 krԑ7$}b Py@'M΂" ^ڲ\ut(ߕzAD1(X >~3ߘ~A Q;RIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_transferleft.png0000664000175000017500000000217413013475730023717 0ustar alexxalexxPNG  IHDRa pHYs  tIME  lIDAT8 {M MN7xM @ | | |  %**+  aR  W`@rdcdSM4U ?TQ7ZjGk|egh%nhE.  xklk|RV}|RUcefyOEq >$䀖ZIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_contextmenu.png0000664000175000017500000000217413013742760023571 0ustar alexxalexxPNG  IHDRa pHYs  tIME  z-IDAT8]wmp ]r_w 61Ki\#  O$ !>>>>?A==<9:<}{=>>IJK|{z>>=EFG344222kkkkkk 0)wIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_dirhotlist.png0000664000175000017500000000147612110457565023414 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڄSKQ3$ZKZJ$؃PRу=T>EEA@RJER؋(HEUd]6ן(0gsa#5MCwK3 `BgқMcϊ\ H !0!@1AWrmi}R2pVMEpUPE%1W Ji/`,to[ 1 4nӶD0}nNJL-jic`^ X=*(s >,.b@Q$U}М*~bs:f 9.* 3HrYǏAd֌>qPQy$9%I[4ɪ0ύ# ,w),"w)7Bs,8`Fz(1JID, ,˽9#Fdz-lF>R'2>km<2@*4v!>ŨPŒi ,{SϹG.7^`uU oc}i)dCcfi$a*ufzC+I-rg!6.7rˊ*{X/Oɤܡ7 V v "m_2=өOyա^?KapKl[IKKUvҸ<7"f#"! ָ>cV'& &i5SfN0WmO1 ֺR!  Ey- +BpN\T(;: ! e--`I03301(gLuE)(6Į S('U4^P*]]]?:m$ *75?;B$wD¦iC*" ޺- fr~}%̥+L#)i)c**@QώR֢Cy>pC8ZIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_taboptions.png0000664000175000017500000000120212110457565023374 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME23IDAT8ՓOHa?*mJK2 D&R?cg#B;v51-E7&R0ӊ%vt{zy}7PONiE-Vkd{@`z,V17SsAZQ$a"tod{^ ]8ͻl)񛴟hں @Eu1p)J%UNlq(p8x]ȋmħe왒EUQng8mఁn0hJSvSvs"Na @CSYES^fA 2Q׳e1ekOqvt~J3N ASz~{[[a/j{{;G) x &ZZFkR g).W+iZ,KWuvvz<vvwhlh H09;3F@`8@<J&ggʿi&a.Tj<<"ȷ3rf`lVИW/y}q .IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_executescript.png0000664000175000017500000000217413015446652024112 0ustar alexxalexxPNG  IHDRa pHYs  tIME  d؊IDAT8~,$bX033~  @@$9:=>PS*Z V<<}}##=>t33(2 ]䟲%/R?3kHELݮ~( HH# (Gs`ŕ73-1LL&!! / t Z G/ՕE    9+IFV=4  ׮Rϊ :QK386ٮ{^ԑD`D=Xe`l],͌29xdyA|9IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_configfavoritetabs.png0000664000175000017500000000221612656270711025100 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME IDAT8DHN|GDHhN;  I|GhO<8 bK8IJ X1       |F D     FQbHBW0%+   2W3B>,W3/! M> R )JE7 3_I=;TLғ7_ғ7E F1=]G*#4"J* "0uo O(*1#2ƈ[10!q' 8!L4j <{1Jw ݮ9w33`=Rԓ?x5J8Z>IZ>I?EG'FjIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_checksumverify.png0000664000175000017500000000137712110457565024256 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME 6rtIDAT8u_HQ?7يf6=DXX"Az 2)(z(R>H1W|1)If:ͦK&{9JD8ERc?4q]@,@4Rs K'Ph@gYQz^́(y #_Xj2e v$}R*DyđmvX~MtFБCvU'yVRw̍s* 𴽽 IUJZωR Z4Kuƌ S51t>q¸EuN8ptvIh4J,#4 Bb_VVFӓHPXIa;?D"C 6RWzǁKYrmBM8[0`oHA%lܞ;V! ݈'+Hٽ'Edo2 +¾!ۺЧz>'9Bi2)ZPF;;['+p{=)JTsr <|0Ѭ$)5ޟr|ȝ,gjcM)4.L x]|}_GR t%ҕIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_leftsortbyext.png0000664000175000017500000000217413014736012024130 0ustar alexxalexxPNG  IHDRa pHYs  tIME $~ZIDAT8f*Rg֮g'QgT4\T4\'Qg(QgR2UR2U(Qg,TfM0NNвԬ ββ ڸ]QzS?د] /<+Rfܽ]"~cZIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_srcopendrives.png0000664000175000017500000000217413013475730024106 0ustar alexxalexxPNG  IHDRa pHYs  tIME  '2=IDAT8X{G[||G ' ^>>OX    ?>>ږj D;< g `/ٖjy-9&hxA4xA4 &yz$    n&j (LuIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_markcurrentnameext.png0000664000175000017500000000217413016303343025130 0ustar alexxalexxPNG  IHDRa pHYs  tIME 4GIDAT8[t;Not /G=k:E1UG- ц/ :=  Κ'xZ/K^%AwK%wF[^P>G#n% :  EKx6Tد Ȥ+(:U 2  y9V  Kڵ   6ۼZTEٶ KKK&< E.;` ѿ  zs]ppp((('''ά'&$ (7#T`peee9[[[0uUy'IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_settaboptiondirsinnewtab.png0000664000175000017500000000135212110457565026345 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME /wIDAT8œKHa4faQ"(8A nԮ]`-ZH!0qtFef5Fykka8ˁK,yM~V&5MD ]/i-/xdWTɒ\6%:B.U qlZ3lZ #^7w4F28T`Xq.:@ sGq:bX;5VPrDh(`peP*02~]O}-"i>0X> 2[9 wGp*9y܌u#L7-;q80\fS8Mbs&HٳzhT5 2JTsaan-i?ܼ-8aNe+8 𷃱ZH?q L 0p 7!k}5`,TF$baa9C:) ̣ D#v*LWP P~@Q&p , ۲R,kloDx5;=+x,aI rNR,|m'Xx]&-QKAd^WaEH TP\ZFWӲ9C)4JIxüE2AWtBzf'7t OIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_countdircontent.png0000664000175000017500000000115712110457565024445 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڜSkAfgf7mDsl= ѓw/ēdEڊDkAۚl̎ov4 =d_7]駦L 1F_\FvdCvwk->}^Ŋ#4BA/!,Xpҥt\qcTy/7)-!tfqN"(p~m\C&^ 2 PF0&*LT`GO| |3 \Q! ?捆4YA+ !BiqyS 48BY£3jtDmܩBǥ2$ψoQ# '4wpSmjb^јIa'w@T!Bj%35F0D &V.!6Roh}F۷SQMI.5Ǟ~+.V,WZ+ۇ|mtN?Gd;bH]5IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_togglefullscreenconsole.png0000664000175000017500000000217413015733506026147 0ustar alexxalexxPNG  IHDRa pHYs  tIME  \VIDAT8hQQQ McW555   oWp_p_oFFFU:::OOO>!!!{FFF>>>:<<< 33/Ew444 lll|w999GGG 778 ý%oI}œIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_clearlogwindow.png0000664000175000017500000000217413015446652024243 0ustar alexxalexxPNG  IHDRa pHYs  tIME  ]9IDAT8T\PFPTT\ JLf ^#$J ZX ɑX ZKEEz t2' F&  @Si 47ʿJw~9;)G` x 6A {F4wD4t DjVn#,Ѷ" m3 owD*'-03i+ ."?<hL5 s4/*IALEVˊ5W/,D`D=Xo٥Y" ,>,r) BLrQ3`qQ>IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_saveselectiontofile.png0000664000175000017500000000163112110457565025267 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME #8* &IDAT8˥Kh\Uƿsνsܙt^&HKiJB)X)eV TVD| >4T몋PA0lc0HJIØL3}{4.\??";Guj #y JO}w<;2rc ͳA'}L3 Kw:N훮kϖ (PivH?3=Z\;n TقX:kzCr֧K7+@3A5栱QoyҷoNfWñ1Jy2wݓᨅ0[u\}L2B3[=*(R$Bٙr|;X}?unPUJ՛+ahvq' !UrQ`/,]tk7^[eF ڶ@P0`fAPжN3Y8@LݸJ7젙eI-s. |Q,rQדE(,ڳbĖ+ЧQ<>@H%+Av|8ۑ:.E`V]?@`fP9 U{5^k乔B *%Pʧ^2YIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_pastefromclipboard.png0000664000175000017500000000217413015200640025064 0ustar alexxalexxPNG  IHDRa pHYs  tIME  $2nIDAT8WtttXzGO,jMJG Ԗ ]PvCPU^ QPPQ}I+!їꮶ^~I*^ހKYO(qS\7XcKs]  h;#q<#`@pp T0SM5Uҥb2ҺpJ4]a_AL3azlG ӟ =S*A_V/Q0^ =  GG... +.V `< ? Κf#@=UIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_leftsortbysize.png0000664000175000017500000000217413014736012024302 0ustar alexxalexxPNG  IHDRa pHYs  tIME $=IDAT8f*Rg֮g'QgT4\T4\'QgLD(QgR2UR2U(Qg#',TfM0NNвԬ: ββ WK}'QzS6?د] 0/< gW(+Rfܽ]@?i}IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_viewhistorynext.png0000664000175000017500000000217413013475730024513 0ustar alexxalexxPNG  IHDRa pHYs  tIME  BLIDAT85>M^ʟ" "ɯ   i և5  Kd|J^[U4 bxLihjkvN} S4JkC7.$Py4|P͂D=y4>x4t4 ĵ qL%`O3.t FҌTz" ՐIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_leftbriefview.png0000664000175000017500000000217413015200640024041 0ustar alexxalexxPNG  IHDRa pHYs  tIME .BIDAT8 B - 4 -P. >Mm++f^{}~|}!"$IP-`a uv tuIP-]_xyxy.fDF]_ }xyJ1I"VIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_flatview.png0000664000175000017500000000217413015200640023025 0ustar alexxalexxPNG  IHDRa pHYs  tIME  KIDAT8Д< 2@.k޴n31@@.kO()),))T ,OQOO+((S  #?1K  4ʮ}S @ =<;΍<=/s#(3!   glӧ  nnn;  3񾯱B36A |mmmSQOO>?<fSQOORPP PNN@\_9~777TZ_]ammm4 =<;v ʂ 3z3: ?M%M?:IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_wipe.png0000664000175000017500000000217413013475730022164 0ustar alexxalexxPNG  IHDRa pHYs  tIME  GIDAT8@ omqA@igl@ J J|qV|qf"?b,8DD1* I?mnj`_bCCEAABDDEBAD! " !  &%&,++,+-Y   gdrqu$gfiUedg*edg cbefehh~| AIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_newtab.png0000664000175000017500000000113112110457565022473 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxēMHTQfaސAa.ia)CAїE}vӪ [Jʽ"ieTLH1Pk߻)]8s?2ưYᱛ}i|8PBkU-Yk}G))c{ؼ!gIUРf NA[9x.Rμclj1:Ļjczo"M8R.&^EyqJG^0r`ZǸsIVڊ2|Srׇ00[1-󳂬L6/Ck3tc>g_OQSMPnnD &sA[ 쨓͇[ɌL<&l_- M:mC mB .3tSE-#E =$R4n"M~ٗrXBT|iWv=tQ81;|,sd_+şR7. 0cUIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_changedir.png0000664000175000017500000000217413013742760023144 0ustar alexxalexxPNG  IHDRa pHYs  tIME (IDAT8ҘCG-gД=/hΔZ.hڋS2hі^әE5-g #qZ&ҘC #QїbQ!3&-C"Cu!5r b@tČǪoP(  P4Wҩ.8 nQ5^>"O R5b؞Wљ Ӟ/zY)0.` H_Vi !333GA|!JA|!3#=GIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_quickfilter.png0000664000175000017500000000217413014355224023536 0ustar alexxalexxPNG  IHDRa pHYs  tIME  2IDAT8B8q7{FNJ[.# .Vn ؁MłT1 B $A*  & "M^F5F 4 ιψVjں /)! #  ͸̉Wj!3L>u0:IDžgOI4:#c#?n@:{cc.,sK9ӵvUng GgG1XVJC5U'%i5Z cb䔐F\" Ղ+N9ǖJЮ\`,ρy7:'!f$shnnMMKSh]!Ł@ROC'$N7_ `S&IzзFM^ ƶEA( Cw< c{u5jj<$ˆ?Y ߼Exv.WKJw~?DOw7@"5m3xTn|N J^ ǏV+7 BWt]sjW J4g8Սd2i FqtX{#ɩ)knwر ׇIMSG֭[ ty4~Bჩu|c6/쟍7d9%fáHxTU磣nY=E-b/_ ~ RB !o/q:IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_switchignorelist.png0000664000175000017500000000217413013475730024621 0ustar alexxalexxPNG  IHDRa pHYs  tIME  & o#IDAT8ҘCO/i.Д=/hΔZ.h)ڋS2hі^(әE3-g W6 ҘC \˦mܠ 3%ސ 74qئT{ )ϡ$4?j  %QF! !c]\,/{rp (+,''' љ a0RQP .ﷷiۗ)^vIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/system-search.png0000664000175000017500000000164711323654424023335 0ustar alexxalexxPNG  IHDRabKGD pHYs B(xtIMElx4IDAT8˥[hTwgn646>|P4B5M5TZ4DThk&/}/Hh@[d޷=9%Z 3Ïo>W~7ߊ*qBfyxE |ͲQE&NgRg2{v[c ;֦[aHR,(ĥ\6J>iTw=6DrQcJK6 hDčآŃCro::毫<MqIʥ"3d"rIP\fU[,X6n0y}V34ݑApw־D$I v(x/7br]Hė4ʀ+m$yZ$QO&ژ LhbN80@D<ޙw2>s79(" q0ȭXt}rL&zee` DQJx+V5`rGArPpylxo#Eԉ} 6.@o{`rO^Z&`lZ[[[TCz ;fhOIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_makedir.png0000664000175000017500000000140412253356421022627 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڌR[HQ9gvli*Yj$bv B!!*1 z*#z(^CЃj!Hb.by52x# fQˁv<PvZ !&9Q׊Yj粺V wABl2@Ҝ"Cnr(f%D̮ƞ'AYݗr?Dt0EW- oV@k _+ fyG#.%2 asḠ&D(㹽rGN*j5ǹ%{yF+[ΞNm"ўaL[_֏ yۑuԲU *v`6dX]GE}gu*rI]1iIHϟSF4d]Hrn]L^O>I@9WVQTNAEePD7BIL!:?7($a[J dǃL4E@4+=B! ./lJ TA/?K4!+1;|H4 r`N<;0>̜F|I4]SE0@F!&-(h"H4?$FE=6>"#̉,W?K"h@+PIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_leftsortbyattr.png0000664000175000017500000000217413014736012024302 0ustar alexxalexxPNG  IHDRa pHYs  tIME $;gIDAT8f*Rg֮g'QgT4\T4\'Qg03(QgR2UR2U(QgGF,TgQ3NQ3N,TgHG ββ ;: ڸ]QzS?د] BA/<GGG)3G$+Rfܽ]/?6M-c@BP2s6͙9壅82tRLP)= lXLw-%+Jw `m߁:Ю 42\;9p~@ v^Q.8e:@'%`4IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_showbuttonmenu.png0000664000175000017500000000217413015733506024321 0ustar alexxalexxPNG  IHDRa pHYs  tIME  `IDAT8mmmO4ddddcc 2451876  %#$  5$^l)Ϋ50784?Pƿ)?c  LV/ Ϩ99kD0*n<;; |K (DߗF+Ryyyyyyfff#  Z ˬ IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_showmainmenu.png0000664000175000017500000000217413013742760023732 0ustar alexxalexxPNG  IHDRa pHYs  tIME  0tRYIDAT8? $! qjf|mGez[^^H*3 x@IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_previousfavoritetabs.png0000664000175000017500000000217413015733506025506 0ustar alexxalexxPNG  IHDRa pHYs  tIME  "^iIDAT83KK33H7878H33G75 *fݼKeLS(StM:81(N|GDHGhSt] I|G:}8 bK8IJah{FX1 ==%.&$  NQbP DJ.  7i9~BW?:(1 " ba R )JE8E4W2-d~  'Z {F4scŚ{ГȂŘyHiQ  3נ?{C@\P&sZ1K  Jw ݮ9whsXZ>b hi(?IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/go-previous.png0000664000175000017500000000121711416270327023015 0ustar alexxalexxPNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<!IDAT8OHqǿof~;RblB n["VLD"%t-z;$% n$W"KPl0wz{RJ7+[Z+a X&殅 e>(U*/255.'Ug2R). 3Z5Z۸$B=8XT7lۮ r9qsbm j`:`:ݾ#5ȷ>z5j{]J`""$$S/Q@'dm'o=lpd{:Td֌{0=J8=TdP*FΡ"tn|Ù:S_QCo8F%9ˋ.s? A%h6_7ΓIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_copypathoffilestoclip.png0000664000175000017500000000217413015446652025635 0ustar alexxalexxPNG  IHDRa pHYs  tIME  , m~lIDAT8WtttXzGO,jMJG Ԗ vCPU^ QPP 9!!ԎZꮶ>iac $RIC/nYrj}$:3D,J~ǬD - !қ0Z?x { W?)RsUq.jSm4?Zo#IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_minimize.png0000664000175000017500000000217413013742760023041 0ustar alexxalexxPNG  IHDRa pHYs  tIME  !6IDAT8?WKXuOYF3$ =?=HPp2wml1vp@ m]Q|R<'m]R<AWN::Q(F W|Y9?z  @{|W7WfN5J~R8eN6  R32qRv10)|Q  |Q"v,s,sv" j}X6?w|Q ?{Z;{Z;h>@=#9t Fnj[z"L-#D&rIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_configsavesettings.png0000664000175000017500000000217413013475730025125 0ustar alexxalexxPNG  IHDRa pHYs  tIME  [%7IDAT8FFGW&%$431431 `_^`_^  6~?<f21002005-4WXg@X_ǂ777gfff(f2Z_Y_]a6~mmm4_ :~:}8|fWWij3z3fikII͆B1qXIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/document-new.png0000664000175000017500000000073513110262523023137 0ustar alexxalexxPNG  IHDRabKGDO4ױ pHYs  tIME&Ӷ)jIDAT8˭OK[QsV$}%[\f qYE޲w#ĂM7*RJRJIZEbwDž&Tz63 s3R.kZ\go˟oϾdRIxS/Oh缠'+⮶23l6 ! "=c~!"f L&jǷ[SW{jky`1*F_^^o: L8 n4Y:OPEi@дޛzƦ织'Z_YD)]Cu4qp'?QHi,0 (9vyIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_calculatespace.png0000664000175000017500000000151612110457565024173 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڤSIhA}]==3c2YL4J\P- bDD%AŋAAAQpd,3ʟvD=_*& g'#dppͿ2B[sANK߿ e`(Xs,zܯNs TA=:ɉ`0!5@- iS !#6p04jB+k$C}8<&Q ^7tAg #dVT2lbhKs䈪(Zk,|1yk!4AOoT5P"M傛+Bn&6l_3g3OXz۩DcK3\Ov8 T DB_-\<Ү:}7bxÖ\U/Q\EKUZS#+㛟IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_renamenoask.png0000664000175000017500000000217413015733506023523 0ustar alexxalexxPNG  IHDRa pHYs  tIME  /3yIDAT8xw{@xw{@yw{A)R%b??÷.=ELݮ % wuz߻GsZoTOO / O   ݤVxw{A'+IHݶ 9+/% .'  ׮.g~NN000+%&ڳJ@j!!! ̝դK )vuzba/Ц1F**de#d b`euz|  xv{4\xv{/55ڊCIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_editnew.png0000664000175000017500000000217413014355224022653 0ustar alexxalexxPNG  IHDRa pHYs  tIME  +0IDAT8ĠDEEEEE<`f5H5H5H5H5HwwwwwY]'K˹_@ToL0`آK`֭4آK_࿢֬4qآK^༢֬1xv{Í6^۹{`aj7A&6wh`  &+&hqC -4wp7p74wsۉ։}D 9x\tr tIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_keyboard.png0000664000175000017500000000100212110457565023010 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxb?%w"l S1 Gv:7J3L jfddd`߆1m3 ?5312031mdHVff& o0012AB-,4P` @tnó/"<xɇ3h3)sڙ3>u'p`x/Cf?Õ{> q(2hŒFų"hOS53`|.P OF 41)3>}ÐðxN?7`bOu@W,ݴ!6ː3F#0P`8r"8ts#4ղ03 .^ᅧ #RB׃ (]?0R /JstIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_leftequalright.png0000664000175000017500000000217413013742760024240 0ustar alexxalexxPNG  IHDRa pHYs  tIME  "|8IDAT8͓/3mg 1Xf͓.0׳";Y!9S ̑,&0̑.Ε2N!!  5oN+;5>+K #Ԝ6)Gm>Զ+#2?'%C 8" ^ڟ *Ca 9Sש jJ>IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rightbriefview.png0000664000175000017500000000217413015200640024224 0ustar alexxalexxPNG  IHDRa pHYs  tIME .0b%eIDAT8K2KL6%G" G"%k%%&$$%{|{Ky==;yyPRDDBzK v==;vyPRHGFffnP//13ql/> <ww==;//CC~5PII-KHq||XXRe,IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rightsortbyext.png0000664000175000017500000000217413014736012024313 0ustar alexxalexxPNG  IHDRa pHYs  tIME ' PRHIDAT8GvfBVfygDTffTDJPrrT}ggG29%ι{g& B̊[jy4@g@gg//CCC//II::f||avoIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_packfiles.png0000664000175000017500000000152612110457565023164 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME1TIDAT8UMlTU;33 hZK5ƍ E*[bX,it!ʀ ;RqM*NSԐINvu{er99˹~AD\eewyY.͇/>“k=ى,kWŵ확ӯ;LC'~nQ >TˆW]3s zf+srCMj\X=CIgGXbzjw߸I6&2?qq]{zjh$@_OܓrYv`Y.Gk8r#Gظ7Oc}z=|~[G/ "h.r*OX5fA'~o9ɯ/qp=$yMU>-\#jRø<VW0_q#6$?@0#޹NעCL%3<*$VBY ZUn/v{QClo J~ {R6Fk(:x)Xe!lb. yvl F,u#md;6@Oo7mY=m׵R eY -G"{]gOxo}`FKF +b_$.& }:qa &X^yrSo3kyX"bRC7>; 06>o-E羘\"R=kk2 IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_configsearches.png0000664000175000017500000000217413017704640024202 0ustar alexxalexxPNG  IHDRa pHYs  tIME -}d5IDAT8wy{wy{###$$$4;<;866<=< 4uxyQ򫯮VgijURQLMLUwy{ CECQ =aa_,-+vxzշgd]22 2//1)rtwBWC. W3*kji  @- +˜''%O.M_ F ӫ`I0g)(B8#ESo25<:V6 " (3 (V %#%**75?;B$w̦Z4234A ӣ=SA>M#)l*^%'ENhҀCIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rightequalleft.png0000664000175000017500000000217413013742760024240 0ustar alexxalexxPNG  IHDRa pHYs  tIME   ZIDAT8͓. f3m͓.0f+O "=& ! 0*DBt\+gefۂ-6|IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_viewsearches.png0000664000175000017500000000217413017704640023707 0ustar alexxalexxPNG  IHDRa pHYs  tIME  /aRaIDAT8B  {FV8y@K$ K$$wy{yxvPNNM8y  x-++) DV;yLMM#%@o=_ƢRP""! B]% ]yxvP NNMMMK 0/.0.-9 554NML]^^342JGپ - 䭎D-#WlF689011ccbvtr<Y4Z\^+j *VIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_setalltabsoptiondirsinnewtab.png0000664000175000017500000000217413014736012027213 0ustar alexxalexxPNG  IHDRa pHYs  tIME  ,#gIDAT8DHN|GDHhN;hN;hN; I|GbL8bL8bL8bK8    D BWJD0JD0JD0    B>,W?3db^jGFCij`hai''&4`hA8yRwA8h` l h&+&hΈ\ww\ʎݦ^Q>LΓۉۉ, x^GtrUStr,cIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_restorefromtray.png0000664000175000017500000000124312110457565024466 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME PU0IDAT8˕OHTa{oL`6BAN + *KD4E!l B,% OBa4C|s[X(:Ё~r9RrizvTHyC_b[z]wzOKC72 ȋ2 ȍnpզKn)\9c?ɗ{gp`:D.b49{*ٙ]]χ8Djq﨡i;2 x| GjQ5`e0m YXXQRpM:Muql y;+- bHbc"uxrfcbFbHeC YDm=c3L/B'K Mh2vCm:EY?˅#my,?M-'c&)q4 WڥGfBF*9A Bi+JGmA5]x:j Pi?Vѥ nIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/help-about.png0000664000175000017500000000164413110277137022601 0ustar alexxalexxPNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<6IDAT8m[lTeZQN6NSMS.F-Ą+IL'Ai$A  G#ՠiZۂcb-P{ivCK엝W^YKSJqcok u@p~Dָq_PErWw>ξ'B;tdz x;B-/=윊p=FO0kJxƵO@m {0tr߇.R:˖0$i`Yi {FR<ځc[2<| ;YqڍLhs(lEat 岵M$A.f$IBy@f.Ql64EQ ("INyΊт h4`j"úDnKL!Vg"gc8LYd :~E @`P Z_4wqR\}T.)S{&Ъ MiZ7+˲QyGk~C^]7!Ztpi8#Hy~$6 #F ('t)mG^(,+"}߱o_}d$I{= XvT,>L q3s_^y)nr:]ͬ8 +Ϟ:өٶQKKEǏ$d"ݧ( ^zCQtJ()5rY}չ)*%$ڦYϡ!cR`":i8ҘD0fl7MS! sߵ S@G 0h>zY(02\  \R< ߽p1t#ݚ;>p<vIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_markcurrentextension.png0000664000175000017500000000217413016303343025503 0ustar alexxalexxPNG  IHDRa pHYs  tIME 0gIDAT8[t;Not /G=k:E1UG- ц/ :=  Κ'xZ/K^%AwK%wF[^P>G#n% :  EKx6Tد Ȥ+(:U 2  9( j7Kڳ8\7֯݉G[&N  67I" ,]h|Xg~3!  !***B ",u-*s E.;` ѿ  zs]ppp\: L؆((('''ά'&$*3((((((CCCśEEEz[t 6IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_focuscmdline.png0000664000175000017500000000217413014355224023667 0ustar alexxalexxPNG  IHDRa pHYs  tIME  0ۤIDAT8LOsPFgGM:81Ƴs;:jPSF1SF1SiPS:3G75! x4ݼ *fx43KK3)#)tBrQqnms)qnmqnmqnmqnmqnm)))Nq؞IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/edit-redo.png0000664000175000017500000000111713110262523022401 0ustar alexxalexxPNG  IHDRabKGD pHYs B(xtIME '?!IDAT8˝MkQ;_MBLcm6v*~Tc B8nD+p;~Vu)D RjMu!)bL&Md'Ag^ùnjnjQgk[7<~`Mm.8q<LME^vx>'TpuXMUa?)}[PNeڧt5ɹ={V7c3Xu,O# : 6ĥ,-(靳㓱tw$Z 4nUxEG:=x{ `@fM{Uv"3C0c\@nFȂTbTZL\>{tWwvYk-0U4lQ4l69n7J]HaN3E.En ͽZ65$ݖ/܏nխϯ;v?$#P6$E/K^5IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_nextfavoritetabs.png0000664000175000017500000000217413015446652024613 0ustar alexxalexxPNG  IHDRa pHYs  tIME  ) IDAT8 {:;" F J)5%6"3%" m2 0#0N|G?E!V1635$! I|GP&sS06 8 bK8IJM  ${FX1 > K27AB?,tg9D`Rg    7W9BWJD0 2݇ R )JE8E4WK*81r6CS}  'DKeLS(S .3@&;* "@֌3G75! x4q' 8!͹x4x4Jw ݮ9w3KK3J8Z>IZ>I?ELnaIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_reverseorder.png0000664000175000017500000000041212110457565023723 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIMEġEIDAT8ұ q}o(o3d7<FhQJ[N_nCcTqKc5Ћ`-lF*` aJY5c )f]Ln"/Pi!L#l IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_leftreverseorder.png0000664000175000017500000000217413015200640024566 0ustar alexxalexxPNG  IHDRa pHYs  tIME :7ﻓIDAT8f?22U 'Lk6P[72c B2%D@q@q1//$>6g6gf+JL?c`[gKUKwm> g_ Kgb ##IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_multirename.png0000664000175000017500000000141012110457565023535 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME*!NRIDAT8ˍ[HTQ猤e9ZQ$5jì%*C& z) *JLQ,) 2hjdd)99g0LIDio[??WWe%m#^(R(GL6/i&Y4E{^5*:>p%%%eyyM"c"3 KbMu&]a8PZ?0@jj*+o[+A:Bk(ncu 7u0*`8dgeq.\Ld>wʢ=LNe* @clv/䙋,urCa-njjkED$Ãt4JVbC"?C"T˃lD.KK~)۹W%/KNbDDxTA1 W3N7Lȳ &5(ƥw%- +-!W O(8WI !(>i,첅 E)(6= ˳S(At  'D涊z6;+0=m +* "7yS) ]?\3>7y[0OA\xI~;AFw>,>|933s-ԓ?J7Z>IZ>I?E4SOڸa͈%sc:Edx*J?DЇt4Zװ7 m[3~#:xxeG"0UJNn-A+`-0۽/l!B$g9EeL/*:41:\v ß֨ɥLuj.XS"˰>G<.b9#V5KN&}]1Q&ryȡ2D,s5(uЧ#gpv0?fim2iwl. x2|ꐷmiRfA=Fhf(Ţ!)d4žxqp)213uj9Le.gQRq(4ѸlCNC] p)q3i IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_saveselection.png0000664000175000017500000000164012110457565024064 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME A-IDAT8˥[hufgvv'۽ Im!bRI )F*>XxC}R0^hS/}(žԨIk&l6lfg!d۾ ~O80K~=n9'r#SLjKԱ ѾEf}+LC{r cnm zr /o{\8U:㟻CQO,{̜^jص&$PvhܽV/gK)i@ j  r<1[}wQ[de,:.Pp"סiPtG~Q,O(Qj} 6fTRa!o%fijމѷKW[9GFl' L}\ A CXC\kFe̍ɘ^2 o}Lv MPtK.r˒o$ e,l1C'uD3ayb/MWe*ɳ`P |ŸJ܌˛!nYcʞDߎ4/*'xZۉ !]K4ALEV-؇#"(VϿ0/ G#n% :ܺ " tKx-G6#&&+,;?)9 2!   y9V  Kڵ   6ۼZTEٶ KKK&< E.;` ѿ  zs]ppp((('''ά'&$ (7#T`peee9[[[0dx!]IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_quicksearch.png0000664000175000017500000000217413014355224023516 0ustar alexxalexxPNG  IHDRa pHYs  tIME  zIDAT8 IAev] d; {JM! }ZE$VE(%A-#7 P=*  /"_G)^@ÈRÉQj>$ l@ dE) y@r? R8#U//~~ ? #lNZAIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_unmarkcurrentpath.png0000664000175000017500000000217413016303343024766 0ustar alexxalexxPNG  IHDRa pHYs  tIME 7FEIDAT8[t;N3i -M*L v: J 4?*hL5و2/>4/*'xZۉ !]K4ALEV-؇#"(VϿ0/ G#n% :ܺ " tKx-G6#&&+,;?)9 2!    " {YߺTTT 84+5/'ڷرٻ*```*YYYϰ 52( A  $  E %H&&&=Nl7BP HA8DDD㑙)M*Q NE=$   ooo(޽SVyIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_copy.png0000664000175000017500000000217413014355224022166 0ustar alexxalexxPNG  IHDRa pHYs  tIME .-IDAT8O0row.wuz,Q/(((-wuzT'''))))))''')))))) &&'''( )))Ӗ/ b`eqpu|  xv{4\xv{BYJ=5IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/edit-undo.png0000664000175000017500000000121213110262523022411 0ustar alexxalexxPNG  IHDRabKGD pHYs B(xtIME #!IDAT8˕Ohaǿ҈ABCxbDP];<Aui%+$IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_markminus.png0000664000175000017500000000164412110457565023232 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME 8 Y1IDAT8˥[he7|3ݸ6{i VPCJDXD˓JAE/O@" QX*bK&q6n^ٙ!&oq#<#rk}zԍOPE#<@fݻ qk˱'> i٥%}Kӕ;2ĆhFNWbГwLgD۰fTHƷ^(z)>]ٙt:6T]릁+J(:R+Wkj=VtR  Fs+mb;{"m$s4p-f)7",3x_3ԁ1|tSSRƣqwp5Xb55m  x"W%0<-=OJånrF$K`k`0,`(#/~[X1S0L[k:M txq$Iǎq!ϦR鮠5ŘvF~k@wX] 26gat]ǙWxvQF4VrʍD-iDu]=oz2@UUBH͖>W*" ?~2" 6/).f|| AASp8x>,%[4M#=Ϻ]W[~-j{hcc?{IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_prevtab.png0000664000175000017500000000114212110457565022660 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME$ҙYIDAT8œOHQ}qR'e4"Fʕ2XBDB p)Ÿj͢D-$8#P٢p(*p)ڼw[|.:9󔈰h6 $3t͒wN|_q7y&z ٴfF'ؿ>m]Qxal9ʙނ $xZqa*wV "-̥N@H&hXfk 9 --4Fh464a wn% ƉHT|ZXxPJ43XkbףLV jlS#[8dq8a?~ʇRZ<މQ*䬏e E_8UіB ( #+  kDp јE ;x5TIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_debugshowcommandparameters.png0000664000175000017500000000217413015446652026635 0ustar alexxalexxPNG  IHDRa pHYs  tIME  6IDAT8G$&GyEyE4F 26;y]gq3Eq СhlpGyEGIEpQ4ۤ'bmV;,C\k0;>$4 3*5L;6!t:g"  Ҝ elG ,fhid +1#9EֹR]i_jlq4mqt!m^hq増QGG3G8lEqSW\hlp3GyE4&&&yEGyE4GyE4yE4lGl3, MwcuIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_edit.png0000664000175000017500000000217413013742760022145 0ustar alexxalexxPNG  IHDRa pHYs  tIME  2CIDAT8ĠDEEEEE<`f5H5H5H5H5HwwwwwY]'K˹_@ToL0`آK`֭4آK_࿢֬4qآK^༢֬1xv{Í6^۹իo7ԭ6$$D999qC -3---\Z蘹IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_configfoldertabs.png0000664000175000017500000000221612656270711024534 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME"" sIDAT8DHN|GDHhN;  I|GhO<8 bK8IJ X1  UT&BD(!"  ]U, F; ѫZ>F5kM3333333331wH3kUҕX/# afߋ)ArVN]Kܣ9~ \\`=эCw5=ɄIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/document-save.png0000664000175000017500000000161713110262523023304 0ustar alexxalexxPNG  IHDRabKGDC pHYs  tIME 7*ؿtEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGIDAT8˝MHTaL1͑QlQQ4&E.B(,V-*ETR( "((j["DETjܛN al6<=_'?[ظ3 T[&Ÿ?ͻϝ 4wt퍭Uk:#km'-Q7˺; <}۝;ƨf(ce#+s >b$y,%_FDDdsZzD/Hϫ/.wY%<r$qDxXBAA(W'n۱wp=/x|vl_PPP#wҘX̌M4єXi^"2"0e1.XͻǪ Q_ͭ{h\Î,4M9H*|!mkص)i8(m41MCRO-hm aPYYޚ <۶qy!<]s?D30DQ,@.x]:R,Fs4_;3L"bmIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_filespliter.png0000664000175000017500000000124412110457565023542 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME7,=QciTXtCommentCreated with GIMPd.eIDAT8˝?hSQ$/{77T,J)"Z EA:\MZN:):HJ)*Ԅ fpJ٥`b}ihho9{w"vղ2/*h{KvCyɹKA~܊ƭzSPV4 ֧'Ɏ%?zZ3N$'Ɏ -#lLayP:H#d|6Nh]in53'X~ s}\C?W..:ԽZՙV0L#(?0];[ }w_Q` RT63RN'i̇/8<ŠNby*J) @l޽t!ЭԓD"K?WN3 k$/JRvMfCz1} >_&_(#_(qd1G*輡, WuUʕ);P8ئDBr;+Qq]~n5fdIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/edit-select-all.png0000664000175000017500000000067111323355446023514 0ustar alexxalexxPNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<KIDAT8=N@X  .   @I.A ډ)wQ52ͬ3߼7 I<> FZKlo hi1ZkjRY12i4MX,0p/ DdqvXD"$IJžc:KVi" wxS8*9Q18m6*N7qRlFId2ٰEkWZh%{x.>+ml6[0."A%AP[dQQUl$Z-<@!`fqF2t IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_copysamepanel.png0000664000175000017500000000217413014355224024054 0ustar alexxalexxPNG  IHDRa pHYs  tIME  ).4IDAT8O0row.wuz,Q/(((-wuzT9π'vs)d1QqnmsxG-qnmqnmqnmqnm)sBsBsB) _-~@?;9<1  G&>k:!Ӗ/ b`eqpu|  xv{4\xv{HRIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_fileproperties.png0000664000175000017500000000133412110457565024254 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<~IDATxڌRKa~a0uvSsPY̑s.M/B" "$b%sM$4ڦ-f_}sU4YTz I`I ,c8hJ\/G#a_7ɒ"]_~D`pz\~V%30(2T.*P_8\##큯' 9"XYJR__lrqvvp>*_ m C8>sp57#WۍY:Rߟ\'PcP244hy6xuy+122%:{<AB5 | )psV*p8ӡso.=xvwKB. o- -S2Ӊo++B9w[r>.,ږ1S囧'0v|f*&NFy|]Vm0/ IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/list-add.png0000664000175000017500000000050311323355446022237 0ustar alexxalexxPNG  IHDRabKGDC pHYs B(xtIME DxIDAT8͑``rҺ`6[;tqDdZ &g7Z,Vi1v`9=0+n/\ϵUR>.009xrbD["[-$mx\9XwV2@@PiAkeRjt&Rȿ&ROXNOӅ43kgO=TrK wIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_viewhistoryprev.png0000664000175000017500000000217413013475730024511 0ustar alexxalexxPNG  IHDRa pHYs  tIME  /ɀIDAT8ö0'bF5*zG# " "ɯ  *d K^|J\xLwbU4 tC=GvNhk/S0# d v4jLbI!4ͼy4bLNͲB&ͺx4@ Ͷt4 jL?%5#.t FӍSz"-墙 IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rightsortbysize.png0000664000175000017500000000217413014736012024465 0ustar alexxalexxPNG  IHDRa pHYs  tIME '.IOIDAT8GvfBVfy}.VtzDێێDff fJTrrTJg{">Nٿ  Ŀ>K"B&3BjD3&ffffy f@u||~//CCC//II::f||6D]IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_viewlogfile.png0000664000175000017500000000217413013475730023534 0ustar alexxalexxPNG  IHDRa pHYs  tIME  ,dIDAT8HNrrpax 5^âIvvtQHDƸ5c\5]ﶘ"  Ax@x &ɗ'ɗ词ʛ π2geJ z6%oQm*!!+ 1c0ɓsj$;e46ԡe| `4 ZsVeq}\k &\?֝iyJަ | ?K5IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rightthumbview.png0000664000175000017500000000217413015200640024254 0ustar alexxalexxPNG  IHDRa pHYs  tIME ",SIDAT8 {M2 MN7. 'L&I" I"$V$?>'  9 /Q/Q 33+G|,G&%J:LC%E(ͽ3DYt%/˹!!˸!%  ffP;K ;KWsWs$/$///CCq >4OII$R*b)o71#!$)c8IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/application-exit.png0000664000175000017500000000143713110303146024001 0ustar alexxalexxPNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8uOhIz{ a/EAѫhPê( ,.WEP/DP$jwB&l@gd:=?z~_=2I~P"b,ϳgΟ0IC\&"f8IӔ ΣBkR f3iA$ ijpΡ@)1c/hmYW|0 raع[kADы<ؾvNk-ιNnA),!j"_3:mZkOe^t  .߻eO:mTG6x;Xn4>Mі֚nޤs'?Ct>($}}Rt گ[X](`sZqLѠ5?"XDP| o^bXD! .MuJe6JV`r77ܰ,.,Rj!l~\D$//񺺞~a`hbb ˗XֿץZ6>c0QzS†> ϣ&jYٻw@`xGV%Y\`Mxs-곀|mk,+#Za7u9 ?=]eIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/edit-find-replace.png0000664000175000017500000000141013110262523023775 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIMEvhIDAT8˭Ml a3H,VЉࠉ4q RIcKZAD"qD6уK}DHEb[nwg?];;i/Nɓ<y7Wbh4MhTz-?$kKe]KVԈS%U_w?j,a aYd+ԉ˥(cRU5o:H|J[]$t3l`}'ǎ6;{s;ǼlA6W uh 8^o%osy,\j!pp$Cm9XM(O=*|%~2]M:'7yeP*̙Sbr|N JgYtkikypO;o?E[v pXVcnyJ6>~O3ZTϑ{Inn>! /h2 0䛼YĂw;3ɐ ?xHa ? |`U}rb<.v>he~gj6fyc9$Ir<21Hz ɐH$f(`O(rB˹B SKiry νYIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_targetequalsource.png0000664000175000017500000000104412110457565024755 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME*;C4FIDAT8˕jTAg\T1SnBSͺl7l_@DY  d4V+kXxX{gk3G77kY "X4@`Foiuu^59HS,7ΑfYĜY{^19i=}%{l/bST{iV9J2àzi>}fK!s@Z_IYںūmY @e"ULPt~YݍNZyN< BSZ+[ !CU_7c|}'&8roRO?bO2 ކh˿ykq.э6FC_PSJ|Z:O$Icta3IJwgٞ;Hu+0l}9kN~0,zTIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_sortbysize.png0000664000175000017500000000103512110457565023433 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME5?+iTXtCommentCreated with GIMPd.eIDAT8˽KTQϔ @( 䔫- ED KF)Ѱvw}3m!D\߹˸NgvX͌߉@e|v,Zu@QV,}!M^~JPUPJLzwp8d%j O1إTznlut9=?!bQX][|tz8ew0l Bv 5|S`Oʞ1a pK _ Zbgb3ɳI'q\# b: ϗ+BUXz |-nlzn(.-<&cY\knoXs&*W΋gIIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_extractfiles.png0000664000175000017500000000156312110457565023721 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME dsfrIDAT8˝]h[eyOSav[B)"^ntY^HY+L&;{! ܘM܅ ?[ktm&inisYr^/UD|=7}j>^ԣWt_Op7b#<0#{dzu pt{@Jl_xg-"4 M79Ecu±+l`{w[^AA.KKKN^z; SOvT u<+ˊ4gcut|8qIz~S:'/4ּjW23H]Pt\.z4ޝM>NpCMoS-ܡu:'Gj-Fk gcF|<Z:ϭG4&Yjj4lmT, ˬ,dY."5w ೯s,I$Rd粬.0>z]գ?Z&=%>5G,C'2pRԚeZS֪1=gs9\L}cu.J)[Fv)4%!@]*Xr͝LLCN1^!pEt)Q@4un+><T;hY)U&^iKRiRY/xK}'Ef01Nj~\*Gf&cE̜f/hu116L7?<> $Ͽ&/4IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_setalltabsoptionnormal.png0000664000175000017500000000217413013742760026020 0ustar alexxalexxPNG  IHDRa pHYs  tIME   IDAT8DHN|GDHhN;hN;hN; I|GbL8bL8bL8bK8    D BWJD0JD0JD0    B>,W?3slIy"IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_about.png0000664000175000017500000000137412110457565022336 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxdSMHTQ޽gԑƬleH !r#P۴( 讠](V(ȍpQFRVPRZ8:<a;|{5sJzmp]璯iZJJo}3Kmдƺr)C0#'&"\ƶ^XoU[WjKx7ln9%,D}^$Na5pt~ x6$[6DIJ™|O3w\د8(HggI1ϸi 0Ppz.$hg;7uX/c>eC4P]i,dHU׳?ÔZ#p\0x*aIBsqƙ|-Xl-Twj@sK_P&s;6YWM;cZ4͕-@`:{ )<;J mUGmG"HPg9ZQzBS YئOT@smpʶ̪d$[xv/ gwɞK QLEFx5So<:5{EtL^Z]9aZo g%:UIz=A;?Pļ)&l;g{e`B.8WY ~:~/N3{LUo'Vn)B.lӕw#x^0]B]qlygw/ѽa7 hd~x] C02!  pf;ZlإH'ZG{FzE*ʙ,DUo7LK"hNh !20>S_Nӹ^̓ˎx]sIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_operationsviewer.png0000664000175000017500000000125112110457565024623 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME'(iTXtCommentCreated with GIMPd.e IDAT8ˍKUQϾ Ek-u> Q"l$ ́9( Y%8u`h *jt{5>΍l^\nlWDt( h9 nkC34PW6XU/Ĥ(!ldj+[`<@]]ܾ0B\sj>T8vHNh9HMAНa<6 &wl2kL-cg,8X)9O<魭1TSn>- А920(hmC(!emXn/!F+7o+Ā4/ׁ2 RլIɨ(S__"{C8@@)1DrXDUat؅AjwNͭo[%tet@ \5#z=Qm"bH\!,g' %;G1vT, GOu/O&WIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_leftcolumnsview.png0000664000175000017500000000217413015200640024432 0ustar alexxalexxPNG  IHDRa pHYs  tIME 1! IDAT8 B - 4 -P. >Mp++f^ }}~nmjhgONMIP-``" uvnmjhg]\[IP-bc qqnmjhgdba.fGHffjhgpnlff }K2mƩIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_hardlink.png0000664000175000017500000000114512110457565023014 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME |KIDAT8}kSQŴnB!6 EQ"AppOp"1 tRCAqJPQ4Iqx/iRS?8.;=bf־uѕ "/'3K'ժOFʕJi@{$`k{iT"QVVh,(J{4p||JVK p!&'&XY]%q}a3/ =`:g:{ Ɓup*dE@QxHW}O K@q*B&7?xeN؍2N(9w=*PnΜ Ifnũ@29,~jpާMb;Mjoв.UM3P$>Ugpٍ3M'7YF*pC& w_"6#4)ώ]4,/sϗ. ixof)6SIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_loadtabs.png0000664000175000017500000000217413014355224023005 0ustar alexxalexxPNG  IHDRa pHYs  tIME  3"zIDAT8DHN|GDHhN;  I|GhO<8 bK8IJ X1 ۗf Iq D ͳrB"B]FA. NIG _^_NJI3AC,+CBC{F4$cc ~I?[[[SSS'<E.'  Dm{{IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_copyfiledetailstoclip.png0000664000175000017500000000217413015446652025616 0ustar alexxalexxPNG  IHDRa pHYs  tIME  81b;IDAT8WtttXzGO,jMJG Ԗ OLVd tb^  MVdO!їaPV>i! ]qC/nYrg_" TLE~E vWJl^қ0\T7 2J1* h,N7L6L6?)Ry 0,H" H"#}~~rtu$##decsrr66# y^O4B9tIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_setalltabsoptionpathresets.png0000664000175000017500000000217413014736012026704 0ustar alexxalexxPNG  IHDRa pHYs  tIME  7@IDAT8DHN|GDHhN;hN;hN; I|GbL8bL8bL8bK8    D BWJD0JD0JD0    B>,W?3db^jҘC,-gGFCij*?&T &f6''&4ݰuΓ\ΎU l4P;-ձS"|BΈ1lYіB&*# ƨYWʎtD"K??gIX\b, .g0u-*\H^UuuLP2%*39JCVVXIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/document-properties.png0000664000175000017500000000072013110262523024534 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME  +T]IDAT8˭jP l"ނfuء-8(q%.]tiQpNDdМ)v1}qAG%rE"糈d0M3%Q~¥Dz׍j5z^u:JR r}Vv5Zk`:bfneYXVjWwpθX,<A$v{sN-fb1FA0$ C!Zm6& B\.|>RJ;pza4$h\..v-4))? ``0x}+ڶm1$IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_visithomepage.png0000664000175000017500000000115712110457565024067 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڜS=hTAvySőzc! bR  B,$AH iD k€IZITPRD޽{l11vvf[6EZrE؎ !btAB'8$ W+^"aLTOZ$[G (d cGl;5y'kUasy?,:* +L<{E}ϙ)pa粄[3b FU0r#fdo c붔@>=Sjt5JM[h\K lF"'^+26WLC#{y9z{7kVZ}=gƭFm ^zGGyW~kg|σyM._ظuzeӠ9_@魔^L'Y>wCUD\&*XUȘؽ%Bը L8qRlϦˆa $߆xS^ˤ@! D1 H!"bUtsTl&Y` H$83kk ,8ǒ%KUlo ! hޱcЁ0sk<tx [[[WgyCCwN@(fz(b ---3"R0|"آ/2}Nhm Azhfv?CkLZ"Q!`t8+2IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/edit-paste.png0000664000175000017500000000106113110262523022562 0ustar alexxalexxPNG  IHDRa pHYs  tIME IDAT8˕kSQ4$1Ԕ "\\jbpv!8EmA84K.8)RHB^olF91/m ~=?T*{ϝ~I\.konΚ+*+v< |`_)h/Y2g .9.Ҵ0f LD9̤γ׫VTS yf,y_ϲxAPTB"Jqm.f!1 ނD"03sl08[y=j(߼ )>\qKa{UEEȝ<9DAU21 (mnh>A_4!5纀VҨ)onP^CDz\Z14I3XpcZ7l/D#팦$1fSU;`\13TKOxiIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_clearlogfile.png0000664000175000017500000000217413013743363023650 0ustar alexxalexxPNG  IHDRa pHYs  tIME +,SV{IDAT8M6h3iaxE; "+*QHD "/*"hNEBzALEVAx@xy&ɗ[t%#!ZһLrgeJoUj(<94oQ_w!$1c0ɓsj6ԡe|  ZsVeq}\k &\?֝iyJަ | ?ء Qn0IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_showcmdlinehistory.png0000664000175000017500000000217413013742760025156 0ustar alexxalexxPNG  IHDRa pHYs  tIME  :5?SIDAT8T\PFPTT\^}I}{T\J ZX ɑX[EEz t2qq15oo 6A tDjVn#,Ѷ" J3 "))tBrQqnms)qnmqnmqnmqnm)))W G;IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_shellexecute.png0000664000175000017500000000217413014736012023704 0ustar alexxalexxPNG  IHDRa pHYs  tIME  NNIDAT8|GS1!T0ݫTE&O      ^?X`BKX,U~cC a.???!BBDAACxBsBBE QD QF!QHOPR G˳ ^^a /   _/)  ݶ 9+/%  \\Y/:, ׮+1\\!ĭ%Eة F&D s >h cIF # $͌29xguPH(GIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/list-remove.png0000664000175000017500000000036711323355446023014 0ustar alexxalexxPNG  IHDRabKGDC pHYs B(xtIME ;"\IDAT8푱 Pi:+#mF stԶ"DO!ʳ3w&H6暺`?S-FIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_focusswap.png0000664000175000017500000000221613112333276023225 0ustar alexxalexxPNG  IHDRabKGDC pHYs  tIME!CIDAT8MJNMN7zM6xM }? @I" I"$K# K#$***8c$7 b$;  $ | b9(q7 E"  -8$ | #I$  )7!:#,۬ 'AY(4Yݧ& I(; B,a7J^/9O4*0 01#?u > X?$"Ŕ^IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_leftsortbyname.png0000664000175000017500000000217413014736012024250 0ustar alexxalexxPNG  IHDRa pHYs  tIME #/ZIDAT8f*Rg֮g'QgT4\T4\'Qg:(QgR2UR2U(Qg,TfM0NNвԬ8 ββ ~}'QzS6?د] 0;/<B+Rfܽ]%d^TIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/edit-find.png0000664000175000017500000000115113110262523022366 0ustar alexxalexxPNG  IHDRabKGD4g pHYs  tIME %/IDAT8˝MkQ;$MfJR ]hE Uw&o$ADtYwUM;AT(VP5G'M23EHIBRgw=GvM;N!#Lv B]wf2f_Kдkw߾J9zjmŋi+dk&nߌĢ5(4]#Ns ^R>q>sƕ]$ ORpsӶQ %#6Kot Kz Xd4,U~_e% EJvK0n \$[5ܪ-]pi-Nlc5ߣ-F}=kr+Bt4M¹|'+7*|\YT[z,?",+| 0p8TNVdT앬/dߧ>xtXtk뗧d3 ;e+D, XG#n% :  EKx6Tد Ȥ+(:U 2  y9V h8\7*ڵݷ߉Aق"%*ۼt4P{, ܠ6G ":ڃܧ3* cnyIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_cmdlineprev.png0000664000175000017500000000217413015446652023533 0ustar alexxalexxPNG  IHDRa pHYs  tIME  [gIDAT8T\PFPTT\ JLf ]3}̓J ZX ɑX3}>;Ƶ{{Žų[P>3}3}qq15oo̓4̓4 6A ̓4t3Ӡ3bVn&#,Ѷ" J3 "))tBrQqnms)qnmqnmqnmqnmqnm)))DyIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_openbar.png0000664000175000017500000000217413014355224022642 0ustar alexxalexxPNG  IHDRa pHYs  tIME  IDAT8.k. V/f:p # ]D, hW/#  5#4$  3%cG/1i5&nDf3ϏxrflIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_checksumcalc.png0000664000175000017500000000113212110457565023641 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxb?,Xd`|lqVB\L:LjLssse/bHl]i@&V޿YVF7 Ξg`afF1DJJ PcEcx5{RL`[ `(lmm;MKKARLS _~JN{UĂ@=g1\f͘Gnܸs3&fSHjY'\RL?r/]s/jƦֳ̄_cG \QsOf+ûw^<6,-h ÇO|򲺪(̝EBL^TTw o߾eXha[] (yvݺ: tfނkAa1z`T6g2X 0 F|aFT4Ç.\2WRR" 0@e *)fIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/go-jump.png0000664000175000017500000000132313110302615022077 0ustar alexxalexxPNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<eIDAT8}Ka\K iF&J -DDR˨m_("EH&- Di͌:_3iǬgs8JDQ \( "tl}fv%:UQN6nV$'>'{clf ѱ_3;ҺGUW0}[r)2E!pڷKL*1 jj7Ұ{՟|`ZpMC,AHJl6{o@de&\=AoTVUc X hcdc;g?K1Ȥsxn'WByrlSi.K2/;xܘ[tl)sgrvlR@f21GpY@Eǣ9Pv6VUk( xȂd?h95hڈ?Tق Rh*O 8YNIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/go-up.png0000664000175000017500000000121411323355446021565 0ustar alexxalexxPNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8OhAƿ73ٍzhLт@*ՊhDbE-rkJIbREOBM*^DPC)*4&Q!|ߛ!5ɛ|fvn<IuL:.O <WLFfG ฼ʼns֖ǖ% Ep74HK: ]"GJ a2Wk =<؎Ql*eh :}6.N_ +XR"K(u@AVqE؟~ԋ+U?cjJZۆ25|I=/b1 lܺ?n%&Fs'0۶К"IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_editcomment.png0000664000175000017500000000126712110457565023535 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<YIDATxڌmHQy~*"!pdDѢ>!BFAF(,65Շ m)<"=\sHGU0&LIAUO$ne!aCV р3'iNvl$O6eW1JU+\kp77 |Z-up]zi5ְf%:ͫd*S)5ְf#gPʔEʧqiX TD#Oqd 32ìÄT< `3gumvhp;DTyqg kaVv'3vURG΀RuiiC˱6Ujst3Hp7f3;7 ފ= 6!'n Lh;w< <[PYiPwyڼp:{}}A n] ~|{g UQQ*D/X#Zx'T9=[ BeIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_quickview.png0000664000175000017500000000125412110457565023230 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME()9IDAT8˕MHawu5ص6,;BBtحC.:t cq@,@ ! $d-Wl;yfF~.'Q w ?F3piEy1QJԯD@8ye]tNPwRIPaq=Xf P UIPi;)ξE!@}]=--7F`dYBkM.a _Z{7$(9xcNOTl`fltr{7& ζ%X:pǣDl`Л Yi@iȮ|j,60F J(MΎ!,5D,oM^oݱL(zC"EX]ၶU?EK}dnf>2xd+  4/)2D :n(g+ r@ *jL9>IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_settaboptionpathlocked.png0000664000175000017500000000124512110457565025773 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME+rT2IDAT8˥KTQ?t8"j6:QH-&1VjEFT-lZ ᏌH$+ %$py{~[gy8%"lMbn~DZexZ U:iuR²Y;#)afZkR^ڻ'G}¨pl7g|Q s#x"S?yynZn3>"!'pњ CT`gd"1≀^;7 C4f10SSLd(~%CS9C]ZBQӁF=hTxL!VS+5.B>iGExd2/vXZ0Rؗqv ^ DPx^R8Z8*\y§W8Ԗ',^\wEjb0˞}vyG!a~Õ#c,26:L0a Dlz" 9rq Qrfa^AD1(Oz_20!NIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_loadselectionfromclip.png0000664000175000017500000000155312110457565025604 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME 9IDAT8m]h[uHI~lĶvBz7˜n(ݍSȼPoU7ެW^^8o,::"RLAQ6iEXԶ49IN߫ݽ}>VUɽS~"^kΝ~Ų,82!KEڻ=o/P|ߟ;v4wK_|7+C]ӥ/ɘO@,1tk<5@ʼnFGhc   :ó  B#tJEڵmd n q=Nc戥'T~2v$/@>^LP0̐esfk{Ub?گ G.2'ֱ<wgL*U5" q~ aF$"}(v>T[e:  o\m<VM" -cW.ܳX)OP8ҫpI3ѕQTnUJ]kk+gb i5!Cmrō-^ #iD(3d;?f;Hnm=Y> =lVfo4 L‡H{ul7[n@~zf@W ]?K4nP/ybg+fMI@:zDZ+]/ #|,矙f^ P)IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_sortbydate.png0000664000175000017500000000074012110457565023400 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME5\GiTXtCommentCreated with GIMPd.eDIDAT8˵JQ?PDDUV|[K%`a4Xx-E+&xCVbD,#Q;wϜkٰt``˘;:kvZM^$`0w ew[JĻ:2\+ߊmhE6hWkG٪WjxƁX/W|1獬 0@5g(GcW؜88cR_RuAٿm'`_# dBǎ(uO |Iql<[5BRLY(Y#aCw!%!hDGZm;h w|IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_leftopendrives.png0000664000175000017500000000217413015200640024235 0ustar alexxalexxPNG  IHDRa pHYs  tIME 22j\IDAT8 A5 7{G[5k:'!7T'FZ[ ||Ge7%'ff'M  f9%u'OX    ?>>@ D;<  Qz `/"Ry-9& &yz$ <   g 3Y @ 7g=:`%IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_refresh.png0000664000175000017500000000144412110457565022660 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME&J!IDAT8˥[HqoZ.78ٴ$ ,.B(Ԃ.((脆EQ!yᢠ.(Q0QZiWRRAV[͚m߿yHo{/_^~<)%3EMII"=&@L^MJ{b4uR袆xơF򵡘l)c@AN9iYSxﻋ_ 4`u? @5+yi[CskW`Cɐ`!.8 p=~spp'Yc.޵$ RšTp HH,I{c>P[R:vjτpKo!(  G@'?\|Ý0cdնv&Ӭ $Lx<n UabH[6Ƹ ε|e4C Bz^"Ut:=O)KLM H$ϳ.̋ HIF *8yG]w)q{Ѧ[0NЄ>< $p im@64 UoK`P"nqKOaCR?@U9:y0L'" Rq XLƶ2:j .쨄mp&=V-Yv)|rI|dg%e.- ֟WIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_exitfromtray.png0000664000175000017500000000140512110457565023754 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڜSMHQ{EFE.v tEm EQ l@Grk% "#*ZQT{oͽs;w^3a9[wcip0ZѰ~3Ay5RU{WK踥U~IItrw;CLHDo,R [`+#%0] -Avavz /(FZW2^R!S3}*XQ0 ca4Af<;9H d销QL4->ग़ lnP 萛S$݌E E{"ب$&^bna]0ќiI)(6 14 h GEYT+|.ϝYuSCI'MsK dV!1B!B+P]b(55ap#w,V#OY^C2bb]QQCjPM#,+NFt LAF#$*8EaiSKk !. \Ec`~XuTF&#b)iU@^el:j@oDγeG^C"', d,N.#Hs- r]5֗y"X"CqiMr# dIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_rightsortbydate.png0000664000175000017500000000217413014736012024430 0ustar alexxalexxPNG  IHDRa pHYs  tIME (zIDAT8GvfBVfy+DێێDf=fJTrrTJiq3|~|}&3BjD3&fg}f@3%g//CCC//II::f||ΎIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_copypathnosepoffilestoclip.png0000664000175000017500000000217413015446652026702 0ustar alexxalexxPNG  IHDRa pHYs  tIME  +,5OpIDAT8WtttXzGO,jMJG Ԗ vCPU^ QPP 9!!ԎZꮶ>iac $RIC/nYrj}$:3D,J~ǬD - !қ0Z?x { W?)RsUq.jSm4.6WmIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_thumbnailsview.png0000664000175000017500000000113312110457565024256 0ustar alexxalexxPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڜSMkA}==3n ^4ˆ.TP S^ Kt֤UQPt ,.JuWQd_7p~y^w͑_j-ى׏ V A5GXh# #oK0/A\@;<0Ơ:r Pnf*Wѡ } T5مgnݭWu6g6ZQ|N?kSM3@\cw[1YEIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_panelssplitterperpos.png0000664000175000017500000000217413013742760025522 0ustar alexxalexxPNG  IHDRa pHYs  tIME  &ִIDAT8MJNMN7zM6xM }? @I" I"$K# K#$******ZZ~\oR2oR2\~\F.:}:}\F.{< J?.$ fS7>$LHv#/,#0.J<333B JJB 333755D)333333)D755999oC333333###>$Z{ >c*IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_resavefavoritetabs.png0000664000175000017500000000221612656270711025120 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME3n+IDAT8FGH [RT\bDHUDHhN; #,1~qd@hR< 8 J X1       |F E ]?5:=;'ryG4 . 2i3~B>,W /" N= R )JE7 3   M~  'Z$<զ#4"J*Ȃ0uo@n6 S"/ok0uk I)οP+ Jw ݮ9w!<  sXZ>*b)Y.VcIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/actions/cm_unmarkcurrentname.png0000664000175000017500000000217413016303343024752 0ustar alexxalexxPNG  IHDRa pHYs  tIME -ˣjIDAT8[t;N3i -M*L v: J 4?*hL5و2/>4/*'xZۉ !]K4ALEV-؇#"(VϿ0/ G#n% :ܺ " tKx-G6#&&+,;?)9 2!   y9V h8\7*ڵݷ߉Aق"%*ۼt4P{, ܠ6G ":ڃܧ3* pp)} IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/0000775000175000017500000000000013244011205020370 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/video-x-generic.png0000664000175000017500000000132111312762055024072 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<NIDATxڅSMkQ=3iڅta-&~A[Z XUjq!.\(V(bQ7J*(HVnZu$fQlL65GE3wy$AӴCh1xh-[SL yOsn&uuv4:n`Zk@ Hvuww0H)es &ض:{ɫ]IBUdIr^L:Ocn.۰{B W.O H$}6԰ğk 6+R C4zůEܙMb*e*5x>Xyl8::A8qnݯul؎BqF1}k@USy|Jo_?RhOnJ%Χ,  jTThh(BGOKS4;I##$y^U Z/>/j^T;3R(d<һfP*, D>[4A0yvyЉS W2y,T,!uWYT6{7oxsy;|ߗrԵL1·dhX~m8|nIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/text-x-pascal.png0000664000175000017500000000126011312762055023601 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<-IDATxڅSMP=IM[RpppZ WҍɂH2*80 hN?IQxR8=@Ӗ{Q‚zq`)&/q¾۔{$JLPM/ +@EXE۶N@#F4mwqY9Cl~N WA <~V&kaJxfGr$(Qtԭ:6>|wUI qCnsz&H܉qi<Sz8'ȋUf).L5'`\wp3nՎ,":jht&3&?3┈?3ӀIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/x-office-spreadsheet.png0000664000175000017500000000077211323355446025127 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<wIDATxڕS=O0}EU*€:0ЮlWǸu{4M4MeKɶ)(2yK2`WdBj!4y VAeIA,6g/>l@l9ۀ@BA~Z ( rr,+I c4i'J47b|2n sx( &l߻aU0AѓdJJl;ğgF\ }ȍIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/application-x-cd-image.png0000664000175000017500000000120511312762055025322 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڕjAͥg&Zĝo#t5\F"/\zfzVeu48C%!'9PZg׿TVL1 /"̼Cz4c6W,ON!Y\ZYxz:IDd9gw=J"bi{vDҸ3>Lbd(T"/]{w]ItM31 ,;sDBO8=Xvf*dk38F 7Pp4Vھ݉\3o"5 egWָ:o]\9P$flX>o,;3`2{50$Lj3 r |C|.[8_.R,LDRxFMIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/package-x-generic.png0000664000175000017500000000067713063505653024400 0ustar alexxalexxPNG  IHDRabKGD pHYsStIME ;}lLIDAT8˥KJAv:L1@܉P.č7Apέ^ ŀկI SZ__w!ofwZ %(xڧ.;[Q2lԸLJcG ies_,G8o+dԓa*u eDS=)xsF+ވqg'5 HƨV Qщv fWШ0|)v kZW;r> &o6#n3cIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/application-x-deb.png0000664000175000017500000000132411312762055024410 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<QIDATxڥSMHTQ=SKS&~4B6.k]w%.[6[Hт~Bpa6::ͼw"w|{1W2$4slnpꕨ#MSHYC&c 5qw?ݢQ?%If d:+J˲h)Df0+*C=\2pk4HW@9v;~m۵px绔IZUBhƵ뺟|AI<(_,^9Y([O$Y  !FIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/image-x-generic.png0000664000175000017500000000105611323355446024057 0ustar alexxalexxPNG  IHDRabKGD pHYs B(xtIME 6IDAT8˝MkA4ݘॅ\ĢSɃ@g(1 z @ ՞TD*C"&nٙab !{fgDQ[3ZyBQ3ZjQ31nKVWpf,µM4(HakM0؂33sZ$(l~{?CR@4yò,.1SrzoD'S@)_@JNh'-\̟.@:} b}x{_ʧ|=({hmh9%_}z=oj%1@usIo?GN7.nքaQN&x3iv$ĉqǨLdk&|[Z? Ƚk^CrB0EJXᖋBIENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/text-x-log.png0000664000175000017500000000116511323355446023127 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڕSn@'n8C%7n KT<HKVmP8.Os`O3;/qp.?=v%}2SJIQtrQy_!`QKe59[nAmtj4@pPCh6ch x4p=x,ϕbqN")(DQ7ԪoJTBLۃs"̃hqm {p4VEKD8;9? x!|ݽީoF@탨 2hue0'<~8Yfc YZ/0P 0Ur8j8Zs@sb4"Y.//cW/Kphݮ,mtjy5$IQm~n)c]sgJrY߹PvP |j HL6IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/application-x-rpm.png0000664000175000017500000000134011312762055024452 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<]IDATxڥSMHQyOE|aDEqY+q鲶.h#HB(e"~|3oܿ7Ņ->ܙ{|92c .qgW06Xǯg: .90R?!ڐgdUxu4*=JłTe@E󮯯5W*O` .)YQ*3#$|: ^z0qm\,T&B7B)V |w.`zy.~lkHs\?ʹ`mw TLh%q/rJkHR4" H#H%fy ~t_G.MX 7R/8=e"Wޖm諔xzNam 4Jg kH%]T)W."NbiSS4!݋Wnߙ̼xrL6QZOV:zZx:,~#} h/m&5H8.HRL9ט{AY $5?\#A0{/N%IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/x-office-document.png0000664000175000017500000000061011323355446024425 0ustar alexxalexxPNG  IHDRabKGD pHYs  tIME  )TIDAT8˭J@Ir('[ "&xYZ X0!i|_@tD] #xjv YNaEi(əy@D&`6PZk$)5%"z.NA#Aba`Vs_3c,2mj [klvy|!Iմy;v "߮a?A7`c^nk?Bg}TЙD# "RD1yER*6MJ3K_Ut8F~IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/application-pdf.png0000664000175000017500000000126011312762055024161 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<-IDATxڕKQǿoM%AzP,4!x*D hmoC1M4FAׅ>bwJ:~D"Adne0~P Rp`H& Ľ`bsmmH#>6O@$ k5TqI ϳOHgpsB.,$2xyr7ߏ9]a!gF"GPx0"4rem.,|R[ڬt:{(voO$@)+ B 5%GKd8E$if2 7LF&ipx8`&"Reo#0/_ ս/ fvF&H=]UTE ULFyWiv":pXG\nv7sd~ix|=xTc{ߦReu voQ>8xҮN6efff+VB%t]r_Y(⢘@?Ȟ2qݓaĄWY>>Ηֲ-|Q?v }IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/text-x-generic.png0000664000175000017500000000116511312762055023756 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڕSn@'n8C%7n KT<HKVmP8.Os`O3;/qp.?=v%}2SJIQtrQy_!`QKe59[nAmtj4@pPCh6ch x4p=x,ϕbqN")(DQ7ԪoJTBLۃs"̃hqm {p4VEKD8;9? x!|ݽީoF@탨 2hue0'<~8Yfc YZ/0P 0Ur8j8Zs@sb4"Y.//cW/Kphݮ,mtjy5$IQm~n)c]sgJrY߹PvP |j HL6IENDB`doublecmd-0.8.2/pixmaps/dctheme/16x16/mimetypes/audio-x-generic.png0000664000175000017500000000120311312762055024064 0ustar alexxalexxPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڍSkAfdW֤HBNn%!+=#?" HC^KOH#h~$6 a7N=6&̬RB@? 2h4Hq#! ]}I 9R80&P0/ncq$>1q09(8O?=40UX)L]NmVs(}BRlvT iɶiaμ3Εe(fmXz4uIضVE >x<^]μ`D"9K#yub1"z, #ahL9~|;Ass98CT[01x!6 _{ W4Mt:`ۖO8 X{(zkZU5[bgj#/8o;0d-qgۆ*6 Q!5Pg`Eb$Ƨۛƣ,S\=%mfqz,O\;wˊ0($iodՇʾJ6pUW,g <rkWuS؎d2fӧ+2ɕbQIy|WRJU.U: ZW2uŠT*UkP(ѱ9`O-r;.~r IENDB`doublecmd-0.8.2/pixmaps/dctheme/scalable/0000775000175000017500000000000013244011205017335 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/scalable/devices/0000775000175000017500000000000013244011205020757 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/scalable/devices/drive-harddisk.svg0000664000175000017500000005657013175314305024427 0ustar alexxalexx image/svg+xml Drive - Hard Disk Jakub Steiner hdd hard drive fixed media solid http://jimmac.musichall.cz doublecmd-0.8.2/pixmaps/dctheme/scalable/devices/drive-removable-media.svg0000664000175000017500000004475213175314305025666 0ustar alexxalexx image/svg+xml Drive - Removable Jakub Steiner media removable http://jimmac.musichall.cz doublecmd-0.8.2/pixmaps/dctheme/scalable/devices/network-wired.svg0000664000175000017500000005066413175314305024326 0ustar alexxalexx image/svg+xml Jakub Steiner http://jimmac.musichall.cz Network doublecmd-0.8.2/pixmaps/dctheme/scalable/devices/media-floppy.svg0000664000175000017500000003367613175314305024117 0ustar alexxalexx image/svg+xml Media Floppy Tuomas Kuosmanen http://www.tango-project.org save document store file io floppy media Jakub Steiner doublecmd-0.8.2/pixmaps/dctheme/scalable/devices/media-flash.svg0000664000175000017500000006540313175314305023674 0ustar alexxalexx image/svg+xml Jakub Steiner http://jimmac.musichall.cz Generic Flash Media flash memory removable photo Novell, Inc., Jakub Steiner doublecmd-0.8.2/pixmaps/dctheme/scalable/devices/media-optical.svg0000664000175000017500000007060313175314305024230 0ustar alexxalexx image/svg+xml Media CD-ROM Jakub Steiner http://jimmac.musichall.cz cdrom media removable cd audio doublecmd-0.8.2/pixmaps/dctheme/scalable/devices/drive-optical.svg0000664000175000017500000005673313175314305024272 0ustar alexxalexx image/svg+xml Drive - CD-ROM Jakub Steiner cdrom cd-rom optical drive http://jimmac.musichall.cz doublecmd-0.8.2/pixmaps/dctheme/scalable/devices/drive-removable-media-usb.svgz0000664000175000017500000001022713175315140026633 0ustar alexxalexx\mo#7:K+Xw.wYjyt%CǞ"jm|dNajurקc.֫!Tb8WlpMVr/Wo.lp'z6x\> ~ZNvZ4zs;~;8;ۏo ڞϦæfͦzYիv mi6vFf6%24XZm?vdK]Q1Z?- EcB{g!TqsYWz7~}器fM<±ɴގS9r (P/n?ZqQ?mt91AX. LVhd=|mwTQvquir{D%#]J2;[Oi4lXm pvWMEFv_]}:.d6MTKv_~u1zOnrHfsdw֜J!] nt_3AKKebŸ捓W{'gKlx3|D^}OVl?LW)[hlxջLV;BhOT`*'| rrRI?W6eX;RD՛ᄏ{|UXr{>?&!|i҂")BhzI+<}Į<_4|X㫟A>bhʞZi{OIcmk8%HSdv U9^#h:< WH4S\_GRg+c?G ӗ"7ep.Sd6 Tl{Bd GS^#{@]bP _GYSu*[;12-2f𧈸Xbw(:P+FrzW?UzO3+&Mp&s5p' 5,5e%;zuNK{M:R1a-:[e Nfe=:(Π*S:嫟[g|~@acmŀ=uqIV?W8bI&ej] H[LoOʅw?ʞaoN7OP@p~3GI%QeN#,P˹&}m&Gr)5(ӗs q#| 5Zsz"{:) 'D/Qgيe}b}뻁[N ȹзl/sWo\Ov G҃ 2G(7rz~@ rBVHuC DQ( zP2{zc cmfd.P8pC83QYج;:` Xi W H*"\3}Qf[FdY<#OV)k+6 _,$'y ̏ryzsN|}.ШZVm^[!9EfoWʰYV'+>_[17TLxaj*dtii1&uTyJ~&;DŽnBν4!pF5K4 q%l*\aTW.aBBDH4uv) 皬$71֯~>+]\t!z4l=6(Y"'yTJt ޷Cwc+/EVBLe~7sҭu# GEXI|0AԌME4m?ꭊ7GoLTDdqU蓤z~f.ˤ@2`9aH/XZ|[%Mppw+n=1cEÍ* iMe >(c>½K h3b|H^!laW/7UsQ.|ua7Þbf:xYtr&KN`4{&->DmX&@#W:\."0,#koq+NKmP,X[+g[@~^_/DD%<^:tWƢ'FS#sNg'O1:?!K.Jf³y"4jXu_]2'-Ϗ'/XV'1".U)R5gJ>I\H0D8/*P66M:Gč81a$&Rǂ4t .oi^kmP\|4 slUzCpBDCxw-fіKϝ̵D[=›[|;pGFt-6BsK|O6"\P1~PkE~5cZkqb\'P[;o.q[В\ߓ[mg(S(sc++PdE~q3?oBn/ηP6]l:uw|Sy,w;z—_]xvcwzPN|yxžwқ8Z牃l+pz)s caG^V2y]F><#h ƙEe>;`v~d퀣΄_׌J[Iobܸ4Řtt5 )OHHgJB:uҋ?"!ݴyòejRжCX9N$cJ,\IN PN 7ml;YM)3 ͦ,M֌ ue{Dƶ%|͘Sh (*FBV8X"-Jȑ6r`!<ӶK~f]xd~$쩖Ff2BK6%7l4-6u|KYr=ÆLD c R<P$b)#FFs h 숆v4;-IÈFR[nA`, ^"03R(هJ+nj`.%KLH' ӄ kIʱ>6*R[+HSτošCAdƲRn:Lm24)~@I[:~9V`pM!K;cc#CaL1T|CG]DL< x=r4{Du6a/*A8 JHc%@+)U”ۀcBiP+cɠ}ՏJP8GՌ̄& AEr+՚ʓمȯd.giJLJ 2H+. [EMMi M*է먑fjd255rC52"S#ƭ1jՈPF25"kHB>]l\GܡL\GlF&S#Q#uFFdjd:j35jEGLF2S#Q#QQ˛Hgjdr52"S#ȊV,dj5C5LdGF2S#fjHwHgj%ڄuF2S#쨑ꨑHej:j$ȈL0S#O'HWs5OYL>]lGlG S#騑eg#l䳳﨑訑է=T#Hgj:j$HwHejwHgjaG0S3!Q#Hej;g#vF@DFQ#8T#;j5LTFF:T#Q#djhVaFQ#Q#Hv﨑25tqLDjorI_.vohPdoublecmd-0.8.2/pixmaps/dctheme/scalable/actions/0000775000175000017500000000000013244011205020775 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/scalable/actions/go-up.svg0000664000175000017500000002003213175313470022556 0ustar alexxalexx image/svg+xml Jakub Steiner http://jimmac.musichall.cz Go Up go higher up arrow pointer > Andreas Nilsson doublecmd-0.8.2/pixmaps/dctheme/scalable/actions/view-sort-descending.svg0000664000175000017500000000222013175313470025566 0ustar alexxalexx doublecmd-0.8.2/pixmaps/dctheme/scalable/actions/view-sort-ascending.svg0000664000175000017500000000216613175313470025427 0ustar alexxalexx doublecmd-0.8.2/pixmaps/dctheme/scalable/mimetypes/0000775000175000017500000000000013244011205021351 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/scalable/mimetypes/package-x-generic.svg0000664000175000017500000002326613175313470025371 0ustar alexxalexx image/svg+xml doublecmd-0.8.2/pixmaps/dctheme/scalable/mimetypes/application-x-executable.svg0000664000175000017500000002312613175313470027001 0ustar alexxalexx image/svg+xml Executable Jakub Steiner http://jimmac.musichall.cz/ executable program binary bin script shell doublecmd-0.8.2/pixmaps/dctheme/scalable/mimetypes/unknown.svg0000664000175000017500000001761113175313470023613 0ustar alexxalexx image/svg+xml doublecmd-0.8.2/pixmaps/dctheme/128x128/0000775000175000017500000000000013244011205016524 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/128x128/actions/0000775000175000017500000000000013244011205020164 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/128x128/actions/view-sort-descending.png0000664000175000017500000000521713175313470024753 0ustar alexxalexxPNG  IHDR>asBIT|d pHYsvvxtEXtSoftwarewww.inkscape.org< IDATx\Uǿ ?bZ (A-fME!EV0H(!~Z(!) ;2dAښh PXi}scf){3w>fsν3λ}wAAAAAAAAkРRl#5+"(9"#(9"#(9"S4y1n;L]f QR1} ިT*HC%"wj 3?`Q?"?RVi0(j&K}/\+뺟݄nR Q?OJYr@|,~"qrB7))gV:޲"m^!_! P*e%AJjd*jpVB7))R\OF钉Ǝx)(؄nR3 u8s /%ҟ `ll"W)jZ%GTJϐplR?)ْVZu6]ׇ1.}I|Rs(1IQ(.W)9aL>\I:ҟ3F6꫷љ2Tm3pp] DDgX#$ #b9ABJJNaA*@@@@@@@@IFaܹDԲ$8st -{7NWf4XvoPJ` /|e9(RjRj˘yFp5O>,e[y8?B$c sk2A||T90)ISzpRǘKL]=-@OA^.YpC{MYshOdq;jvO"~oZT}yt^o߾[u2,pJէu]㼁6\d&uOceNpzZ5/u11SAɿTٟMjh4ݻN3j+)oPJYan\}}?8RG(޵kK$}@ainlG5L  S01A3Zk̹<&g3+)apټƘ}+co%04Xr1͠c̓DfEQj{R*wJ)5k1 HZ뫐rC U ݼZ)mW:c1'^} [@~:==}[ gqb/&vN^uI3c^Dm\F茌%Nb&x65 lʍ.5f\u383?gh4۶/-ٶ}i^ ,v2ȶK!Gm۾(6zaBqŝ @Ǘ,YraQx.[w43Of ~yvf 8"Xx͛7Oo`SJryv?k;cKkzz"470}zn; 4͛۶am+bCh6$Lml"x30s$^/N3ESzRpɁUׇ0lVyAAAAAAAA('|+IENDB`doublecmd-0.8.2/pixmaps/dctheme/128x128/actions/view-sort-ascending.png0000664000175000017500000000521513175313470024601 0ustar alexxalexxPNG  IHDR>asBIT|d pHYsvvxtEXtSoftwarewww.inkscape.org< IDATxǿKeڴ6џLx})Z֤WJT+VTeC̬=rv폘wԐGKh?m;3I>ϓ<}fwyAAAAAAAaAa:|LRyfͪpV׊0sL:uL|Eo6)K6([Rś|{XtCX>'p9J?._ ؠ;Xm8q?,kAD&5P*<7EkR鬳Sm`w#HDי]`ps;;;_<|`tJODCjuR9088wuu]0mڴur 7Xc`!2 ch``>r."އˮvNR?Z;UOi5V k췭5ЖT*~|?j" -_>Jm)Bp*Vm;y޼H 'OL* JWy9ʫYj}2]BwN~Le-`,TjJT4͌y(>tppp,J`5uH4>>": PJ] u!ljmS (0 m}9k5 ۶}oCDTb?W*C9@)~E} rرyiqD40{e[n=Vn͠eN7_O~磿.̼ttttWvA˗u>L__8bM4FGGׂLl8 p&~b`fw5v43BO[av:nLelv\Ȁ!Nض0wttlQJm\.^\.0Xx)X~_\n T+U"[l9P]4?`3D4fkZ &fW.J%ђdf&[Su~Zo;#Ik{.&Ȳ'C P*L&@[R[A'rat1f\.83~_\^NBp\.9%=EEbD-P;,"kw.H)i?PJmB"v8oq!>uor]dZ OFٵ䇦i Z뾚N?OD̩_~yL*q~Y#Eg~u,z>͟HTsν{8νL""ZNDO8HDox)ok[9/ OpX3iuX<jRjL i~ym{9y=⺮3հ0,G\| SLkR늟(3:N"[` @) }G^:AEXo5][AZmyx uݟmb{XS,l5ޤ8sm_VX_ go9*Dq銓8/Qڸu&el#Quv/~f6]ݣVàՕI\>  N~HH8"#H8"#H8"#H8-蚇[u38lI-:Rj.3?pq0JB "vi0NAm)Al~_ 8l80Iv˲kՑ֯`ZtH~&pia5rM8sXT@鹌:NZ8D*4T*xilW" 2'?\"@oo,|:R<äG@r+,:NZ4*ˉ&J돈`QTv*?BB3J~izzzѽM 1;t'? RlpqqAROJ m, ͜]'?FJmwO)Ѳ)ѣK͌eJcr,DVG2B,f~|B`BLf/"#H8"AAAAAAAAIIfIENDB`doublecmd-0.8.2/pixmaps/dctheme/128x128/actions/go-up.png0000664000175000017500000001615213175313470021742 0ustar alexxalexxPNG  IHDR>asBIT|d pHYs'_'_jtEXtSoftwarewww.inkscape.org< tEXtTitleGo Up.CtEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATx{p}?]H<IHHHJ@ITtM[xvNŧ(:uWWK.v|Ϗ8eٱY%:z$x.v陝],vAj1=3=^= ******⦅ʁ+x+{,uSNhB@^2W}_UXJt?SG!bNlĿ{ue2WϰOĽx+h ӄQS?[77d2{6XVWr]x`-S4ֵкg_G)p_GSn7=+ڕ԰敜p@D^lYoz qSGD<~ 6mp[ڰ3\tqxSW#M{6q'_MZWmz2}K֞w};nק%{?-Miz6#c~3|9ƒ#Lڼͭ;9 es^![/ d~;a!k1B1V6@$Ɩ|4Rض>;eJǰn 7Z7 &1@gdꢑ+F&/Ro~XMm[9y 2=]Vv|ME |?oK4pb'# +XU5%h[;~"}NO'> )@M-+8nIN)#$4~[M4XBss#;!"~2g-*n <KCc6M \"kgO=p"@&L"x$k6mC6nѳnzZe[]M_yH-~DMC9`m)ĊP:<7W -("\ˊ䈓ĒoܥNzߧni`b_mkn}DA81|3D{#43 j+h_O"VNӝ=;:@Ų$@SCO԰}3#)xsnइ5 o7QJ!`GSo ˎ]O?UY;ٰj3W'/֥=A#~2ʺM\{ M[׳&^8 |^{`ѿ"aYޣ5>Qvv`2uW~HVeܣf>EJjd CglIJi=*ap <ֹ?쵥y Ų!?!v`&?$5! ml+lم%1oWG4(Ŷ{쯟;eAǨKr;{xd'D, hɗ ML0e;18rqnɊuփ7νϢX$=@ȽO`ǹ̳[< }MxҋĬ8USc6k'ďh\'?ˊ&΍Iw4FsAoKP>M'#[2ϻ_ k4Q)`1`4ښzZ׷s[RᡎycWNJF`^xF> {H]blHAE2h%.[7& '=|c_E{@%BE)IG{2Sv)g̉(lep456mᱮO!(;C'~ յ!^9}p?ulAQQ螈8o4=I"^ _ru2G\Kβ=䤇JxyP11@ӉO @]MO<ZVE?˙)fh7_[P }lpjh%Km οE6dogwl~TϫTt'7{[:X* M2G ah,kVZw!%%xd%C `,j8'x.3q2 aa8]mq IQXᧇNzC xd%EY  }ǃuj!vX2,,e#t dS5"t]\MMW`q8B\-<~߈6N&f\k!{!q Ʀ&:%"z߿؛^#QG*︛}Z;ýL5r}O+mj>)s+(L_\Z cߍ Rd ʠ=G"%Bdzhyazć㌗ ߙ7l_|xW_etj3a;0:NDkA|B,-}gA)2jD'u!Zf>Oشzt3cS\$bݿp/3 {c L?*C|?odƻFG@aֳr,FpC|qeAQiR4qkhwP V#e'ucbrF s;E%@ӱA H"KittN rfu0>GnQR4|kRxn89-uqOGFkP^[0/=\߸K,nmفS:SV]a,zJ܅wK>y(>l_]G\x ~=k`D hP`=lIf$әqf)|i&C>n!g} {L6ݱ>K(H,  ~ ~;8/Y= clfn/AC2V«@9uoG dji{SC D :ܳkX}b6=DV}#2p鱐@j=$^% 9ĽN0!an~=hkTnz䧇1#=ߛ\Z)(-au$ض}|'ęrx/>5Lxh$ǝ蝀yLD<`y1M>N:7t3#~/&h DNyY;"=,vd@I н7XzO<%j( E_VrC~}^ܱAg qQLe3J/\gdpo*Gk. rufz(-`XwڥJlb3WJ= P?EV4G5nd]F㇇{ ˲}ݢ 2(I7vRDߟg{Kۂ so*v? ^Z;=麅 LgƼc3?ۯaP<7Iށ~@T9}%Fž:LtiSDS"l_ʨ ԲSԋjK&@`ح4/"N̎6L! /{NTo9 ΀0\ \K]brfsayQM`H8SSp@(d tL@@)Zgg|5://h7_A"L@yÂNr=597}0f8qO ר@T$>V$op"( 8B3 TYg Bе*&I#WGȪtP#ݲ JɛrWr<$Xxxg0+|{njN !r ^8"F @@'` ɋ `|0`J谹~ Kr2e'd[1|֦, BiKj勊'R43v27Y]A(M _ {sN4]1a,P&_`z/. qw$Py<&@23#A9>lXJ C)O(ba$6a9~'0 Xo !(!Fb+=p%FFٽR.'Ty{(4D-Ƈbp) |sx?&DćʶI[X]301_2]iòAfr&暀+g"X uN#'Kh$<T>H"$pj\]P9s)K̑*joHۍ^F$.<觅;ˊ;+qcrM2f 4*ja^8Q;*S>ۍK lu?_r,5L(. #)[δ_1{`^wc.2$IALYRB,;k5Ѳwooi *D#^ZVsTF[NdK3JsѰX'h+O9h-6T {8ZWɌ;5ei/`BgQ,-$B%E PHȳ ߯Snv x__Zo '垯 oQ0 S&AVGi)0 lKJR ,Ĺ P6pQ+VדS=1qLSy"(b\l Qnu2 sޣq|z[nf EⅬk!(ls`kPBHA) & ZWpMxK:3w y.-9V@3$CM8gԴ3 >2JmΛ !@H>gvbD$ػwt'X_9kEi22܅̛/v;/.<*~ %:M~&vk7~?";BЪv^X(]8?Qx`Bo$X IE%'BPF5\.gO_-Y휱bnlΟQ{(xo冝TEP+9[`W(KZX RrE> V.TWLۂ G8|Ma\,Mm |1J!+ޟ  XTP &Laf{Xp)`m1)6yQ}!S_ E>51ŚB/Z> %\ }6_/DŐ,ϗFJ$|.VQOm~@oq%(,,˭qs1QMa#Bq$̬_Mχr g\k! QqeC% >m\E<"P PF1YhφJ`******2C砦IENDB`doublecmd-0.8.2/pixmaps/dctheme/128x128/mimetypes/0000775000175000017500000000000013244011205020540 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/128x128/mimetypes/unknown.png0000664000175000017500000000505113175313470022762 0ustar alexxalexxPNG  IHDR>asBIT|d pHYs+tEXtSoftwarewww.inkscape.org< IDATxSIǿ3$$$@ėTCy`rx*~C TS'~ȡ5 <L5E`8T`rx"A ^P`r0T3,őL*$d &CeH:Œ(7oak{h,o6U.TWԠ nWN!(<}` 8g(vQ~Z fSU˿o`6b8_AC;X[$mߙ^ CuM&A@ss#2{EQpm| V+opzi3AOvNjN;&&]Waj:UWW nƍ?*/%Ŕ_8ޓb-/!dݺiϻ^=a*։4N'NvխT)'%eumjmm'ag'K[Ђ) `)+#t8 Im,ORʔ$ۍvuur͇0 L@sQ"d2EX<EQliL@ggт "V_(ZL- sU:qt7>hJ՗WKAbۆ#uoSv~z;ҎʝmhoV_JQbOd+ խM pqx3lmnw%Z[OR'T>_3*+bfk EU1=yCpLOACNim fga'"mooE]6`NE8lv Qa{H$Y$Q+_Z^Wa*KKA, ^p^`ISzH&1~lپ^twأܒB39yp8]oO'r|YxX-8׋s}:xTx&H% To^nŐy`p0|zw;xt.J'pm'E vy}}-]M s~Fi\uu4\P@Ӏ҄rz%:567•+J&??e1Q!Hh1pDc1+wu1 iKEQDoOg<* &8ExvX_w"x dIF1~(hll` 'Y㠝?\n =,%L^U"xR|LcN'[Azʲ\O)E`*?,E`K?󢫳vzXŽA6䡍)1dÉ@~8T`r`,HdqQ؀3=)2aG"]loXZ "\>tvf60(z@;H11`d\=4SShjl0.0\"=_8},2c/~ȕd*td.J?J &Da)mm=G3lőzÞM4ʨt&_ Bb`#_|}+P__NF- FGZq(+xR 558PXL$L>4={΁&% 5 `N11K8t`rL'9yRp~.a>0!S<؃&`\>:t;oq ^[}>ǩ x슣{m8)+ P.IbTГe"J%d>O A,{N9yHĶ(EQ,>O 9s.%IR @֭[\DTi@ p[/ ȫx_y4TUP@DQl6r9p8Y --A.IENDB`doublecmd-0.8.2/pixmaps/dctheme/128x128/mimetypes/application-x-executable.png0000664000175000017500000002242213175313470026153 0ustar alexxalexxPNG  IHDR>asBIT|d pHYs'_'_jtEXtSoftwarewww.inkscape.org<tEXtTitleExecutabletEXtAuthorJakub Steiner/"tEXtSourcehttp://jimmac.musichall.cz/iXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/ IDATxi$you};{;.OQD"N ,P1"A 2`I.) ?(,#ǎmާD{pwgw:󡺺x][oUޣnmmݶvnmmB 첉'<6=y.ە ]]'ޟ} i}nWk$ɓғMwҕzK@ "KЍ$^yO?{y TZZy[@3B~sjVugV"Sή^xY{9|`H`o*? t܈iZBV[|f#.;ci!s# .\8~0r%D=meYd_D$<ؤb *. LnB,~-i?hoi´,½'ه,s|jt$*/Ͱ`p8.>q w ڌζ^`Մ̃wGȩ&s3pF'@;~瀿/)QlaZ++̯$yAgf27usF&@ûb +LlՀ/vՙ.O`Z sk~ÒF!@O ݀0M\!x8NZ^O!A F?;qydEzir4T* .rZ\.`yG@H =1 t; t/(nJog+=epiq<}]78sqKk Z2חYB> f}Q {{_xuu6mn)L01ZBÈ`aa9I"P HWk{z6Ӥe&~,=] nJf=T@+z~:l.^&n2ca9 pS9fy..] {MC]xf|9WVwR<ˉw۲O* QN:ZG{NF/ n /|>{x?+EBzl׮t7-. i Ƕ,&&8}a C7+BH›/As/?sB6 '/}bW/WGՌ` xmoRvel*VPvvsp_w@Oyiqjləb]\E;N+HM}<"FC@]:Q5U 3^-sM7x냏+v藍}\]4} hksh$P[4]4d'J, cuhmj@,qSNF2kST>G@ Gm][PXy昙x {4+h91υsNIPol l~" aZa}=m?M"HE*$)aYs䗿GWW//pnnm 6wzN1Lwsu1;2ıR˲X,8zmMRr0quku˹+%p/]v!e ]2L2錓-`5}ejf esۀ+0~e~jh7X'Hb QE; ܽbj.fr[}J9|+(E {tp-@UF=k$ w >:=bz!^Yru9K8N^O(qc(׹Tw_H:c2̅ҰF伴NX"#a^&e !o>Xך 05٨#32F/Ajp~Cr]NxX,ez>F_O;$Ja&+Ih% :?`,ټO Wu\r6㘆` eo׺&/syfLt+PBVɻ -w#_ɻݍ5.͑LYeiXB.z.2(Jo;hurD( y>stVL 2 yMKkvԀjmZΫx<]li87>BG 旒ǓKYlŕݝ-47^Ra9 =>WP)D*(Yc:`$0ɧRJwg+mM['U; ?5I6Ծftw%PWRD#ݝ0BӫYw&!_fzҎM 8srKWx4tVg.Z[(/kv:hmn,z|pIުf0 M= :eڅr׌-69'eYYv!JACUumypA}҃?Ik{BZ?;Dz/PwW{d<__ R[>lAp`k57|pK3k֚FʇE΃䱇\c 5.|r}4D#iOۺ.4~  yTMS0x~1bfNmEIVV45 +ky{}j.j,}D)s#^<)䬂eSrV>N$Kw襷snY^Iϫ2BHzX%šu]7HRX[sN[f'A}wG".W3@C4$aqp0;\%swS+$R9;]NX(+<p&śCC:2ׯزsփu b_a׾UtH.i?|/HC) BQ4w -,s,ǓMRv /p7M "}t&Z إ½u. L]=iRhm6<o1}Cwu\ٷ˄6B8aƚ_Ω{ ʍޞoqTX\!j*ԭ$WƊ]={"Ln _ ]'L0w}#Vt5D2/)?PոLkKJ6ba.^,:Sz0,q%( ݻd&e|:8e_2 N2{oDwrh~[JG)0M%,]$aY}A|EH>{'=@O_ ɦiއW00 O—3pF1櫪Nbm~AD h:99 )d СԲ/Fx˚9*vmm]N)DyqI , OuiU7%/smxCH9Yf~"t"X޸c I-/MUn3:ز?ihj "O]gs,|L*%%Zab|p2%r?ƨՔrcߖ};v%Q"41 U"QZ:7MՉw|᷄U"fE{GOp9TN\\Ne-&3@F]PfufޫbCIIgqf.`wSw{0j/ˈD"FpڌSnNNsy Ucum]$@%eRiPckkA”ɤR ^-+7~/q"l  IY 2R/!]7(Er4=HR$84, L>b?d j:r@6J/ 36zL&~>z7߰1k%`z[phQAeri#Yyȧ$!uEhokUR5zzhF]B5QJuNP B8gN"Q4f~[FT`K`>n_U r!?4rBS(htb ]]}446)P475N,qtsk3%LN}ӟRz?l+?zI%LrCG~!Rhkô :;{hjj_MDWd2UTGg/Ox=lcT!m˕AQF:#Kt&Jg{eEssKmwH$ NCPTxWYC#Zwg~/W[S$,`B-UEəG>)IWT:;D|֖6Zڽq-BAfim f&g?ϨNzz  ZeUB!obs ;IIuE*twUpr OE (mN!Y˫Q|f~JPț<$IZQ :'}SIm]]/ )&l/X/=_PZ=O\=~0QÅ*FbḿᣟHaM tu$ȤN3@0˙$sl dl3oV^]`p/ ĺʠXys`ߑOD"aM)IDAT*mI iTUw0\Օ˴| ~bmϾ 鄬bNɶaia-⍨F|ߪZ03o ;`$L.'7T dbWilPT/~|u?\8ZrCl^$5f0M]3" 4>!fm^+hjVwH$:d+Av$u, dsW7[/cowvl-5VTZ(߿2 rz:Js| [oqt/۶wv_5Fle}GDCj1tvWUN͹oEzl>^o}6b:떮zle"蠪$32d եk{qaio{@^-w?D t2kS?toBZز]ߔm5*QVv MS Յ<D,0c+3߿8ƫN #Bzl6+,^Zu)qۻZ!ˉ;Cm*Rk]J۷̶NV૥^]oCJ۶ݶpgnӫ*{=mjP+j!Nz۫uzWҶvnջZd^VŽ&]5ZAXZ㠻m/ojak]eY5@|WgF#@5E=J*|yommݶ  OAIENDB`doublecmd-0.8.2/pixmaps/dctheme/128x128/mimetypes/package-x-generic.png0000664000175000017500000000574713175313470024551 0ustar alexxalexxPNG  IHDR>asBIT|d pHYs+tEXtSoftwarewww.inkscape.org< dIDATx߫$Gǿ?{ܻ{PYŀAQ0"FI6>$,Iv!$He("D$B@XoF rwsgLwfzgzzzn}]zO:}`0 `0 `0 `0 `0 `04nV=TzؿE'_ʇ-.a`#HE*a[ %c@4`&=[*nQ͇-{VqOo+u. ξ" VQOԙ(`Sj%Rh<-u<;oxJ]<j Nn^8׶QZɺ۩sQmQl1Ic}ykG*UՎ$bjDqh? ed]Σ iE(D|<2?HvGAg\C^~ݞxL&YRGZ#7eD=9nD q:8hEjY=޼qw]:cY Khg GC@8 [has}o}ƍtCr(5}sZe9=CFYC@{'"XqXx(ZG)=wvsmHα}Fy5rtNN? x_lZX?yV8_Q}sx~%/p(h*{iRZ}w-lĢ綶wQzU_ijn6xvӏ1f]p{]:]{Np[>,X{oi!}uk{׋: +:98ۢKd-'/G틗݊'K{I$sU"`_~ᵾLi{`kc6tDDWxu̲oGWR`gov>82?+À(vG!iR_%p~͙{fOgϬ3Zem{_ʁe?MYMu!qAhwXޭwu cϴ;{<Ծ)}#顁*upvwUm z_y-uNjD@JXD~5iͷ?Q\V*|?x̅4*VG^I;;1-Qmgr}Tr;/ws㵯\|佖mrwn*xy`lA'DT $;Zg;{J^\-j/ʤ-|\sn,42}&5 E 9Pap?}7p88Dwϫ1N@MUA̒(~5T’|5&{gHy8l2|ĖOC9HfX fC:$7qLIRBQB80:[)7k3HLKm bVM*9TZM/F4>Є85CQVImB  זL ݰI5%xdR(jWi1G.\-M*"o,LN(` h@7TPJƵ2UAYcj#+.n+MN(hOvL :jl_ŚgΪBŷA͂0M sPlL<@ E&Ѽp=I ӁZgvJ3^Q67-'>/?[.Bհ[:to1ϔ2 #7.6|5,89Ix @\0Д|6nۉ#E`Mkf `l<&>懀DPd yCJMy[-,D_hiR 7I%;?ShY\ KV5  m`&+xMTU7Mɧ_nk&JV͠dK0gDatPb3(@?vi7dtZWtw1Sx,-Cyų< f8z<M44 4T p2>-H&?K;B P<`Lf}, *!m!@c¢$d^F4s0u,O?AD4Y(6̑ D[~]pN/dwP; KlQ 3~|^5̞c66@kr+0hM``i@ӈ'}!J dcbҡWhhqz;86x` y,>)4xI\ -14M4ŒIENDB`doublecmd-0.8.2/pixmaps/dctheme/60x60/0000775000175000017500000000000013244011205016352 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/60x60/actions/0000775000175000017500000000000013244011205020012 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/60x60/actions/view-sort-descending.png0000664000175000017500000000275513060735370024605 0ustar alexxalexxPNG  IHDR<<:rsBIT|d pHYs7]7]F]tEXtSoftwarewww.inkscape.org<jIDATheǿ\{A"Q&.؛W*%k~QD؄藓n7{uA?" @#2-ɛ?n7qvfvv1}<3/; DDDDDDLKTe;Ba_;i^"eLLDL;Ts,r|HeiYV,`NlE凪{a{]Ҋ,g.,j"I%a!lhsjD3lb3\4ptXuUU3!3# ê .Ҵ.* NR3[nt/* g2ɶq[RSA`Ǐ .Ҍ(* '6SJa!D\ ̠R,֑O)6󶇊gM]vfNU"SE=o{eY'å4x. 'Lrŕtdr'2|Gooo</(J]DHB\566GD),,˒$M(0񗆆̤+f `ǘ(PUV&J| wtt|j`|H$څeݺu5iڟ\ " ]{ǰ5T꒍bvggi[eZQxd2B^Z̼|><(Ykm^ D:Nwh% !MArpCQ>:K]ޘ@R>ىI$HDtmu\~jB3wlwגuT*]piʴY6BK}>vHidfg^>d}}}=8i#ADgg@H%t41=k;\h: UFFFM8.ݺ&kM E6-uwwo$\Dagع%N/mH&+$Iڏ&fo0]_n&3\*dY.wr(npq 0aZqip{ >ǎ;MD:`;1aϚMFӴa<@eI}[eff>ڊ4M,k=A`潆a8 \vXʏYl>6T̼_၁ᰉm۶mtt4zӕ1MK 0IENDB`doublecmd-0.8.2/pixmaps/dctheme/60x60/actions/view-sort-ascending.png0000664000175000017500000000301313060735370024421 0ustar alexxalexxPNG  IHDR<<:rsBIT|d pHYs7]7]F]tEXtSoftwarewww.inkscape.org<IDATh]lUgf]lbDh-t{v& hV%7SDНMJĠVEL"j4h0vvWۙٯچ%}sν̝YE-Z3P5xcr8LJN7F(oE.{'|JDOmk8VP@6]`cϕR/9 Fb΅N,sj/y po1vcͶm/D",@Dߔ [ֶ MUm{ cB!+ >bm.1kj*,[lQEJ3Zſk]r33HDiiԼK)/mgfnT(0sH)%:{{{opsq1dQ !9 Z0u>B+89e X1!],ZwjE.K5T8/B,7oKop4ED1u7q)R{YX8CJ":{yZzUX3*6!qI@ <u+NbY-)Ff#ȍSSS===KCLD? !Tb7%y"G< _$m{T)uU9Vcg3Y"ze&Be9ccxEfdj v]d=fBB E[@ؤDBW\1OتEfasއi 0%<|,LB!ƘO0+|zj$z8#@B=ii׷cYc#Ȗq6=U:RvfI)%olI&o=b%ߖeݟN{cR)fSRHU×V}_V P (7čݝ9qTzs9gfEYEYE -5Oۻ!@YG/ wrCM`"+{/`-DX VVl.޹Ajtj5,F~*i-]kw>j/-\ES{j&|!sPr<%ś^h ল-q[5OG6/5O?#o~ʼnb"Xr7 o}zzV,[:^IbC`alxj6Tl#ǑO 1r;wo\>8:D14ޅܶ:R߄T^o]wܫ6d1Sc9f[4qv3}0pٍW"WCXv/Ul[Uq\C/z ZhP3j<٥o"הW>HO]NMF={jNGqAVlXy+֖[-e|g3x%sp^|QᲪ4&1|LnP7“m/cŲUUݠy) OOE3{6WdXP׌IWsZ~7D7PYjg;sVȽ5l!}HH8k".@l25v\bcCj$v~_vy}+p-;lI-}0)vA*h8xIxK:zlr"7ޣzΟ˟{n>奫YoYDMUv-ݳa:!F&0sOboUN[Tyc$0@C |xBa7Ym/&~)tG~r]N7vƇ{3 Hq'` Ұd`aX;[V˷ZO^_R&>&0ʥv>vXb#dK9k2]r0Dܹ4#<}cxV*tt5'wFh3{Ej8Ԡ`b /0 νBBpb<5Xr@%#DtJ3/UXQukg c:i~_;ߥk~R=+ $pp P"`vM{2DZX T`}`1oL҄M/WGʶmq^}=se?-nu)^U)QA 0Y$xʢ)cBz ]m ,3 Ibb1nU _\!Սswt#p1oGP(U=`MaBEW]N(CE8hɴet, X@*C[ )HILheM> @d!Ҭ O90 l:H1ŕAщ"\hap' Zpe16< E܍E GdSi 4 ǟ"pM Ƴ`{WYiDjP+(+cW H& hDtbJ!S\a=+dhT[̸ aXD@¢%J1Lket ,T'!61{ 0-hQ WY"1DX>A،K"@!}/pM-p6dFo922^ 0+%@iYغT;zP{ oqo5 De2;3p6 bypMB)PK^.lCY ꦅ 8d^xTs:f|票0ҦٟGλkN Xr4LMHpb w"HzE`>N0i[{ \c`rDfd[NMֻF:e /TW̵ّ8omZm1J.rI8x|YQz.u͔~Ey8BnJTX`v頯Қu3:^EYEY+=F"IENDB`doublecmd-0.8.2/pixmaps/dctheme/60x60/mimetypes/0000775000175000017500000000000013244011205020366 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/60x60/mimetypes/unknown.png0000664000175000017500000000270613060735370022614 0ustar alexxalexxPNG  IHDR<<:rsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<CIDAThnI}-clD`d$P!`Ċ`70;'HD€`Y(ɑr_fؓ]NI޴OS[0,03f(yЋ/={YM˗?|u?dbbWvgVVVRǏFienu~|~e84M6vVEŋ|0m]Z~,@8&O+t:b1rW* mڵkܽ{N8Qei}ٹ9nܸ1T}t,+Jr Z\%2crJޖ۾ᅫU*pž '-!H Z>&ɠUZ&#;Ze캻Z<;qŲ,hm͛&"syFbF%{h~]jRD\ƶmrL5, B/;y.]tkf?~P, 8C(q6(Z8{ !RjauLe7Th4XR~rT&&&('Isk:=N?=N *-O?LXu]vZ1aLJ)x1= Y`m};@<k_O9 p S~=q,㮍IENDB`doublecmd-0.8.2/pixmaps/dctheme/60x60/mimetypes/application-x-executable.png0000664000175000017500000000734413060735370026007 0ustar alexxalexxPNG  IHDR<<:rsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<tEXtTitleExecutabletEXtAuthorJakub Steiner/"tEXtSourcehttp://jimmac.musichall.cz/iXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/ IDAThs[}ǿ@wJɱ2ږZ]ډ(q26̸r;~C;L>H'O}vL+-ْxS ;pp}x E2/ޙ.ggvihC?ضphCO pwEoOsS=g_'O:MSqZ^=|K@}[s2iToxVp[Oz\:?p޵>q`v|z8ێW^y̟ ^[:Gsa,ق׮LgNĀK`R9)?T:o z: Xߌ#p[82<^ J6`@ovtv Z.up;` 9?:9^c6"\K,`:@ v<7ЁhJ)i o|._zj]e.-A8fyJTηN,vPJ(2}][ome pv|>K &[gm[|;% qUx~Jgź |{{ `^xJV$ Ji8_猣ދأ }$`va K`+)؎& &M ^7.]ƀ7l>K` 0Ƌp_s|_;)bN-1iJ EGOW# `{υCC hf 8U5s`5E@iA]c?SF|p:#v%:9vx誁{g}  8+?TTw)!u_ߝdEGύ;XBc  W_@{#r:163|ZUʊ'feܫf8vxk],jJ.]SSN]gc4 v^ @]3/.ba~*-a{'BlnC[sv[8F&،$:Y ЭFU<?dUR*S5MuE z:`ђkh>B!{7}CW.T K&eF@xJ \.z`;LB,;bStvwVhd_s}_ a΀5"Mo" %o.>gj^Z c~i,`xmxܮbX")?tAkD#4Y /Ϫfeo껎,oe/SAPꤊ0 L;ءa#|0[ڻLF6(}(J B $R9x1VɈƲ{b,%=_F&D8Ut Ra#JX[RCKJ dtPi N"sd#EV±1oڜcBd l?%SBˑF@ L)mւtA)d2 lmE)acdC]I\7n}r:C&Ըś3b>c4BaE )_aLsÙ'"T)mklh ^AGGCVGJ";iKSHUgW]0aYCŬ߂NJ8U)mohCp8={nHv X Hn)5?qPhQ5[ Jiw]#EU]Mp:%J*C2)b'obal!"փ[j'ht݀U(^ p9,h7nOMs*r&jմ՗}d2y*kW~? [)k[A9Q=x|4)Srqbjjx +j::KLs,7լXO&s3&gUWmsqHRFX||'#IJM+rHK jT$Ļh9t%K:_(%a{18d<Fm..=1:Sa[rKQIֵ[ՙD(U`tQDG|[2JAPlPf4|]l6˦_z:4;.']\ hdbѽAQDuRfZ)=ey/qQLdd1h%+O~(bfAmS +_|陳1!5TI'Ge9 PҨf* m5ҡedͿER4/\"sJG6rR Z[iǕAF=$O# _J%Ǝ1Z0IENDB`doublecmd-0.8.2/pixmaps/dctheme/60x60/mimetypes/package-x-generic.png0000664000175000017500000000311313060735370024360 0ustar alexxalexxPNG  IHDR<<:rsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAThZK\E=Uut3 (1K! ԍQPAQ7"+.BpB+l܈"J"$Ltwqzfޯ{&龯nnݪzK,K,Uǯ>|QgUbi;FȬm p>U,_wJ׎+p>iPrd6Al0et~nn\i}ԳV#jZm) kzj ].m _BVo]iR-3gر NݑŠq{殇_~#L*D mIHn b >J*"ՊXe@*Di3C$-V*ՕNc4R$7>iEuk"ÐIR?d'ZZB{EXro>-jv56s't8P]567^Jy,h}{>|ikLOb/:2kwP,?~cn/y~<- J{ enn= g1NWӱn'*!TYc=Xz">~H;?UU#*|NE֔*TP/ߵz}3o}ܱmU뇃z t"1IrWtHPxqDj8BwcWNH&+P%h)8VFly.&hu2邴#OX$s]vjJ-T<YZ0AR70%6C UPJCĂ SyxIHBu-l176Blby P, Rk20#\9tZGtZvJ*O_%" (BdN֩;7H)#\N5A`GtD$9 MCF*x9aR?Ag|;$D,&,8eiBAd4Y@J7C0q!x.=:JO&kK۩rL, s/Q*D᫛rRUsxMa>7QfWK5CE$DnK%vSHv*<nw;u0alsqx$TVXZKyfZ:c=YTR"TBܲ92n)\[:F0aQ6RD 1m88UsbpS} M/B. =h(|?{vbo,wnFǰ8zϾ#<~صXl6~?y'J !$9,L"VJjPi/QIZIENDB`doublecmd-0.8.2/pixmaps/dctheme/index.theme0000664000175000017500000000646013177323425017747 0ustar alexxalexx[Icon Theme] Name=DCTheme Comment=Double Commander default theme Directories=8x8/emblems,16x16/actions,16x16/apps,16x16/devices,16x16/emblems,16x16/mimetypes,16x16/places,20x20/actions,20x20/apps,20x20/emblems,20x20/mimetypes,24x24/actions,24x24/apps,24x24/devices,24x24/emblems,24x24/mimetypes,24x24/places,32x32/actions,32x32/apps,32x32/devices,32x32/emblems,32x32/mimetypes,32x32/places,40x40/actions,40x40/emblems,40x40/devices,40x40/mimetypes,48x48/actions,48x48/emblems,48x48/devices,48x48/mimetypes,60x60/actions,60x60/mimetypes,64x64/actions,64x64/devices,64x64/mimetypes,72x72/actions,72x72/mimetypes,96x96/actions,96x96/mimetypes,128x128/actions,128x128/mimetypes,scalable/actions,scalable/devices,scalable/mimetypes [8x8/emblems] Size=8 Context=Emblems Type=Threshold [16x16/actions] Size=16 Context=Actions Type=Threshold [16x16/apps] Size=16 Context=Applications Type=Threshold [16x16/devices] Size=16 Context=Devices Type=Threshold [16x16/emblems] Size=16 Context=Emblems Type=Threshold [16x16/mimetypes] Size=16 Context=MimeTypes Type=Threshold [16x16/places] Size=16 Context=Places Type=Threshold [20x20/actions] Size=20 Context=Actions Type=Threshold [20x20/apps] Size=20 Context=Applications Type=Threshold [20x20/emblems] Size=20 Context=Emblems Type=Threshold [20x20/mimetypes] Size=20 Context=MimeTypes Type=Threshold [24x24/actions] Size=24 Context=Actions Type=Threshold [24x24/apps] Size=24 Context=Applications Type=Fixed [24x24/devices] Size=24 Context=Devices Type=Threshold [24x24/emblems] Size=24 Context=Emblems Type=Threshold [24x24/mimetypes] Size=24 Context=MimeTypes Type=Threshold [24x24/places] Size=24 Context=Places Type=Threshold [32x32/actions] Size=32 Context=Actions Type=Threshold [32x32/apps] Size=32 Context=Applications Type=Threshold [32x32/devices] Size=32 Context=Devices Type=Threshold [32x32/emblems] Size=32 Context=Emblems Type=Threshold [32x32/mimetypes] Size=32 Context=MimeTypes Type=Threshold [32x32/places] Size=32 Context=Places Type=Threshold [40x40/actions] Size=40 Context=Actions Type=Threshold [40x40/devices] Size=40 Context=Devices Type=Threshold [40x40/emblems] Size=40 Context=Emblems Type=Threshold [40x40/mimetypes] Size=40 Context=MimeTypes Type=Threshold [48x48/actions] Size=48 Context=Actions Type=Threshold [48x48/devices] Size=48 Context=Devices Type=Threshold [48x48/emblems] Size=48 Context=Emblems Type=Threshold [48x48/mimetypes] Size=48 Context=MimeTypes Type=Threshold [60x60/actions] Size=60 Context=Actions Type=Threshold [60x60/mimetypes] Size=60 Context=MimeTypes Type=Threshold [64x64/actions] Size=64 Context=Actions Type=Threshold [64x64/devices] Size=64 Context=Devices Type=Threshold [64x64/mimetypes] Size=64 Context=MimeTypes Type=Threshold [72x72/actions] Size=72 Context=Actions Type=Threshold [72x72/mimetypes] Size=72 Context=MimeTypes Type=Threshold [96x96/actions] Size=96 Context=Actions Type=Threshold [96x96/mimetypes] Size=96 Context=MimeTypes Type=Threshold [128x128/actions] Size=128 Context=Actions Type=Threshold [128x128/mimetypes] Size=128 Context=MimeTypes Type=Threshold [scalable/actions] Size=128 MinSize=128 MaxSize=512 Context=Actions Type=Scalable [scalable/devices] Size=128 MinSize=72 MaxSize=512 Context=Devices Type=Scalable [scalable/mimetypes] Size=128 MinSize=128 MaxSize=512 Context=MimeTypes Type=Scalable doublecmd-0.8.2/pixmaps/dctheme/24x24/0000775000175000017500000000000013244011205016352 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/24x24/apps/0000775000175000017500000000000013244011205017315 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/24x24/apps/utilities-terminal.png0000664000175000017500000000223113061031411023643 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHǵMh\Uwf24c+nJmBBPڢ7nMZ,mbЍ‚Fn 5+M&Mh4Lw9.|d&=wsK#w;N9fXZuXun#ІXUk0 /<c̫{>JR!hCW*T bRv({#N{]#=ҙjK& _| ;Dj *(AXq1T5գk8U ZTb(b`- >v.J8 #GA"h.8qTBʵS`~LD%F'r@/ڠF|0ưsnƉx]BwWCZ@UY^?}>~n%QA8 )WpNin80"gOg2{+qki|JezR@UlST^;7Ďz93'/S,7AyՍC7?oLNMp[KtgsELyذM s0ϱss>Y}=6F_o&Hx0x3lS:m-*6齗Ϯ4vIpǛ*^GCYVr<JђƘ5gm(M\Vũ#GF)KEʥ~AUݯvK˷b@Ugf:g~}tO4ZSn.hSw"rIU+sB!AY#"٦U|!o0yc̪1f5H䭵ZeiN`i Q @(k@abkֲo>E- d%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/devices/0000775000175000017500000000000013244011205017774 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/24x24/devices/media-optical.png0000664000175000017500000000303513061031411023211 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME (ݺx IDATHՕKl\q;w< qqT;qBSbHT@ BY@JIQ䬺 nB% B]QEgDű Qc3xa;Sos6΁iЮۀǀ @s8+^} ?s|=ADLjvtt']|+{7 n}Yթ)Xkȹ^eQNX$I3Ǐ}]n&#>ySOry 1Hq5J Kw}-Cvn}z߷ל4̂p\ 6Ul 4auROS傦3gl5)hA2cI!LMladoh7`hmcfs&jhBJHxnǔy$.\."b;D,]$! ,#$%lj+(*)3 !p%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/devices/network-wired.png0000664000175000017500000000300213061031411023274 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEMMMMMMMMMMMMMMMMMMMMMTTTMMMMMMMMMMMMPPPMMMMMMMMMNNNMMMMMMOOOMMMMMMMMMMMMMMMMMMMMMEEE[[[MMM@@@TTTMMM666NNNmmnOOP***KKKQQRQQRIIIQQRPPRGGGQQRPPQ DDDDDD(((OOPQQRQQS999===EEFfffQQSQQQ>>?LLMzz{ttuQQQAABSSSffgaaa!!!:::rҧy雛ᐐل¯xxx\\\ڬ[[[qqrҎ]]^ppqrrsRRSQQR``annphhiqqqoooTTUkkl___eee~~SSTN,tRNS߉ x ph6_- i$ ` "+Zu,5W *4>W%/9DVv6'1;EPXNOX 0AGLICȶ6 -:@?6}p&23.)7J$! 3|}bKGDHtIME (ݺxIDAT(c` 021bgc8i2'87ϔӦϘǏ*!0k_PPHYBd%K-[bբb 5kW.n Wl,)f޲ey>c]e`r{1K:|D&r+O8y30 5u M;{u`zF._u7n@%L-,oݾs>ie wptr~dSg_|u,eBB#"cb>$&%e32òsrs# KJ){T8T:VUGd7HÜܨndޑ`Rhj)ՕE2 u=w>%2MW؉?kNp4%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/devices/media-flash.png0000664000175000017500000000241213061031411022651 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<RPLTE.46.46.46/57068178067068057%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/devices/drive-removable-media-usb.png0000775000175000017500000000243413061031411025435 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEĹssstttˏͽ뻟riϿʲѽﳍ쾟Ҿ¢ӿorԿƤ׿~ʧΦʙ̡ӭձҬǔÉÈrrϖ>vM:tRNSpo88ed;tubKGDH pHYsaa0UtIME (ݺxIDAT(};@qmkͮRZG$MfzL(K/{ 5jTKu2lWb:NgÑxiQiw&4M.96"RSI!ؔڐ&!E5)f떮*/^*@4 uOOtH67}o 7B(m]2"C>~elȔ#OLNM#QBYg ٹEHA"rBsi )0H&x"9Z@Og jbFEbVN^LOgKw[,Z)}bxg7鮇8-wvtwUR`[u21c&MuLO%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/devices/drive-removable-media.png0000664000175000017500000000150413061031411024640 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<&PLTEnpknpknpknpknpknpknpk}UWSUWSnpk{}x}~{=tRNSgvD0VV9 C%bKGDH pHYs B(xtIME (ݺxIDAT(c`*`BLqf)iT `G $Uʨj` M-T -5N86I@t@=y%Fh؄ (mjf@liemmnacRN.n^>~~0 JHA$CBBB#"Q1n@|"#$/KPHXDTL\BRRB\LTDXH ?@%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/devices/drive-harddisk.png0000664000175000017500000000131713061031411023402 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEnpknpknpknpknpknpknpknpknpkgidfhdUWSUWSnpk؛ᔖwyu~ᱱȑ֔ĽB~tRNSgvD0VV9ˍsbKGDH pHYs B(xtIME (ݺxIDAT(ϭ0a nmiq/{O$,4B>Qv.2x*\UZBh Gwc:tDPC:"qJ:jY @ט3,,rlw87/|{oXLrz@(U* M%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/dirhotlist/0000775000175000017500000000000013244011205020537 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/24x24/dirhotlist/newadditionfavtabs.png0000664000175000017500000000200013061031411025107 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE  a1R4 $~&| ou~{}~{jmfgjcύ~|~y}uwrtvq]_\žy:z9֔SIdL݇_Q\دڣҮȐ䑓歯CmzFtRNS!3# TZGGonFj*'...15> -573*  ~>bKGDH pHYs  tIME5`W7IDAT(c``dbfa" @$X\J <<}dd ~P P Ȩ8U5D| $&%k@%a #3+;G(<"-vqIii @%t+*Q@XX&U%P@sK1P¤ %::A(aaiemmA;8:gWF8jӃ%tEXtdate:create2016-01-30T19:53:01+03:00Ȇ%tEXtdate:modify2016-01-30T19:53:01+03:00ɕ>IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/dirhotlist/submenu.png0000664000175000017500000000257613061031411022733 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺx$IDATHǵKhUsK&NZ{X * qSKq%RRtJi%F 4mR$Mtd.s\L.3IZk>s{}sGƤDAL봲K^=zJ,zrpþǏ&7&…YeQwpNny1(͸>ttRJvoHvO3 t:PbkjCGdv<'?>[5G%tXcHYJݢ?ݳM 0!B*`+BM5B 02EX H R!0XB *2| cZ@1KwXA iYZ@)7M)W"l@k{O)M^ ϟ:JQ+s*Z߁-/48 4ҽq/^-XDhCq2ލ!rTX[I`*s—}sBSRtKCmxNچؑ;ģ4Vٱg*%#4WNv!(bgP22AkA1{mfⵓ Q$ZU]@{,[oK@11A0dώ z!0~]@#PҴ"8AX m;HX1TF'rǿ >] fBE`$FGDگvDt AJ+#s} |4 $qs[p[~$wZw㦵 1RPVr^kv|E(0Y%tEXtdate:create2014-09-13T10:26:26+03:00ț%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origDirHotList_tEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/dirhotlist/submenuwithmissing.png0000664000175000017500000000304213061031411025206 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHǵYlTUiJK-`1c1|pAP| @0%DQB)BYN鴳:3wfz|(--{wϹCI>h96Ys|cp9mq弧wNǶdUk_u*Rzbvn?{ZNPA@sR˵cD-{6p4_\@QÜ+rۓBQ{D/@(bT~hP5 ˖vh"F- q!E%3h4RU#|.g^˶ ~|jQ l\EIH,.64zґ80 PU)L<9f0_\pAN#!=7.bwA:T$5+B<XpM!KG/$ 3@-W[;l;vGpZV4tTG@ q$]}Qp WSPy m 3]@H[.rpq,Aˎ2^Jd/y ^ Ebgu$HKa0n8ʰ̎S8T|9k,Y$W? ^Jci-7~͆J/J3Ox. }io^l-9%Ӆ((EP|%d|%*e2+Ds?q.=¬77"jgRKZׄ~An*C*pFJW5pus}V֎'Cɘii0=U v. YvD`pL ^kmD#ZZV`.yEooez @Юd~yc*&i>ּk^Lʚ&h}UsWкy%8a&sIƼtON|EAYԳR[ƈןpɋW-vaغM>|Juw<.Dz1}Eqn1~k'F2=g0 Mƚɞ=/~?-_(`΄riMh?CX˂PCdCt8Y1pƔG{3zGDI)U C٫Ѥc/Ko8agab!%tEXtdate:create2014-09-13T10:26:26+03:00ț%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/dirhotlist/dirmissing.png0000664000175000017500000000274713061031411023425 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDCtIME (ݺxIDATHǽkUg̼sٝ4.4-[?fXQ(ZjHd`Q*"d} [ ~ RfiRwwgv^=}\D%#·s8<ρ8.lthUY*!U6B_6*aAP CB:,# v9o+1-HD M46&Ztua$Eɝ?O[{{]Rv`&8sWfhQ!n9S|9FSB^kuwsq+y|Gy*DaG1C\ ZP7 "~0*<~L$$ 9ა 0DuuZۢG Z8>5 N * rèMc2t]G-N'hy>@H`} i]O2\)*vù(Ӻr%ɥKfDH" 0FQs09)Kc[h: 3g|j\ALkPaBM72B4!Ϯ}E@/ǡV"P$ǣhc:I?VO)`p hFb&͑-@KgpĆAQx .q*`C?D}['{i95"?Ͼk0.'e[A`4jE Dﭥ9nw6<&X[AKb P3e*x قBChhm 1cRppXj57 6 +6x8\PL]o'bҤ/@ӟXuh0G_ 7 8 ?9*]3g#1l??y3.!}v/B˘ R-lR ,S H(B 1~2Hr\~R_o@Z%8f إj2 7;Y@qLCHeqm\| ޥ$P+2!X3c0Ip@B4l= :ԗ`b%Y !M(.ѣ AKO`'oonv~ MlV vss-c]sF.V(h%dihĥPk4)(_+(lyGQTSh1>h."!k|ۅNmˏ׹ a0(>p2?'O5YS Q$`$!Jެ*֪lS %tEXtdate:create2014-09-13T10:26:26+03:00ț%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/dirhotlist/submenufavtabs.png0000664000175000017500000000163513061031411024275 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<wPLTE6n[Z7nIH>yGF?|*[>o -YVHʒ *ackgvNP gW7$F_?0;G@`Gpr%#c+6.+>(B‰I"Bb@ q I(NNIMKMIA\FfVvVfrn^~^*ZcFYyEy&fxViihVcc8! %tEXtdate:create2016-01-30T19:53:01+03:00Ȇ%tEXtdate:modify2016-01-30T19:53:01+03:00ɕ>IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/dirhotlist/newaddition.png0000664000175000017500000000234013061031411023547 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<1PLTEpqoefcUWSOO_OOOOjROgOOOO4e6a8`o:]XwmokgieЦ]_[XZVWYUVXTUWSXYRƺWd4e4eX|mү̹ܽ|m݉֊ԝ΋|錧s_a]ҝȚ}߆֎_ԑ̞;j҆ňֈՈևՇևՆՅ|ނԂԁԀԁԀԀ~ӊg~{zzyyyxxwwѐ٥ussrrqqppp}Ӊ׭Ԕlmkkkjjii&MAtRNSW3fl; ^+:(Ψ]] Qdz7 !)/1234,&   2\bKGDH pHYs B(xtIME (ݺxJIDAT(c`&`t''&t GgpbsYXY`.~<| '@  KDFECALl\|BbRDG`J*gdfe $"E%"` $eU`{!Qs\%j:SS[ZZ[[A@]=}&N4YRJ(!9e3Ϝ5{֜_ #+ZhK-_rkV]PZa͛lٲum;vSQUSJhh-mUJ6@nggkloCFJPNҘx%tEXtdate:create2014-09-13T10:26:26+03:00ț%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/emblems/0000775000175000017500000000000013244011205017776 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/24x24/emblems/emblem-symbolic-link.png0000664000175000017500000000220613061031411024515 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE---111111---EGDLMJ@A?QROJKHHHFDEC?@>;;:463//.)))###(((---~~~%%%FHDKMIPRNUWRZ\W^`\ac_^`[Y[WTVRPQMKLIAB?FGDYZV]^Z\^ZXZVTUQOQMJLH;<9?@>DEBHJFMNJQRNTVQVXTWYULNJHIF897<=;@B?DFB\]ZNOL@A>453<=:?A>BDAYZX?@=01/342785:;8IJGBCA9:8675++*./-120452786%&%()'+,*-.,ijh665 "#"%%$''&\][NNM/0/$%$ TTSFGF>>=))(!! 554<<<^^^2q-tRNS!PRSOӹ<>?Nθ;#VfbKGDH pHYsvv}ՂtIME (ݺx9IDAT(c`LXXء\(,ǯo`hdlbjfn! ($ `071wpJ89{xzy{H@$Y| %T* J'%&%SReiY2d9y49DQqIiYppyEeUpui<\18M.?aɊp)SL6}̙3;fM:E *S@ $SPBBUB*ʭT445 N * rèMc2t]G-N'hy>@H`} i]O2\)*vù(Ӻr%ɥKfDH" 0FQs09)Kc[h: 3g|j\ALkPaBM72B4!Ϯ}E@/ǡV"P$ǣhc:I?VO)`p hFb&͑-@KgpĆAQx .q*`C?D}['{i95"?Ͼk0.'e[A`4jE Dﭥ9nw6<&X[AKb P3e*x قBChhm 1cRppXj57 6 +6x8\PL]o'bҤ/@ӟXuh0G_ 7 8 ?9*]3g#1l??y3.!}v/B˘ R-lR ,S H(B 1~2Hr\~R_o@Z%8f إj2 7;Y@qLCHeqm\| ޥ$P+2!X3c0Ip@B4l= :ԗ`b%Y !M(.ѣ AKO`'oonv~ MlV vss-c]sF.V(h%dihĥPk4)(_+(lyGQTSh1>h."!k|ۅNmˏ׹ a0(>p2?'O5YS Q$`$!Jެ*֪lS %tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/places/0000775000175000017500000000000013244011205017621 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/24x24/places/link.png0000664000175000017500000000175713061031411021274 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<ePLTENNNNN >;jn=}"0+:+BcqLtRNS  mIF "(D^ m QH#j6 oniLAbKGDH pHYs B(xtIME (ݺxIDAT(ύS0 Ҧ؆w0\O3hY/{k( sfEP|t[A)"!vt/ŸpxdEcq%޼I:NY'#e.W..gm޶|w|ջQYU|gMm! !ȜCSs J!@;PMĮMiT5z`PhHЇpxdt4#{ɩYs.,!-qC_X\Z^Y][ؤĻ2sCUF|jE?r6C%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/places/folder-link.png0000664000175000017500000000240713061031411022536 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHOUu?;G߼ɿC340i!h1@pca`H)HEDtPprDH,Ņ(4wwGg)bU.^9bGI3AC7üٓ=֘$!$wsV7`h $ͼSLo` wv>1! @O[rʑ^x`f[]p-g,}7RwVnk:G/}-[yMf*nFotRs?]ϳAq+  7l%`E;Ow܍ I=ĸ"ݣYb:E?!g99osrnf(-Х v'5sd*e4HgI:ֶӛDJNP%h?o]?6qs܍$+0FVըߪ2:vS815 'u8_~J5et|Em*mU:*TVږѾ)[Xc UHa+3M_g$Ѿkٴv}T1{)rczgt峧d_vf%(TfS @ 0uL 3\3L&GFYvG7G-,6SDANG$D!:^\ VrJ wCu7TG4RsY!⠱ Wۘxff8s:}œdzf<˱b N-\Ȋֻ~C}INtEXtCommentCreated with GIMPW%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/places/link-broken.png0000664000175000017500000000201613061031411022537 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE# 8 !)'8 1G/Z.7  53 (\1@ ++JA hA.  I++  <(9    ~H"J$[$^,[)SN]3V#TSWKAKX"X%X'Y'^$EI`/a(J$22R-OCh`]%! zw  'S`)\.q+bKGDHtIME (ݺxIDAT(c`3`d!ʆ]!/ (TX$,"*&.Q,-)-+WPTRVKUTVUի3jhj!Lihljnim7042Kwtvu#aoie<Ɩ }'ܼ}|ŃCB#%"cb0$SR30LQ"##0$h Hy04Ș|%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/places/folder.png0000664000175000017500000000162713061031411021606 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxaIDATH啱AEO= F *"榆*¢k&b"b fnh ( ˾{ gS 6h{[3<活t`yffiXV0 j R:G`w_"X||;8z"Ѝ =6𳇃P&9L<5r^AHO6|}q'/l%XJHa' A+}ʄvJoݏ΁et9ZK"ڐJpٱ`v>dQ%l׻{\6mHA3T[kPu g hD21ڃU9VӒ-8Ѱ/qxnLf5g7Mg֘@oVĄ{sND޹<$]Eu,H-8ruϫL8L(]#zz͂n١(]5j i }H3Ӽ`Ω@ddN}˰Ɓx֡35L]mcf"zȓr" 8k(fL K([`"ϟ;ýʡ%r'G#- 1tEXtCommentCreated with GIMPW%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/places/folder-link-broken.png0000664000175000017500000000235613061031411024017 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDCtIME (ݺxIDATHMUy?fޯQgBIHc$k1FhQAAPHBhcBV\XMPj0)kL;=紸o9 -ftsys΅:roldNɛ/~ZEq bC _QS;ߍSO$tpytI[>Ρ[w܁m|KS1LwPh5L,kmު\it4AUAgJwW;S&LNQ>q5?04$0S8ǩ>^3baqAsi]Dtʫiʁn[d1 $)~}c,-mi$&BV-Qo1?tIڕ԰) SUC|xE1r/Rթ\/Oz`ɿYڎN Rw% sxY-Y|CIPG֠#gйn%@m&kLjPR4Iq.MP/eHg[i-dt?GGā,i@m-0ryj]to]OOG95]dp G[VTmL 7 s)&F"Ɇ i}+BMMqOG &Bv3p5 \A4/y|tlXMu 3Ր͢"<VR,^#AɋH\Wax2p*fSHº^B`9j}t48LA$3 aFX|ndo%bџ'YBH604o'r1wR2J|ZCv⪠"1T<5KS߃~ݾeYmC Askjr+Jsz/iY%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/0000775000175000017500000000000013244011205020012 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_markplus.png0000664000175000017500000000333713061031411023041 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHǵ[l{^'1!!$MQRPV򒪨T!jRRA/*P!qIoXf_Kng"b{)uQZedWW\M$CY'sItkݣO~GD]? }*fX1`j牠$IOtgCa!/!yK&y;K:3/)+/HiJ!WCPsP/Lwz1 ՙ$vqMQBGX7Ne,}"o*),>zxJ% Gmp372j!ob4KeC<cH~7T^ؑN/;D- to0QW)4?* J>QLۢ"ٶVDÙD"-{7Dq膪W+`+djZ/W[k ~dA:ۓ?A&zBA5PY.|0;l _ݕ=QOjlNϰa"^wuuG\AI$B%(5°PImQ[ur;{6S`׏m_P6˞b!"PPqZ)5k(\7M@> ʇ1#>9)=3C5ʗ6SDՆqN1f{IfVdxn}d@)Cn>ECEvS[kZ?ůٌ́%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origMarkPlusIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_markinvert.png0000664000175000017500000000320413061031411023356 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxOIDATHǵklUy/m߷kunV`%>(8Hp~2Mp`bD F ^%cL$0LD1ƶue2 O·<%9sFNl S׽79}cW%1T"QA*v/wkR2ZX^m*POʩNY Dt4Y#ӧ ~&'.z-r7 JXɱVh(rTUHy.֮8\%.oUbj>tw'fں2\DgqOkBM,͛QbD 9< B@^<)ƃVbd1@8 Väqѳ 4;@ՠkzWȹ|N*y%buf^$r8ё9ILI0p&:9oL(Jhc!/OT^/'ƕфkh+]w}vDž5הWN#gzSn@zli ޷0qի흑_VVhHP&4?۹08ݮ{fu][lfْǔY$_?Tm(l*aEyjB'k3;#+Y̺×zLǎx=^PJ:#{K5jkޕbQLCc~7=M/ccn h(rHE %EU`Pddh8=@uG0 gnhF '/k+{N$&d3+1ڒq` F۷5555mkkW.3vgdŐx%ٚZg_eb²hllDKK H( DC;w&PG~?Utm ,M24{MiuwӖO@iEq,7Νx,X4:?6²0 B7̝}BXa~` -{30h%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origMarkInvertX>IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_filelinker.png0000664000175000017500000000274113061031411023325 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE 8NGgAbAcGf 6K ^i][[dffegtvvucZt^x LkjihiiiciНߡԿ̬ǢǢƢ̩ݽʲs}r˰ښr vݙstߞ㛺uv瞼x x렿wvăń߀ո熸ײ匼٫ۡߘݙݢߜɰʲԦܩ۝Ÿ!àġ##àƢ& '˦|&}&ɠɄsss H'tRNSGEvuwwmjjji^\\\mw\x]Y@8C7e0bKGDH pHYs  tIME (ݺxIDAT(c`  +P]]CSSK4u488\zF&``ldj 4;k{ sM'x{y:9%xCBÀ 4<"20ߏ(OK̬윜<;=,_E%%e v>D kj̊r_cSsKk[{GgWwOG{[kKsSHIL6}Ɣɓ&NI̜5{9/Xhy@Y3@KFF.[bU+W.Y+ X~}ކ6oٲymyׯJm߱c]ݻg:|'N'N9{p8X /]/]vDzUn۷ޫ2J?Ǐ>x* C @ %e ;6ȯ 7%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origFileLinkeryPIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_closetab.png0000664000175000017500000000226513061031411022776 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEP[5w6w6waO8tUnyxyqEoVUEo :afl@f 4VaqMp @_ǘkw_38@~KutcMJLx;vvTd4eE~E}D|C|=oe|/!."1$1%TA1%w%G7G7w%0$P@0$-"H8YG\JLgfegggeccbuwvvɕ̓줄qg|jl|jukra}h\CP5}inՙtkq[K0I.K0t^okmZr]rrjSn]aNs[HjUq\o[hRgSkUiThThTlZtaubQtRNS $ !%x%hfQj!%"wk_f7<vuy?ae qJYbKGDH pHYsHHFk>tIME (ݺxIDAT(c``dbfV6v8'7qr@@PXBX$4,<"cbD !)ܼ¢bY9bIiWTVU))%T[ (:=}}&% x)SN6} P L-fΚ={9Ace=w-EwXxENf.nn.h.t)T %tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origCloseTabtEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_briefview.png0000664000175000017500000000264513061031411023166 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE~~vJ nkgffegd>SQ> a *&)a^kH79t`OQPߘ⟺ԭ©ޓ̴ؠֹ褿سǯ㘵кޥ٧̶ܺ鞺ӽɹȿRtRNSQ\\XjjjjjjkVR4=3WbKGDH pHYsHHFk>tIME (ݺxIDAT(c` Y3#PMF Ȱ%Q;PCIYEUMM PS]C hs%uttuuAL}m-. ikwptrrvquspt2ݼ>~A!a~QPظĘT 3> *_PXT dB$+*kj+̦2OYKk[{GgWwOo_ s2)SM1s9sy .Zd+VZf%χHlظisݖ۶ޱs{Db:|'N8x3gϝp+W=w3` 7:s2o%р0PBDT K%$1$)ݝ],R%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origBriefViewztEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_loadselectionfromfile.png0000664000175000017500000000327113061031411025551 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxyIDATHǵklUw;ӄҐBKiU$^.i"HH@ Zih|!>B ,E[hMдĉ8=3s$QKGW9g ?=ieϦJBKQ =bTserae2'N- u wXwW{|O7]͏fإ_̮V& =ī[#~ӰO vܭ+;xS(-~68|N\8rZ\ Y]n ⏼ys3 M-T-C|2uxnp+c.M W5p_*I.!JSi77gFג0~t(wϛ ?`**4z5!i ]H(|.P$ Wgu'&ijkUR1+m-j !֤z봸˟웻x!r"gV([wDU/OlOP!t2 3sIkNAb/ec^u_ vo5jeFVb̅/3}J/xCwQEc^^Σ|q4=2wt4 qDpNQ}|Ap1&/UkR0-~DZժ5۠&5lrZ$ geRZK$j</{$ ^Y!2yaf0>]tf'tʪYƝtI49SoV+3ߜ:ُڽְug=g~ %rN]=z{;9WMM v\!=~zC?d>9˱&khԻU묥YwDj+M7hσBr䴡_D #cw.*/LTv?Fus(frr#sG=baGxFo#j]ySc$<Bljs_ Uh2TR RlINN,+``д DfH̒pt2{aԙK%|}M.#?в}lyP.Y`~%)YNE2%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!#tEXtfilename:origLoadSelectionFromFileGIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_helpindex.png0000664000175000017500000000332613061031411023161 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺx}IDATHǽ[lW̙[kljk;v۸qhHKhD* \JxC<QEKH /W7C},+&ChKeRK5wyM}޾7OP5K]f7s oTw?kI{᧹џ|cO=H,Vn.K>$w$C2>[ r)_F?6~k/=7єx{zږC hvi| %٥Ac~J#Z?xo͹'8㯾G??:,2T! C⇂ PBQ%Zc}h#;NډszP{ٱOO|?^M;M*xfv6*61S2=ɱ>9{k~ۭ|>כN'1Bvn]u+V/o<ЉoN$ SV|X|W[ 7Z:]^L1 X5j@,m'%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origHelpIndex`tEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_markcurrentpath.png0000664000175000017500000000323313061031411024410 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME  - IDATHSmlTe={wivӏBmcX!~a@BȲ1heWTtՒD%*F(t+DY,նHi|3"lkϿ}=|3L3{N9Ƒ:YjJʂʪW =<+>=fQ~aqOyncZV11'\aɘ x/31{(bKHӓ@p!! lJұ3 1}y!-OL:4?1Zl*g*>ڶAs@B9Ù$S| ;ѷ)f(Q7^(bmORWCtIME (ݺxIDATHǵUklW=ٙGv#^{$㍛MV(Q*T(E@j$*ڈ(T!M $SG!ͮww}vԤFݫ{>"w`s늽ǟ ܽɗk7=^[.EUT= XEBACl/yd_tտ3e*;49U64I[F=:"GA3g+@+?7~j]DEփY[wvE h<J$|j]/FߩhDHiÁ Nȩ:;J̗DDƵ|5Á |R@Tqs qT={EZ鴣umkzܣFc`1 B(LCpJC>9{kq(gS]2V`DAfߖm^Q+ b@DW.QjN~-*"ɌX˲vnH.to281J^SG:aHnQUS o{0?Z[ɛ/8~kƵhz BƦ9mgpǯRPu$$V%1Տ% p #ymxb^Jþno,uy u8@8 P B8TQ@+9./m_ OnuׇǛAg&fok.>a:ȯ'UIn\ - AUR{T從_߳}OgGSauA$c&bkbfu89}6?t3Z`G/h({藪@@U<Ę8ʥFÂhٹE @|c (w!E% 9 f^&I|wXEki_:5 v!R.36~?NuuW­)(z~6rޖRf.Wa<<޵JyӃFX0ss3<:ַcp[rFwCZBR@́6E+WW -cT >uj,ԊpgO"Y2X^ Gt9HWMe%^}m8|[O2ڶK;zbࠞͿ)eJ|rwn\iw[|oiy䲵`Ey+5A g+>`PQ*%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origOptionsytEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_unmarkcurrentextension.png0000664000175000017500000000330413061031411026032 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME  - IDATHǵS]P~ηǷ ]W Fv(bkTҖIbR!֋Ng^411Ա^T߉&fm#cb&e4DpD ? ^g\s}y1|oܲY+ ?ر};7\}::ѱJvΩh14ooW~{َ`Х k< xx&׫Vեյ+:CG3cVO̓_aD׆e[8vA^Fۍ^/W#tߗ~CY^,m6nY`}k)V.@}M6؏[`XÍ^~6J,60=k&4]g(tz~1} ru IT]N2N7gcu_sQS}P\A+W BX~ǔpG@w',|ytП}o.>Wů`*0#(#dP,BE阙1xI/u$A9GeJ\M?a3V"sVraSYȲ ((s!0H鿸?@Udk Bsy9 T<C_)To&Nv-p0 sV77EdՓ9)x;^e6T*tb*#$Ͼ>K%`H DDHSh1LG:vll'&56$#MNS[c&jDF(/ e!,a_`eٗynǜOw͙svp x {u/`mw:~N󿏩P^4&6XVY˚ᒓ\q㖵| %SoVt{@~aQw1zCk !|-KL3ڵ0څRk̇ * aeOزCڶwxt#],8|6| |<#_D^6f4[#WO˜M {_n[νTW7,كw˰X{Hv9-]o_`}"aYǘNə_nAW;/6i;̋>X\y9܆פּ`,ZKݖD4䂾wŏ&P1F(ڜ-UŅOK5ˋ-*D[h)W Ek6r$M9^Vc$JcT̢{l%'z7?"4#v} XAm\Rn_/nxʬӪd}8p? N`{WnEgSOf]Px銺eqV Jy$'o:O>k=w6pDa/AhK_$0}YmqB2s yd4TQAJ#-T \Fi @Ai5|jt7#ZZZ5i -d`0rj.o4 -m`(qB9&P)B'ϳt Yd4.jxK3B9^2'S9P5= R68y}ׁѾP ᆒh&`zlҟF{v~\T!q<}3rx͟ h$h+oe`@@@bP'73+6aCOu#k6&!<S2=Rߗϻ~Xy#!]3# *su`+7SQjSBdBd11uLfp`M;d3[Eˎ{97exU..`i3_6Ru2KL (yV}uܺpw pO**-`sTKF"J=0: CII2Q<0 ߸ou=[e^}2QkhGwos?w>++s q@ O2pJͤWAzz}c?l zGg>5s+s~˺5N ?#q0(`1BuAy.:`_/s.Lb"5=zdɄۉሺሻᆹއᅷ"4Do\[Eo 7\cmAd 3U^q$Fc 1U]mBa?|VYF:tH-Wy5g0a/`.`/aAeLasM^lDf/`4f,Vy3)!B=9A=::2+voݯʦcLONJy常bFKIJCx\>B@;w˱Ͳlԋ끦xqMItRNS,,Ǥ/,?;;kk?◒? +991{vrbKGDH pHYs  tIME (ݺxIDAT(c`\<|qA!aQ1 K@`PpHhX!1)9%UI,_PXT\,-+ohl5utvutuu%'LL6}ƌ 3g%LL- ( .n@qTo>>J%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origRenameTabҾ3IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_opendirinnewtab.png0000664000175000017500000000300113061031411024357 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEP[5w6w6waO8tUnyxyqEoVUEo :afm@f 0Oar$GsČ<̜QvY`+V-0?O.@r+=zOo+yOi:tv/ҨjGd8u}wҴke!xdrhHm[Y:/8釀{p#Ĺ9G h@\7e|hϩs $!w= Pվ vVv񛁆Yu:ɻj2Q6?7?+$bk-&Ts`s(cga1KฮB#w H}N&93A8!zR0n(Di)Jd/_uzM p%wgN $`TBa !5Z~TU1\~}L9ax/˕˾+ .,ϝQ0"ڽR \בVkt,Nc}dy&rFD](*?Al3--RU /j1L/J[< ̜4P1<IRc8|YzbQK]wr~{vI)u[iD᭷Z>###.N GH%s\bi(ND{A&n۶MtEkk7FW"Dj6sq&[~i7Y-KxC~;?|E2V bb''ŋT1P6#FB!'3Ɯ4H2T|Q΢Jv {9lCAE 8?-kC0 WR|A5{F`dEۇڱc k1"JJ\^6(k!7@/s.Lb"5=zdɂچᆹᇺᅷ"4Do]]Eo 7\fpAd 3Uat$Fc 1U_pBa?|VYF:tH-Wy5g0a0a4f,Vyxhklxzlԋq҇3tRNS,,,,?;;kk?? ߯bKGDH pHYsHHFk>tIME (ݺxIDAT(c`rX9 \<|p/%661E&"` 1q3s K807KHI[Y k[YwTP+)89'U5u; pJhi]=}04@'>$iS@%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00! tEXtfilename:origSetTabOptionNormal$]tEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_markmarkall.png0000664000175000017500000000333713061031411023501 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHǽU]l;?zul jB~T JK$x+?RiӦDmmhURJ 9MH 1ql'uY﮽.3;?;sg`R$=}:=]lVh$xj΂hlrg˿|rŏ,[8Tbɇ{leN-Qb[`;|Jܨ\^OX-Z<N>EiT _9zu;$7lfoSm1A96+dJQ؋SLdE-`0/A*HLF#&]Ӎ}Yٵ~fPg$wT;<޿~G8HdC;q,(ݲDFNd-ti%fJ6vwj]Q>0=O'1wx=].unE'%۬T);X5N(W?Ϋw>%;I-??ݜW$ͷ1,1!{2gb12aybܟq~ 緂X9\qp46e~s>eԱ%u; I4gNzG} p$%0q cB!>0u( cY֜n[ODVAsn C2w=>(U Lc|"|q)8e`ڐۀPm, _D<6!0c Q&VJSn¥p,-"#hфkp\svDk^ Ь^^/s(@ Q! [Dk ^RN3 V1*K_@_wBucJpfr񈘉LL4ye ~~X;;S{p3vbE bNƌ>ZfhvVxOݖK"D?H tFu'EYYN.%ؑow_.1|o BjǞbeqj 4,S=c}ATF+#9~Z]5g[dWs#?L} ZZfbמ s̩͢-7S{s DE;ٙuϛŷSInr,jOػ.cfrBPmm%]}h6|a$*٪8wnvϮ7#btn}@H^41y֞ss܂8^|vŀeK޻P%ڲM%%<;=?>@@?A=<=WQQՓ\YYFFHooqDDFIIKJJLGGI]YYa]^||}ttvLLNNNPKKMa^^eaakknPPRSSUebaiefTTVkkmRRTWWYjffmjjUVXXX[Z[][[]XXZqnn\]__`burr`accdfyvvefhhikghj}zzjjmlloف}~mnqppslmqops֘A)tRNS3\\\\\\Z'7*hcjjjjjjk^R7==3c7IbKGDH pHYsHHFk>tIME (ݺxAIDAT(c` XYYX98A\ܚZo`726153wptrvJ{xzy %D"" &6.>.>!1I(!Y9 ܼ¢8(-˅HVTVUAmDZAb]=[/0qLHL:m: 6u XbYQ3 sΛ͝XpbhĒ˖eK@$V\VK^v Xf8PBbh`z J+(*e:PvӮa%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origRunTerm_tEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_testarchive.png0000664000175000017500000000251713061031411023523 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHݕMh\Uf2_/3$i;QJQ1qmVnƅt,Fnb)BQPAMdҤd>޼xH'IKӅw&|Ɯj*?ꞽ}%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origTestArchiveM0dIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/view-sort-descending.png0000664000175000017500000000061713061031411024562 0ustar alexxalexxPNG  IHDRY gAMA a cHRMz&u0`:pQ<!PLTE4e4e4e3d4e1p4eWxtRNS {bKGDH pHYs B(xtIME (ݺxBIDATc` H4"q:g( s pr9 .P3Ι3&p̄Ḱ$A 3/q3%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/view-refresh.png0000664000175000017500000000276713061031411023140 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDCtIME (ݺxIDATHSkLW=. HPVj5Mc҇ljZ_}Ii4T[b[-`Mjlmb "HQB} qY=3`1IOd$=; ojcҿ{hw͝'Kw^(' XgY, (%~J,8jwS{VۘΩd1k;T~/ e~矙g[&;*(%0 {{00<W~sJA݌łko*PI[L 0t@?AS\SwU<*tq7)gB+ *v=! Lu% ZG /!׻,K|Nd*ѩ:~k5%8?v(N5w]C¡J QBIAQd 8d-<^WRgQnFaXrOˡ򫗪j?/LSO1E`H<C촚9VB{yb}aZ'`W00) p3`SIP90/m"V~LɉW:2SX[U`qAl,=3+7rĩ3 B_΅`g\ӒʆQ8g#>BG6W7l7"=Iom2@@6,|Z;jͶh_dM$eEaWI5"A4 (OE[wME}2wK*V_a:2sM'6-QA YZ'_+: s C0AyI bC3]O]*ٰ3Ad^$uXkS$ᚣP]\I b1RiArkਏ ݥ#?/ )In q(! iЍk^,< LEr!p2,cAm~f4=<3i>|?wܦ$^,EhFvBsZ:]؃=G}ZzsK/oGeش<}U1K߅ˍBQ!@UTW{hiP$K]87Fz<軈D}ѵNc00XS68\%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/view-sort-ascending.png0000664000175000017500000000061513061031411024410 0ustar alexxalexxPNG  IHDRY gAMA a cHRMz&u0`:pQ<!PLTE1p3d4e4e4e4e4eUtRNS ̯ZbKGDH pHYs B(xtIME (ݺx@IDATc` h@t@9.9s D T ,:gp`5 @d{ݝa%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_exit.png0000664000175000017500000000237013061031411022150 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺxIDATHՕoUu9~ѦD F"BMj$.DBM ]iĕKܸP7n1ABT E 4mf\+jInrw9|is1Tw- Y X5Ru <¸}=ryӀ= Ϗ3>[;2vDj&yוg!ؕ|iѽ]o∉U 6? >5j5AJ@˃v KT# ?Cq wCO 3 8y򤴫6ftvi"u*Sݫ`vv<ߊ;)QI)T:(̹''˲ d^4HD6K+k&D;З;=yCeaU wsol%@ kZ?#&@%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origExitztEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_horizontalfilepanels.png0000664000175000017500000000156513061031411025440 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEy7p lhfee mo mkgg a>SQ)&HHg[NOoK9:ڍ^ΉۄG[WWkF46vfVW8KNtRNSOhjjjjjjjjjjkR3=>bKGDH pHYsHHFk>tIME (ݺxIDAT(u` C 2op. F4AIL Q5`,ҀB񁠆NGJC-htsY>u S$yXdo?Y?RE/]3'!r8H3o-{ `y*75s>(a ;r扌5{0lorU^ 7b(!247 [6榪=|J²pb0fK47b܊tZˋ _Gck>`xKDZr1N6pcvsj#v`h:E"C)&8sOZS,F]&#+P;ewp-865GrKK$mJlzm\ǖ-@jҹbkdMIeEl޹W@-XԊzjdd|/^_ZhpKtwuP1o>u+Yfڂ|wu)`pN8\Tx PC\now-D#Cr((.+gˊ`Y}W2n60Zvz{z2Ne\ȡ̤ CA4|dF p:̞3TZ/e G\)(,"7p$̧ (WR!"0NFD`hS理YE),*"/? jj8!Mhؿլ~-2:XD-KW?SVaق&;+RjəF*j&'Kg7l'Gw@:zU7ݣS>C)^02o/4x]Smxi_J>ypM"BĴ20m .ac` b$"%G$hhNu;QjSQ> a *&)a^kH79t`OQPߘ⟺ԭ©ܵӯ褿سǯỽٴ̶ܺŽ߸ӽȿ%ptRNSQ\\XjjjjjjkVR4=3WbKGDH pHYsHHFk>tIME (ݺxIDAT(c` Y3#PMF Ȱ%Q;PCIYEUMM UPS]C 4555u459\z@`dhlbohdo03wptrvwqKp{xzzyzz{xq%CB#"cb"I)iiəYii9Pܼ¢ҲT JDUuMm]}Cc]CSsK}cC}skHϯBľIxSN>cٍskyBĢK.[bk֮[{͋ [n>c]ݷC+C$=vSWi<{3H\|eko̸p;wݿ}ңK=|`^ Jaq 4ĝx=I%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origColumnsView:EtEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_exchange.png0000664000175000017500000000255613061031411022767 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺx;IDATHǵKlU}A*)AM Ƙ@+0č 5qaqe41č MԘU&!V,Lg:t:}u1Z:ϷrϽss6~G+m ϷXkoECAɗM{hߨ;0Zlic`U"Ү8CS%+6ye;ʚ2$__.e_`-C_}U.#s$Bg 芹!vC(Uwa)>M@[Hs|G0(QWf){ #]B./1Ł7EXy<՚|={J 2r~`hQS)B8`6 98VnPcBU{U3_x~-cv:2l8ZPH7rњ?ϩHB|:{֓6>c-% `hj"<a7Jn.c;eX~ښF7$Klxu R#XW1]羾8Z6-kАH#QR5LłD v RŸo2SO8!^~ś5bp~;IZ h &eyLQ\+\I>=Q ̨ Mܽut/@OȕI^a_5,bLOWA~=z@~`foz}71H#<~Zxz}7(8 H3ZY*g`ݝd_Nx6܈,TFsz1)T\1Xվ}{I&6s1WjfKU?Ovm ML:{ZJ#}JKP.D}V@6-rE%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origExchangeYIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_configtoolbars.png0000664000175000017500000000315013061031411024207 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxWIDATHǵTklU;n-v RC<*U@ J4&? F$&l+K A05F!X @(1TlyK)lhv;3f[bbss3Ha矝u(Lte53&[cMU] u@(S’j9c^7Rۖk< `2V\ lbՎ619)3°ayQ b ,i3f+5YUTXM?ҍ։@DZ\TU@)ن:xފg RuDF/zEB 8x>/>,RM&mA(JT+Bu̍Lz@`jn29Ǥ)8tu?bY9TU(hhG0{#8yT:]C˜% ^oߘ={wHJLN`FsvF`uP!!-wu|(u(Xp @?Vo>Gl69(%WּThrf@Hϐ͊!PtuF]HASUBp)xMUHL[+CkGË+A4W 4Vs1~ \)~p>nY@4϶Kຎ^!N]׷Xs1šx.a;U_'}uV+?t Hf<>n:JVsάsB$80564SbA[kIdsGJo$ 9Vȟ,U<m=~;l%kk5|hYTsfp~xZ͸CXQXgbȪjɬ*g pM `m’keZ*}Cjm{[%\c8^o93?my ʔ*b465dke[kr"ڸ/uWG/Ő%Q*J!"TE:a+Â9׋8;  9} ##SҗK!#8ZQ*v_'kCFaEs#PMcR"*HHi#^aCb7mhc7'.L1X YFQ<ϭhXuG |Pq(@Ԗ@RAL!D(T9"tvΊųiG `e bCu]4ɠV \V3XDPt?N)5ٕl>鞟LȊL$t3!U2aSQJG _ ]ш"9[μ }ih ' GjbwYx;pG6<m۾ڒ5 q16RƆ9|G)qFԿ3*lHc%ۼ i;xFʆcb:{{~3ŢE1O  *T@o'ןӄV&l&tϙ>u ρ|fӝ[6o>c~UzTZaK:ȣq/ןxc9<ܘ(M5>דtkUaZ~Rذ8\1xljJ7Rha`t]cN%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origCompareContents8"*IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_openvirtualfilesystemlist.png0000664000175000017500000000271013061031411026546 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺx_IDATHǽoTUPvWmPBD!&ƍ. #hB0 M HD&JB' A[N;3s>\дг:79y7qksЫBXNaR;7?r͋oK qGXL9PVr$H_Pv>O۽5$>,!ظ*;S@AfvzBX— xy82s9rR1` QJs{MDc8h^ hq|6Ps``5 *zAf.T z@Ԋ_ uy i[W2_DC/w?q[@.X#byLd"ݲuGt&|LDFkMuUgcJ!YB-h2wj75>>.")Et{ [НQf#V7q_<|رeā5m^N4ì4]R3;0דMѓpWG?&>tIME (ݺxIDATHǽoUǿwnm6-BPL0`Ԙ‹AC|P›! /5+$(J"b- "n?̝Ç">Infs{=B:G>cO\-*Oϟ{|KIv++_fZ'V]A9J޷ׄ4Il!RucNyQVd ecϬg\f( HFǾ_WKr¶mrjrC~}" @p===8ލd"!ZG;SS{WiZ-DJAgi /$KwF9kΤ`6BT*]l6[1JUJbͫO=|l  wx<-y0M DJH6yǁyp\b1m=-ueHgQD]C&!A4MR*>v`2PJ !X9mY`QB"v0E& !`Qι|Z7 a>6Jbt:@حo%Q!CESBzlѝRBDQW;HX"bBch4W>?9wBIy%,d~0l0s(%(bqs~X}Vsc jRnٶ XyF8FOġ1Xp4MF8ixd~Muҩ\ו?+ZǶ`6\ %Fyom[plmC !ST7`ei۶DD\pp.9ͦwiԪK~u6*jߨzȢ[$s; NL $jz%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origSearch\WtEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/edit-cut.png0000664000175000017500000000241213110270720022236 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE  XU     ђ⟟܌Ჳߘߒݝܱ֩ݰسok10:9!!%%))""## }oB0gtRNSFbKGDH pHYsHHFk>tIME (ݺxIDAT(c``dbfV6v8'7qr@cb@LXBX$>!1 E)p))΁ܼBY9bQq WTVU*)%TAW (:}&NPMLM1cÝ0`e=gy,Xhc2vN΋H{xzzy,D   ua,"RRϤ%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origNextTab"AtEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_settaboptionpathresets.png0000664000175000017500000000246513061031411026022 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHKh\Us#wfr&I&/ 1mh"}X]JA܈]]Y4vEH)(-}YH0><&d2dޙ:.چsaspyg7; ;լdblޞϺ2-dԿ Bilzf _/ Kdܶe=nzLezM(eaS[K)`! -"=<$FP~Dv|-J`cG3k3NB? <-ȚU jމrH?b-_+14#P R$jS>Gom5حʨByCv2PMR P{(s+!i3Ok)^=pⅬdD1` 9E@#т8d+mW݆`(x|ȯ_ Ҭƛ{r4Wk~ Q`uB.JHBD0$ CVK(#k"T@K?m`o|Xnζ֒&&"g;] qDȯovL t )$-$3&_>xkj+3~WF4NX/$LA: ɵYWZ:'#_E;asDپ~3g'ƚr.6>y~U`$<G\``Ϯ.,T~Rh8w4NGtF,hKI 46G9eaQB>]EWZ,P.sȏ5amfzF <0114AEV }O⧋k3*%Lc_ސDn$'gKWɏqvUʝYymI˭JQlP(%RMwWG' Ǧr(ȱ*8}#8ͿqRjD4J)fzW*.؅Q篑?ùOm@%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!$tEXtfilename:origSetTabOptionPathResets9IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_dirhotlist.png0000664000175000017500000000257613061031411023374 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺx$IDATHǵKhUsK&NZ{X * qSKq%RRtJi%F 4mR$Mtd.s\L.3IZk>s{}sGƤDAL봲K^=zJ,zrpþǏ&7&…YeQwpNny1(͸>ttRJvoHvO3 t:PbkjCGdv<'?>[5G%tXcHYJݢ?ݳM 0!B*`+BM5B 02EX H R!0XB *2| cZ@1KwXA iYZ@)7M)W"l@k{O)M^ ϟ:JQ+s*Z߁-/48 4ҽq/^-XDhCq2ލ!rTX[I`*s—}sBSRtKCmxNچؑ;ģ4Vٱg*%#4WNv!(bgP22AkA1{mfⵓ Q$ZU]@{,[oK@11A0dώ z!0~]@#PҴ"8AX m;HX1TF'rǿ >] fBE`$FGDگvDt AJ+#s} |4 $qs[p[~$wZw㦵 1RPVr^kv|E(0Y%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origDirHotList_tEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_taboptions.png0000664000175000017500000000221613061031411023360 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE2Kb0t9{SS>/s.Lb"5=zdɂچᆹᇺᅷ"4Do]]Eo 7\fpAd 3Uat#Fc 1U_u'F_?|V⟦gC:tD}-Wy5g0a0a0b?i^wdeh`yLg\ZXZ[^ YZ]iijacduwyRSUacd012TUXTUX012jlnjlnDEGrtv]^` TUVdegTVWxhklxzzzzyxۂޏӣlԋw˰̬c׵бطfܼsftRNS,,,,?;;kj?^ e=eU-]!= (+!2@bKGDH pHYs  tIME (ݺxIDAT(c`rX9 \<|p/%NK@i"` 1̬8ʔKHICAAaQqI,XBN**kjAJ* PҬhk޾ 'i%utu@O`C#㩓MLfP`ie=aj8Lwusws*3O@ DPpȬsJGDF͋COHLAԔ tqdCU*"%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origTabOptionszqIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_checksumverify.png0000664000175000017500000000311513061031411024224 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEwy{egi]_`{}_ac"##~tuw qsuikmBCCPQS9:;UWXghj|~DzfOrtuklp>58E $%&< 6:=FGH=~23j&*$)*+=6)/\zoPOT<~2)1^y0g;|().Zz1]oqs /Z}2X xgKHSfhjrtvxx~Pg8rOg8yyOPQ%GÿȹM-$,Z-C2:-@%)Ƹu ˱}m# ʏ~ в{z~tRNSC{299$7./5:4h h hzwC8Y #%6uebKGDH pHYs  tIME (ݺxIDAT(c` 021# +\}9P0w'\{ -EKxx|K-KHJI/_RFVN^AAQIYaƪ՚Z\\\:H7XfH$ T|ͺ LN W7=pPJ*WZ#GedfAݕsSyϜ=WXd /.)=eeW.]ZXS_Qyn߾sU0 5'O?K6<}W߼}]cs]6Í>}Ҋή޾ '%L&O ӦϘ1}LcBI_]YJ%%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origCheckSumVerify !IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_markcurrentnameext.png0000664000175000017500000000302013061031411025107 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME  - IDATHT[lTU]>f<;L;,RAJPi#ԐjT i&B"j&1X !#J-Sh;̽s=~i;5+{Z? ޽9z6}-뿷Z)܃f  zqهk,ў74Y]w8Vw׷㽟]>rh&`fzR(l-X)wga_um?S$-Tip.~򩶒\/`'#Pȅ"zg@Iʖ4*] vޭym^;(~uky{|./t%D xbn#Ȅ5Io>9L.PZrT`<+ Uf7Wl~S3o}Í" '?/7$ o.lI?.jps洽h޳=CxcPV0з ѵ _*>1<0, T w_6]/1i@GB{*gIٛ1J ptͯ^%8 UIXpL¡2ʒ>Դl%!]և: fwl?gFȃAQ7H` ((+Pbhrr" d0Oz5| )?`2KH6m4F)  N9[9L827)kH8j@jD:9#E($HT4LJq9 -n(y&; s<wƔ|j7l6o11#%GN8#qr?ˌuVwzOKM < (Sk62]G[ax"[XsB-gLtFGjă#%xіJ Uy|gG e[ :oy rV;Q5rd4,EON2B4N@=tb̤ NXď @j>N&~Mͦ4N1BUw)@ ) `F2Uc8x<=6aSx\#ٙ%Ibl 錚 j^{%5H\z.U$-&\K4>4NQh D .nO<0(& aͰlQQ?OO1s%tEXtdate:create2016-11-19T12:20:45+03:00(%tEXtdate:modify2016-11-19T12:20:45+03:00u?IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_settaboptiondirsinnewtab.png0000664000175000017500000000247313061031411026330 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATH]Te{Ι93;쎛PehF](^HtMwAAu T AYDeaQP_άqf9yH ݖ@>uԭ/)T}ﶀ^=tal&&C{AuOUN]_yľ\ߙׇ=\k׬aS4kwɆlu5:߼g7nD^ IFBLeFD#ZusP]f^T,K* GrAЎλ&BhhQ;֊CXvFqY9~xC)Uj 4Mv^J;Z#jLM'm bA! ֔j(2F8y2tzlL|a"u/MΚv6EJ CX<5Ε~C@,S"Q93]#SxfCl\9Uӓlcs3[غd? >Oq $E \?k#DWҠ#f~ u =g\ԣwW.2Ri=Dֵ V.:!QAAqãqADc\לun8]QY- T`1[P.W+DiרƨUؑVWJj U.04>ȧgPN}vo@ ,JyhQˁok?OgQVE,S|g*MĵktIME (ݺxCIDATHǵˋ\EUuvtIfL$08ʅAĝ"(.\&B"n\kAe.\ĿEB2y81!i23=۷oUu{^9_s gSS_6 R>2ă4bko?X֒'N]|we(dy|80#"hc@y.֒\; IC{*" `qqu@k"_~+UQ>, BFI {R=4W. 9@7sCR xRxګM:GA&LL, l3UG$=ZeW4uZ W!(l'_14e J<\l_s : R)s10}8 ܽqThAJQV"2 ƒ7"((4TyVJF"h J Ͷ΁s[W/Nv|<#SіV@@!0IѠ^,ʥS:Yko)oArGlPZ+ׄĞ=}l<J]U011%V)Z)?;G^P+KOv1"p&xA)D"4:i2l?[,aF֫٪/{rsD, =r髾_WV;Zs W?> }xqDшoXzӫ,:z=@\mrfbF~v<7F[G1L6Z:"D@0qzwڕ0pf#y&Μ\%f4`"ֶf0K}a$*{w.YmN1:]ڲh ;3HwCtY♑ˇ_ϝ(< 7{J0J<&)Jt!\ڻ_򧹢_&.FhfIw-Rx:o3x7n7.8BtȢ 1 m i{x}Eـf|azzj"ɾ]`q!4P=`_4((qs˯oی=O qR uowܚŸW8gh~ #򼬪(rpG5XBefn8/Byߗ! DFl(Cq%SlpB>;{.Sknݩ{6u9T F\rS [YYESKJj*1e0v.p9ɖ,vC':y-'a ''Nvᶈ$꧇s GEо{{7Pc~lbpZ ttHmjM`Lcʾi.!"|Vʉo_9 fbˋl!c'+'zxzK䩇7L&Y>ah.Ue GF\e^iTun 4+`̧jp̹z-mJ$] H(8({9uH\Gm lz<\tIME (ݺxIDAT(c``dbfV6v8'7qr@@PXBX$4,<"cbD !)ܼ¢bY9bIiWTVU+)%TW (:}&Ncs3J -^5h-_r56vk׭߰ U-=}|}Ł.3StUT%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origNewTabxrtEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_fileassoc.png0000664000175000017500000000315113061031411023145 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺxIDATHǵˏ֭~TuOwy11Ɔ@DBEƋ,6?`+6YE B"bm㙶{5wWuUˢ{؄OSus\]K<ȣJw2L\粯1sGBY.9uJ_ @ӥRx w@B(XLpgjuup# #c²,N->31K>Y\R6$-H*H&aPGGmH1X3赱ӷMMrIpCچ$ ˤȱYEJM QħKgdC< aP1a}}fd!.{Y|qm0\B7N apEJ obRJbVkJ Jj:&֚HF$.`,k*( $4V7a@?DF`#%v?x7H~vRJx/cACCzfc:ئǁޟȁ*qħ=(2ᅢ@ 1kFԏ@` ([E{DZy<%ؐm0ȥQ RE Bp_^?cd&P H%sIBw,^ Lp788)#2䬈e,H[GBB,*WkR)n3EnmR7!Ȥn 0ӏ a'hn]3aF*f=`4ni(cBMLN-9${fndig{(j77^y@|9=yXCv:ͩ/;w.fjv;8$яYEF9tO=o~ugM;z nӿ5*utamf56~a/i6:51voѦƫnzzPZlu^H:OebwbHU{~vbi.cad >W[H"L AtwF"8  !/- ѻbKGDH pHYs B(xtIME (ݺxvIDAT(c` 21\eecGs/?M!aQ1q[RҷeDe khji#$L[XZYs@H8wrvqusvz}? 0(8$_DȨظ;I4̬ܼDaѓ%eOUV!ں/[Zm^w>z^d O+'lW˺_JF%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_makedir.png0000664000175000017500000000276313061031411022621 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE@ˋ0Ɇ)Ɇ(ˌ2~9t(?( a͒ȏ=`&`~)` Â'ǃ'ʊ/@a o$a"ʛmG͠\a"v)`#9"`$b&A"f*R1jl0-`i0ЗD͐<ˏ;͎<9.\+ ,!* >.Y GG*NO&AuȌ۰۱ܰQ[VҙGӛIӛHԝKګ`khߋ٥dnomne؟iqrtg߬JKGnכmtuuvo٠@֖ۧrrXYY[ܨOl^]Z~֒u߬KgpphՎwecjjuttuz}~׌pȀvyzㄲAJ M Sy܌Vߙ{}}qy@{?oۇҘBpn*qɐ*rihyNuoЕ@億8zធ=vjunnPMtRNS*--)2?u???v?7?, ??1???*?=v ;uT =u;wT :tI7mBy zD}G~IJ؟tUc#f(j-m2p6s:u=v?֚tu>Z^a!d%i+k,j(g#k)r6ՕqS UTWW Y [ \ Z ӄlNRW _ bdc_ ~aSW Z hkjgcca`݀ᄵ憴兯݃قoiۀu؁yVbtRNSGk 0Lri  P  D$,@G:3=&-27= "*h- .bKGDHtIME (ݺxFIDAT(c` `db*ƎE+/_r  ~Դt FIDT,3+;'7/@OB,!!%]S[WҚ&k0a0 )MSM1s9sfϝPR_`ً,]d U,^v 7k@5ut6oٺmw7iٻAK+#knv /op CQ~A!~&ڡaK#|#c|#õcà Ӷ3O762DvD#[[P0Yfc^%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_symlink.png0000664000175000017500000000251713061031411022670 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<pPLTEvxx̺WYY⵷gkkOQQᶸ෹fhhEGGOPPľ8::8996 9ExCLHzl?u=6j67j98k;9k<:k>VWW;l?///nooghhfggiikSM>nA;j8GxBGwCGxCGxC7^6ݻϻκϺrssxvr|kKUv*{2`KxV٥eҖ[jPܩ̸ӕΈ:fJݩωp(=}_EИ`vU{vFЀߨߧગ\tPNJFEGNpPM=^BtRNS  _LSSSSSS\qqrT {:#$nd|bKGDH pHYs  tIME (ݺxXIDAT(c` `!\p n/o0vGHAWPp\"4, ""|Eb1q`".NMDqIGHĜl)D.!KN‚"iDqp WAbKGDH pHYs  tIME  )?IDAT(}iW@@1mբV]*-tR$qV Nݯws AΎNzK4-7C$IQTW7P=-8VSVxhૂQqfHVE` 8 A4E`hxdZ$RJ1 ;P @4Ehrjz< \w$ d,]b!,FhGӯons9n& $Js}#ۢ9+|Q2|`1;GI k=2d̑೮=PkMmgeaZ,i?qX.ӿO^1%tEXtdate:create2017-05-21T13:49:35+03:00u9%tEXtdate:modify2005-10-27T00:10:15+04:00G=IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/document-new.png0000664000175000017500000000210613110270720023125 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEOOpORO_O\OQOOOmnk{ono~iӔ숊ﮯiNctRNS ^+:(8a)bKGDH pHYs B(xtIME "-GIDAT(c` 021˜H@DTL"!,R2rlP yE%%eU5u M-mN7TBQYIΞ*䠯PrTVq feJxyzyGDFEH2""! p K K 'gdf!Ix%e'#K$%gd!I'E%UTdUV"II$m+/ihDJn--mihhiE̪jnihBHNkmGP]3e)S!I0D!7,[;5U%tEXtdate:create2017-05-21T13:49:35+03:00u9%tEXtdate:modify2005-10-08T22:34:45+04:00_IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_calculatespace.png0000664000175000017500000000277613061031411024162 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺxIDATHݕMlTU7G;PZZ$7ĭq `ch .LP1  ii|uu'9y/=}_7`9v2,eYj=U?Jn[帽NS[N[a(,cUB_/WM 'X^ 8~KdSgmnC(эYCgst^ hDE4&&P̱wwU79!C{7vjꉇpgQ"t"KA b')nM\ʋ@2t8|%X8]DŽoE7H#Etm#ma;iXŵd7{o65f}0vkKe7RTgrù玌^>Tm̗,7q\G7wE\O*B!kJ@uJ#ۿ @m] #F*ڭ@8P# !%BG }TgG/=;:tdVaaҟ6wn}T惉xôjEZ*^~)?90?qW~ eVY*4tݑDk48hBZjarl;@(\,k=ll%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origCalculateSpaceKotEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_keyboard.png0000664000175000017500000000256213061031411023002 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<XPLTElykx6>Bjveqzq~vn{jvht~R\cgs|mzkwhu~gs|NW^%*0jw^iq6tIME (ݺxcIDAT(c`02agfa"ō)/ (!.,"*&.!&*%-#+'j@ M-mm]=}824J@a`_ P4$4,<"<"2*:&:6.>!<*1 (a_PXTl0/)-++ooljni5՝S?aɓ-SN^1}Y̝7y~@ ˅/Y:y+W^l:i 뗬_2b=6mJXUnٺm@c{;u5Pzi{@`jUS{J>r>r H͵wJ8:9W7'&#i$w}$%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origKeyboardmtEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_packfiles.png0000664000175000017500000000271713061031411023145 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHǽKlGgf׹5IH IBڤYMwtP lB $.ZCBH)W (6&ϦNع~]9]b'!j4s~93? ڷ:'xa)OAӠP2x,TM,T"ܫ>P}LNτ,'Ru*P+(Jհp/=7uT0kǮч~PQ䃂 ^UgU$wp{˖= YY*^xxtk_-p\{ԙ"{5y~?e@7o Zp2wcR?:wno+Ǔo~u=p_8~v<z@ճsq-z˿I w~ywІ oZUib;Pog6ᇩ(p\7{.E:qm]j}|R|&7jc#;n"G"[ƕ]?]1T[L:}݃׉1M>6^ЕkjV3NP_0DW@ЩzO^ %_ g6qQq-{(.l0=kkȖweX" "f  F o:%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origPackFiles`-^IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_restorefromtray.png0000664000175000017500000000172613061031411024452 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEL?_L6@A^O'!0^ 7tF<S4 t&9[#v^ vRecfY؆%lΦ˥ʤɠƪ<ʴԖ߮پ殿樽ύȰ䯿ӔǺЩˬӡ~ŹٞҺϿݲzѩͥܦxĽŊ檷Pe|NczMbzNc{]lqgogH_yciiQdsy|gKa{Od{Nby tRNS@fbKGDH pHYs  tIME (ݺxIDAT(c`021cgaec"Ǐ!. ($,"*&.!#)%-#+',E%elkhbգĻpAHBF&fV6vF` {G'gW7}w}O/'go{@EPpHEX`x/X"2*:&6.>!1)9%5-=6#3*,_P__\RWV]hhlhninjKttvuvYOП8irWWA7auL%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/help-about.png0000664000175000017500000000303613110277137022574 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDCtIME '7IDATHǽ[LTG9sYPAxYT5F%41iҚ^^zmjbbڴ֗PҚ4i4FJED/ xaVhM~ɗy~3 BHIY x^N;"%Em{$Pn&FyU$VnGJ}"@VAh p2D//MX9?@Ye5w**~/AKf8K틝GJzU2i_S*kgc6Bhh(@%yLNmjmőWi>ų드8aδ L)\8ZVLf /!y2Ѕ(%)i*^Q=S{kg..뒚;CjCqpٜjq_<?[~cϼxf88 -}D} 3~>>Pm;+zM}Css3|w<{:G4Lޅ P)=w$[B{~=K>u=m8 )|ߵ[ߕ , h`JL11=ˢwŏxxG*Gwk] ge{4%1?m=}1vc HFcq#}Ĕ1bl"!Evhw[cwۅv7.Xϑ@b1ގw?ğ#Kf%tEXtdate:create2017-05-21T13:49:39+03:00>M%tEXtdate:modify2005-11-10T13:39:18+03:00F?^tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/edit-delete.png0000664000175000017500000000304713110270720022712 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE J IJhiewxursqxzw~}kmi{~yy{v厒Ĥʜάå玐ޞ̳ף릨¾葔𴴲툌ꩫޖԚӢ޼ۺľࠡoqmwytegcrtp Jۜrz|wٽTN[j\djY+Q,RXXʞ(7̦ˇ}tRNS𾝁΄ρùҼ #<)/1230,-*"`tbKGDH pHYs  tIME"2IDAT(c`&Ė۶m;vl߾s Dy׮-}8p-v1%v:|1 8~N:z]`gN={?ąP@2\J\Eנ*q$Xva`ﱱsprq  AE\BRJZFVN^AQIYEUM]*o`hdlbjfnaiwptrvqusJ]qHDTtLl\|BbR;)w݇Jgdfe{O{r>wxqhgM;w:yιflmˤ%_tXʎy<}3Jmw|&/ߚe+ktRp*=P" &!+&׮{rR̺nD0єUOUEYp Cre'CHwr_-mZ$ ~p=` rͭOeNohl[Bl6r Wh9$CTed, 3[ګ2.b%hݱQ9M|fFEǟ@~ gp^1!܃lyM z"m$N \@ﻖXn(!Dci\ gw4f'aP:n@nqT]]}<PccuT[[s<$h``@8{_yFGG555yv{h4_|`[[[;c***F5M󔗗9e˖V5}cO/~%tEXtdate:create2016-11-19T12:20:45+03:00(%tEXtdate:modify2016-11-19T12:20:45+03:00u?IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/edit-redo.png0000664000175000017500000000175713110270720022407 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<ePLTENNNNN >;jn=}"0+:+BcqLtRNS  mIF "(D^ m QH#j6 oniLAbKGDH pHYs B(xtIME}UIDAT(ύS0 Ҧ؆w0\O3hY/{k( sfEP|t[A)"!vt/ŸpxdEcq%޼I:NY'#e.W..gm޶|w|ջQYU|gMm! !ȜCSs J!@;PMĮMiT5z`PhHЇpxdt4#{ɩYs.,!-qC_X\Z^Y][ؤĻ2sCUF|jE?r6C%tEXtdate:create2017-05-21T13:49:35+03:00u9%tEXtdate:modify2006-07-26T14:21:08+04:00y`IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_reverseorder.png0000664000175000017500000000123513061031411023705 0ustar alexxalexxPNG  IHDRJ~sgAMA a cHRMz&u0`:pQ<bKGD#2 pHYs  tIME (ݺxjIDAT8?hSQMLI * Bk"t^ HN[BPCK$7Yr8-y~M8;ظUIƄBe5iǠA1"z<5Q\ӕPtۖ@y a:LQPISpEU67-,RAA 4i^{D'hjgYwyMc?;ZQtH$tlwNwb +b^,)5{#m܆sN[aTR`TX-4OΚDCZH(+#DPKJ(#o'Ohlc%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origReverseOrder1IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_multirename.png0000664000175000017500000000265613061031411023530 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺxSIDATHǵ[lUnF]-b _4Iʃ&b@H#0 1!F@mhhNev4,b'yso΁{XZZL|F ȁ /nڸaC;~˧ֺRy?~(p{h豒)X q'|>zzz4WK)v~JwJRYS<_ckߨXgdG*&q'T*EItܹIeN͚.O=7c JJR*H!R)XX%}vZ{om|d9B xAMI|(  S۵'.%><|x^t)%%hG]# )l?!.=Cn|tP^P| ?KvHO(*VZ"1H0{ ]GTP{s= FeYTU4gv(C­N2exG{Y﾿9h ^~O$ƦB(Bl?{z; +k( NJ|,3bVJ_"1,vOmgLĭ˝&Ɗ*ܔD'gd5K^c#~] 1hU=(;) -Ճ(.+&3*8=m]ʭUVI#=#Țo6 cG0|Ey$[<*gZd6גD#Qb#(x711in3R/+5ahm5gҰݍH*_2p1?c\_d,Af.@)5ђ"vhhyOLOm&H"ߏ֚p8Lgg'Dh4MԬYpw,|L̶#cY{̻d2,",klzLdFÐmsǶ)(g/ mc q0'uX]ݏJ)sRjE=ݩ~}G(`2vx?<`У{,%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origMultiRenameфtEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_showsysfiles.png0000664000175000017500000000253713061031411023746 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺxIDATHǵoTU̴̙ӛ F@XAB4@ &&O?FL/G>R%1#JNa:3휹9goN !䜳ZZkšQA=v~ĹBJ}GOz+:Dq魳Cb-:ݕ*xx#-Xrh־eS:ri>z1`Sw1~9LP%Fbh[FJ]OMYr `}DiD`إ"(iYo%Hh~`-k2 <(QB)_svu5 }_TR-ҨPQzU܌K\K:2>}h ZS-x3UYZƫݗ$.7>1I@`PAr֙rp{M X s9=p'"4)bdScN V@ӹͣmvY~E eOON]Z_Ww!0jעCw (AIRY2s15`_hhg|AcW=Y6DXLRJ"XJ Bf||ZyĶ$SgY7KW5_>3w0Ʈ`vF~'lyӿ}?wɱֱVK0}s}tv|'\rD'iNsߤòCwLވuA!=6FK+LGL%UkQ lWL_Bdb$[[_%O=bq"^5֥TqAz4!?^O?%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origShowSysFiles tEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_saveselection.png0000664000175000017500000000325113061031411024042 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxqIDATH͕ilTUoyufL;0&h .[Bq-Iܢ!㐲b}f:YvOsor~^?5oφ\J7?}!Xmy8}!;^PV4wNL;3o`k%hZ Y w |d&7>>%tBWtC6O]dכ bT" w"?4i[Yﻕ`R1&p_HC(њK$ RcƉ[?E\ЀMS3*IöMQbunW/{bE[T%Oӝ=w?*}@]o f=`L͙D1dedJz<>wtͱi+w">fH")%rtk7tIEU$,E ?^ޛh.;v hj687Ӝ&FۊXLj\ZV1FD}-kNl`y"d&MP V xiaU7286Q詓-ձѴ#0.n)Љ14X",4AaIeY >WRbYYlm6E-Qu,8ek*щj"2Nt܂(##Rg\+.Vp(i،c#z-aRykl E Po\ުH#?N2r\.5α/׉h 1أĹ 6վ鑪懅2":&knomL'K>9ə Yr*:iv y}V[Y0O u;fN'].S嫬=~JfVoExM_?'-#H=ƻ6ظ )3l"?v[C>~E kx*K|mneS]R5hò$M' =O a:DD(#kaKs_ԗ ~˅hy5-y&?]Et[r/uH%}&Ʊ۽fx!ˁJ2)Rbɪ/6p1^MC(Qa:+=(<]Jx>nSzȀӚ +ĵto-#rLRC~jn6bO?l6;~8kyËbˮz@1d{dIVbTwkIJ~c7gֹ2G3Nڹ/>U ]%u~!5ug| k|_k l'~S~n=%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origSaveSelectionIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_unmarkcurrentnameext.png0000664000175000017500000000311613061031411025460 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME  - =IDATHǵTmlSe~{{ṷc0Y3 85$N$?C&A1A  a07FǺcno{{}Q ݗ{9vY /9sYAgBGs}E%ý/͋w쵕81 wtO.no m6lljxkG״DN^F_d^[sRa?Ra?lM_J߯ӻ܇- p4=aaSFC 1k#4.jܲ`#H{ .g6B_& FG 4:`뎽{e1(cY1-&!wm),/N(:.:wW&pLfA(f j\SmΔG\T_ƺY*ɩ}ZSyApgqUw*96SC7ݭ,{p|o5!,Zdn}偳;wWg1wd:$âmԮ:>m/0X exϟ]0D$X$)x+F ,um^R*-ł~)~+EH seJBMnxg]m͍ޜ p;IC*6j#kt6P4DvPED2RٶlLk a(w9`( r€kI5Vh@X&x?䃀K@X*A2YJĂɔƤoex*! ǂu`9:藎 h4= ԋt"@$ulӦ[싓Q_,&yn;u[-O?؄H@r?w snp{YvibFsXHvaH.Y"Ա< 0$TƴB21_/C <;4DZ6ˆ)Uxő'P`"rx^u֒ӃSJL4E!<4Ns@UTbLfwTU% )BbA*p%7th}gfL@NPu0 ER "t6+,ͺ\*#gܽܶq%5~CFHfqZ4}W pPׯ D<ٜ"D<xD6"rÎ$}qO$@i3@mK'mxr:#}4LIӃ" F՚՚K&YVp3"OoSD>a%tEXtdate:create2016-11-19T12:20:45+03:00(%tEXtdate:modify2016-11-19T12:20:45+03:00u?IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_unmarkcurrentpath.png0000664000175000017500000000333713061031411024760 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME  - IDATHǵmpTƟs{7mòI(/ 10VS mEFg_֗v vC\>/dڊ bB̚Mn6@S}{<~Ϲ,>P p7\77fϟVx޾K3^ Q98gO>{r6זH˹Ȟ[`k Νojt2dFo+Kj셫U/^ha@yõ/}AhXҲiM@6:H />G~055ݻn}bgL/C(5X$oRG(zdždža@}P!gs66P~hc,p_p7? <aQHf:.>ryr0v`̶Bb'l`=px*AV Hִ\\tYzYЏw;J+?塇)>҆"¸4 *)RIꙚ+1꾋e3Kt@ͯabHM0.DZph.709]7yy"rD+&/DuL}:ոN&Rq ),@ 6d_(^lj`suS ;я8clc0vA)D ai9hp, S8"`=(gH푕(ʀ6 *Muyc&ѽA(HBH N0^ L5HȦƉUԴ>=dzmRUG5A߱3.0r$.vSaeŐLO9G6KG3lh4mď_LڧIXuϝH i Uĥ[/m$[j1P`>yWSDDinlXd:Q@Yϝ 0f6y?˖ `g cmVwNtʀwh}fVݵп^FQW&zkOo X Yʸ$ԜHEl\P;q~As lSGsEan0-C{EQlw8ŷtI#|wF" 9I8UW韇wCcL&i]G9*˲x,(/҆3OWUE1p 1֦aŐl!%<.F=DBN /lXxJU lNӴm Q IbE/h[?8*~vǎ\t^թP8 N-&KB͛{"u]7[__u9 ;1v '%tEXtdate:create2016-11-19T12:20:45+03:00(%tEXtdate:modify2016-11-19T12:20:45+03:00u?IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/edit-undo.png0000664000175000017500000000233113110270720022410 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE"|zĠ}yĠ}y#}yθ(Խ$O&4W,1μ"< ¬A o$$͸|fB@q |yZYcb[Z 542120}qmYĠG%+DNWN243G]\atViqql9s牣 I JK#$dd>WPTZ SQU+.VWWWZ,W.WFr0&fV6vu]S {G'gW7wO ]m@`PpohTwKxDdTtLl\|,ĤԴx0ULFfVvNn^~Ai *::EE&&E:r2 xw] 2%tEXtdate:create2017-05-21T13:49:35+03:00u9%tEXtdate:modify2006-07-26T14:56:12+04:00ڝJIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_markminus.png0000664000175000017500000000330513061031411023204 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHǵilTU߻{gLNgi0%R c(D1M`Q(Dh1&.qC( FE,NNٷ{$[⛜9| ϢpEf/(g ϾnX\uP}{[o|-VTܷ74-w"c[?1J<=Ls^F_, oy/$[}-]r8 wؠ ;r%zW+#SJ6yؤǶ+`$pPSdt_@nC)mrOæ>* _Ӡl'ϛ%UM=1 R*_Az[E0* n~x̷wdy,^Adj:n{>/=#mٗ P*Bܐe +7K$ IB;X ߾+f>v@~ԚHs" MI)$'&itA݂Knb$&s-w;[Nley>Hter&=04} c[ MzVV-[ G j$@ƨfhKhTDil#Tgfܠ9N;f 8On۔IJ2kL:(0VM՘ FyT8JUSTŨ^3Tvဃi-Wׄl2g(PSuX8~ӗw+5үxZ=#\u0(ԉݧ3WjAv 3ØI G<i=n_,9NjFBr>{P%aRҾL%WP'ȠbE]I%`O nsmg4)-?N" 7 %&űU7{ݓ"/_`] X@~ ["M 22GV/w7- gr,~$'RA+ ` h E͞ˉP}KWk^I`P4@6Mg&}_L,N\+:]^,歡LaeL11Aedh:R\/ؽ#| BJbhAoRkO q:o_0s;o[N%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origMarkMinusIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/go-next.png0000664000175000017500000000227713061031411022107 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE;u9rX);uf9w ,V9s=wJ;t9k:8pZ)3fN/]7n*R:s٤ܩ՛ڥWҐۦڤڣ١{E|Ĝ٠J~I}GzDxBv>s:p6oqלxAv?u=p6m2j-f(Xx՗o4a!f'k-k.j+h'd"_xͅONORU X ^`a]w:u~TX \ ^ `_ GpW \ aegiYg~ԁ؂܃isiۃqrvz~ORtRNSLq 1MsmV  K& $,3:GE-27 "l* FbKGDHtIME (ݺx5IDAT(c``d!̂C"DH('wG񣨍ظxA!dĤԴ,a$윜ܼ¢Q1DiYQyyEeUuMm]N\GR . 0qҤSJ"KL>cs+(Bŕz{_p%KUT5Z`,[BWOH] *hJk s3S;UV MQFNA.VnN = hyxy;Yxz@anjo`odJ Z&&ƚ OY|%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/document-save-as.png0000664000175000017500000000205413110270720023675 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTElwMyAlWx}nTqBpbtSyInjZQygDx?r?jlW^|ym[~zdx\BnG}J?ltMMrplwlTw`}n[zr|mnpkxenpknpknpknpknpknpknpkgidfhdUWSUWS8guc;lG}tkJ^[SX`npkuylhTr{ruk`ʃPc؛bA꺞Tdh,1&sGt Fe%tEXtdate:create2017-05-21T13:49:35+03:00u9%tEXtdate:modify2005-11-10T16:59:32+03:00U=IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_prevtab.png0000664000175000017500000000221713061031411022642 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEOa6w6w5w[P8tUqyxynEoUVEo@flf :a#Fcta 4V4Nr_ @DOyuK@~J;v8nX]FbKGDH pHYs  tIME (ݺxIDAT(c``dbfV6v8'7qr@cb@LXBX$>!1 E)ip))ˇBY9bQqIiYyEeU5*)%T[Z;:@W (?aSjji뀁>Pp3gΜ5́sΝ7V60` wX %l=~=@'o2r a(*)%TT0 x%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origFileSpliter!$9IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/edit-select-all.png0000664000175000017500000000147313110270720023476 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEݫ٩תجށ߭tRNS$/5.bKGDHtIME9r6IDAT(}mW0a,^Qe9`BgcpڎVm~h)K蘖5M-v=8,=:C8Bga W$K@,NX>Fs*8V`˒4MÜ(J>j(_8!)eK Y+ėٚ ܐ*c.[kJN4(p赔}u}Ӿ7 @˳(%tEXtdate:create2017-05-21T13:49:35+03:00u9%tEXtdate:modify2006-02-21T16:57:07+03:005HptEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_fileproperties.png0000664000175000017500000000262213061031411024233 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<yPLTEĖǔŗŠ[]]>@@899%&%}VXY;<>}~vwzrtvceg9:;|}%&'ijjijjfgggiiabbfhiikmdegTUWsuwYZ[BDFbce\^_&'(άֽ権аԾʞմ垠̣ޓŷʫ•ǫ,%OtRNS!" PE5Cpqqqh  !)^;*  bKGDH pHYsHHFk>tIME (ݺxYIDAT(c`  ! !a\p n GHĂA\|BbR \"(R32#"A-*/¢Rq DYp9$V $ː@P$\"j:Jj렠>HJ&Q M-m2rPWPTHO&O:mU y,\xRU5IJ+@`eɪk]~u DM7o^bmwܵ[S$g/G%?'O> @F@E+k[;0酞. }|1đĤ@/%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origFileProperties\ItEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/list-add.png0000664000175000017500000000102013061031411022210 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<{PLTE4e4e敷۔ےڐڍينك}ןqҥoҵnWetRNS ;bKGDH pHYs B(xtIME (ݺxlIDAT(c`+;+$80$;'Bv+7/'06VvQ1q I)iY9V 0hST*%e*$Xԁ"3  q@-YhA%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_configdirhotlist.png0000664000175000017500000000307513061031411024555 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDCtIME (ݺxAIDATHǵozkz`kIHl% !5Em^ԫ"?EUjP/"RB(%_(%$&vzg3;3*^{> |!.r%"*@MkF ̾^}8ǣ10uRϟ{I*JYڴgqKݦXs:0G΃lD׌g!Uk{GCPGX Ub:{7n]H$麿YGH !P(.z!BU5B މ(źN/XU@#) ؅ Je#"zwط#$e{}wW1RC:Bjk@%_}@"L7νV 4jc!_\ӥ !j4mjĐ7><$ 6 ʜ5^Y'Q f 0VmDԖnD|/w}@Bhq)/vi؁GYqeF/.ϮJL(W4.Ͻ\啧0c[ic POPH4"Fʙ[g\,L|^yO&SFym^AsL%p\)1eG@.[y.3triDYtu?E&& fj&°f(_rV؅"c~!l%4MĘykMV1"(3NGzUj2\GF, }ثOt*Œ&ryBA~*zn{vts=Dڀ?chqַC+ JNqxD7[W?q27U6_C-ɒNO?Dg1zf14cN9ڼ!"aXC Fc'w>9iolx}TΝ{R'lÿ6{cVbpڋ PB#W>rSU(;bWv~M\-wo>іޟNeF ?Wm)fC,xj0°]xáw5;^8#>B>nQWU6;Svt荄T7RjfOxrCdg:hyOE4C7vGO- -V-Qӌy:ׅ%ˮ\֮b/%tEXtdate:create2014-07-19T04:58:36+03:00k%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/application-exit.png0000664000175000017500000000272413110303146023777 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE[]Yxzw --77HHZ\X_a]UWSXZVbd`proxyvsuq~~~uuulllfff```bbb킄zzzrrrjjjyyysssttt{{{ÛĤCB맧>>SS莎ꗗ잞۱!!UUrrMMLLOO鑑//77]]22..##!!xx1111TTد'&55CCDDGGJJ"!99efe𔕒ddc熈{{zxzwRTPŕjliDEB»ſ_a]WYUY[WZ\X>,tRNS  $%C~ 砩bKGDH pHYs B(xtIME;wS#IDAT(c` YXX:o``126153dK;8:9{xr%}|CaNNQ hDLl\|oobX&❚ Kgdfe%E D% E%IAeUՒںz+Ʀֶ)DkJWhwOnRo_&O* 0Ȝ6g̤Y̝7P 2|g-\xeWIZѰ}ZurrP aY6mڬ P"(dmwܥ$ѽ{}Z~@ @VPpHhXxDVTt!KlT">!1)9%5M+=( 5*K+;'7/@0:*%*]RUZV^Uהց+IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_targetequalsource.png0000664000175000017500000000234013061031411024733 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHǵMk\e9ޙ;ydbIMMu#B \B7VUЕDDbŶ+-*Iid&އs9s^̽2@9~_;izyC4Q0x#UL}n[͋xGZĂqJs336ʷ7[O"f'tv`&0513R05SoX9bfD[0^HMeՒکQ6{#sR_.l٣ 'V?26RxsY]E${F[#cU ]""(ĥH ("2[* /% k<{u&*U 0Sϝ(^K[7R1xՍb& Y?m̌̍\Zo. e bZL5(NL'W~_0{;3 # `/BeS^9y;z8KxlJȻ2 X&%`N^ "<4RIJ%>:;DQz*fUpE~B);7n_e7 ,uJ]TJiS@T;*dY0'mge>.O̜F >}"L0kqp ag&tn曨 4uզYܤch<1gC\k^JTM2\ 4fy*oycɮLB=gX~_/&-Xlk>b`AH{|OL@|uggg9՛Vva M`h<3>Ij%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origTargetEqualSource kIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_extractfiles.png0000664000175000017500000000324313061031411023674 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxlIDATH͔Ml\W{ﹿ38c;$Qo֩XPݒ H U B *EH,X6,H A!8'{̽3w{X4N@.=;/(ŋGOG󏾟:d\:ٞ+/NLߍ-'3g[?=_+xBwrպDWJ:>4_nok9D;85BBSS04>$.Yeⱕ/x"{NO;g?3|'A7C)A˥Hd'^<?>nT35FWK}g 3ݖ:9AW $[ cRZETo%gaX޻Wl_췗Vqltn4tī \NЎ'q 0 (px6U5DwprFKV6~ \b K[)ٙRCFI+bmtIME (ݺx.IDATHǽKh\;w^!,{Dlɶ,*ii m)䁳.uH ͶB7, 14JBSSb׎Ȓ"aF3zx4սBi0=p?w>x援Όc(0N8@c ANgTnTi#ּؚc&L6g΍|orlhxHTа6Jm U,lg֪_/$p_/tVW|6_bX 0@ь &?"X~޺r5/]'D_<6q}_r*m{ 4()Ή\#,,[?^T0;sW=rX?\YR[+VD,E.IxH!QRQnSpd:kW=ٍ>93'.Nˬn6F4 L\~soN0KpEq Ξ22tn\ LMgRv~81RbX'hlD+@Ԣ_ZI,-µRc 7{RD:u;R~E%R ()it>7jX⇠U/0U4w z,2dc+k$7ےȞPk{XD 5\a;:40ĶZCh֒w. l. ʕ2; )!5@cR{5zOmKB/ֈ;D`h/Ax? 1K!x}[Iluh3F`~ CYZZ;>A%K5Ogkt% KӅlq$E*q'R.N)@ܡAVfZޟ+6>̗X()c%r:YZ+ӪWn7׻*Rs0r44Ry2xT^`nd UL2J|ᵟt>.٭ncɦ=7z,-SmGA~ŵuXgz-Q[ 7 5n~k_vMkUH_ųer(rh%ol[XD8,~gɯ?lϽ` kk-xt(7tI6}qkw-b B"w/kz@tpI>{/=x:]i0BVQڪf:ۿnN7OpzDqٟqG; ‰ cWIgƴph> @pzu ݚ? ;%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origAbout tEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_restoreselection.png0000664000175000017500000000325313061031411024571 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxpIDATHŔYlTUǿ̝BӖʃ! FX11hD &JL jXH-j)et:;..0%w?6y cϋFh~=𱷌"\&Ӹ'||V* E@`W)ฉ`-_.+=0|TFnV7 ?h|`UK88•{ %u-g6 дTlrVr^O[{D[0w't.Gb'A%^𔕯`m&XdcCӷF得N"A5p,=9-20)d)z^.R}X")$;{my_ =_j+9fTh[ h$'s޺'ikS~CۿMJG9@Qf=}<95gESKY+avW)C18 Y)q #P8ݠ /[نS&Pdqb972OCN3W'!2G'r7whk,qլ%(iH,5ͫyH**t/B^Ӆ]e 0FB%Dv45HH5 $J p LppReI2bh0d\%tAYg*)MYDE@ 62S&\'ؘ\(c&#iȘ04EmV1[UU'b54CAY[^΄Q|d<]d*6-Pn_8:ȕ9JH|G'~i`ygnhxhFp`U ?cc}6<L16|@p[Eki]c,rrR M&~hUq+GYm7pK.'AdrAtR ~Ƅn_ (Ўmw?Y\޲&0 KRkʬip;]t, YlwP䞁ZUxvaQm3 '8"{)>:@) tH)HZNoR]  e {J؏ Ӂ$p00pvl73K,$##Wxa@瀈w# %+߆s@ USGɆ*x4ҩDDe# rk_EgǮ/ Ooc#]BESlKO%>-\ŕ$A F]+GH[5_ '7Ӏ'zVop|۷,VbMS{ݝ|Gc 0%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origRestoreSelection(IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_operationsviewer.png0000664000175000017500000000254113061031411024604 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺx&IDATHǵϋ\E?U̎M6&!'ɻ< '/Y*b7hBv7ٝyufvvQT~44[Uߪo<W^wxwoe;egWR( g9>s8x<#W7nO*PGO?w$Y5 '_|"%Ӕ\V7rq"+wQH/qwݩRYN9RE$!#4tgsHT  D QrT:YySGOT AQ%b/(˒R%UYRUW778KyN+2b P1@2'BA d$MI12c*z{;X$3kkwWnET2d(A:dD4,'KܡJF'xܛone2n1H{7mA̭>k>`d; s{ F::Rv;p*ք;HSorz:0 P qm,ɢ4,ȲHPQEcd $nEчA6\]ITAȲUHR{TP$@2ÛopHAtC9BJHQC 3#%I7+6gX7A5 R"3H*+Cܨ` >Jz/͜Kpkm6R$ <{U TCqnk+EREdBK B;*o9Dƣ7Y "tZ?RfW$2Q(*œSDvpJSX|q,6b&R!E!JjfN+zǀlod6( -uW~"DȴNM B+SQ?*Ej陬IZoo_8j1s̭voJ3YwcLu$ɺ1w'Ss {02 7:TT$w:~L:yě|w-uyQDuœ%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origOperationsViewerIeWIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_hardlink.png0000664000175000017500000000264713061031411023002 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEvxx̺WYY⵷fjjOQQᶸ෹fhhEGGOPPľ8::899::9=!9t@'IfXAde 7Z`8Z^9Z[9ZY:YVWWW:Y///nooghhfgghhh^hqST<[(8p>u=t(C(*)Du\ Ԃ@ \[dIm@P-  'M2y4U 0csΛ`:Tb%K,]|U׬]RC*~lܴymwܥ ٽg=GՃq8qgΞ;o`02p.\|7n^11K[Xͭw޻,aN.n.^ p穐2?%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origHardLink ZIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/document-properties.png0000664000175000017500000000145013110270720024531 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEkli߶꭯QQQgggiiiVVVhhhjjjkkklll򮯭___xxxuuu>tRNSb*6ACFE@7& XGbKGDH pHYs B(xtIME  &.[IDAT(ϝk[0qXv5 1]AɐH&QYݴ_syEmY򟖌R?`91v8@"@FRjXE@TE(^<>l@wr"@ʨ+Q$@yIrK!0$,\2.stW-T!nn䬇ǧEPUxO!>jW[66wv{fu0Y^%tEXtdate:create2017-05-21T13:49:35+03:00u9%tEXtdate:modify2005-11-04T13:24:38+03:00cIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_visithomepage.png0000664000175000017500000000244313061031411024044 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE~~vJ nkgfegd>SQ> a *&)a^kH79t`OQPPߘǠqɢsƯжŠrֱس]4|*Ұֳ^ժw0˯fɩyu꿤xŨzµåvw˴jѸə]ԣeiȼǪɝ_ȇķĨ–TްU´й§GޭOòʶ©tRNSQ\\XjjjjjkVR4=3.}KbKGDH pHYsHHFk>tIME (ݺxIDAT(c` Y3#PMZ H%eP,;PCQIYEԀH(+)r%854@559\:z ``hdlbj0wpt0J8{xzy8C%CB#""cb!q I)iiY q ܼ¢⢒Ҳܜ8nDyEeUuMm]}CC}]mcuUeE9X inHtwwO8qB_o$1iӦM2yD3g͞=kHsΛ`ŋ-\09p%K-_rիVXlϚoذ~#X֮J ~A!(JHHJaI ܉BבߍM,%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origVisitHomePagefHtEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_copyfullnamestoclip.png0000664000175000017500000000251513061031411025274 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺx0ӕri.n*E*Q#[H5 dt؟ Ma@a2A .[>,2Ē$7Xhp.µ RUA6`]ENO|Ґea!'W˷F9;wC16s$:.1xb]VW_8T p){lK>)BcbzK&-4j ,cPŊG5R͛6p}WfsM{eCcCEe:;ZcRGG!@R 1J KE!ݦ5e53ʝV,-d(|a%Ԭ(U8ݍ 儉 47sxLCַocZ/sc8|Dϖ|EX6U `%<gY{=tm+M2}&&pAVUZZJz?u ,_@foKc P(^'Zwyq2e `k*a*$r{W+8/ֺd&פ+ZE@9}}D ŪUxj=N*D@ GQ U9\6K`j^ "D>z0^8 F"}y^ Hjl #&NW*|]#G_PU:tkTj[V1TMtmldT ij~,SXck D' >;q+{ydʪڠwn ¼{GxaBgΜDUW@"OOMM=1I5i%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/edit-paste.png0000664000175000017500000000203413110270720022557 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE\\\`@ZWO^^]ZWPnEmEkCcT:cU;jClDkBoEnDmDlDnDlCkBlDlClClCkCiLddYddYddYddYddYddYddYddYddYddYddYddYddYddYddYddY\\\zzs{{u$~:tpdbbaccb~#ň&uqdkkj^^^rocć&lCƇ'ijdhidŇ&ņ&hjd릦Ň'Ć&⸸⯯߭ǵfhd1sobm5pnb,~"{"-tRNS9<]]Qp +?Tj~p\G4"gbKGDH pHYs  tIME  V-'IDAT(c` uUUWO__O &e`Fܜ<|P&fV6v& fAG'gW0pqsrIxyO@  !$}|C 4 ]<<E"#2*:&]<.>!16 Y"( T LHLE_PXT&Q4%UdJyEoU5D~Mym]}OUcS3\B(|AHmM0Б (Ơ2ȕWPTRVQUSh(la,V%tEXtdate:create2017-05-21T13:49:35+03:00u9%tEXtdate:modify2005-10-14T04:32:10+04:00H IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/list-remove.png0000664000175000017500000000063413061031411022767 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<EPLTE4e4e啷۔ےڐڍينك}ןipFtRNSACbKGDH pHYs B(xtIME (ݺx1IDAT(c`ـ 0"I01;'7/(1FDp?i%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_focusswap.png0000664000175000017500000000462613112333276023232 0ustar alexxalexxPNG  IHDRw=bKGDC pHYs  tIMEɸ' #IDATH  JP +$d  .  #      j0  M# V&  1 |֡%5 ) ӌ9و0]8iE~u  huP1.!G7! fhC&  0rO/#( qP3m[qI4 [G.^J4 (ТA  ^(QIENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/edit-find.png0000664000175000017500000000247213110270720022371 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEz|xnpkkmiʣ}npknlniȄgietvqhifUWSjkhtvrfhdlmj?@>fhdzzxbd`VVV|~ykmhkkkccclmjlmj퐒rsopqmnpkrtopromokǸoqlۗqwroĝqsoڋrs΍ţrqikff퓴tǁq{vͫ|ꙛĆʇΫ޴jĎ᤿ܳwyvy墾y҉lni閳x̗丸mnklmjQCtRNS:1o~0)5bj jbdVӝ&bKGDH pHYs B(xtIME  :LXQIDAT(c` 0213323;Bή†BpCpO4n`M@`!aQ:bcSRxxL/(CHWTVU %[Z[;:=}&Ng; oZPHTHDlF!M?چjڤI?kXB[BRmcжmQ 2C >JNr+{흽L}FNȸy?I[GNEQbqĸޗrފ[\Ip4(:Kު="㦈8b@kȅ73 j.ye|n=V󢸢ݯ?:qtm\O)E10!຃ݦ]ZC,O9wa[|iâ ҿBYEXMvgU=kŲ1Oy%9aX'Dah o9殸f ]&{'*mH{9z[ s,1NMƘ )Ve4!ΏTe^24ꉌޓNj'oV01<&̢1>eFԷ=?un60%3Sb9KZjts}0eaETЍ^J b,` YCO!lg7SV(Cԕ%ݎcbtQV#+{'=dr/h4z:N > WA^-U3}.U(|/T"2j[5xDωp2 Rb P|AbZIcbBBJ\p4yuy׍tQr(JKrT%/!ZSSut5.]Ji@]qL> l\as!&$ jD!jX|W)gBX~}ccդ$(۷ߟ, L 1k1pڭX%tEXtdate:create2016-11-19T12:20:45+03:00(%tEXtdate:modify2016-11-19T12:20:45+03:00u?IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_checksumcalc.png0000664000175000017500000000255413061031411023630 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<4PLTEacd~:<=:;<,-.)*++,-(()acd`acEFGEFGFGHRSU678jklDEFOQRoqs,-.$$%z|~<==\^^HIJYZ\99:Z\]122KLMfgi~qst[]^ijlŭ~]__fgiZ\_—::<=?A./1124/02''(&''"#$"#$##$""#ǰƹȳķn$]BtRNS6\\\6 cYZYm~# R|! 1pEC Y/!kp$RBtIME (ݺx8IDAT(c`YXa.1qS `*'\g3fysΛ!(EDb -WPK()NpьI&@EfHZ4g-W4g,^I'g9aH({L Cwr?%tWX*"2 ]<:f%q@ēS,MMK2329yk׭/(,*.)-+KTVmXq[lٰu[u \n;!`ǮDcSs w%:{za"8,BQ8oc31%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origCheckSumCalc+tEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/go-jump.png0000664000175000017500000000241513110302615022100 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE:s:t=yzx:s:s;uJ;u:s:s=x:s:sX'^*:s:s;v:s;u;uA;u:s\+;u>z:s:s:sH}:s:s;uNR:s;uVY#:s:t`+:s:th5/]:tp>p?5j)R:swG:t.[(O;t+V(P9r+V&ReshWLgvf+y }.Vdk~3d^ j%ehhV Pb#b:s_R NQtCp5f(R}IX_\fbmlPidZaV\S WTgh6@pxtRNS{ƈ[f}4QI1YkdqWF &" 61 GA !$UP$h/ bKGDHtIME&(DQIDAT(c`2`dbfaecD橨@ohljniAnkꖑ +(2*)OP 'O:u.LBO0>cԙ`&PS5IXX20XYOySNo bZd,\hԩ .\howeSA`RWg'$߸{,__ %\ IQ)i22"2Y~9y)iE%)ɹ9~>:JRA:|Q(//eÀoN%tEXtdate:create2017-05-21T15:12:11+03:00fM?%tEXtdate:modify2006-03-22T23:03:38+03:00 * tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_copynamestoclip.png0000664000175000017500000000246113061031411024411 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATHǽoTUۙ)m-JP@&C0B+A6b;\61 wb0q!AB| tNwf9bi;R* };>nܹ_El6ٳgO\w^ Nd2y,FQl}txG{|n~6_Xaq+E}X.Rol7Uڇ S0o}H$ؾ7}%^c4oAk"Qw㲖a7j 1b#΁e@1zyǻ.ܟ?GWeКĢQa-Ld^פe_Uj |xĕr`hiJKtw rdrb8L*+⯊5ZoX2ay8#ۻxG?қ[6!SWP*uoYkReng9C:Ӹ'  X 7uPMō4bjZR-=CxGoo/"l xzWQE15a d$x*TABQFtcM=f")eoZxk)j 6X Xckҽhm܍>8JLXYe"e9!#z"EjuK\# O4l(Pa_58RjZTm|g|aĕEclqP=KE2FnO 0,*c(kx299i9Rc D"?=55B!*+R%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origCopyNamesToClip;IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/go-up.png0000664000175000017500000000223713061031411021551 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ< PLTEr>v =x;v;vy:v:survr:o5mpRZVyCdic#^YTP}l1f(a!\TO_эw@o4k-h'aS QVj՘QyAw;s4n,\W W V ^rנۥۣܠ}Ay:e\ \ ՁӀрy:sޢEr*`abaق᥇Jfeggf܃|8iklk߄t)oqmlfjmnl߄㩯څۃރ݃rKFtRNSySk4D' sxLN   "# fbKGDHtIME (ݺxIDAT(c`/`db*ƎM͝S˛]\@? PHU\DT,(8$4,\\BYYJ:"2*:&6.^FVIB^!!1)9%5-=#SQ !_PXT\RW(+ohlԂJh777봴wtvu9zH4O8ir3?L6}YL9w(ͳ.ZdF0ac#+W^`f3S#c}e3XZe,:́:lllmNH98[;gрSr%tEXtdate:create2012-12-16T09:30:47+03:00,%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_editcomment.png0000664000175000017500000000215613061031411023511 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE2s[hkjRrԛrQs%SnO\\ZZUAk$:ff$: 1W{qq2W{ ,Qshi.FZjcd]%' Cc!!UU^9Ń<@//( P 1Rf< KQ;bKGDH pHYsHHFk>tIME (ݺx"IDAT(c` 021 3#B |}88`\A` ^dTtDGEBcb@LPBX$.>lj%Dⓑ@|R(HB<%5 %$32@fFXBR*;' dKI$ed ?ON^^E20((RVQ{P@M]C굴 a"Шo`h&:ҰP5kj6+k[Dٷ88:00t&!mKf@`׋H%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origEditCommentNtEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_quickview.png0000664000175000017500000000231513061031411023205 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME (ݺxIDATH͕o\E33+؛XƤHA)S )R/PD))i(EH"lmQ~O>zw-G!BH4<|7ܘ=3rˌml|Two?NO~w$&KV8kVOhal(6b<# VT9;b H9p13"zRHI"w_c2:H@ 2B=@AA#GD;_h<.Bo@D#^^'IPQ=IpxwJ"Z *Uu q` v)(Tit$ԉ"F:8稔ˬI)rvTB ef''9 9:-`X4-޸ՀG6~XƘ# X 8EX 4Ԑ\LLSF̿I\ *S[EY;I@D+$rc J!0) f)5H;siciP ݪoܹ&r#2|'<DWֲ?;Ԧgټ3g'g0:}pOӯ]νD ְZRqzё JMzcwie1Amzws?^PET^a+1d;mڷ,y,qwa֞Ti+<,k_-N|'nS0 d*PbJ?tx7fӵ%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origQuickViewW;IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_settaboptionpathlocked.png0000664000175000017500000000226113061031411025750 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE2Kb0t9{SS>/s.Lb"5=zdɂچᆹᇺᅷ"4Do]]Eo 7\fpAd 3Uat$Fc 1U_pBa?|VYF:tH-Wy5g0a0a0bDi\`Bh0a4f,VyMIKJu ܩFSqr ء:ܨFnm ՛1١:ik ͒&Ж,i `fkjgk`xhklxzz|ꎳ͘Í꛱ēάϕlԋ耦}}}Ɗq׿`_gZaqknks>o F6^>6! ;3ߢ#Ֆ6ZWtRNS,,,,?;;kk?? <;,,,,,,,, bKGDH pHYs  tIME (ݺxIDAT(c`rX9 \<|p/%D"` 1 QQ` )Ĥ䔔ĄTY|ZzFFfVvNnvVfFFz"H\IY% _UM(QYU]SS[WZ[SS֮ 7142rMLfV}&ZۀfpMf"zH;hs$ ix&vT\Q_sw'&u~cvq t& n %R(WCG;voU35OB )^B% .matάS7Q.; h=@_)4SN`e&is|;"䄅*je:ig)`L*Ro9Y;D3i+2¨M8WiO)#Shs5A^q=#ȈBװíV1v*s$ǚ)’Yy鉀6iQhC[Z-wOzR$bE-';Vd2Kƹ29"B?q%7b6%_P/MJSɐT;63r֓ѳ_N⨀E -d7ߞ3q~kܷW._6?3hI 3MX&\sl$:3"luyhu۱ P洍X1O_n⇆ӑ(^Z/о"uW|2|PY;l:/|K[_{{vTxy|Js\e)nwL[߿gqf. #YT^!?όQtJQ\S4[a K_||@.|[݅X% .y!Zx‘US/qQ],%iDb3h%8Ρ8n0}J E +tr:uH\d* 骱#/j}tՆM̒IJtr> `Ft&,u`*[~g" i+@"'=vǞG6kh T]Ύ DO2{kO&S OM%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origRefresho#IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_exitfromtray.png0000664000175000017500000000240013061031411023726 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺxIDATHՕoUu9~ѦD F"BMj$.DBM ]iĕKܸP7n1ABT E 4mf\+jInrw9|is1Tw- Y X5Ru <¸}=ryӀ= Ϗ3>[;2vDj&yוg!ؕ|iѽ]o∉U 6? >5j5AJ@˃v KT# ?Cq wCO 3 8y򤴫6ftvi"u*Sݫ`vv<ߊ;)QI)T:(̹''˲ d^4HD6K+k&D;З;=yCeaU wsol%@ kZ?#&@%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origExitFromTraytEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_thumbnailsview.png0000664000175000017500000000236113061031411024240 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsHHFk>tIME (ݺxIDATHǵnES{<0rDmXo'2o DBJH (8Ì=:,zf$M|_?/xKi/٬f-+vaͭ_r0Oz!coT %_/h [76J#< 39E1r30V=b a`b;hǭâ:?7ف"B-[&M@`P%"*Fʚ3 /[W|0*v ?9_)*ށH[wx L3"qYn3u1Bʽ6g(#Qi?{J]DqQ!EX$8|l쏦FC] @'ԪObh2 a l2Eq$N?pJ!>iNH}f>UndRԲH[)ws(w7&ҁ[:HP84OHh,tT"2C@xR鋜:  -|'Nɡo}r,B'/A[v"t; 㽺Pm]x囯.^a!C,OQ ;_A^Ra?\%tEXtdate:create2013-02-18T19:53:34+03:00+г%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtfilename:origThumbnailsViewItEXtSoftwareAdobe ImageReadyqe<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/actions/cm_unmarkcurrentname.png0000664000175000017500000000322513061031411024740 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs  tIME  - IDATHǵ{lTY?Ν3;mN2}Pʔ7MCaCTf"Acf5A#1YͮCEXM6"v@)<;3(%SMNr]쮨kY,:LR*v0['~k}˂'9Rq6A}סk :tCD1AlV~OOl|E_G;((v%uK/nmXf`g*RI!*«7޽{r)Ѻgf;roIY(Ħf~?,`Qy_AzP9+=fVu8w4V<~gq/eg0LLc]'3xR[PK lQes닮Ԛp~x{;߁/a[%T0o\3'q=!,wֶoSJ _?%][f1;UjEb|ws?=u]/ okr*@UXM[v@92m|DZM uΧ[?q',kyLC%JGVk 5jpGF{ l=8 ?us " {R`<_h嘳yL3.{RGu SLPW'PU~6[zcJu_H"\v_L:r%!+Ld %M)f[̂>@|yDu{<R;L qEQPKMk.ݦ"A՛O:Ebڴ7%E~-*9lR͑PH'1ط ===v8޽{7ܹ"rU'Rʾ ȉof_UUռGiZM6óK*FUǒƛ ԅG 3}}}礔'sܟx-}oo@ 0iZaoG B PbJ%tEXtdate:create2016-11-19T12:20:45+03:00(%tEXtdate:modify2016-11-19T12:20:45+03:00u?IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/0000775000175000017500000000000013244011205020366 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/video-x-generic.png0000664000175000017500000000226413061031411024063 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ< PLTE999!!!҆񺻻tsu힞ggqۃFFJ׺yx}|NQY^`g..500733:`afdekffkootlmqhioooukkpffjppsȿɽɺɸƳű¢UVZeej}~iirRR\sr{BBJhgnA@GSRWrqvddmLKTBAGUTYvv|qrz[ZeEDOZYcQPYWV]@?F##))(/--40/70/8.-6**1$$*OOR֡||~qqteehonrvvyzz}^5ctRNS#S&l\MwXbKGDH pHYsvv}ՂtIME (ݺxMIDAT(c` 02f$HIIKK˰B%dUT5445:Jzp #Ee5CcS3s KK)\BTYSEKCR!ᢢ*5аȨ8F|BbRrJjZzFLB+;'7/4+ !!YfT^QYU]S[^/#$mie$ ʶ0q)S9F.ӦϘ9ksrq3 $,\xɒ˖ˬeKXKJddO]..[ɏg`deɒDGZ!aRF!OX3Fʔ%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/text-x-pascal.png0000664000175000017500000000224313061031411023565 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE***999DDD883$$$ʿl-ef,`p=llc&\x`&Zg]&WX%SV&QXƵij\'V黤ZbƱ[(Vƽݐ_Ȑe͹˜l\(W۞u{kltRNS98"5=G;1sObKGDH pHYsvv}ՂtIME (ݺxcIDAT(c` 02F 3TIVN^AQQIIYEUM]]] &o`h$""b 0QT253K((Y;X9ډ89%D]\] <<ʖZ^>~.j2p аpH=[)(dtLl\|}KT BB:9%5-=%/I** .ᔝ_PXT\RZV$a\QYU]STWԜhimk&Ot:mfaaIH;͝g!l;?++LI$<=[88N22QYQ\ QYYb xx9300 (%Ǐ#_SY~%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/x-office-spreadsheet.png0000664000175000017500000000176313061031411025106 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<VPLTE999!!!φݼ\ftRNS#S&l\MwXbKGDH pHYsvv}ՂtIME (ݺx@IDAT(ϝYW@pCW[,ҶqDEDvl=30LW Kolh¼A}m_X\Z^Y][،D)FcP:0x4qrzv~(%^^]䔼,K!MŒ5u a6fGHoe%2eՂ<6"ʣQBU()7A>^?& 9W*ҵOA@jKn#g`p i&0+\38<]Pk_CӺ*2 D~TGig^~]3F9)U%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/application-x-cd-image.png0000664000175000017500000000263313061031411025312 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTExxx{{{555CCCLLLPPPIIInnnLLLûǴɻʻöտܽնƲҲ˽ƻ׽ɽѸˣǼǻR*tRNS\\~0I]dMf:*SbKGDH pHYsaa0UtIME (ݺxIDAT(c`#TZ:zF&f@ 5I\B(lbfieml- ]\݅^>~Ap xHhXxDdTtLl\|L.!1)9%5-=#3+;'.a_PXT\RZU^QY0ojljnimkKXvvuM6ir \zTigh1s9s%lEE/X8cƢK.[Xr5-k׭߰q-0 Tm߱m={p>6'N@H>sI.^|媤#L"(>777oݾ(-@ADUUG̼ƻd` `DBAQIYEEEUUME]C!jzr%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/unknown.png0000664000175000017500000000210413061031411022566 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTEKKKjjjiii&&&444;;;***daˁB%nRȺ_gdhFgCi$njTZ"l)p„ۙ[QieiP|8$tRNS-=.d nvypj9k8bKGDH pHYsaa0UtIME (ݺxIIDAT(c`  +Xp%eUT5444Zr:zFZ Ym%S3s K+k[;\F? 0(8$$.m 7pԌOH MKxēCRRBCcc. qXxB>(YHxnH4 Y",9hi~P0Uv YYqE<08OҲr^>~Ȥ؊*/ZA!ؤ&a8\")+ԶET &KKQVR !ʂH2 ZO%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/application-x-executable.png0000664000175000017500000000247413061031411025770 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<pPLTE6HxspyzfsU^~bl6Gtdrfp7Grbnltenoviouy&3Ujo$.J-mp- mo ) 6HxښÙBbĞŞůDaơǢǢmKfMhȤȥɥɦʵRkTmʨ˩˩^t}~ت̫̫ͬͭοoЖh{i{ͮίϰzŰm~oqrԼղѳѳҽ՝vwuwyЌt{˭}xy׿ؐŀȊݚªʘ̯߮ΞOh_tRNS6 #2 $BR1( )7DaqTI<. +;L]rbRA0'FS^caWJ, !#"_QbKGDH pHYs B(xtIME (ݺxIIDAT(c`03bgb&ϒ)ϖ̎.ϑ*ϕύ,ϓPPXT\RZV^aK(oh0 $T75wtvu Be'L5iӦϘ)!2k/X8%KƋ_bU׬]fxIR7m^e;vJ#A22vٻ/aYdqC=&*ΠtS*jHZϜӇKƛ7I;8:9ǻ{xx5  G."2*:F/6<@jlIm%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/package-x-generic.png0000664000175000017500000000116613063505653024370 0ustar alexxalexxPNG  IHDRw=bKGD pHYsStIME :gbIDATHՕP85" J$hhZ R< oDC44!`؞CuHv؂9so_=Po@%]A9œQѰ̃#Luvgt2} ܛ3xQ\܍T7x @hy|].y|VqqP-eș/5ɋ(uؕα^f No^% :; Z)g2 SdX+"FȠ̐{+0<Wusňtk+{1+:::SPRR(0Gԟ ,30"k;S7 kHg/`r740"?y.4qT6[*M9`Јh#Ј@r#g?\OK H+@_|'N \T_IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/application-x-deb.png0000664000175000017500000000235313061031411024375 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsaa0UtIME (ݺxIDATHMU[]3 wBq ui .nt!. BLLdaB@ݐ57BaffzzHƅ'9usoUOܓ_k5kkdqg~k*#k[h6jlݸW_wS,+t4[t}K7ؽs"-JtJڝEN+Iq˼i&[ :E,P~zbq04llr ݽ,lܟ/5001-tBe21}}|wfZ/439K=;;;888777555HIGbd`^_]Z\YVWURSRNOMKKJDDD>>>:::///YZXRRQIJH?@?110...'''GHFefd<=<897443;<:YZWQRQ676222554~}jkiBCA>?=LMLjjiggeeed453JKHEGDAB@QQPyyyvvvuuu342HJGDEC?@>()(886---***&&&$$$ƴY!*tRNS\\~0I]dMf:*SbKGDH pHYsaa0UtIME (ݺxsIDAT(c`#TZ:zF&f@ 5I\B(lbfieml]\]=<^>~A!p ȨظĤdaJjZzFfVvNn^|~A!\(<.aR[WߐԜhKXwtvuW$ zֽ}&NH!`K&UV--I,[bFU׀ubа^a&^l]%.ضwl۾s={%a kZz$aE P$Ѳ~L,Y/gPTRVQQQUUSQdD$>`u%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/image-x-generic.png0000664000175000017500000000252613061031411024040 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE꟡WYWzFWsGWsEVsEVrDTqCTpCSpBRo@Rn@Qn?Pm>Pl=Olfs?Qoachq_~[{WxTuPrLoHkDh@eQoѯ뾁xurolheb_~CTrĶŲܱ}nycjtnjHWsʝdz·ѱØɖȕǓƑt}kuQQQn}JZuIYsѨҧѦѥФϢΌRSSupyO^wETn_afWXZpvUVWKYp7Gb=Nm=Om;Lk/Bb#6Y 4W'8T1UG{[h{{_[h$a/39s~3ߗ?%̝&~CkQֹ؊$+͖Leid(MM{Ow%8{pVMZKYZJke1X[Ra4%R4%R'va9+\>qCj#sf,L0A@، H7T+ĊlݲqIv`iuCC`Eau=i͑cČ eIQZ`j\(TjST!*<ӡ; @ |DBl i ȃ[m4)ꑲI;'P8 ε1DaaH* &[UC -;DKDKp3gǓ123R˩ 'ȯ'ٱm=8^i5۝m;g-شa-Eza;'ύ}#DaHQ:Ve/^oqHDxo!MBD;7dB܈ XFDZY][5bps+fBaPON/ ƒE˫ 흵D0!q(1?2/oF__ÚZav"aQf*g?mu~Gj?>L%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/text-html.png0000664000175000017500000000236013061031411023021 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<CPLTE999!!!҆k0{?UטQ0~jEwlkY.zJfӲbxv0}6x_΂s_kUW@~iӖdiyyd:zbРs<x~f#lQlկstZyꀳ{Xcdltd#m"lbn>`i耴Z*ulm-wFښdbߒtsfu tRNS#S&l\MwXbKGDH pHYsvv}ՂtIME (ݺxPIDAT(c` 02f$HIIKK˰B%dUT5445:Jzp CEe#cS3s CCKK)\BT_R!ظĤԴ xfVvNn^~AaQqILB !!i/$1aSN>cنp sΛ`K.[*!mr5k׭߰qfN.n䖭۶عkw^LȄ{9 L2@Q2IA$q&/u_&Z %tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/text-x-generic.png0000664000175000017500000000213713061031411023740 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE999!!!҆ӶftRNS#S&l\MwXbKGDH pHYsvv}ՂtIME (ݺxLIDAT(c` 02f$HIIKK˰B%dUT5445:Jzp #]EecS3s K+#kk)\BT? 0(8D!imc$.))-PȨXDxAJraL*B,-=#3+;'7/? !!Yh$*.)-""*#$Qd /1KHi؈[[VTVUs@%kj[rZ8a+m*ini%SPdJ؀$*mXɏg`]Z*) $B D%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/audio-x-generic.png0000664000175000017500000000205413061031411024053 0ustar alexxalexxPNG  IHDRשgAMA a cHRMz&u0`:pQ<PLTE***999DDD883$$$} ѳ44$""֩+ ZZ2&Ԣ1'ӱ&߹ywU:z &q'`1zUB:w6[%}NwR= ƭښjtRNS98"5=G;1sObKGDH pHYsvv}ՂtIME (ݺxLIDAT(ϝO@p(-SP8'}N{oӭ 5ߏ/\3vسਭc9'/@eSr{> REfrJXe9X=Q3nim3ĘN Ț-p]=n%`p$ulN(mdTX MD4gLN,A "\\B+R uMd&"d;Cv0򠋚pxtL)֮tÓӳ Ne. sux}s{wO(%EŹ>C3 EiJJJm_aBJm?VQZF?VUy B(%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/24x24/mimetypes/text-x-po.png0000664000175000017500000000251713061031411022744 0ustar alexxalexxPNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYsvv}ՂtIME (ݺxIDATHǵoUE?3s-h* ?h!u뺊+W&I  ᑶIr[{^3?M|?93Ky}juGV(Xo76urv)hiP,ـs!RӤEff&fZcEsBrmJ1cֶ,7"j3(;xZ` B/PhJNPbf)*]n&,exq(#4ߧ횃"2󌝿Jg%Ϯ""ԒYK+m4ob0bZ1_al@knqŕ:zسgE PT%B>鶴^7 ,cqi{shc@7@7);JD x,Qh+zKi)cȓ%MDE V]ylbhE)JkkuъM<,}ռB_YO1iP aq~"֏mV4pFG_W'~[wkL,e$)w΁2ęt ?ZVgxρzPE@Ȭlo (/7yEܹ7\n.\=O=`~8S[maحN@y!qYBrdG/ };\ p8Q-+2S9P@.hE=~C9^.|9z|},^wQ,U(˄A[whZGXJH3E49ܸtO~W^ 2]ʩ>-łaW!٘‰A{gSotoONNSrbb4Pg:1??/UqvJ$$IdttTժ$I">*Oh6E$I"IHeXk9'9XdiiI&&Ƴ/<0'{w[?K?ql%tEXtdate:create2012-12-16T09:30:48+03:00*%tEXtdate:modify2014-12-29T02:40:00+03:00!tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/40x40/0000775000175000017500000000000013244011205016346 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/40x40/devices/0000775000175000017500000000000013244011205017770 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/40x40/devices/media-optical.png0000664000175000017500000000641513061015620023216 0ustar alexxalexxPNG  IHDR((msBIT|d pHYs N Nw#tEXtSoftwarewww.inkscape.org<tEXtTitleMedia CD-ROM$4[tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/ IDATXk\uk}ܗ {&؆aô)BD(E"/Z5B2rqJPQjRG&V%h$ )93W?mh~39!Gi|nbbUlsc @TOEn~n>p-4&'ꦉM4-D TNK9s&9;z}8ol67>>s{ɶlBYvʊ 9CEh6Z-bK/_޿3Dx_nZs=#[laee8u(yEEQUf<,#k?|-[v}Op>m۶'F˗/%(`HTL%rT@TΞ;ǏXynnn~i`Q@"VCP*FUE 1v~jgcvݻw﷟kB=_={ŋ !H)aɈQ0 źȞa ,fuiZC8z?x[v}֭[I)|Ē0"Z)p5`&43P3D0gɀW|NCa:)ff 1J RfH]H"RoC"#Wwltޱ?2_;8j{;Gőb *PJErjAUEGFJ zܹKƁCmPvl64n/R U:t b0zEA;@cׯ Cp>ǩ"a ZL,NhKG>wMEnQ37Zȳ USez)F J!$zEIׯ/jn "1_jzM͛7uΝB9G*5CPD>sP=Dv{Aț~U<..)S\hJ2a . T"aĔ0;دquR[3PCˈ,Ir3.]\㪺`fw-.OݽƛnΓRϔQ O@ m{SJnPPd j,ot)]^^ڐ-g9;'_={ B~X*$ //f ۮ NOLLH`9?<2bUXɳ1| 7+Wo߾b0 fEFbPQF#)b}Bin-)GFFn'CģNȼ1>egz*cjғpkcS`"eDHuU!͈)b }&v{!1)A !D:#&a0J1tšl~A*Dh%Bd!(X,jVG4ZJt`a!,gصOm˄.w*T ,EdTU1U*kRr !Cְἣ8o>[oLcb|vg?}hjMR.yVⲂ,Y H0 c>!67ϟ?+O, Qs0::FL4J]'O?V:+}/lq}(:xp1Q%`"ґ{cye{Ws-Y8)FP53q-qA@REYھ]6=0tɖ>9<Q:2!kyfL C8anWs'h8YR2UPKH2~ d^Ȳ zReFQTb6m"̄P8{tcL+]ޑf}m5y8?(PJrSU%堋P.,`0"X{^A:c\?8wn*:7A*NTPh4TW_$#"∡۔HD, J,"{F:Wݻwia,jQNbdIhxFFrZ# yh[R"QwDfbc0>~􁴻/̞;™ӧkxԕ U, ,C4d6Q% 3%asw~z.=fٳ_WC:x8'5ː"]?č@6@ĉA~Q|~T6>>VCXbcXpCJ KqݙtWԡߘlP׍ xmSN-%B "9`"nYiqiqNO`0%PmaxiCmJbرcߎ1\\\壣c:22RRkUE&^"zG2[oQ;7ѣ@ v6z-Gٻoᮻ~kImx-_V./Kǎ=+nPڠ`M ?L߻V=ßnڛV~ٿvޞ;osIpa7Dc?=]qXdZ:(IENDB`doublecmd-0.8.2/pixmaps/dctheme/40x40/devices/media-floppy.png0000664000175000017500000000337713061015620023100 0ustar alexxalexxPNG  IHDR((msBIT|d pHYs N Nw#tEXtSoftwarewww.inkscape.org<tEXtTitleMedia Floppyr*tEXtAuthorTuomas KuosmanenӇL#tEXtSourcehttp://www.tango-project.orgɾXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATX͘oTU;td(M6tѸ@WhBj.piҝ{V 1&Ƅ@bEL?iuqgc[|=w=yy;5wUa4{?|$K?gCߜ=Ϗ910<\Mt]$EQ&߻ws T^ayn-Ohgn!60lN&*pQ?nN>Uz/>>32U7^I t3)@?8}C{ko(CӨNP/tAEE9lCiP#JpEVEԄkg&*z޶+ LNN cPbphډɑY h04nd8L&z&.]6t&MLTU$2S˵0})DYwR@ZZD3PKRfBp[fT,jĚUa :$_pyy j0A 3iVhcLU E$/ uI ¶ˇ&&UdM7lr}9e3}bᙛ̜O4;pRl}(!H(\oFw s"Fْ"L(5b[u398ޅfl:3QU&:@)@ ދŐaDb YLL:PQz}3ɰ1(ۭ>RZp~ izQ#hħIޭD "^_ "f\zc V*P /cPtL$YNp8\RAƫ/OpĞ!ИGX&& `LtڬST;V 8t8k{̆ƢcqqqH|2B@5Gb; Z- fnnN4 Yڝ*fk&3g2eCB[k1{7^`>1h4X[[lAmVQ(0022BRallZFZ/JTaR,M윻ӷ!NP(P.ell kmrL\vs7<<}JVғ_IENDB`doublecmd-0.8.2/pixmaps/dctheme/40x40/devices/drive-optical.png0000664000175000017500000000402613061015620023244 0ustar alexxalexxPNG  IHDR((msBIT|d pHYs N Nw#tEXtSoftwarewww.inkscape.org<tEXtTitleDrive - CD-ROMǞtEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATXMl386x!2KԀEbUi7R{hO=''DrEjJ!Ҡ"E!B@,FĉCvXoG 4<b_kįo!?>s˲A)nvvvU_ϟ?[p3`ڹ~ܹ#@"IS ,!(P ď2̯ggg ^\+QMT"4~ɲ f[i H9PL&WOeUU%Iˋ/aׯ_ɲ p~ U*²^힀ҙȲP[@&ea?qFxOT*uLl y=SV1>>.)͞o/]&_bx*VU [ҟHEh̭ QѲ,pGΜ9L&l 8555NɲLځk6+QYwBfΞ= '{hG5 V,d2&L&9444-It]o~׮*9w\0Me}Nob_UUL&-Ƙ'<رcT*]FԦiB$rɋ_,L~$>6y4M׭X, ◵dauue]@tss|,~߸v|kUUE>{s@:U]N+++X]]-ni6wnq\]Z]סi8É'Ʈtl{{\`tBJ n&8C"@ZuB uB"ܽ1iѣGqԩ8CT(8p=B<STu?~DQ< !x֚bSAD" y0%@/^ׯ]u,B(P*`Y\ݠ@A>GGG:;;[*Ƚ}6|ifWW"lάA(1۷d0 W\.N> Buޣ"bya&TU`XUU(Pa`1QF!˲T*A4B\AuW.P(T0 hf`ؑx<S" k`wKVT*(h4QQDsR" AwJe==0P?8ײ,ΖE1pʕk׮QQaFΎ6tMLLD8Lt0 lmm5xQJ'Ohsss{TT]P,APKKK$P(|FU*M1M,,, Ń`lٿhM; ._|(J*L9r$ "F$ <σMӠ*666P(̵5UUϞ={mT[*.͓2Ӊ}}}yg&(ſg lvKpUz ? 3g+}j,4[SM2 J8yKK H$pG[[[_?z :a$ $i ,ԩS6#Oڤ摩)dY ˲'WVV033cn,Cu$ `XfaZl6eY?~p:֦n evdYDQ455l./ QAQL3L` (,ZVtttȑ#Bp,8999(' ~tBe(H$z$YgZ rbBXд CUUl6tuu766^ܴ ㍮뙹98W`pp<ϗ=h3ZH$PU @#r<A()"RT`eYVQ,KyA=At8r9va13AQ\6L&D"Bɥ-p 82}Ae ]בN!ʂ8*PYLeH~<>>ڽejjξ~Pr8@Az122B J `Ϟ= y | 6]7`D"v$f3dyu$ xv$A" Qv Y͛7FD"l_$SaJ Fi,A󨮮j2ܹ\.555xMдVrx|'Lv777|>bi4 Uj[ZZrDbyBlvou}3J@T*$Iҵc5552ȹ9(jR)\r\cfC:a "']: Õd2l6;f_b Q(-AqR;MHq3ÈD"(WNǛAESԗn$6֡\.'bq( k(4Mv! eѰxDUU!9 '&&#FH`M(*<_7LAh,4 . qgE63 p:p\o[Y)OmP_25(Z,A$3??!Jի1OU}>`ǎZlΝ H/;4ikZ"0{IԣoݺW*U$1UUuj%{<^l6"4M뙌aYz(*+͎ښ kdrf%#~VbGwj*4#In,g%IX˂ CPr+zk4Q5ВL&?|B ^u8EVQ,EʲM_C_ Z57Vq@%\ ,Kvuij9ò-//[Qh*gq?M2_\\\ey 0m2 V4Y]Z ӡr2ɓQ\7#,+ӽ~}m1V%zzWNMw3 Qs{nʚ%D{IENDB`doublecmd-0.8.2/pixmaps/dctheme/40x40/devices/media-flash.png0000664000175000017500000000412213061015620022651 0ustar alexxalexxPNG  IHDR((msBIT|d pHYs N Nw#tEXtSoftwarewww.inkscape.org<tEXtTitleGeneric Flash Media%ztEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATXKoYVWĉgaIH DiV B"V|$,Hl,!hFh@Ǐ<,t;[s܇:uvҫۻW&*ͽW7ϜЏܿ>t<~ڶܥK{lxg>ֹ[׋е>`m+333]uEV-msyk|<:>{u'N~ڥK7p]1ߘÙcO>S?k_G X9ǿ3TJ@ Rҽa,H2AMBh^l&* 6=L_9-_n|:5] GW"[L6q,C\u.IxB G#-h u^-L-"l(MĐ֮]W Jo?LQ D%|8n۶* {3{{f \j a^7]:lLUTo_I~v@+ɚgD ݒ(/|s6,.JgjofP>*.=l)6Y{,chh@}!c 7}_\/pJk/wNruCyFpG\Q_rA$ d:wfȱK|}W] >C}ΛLJeaz}tTz\"p#R ` @6aK{Sވ$8 @0EҵӾH,&JHQn,ۀt̀QDl!4JMe(!*`hQxNP&;./ꍙuͣ pRP*eqY}o]Iui ð<@ |ۤF#R5;$2ؑ3L9*Tla`9~x}U p,PP ] ҿG˟<~_FOy7FcM? >*=A@H*HTyW$IP*sԩō;(v=;f_L^) iGco+o!SPHy !&p[Ah4ByKKK D5??} .BGGOk^ZGI@hRo|=CWTo9`0Л|DesMwVWW]7QՐLU#?0֠q]Eid;77FŚZ|{jكwiSW;bqqqɰe}q\pSV+&{oj`uR)fff^Bsm w ):B:Nj Klt\Y5hcJw!8H{4fFu:;ޥoޅx@Zb$}:yW.D&2111Wl6@`*d!n,ZM 4ѴV)5"Vkg$o_7֏qIENDB`doublecmd-0.8.2/pixmaps/dctheme/40x40/devices/drive-removable-media.png0000664000175000017500000000273613061015620024650 0ustar alexxalexxPNG  IHDR((msBIT|d pHYs N Nw#tEXtSoftwarewww.inkscape.org<tEXtTitleDrive - Removable(tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATXMOF66B!UX"jH,^C+H3pCzO[%n\JzF !oYqthߍ/;;;/"r\s :{{{pu (˲4::aZqppPWo4`'pyB># Իn Fu!lCA)}ӈ$h[r###+++^6͢P(ԵL'v- 6 0o<om0chh,n o %`aOT*sss߼zj%, ^h4Zu3 @,`l Ht:b {keYPJaٶ,[Nkuc/Bkp\777  !H$RnU RA)Xj9F*S[a+Z\F&wkkkcU&Mx?_ZZ~ T_6P(q6 ![SSSL(bj$I(BEHI`2`2`6a6"hVܿ'3o Yjll RB[ mjτoooAn}}}@Y2J!pB.nܸ |wz=DQJiEJ)cuz0`&t]i);]y.\jY:3`^uV0 E1!RJDQUPJi4M풋bA4!`qqvg pkiit:i`(]RI0Ji˫`B4M s )VUy^B2USϓk׮}QקO{ڄD%}L d8U(c `aaQmŃ[t:ʆ3")Ty>99)+ʽepcc|u904d<#ZmsZ+++Vۍ_<`sT yfgg%4U,)@0ttG{Y6#' J)0lj9dzzzi}}}'oߞ}$Wt<^y6Dz`y4M͛7~(y~:n4͛7Iۍ7Uj88멪Mu1J%ض J)&q0 qEY*~yBR٨T*8<<(!hZG\׍CnY2(8jBujR{!J%躎v(‡;;;_\UTV+塤!('T0 ~ܪ`n꺎Wǟƀe=σeYT*<]vNy14>'O @"B˗w^~3[yWEFrI(5lْNy0h4h40MaĭjVyZNj/`&88889eYh<G*<ΒYiRT0V$ϟ?I> &''155J4s_~V-&pNSim;cy}流&H)S$Xhf3,ڶ}KV*˲NTn^n9¶mz a " J) Àit:B4 @l6{{{?oooSVc0ukalv=Bٳg>}t@Ha. @@]$RAjN 8H bR"az.[eIENDB`doublecmd-0.8.2/pixmaps/dctheme/40x40/emblems/0000775000175000017500000000000013244011205017772 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/40x40/emblems/emblem-symbolic-link.png0000664000175000017500000000300213063505360024517 0ustar alexxalexxPNG  IHDR((msBIT|d pHYsFFtEXtSoftwarewww.inkscape.org<IDATX͙=lG=, D$$bl,WA].)؆"Pi IEKD&QSҚ dD;Rs "lnM={~̾{ovNJzQlqJf@;жP5 ,p# AW* B eͣ7J|ooZV8 ߒmYkk+0Yxk4J)ЊP q;pp$nOon===f2` BsNGp++Ͽ_9О< WC?|͗ PJ?qVh?aN5kA Efp`G1-1p\3~%9qI*s`m\]bܸ1·\bǎ ;]7"X+~Hj.Pc,333|ysss-PEKX&<-AZkkO&Ey!5cxO~JӀb%>V 4ȒOPQ1Vh-~IQǎs(XPBֈ%G)'9s泦(#/GMXv 'BB)Mo~N> Vd ־f$q-(hPZ8{f*$<.}7 (Zi][0`J$iPf)/)&c,{V[nq{ˇ}ӧ[+Ц5~q *uC@kb]XXH540'N|ʝ;wXYY?ɓ'cm.Wbc(,//׍… j5-J=I)}l$LB-###u]Rؚ?T*qfggS\o,wM^ _ ._km4ݻk$X,rT*š^"౱q\rx,C<~@ Z.^H\@)}if]ٳgr;" 055ųF(bq=XRy0V߬[Tm۶v螩7SŠJ|fYwۣKKKkoo7ƻ 699YZKN6uz[qMLLTw[#{J3}}}7z3eBg&Ob xot1{IENDB`doublecmd-0.8.2/pixmaps/dctheme/40x40/actions/0000775000175000017500000000000013244011205020006 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/40x40/actions/view-sort-descending.png0000664000175000017500000000174513060615027024573 0ustar alexxalexxPNG  IHDR((msBIT|d pHYs$$P$tEXtSoftwarewww.inkscape.org<bIDATXOhU?]%" ?D;DO uLpcFQ,FaX>X}v; hZ]f]$Dd&o!nvytU?;ɎN[UX 󼻀} 6p10{<Ec$9ǠsSlɱ.m}^_k+@ͪzܾJn0neey_c8>[[[;ػމ?<T0EQ4_x<^n빊'&&|cxu9Tkm H™́Z΋-40ģZkgEq < 2LZ=l6^,nZ\>N3FDNԬqZ}xЁ; UZËfn xDUWw"2~(1Nj} L{ZNDn'E&"{{^[7ccc-F (Rn* -)|KIENDB`doublecmd-0.8.2/pixmaps/dctheme/40x40/actions/view-sort-ascending.png0000664000175000017500000000174413060615027024422 0ustar alexxalexxPNG  IHDR((msBIT|d pHYs$$P$tEXtSoftwarewww.inkscape.org<aIDATXKoTqkJ;@ #Bj Dd|'ȁ@*-,AbAD*jċ E, PX <!'vf|s^^!CvDf&U ߫l NNNj?Vz) .// |IU}^UL׫p$y KXѸ("ߦUjR8r"WҭĨ0<< q571ωȴvcܲɅ~d0 jz`|!"A$ XUɽ$maj[38 , Q"yGt=Fz<㥉v#ZL~cD䬵KYĮN$huccE3 WTt6y$P*fq/I\&Bg1FD5kx: SݵKwAp]" \&$I -" .= ~(亮uZ{ώ[ ͵o `Pr?0kw}W.'``WJ{Ç]s8R4۷~;3o.ܕrgEVQ16/Ug~J5+d V;԰ZPCFgh9T3<6wC\E>ng^2iZUG3cdCk^;neMMm}aPHNƲQ" YSA5Oe5,, -O_;W{/ű*s?|k]mOW:z!p/ /xϋˁݛڟ>;ͳ}C'"H$\z 8j(N 9r,לٱeW˻Ϟ{jNE#ji|{֛`,w E&򗙳Hi3h:ESX))C3b/`++`%˪*0T>j=4*UO~μRA91SExAB\s /u7!1`D F(  `~W 0t DpdQ*Aue"#川OkRl%3WS,񕲌+R+ +exgU}ԁ-qpsZXlWj!** LZHYhʑ3;5@} .қ `mAk$M={1&q78Y+bb{M(1Wś4Mh2# rHR R4VR_ Pds5?.|O:L](Q@EpbIEpS)^} yMC9իP5[k^W F@)݋LJ,T†T ԽZO++wA 77;θIENDB`doublecmd-0.8.2/pixmaps/dctheme/40x40/mimetypes/0000775000175000017500000000000013244011205020362 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/40x40/mimetypes/unknown.png0000664000175000017500000000175113060615027022603 0ustar alexxalexxPNG  IHDR((msBIT|d pHYs N Nw#tEXtSoftwarewww.inkscape.org<fIDATXOH?ݢ^ FŨ\6=7xًg#&^ f1x047$)vBx}BdC;噙g|>Um~oضmN7 iS˃- D(o777 j>>>m{D"joNmH)g/7"sQ/peYszw((NmSytB;BGgMCI4 ^__i4t:bxd2I&!LN%rs*Cq^;wwwu"V(Ů:rl6KP@UUױnW Q,1 h4J.UU1 '2i:b 7ɧ0fDz!!Nj9ny3tQeYeYR)yjEЋt:NضM=' m5x{{c{{۱(B677=#@˲HӬql~R'UiFFA&!.\uГj- k!0DJ~vT* `MDD`٤^~*;LPjBȍA h$ |z%P`GUU;6b\.7l`3dyy9LS< Ep&'W* lll2vNk6T*EAJIT=k'+bj~owUU9==Z( Ac[(kPJ L)% Ob4os+y~g]S$)'7)X ?MzyIENDB`doublecmd-0.8.2/pixmaps/dctheme/40x40/mimetypes/application-x-executable.png0000664000175000017500000000460213060615027025771 0ustar alexxalexxPNG  IHDR((msBIT|d pHYs N Nw#tEXtSoftwarewww.inkscape.org<tEXtTitleExecutabletEXtAuthorJakub Steiner/"tEXtSourcehttp://jimmac.musichall.cz/iXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/1IDATXKl37E.iRJlN,MQHaXp/Yh^Eo"9PC!=Sp㤶,˲,K(EKzE23K=Nyɟ5WЩ3v3#?{kbW8>1tSS sŲ6} ݞ3*?+<191!_ P6±4lob[L|a LMg" (!Nba{/B * !PX2; D^'&<֔{jp,(Hd ]c&[ p|b2=3EA j0#HfJHeJ|ܠ5j?d׀A8}ޟ-m@VB@)i*H( J+Tp{Lkj  +EM͎pZBBPC)JP Yc>Lgg2yT^'mQmg=6j Q 8:2~a3!ly `+]ء4,X +*J l3y @gTfߞ8>1x+Hm`t%y#ŲAxa8!'7 J &Nģnm'&^w LQ@2S4@CѶeYA*S,yvk,L`vMj  lQv@tek5\Q, }<(! u/Vhz%p80Վ/JXˏf rW_]ӟ})"U_ fMLLʥmwJvjCƝ͖Q, y*foz!\g=HvpyVP-vu:{@):VwrE˟C;iFwH8ݍ*ơ% Lt=;RA5"$2 ٜY55IB&L5VVZ4Dš0s\b`@̟?nUu@P'%,]mI?0AXk'8/1ҀuޟXV,ψ3&Kٮ (cjQT$J1A#,DXjb^qHTn0>V:4$"2yfu]* W1Df@Dh6'Ns6J_V^o}P+DOh6޵ku]j MSY,C`fP8CQnJj hZ8y$9p=}?z_>/h˖-֢j!I9f``6`P9 hLj0:4ew<{n;tpU8`s@`"'d_T\'F&DSN{|O?/Pnj1Zm޽{ihhh6 "D1^CX@akt="j}bc ^#9$9FDO<3=zЧq… >Ή`#lnz DZzAŹZR4@@l6q;G)kO?tpСa9:88'|.]BFց b`aF .P?8C;K7^SjZŖ[[c?'&&ŷb|^,˾SV?o>bfLNNBDJ"._ P &P\rDD4ܚ=)ܿZ /Qdc̿n O8155M+5TxI98FPDY5^* q &HOU@ @ <ߏ z;73!Pw|Gn YƸŖR e()Dg,CLZ&?R!7V Ws~O?^ϾzÇ1qںu+)*'1f6iwŒk q~ѣ"U\pyυcu=%FUs>Y_cl!'O]UC!2%L]3>n]\+D)r'R <-OY9@eHy.}gt=zj_ܜWvOJ~JyuL&H;m[[Mt:dY8 BTa7 4AP(quvv?D ܹNd|%ߋE 9 17?v'8É+N$qX\hN\A>\PֽޒZ6O"=삊__`{/j5$IRz 8.Zm͡JDS`QT4i>0/,rFv'K9 bgBR ̲l;eT}c%輱ą'x` jhBE"Al{sc"@J&1V <@KMQd oێLLLt rQk^ UF))jo Ck"^Q-)\FC[e0_z޽CCChuh7[XXaBR3wba?Bαj *`0" &041{iKPF:\Թ,ze?.W_۳aurel} 4Zm S  !E\KpB.,޽vZ-DfW.P0``ajj ls+ؿ03cǐ;ET"wA5"wN"y@".4(gzy ̼c][6 N,D9K *P 6$S7+T*77w Nzyw *w1`ddQ}CDdVO\:8,e)CSbETbC$'7288q54}"jՊoՠ YJ0rȽ0 .gWk`սZjQ`*:'TfA¨DfaU,Dit+G%/moa ȜC'B\7 B7@Dl e\Pe &?>*Eh~GƁH1 .Rd9ZEa \!*I}EA :ā_p*,5" è&-1_zfsh(R;0P䠐 1C*',@%eH]Ty WJa"BUQ?:-¼bacXzW:z_Ě0& wL R+k RY!4LKz7زv@;i"c3 4$+TŧPe^]ߗԀy$ߙT"*V "/ aVQl,s f V1ߏZ\۰ؘ>{0{5A^_cyzƱ/mjtPu֯3V"/*H}-dD@BA²g$86;;EYW"f* ƠQm,a_xA*>4=I9WǼuݚ42:F0Ngc_e`x=z>ֹsg<޽ BlXGA44.58Oh) )Hkyn k.\™Ak~_?l5[ Tˆ_{çOpwI}K$pPN'|R :OD}A!Yơ0F1gphO7a{GzP08 {~Wtm|ԩmFyAZrbエv7Is1a J2Ż$7Q B `+1J/_Dsʟ<h,;ް(\5^{عOĺ{ȑJ#ܧOt{yL(a# ![/c /@ O?ԥ{ed937x|||~vn/wKЮx wl}A?Dw>t)UnSܖ8q$f&_|H=ז_zf%|wD }^EN\|,ʵC{OoC1UT*1gϞlj?׬5{/{/OܲQ\k${μ[a_t/>}iph~sweEM%LB@31l0.^:S gNַ~S`l[Z_n\qtcwrĒ~zϞ=;<5k]Ѧ0Q䋔N.ȝ Dx EN+TF30;|ˌ\id߳0y衇nk*W7n6mƚ1<<!/ȆHeÕ+x fg b4g9z跏;v׺Jޱ+Qa(Hׯ__w͚5O>,Q&[P"!K:$-4n,ԁ199#G6b6/.F}|wE&\ڐd7f5{3.P^uҬg|~3"⦏<^|ťb, 4SI$I4bh*BGGGѣG?xoz^7A)a˂j.r; ,K1::{ɷ~\>< G??ztM4mVmr_~%$rח^#eYLMMahh_ۇ{qIpff&vS۶mkBQEVor/} @4E,{ѣ>}zOvmhR!-gݸJAB-aP{,irĉo}[*g?$I7m4nr_. WU.M$̙3P(4}v8z\OO 0!BV'%W_YNi0 f)g&* #۶m` x0 H X6[ZOaږ5-!_]J P(]r, ]mJhCW9e+DŽ)]VaajA]MEQ`<zD`ڊD"\. mDXJ* 岝qE !v#NӫQ@ !Du @$lܸ!NCUU<t:!|u \.:,gbrr---|y^U\f[4Mc||# ertp,?V!ՅAUU j*(!E̠`Hǎ#6m*׬|>otuu[nh\.J)<AaX,"ˡT*}tS,p,RH5^&VpX,Á P @QADQ@KK 9@ ~8w<< fH544،ø;FqT*]VB$M>?Ae$IXbl-oy˲`^P|BVD"E~q1??Ç#"`zzhmmU0Ѐ~WΝ;!9{Xz5dǂx<˅D"V#0`Yttt@u2 ÀCss32 N:EQсz$088Q0 ]u* 0Mb$ĉ`YׯΝ;pI9s8466Ce455d$ٙ%ǃh4`0YmT !DZgx^ 㗿]rQQ.*5 C%vСnذaŤ0:: Q!IeY<8p4MÖ-[ 2d I"8q6$d2K.ٸ^յZiV(X,XE[[!ebb DQJ)By<~0??A<$I"W5a%!H୷Ν;rkA$DQl޼BB X(ą :XW'Ħ&L&cà(4 ~Nr'NK gJ%?~lMMM|`V*$x'Nķoߎt:t:1tbݺu|;eQWWN\. @ p8 066Ia:8Ckk+~?r|lR)2>>QiX$nq$ǏRt:i5#mW(033EQbX 8+V@}}=E$IV1Y188YheNiPL&I 333$CE*"ٹsgggRkn۷oG*.]"bvJ7n܈:!8wUU0  QQ__o7*H50 "Lbjj Dl4M\.C %`zz}}}HRC͡XՑ{q 0fF/|i4Hd2`0hH۱j*z턦( TU%B&TVe [Y(PMDQtR@R!|djj $rLn70EGcc#x<4cr,&c֭JqH4 ` @a*"tNn4DBX\@u@4%T*L&Cs$ Lb<#[e7$NO<`r:(Ilz8eX5H$A ""m:[`@uM܌E`6A$+V sss}{o;c cu˛o~xSooG4$IZ(Y (bvvv:T! 0:;;!" TUE h\.:uJyO>}? r9"ܽgϞ;vY!aQ`0hWt㋞T*IE@EBE8.믿>+pi),,7zܲuM֭wtt{zzX̆BaL&*}χh4 ׋br M077sUرc?PR_+,Us!W4X p6566FEW|>U|d]+k\>s &f5)I),p 1۷GnG5if4MbUz3_7onhj$M@+T4T4#6> RZy0#(SJK> !p#J)k@4 r e3gΐ)ǡX,;s뭷/35bRJeJi4M%N'1MBdG,fd2`tQ[z|>d2$I e]@p85$up9LNNRjjB(v:F,|t:)ժ/|ripݒc=h}}OdY] [1nyM<,ضm7v|_~SSXIENDB`doublecmd-0.8.2/pixmaps/dctheme/64x64/devices/media-floppy.png0000664000175000017500000000475713061015620023117 0ustar alexxalexxPNG  IHDR@@iqsBIT|d pHYsctEXtSoftwarewww.inkscape.org<tEXtTitleMedia Floppyr*tEXtAuthorTuomas KuosmanenӇL#tEXtSourcehttp://www.tango-project.orgɾXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATxZMGgwbo"Y;k+HsB%"Da~PQr 7+\(. ȉPBDGěDήzjvzv ~ՆyK\56/M_}>:K> F[|*O@w&LO)p!U7Bl _={g[Fzw\'Q@ûrѷX4NቛH< TnEe A Q?IɣDOǎ07̀=IVAC_ '&` mq*>R#x4L9D[Th :s"!47nʕ+}lzvL$ 4M&eÞ$MSvqE}~*Px9@PO6jpԊXmJlsq1umHEQ ˲ 7ITQpulr@eS]rKy ɓ1`!Z&)&\Fbʥ_80N`[{0B7B`(dYhG 50EQ 0CEHT1sms98xcݿZ8$ň@0lllgط/WeDQy񪽰KD8}u@@|Ho+.\x :ݍ?XYYxAy@6 ]x+c@T7Gمfa-~Me.or `#|TJQ( 8ǹ>N4p.\[-} ;wzw rIV\ݫV, }Ο?9y…Gcccv[ D)Ų^ÂaJY*ic< @)=}!H䆿3@ PII 9t]9vϋuKH&BUUXAIЯGݠ./_b֭[7AY^ 448?q/Nrz_-ki c޺O !{J|6 C$ ȰhnnF:dt%(7%80 0:>>rػw/ (x(kI 0Ӄp8L!ָ4u{ .mCe¶.~8c $m5#r$ *%ц躎L&JkX1d~~H uAue UFeA|#+m͕{iSJ !BP ?yaa.a9!Px;uO!,} N$Ixa Bq4 D"w>hdN=1LNNmOV5_ EÈF%@QF'KKK0 F|טvjvv'Nn9744 s^U۶A)!`jj}}Wl[ X @.6mI`Y!Τ!;IB!tuuUCF)-ٟ8Nr455'(o?x[sss7 &2g__x< %!i۶^{ hjb&fggjI8SJ(ed'10pULMMaiiD/7d?]xY @~';^gL4M9'd2h {?r㷚TB еkp=_MRiJM);CbBl۶ĕ+W.W(@JÔ,?@ ٳgnkk; /nXҎ84#UU˗133]tO?t/PuJZa|6<:u˲?rggL&Clقp8qA!_\\| 7[xO)rMJ@8p+⎡!200b\^^F)mW_}S==={t-9ءTnS<8_r|J 77~ᇿLLL|8551[j:ߘݜX,jhhFZ݋ Tm?RԿ&''yYhr}V5nIx<EQ$s#f޽;7dcwoi6oNB<~sP DqpdPEA1 ֌q~DDɣx,/^u{<+6Do"IENDB`doublecmd-0.8.2/pixmaps/dctheme/64x64/devices/network-wired.png0000664000175000017500000001046713061015620023325 0ustar alexxalexxPNG  IHDR@@iqsBIT|d pHYsctEXtSoftwarewww.inkscape.org< tEXtTitleNetworkLBtEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATxZ{l[}KEKDQ$K$G,pM=P,uAv5ÀPlE;,Kve]R<s[N}?$ʤx)ɲ1}9sw~\6oh vVLĦ8y^l6 :D"Oi .dr').cW?ր˗/lvF㿞={n9oCfۏn/?bA->(c[ĉUUo߾}Xjuɷ![ǃǏZ,z󭭭arlĉB֓mSxtq:=J:i? :^G0~O׿zeP':M{E0@@nBP N#PUh4đ#G-ɲ|vg[CCCA'!@~sS*o@~r@02BUx @QKLNN̙3y&ܦ(.\58r[WW*2~]'.a, :@ {vyM4(8પ?z7߸T)cae٣?1 ) s@aA,4\WRXnݺ~b1i}VASo_Kp@ (w) (]?iz&(iM 8s '!/^q^#6Bcc#` 4PAI ? O(( . ǎ)<===#@`nևg^?w^~\.0z+ԦP:*۰dY0$i]B!( 8v(+idz@ pt)@OOeٯ8p|p\0 P .`E+YN/eǥ8PBIݍF {UUٷgϞ>oK_4p] ӧO@r h @tAqU D/^(5;g 63X\\Dss3fffV((\>»Fq @ܹs( hnn^X,|jhnv@Q|>HT{ X,J~@׮]+w4kC3,GGG;;;p8VrBD`Z\!z=1<< QаRqN'&'PWWχ˗/jBELLL/~ BY~c4t:(J٫)BTs0p8J%qmv*򥚢( hjjD7n fAB!P/ccc[.zvvVEn?::m۱sNK d2hkk[sPՊz+^Bá3jeֆ7dY à(ƒ_[ NdzzAww7hXKrXs`v">V Vkdv !#@m:)ZkF$j||Ү]Gx^_ImQ,DrV-PV4>T*[khlo 6[&'c6'@E-DdU9,hjjqkNfp`b"4Ɗݤո}6L&V+ަ\` &nll <40^VUSF8kN`0r!" f:B^Tj)X,xE;,Ǫ ۍ;v@R=;; EQ\!%׹~:R$(B0D.E}}=dYF,6?AN:fk W@Ya 0W8;2::ZÁbEJdjCr9 `vv(Bxp L>FGGFW( O ]Zv !3bq𰭵. ,kf||X ;wH8<;(DP`x Ύvײje5d2d2x7ftuui&LRpFp:`Y 8<+#  ajj|:bhׯ_7&3__&)+XKU {p8N4n7(J3!o|EjG4,.."" LB`0Y>x96#z_ʭ`-!(QI$r:xܓ>4Mc׮]08~0 0X,0};.]a=HZ.?&  ]miigp)B" à7oD*t:ݲFFpK=NOݥgF?ReuyY}H$n p8LjP(T t:ttta\rpB>4=4M߱lAss3%GlFPk֪Wړ>(p `{zz`+섪B<)]O$g M{XVϚ % 0ͨ3p8Y\T+_y7n6j%^ޞ0 h3ڵ ---+B"lFgg'DQ L&yʕ_-Kxk,]08;!jhqFթVRWg,K7V PaCė!j3bl( t4yիJqg#dr1cnKl6&aX@P48OVVNP"lc6L4Y7QIENDB`doublecmd-0.8.2/pixmaps/dctheme/64x64/devices/media-flash.png0000664000175000017500000000705013061015620022670 0ustar alexxalexxPNG  IHDR@@iqsBIT|d pHYsctEXtSoftwarewww.inkscape.org<tEXtTitleGeneric Flash Media%ztEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/ IDATxۏ\]?UuNg칬u]6Kqbc/"!W"P A"H@_@( <^vvl3{_N9=3=-:SonU]f3o}BAʪ8s] 8w\mtP_;2RxQ"BdU]~;@B[':4b/=DD |0s|{wkPQrlllc$Id ok~s+._nݕcĪv4lVk)F mnk I@9&'⛯>3W^ܕݰ80~1=Ŝ:'81911q 1~|{g^rwu/=d~w9S3B5uI.T#*LMdeGssa*՟q]c@ӻKhzDjkwpɗۨ*69I}=lY^Ia<͟"!%*Lݯ_avqQV1f羰^vRQU~%^24~b{.eb{g+Dvlevk7zt1Mu4' kOtUn aZ}p%u\i[jQ` (웾rN2pd Xh:nedv7 #ݼIjPpn\8+IdUe}=\,+3&":I >$Э: c SG" A06)D4>%Ņ4o#"!u}/J&7U i">}N@JA=!(!d>hPin莀j="2!|hB |Hhi "B[>[*lk i ibrSVL>6l@BHFP[ XXLXA[\`;Z_MfUH}B?ח>CB i,`EBˬ( 8X dCX"ҌFPg'뤵lY%ɂlHhґw1`L dbzwy Y@QeiQ4QT`h +H'Ny5Tq6PX&+zQsĥϑ d:Ez(] vJ"4\c}^4*}zHFJҬU8!rW(') s08 SFIQ^ XmM#e-@w&$S4jZ ت4ͪ>C 8&W rvMRffDdd9We БO ՖJ7 #WnMAMZs fIm,9٤.z(pKBP({TYe)PИJ.r,ahiϘYKma4 sS5PEA |FCn63(qkE1f  N51T+_'hn+ @!r"3ޢP:ߡi ߢP>1P(N ]EbJg|W<&oal1|Օamqlj\Y}! sGw?04~uҵGf:iu ToS߸I:@Z{D}m_q6͛D@͒ lk{$wyʛ,pfu)&q3`wk]4[u s7צrlNךMwho3tr~|8^ OB1ut[s1<ﰇk-h c kK-(Q0JV u|f-6DZk}vIcg `vqhѹtn?]eu{^ ;g\re-os?r]llw*^:.ѓrwo库鷌x |Bf_]` PZ8' >) 9yH=[o}=JFql|re~qyh܃=񼰱0QXۨz~D]mي/?&n-[TU]`8[zO^ヨ >,߽_c`-7h#g`8cS.$xGρ<l7$@92b^iVd+ 6gvPtdJ{o2?X8i)IENDB`doublecmd-0.8.2/pixmaps/dctheme/64x64/devices/drive-removable-media-usb.png0000664000175000017500000000715713061021161025452 0ustar alexxalexxPNG  IHDR@@iqsBIT|d pHYsbb8ztEXtSoftwarewww.inkscape.org< IDATx[ˏyUUgf类Dqd, AJDK`+p$!|.`ه9 ?!@KtI@Æ-@%H~E E")J$;ÙgwPSU3!R@~UW_W_)%,H^{~˲q w5f1g\޲ʝB.?HPBB& /ܻ+s O]f_%#ڝ_G{>*_D`$I! j|B Asq<.8O e L@xtR\tX*p =]U!)19gddτPq 0H\u2f3T"QLP*8|VI Qض}WF`ynYDI RURJ) |c:M$@}c5jZG) IxJe^uN&S|7d]uu8M a(S5B,q°P7>\}3F$18O@)]{Us& h+O@e1RKWj{5֔ Swq$!A4@LC/y~$WdvϫaȶTu7?̵/c2Ⱥ(%s煼"*2 (P6P}_c{ m0]x@]9|eeB`v:.s\7 ajO#p] $Eµ/qdɄHb9Tl@ѣ#xThBΡ;%h!B2 !}8זض I0Pg6h~{Q`=a߈:O"x4۔R8͑W'AuQ@zqc_KKuGhL!HVL|rz^TEW`a:h`ڠQz[lmzCZ5W{N뱿qFDN? w3`Tun_g}HyI_LDHƶ-4MlZ 5# + ̫v@@]m%cB>`A 7DB1zm<ab0 4ncU N\yo~_|_W:'c kHRg^""dDZ ;94RFbi#8G[}GϠjFf'朴¢jT*FJ@ V*݋dB-M{WA1N">n~Hu-@ P:G5s84u]O60NCWś_' `\&-4_wEDdieẮspp-;ٳM۶f% ukio#ÿg@>Y\Ӕs,C5d2/8H,Ogg du('ɓ@NɎe$򌅰L|eY&padz%0e9rEdB\1^obNjpZvֹW6UHo[0wX s@`[LYzB, }\^1O-|RJ̗Wƨ@VfPX>sN w_vi:^ֵǕ_z)9Dtl6 >TZfo^h-|:Z+ϰ=-?>|7Hɸj5\ò!0IrR xQ`q5O +Bˉ(TȅdeˠylX|^Z7,W6CA75 VsǕH{pilF@F zw5DXZ-Oŭ Gy[&8p:\Į#io o`z)$NQr8x;0;~orU- 7ao 8O#,Ѵ~2T֝er9klkkK XnKWXfI)PI_$v%6wX;NV^뾪 ^ql({%UlrC1ZT S+hTpywCA 4kP%}֭}혉(mQ޲wx}<7oj)Νꫨt%(, ~rTeFDJ)\5|p?>g>AlEm pn]AD٭+#xn9F#mUrXq'@8;d`hzw駟K$I,.Mwx pJ,+/?Fsnf0]l@iUvN !O\ =L hWbn=TB 2_!1% 3(C"*jc/+w. yҚzzIENDB`doublecmd-0.8.2/pixmaps/dctheme/64x64/devices/drive-removable-media.png0000664000175000017500000000446013061015620024660 0ustar alexxalexxPNG  IHDR@@iqsBIT|d pHYsctEXtSoftwarewww.inkscape.org<tEXtTitleDrive - Removable(tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATxZOI}67a KIL8 (=Y;Y)vsιml.a/QH%R6&N0i`Ӹm fꫮ FmFmFA1uB 4\pᧅڈb,cDZ1.@]0ƪm׬L_G)}1P(/_{#|򀹹9Nbvv6055J)TU5%xoK)5Y]ky籵2BSN y@P8.puӧH4J^Q111+Wp,׈7oիW׺Urbc&!!$I IW899l6>8nJ齖 @){{{?JldYƵkopݾ}"Hؒ?7;=q2ži$]0DH$(#iuu<#1}ΏaeeŖQg`xݻ]޽{7n`ggۖ䏚~qi:uT*|1x|pzmTUիWM'S`N$p?ג(HR J4ܴ&/_Mْ?v6$AA)oZϝ;ljUv|+޽{Ba$یw(ڲ%]:ӰX<ϟ&D#NRQpg -`MMMrY`3"Ȳ\.p8 uIv,@eqk||lďU;i~i04T* _&X`uu߿7pt5cNp2k5R)`ddϞ=϶p7?66FѣGpҐL&!"c$ŤVw` ,,,p`ssWA2 A@0(s&X[P(6?YEug뺚W ˲ܬ?힌1 ۷XZZ_xk$DQDXDOO)ifaFLl񠷷KKK{7WKhԠـ FNk̮(!V^ .aڧQ/-].DQ tkJRB(uP;E "Td2GfPM]q с3g8vN\ˬ̉7jSK>r:S9H4K\-aVxȎz+YѨi7T+x<~dEM#} vMht숷"Z ׫E|[^u986(w.]u{`!MS˲hJivM?/o B4MCE]$KKK Zp BE`4j <.*+ɒ@l3"|y{;k' ŋ[.__|Yx~%MV]~椪ʤpcq @^dz>C4yRn$Vwf֪zU͆F]1$sƍZ-U$I0 "̾w/B*ua瞃84[#@)sΝ4M% y=oef**rfi a|20 '%r_mt:}{(fY@^:<>]rFQW^y.+L@ժ3^YYAH@7ѰmܳA L Tm0˲)6ɓ'PJi4ܜ82ƄgwG9yePg |Q]Q.h14ū v!Y]]cg@t:0 J"'?t8xʻ 8r ?< h:_B^z%JCuT*(+r~yP*P@)m(BT/ (a /`bbG|?T.eazz>JT摠hGSTdO@Achov[ E<ɡp||4fggAkvvZZ<8qBgt099zo,-}lmmP|@ 2+וe\TEqqROD|PP9£R.xUBȏ#Fѥ)n_bLv\Ie( yJ8z010TfyEEQJ{C.',=. CAso ;qf/$1Bơdsm7A=BH_8s\Qr@ L&c%I4v$d>D`ass=؊| \^_'I4M!@j4í3gΠhT}σ6dj5V!c8ƺjUcy֮ y{7MA>TE3^GuϘy//򟇸wRLk-JoF,ͭ߿'?%S~l6PJmƘ 1F!꺞A🯾avUoIrS6>3 <:Cp{StI.͠}WSz0e,c[ ޿COЎIENDB`doublecmd-0.8.2/pixmaps/dctheme/64x64/actions/0000775000175000017500000000000013244011205020022 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/64x64/actions/view-sort-descending.png0000664000175000017500000000253013060616051024576 0ustar alexxalexxPNG  IHDR@@iqsBIT|d pHYs;;̶tEXtSoftwarewww.inkscape.org<IDATx_Tu?ggB % $ & @HwseffZ f(A%Jaʇ^ %)q)Bdv {?o;ȘHҎ`lTlxu|ND'M[VO_[ss$df69ù\L--Q |a;TdD:) "l,s[{P(,ǙٖtME0U]s֘ nXz{{/DoMk"5&''oJkNoe}|~=VYўBahk@m'kԂ? L' ‹i(T9ps.߀5) J嘈 ϰ W*Xր͛7NrmWd^9wsnmU=*"[k٪GÌ ^ xT*~܈mZumLHr =᜛H#meBn`fYlW#!B. /8007Zu@U1}RDװmGmlK*OcfYOOO5U"ggӶb‚c{߄d Y`Lr;NuʞLdX]گ #؞깁\z13 [ +XFC#Wȗ[1I3k{w<݂zO)@/} zFt҅LM?EQl2$@MPpn_F$Q8b9Pt4 r WZc3a'"ƵըډO>H7B+ &Z;^ `oACӌom怆&,a Zfjݣ11ϰ1c0e aͭ[PZR*.woX^wi/F:@X\TzMFhzZ]rNJp Ɣ9z:vҹnO@BC 9Fw1,VY~ahvnU@L/jKY YO;/,('WALN)pj!s< >Ʀ yM`/BLF6G1-#h Eч% :0w1֭+SEA$/B*@ӹ1o+C5 ';}.Jĺ&!b FⅰO;eZkWn.uhz|mvnjeXZvmO}娮 x8|Ñ.-H6!!!a"4=ѵRuU/[=e ֨kjy`Zr2[73fQ\XgZ br n?FԹnCJצz0mA~`/<`x. gftHB'-((c&oZfODεo2xr}W0ma,tLAhwH1A5^z@hl \lߎJ{(KA5h9n)jGDL1Ä|;Bs&O s;}l=EZub: Kfq nN܃0p/5ҾƐĐ01 '@L}|I͎{P%7#dld: QwWvG Ha҉ aaE;D ѷCB*Ӆ eC/ya<wZ;+ܑ̾~]9.f |#/*$U.ۉc4 @VB6?O/UH'U =RZjD-o%4TL|5 aT3Iڏt@4핥?[خ;!sUUqskhiD>>*i'oWvRewwz"w 3&K6I+ fv%]W ĉy)'k")C$e {=g2t9OX ƅ#i%5 ߹n$@2! ֢8 mn&_ xR%8p-c(b#d!pCf#){{/!(j~x &)>A0Ps@|V$L{\gc 䥐IDATxZmK2]vח5{Lʒ J$Dࡿ'>`eAB lWM?r{}9K^8\ٙ01P?Ida^>|0h=fN3;#q0^^o6F&/On#@$FC< A=)@jn)@_Bx*tôPrJ(\.<A@$iZ-y |||Ցe,^P(8qϼZ0V@R9$IeY}=J Mʗ(V\F;N$IlnnUQqwwRl6qvvSаvf3 loo`Lt ( .// j$I%[]]E8hgccooo*3$I* ,s;8lmm7iiVu^wD&I:Xv0RX B!aj.XӅ0 +2 PzL&l<<<|>O"ByhiDP rFF I\ >>>ZdKKKHRG7(2U~qDrp*\v{ymm 8~-HQP.8z` ?Y` DQo&,O D"a SRVVVvuA} (2-..ZEúx |zۧ~, Yv8DQ, cTh 1-t:qpp`Ao +A@} meYakmSBX,v`v#J! BH$fYt]_UձdY$IEc vƂn0}ʱX͙t^:::BT(8 `yyْW-[@OpX,a^ح} m*;Oy tvf@9]+,/GY?mG87=5%ƂO}}GGE=lzaHŤ3g/3^z?c3O.Ju~qݹ~q 9{3s^~yH#&X 9{q…WNN8p&WqwًgA 9]J±0=s21pijҁU<$<-̯G2LV+9׎c!@W^&۷"kӷ+ܾ-Yo75л3r릣DsWD d RK'2Fғ_%~xhzfm [D0دBӴ@{Bgnv`vY-0[ع.XU(yg`D(B#7a`Ёg$Tizf-qx/h2oXjVJ@Z ʀ1Z( ;Jl v/䨦𨼻 FAeC|4B##Zg(clAsD~ ٷLfӹ^:O'C4DQpwX"I"#d*1`z [19&@eج撱UU7ǚ+ >A+qF! ~~ه/抪_ -b Ng0^3g [pcAD|>_M%>']͹Z-M[nAQUH @WGӎ76uυt&WJ `tuP0ؓ(?:|"U g.$[mD`i%}YJtqŏUg01Bh¨-,hmip8+ 4`.~,O >?JTƗ-技&?9>{ɢ,zc3TPc`Q*P:37//]z aqՇD*]9WӅ !4P,fM 6Lt "el3C_s^6b5U"vɬʲ Xҗnc5|_ XD0"ƒA @ cǨde>ϳ UVk|b'7~ftv7]0X|8:ڛ E$:ښ`vX$+wCUP;vYB+$ϫP?DOLaf(Zv5QT鏃Oe%%)Xhi@O~ċgfH(|eȒ>P/~JX\"w$#ϊX-dl}4W:?Ĭ"R d9Cv)8ig4CσH㻂j dCIv6VK0nZkt؛`Le Nsfn46X c97CQ!BhK[t-AI~O$u穭8!EYL7!q*ܾ!>;snd2"@X\@8*A1ɉ^p֯*ju/B2>$IF,VxZ(+W\Ϝ9\8фm( y @"IȒ Yei49 DQMΌFuu\2Pd\ 1^3> |~˙3gp]EU#,Z bLKP-Yڽ=--,1DD )="B"y9QB$/>twHgƄ\Vֶp&Sib3n=-hm/ !7 rxn$Q>}PlaC a,LgDdL\"o e1 \%D h@D@9 i1V;,=RrE;ֆ#)tu6plnZQ ABzt.Xb$+T}m0"ol5C"|V GPT"A̤6[}!` zZa6s Vr'Hhv sYm6444ofT Ўx | FB{+1!-4Y,46 NS6wf5hJax,ҙ*w]?9^)Ec}}=yߧd2(#ùtZ?c839 M0 m~ȶ9IJhmm/EiX"Q񸱱L&o \6u2j}.`k&$"|79L2$KY]څr9H4T* {[CPȏ[F:æ?l:uOkM$J+jrk0r9._yoPJL82;?rjZ@$Y,)fslcXh MۉK7njZM|%2 U$.]Eo`JȎ[L w㸝HՌD"wnAܞ_oty* {.&_3,wÞ GJȎLJnl*$Lz. vvZG7n#G.z?|@r`EQ}㎤Z(G`ob)}>A8l/琌+㕀 j$E@%Tw%CQ.]pJ|"YNo]s^};m/ƪT7Ĭ]W=#'x!;To#@el8q|9ģwz/JY[oTr{)]#'x!;@4vsˈE6wwFR岧ޮXj:sĦ>M }pgdDc&ryޯJە<@үղvY*UUo!o߹dxVeóZ{ײMs=~>RK,K,K/A*޼+< Nm'׭lQB{2_b oʒ7y'LlN~ڹvuaz54g ?`n)q+ShۼwRѦW_sB@^a._Dmޢ?~{O`uXɘX`$>L`"xo;|}>" wVԔb0x!h٧X/ng;_vɩ25) mUdD`l۱?|{ |9hm4HL@f۹iW.n>'BU:wGO_`0ֆKjqx0=j7je}937[u8_G H6j@-uاth`Zk l)FvgjMȀ|e([ɮL* )?i`ߐ6t a ۀLiQ> %lZ+G͏N ɋ8 ^WZEBgAY rS RQTIQ 9 8WJ{u02PFh:,w5c3Ӻ: (ݕӀpß ŠoS!e8 Ekl*[O@U\uck$-V}3-b},^GC'IԌ TSVʖ%> "X`{{2Kx3`ݞHW>jL9AFǩlBA7F3vfN9K]Bd3Y%C~ԟO R8}  }Qj}%O" ˲R_}f 苈XK'yv;jwˋ: c=0eԪXGBLNngGhkg6ulY!KtB4\^IENDB`doublecmd-0.8.2/pixmaps/dctheme/8x8/0000775000175000017500000000000013244011205016216 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/8x8/emblems/0000775000175000017500000000000013244011205017642 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/8x8/emblems/emblem-symbolic-link.png0000664000175000017500000000046011312762055024375 0ustar alexxalexxPNG  IHDRsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT1 `@f ^pfíQ $5B h}m[ 7gכ^<8mx$[j:Mx:7(Ԣ(=iHy~ "Lmј,K" P׆`X1eY!"iEmmuo bBIENDB`doublecmd-0.8.2/pixmaps/dctheme/8x8/emblems/emblem-unreadable.png0000664000175000017500000000050411362134553023723 0ustar alexxalexxPNG  IHDRsBIT|dIDAT?Haww_wD'bAPKKm5HVnH{. AE[k JkJ; G5L6[ЕRoF+ O*Г=fLlSLJ<:mz 6^X7AzA2%J9Wi㕯P0wMν8LiF"‚_-vry>ޢyǝ2Е AӦv0. !}~?M?~ŝIENDB`doublecmd-0.8.2/pixmaps/dctheme/96x96/0000775000175000017500000000000013244011205016374 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/96x96/actions/0000775000175000017500000000000013244011205020034 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/96x96/actions/view-sort-descending.png0000664000175000017500000000403313060735370024616 0ustar alexxalexxPNG  IHDR``w8sBIT|d pHYsXXm7tEXtSoftwarewww.inkscape.org<IDATxeǿJS,"µZd V۝wΆl C~F5HJ6ƴA,i*%`$Ĥ$MLӫQ={;3s}g{{Fh4Fh4fXF H)#t!:aG 1Zd c̨TV)m_'E}0==gLӼ;x7Rܹs?~vD{~~oisCz}L礔7Jjw@V,=&@.; c솵y!!Li~{YYA%~ض}%GCuY'Q&&& <l|G>t|%1l3#.=HD!%<Ɵ.=$;. aKϻ-b7 [cKOo.9(.=>( `揙3!Lu @I!ėV`"MLL\ )f9!Dh\PL-95!P)AVQ 1TDh2F 19G-@h2F 1Zd c-@$q:[Z"?NDW/̧U"sl_Шn nPpsv3qDxeY ` j:9S7MKDIuOkB1x޲kwA: 3}DtRئE1Y@Dg WA/%o[T seR*^V4jusTzͲ[QV `t&Xqz>jnhX5": gƉjcqquPV7q=mYE>+ov7Ž'8>[ƻ;>y^h⮂6&LD90>6Aq_FH>03[R{ #1!ި>$LD h`@[!-u{VĿT:I)$LR!L!)Q}Tz>քcL!LaqOe-]Tѭkkkۈh liZW^!D}LƒZ,;g^GDv43^Rm;1-BȲq=*׉Uvܹɶ}+++!i87<`2fKm$O۶?lƯ\vtǎm׉A^p UCJ |3s'T̼ fG7FFF5?Q^ض=̾5}y, `saj<{:_D<  / /f]׽:c3MpOBv~t7:2|Rʻ JpP\e7^KNfVڙ )H!~@۷ z+W`Wc333V.H\DP_^:U*m^+. g򮴓Ci^a]_ZZZZ%py?IF:!~{'  `0 `0J3oOU"A"Z`\ ?"r'YuO~v>Z~l6w/,,GR\CDL)8=\=)qND6jc) yBDI1Cju4E@WacD*xM8n !<[KLyC uL8ED pY/=@"z=b} dwkkY*8}4amĆD}*}^ڑ#GZ%ӧ%I\#"DimۖplѣG MMMjM4R`Pؾh4خ1}{8tX+KjtOh4AyXdzK )BǏM)+XGs~]1~"95D73~d$a5r<6ɶqm"Gc83?`g)ͱߩ#Pg¡Jr}T ~+bO=@J~6Z֦Xӝ5R!BшˉWe߅BE{\e4-6Z֦zOn"-|R!D3 zO?+¤k`WgTm"o@)#FN~@Ln3Zxwln&{,ǘr]6zw^Y|Rw#VJݝhd,,,,V,tpK"R,y0.ݔvbdJD&/uaG"̼I`ww7\>A|׆%:ͽfYuhurE8"LR߹و̒G:r#y?$i,*D vj;̍~2'BߒBD<ϻW_ZmBp'h]`۶s$iE 瓻' `PҎ!`0FbV&Y ]'```$tԕ"r@lRy''ZcYYkd.|Mͽu0JOHUSz#]"r8?SzHZOAǰ3zlajJ*$-[6')=-@| [ce05'-3֔h+Jx1/,3ou"^iN cnE #1 `0 `0 } "NIENDB`doublecmd-0.8.2/pixmaps/dctheme/96x96/actions/go-up.png0000664000175000017500000001162313060735370021610 0ustar alexxalexxPNG  IHDR``w8sBIT|d pHYsetEXtSoftwarewww.inkscape.org< tEXtTitleGo Up.CtEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/HIDATxkp}=H|,ml4 dbSi C۔$-3@鴙|h~hIg$4m3! 6m!ɖdٖu=}~ۻ{Αu?brj>QFeQFeQFeQ/bnlGڭ7e{o^3lhn.Rkx_ ve1X][G*]uKܼY*uf$u5jy`m"?:͛7q(gݏPS]O-3ta0 >i_,u[g=OkH,[?͚UI@}'in PSsեm̰=@WCHѾd@Q|#[5ZYm]OKZlB ^ZZIchU,[ǖ+9[dMUi)u%+@ǓغJxK,<c(NvE35khSZ_n+}ci 4VS*-H*8y N_xFJ uPs~(O;-PuU5(+08v#Qp%xMԯ@zv w5wX/v>ΔXrtJ.e˲x`#ma,u7zN^u7DHg'I X{% 3ta0Ӽ+񟽝pj ,)oF&-b{G&ydr) z-CvälXu6\FF/Ucu*Ēʫ@صkl}]`}89@"VI]ud26gY7QXju /[?̝& '0Pw  uSl-ױq%lLKC_~DY%`#$U;7qm't2#{?ѓ]BͲ54oBk}ms5ۥJa\-ľ +r%#'9q"?=118zګYu|ۛ:䭾N}4OFIh? D_UQg}u 'ygUhԟF̟JmGORJ튵^]''{fOsԿX,N`x<"#Cw=FcVQ:Clͳ49apMuf#|eWj`1xE'|a>r=Y;[/M ;O!6  R-wP%_bn\f}D3{#d8xy${x NLy'oS ^ܸ!nVu# "@ߊoX'a89] 0dyR((D-=.,V(|v]<ݸ_t Z5u'X:&>q+gǰptUluШ+Av}uЈ%hl@>*T֭d14}]|s,@h`}?`ƏSY;#djCy9Xf(R8AO@@ȩ '^D^W@%Ⱦtڃ̣m+ZEֽhm@'Q#Ԩ L>\!xPh_,3*ENqxÃtMPZ}M7g~|q$u_>fH5;ڸC?c89[gݎFw3-#'I2*^##B= *Ñ;!ǿ+ȵ-݇Yqza`Q`lm.f21~[@# cO`c#8K NPtFje珩X3pطZ\M(Q!GL BhN[U]Źrs`Kq"f/zMќ1 M?6=6ۥ~6`tW-yxAZ\EڞtƩ W.f ;?4){9jc/a!$N4S Zۜ5GOk9s `OK.uj:wO\ ,mzӽ91 lss*}P 0>G*7ny$}- w;y_7h^?(butef؍QD?'|AcEJẙqc{JU!es=&%&KKęug YcvN[T]nUh >xh8̱w  pc zU%dhvzgg\+ˆA&LƑX(?|d 4~ޑVbE(ΑNr@@r0l (ܗWQf l8P>ȏ3cV4G&vp?eY%h%7[7wFA^~0b*-cY #f#@! 3kiOdX`Ey1mtVaism3CSh 3yS1g$L.'Cr:WfJ `PT2dxXH0-{$yyiTbZa!N_ޟJsqGȶ(م_b2avLE`OrRL9a0Qt0nQky@t>WX7,χG9Eg o}>t!;&`\lgvu8\7/^ !\|>O;z'Wv˲H>&9voI(Эj~P;#7bB8u&B0)4PWp*0z6 MNhH?S.cB p 24=hp"0{L<&.1.<&c@@q'z-h躎cZ-Z-~FH&$ T td_+n˗/GC"@<G,c dX3ׯuHR?e$0ZPnN@1bw:TU('O NWiiD^G6͕$ $4M~b=,#躎W^AQ,--]{ !,Ceq@CFw$AP)*={H] l*2 cC,--aqqhB@ACVC) Ya޼yϟuk.۷4mס( ,:| ,vvvF^ CW? ;ã#pί> H˲n˲,$ lll\q4Mxn!IҵmdY[&JeuǏzxqK'qqdrlE8sbcld,@^G.ݯc4Mӵ8tH$FBn}Ӈ۩~8z!X]]TᧅYz}famm DbjB1)>}1uqߺZCr|>q|%l?"޽{5i3wYi|.!\.n"P/T*Y饿UԠRՒ۳["pQ؄/~&1"~X$1`V,ݗ }n{cׂ)`ss4 $s|O>uKQ* 2(84M2޽{7T%S-Ex1#j0򹋋Ǐ63caa낖Q=15S; *ƍeT*̼ ͦh4|>?CPM@)ސ%(eB˲*4MCӁ렔Beb1(,E @9z0F> <& ;S=-e 12K ?3wkCg:#N%nP*V*lrAsʔRʓB)t]s.}l),* fS0I8g4M! e*v-SVa yX,֫Vpm}HP,Rcq!DnY; =CHHHHHHꕶ+IENDB`doublecmd-0.8.2/pixmaps/dctheme/96x96/mimetypes/application-x-executable.png0000664000175000017500000001520713060735370026026 0ustar alexxalexxPNG  IHDR``w8sBIT|d pHYsetEXtSoftwarewww.inkscape.org<tEXtTitleExecutabletEXtAuthorJakub Steiner/"tEXtSourcehttp://jimmac.musichall.cz/iXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/6IDATxilgo)HIe8sAsbgsC$^$";رIŮ@>&OAHL<3ovYIoRId}]]W>TwCꪷ?V=G#{dl/;_^}U^M؇~uiz3??ڋ݁=xw/0;+ώkc:ߠ ZA v_y ( [ą3pEY gG ~wv70 ^~o;C8u>c瘙Z@1CCB@@(ǜ9+W<,ƙ^R.?4$< oq _>R/YxhHx _q n.Y\]tzDg9do7D}^ XJJgƸE|TE|]AEg+Cw1^|'/? `*aַ!@jÃ}>c<{qbO~5ӗh4?][*cG8C߇@psܘ[Ϝbjz$A"~߾c,UGX_a[IP(LߊHS#|D{TUÿcN0KgxŧG.=8$<=Z8B$6H6I*0/[}MyJځ0l0 v$OB2?UMgr!|/<0$O뜮sklrvfm6<Kkqi8I4`j!Sy_djzp\K" 0?;~ݡ]TUG׍:0skCGy~ɩK!c:|N _^R8niَNdRG?ԝ^G+VKs$ ܽ>T/IvKmP[[-'Ԏuw 7S''Klw0:2ܘ_%)Pa\^k3th,FBQ6WB_ S|^p$댜4sk2^ɉh%lƳ7(Vi38!iSx$Lc%Ö{v?Qrb|h#%#R^I(.X;L,ܳH8v N@-:Z,Dd^$}n.Uɐ,dԶ#ib7>y_}k0 y^aĠ l1&.]a71W~~p4[{BaIF|uw''SA6_\QzmbI +*eY_"'f) &GAW91iL̇J6vY~΍ةA4M'-6T?N20 h*_; Wt&d󥶽ٔJJ $vu)EGkN/}Ss6VWUSvrCyw9 p$P]nC~Ե1շ'<'8&;]}K:tº8h+\Vܾl a3#l%Ju\ tq??Gz ^P{#'vv;1,/!G9;:7}ap7R/~Dr$U {UU %yrbKVgGL@ !H ڪ(rSqbi/g7Up\* v3xX2&І .pd?.au"@Q4y#Il/] 3 `o+ %U-%wzw#Iݒ~/Kkqtݨzt?TK֢'Ē:M'9؞Hhy [{Nr6, 0 YZ@ xp|j4~ 7~M> ;IBB!ӋJreoҢv9r]hrY7wsϞ'?>|ӠNٱIMHhjr1cxs]?/FU+W#eY[rȨ9^Ѷ`}D6H."qN ˪%O(3k{`)\),~ rxu|.IJ%Ձt7&3?p'9,:Ýٝf7+,#t>gN%[>>~NGeV߻M8W]X_]K!r7|' n)A++]?Pt\ rA(3ؕ8@uj kIt"Ia&Qñsnp,DS܍$+!9G\ :O>0| ELxu핏>=պ쿅ETt2ppkȺyp\B,,m%-bj>B*SPٌ8"aq Uՙ5grMj?O.D\JE>?%Zừq0ƋJd0z($-'oˑ,+Ư/K$IU#F:lELҶs)$\-23^%ޗaImoSNl[eȹۍ,@zrEe#vv9,RHB6"l`r1Go_cB PG5*Znth,C8.%AT!fF??D(w$|8\B{hް ̑&H=6NEVZeu#Et+ZLDoWpw׀JL/3w;f,K6W#I P*+$Ӆ v86TMAu70 ZHԢ9r$BH䲹=_۞ҫ]~/ td HB|c= 35ca[ !)R-Oa34sQ9}ai_C_]%I(|MykN(eқlܝ0t^VKXYV(*J eY%MwoU[-lfrﲕH-sύV>U ("=}x$]^aYSuFP*+$>7NΝ`nU?={A`\+VS5\]%1e' U$C~Ngʋ$I&Z##6)V!!s*HK3d3 @Ng(|8炬rd;S(rfCB["'ѭ+| a͚ [?MeH>Y $R. ͵fخckU( :F˳2 !h3' r`@G^{`˧[Ydt]8^_$QU]-pwy_R C\' \R;]ܹnFFEQIgG3$Rz{q&+k&^Mk+K'C*JO(c5!$aSQ5w7 HjWR|$|8W"AUf۹ܬ%n!'c.nvDp}0V=?LS*C~Ga WT]W9P;N}lF45sKuϏ% p^s#CAQdz ijkg>itΏ%R |G 7PQBR*{dV i A@7ْ$l]KKwL%$6{ >$>.$ }GH$فoz?҉#oI X0lewnO&͹x➃HYC;GueW"Mwtǻcqr93#!{thyS0 nO˦ &7ė|!a 0Gڶ%?87z0 LG.oBjc AA./ ULϏƒKe ØVvڏR.>4; 8R2IR3O2?L޾}=A:C~3ZGEʦܚ$31ވ%(K1,> "9NzJD%#[бsOcL(A&G`CBg#" b:V >Yi }Aӹ^ߧ23<4v0+˄BA2-zBQ U(d"tTDWW^=x%~ 2YN 3kw|3?g8@Hwo߉[d[.bt`P@ ʲB ͻlPGu 0 >%ۢRXߌS?^]Ͱ;ow޹n _Qݻo u2rʏ7犥]dR[x}>{ixbI~$ ]~B"0{읹_Hd~3ooFؽߺ {!9 MƗ?{bNr$R>f`7sڧ$q0&ʠܭ_q'C$t3dh$8ۺVhlCc $tQ(d5޾>ᗘA2Cٻll4m~q͕,Ao[ nd+ ѭ;=4<6ҙBDoOb\H Mה:zJ%7gWY߈ioU=Y[w*Sݼ. B.rb)Oc\`Kw&$W MSn7p=|?`p$*6<<6V#\"M20pc7g~?7gVWnN|drnAxXZ^ hJH CxNEzQ Tx^ ]@x<:ܞT4e7BND6!h6_HoN;r;gHgtwK̍e:sv&[^V޿\tMc#zCC!`D_~[zDN"Zhop܁R>m[׫ܫSHtM>WO"|OG]X&cR.r{R ¡yKzY,֦"`f?zWat [;C{^^UI(=@"fā{kh0/fO_QRV"8D$ dܧ5c1 \9{/Cx FsjmbJ0 𛅦!ppk~uu|1|F)e/l@?IY/po {aF&'%[f|^2QJ[_}j]ۋ9~/5~+_+RS"\AXeS+A߇|(GO2- 7F;η(i=gk9/3z?k ,bX8Y`Z|73ANTLAu.A>mEIAHE=z5ꩌ$%'":lj"l  jrôhXI鯄!vOb)5Oq-RE!߆Sd\{ .rEhJIt jӈ8EAWJ6W%}9(KxAon֌ Bc;'ih4Wm)SUqnK 6c7oDk i\P(M>.x(Ԍ^յU2)ΧHnMY$t/pXṶ\ @jg;%;L+bJ@f`:9 lY- e`рz]N`#Y{U[G=#b B ``۲Fźq%n$ܪ`cCdu>G G`X"#က#G zUA `:- DK,I@@d}!26>}5IVэGdcoB6:F_p\- N |XcZ :,;p<Ȱ,7^}V H1@xokӳwE 솠]mZx! Ce. % &0!c)pv|ظiٻ!i|gIENDB`doublecmd-0.8.2/pixmaps/dctheme/48x48/0000775000175000017500000000000013244011205016366 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/48x48/devices/0000775000175000017500000000000013244011205020010 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/48x48/devices/media-optical.png0000664000175000017500000001024213061015620023227 0ustar alexxalexxPNG  IHDR00WsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<tEXtTitleMedia CD-ROM$4[tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/PIDAThk]uk}}86mpp#M7D(V*RU)j&TUVTURҪQERB+@&@H"x<;saƃ_s=s^k:V?j)pp fvNU%0z= >زya1T`8CLQ 1!ǹj׮^>IO/iVuSV۽sN;8U8 ( hwJPpN8BbQt,/dX# .!LB`k9i}K_.Il~oeYGUUVRUGU !D2bPMi !8B0"Y1V|0(XlzUBme^@ժEqǮ](u;TUS9(2Pb 2 XAB^wxe )! !e,/w)ya!J(#AW_ 5?uQ";vH*΅զ̩[c9C]D]$ϕHA:,v,-7q1BQ,g뗕5cE fjs]|P*؄4Tb(JL8{-MX|l;}W_{v_Cr 22FRR#F366g{fy֭[WJTS#F)K@P"j{\y-cq~~ӿ>9ZV86>Tk ]D "RGM5Q+ccw ÍF*\jƠĐ'5bc&I>D6B=Y{5ub(#h E2TVmZf @1˲fXsP=h8u!5 +ej^\{=S?a%X$c"Y0D߫ G!(*5Ȧ բ4H(1z3BYo(f?|E[F(1B)I2B&"UӚs 9cUJ^8' 28:K9a4,-yxuej]+pjhU6 O~f#y*Z}USE2Gy|y]AK"EgP eWj/ߺm۷Jd.PJ")7cii$G۝+heH㠨juE\FwRnh[6p cc#e<>YYYwI 1sϋn_۹c'QE:Dx1<4LBDI/r{gszGnhZwڽn||sg<$ &J<J\ F3 G}{u~e0.m 2Waڝ.c3s 23؞H[7ׄQ,Ksq Qz4IjQ2QInۣ.HxɲZ"8[J9`A}цt{]6n }ϝ(;,T& 4jm}Ls@R6SE")j^>zODbᣟ羻EBEQ?l.mR.*w T(<*F\5GG5̧fJQj%r^y%Ӳwyݨ?t{SSkyJmH+eP0Kn'DdĊiGD2ky!E%#LLı{:yd wmP^I[ֹ+cSSwh櫍$+y[*AhE"R#*WE#5e/ǿO+li5 5vȑ./ݻWkzEDJWiIՊV#e5&'y#?Tz}k$[#{l|ܹs<22l޼MO"e*1 NW`(e񾆙˯_}+Nfu.*KK/4=szF'''FxR*ж&Q0HLj24[b>cffbx!rVrt:P,,,MV;+uFDB9Ygxӓ''7>/eYv:)}]xR,dM6 u]wyk mظgϺ˷ocdthz2`$ZY{e̝aԬMM>?H$lgg'jF(J)$R e)!dYd2)L~߄'|fX,y~ ` ,|;!0똛[H$owy:>ٴi?b1j̛,9w"c%'|W^y |G n۶pi8<;@UU%W^=svܹL&Wlٲec W1x<:wءK˟ɓ'X̭B}DH,>_uh]ס:(u, ?˞ѣGGWXwc`d{Ԙ`]>R?qܟn?up\T@bI?u .~7m^_ iI!kZ+5M$Ivg/N-iZiUK ۯMV/zpRRjbeY3nOYSӴ_ RJBVkyMRj<;/xɨeh-# ˲%\.G|>x?Fr~J%veB#͂|R,HRfYuʲ,fffFQTP*r:]h4Xt\,f1SCX].V+;͆ueZ-0 ccZVBl6QT( :::PVq9Ks lbh|Xr%N:vtww Br<ϛ$8AAՂ(Pf! "LHRB jމ%QADQDDVh4ߏ@\FV!,˂8,D,n?nkn/lR2 Eqyk׮hk>t:z<c!̙3?8ABPT ]⋼ /bpparrv|z(bݺuD"p8h6( H&(fNS3gtNE^P(`nnp:zek׮EVC2Ċ+i>3[o_ lذ333PU7oƕ+WfQ,Q( ":::BV^ M1RfiLAt:7oB$dY ǃ@ UU188'N^",s!EQ4ɥR),|ÈD"p\fjZly(Z"J-kz`#n7:::Q*PTP.( 0B Hȑ#ضmN< ߏ7oZ$&[QL&q y|PUB6E\65k@)E.3c(P p͆^ȲlVFӉh4={N###$ 64VyB4$ \r`͈Fx"Ξ=kN8ew}D"H&&PPj<&J!Jabpp<89a !";Fׯ_. ? 7>>ܲe 133ۍl6 J)6oތ.n cvvtAv°!eY(h4Ʋ"zzz111Ӊ@ |>5k֠cccV3>[,W_}ebA2D(B.3S_(BWWmMP6ća쳿pz7;4 =<<a\Ev!" ۑN177g;F[Nχ>SdYHf OC)8|{} @@u~۷o400EhF^/ BHRXXX0ł> bڵ(J&jlp88uT/ؿ_03>Zo*MՒ{pҧQx/:9<#z y^6)p`6cヌ"KT)_] A+3, &ɷqڜ3E (Г1 eゔ#8%xŏ+jKm-t Q%3"Ϋ8)d%TLqZ&NJ(!*Ѕ u%DRFK$?x\$FBẄٺf$ 5faBfD" 1Q M"SzHhAPRs'MIHhI:@道¦GhĔ]*@u*!0CU+)7pR%0HUh [@Jh.$STg-ROzzzq WNcmu###˵$@J竮h5 xu>{iAPJi0t:-<i޽4b lǽ À(طo.W m܉'v8fONM###r';#a݈D"dk]tmǎcPU5uYm۰, "!Wu ض͹sS tRH#]188BoQv~J`pp>7a#T_0 $ twwR$N |)2t]UAkcǎe#rI_6堫Yb={  ]:|St:-B_6j ʁ6̍D-a8>|Xyci²@A?ƕyk]q!ض ~vA rz\LDWWg*FEKK 4MmuyrdFb8HJ) B?z l---hnn6|kTn&`Y,b@ٝ0 κY\+m#mmm>rieFt3FoǗ/_bzzM_Vk?P i 8\gie䪪$Ii>]˲ىH$bΥ( xRDŽ@ xɲ EQ(KI!1lll!VVVF}Vp麎Qd2wP(X,V!XXXʊ-AdYFkk+!hnn(loAׇMp\U##C4w0on(FFC2ƨקcUUFs;#t]qhCCCX[[swthkk۷oA)un|9SJq677^9!0/;Q! 1::^/aB "!($ [Ӿ[P(`/!PJ亱W ۶m^*x333f$ iR QA)!<ϣP(cd2>P;,ːeuA/8&&& |X1 ðL!TӴ<~xŋعs'cE"<|d<ϻy}(0 EdYEEaH{0pDLMM1ߦ4M{9`ؓ'OPJ{&&&&V?~1wuDQ4 RWGA8y"={O۷䶖a&$a &K5O)_8}漏 m8azzSSS?ܹs珳+TFh*<` `)9۶577gWWW755D" hؖ^)yl=bu ]d=qT?'Q|8/7i``T*]SSӱ#Gv$IPU={3Zql2fgg٫W~޽{K+],zfEvm=)qHd2ٳ\joobM$$AP,: 2 6665Fz_}փ#<ٶeɌ1J)(yL&gffR9'"a3෠)NYf |C+*l6,l#@cg ; !uۇ~ThUWhljڨJG: ѦhMc'[lǎqbV<ңc]{<omfl6HBfmS?X,Cb[[n[W6b :yp%?4*AjrAZE&''o \VUO|pС>?ڶJiU3~ȵAE+W[o!Ν;;qDKyH]P @㎝*̈́؈G}[liEkkt%*a5>մ*c^#A p36<#`Y}ffݝםNg^9 BXm=Ṗ(^A@UUd2h4U E n鎎]ctƾ2Dwww;0H$hjjE(,A@6-h4C=DE5;;kp8ƜNg퇻:Z-A2 ZZZ@Hy*,d=Zd_vhH&EVT \x]e<?~'Oj,,,G2RI\>1ȲL&OFt)f2sss?lTCCr\p8\.I|ǐe ]"N#Nrꩥ%5`~^}iZ[[ $(0::bMU/e03dSmmWCPz{bRI|B4M*Wy###p:+ Qp8 AhQ`<Ҳ}rzc(^f{3 QW-xEQؾ};$Ǐ1Feq8BOZZczzVR't*&<k{{{jqFi4Mt.\|Vkh4FLVkhhh~nd2H$reN߿4MߚQhZرx}b?xƃ?fsNa9pW-0ͲVmFѣG;\a"]r >8innnGaD"hmmE(Dvŷq3Ȃ sssWrFm ˲ a4"Mɩ9unJ!֚I&I>5ol6vcddD/烷+R~Q`YV!Ba(JEFFK!Ԓv+"{>~6Ws]]]=-Ay/K~NJnhJ)i.CJp$"ÏY$yRN>}:Z*fpP{i*y,UxF' CUՐ,3gd(Zef۲`HE~Xľ!T( B[Z(;EWPzN@*A(X++hk3Y|]vv7LnIENDB`doublecmd-0.8.2/pixmaps/dctheme/48x48/devices/media-flash.png0000664000175000017500000000463213061015620022677 0ustar alexxalexxPNG  IHDR00WsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<tEXtTitleGeneric Flash Media%ztEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/AIDAThՙo\W?n$,-tWuqТVTB*< qz;W|^Ө#i^ZZo (~]Ck-Zk1h`s$cHk  #dcxt&w6d1y$H S h'p51(%xp$ n{y [pNpj?&YźZ`< JuB-d#oY&R <BOes (g߲ Np :ƴPJ3a(x>x*| P c."8&1XSQW5 ƻ weQ>ii\gD+)e Cd{8'蕟"GHohTJP8)jUQ4A?ڃo#*LTI%a[@y?O05Pπ!!>ƘnUD)>"|/pO^˅aByyk{g (QTchPj}DB֘>nP0*% V>$"_(nƓ4=D$:dT0t%I4v/DH*ߡ.A * ! (7M&ߧ{6'vx]:ޞi0 T6 e ln+:r~6 p0 fm?ì.ݏťUj&wpR%2i@e}r*;ʔ*LL$̕)m'*ēQB aT!_''Ja0w|Jqb~[ q 帀$@L쭷ݨ\kQ7ufd]~4qېѾl%1껍F-[ n%zϣkcgbjHcFBrnt +nnF׏hSƪQj̍`#߷葲B86 ܆VbwN |E9o>ub]#r+M)fͱ| >{e|~F]ÓX]r4Q@ l^(mGx41U|曇hCƨ(=X:31ӹ{BexoHyXeM@!PmZ{PԀ:"NCv/t)fv)IMѹR +!UAFB:kZTRxQv>57R))FcZ@H:kZ:|o߳oa0-X)5[f^ע@IN{"`\9P8'ry:-4$+Fiցe`h@'vED"oF/WeII4M,!MDIENDB`doublecmd-0.8.2/pixmaps/dctheme/48x48/devices/drive-removable-media-usb.png0000664000175000017500000000513413061021161025447 0ustar alexxalexxPNG  IHDR00WsBIT|d pHYsmhtEXtSoftwarewww.inkscape.org< IDATh՚[U}wgwY@ l11HQ$P@"E EK^)oIMPB 'ج/wgo]y.#VU?uԩ "x/b9H"@%T/mR v5UcR_ TBݗ^gϞ]-v+FGqDZ[}փ{SQJKdl e<^; R ("kSXgvgVZ$BJR|B p}ea0 Abf - ºJgwBjPEjE˲R&$@)eYhºᐕw(Z!텈OOO/V҅v=+iѲ iub@]dH R ♈w:Y*-΀,i+VY^JIEضSvշ"uqh_fy(! >@wQ뺹Enn]y$OaVwZJgL^&>}  ȃϱ{o[bK϶m @Q1Foy׀VEQZx-u ԓ/0:kXǟߏgPB|P$BzݫSJatrrySehD^w(΂?DLvA@O}9FVcgg ѣG~2י\Np$`<K/% 籽M. IvӶL55?Fn!ڇ;$ihY>mfLܦ YSSSgS^p lf4?ATK/>XlۡcҜ =HT# w*^ fggDžn;Wu/ŵTeDn?Xu:\Fjh4 IYd[2Gܾ||BEfph4Jlv1d xx, ^GE~@gw 7*rX$aYaEw='G<z~$w.w4Kd^9\:a\($ |xz*ufR3pUg)%J<ӧێc[P}-&??y4gPIIH亮u&FuرY m`0#M"A*;#M+>].AN8qb… }}˲)!KEaUEZͮK4??̴ Yn8vڨ(/bTtf5&urv!9 \Y@ w|NXnπL4IoQK ܹsZ0#}Y JvX)[wb<]| K9u}N6񳯵ENNݻ><})sßW_G@eK{YVU@8 ^[[[h4ó<:)$uؽ`_uN=$oğ׀={ ` lcNz&lMZ4 ^^tw/}j)XIENDB`doublecmd-0.8.2/pixmaps/dctheme/48x48/devices/drive-removable-media.png0000664000175000017500000000325413061015620024664 0ustar alexxalexxPNG  IHDR00WsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<tEXtTitleDrive - Removable(tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/UIDAThYKkWHiFE0v%C)!*pɣ6)5klbmfen+xm M?HYDPvE[F](jcJRs{E]t{ ZYYR!d@9__޽W'7nuԱif?^lr5Rܹsg-?O5KP?߿EQ,1~ׯt ۷o /k333tL}0չp{d2ϟM(d* ޼y<6a~X]]eKjgԶ0:: &J:nK% D"L&ő d24q( qm+2<&&&WLrmqq\RW;Ef{{d@(DQdC-NNk+˨VHӟkv7J|RtyىճgZfBDQL$oA˗/] N,Ù3gXB(W2L0y3AP(H$@ -'ObggQC;ӊJIJRLf‘(_;wnDUUeGǥuE l؍jvx٬yd,mcjq7u$[mBeK ˲T*f?@7NjRjSNp8욼~86.Cm%0Ͳvb1 HD` Ea:ݞsR-V4^CUU B3:?ڽbu$ 9 3sUUQJ¬j;},k;իWX__M9?vbggg,XŬ\OO_>X_+!J =>'xEQl99+!EQQ'(B8 4M :f*fQbc~~VMEh MMDe|xŋǛmh󽟓Vs @V{{4JHPZ(f!EO(OsMuј4JJ?HhA@]j޾k->w4V)#Ch?4zA|T4zr3=2kvWzu7p*r*S 9IFQ,R`TTvwwg\mSBLKk0'OL0FB}ѥc {Ywq> 7t:k'Y8u֥/ÇB@gqܽ{~_u>#!AZ[جS<4f~R߉Ϝ9! #/!0 UǍ#%pa&666gޯ1( i16MRULTC, \m4cF, s Clll&@i޸qCOE0 X(sO0PIN@,RmAsh|ubzƕ+WVK|ߏс!hy/7tY&mlBWc}67?g;;; tʲH"ny:4N<03@[Uy'E$VW# C /T*o&[[[sAJi].my7s*BȃM 0bV׉.ɾYׁKi`ayy~{{B&z~i~~<<ϋY3]"d(.i uevMJ)I0w1=Selß|s˱ȕqUBD$@!k\U!mXhԭ#.2R "08Vz}s,zZ\.hmX,*$#QntĐR ya# ~̂^033H~ZxL3 BR b8`auubqh#p޽bxwyyb@9z(r͛$=. ضrgς?1|V x=nv.<cLE $NV겲Nt]\|Y];VqI#\(m|ߗ>!Eɇ$ 6iEtW@FNZȒ+ 0,[TEQ,7<܏A$9Qz:9%5 .\P)c I: i{xxX @=w\,.F:Mea fL#2.2<`#),@=/lr~Rj0;;7oqu}W DP=ӧO[1 |CrLrlgwg!+xw Fϟ?/V |}*0Hp38`0?e~D#>֕T7qtNd!!S<D8<S9S.=IENDB`doublecmd-0.8.2/pixmaps/dctheme/48x48/emblems/0000775000175000017500000000000013244011205020012 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/48x48/emblems/emblem-symbolic-link.png0000664000175000017500000000264013063505360024546 0ustar alexxalexxPNG  IHDR00` sBITO pHYs11(RtEXtSoftwarewww.inkscape.org<PLTEnnnⴴ===_a^bc_bcadec   ! !! !"!""!##"$$#$$$$%$%%$%&$&&%&'&''''(&'('(('()'))()*(**)*+*++*++++,*,,+,-+-.,..-./-/0.01/11/1202222313423434534545635646757857868868888968979:8:;8:;9;<9;<:<<;<=:<=;=>;>><>?<>?=????@=?@>@A>@A?AB?AC@BC@BDACDADEBDFBEFCEFDEGDFGDFHDFHEGHEHIFIJGJJJJKGJLHKLHKLIKLKLMILNJMNKNPLOPLOQMPQMQRNQSORSORTPSTPSUQTUQTVRUWSVWSVWVVXTWYUXYUYZWY[VZZZZ\W[[Y[]Y\]Y\][\^Y]^[]_[^`[`b]`b^ac_bbabd_cccnnnooorrr}~}+_(tRNS  3VWkpq=PIDATxֽkQ{٘"_Al@,A;;k[ A() ٙw9d~$ۈmq};ü)d; '`tj=H0ʞh0Ft)ZY/eV,sE/eY=5v٣YBP.MbQ#s]"IdXAb{I[ꄉ :a';5<c|hI4Sw { MљSLǫ=Z@ Wq7Xó6%FvBr V-A Yzwbv`Dд|HƠD ,0ioThv#ŠGd 8 #t^&NՃo_p@ m6K)M~?,v}^X@5)7խyV r\>1f+;M#"*¦lD !!*%y ·1eq9adـ| H>Br^*;sC`wwREPU%'e=ǑdѼ8Dc# `///'+:f: IENDB`doublecmd-0.8.2/pixmaps/dctheme/48x48/actions/0000775000175000017500000000000013244011205020026 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/48x48/actions/view-sort-descending.png0000664000175000017500000000215213104132411024572 0ustar alexxalexxPNG  IHDR00WsBIT|d pHYs,K,K=tEXtSoftwarewww.inkscape.org<IDAThOhU?7J=H@KFDP J9fMz*xыz[-BЃE XMmAD30Lv71~N~{0`D:ֶ1s~,:JRQJN<: j=J(BꜮh63I_\\ Ҹy^Nr[:@V{ZI҉4B'b҉4bp(et\}x+e@VcMotb2w fvk6xzyTlYhqg`@orӕJeL)5-"G{~OkO"l6gvDm23nQ)uZ0FK<}"HOo@DfYk11ZrZ{8.(֞.r}n9x.2=aBa8k1T 0 k"z݅XO/p%zDGH'X'zZ?DcAƘ˕JeB)5Af_0}r֘ hkF7h]/3q r3/"WǙ}R:'jzTDL.ȉ J93ZV 72hૄ$5kD^_9%$"o' M.,,܊ Z6n^NMMYD[RoAƦ!&HFqADJ4rEh4.t:w^a "$;֏ĸLk+r(E~Q0 \w%;MOO?)Z窘ߕRd wq#U t@$r?&{9<#"s:pZic,`9$]Ƙs5`_e8I\sIENDB`doublecmd-0.8.2/pixmaps/dctheme/48x48/actions/view-sort-ascending.png0000664000175000017500000000214313104132411024422 0ustar alexxalexxPNG  IHDR00WsBIT|d pHYs,K,K=tEXtSoftwarewww.inkscape.org<IDAThOhU?oKz6Vml-&"S55ugd( ED"#YyDQf9yޒ+($yH:qaiZk?q+w(~WJONҕxZ)x^͕7=PayP3a߯7,!WI?u`,^a<nu||*NO8^:zez ^RJ=^V+ a8-"wwtt50777$ɧ@)i@Tz8ik ǀW;{t8 axPD:?{t8dI,G;"_^< =c*? 1b/0l`HIENDB`doublecmd-0.8.2/pixmaps/dctheme/48x48/actions/go-up.png0000664000175000017500000000544312561345244021607 0ustar alexxalexxPNG  IHDR00WsBIT|d pHYs||BtEXtSoftwarewww.inkscape.org< tEXtTitleGo Up.CtEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/ IDAThXilT}y5!$,F6!a N$D"4%G&]Ҵ!HUtShUu!*,JPD*%1,k=c=qrg2^1jsujuq۲kq=ZCD/Tce7?pYnmOJVƊChc*ڏ*%?]8Q5wt"'\B('6ϟ[3gƹFyœ[O6Tѥ|f 3n-ߴz[i)d4,U,(r᪰xQMɺ"/KE Ef fF2;X+k6#Dϕ]s[t6:Wbk&>`=A^ܽ)cz ǹY`H\-Xp3]CWvTˇ7%1j.鎷3 .fhj.K$Ro ŋ=|qWug:E23 ZDr#w1{hZI٪<0I-4,5{?@P=k}`ft.%X0oy!Fe #)XVyYkޭ߳>7$` R]PjjN8̠aMǖ~Zw9=:`hYO~[i\ He$@ I#$ X!sk XQeRgOΊ?#d3vįxqی 4]n@IAB*<>9AYqAD꜁T6d/,܆D:JW{vU˿@t\3C/|XZg\2X(K: ei֬.as)g6r妁WR9ՋR@gQt(mϗO =*ubaK68!.4ҟgZH1? '@D5 ֋ tz]V׶c \; OMnTX#K;vF<ۇ= ;tTŪ@ c-szq2w4:GUe5{M~GEEf l5И &nl u"sP0(Xe\XZ=~/tƟe=*̸dzƗ/ 9\bV[r$KD3HdV qp HbAx߯D h7@h2S6 KH!0^g0dɟ;-tEHFp68.p!YEZf\0˧?Վ ‹,PQ30#DG0d!D!t5=OxJG,͒ |F!!ac vI}WA HEBI%Rv AfU\PަueY`Lo$t6,}+ɍ*W})pUID^@6! ~u=Q5I"H9h ,$t /pyһ[x[y@KkkIKW; v`2+9xe JH$;bew,B!s H6qZ_ gs+6/A.T<=(t`NIS{ 1g/p3Z&/f88]HEc#onkP[PK:/"qGz$"'TNJѷ|{{a'BP-^xGHu%N;.xƺ?hҏsdv@PeIENDB`doublecmd-0.8.2/pixmaps/dctheme/48x48/mimetypes/0000775000175000017500000000000013244011205020402 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/48x48/mimetypes/unknown.png0000664000175000017500000000275212561351202022622 0ustar alexxalexxPNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<gIDAThnFK.?Hd#6`đC"r ¯w և(};A\K`J[ hY$] AR֥?`gvfg$ANvH)!߄>~I+$]xUrDJ y0DB~zѳ42 uS B$89A5ܸqCUS{/O< &M.aۈe 9>eVu]{sss>EB4h0P(t۶SUW޵x!C4MӘeY5J?/_!yqVqJ)! #/DpΉi)Ƌ/~d@^Lܔ؈9 0nnn~?̀,4-(BUU{P )D|^upA1ϟ>}D\߬H)㕧4-|&O e0 ض]8>>L Ee|A@J R 10ƈ8{!r߿~ X,^Ν;ms(  85mV+ccgg(mr1 y[,//ÇPUP *d"2K̹ 󰾾˲h4@JTUy8::ϟaYj6ױ!)!"$1"&* Jh`~~0ʔeױR0Ơ(J~^l'6` jx客j+ UGfn !͛8dEA1^˟)"YEP0ưEQqt:8<<[{AO큼]TU躎UR8d,Dȵ`6jZjY3 i7쵤aD ]Z^ddY{n{`T'8RF04GԲP‡:VVV`>5dB&AGn.o.2jZ}v|\V7v: S z~R7oΦaqq1uJ%D_c*n20}b9gHb*{ CQLA,MVRׁhk Uד<8i6_rΆ t|N1?WZ|IENDB`doublecmd-0.8.2/pixmaps/dctheme/48x48/mimetypes/application-x-executable.png0000664000175000017500000000574213060730354026020 0ustar alexxalexxPNG  IHDR00WsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<tEXtTitleExecutabletEXtAuthorJakub Steiner/"tEXtSourcehttp://jimmac.musichall.cz/iXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/ IDAThYYlTs=6oIl*iTݤVYpD8MT+ԧJmꧨ/}V UjR4,)0mlfسsۇx c0/mts~/mz'KG>TIz;:|lw^z&sO$v{=Չ 7zovoω|ג{`Oڶ;:/7 N7G8ݱK%Ξ]m{b't#χ{ܹ3Ɔ K ZEmy(&&ry~L<towl*Ob C5膁lNF"+wK~,O1/v|{GySq$R+(<𬢖R˲C(|7`uk[dyw[-lt|Aҵ ŐLrK.ŀ!ey|xzc LӲ+ͻ5r| 3I73( .;/{;6[iW_!;[8Pˬo&N_ ayc-5{z<@kbȦӒgҳWV -twCc4#r*]@`"L^BKdke֕h]!Xg(V_MbSぉh"%@ ! Q(X҄DYd2EēydRy6!O"?:!HLo!JI-[OɅ\JBcv64QTd0X,/kṯn5˱DM-0;r1,1T>%`ش\w Y9ap>n9ln5`@I9W1-$IIQՇTw+rNln~xwʕZ#++!) .ΛHn"KJrE|0:lpd4tp*7{LBbXxa>.y]U IW5MNJ|>9Qu p(rt;yTQr6j4ʁjD~}+M0 V44BQux4pg\ FnŬ5 Ո D8c1T|:D# 'ԡ{/&UW5Qfخ=x&jrɧ WCS7/W.kU@^]$lʤIMӮ3q_(#Jܺxu]h.@"yaiB`a72Ȭie]sdj*֫,u+IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/0000775000175000017500000000000013244011205016342 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/20x20/apps/0000775000175000017500000000000013244011205017305 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/20x20/emblems/0000775000175000017500000000000013244011205017766 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/20x20/emblems/emblem-symbolic-link.png0000664000175000017500000000140413063505360024517 0ustar alexxalexxPNG  IHDR sBIT|d pHYsQAtEXtSoftwarewww.inkscape.org<IDAT8MKTQ5#.7B\>~@ E9em/Or.D]d2ܹ~)/\އpGM'pf/CVffff= XXXx}svsWZi  Xm0Мm777> /\Cҭ(2Q!a51JkR(PJa{e +Zc W:q2C_9DuN @LgOsjqp𛩩h @k-ZkI޽˫ikk;-JH)t?PI )%BHvwXYְ9dU !)LOLk:=hR&N5NG %+B&FAb!P.HJ3:!R~p}uuFFG+FC!}),.~6RP(0: Nǩ:6(U[sJq,Z8B)w#Eι^dX[[r\i–u<6Rmr?8oomm\;==8??~_//ro5IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/0000775000175000017500000000000013244011205020002 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/20x20/actions/view-sort-descending.png0000664000175000017500000000047213060755414024570 0ustar alexxalexxPNG  IHDR bKGD pHYs B(xtIME  IDAT8ݓ=0 + 8G2u0!5w`)`ҕtIQDq>6뢹]KSI, E&*r+=c)Dѐ(J@m?DV,3nv+!bPXS 6X,yHvH?rF2GGNP O\'WtF^rqSn;oN}3'IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/document-open.png0000664000175000017500000000205213110272020023260 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<PLTEVXTWYUVXTWYUY[WZ\X_a]UUUzzzyyy[\X[[[xxx[^ZUUUsss[]Ynnn]_[jjj[]Yeee[\Y___7g[[[4eVVV4fQQQ5fLLL5fHHH5gIII6fHHH6gEJQ5e2eVXTUWSŰܜн柠зWYUٳ@l8h7h6f5f5f4e꒵ەܹ祥6f똹ݕܸ7g雺ݚݖ܏ڋر䛛Ꮂي؅׃ց~yw{ӕۙ9hۂ}ԅ~UVK~;x-tRNS ٞG.dWbKGDH pHYs B(xtIMEJ$rIDATc` 021s8t y&fV6|AA;{sG' pu:{xzzyBuCBBBC!Q11>>qAĤ䔔ԴtiLFj&deA,XP. -7 E%0PZT,:eJ}RCcSsKk[{GGg*XP < jL<jґ)A*YQAjx%tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2008-01-03T20:08:19+03:00nqtEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/edit-cut.png0000664000175000017500000000174213110272020022226 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<PLTEЏ/,JE    ##   !! ## ''"" Ъóɋٶ˵ߚ扉óJ_jtRNSH՗}?9}3\}]\}zw3\C bKGDH pHYs  tIME *n`YIDATc` 021(VdA6vN ̓$ț #$(+, '&$(_ )%]X$#l\qBʼe*ʨRSDsVUu6BZz}$!C#cS3 K+kC#;TӋۇ׏* g`OHLMfgdƓ.1#=!%tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2005-10-29T02:42:25+04:00AIENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/edit-copy.png0000664000175000017500000000117113110272020022401 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<PLTEǚ򏐋ÌԘqtRNSOS}ЫP̣$ʩbKGDH pHYs  tIME  )IDATӕY0(X&mv_6L9\ cT*by%"Ol4k9RcK_6B!ue떄Axmq0&ZO,wYgJ)_c [gX^x@<*/vk}%tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2005-10-27T00:10:15+04:00G=IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/document-new.png0000664000175000017500000000126013110272020023110 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<PLTE6 F( < " " C$ ]6|rjiMj:hjNgkng@qrcFE𚖖w[tRNSEa 7\P%v9c(bKGDH pHYs  tIME ",sIDATc` 0C3 DP\ ddX9 J*j\PA/L$&o  ! [XZY Ab66v 0'AĜ1Q!B...H`u@AWTA^WdA$ J FJPY%tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2005-10-08T22:34:44+04:00#TMIENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/help-about.png0000664000175000017500000000213213110277137022560 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<PLTE J J J J J J,T,T J J[z\{a~]|-U-UÔ#L!K"K$Nà!K-U/Wck"Ldq&O.U˦1X#L#M"L%Oe;`YxGiModXx Jl8`kKn2[YzFmCj'P-V4\:bKrMs6\%O4];cmTzV|l8^*S3[BiZ^`uj/X8`@gQvbcgj歼3\  B*L’|Ջ#0&IOmȑNXDdDQl>!KWl ͧ5ƭ ?}q'C1ImHerRh3uzdX6;@[(9xLdskx;Kev0@];`P0`xD8 FFEGDDGEBS 5>-=*J@/!((I vi1 *zTXtCommentM+-άJMQL㲅..dM#c$du̼"+}}^niqfrFbN^rWrQjb ̒ TwOrt*~ %tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2005-11-10T16:59:32+03:00U=IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/document-save.png0000664000175000017500000000200613110272020023254 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<bPLTElwMy8g8g8g=iJqXxzBpbѱhCnjZknpk8gfqsbpuJmAtDxQNj}npkkqnnⒷT}rukwyʏ=kXĘqsؕ˿ߒ;k?l֟Щҹê˨Ѩ1 tRNS|~o^~]/DbKGDH pHYs  tIME ; IDATc` 021 s rrq# KHJIɃ XPAQIYEUHM]CSIIIK,o dhdlbjfnCkic wrtrrrvrus zyz 9:;{ xjuA~>v0@];`P0`hiED# @ &LNH+ @TPP4r 8zTXtCommentM+-άJMQL㲅..dM#c$du̼"+}}^niqfrFbN^rWrQjb ̒ TwOrt*~ %tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2005-11-10T16:59:32+03:00U=IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/edit-select-all.png0000664000175000017500000000110613110272020023452 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<uPLTE֩תثڭۮtRNS5bKGDHtIME9r6IDATӕa aE/RO7y3aB e~æK~H5%tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2006-02-21T16:57:07+03:005HptEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/application-exit.png0000664000175000017500000000226713110303146023771 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<LPLTE[]Ymnkږ _a]UWSVXT\^Zdebhifhjgegcyyynnneee]]]YYY}uuulllddd```~~~hhhג>>vvvpppeeQQӢ<cs_p%K- Xjoظi~mwܵ{' "!8((DJ]\y%tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2007-01-17T22:08:59+03:00UtEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/edit-find-replace.png0000664000175000017500000000152713110272020023765 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<APLTEnpmstpȧmokYUYԧȊ꛹ِ˅썱ؗФꢿ߀Yˆлܔϭqёֻ榾ؗҬjљѕWϪiVȟdWjp[9«UʇLB&kW6}{ꉋJtRNSA\3DTbKGDH pHYs  tIME 8!IDATc` 0 11 1 1 KIJIIed*jBZZJPA]=}C#!c-mSm=fVBZ6PA;{!G'!gc6'T Nw-mO/Dԍ[IKK? 0H;8 *  ׎97ZK+&V;.>!1.JrJjbZzd?LP ̬LAN+#W*%tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2006-01-09T20:56:19+03:00>+IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/document-properties.png0000664000175000017500000000106513110272020024516 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<PLTEiiiXXXiifjjjYYYbbblllwwwȵ୭#{tRNSVChbKGDH pHYs  tIME  &.[IDATӕI0 @2 k $H9R7'˒4cb)@iri- AEhlKD$$j)uP6ҦF*|N CebZ?_o< =%tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2005-11-04T13:24:38+03:00cIENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/edit-paste.png0000664000175000017500000000140413110272020022542 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<PLTE\\\__^lDmDlDkCjBmDlCjBjBoFjBjBnFnElCkCkClCkCjB\\\lDkD\\[$~>pmd^^^|}~~{nld|@#ƈ'qod໻nmdŇ'fhdgid†(Ň&벴˹ֹ¾pmc#};sodjlh|={"LtRNSd]d]bKGDH pHYs  tIME  V-IDATc` 02#BEBRJZFFZJR "!+'Q-]=^>!M@`.HVf6vhN.hnH@A'/o4A_?``PppYG삡a %;f& z%tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2005-10-14T04:32:10+04:00H IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/edit-find.png0000664000175000017500000000133313110272020022347 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<PLTEstpmokˁЀщuvslnjlnjՁȦҢԨըȊҿꜺِˣ쎲آХ頾֥Éг͟ё߲֯㠺֗Ӊ~{܋πљУ5ZtRNSЫ\1؉PTbKGDH pHYs  tIME  :LXIDATӕ0u+;PVJ>WH' 2M(HA @0]F!O$Si01KdsBd"(WziPllw`h6"8LgNfH>r.[ܯ+w܏ѣ(< 5WD=%tEXtdate:create2017-05-21T13:59:09+03:00q n%tEXtdate:modify2005-11-16T13:03:58+03:00$:IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/go-jump.png0000664000175000017500000000164313110302615022072 0ustar alexxalexxPNG  IHDRW?gAMA a cHRMz&u0`:pQ<hPLTE:s:s:s:t:t:s:s;sY$@x :t:s;u>vN:t:sL>v>wg/;t:s:tu>v :sAy :s:sF|:s:s:s:sSl_zDJsSwt.g:sbtsz!hBqL\lkx(KjfdhYm`] _cpY W V lwDloRPOnV~OXNVUTQ_~b0A [I)iY@9yJPpHh*LPMHh؆GDFE5@mLl\|6LPASRA ^ZzFfVvNN.YyH22.*.(.21BYIq9ZXXZZuF)( Vc$ҒT%tEXtdate:create2017-05-21T15:11:31+03:00_A%tEXtdate:modify2006-03-22T23:03:38+03:00 * tEXtSoftwarewww.inkscape.org<IENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/actions/go-up.png0000664000175000017500000000167313060755414021563 0ustar alexxalexxPNG  IHDR sBIT|d pHYs''MTtEXtSoftwarewww.inkscape.org< tEXtTitleGo Up.CtEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/pIDAT8͓KHTQ;w=4Ĭ,"BjզU"h>hD hQHAD1y|_=7}pp? 㶜h۰5zH^3T# Cޚ佉6uZ]_մ-ysb?]rTEe( d$*Ũ!}37R#R:9㞾cWjE# c >Ѹj[pwm>oI@$<0VvVzS`ibۺ_s:D"Ą tam[U!36H~w4wV3͵Yyo2vL'!KQwƍPs```J5~ȱgנ bWT[FYJ땞9 &_xUņcElfq o* OНqAQ"VQUƀrJ g&^iX8$s}(OJ if́>+43.:(J÷X7LF DŬ VhIENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/mimetypes/0000775000175000017500000000000013244011205020356 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/20x20/mimetypes/unknown.png0000664000175000017500000000106713060755414022604 0ustar alexxalexxPNG  IHDR sBIT|d pHYs N Nw#tEXtSoftwarewww.inkscape.org<IDAT8Q.˺A0B4"XXB|9S |@FR`",dϤ{̌fI6Cb}Fv78Ͽf3!"DU0Em òEqܶSI.:v;"BKj!ne;# z}_Qȭ v;}E-R&W"V+n:=w~+ 4ME0vw #->3Cz4H,Dqx&>_}sC?VԙFXeL)?*1['yu˽=+隱E"݊`={Ay&S;g/\Pֶ#,#Rp=Z}XXZPc3ώ{76ݠ eDRhwEX]WA9N?1@}GF76UJfJ"Jy0V-修M(2 We]f+[D46J*n^kHEl~z˽y77e:7VsGQ*:5(lC2 *ɹְ^YejME)u=9aA 뒰G? ؞PeZ&ns9]xBQ_J`jr"Z^y{|YfD|'jv:܌2rgiѾٟHI'_ivȌG"ɑ51 xn)ބab|qwP2n|w)O̪U6Q0ohb96p[eE5ⶪe/pws'[j`jIENDB`doublecmd-0.8.2/pixmaps/dctheme/20x20/mimetypes/package-x-generic.png0000664000175000017500000000112113060755414024346 0ustar alexxalexxPNG  IHDR sBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<IDAT8͔1kA-NфFLs`bm#VZe?! o,GcwfrQa͛ WOo4yk%J@*-WUޓ[?/]p7 )&L|@~ڼpvt\GZeIdElsw &ՂwͪRݍƷG+No!v=ĐghyT$zm۾)$M(j>jG,iQ֢CwH=ƻ8gd Dz hĞ3.SR"!SCHTԇ*/"m2}ji[PXLN`U!ˢ-RmԿ\JN[lm2dٔVgAB'J5{/Ҫ,(= \٨VfcTu1<<|Q'/6΂~`&<^;=<<6zhhtx}ug۷p8<ܐ?c XkEf'rKTȊ]kځ.IvȃTjaG[Oz2Yk|߯9gJU罢ްaCnbbi`hwNڱ[rӪ[k:uc[UG4{јd {crLЭ\bYk_QՍ@X|x.e1 c/DZ3PB$5?J]&h%~57oXk˞*"{8d'frh }*cU7_.ig(nB]\I6,ͪz#| IDl':1U>Ij&j+Q<[" w"o0<ͪ1f#NRkkڱP[kڪ(9"b.(Jut!9ᩩuv?CU[]T'"1K`rDd@@7 ?C]Q"^ A^HpC6kېr4[wApQb l!Ic%㺺]K,ꩴs<[WT đ\rt:MZUK@x`=psXsq%Z>FĉL8㺖 gyk T;%Z~1- "Ri1tvu\rqN$L&s~U8X+w"5NZ˃NHx.GTu>_V׍׭X |+}4-4IENDB`doublecmd-0.8.2/pixmaps/dctheme/72x72/actions/view-sort-ascending.png0000664000175000017500000000315213060735370024433 0ustar alexxalexxPNG  IHDRHHUGsBIT|d pHYsBpBpn_mtEXtSoftwarewww.inkscape.org<IDATxkUg6kv[?h ~h}l٨RTV|TbVB6uw"*"KvL?4Lr'4{9gι7wx<ioo_hpv'o|\,w pgeQ/ }?OwfMu"͆?q`&mR>sݤAY #uy\JMCYJ)vMVRf~q;&I !kvIJFFFRe0&,| alDF)CDG]3.P<09Amzwuu]zm*<<^ HvBp' Ѩ8{Pwwb&U.0@zhDtey6=o' Rv˲^`A$XODoMPXވ'IV˲.8>"̉R 4"\FGĜc*4-rc捅BaL$' O߂Ǐ 'ѭ.Lu` RC~]P,ST{PUy.A%Q )Z"EqB˲f_U ̅ b P̢H$2z[9 ti`nu]O'>yezf^]!n>73>MZK:f^GuR}iR۶?Kmm|"z鋈EULCI 6"+۶?4qlZB܄U\.:4{U[5yn-( dƗPy󛌔>(N  h4jJ)}&(Y5 c33LD?yL9FD\'!Ї)SI8ïH߿f h/e}8_)8e4!\zRT*%3qg 0C"XiZ?&ٶl```BJ)D):%=.abnrar84MMaJ@RPHm!$>WcDhSzpŴ58o;>b>2j"ės",1&P"xK8б]0C̝y#N]=K.Z+0΀[p) ETPSdh;F˄/@8;܍5밲q`eqwU@QE:^J̾nN|r D`fddXL j?2>*fv1P9`~{ZM];IgxtrCa9* ga+1qk:5H6=*k^ !؍;'k;:\]vpl$c@4h~IXMd]X^#'CE>ܲ,2^pMܸlN&\hoD̨c 5&˗ K֋H,j<VP@[m:̟Հ#85Zȟ ޗ/bRo`V / [J0o=h;s4Ћ s83ԅ0ur-no\#h "m uV?v#뉴KB9 82rO!mX침rE8ԹLs"|pT}3؁HoB"ǩޮe E{3܀1j،I쿇eW>͟ZWw1Z& h uXk "#?)3LG,޿F^[limZU3y&>?!G,@&*", !A`b @0K4߉x+oT3v޴1E?x۾KW]TaK ` 1E >b BAt) S<$+Lg8XuzkRb%?FX}kjm+h pzgx0XȄˆt蘃LxIeiw$H&RnIy!hÕ/D}eⳖU%?g?qeЫsg]K>;]~H$&BAL )9D: 0%"@{bbeH'0v鋶c$,̯Obe.:O[]|ڵL{P~`l M0nCY82tFd&<(kj ҿ fFEY-*T?+']t3 !(R w>f F@,y )9 ybA v bcpq䊙yG>@yU:qE֪ǿ O ]O$$ ,+SN]0Pm.D wpRMiK՞3s6z}Y.^'ꀰ99_@v>:X}%נ=].;jzJl~eNy Ao;H!ItB33@L 1 ڱp}HGÁtTW3]j ,jzy-ĄpW޻b#\]+ d >X ,„H75h0  (3ũJ |:ygAvv_s vT;Ks@ t`! +"3pTNl ;/5_l>}<fL8fb'NbQ!eRt SQjMƤ(; }60٘˘.*S=;UkjaAH#L  (d"[i!" 1:%B&KRtyCXh$Ki0 X6--IՒ|)J"SLR!3 G/FxYt`DU[Q5(#x(N I1񰢆ؐ-*3QŦ?&0e=Y b`v=  7X^V#0&zv5j@rd9'8@?uVAm%w,z :Y3,5r=SLh AڷO=4[ *6Vf Cm_H`,Ͷ靁.leBz,6z  @oo(Als," aVepUj6굔 jm^""H`pFR2 z`Bp*iϓ̎d_p@~(wT>^3 eI) ̪\'2lHd-X}p;Pfx4P`{/ =Gûó/Z$C&{e6=XzKL0)3W}Md.l3xO"|';Mięnb:nKdawFe2lQ^`AC%8ѲTJP%[L}eG?0@? FXsA#1Ax#Z-Ar1OXf<'2d%+YJV_RYr?IENDB`doublecmd-0.8.2/pixmaps/dctheme/72x72/mimetypes/0000775000175000017500000000000013244011205020374 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/72x72/mimetypes/unknown.png0000664000175000017500000000267413060735370022626 0ustar alexxalexxPNG  IHDRHHUGsBIT|d pHYsNN1tEXtSoftwarewww.inkscape.org<9IDATxnJcc)h6*ETG:/rAIbwwP( Ru1: _~uRb'3NOOouض UUvuq~~fw(X]]ŏ?eɂzly8::B.{V6<8}?J>jx||KX4,hx>,B\:r3LR|h#"dY]әH6bbayFŁ?GUա}"U3Ms9=~-YV54ͱ-HD,Z"ɀ`2 <߉NIAdEQ.P͛TKOE)=l6X__ō2Zm"m'&x 83Oeo>IjZrTUETeYS{IS9qss'T*HR3i%ӰnOH(BǏ3?r#>;; IqJbs.-s/h8+Yu]7S MbOr(OTj#auY!Me9(!M&mYVx[d3qRbɤ4p)!QqjF0yHeAI1wNC@x%u$۷oPmömb_3b? ]i躎zr<>I4F}aخEL&[sS5 +b8z3iqi..."eYx]"A˲9HpbAq&D\E1ّ$sYr"yK'=E,W[ īBtQ1EvNE"-T*vRUu"BݶJ]כ] y:<bݶCJvT3Z{0=j bny rER,pKW}{'mY\"̛&٫x꡻p~W/6۶)#GtMeKA@ @!>'\N;!>lncO&/MoEAU8l|dPσbk5XfA@:>j+iRO܋#~6%txX\ TJHuvbv) G~LNLmn*&7bX][ib*K(վ`9<-n 3Wߍɹ8VS|C5ڱaCA(焦i` )ȁg#S7MAu8Ǐ|nLƐHZo\s@q쯿x=ծ9tpݳ?;z&'F8'n\!.Ѩ0G& J (?ދ~yz + '5(:Df+jiGxNmV{L=S1scr&TNXGh!ztEV?kmJ)">9G9@uuWJ #7OƐk@η҄YHAi !'G1:o)-jucj6tآjeAZP;5|OVQJAA0RѐʗziKab[s1ZFG;0$(Aj !p:l@tȊ|^8)P)/wseBq3ϸidbǜ1u#[,!pmɒQQ5BUՑ*oMIbF8o8ynLD+HA!2YnjX|SÐELVӚ\Aj(Je(q@0.|.ocP(n*mI9oy=}"ǗL7DB_b "F? //#ˋػ+텍RM1$ZT0 j 5T;uX!r'Se fÑoF0ư)`d0`Ψj%49h;vlRNxdH0}8VTuYIT{\(5[n5wZ J#{v;m&/zRX5s\8vJ;35ٮ#'zsUͪ(A´Qc4ߴj(%ؿ{v  x`N,T56VE s$nrۡpa<SvV *AQp0c!F^pߡ8; ߍݒt2ks" 6Ü!eV_3h:# $atKK*8zE̙sTA%`?}̅21L! 7dYE*+ +T**HmJjfոaqKHOͼ9F@ҹźN_3' 7FU{-tHZ2^Z(11Xp A cP,$k9db*V5|.Y(#|Omsu]S`I- !Ӣk @-JHgʕ3""4ˁ/H&i:WEkSӆZ}ܺX.!H+sWL^b~)(2N@4MZDP,VPԔPJ#'x0 YT3gHD\jD.8KBQ"y KXgaqz@@KQevtϯ!P*U% _$PBk|ʞ~ }UչUnư/dCv>@<ƀl{8]BJ&aMW?G9 {z *pytVAuJc%CZљ7POA(#6hbq̹l<ΐI7gC8=_V?8J)RibvEׇLND./%nup# 6T@@LJ-J'VEe3 F@zp.Ҍnl,44J8^pܣv@1.E;5'gYLLG ˇ}L:Xd Rklr˵L~mU_YVL?5SvΔ6޺qQY5'C44D<D>J"t,IaM-B %~op9It3E5(y*Rhvϕ$) TapƌMdbUS H$Z`^( kUӯt ymPtcpSbA x=nSCp\-a-pjSҥ!oH;8!mnW d>X(>/zp= V!IԎ_SerU,|a\3JRA遡}?> NjT*~5~s;QX XmP N'x-ʒ|/$_]#?`JEr_&I9?&6APuS.|>yfpy^AT$e g"WRՎeyPϫ\e!>38\u:da%ƔJy_Ki=[b..J7 |f|`xü T|¹{" Ejjv ō.59N2o dRI B/_:,MU|v޹ʦprҠ^/:*[dc=ֲ:;jkd-ݤ%zhՓr3+TShko[V(]zthƤ+^D;C6vks4R{^9QzheHV"o㻛[vz@f~EҨ2TM "EmªkۧNKd xѬV:rڣ̵zWhTnUk4eXJ .uzrIi1\ϿwsV?qRo)g, vpm0X-&Hn; VN\ }DZ'@V@ .1L4L\'BxYS_Q8~Z&' & HZW,AF>lTL Eɉ,AA jq[yr59 UY$DN[ٟ\NH_jtlArҞ^Œ0؅hQȲi7(IAbX l;vskFcns$$e*hcvl [) nofud}8 pC>X)EaI$Qגe*.#&p C@Qdt@$,>!ԱHn5AeҬdm)[탸2[9 -v-LU8p:>@ݬD,+iT.U)Hj@ 8:–*"W909p|\i4:{xV2TD՜I`,|Qu8i/&q?I<A1<$MS<Ts> B1jf EANb"rD`0( 9$DI1:P39i%H"Lu4Y!!^M b/$hJ,)Ai`mϓ]#Edfޓ&;c%IVB%!$AJ9o0!A#!U""({L , Hb|<.lN3׾*"Ř y:6l(8`Dl_O(@uʆ "h?HW/Eđ6tFa`V&Z23IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/0000775000175000017500000000000013244011205016350 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/32x32/apps/0000775000175000017500000000000013244011205017313 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/32x32/apps/utilities-terminal.png0000664000175000017500000000272011323355446023664 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX]E?3sv/KقH*mIȊZ5jW`b|a !"?^@ ?\kBD(Bn-l*w3gf_s=wƔ_=s3y3sOvF&JFDO^B}iqם |ͺ߼uڑU$|"^CQklKя^epxhX{,IF.Zv|s??ܘxK.9:o@tBkcL/3\a=AXhnHT$ZLLI@ /mO"BWz?v.|=Fk @n!R(?F5l4yXh q"1whm/Zq.ID:H Lq1"Y(욃>`9Kz& $f`+ ̤WU+q$bL@ i`)`XvR=f/8h4kU:KԗN1͛0hdfXBLiԫTiz>U1g-sxv0d |[oa6[/235E>ѐ6+1}ɥ9RE(j ZZ\} @DPIĘsāMח8,3CV_B00OsEG1`9WL6i!M= K81^_m;3k5 ;װyQJt,JkDDxDDeer~,} ^Uk-N1 O _z!c7lcbE#14t%ʻ}lp+HĹ 1`M y&܋{S1]W~%,@X6۴'~]1_+ثP|lYg-^X0Z#6WvHcAkݓֲHҮ Eh!HjWmW[sՆN?`=AJv DRPZ{~ wB_ĝy=_gNr4#ۯd &FYi=|0~ULM.5^K9$IZkyUɴ6]ļ44$IrOJh"G|$@x3шyAAp%P`hg tzv9tF4b|s|;ko} ߋ|y_%"w7o֗e&IRc.)Zy_yV"0}ve5>>JH*j޻w ZCv<Ϗ=XvPJ}}fbb,); (1Xc6all 쬏1>e}~/NNNNڵK.KKKrh!*1hmJƚFR4K"c;]yVG#/<9;;WZz;wc1@8GPaH,uNmeݺu?Ro@7cuwQJdp"G~IYht]bD#8TefHzh=w޴( bh6! .\ĥ%^O١n@X*i;1gO:2R<9 zZk )KR |h(P@ݣ;|ڭ.NUU11~⣏>:6_ڹs!Bk Zb^DD\2kkc|QBڽ.-S%8!05M̊SSS91H b^JCEYʲqShfF&'?/^ZZTS@e!VXkUCRQbt$zOJ<>E)\6>|{ƘCι]$i~zyK NviRXպ;6vc$I4FS_b[o~(,:zg[˻ΑeJ1 .%Day[ˣGp1=ZGd:65XZ}(l4lA?| DT@7PxZ<ZGۧ2#XEY "Y-+391!!DEA!@ $xDcC"Ph."b@4{?z\).]o=֛Q"h-X-RQւ҈6(eր`RJPFdP'#>y>?}ί@h,,, .V}n|1c*B#q >DB5g^}եaW&H`%gϺÇa oz74ru^#`h1Xa3O??p@ 5 [={l߿&;mVozcU.NVsӧO3N_M4 $ q*yNIljbUm]li\f|a’h-ˮT`c_m;Q~˩|A?sfIJո򻨱_EAZ\eX҆3d?Od['P''|DZVUΗ}v-7͠io߾?'[PPVe`4l*QGFQe~" ;Me~?`Pw]LW^囟R#UTr"pO7iȇ?*b(Е*YɏC@tmll+@61[H<nFFHҐHe-A8n`P<' "dv"&C]` MeE{`6t _{{/ٳ#IP?дy .|a12]Č?$ mg,DZ% C(" þek-qchH3:1j5(⫯awg z}0 1jq'NK`Y`R/V*0dwg[kXki۹~D)=1(ɍ1 WG@Pmh`4\#(j-6ݖHp/ RGon3;U΃ #^scufϬ}=4@ 8] Axq|1K4xGd-$' 3Of=&n_x]j`%_ft1>GI֥Ǿ<@EKj3?ȰsϏIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/devices/drive-optical.png0000664000175000017500000000247211323355446023265 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATXMkW;3Fm81J1Bdg1I: 6n ?q@ EC8El#![3sdl5]B_t99GwY"877w$0FX,~}޽/'Oׯ_hR `q\)8ѥ?P(tqrSSSJ%,BcXY R'&&ѨSpT';m$IFGG_|x7 jGz|>pm_x<>dVA~,b||H$2`vh4͙f)ehOviLNNloorI*ʁyPz'N  pҥGFF&mkKD J144tP(i/^V8ήZrVhp)MJ.EMӴϳ,j)~ձm\.a ѣs)!f{H)㌏z>؂+gϞ:"NհmӧO t:M^*n[VVűcPJ{H$ѣGmN/-۶V+8{ۂvT*nܸC_u&''w<BB)^SÇ>iJ)z{{㻪qMP866H)}(۶FA&appZCHӻi8B,"Hw0@.ٳgH)9|0ia`Y4LbY_FA" Rׯ^b #1FIܹsai0 v:RbH\FJix˲hZeVVVCut]$5ԟ<d2 "\p0,Hgl6B`rwL&b~?8O^PR黥ou]O{$I޼yC>gttԷ7wkMӐRcVWWy J]׉D"!Rmll|;G~v^ v=f6pff\6SӃiAU)EVX,/nիW ; TI ؑORԔiК*Wէkkkݿ׍-7T:@(d4 ;+HwW%-TBx-2\}wxq濡Q-˲ IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/devices/network-wired.png0000664000175000017500000000332511323355446023322 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX[Lg.k\ 6d FtEZ)ЗjCVڇjH]U}jPiDJza%"LVnl15YJ~ҧst3_ȳ`mEQHW @4xڵ杝wۿxV[;vzU|ABȝދE`#EQ۷o,>\O?oih AAP-zpB0uvv6P($,@Mf__v>w70 ]AQ,ܹh{UU?{nzx9\6 [0?A[P0LАI񱮮.oaqqQ~Μ9c%0j5M,E 0 q4 MMMBOO%J]> ,ߨ*xaLMMAKK P.A!MhooGXDPe'NիWA ø~-L&fBNq=gnCQ@ڸ+!ɠX,brr0 Q1?d2?|{/ `ѩT*ikۻQT:DQD<GGG1>>x| KKK܄r_Z۝pP=f;wށrڭ$vE_ Ah!DQaeY'7o>б{=)T\֒Yt>}*$DQqD"@RP((}t:)YVp,K C TUDb ][[}>"P(vVjTlRy^Q߿= Z2qT;LoJ7Wx,p$I21 QHIRyQJ+ù9UsiXRY\tyEQQa ԛPs~5Ƅ 4O]U|~m*+ƾ`_> {uk2(%ruIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/devices/media-flash.png0000664000175000017500000000245311323655670022676 0ustar alexxalexxPNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATXŖMlUޙ{,+B&\I"!ĕ &~.Xո(Qd΅.$1UAh"{3s{\׾jf23gsU"iQ#o"ٴ J@4U_w*#JFo^~k-\k%M2) 17nܠ1bقje :C~O^?6ŞsbYz߮WL݂'WOk 4xm}ۆAڂ:"\w3xBxBi?.B /}8'y<< جAܣR?£{8f=ŦԀZJ,H#-..lFx 6MҔJ-(,n+"m/}j/Be4y6"8t q,͒Y c!K$IB;R8Ađ!e)` tJ`mF.qyJҚڌ@wPC1h6% Ű= 'Mqyu%\Qf䭋3_R,1F9(QwmI֒&)3|06#M3@(n%"c(TF0:hiYRw0Dۜ$C [D1b- 1P@R{e bFd%eM h%c}AE)N$ç{ww}:SZso6'ǂsQ@ @8 a!\N\iq f)zJr8^íOjͣ:n6}nkBřJF@:co 'qE~I9kys;8@y~Pk>XL\}?#< (P"^ BY#<"y}+fg!;j?0x9ǛߩĵFTԾ$@w~ T]+5ݱׁ 8J 8ƌ7I ` 0]p[uafXS ZۈJW/tV6H/</:T3 DxQ=&9FxOD\*J S8fs'`p +l:b4SsEB@&O.d jrWS @NhcK{ FD#wW!9TA\x{IuHRCCL;YN0e=VNf'I䀤@ʊN(X|"jUNlũ@vQ41<$(dIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/devices/drive-removable-media.png0000664000175000017500000000170411633361331024652 0ustar alexxalexxPNG  IHDR szzsBIT|d{IDATXK[ǿw iBX4}TbT)Ң\!Aw]W"fvR !-!1(F13vLz3>69sg|t#i-c!M1Cx(wtt@UU躾(D"1:22!!9_5_]gYx<ӽqR)8MMD:0$Izq!M7d(ELP$/--yEy>33?88@\J&h1044tX,>s`300t:S"\H$- 4M5e$|>EQDӴrJnUUe42ݍmG/y @bؽw!"}Mb+++< T*!O+ è>H&BGQE@5}>!~co׋P( Btm@9==F5߬Es+I |j[H$ꤳ{{zi,NNNrxW~[5~W UUz+R{.1e$KuQ(0$ C8*h4 B)nPJR===#խ~ׁ@hnnF63 Jo64tPx :੶6+Np( bϾ+{qIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/devices/drive-harddisk.png0000664000175000017500000000220311323355446023413 0ustar alexxalexxPNG  IHDR szzsBIT|d:IDATXoG j T(mA H""BDI*(z˭rg=s?@/p+\!$cٻJ+3;G4{{PXR:51R*M?0ѣGZwRonݺ866qÇ;88xNw):N B x+дJ988&7&ovmmmVJIE;XrBvT*1ZΕQIiJ0 lAkc RJ\׵mq$ ApU1?7q@ZmXv0*8A1'OĉkrK))T** ~*}WJqEWk}B\^^& C:]EQDݦ롔QVj5J^vM6y͡beeuKWx%Zk{2nAEcyΫoA֚ӧO>'PLdڍ> P rtC#?&>` |>IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/dirhotlist/0000775000175000017500000000000013244011205020535 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/32x32/dirhotlist/newadditionfavtabs.png0000664000175000017500000000143412653161145025135 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATXˏE?~켖5^!e9/xO0FXnɲllkt J2LDWK-lum,I0 --J(^B÷r k;%*_'l( "#8?KQ^a"irduKZ\w^l*`I)BE1=.+;/~~ @^gu)hmiy0QUn?S Y6~eѸno@QaSx1m  O3O(׭ &1  B[l}(7;IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/dirhotlist/submenu.png0000664000175000017500000000277112405254001022731 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxW[lU7{.b/hEI BLHD@|1F10h|ME_| &&DL0@ !h+(WKvwn2snip?;s4M<ȴ ߾tDn͢˘vΝ4L8_{ږ5 0U\6l|>yWt~? wAO%qu1Xi4+`8c:{Za*Ns91 T{~?Y{gk1#-  2@g'+"!j%YdbZJVL<ϐuJ}0'O8L5yYwၻB@3 @?)* ZɊ2Oŀ/ 9p ȤRxPAcP9H߽/E qfTbH |$hZт1s>8Ԋfn .pjb*kZ敭ܔI2M\P_ŏ 8CГq`61$dRbN/@(K:'dRiP5DAԶSDG E9ͭ&)޵F@x~.BXja{A1ff2Yyz5_GZ1)hlldNI*\ՋOoCY MrdF"geWƇt AaP DiY&0Q ӢWPP bSC7eODkmGVETRiN${j}Mfeu@0q>e@䶙RYH_YVJd{|sEǵa GfYLEknΡߤ;1v8"CޮF}#NzzZCUsh_/z7R:%W9mBMe wtWM4D}hysG™aDB(o߉kR~ jRJ \Ͽ|SZCl1<"y`:!!z}l~VI@p?Yt8L{w8U?.r{.> Oݡ(IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/dirhotlist/submenuwithmissing.png0000664000175000017500000001021412405254001025206 0ustar alexxalexxPNG  IHDR szz pHYs  tIME"9{+IDATX  ͔AK3lQ K/hїaL ׆^Α93lP3kї_K %sΑ:3lP4mјdK / ً I0! "5i  ,1C 2ʑܩ%'(͍48r?  %(ә ;kr""ؤ[BQ5 ƃ -YU$GGo!M!M ա2, SVQQ&& ʑנ   !^odj*)!  )P *Qɵ6f.n%*׶ލp 1D 4b] lj Dl{ տӐa)   ,QN6\ݿ,˺!  +;C*-$- Ģ݆hDCR /{07ǫǩ3J9M "- 'ݿ-rd GVY,5Ūd "P%VutV<+D @~w+R簇䪓~,P!7;H@Ԣ$sܕ ̧ 2   3|!l q I-pkӐ4!#I e>:c 8 ΛF|{߻Z!EfKV !   e6O IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/dirhotlist/dirmissing.png0000664000175000017500000000447512405254001023426 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX{]G=bbvrME]4ԕu:K[_?"k)2CA~k?gls/?п}T0*Q& &lW[iՅ1V +C_Dq|R"W΃ϿWsFM<0vOJ5Ap, }•X$qO y_~k4gy:L@dtīfg-~i+Ko|ҫ_cpTe82f5_{FkO)D5h^ɶvi:ު#U-?aR&rQx~Pt/Xޣ7Ys̾ƗH^`.n.uбd5 [**LFBX=C5&ǵ_5UY)W 7gg``YV.&]OIL%i5%)3[wL>hT8ASVF)O2K;!g9} ,P$ws7 Уk̥鞢ؓUs]9Сc!$sp2Ր KI{-zܻYMzA5cCm>K4 ֱES4rt 3VGDduڤM&Ab_VY3<O_feyG Csh (C U(r~=+Ro³79f^ p׳.==E&2 ӌN zsxG}g\,DIcrI&60Q ZyEOԥ9R$2?7S [ CbIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/dirhotlist/submenufavtabs.png0000664000175000017500000000211112653161145024277 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME /'IDATXGKLUs@)HS& "66).0067.$Ai.\PQnHmj4[ R#46۔Ly|BX[f'ͽw=:묳eX}C׌)+ Dl*K&o譧"yU\z'wRYa:P+I><ص~+"%[#GgQ)]$ %4<_> 7 p ~Wgf9QN%+up <_@J$$%eA?,TBJ&IHqH *E,qBM%5 j"9j2@ ,IeӾ `.1裩Ir>Ϥxz,opy8u)~<}h|xO&ò׼EX?DZ1vz/j*@m 4G MUx%YyJ_zC&xӻL' j*%@U[7k^b<t1|7{ m8 + xcUwF}}d5ˆ_ #DށlTyK9-]??)^[}QUrS_ rϪ1Bݚ[.t{BRl f(ESɄD~i.ߤPיֱSfqT6"gPHOE;`eH+0 ! KY47A4v8 \B"5 ƭ#}/Ѓ[m,9&>yp],CDBJG}xA!&7T8#pDuVjU~`]I@4@ w0&Domho"S',ymbnKe@D0DƘ޻wg~cݾngv($yZo:',Tz^GaYzܤөqsc6[\p]ltc@BC7yJ sln_s$/KҬ3E;+mD]ԴHuH> 8::Z9pQ_ч?o|8鍺|[_۽Dg:jf(>aMA#vWG!sΧiJ"4jy0p`ۭisfcPqvx2L&,{pցl<3 MՄsE(ߦV2TiT&$ф1EM{}]|E[0Ш&d3w%UIIdJyD, `uol20(64| wtjT+3"PL&]w+(jƖZZräbRlaM3όhY&3^TueY& ANk"XJ5*e!8JU%mthh´/Q=&/^na%ʥp9ӬdgT!"Ye/ Qe^eYqMV/>(.(!]3Ge<+*Gk"2- $/k= pp{{"4D y8(\BNsf6"+ΟVzhr$TO8f%!wz /VPɂ3rc(. */)1F(8O^AaTύyj@ @vyp H^3rNJ/HjiIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/emblems/0000775000175000017500000000000013244011205017774 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/32x32/emblems/emblem-symbolic-link.png0000664000175000017500000000170211312762055024527 0ustar alexxalexxPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTEttsuvu!!!9:8<>:=?<=?;=?<>?@A>@B?AB?BDACDADEBDFBFGEGHEHIFJJJJLHKKHKLILMJMMMMOKNOLOPNPQMPRNQSORTPTUQTVRUUUWYUYZYY[WZ\W[]X^`[`b]OtRNS )PQXY NXjIDATxڥJAwvbbDb k_ uNL)Q {K DK{].q,30/7,5Hu(?dI(` 1 8?w{+93>u}z8? :!"cGXU$rư "bi F /{ȱ0o'EID 9/WSHZLWȈ*ζ5㸖Y H:1xѦI!:fj]BtL>ۚ Bº@i|L:zFh~H5а=\&S@Z4 uDiJFMkbeHC4sէ5qÖԲh̹3IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/emblems/emblem-unreadable.png0000664000175000017500000000447511362134553024070 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX{]G=bbvrME]4ԕu:K[_?"k)2CA~k?gls/?п}T0*Q& &lW[iՅ1V +C_Dq|R"W΃ϿWsFM<0vOJ5Ap, }•X$qO y_~k4gy:L@dtīfg-~i+Ko|ҫ_cpTe82f5_{FkO)D5h^ɶvi:ު#U-?aR&rQx~Pt/Xޣ7Ys̾ƗH^`.n.uбd5 [**LFBX=C5&ǵ_5UY)W 7gg``YV.&]OIL%i5%)3[wL>hT8ASVF)O2K;!g9} ,P$ws7 Уk̥鞢ؓUs]9Сc!$sp2Ր KI{-zܻYMzA5cCm>K4 ֱES4rt 3VGDduڤM&Ab_VY3<O_feyG Csh (C U(r~=+Ro³79f^ p׳.==E&2 ӌN zsxG}g\,DIcrI&60Q ZyEOԥ9R$2?7S [ CbIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/places/0000775000175000017500000000000013244011205017617 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/32x32/places/link.png0000664000175000017500000000145713065676717021323 0ustar alexxalexxPNG  IHDR szzIDATXKhQ34m4}kVQ_DDU\q!2ˮťBek-RPhPki4I173s]t&NCv`6=p;3w✣!α Pwm!47kpDi[ . 5@5TU@84yx܁Oo ,<# 7Jy7ۜ/P0V-B;G~n^Cob59$u!̀ǁhT@8ڍ>xDԾ A$pY,,(%m+/.?ȷX77C nϹă ύ$xѵ9֖3')kJ+tL~$aO[r, WAj'q}мǏX|&TFD={!!$3&ۚ~u3woWS t6\2,op׺fz5<AԾ4-bˉiXWh*SJ&Kpf"-hNl1Lƥ/9LcCH%)Gt-#?w+RR-X)M!6kdyl&~xdL~8&k}+J!nPᄖYiz#:JvjjO3'yGij{捫Y~՞2L1us+[~\;T.?d M=ȯ#q!֞sz Shݷ^ V3T=*y*`]19jm3\FŻ8sqsr?L~<2 IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/places/link-broken.png0000664000175000017500000000143711361045050022550 0ustar alexxalexxPNG  IHDR szzIDATx]Ka쎛J&Q ceBD/`P}.>A?W](eAIDe*b殹ή3;Ogv7e&= 7`Gt^K={z6]3fA >5[X`5Pr=dÅ&Bt l>rOePd"[(sZ76DOCȠ*eLA Shn `)egu*͞C]V$Aݺ-x-Og(bsFqD!1`dx OWДhN\4Q/0` :Rl>a% tPp Bof[Z&[!{.*+|uuwS/q:wށ%Z#<4:f>*(P{5uk<zhtzI M]VfKkj%Uv+yQsx%$IJ!)܂c]^/#8КI㕲߯G`3p}w 7F#P1dӵTXR+'!$ׄ]| 0[6IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/places/folder.png0000664000175000017500000000175711323355446021630 0ustar alexxalexxPNG  IHDR szzsRGBbKGD pHYs  tIME 'ȭgoIDATX헿]E)S + @bc:UV6b@ INJ| !|˙,ߞsL&.9Zk o+k~Flơ BBl|㷕aWFO ,P Vk(e ~ -l%KhrK?$/e3|/ao<ϸ67Cñm@UXn®߇͘[9ŋ*a\5`oIڕaSiC?T@N" g9jYS)%.z?4·V} }\<4EkN_mi%X5tLMĻ?c: IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/places/folder-link-broken.png0000664000175000017500000000324511361045050024020 0ustar alexxalexxPNG  IHDR szzlIDATx}LUeǿ˽HIlHBj&Mj6[3S0(Y.L|GT.3kp/Ery=9[[Oy<GUk>L]>VUK0gKdH^@p4^2]>p\=#;Ќ>}tٽ:l/Px@$OAm KɪZt^KqH}j;RTEЭ+GM bH\Ȕ5@X({Qu+,.›NH<ЃR@uB%Hn .u@~鑨x"P?f0*D0 D0[J9+-W-_@f*@ZgfnW $.&rp>(h(D2nznh#' )s|);p 9" Wt$ɸ#^ 4n*rUQ.fHNAY#5dE0T47w$?POZ'&Ve-07D=[Xs!L? \׻qDsd?Si0`~6$?;z.1mbmܱ#Y7Xr(0rRsFCua$4Eqc1Fej*wl9xկl& Y{@B $uSH>X(㺗 0hLx[4XdUbl$sؙ"mFB`T2+jtdMm)с"˲]Fu0Cڦ~$ B M(4$&f"&ce c3e-.adLN)Jw]'мI2n&Q`܈7 +<:zpTz{JlӶQ U@tCSVOy7:UĽo(x1lne<NTp4r }]aMWhxSa/L@͆ ("T^Lm ZvȏDr "zz U._n:y]ѼCʊ2/)LzDȌBxd}1^ 2&Ys>zK2< lAKIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/0000775000175000017500000000000013244011205020010 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_leftthumbview.png0000664000175000017500000001021412467744673024114 0ustar alexxalexxPNG  IHDR szz pHYs  tIME 9--C+IDATX  h Bj - 4~JP -P. >M|K K     &&fT++,%"e7Y&8'kڕ&zL`*<G!     (أ(> ? +o- j7 n9̹ )4GƵ $.:K:Eƻ7JKY=O#4$0 fa    #-)5)5Xr@O@Okn I+n4O6IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_markplus.png0000664000175000017500000000467312110457565023063 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 7%O, HIDATXŗ{pT?}?Ivy$ +PhejkKөbѱSԪj_cLvj@+ EDQbf_>WHpAL3{~g;sp3Y\fkN^mUDڋ95*eA2ѻbh dLCZCLYfw-_ JvS 9yƂZ >}geS<ז]q'S|m?.:wMfgfUd W,mQ{>و9Pwp7H \9d龪nx9ˠQh~kIh@:!/x2)䲌H_J~,hYRa- kWT*sU`L:.v =ϣ\6oxFׁ̝[[E6 FBN1_w?ºyjFIetWģ)]W@tGq;X;:|u߾a*}kJnsU^Jmnj}@Đ!6Q]kfHu(b]k,TzG ^tΓ?іmJP5d@ *]$OtMPvntn!{) _DLFP5ed)2lkEAB!2B5)^GY$,Zݠ!IB.((BгFzu&t:`r "" fX Z0QDw5 5JDD $SuQ@>jg $ a"M'P4`F[d!r6xDžnAE0 D͠ǧhg``Q9!yYr鼢=˲jd=.KE&jk?C\s `Divm&沚Vj$%)J M0犀ڛ2PRD{'vhy^3:T_"ze[1WY5XMU>XShoU؀9aS& duÌ_Nm9!$:zxuog:VϪT8GyǦ,yb,0v;&t*KLɰoEyuŋM#8PœSgϲa8Itw2r? 0S#|d750Nb芾.Ӷ\KX&>4NUSrS셈F$X#@Nbcc~Dž,o̮X@$H M $s((jwPnwEG>=ވfer4:E^RU%4CUǨpϠ-;Hob'_a(OӴ'J2r0\ϣlT )g+wv`n+LSL?8;᧔3/=ඃ;m\qxd/3aw oU}tƶџ܉ɜev|z,z:BN\-,3L/)蠷kkNH _bki̬]R=3(g*t% pf&~AiwMf$fq%U  R~IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_addfilenametocmdline.png0000664000175000017500000001023613016313447025341 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 89Ox+IDATX  }~;g:o$$ܑ;g;;}::ې::ې:f}}f::f}o::uIg%p:::p%g;ggJ:ŶfJggJf|o$IfJg}}~ȕDWke?_R: ƔlƁK KPR_RmÒ?d7} ~~ W3{ٖlEi&Mng\yfv2& aG(< c_K vqw]Du͛ƀbEGuN8}nK3ek1"[,Rqȃ ~d }oq (,Mt    qjb qib pib  <b9~ {gednlkhfe {9~~ǁ  ! [UIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_markinvert.png0000664000175000017500000000377412110457565023410 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME ;+KIDATXWilT}۬xavMk!B(a -ZB)jJT%aqi=MTHu7$iA) c{`Z`THGOޣ{>swBF;8($W7+۔HgW=v- 矈 ө䳉DgkP @{|káS؝eM@\pgg:',_ָ+, ۮn.>v~nBpvT-z쩄zOO 8*!+s֡jƍ޺ܲD )0!G:p[qyz 8 8 J ;A z K\rBfY(fԑ.XYdǺMMs* 9"2qckE Z1G 2@}fOzϹ>f \߃Tކ"xxQ 4kY U> =Сn[Ea9:E_gAduɺܣ_Ļ]&"!@ )ۛ_fGHmoF0 U\Vem, ᨖUasNLT#\/Cd@hQ#6Yߪ PV ;Փ!]DOAj Ll3&444^F 37beM 砒:xU'l.*n@BgӐ.T' :@ "C2״T7:xA\d̼S1@1 ݴGC RKLPOIv  qA PL 8x> ӺYM/F`\QMy\rM%"e\Dp~97ȳ=#B\M6"I(*vA,aFh0;7bˏhIE7Bgoq=bƏ\-tvcklK(w tPper/z#EJfnqBIX}prwy g{oKiM?PtMs<Ѷtcck*H />'D @*}) @f,:\+D5P7fwOM2:gy}jI.@A35a_s5@ s\D\Ŭ扮C5 HЇK`ݺͿP= [=VR Bs-,sDX,Ŵ؍YuwBkT|7+ݗ~0 ތ[34)NXj/q;o;˥e~ўz^ fmmmذaWuu:&} HXRhr$JY:h 6m\G@/ӽ]GopDg9Ki}7:u%{9 ·>+9% 䵈yka 'E PH f|F0 x:xT0iJSzӝ-#D̨Wj~STֶ6>yߙ>T)?޹19@DưHbHݙq]CJxmƓsqh4?N$b Z[#n}Ah)IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_reloadfavoritetabs.png0000664000175000017500000001023612653160641025073 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME!·Y+IDATX  ?zL T†V=vO iP; RÊ[ eN: : eM:ª  ^3    ?f!#"*Ǥa&=$Õw!+!lWycKNZ#KDɇ-w *iE *Px7yӉ󋸂 .3%W Eߚ8*+ ( E1Ed^̷w3X5&u3 J:d !3Zݿ+˺ -J <8G,#t`<݅eFVCB tG~eD޵ & &ݵeD JVt4Q  }n_u7ym 7ym"gͺx4`pwhy58%%68޾z FYA/1-tXy4yA   AͶu4'#W͸vv N`6`6 ND|KML:h&j))h&j>C3%3J0 $ IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_filelinker.png0000664000175000017500000000255312110457565023344 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME/32BhiTXtCommentCreated with GIMPd.eIDATXŗkhUs&{4J؛TOtk+ZCBZhbZ[ܦHE U[Cௐ&Mlv6&QZ|p`o"`5pcFN5v㸪r/`(Ipj+r\Zq#ǂQ@r K! fٲ%0#o}/ภ5dss2 %u+yfͻSx xW2upAY2%Gi R% i,=|ytgoa(ݏTH Lsq",0M (E…zEi"UZHV pؗ(aʪGFJ(G7LWwfP 6Ǒ. *<.':e:KٱӃ8NwWpSmhh4ZM3DC1T`vh(3G4EJ9|fJ=`x$]ץ.Ύ-<pmb̈́DK#P._J+hhh##q3[Qv_iY5Ȯ4L|EM 9 S & !@*;o.2P(R )%@yQbN!~Pyys=2}! =t&ڶmf8ѓ +y\%NsZ^Z 555!6` T$I|qq_mߚy.S醕:Rz]Ap8q/P(wCǀeM"@4dx{q-=' ңl<'oOyx\& nhB Lw75qmO./7sul:pul]f:>Zm83kOHSZtݟNp"pr0=N6E)iO%U.9?YFG{ C}$3h-V&2tR\/|}[ wٷy-n8Us$q?݊[݅^憾*`[oE0PU*]i {'=` 7L ??@.fG]s'\IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_closetab.png0000664000175000017500000000221212110457565023004 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<,IDATxWklSe~n^fBt(Ÿ$&$ß !hA LDe~(D͠[.Y/zz._5&9}{g6rX` W;>TUQ~hZ$}Gh6Gж kQSP8VVzkC1=omj8c"8:6bPw`O7B㏑ظ…-x4Elen?GAWB.kc zF[sCEӑ@}dpIPr6$D落 lI^1r(~Zl"LYEy~>vI[ =qٕ5), \@~2CUqG'7gZ9Cَۛq(M iCQQx஗DK!`ZIΆu7 Ī]4aczGv}UxдN8*bSƜΒd8c՞gQ&|Ur:gx$Vag&x{sf1b~oo]]7`d<7:ڋmH| sx<#m()Fn QT?ކ@b$ iÆ=t3QCٚzZdI&sj"s>x}ulRb'v6l  RXwkijzW8O1M l ͛a]S=2lQ-`>Ch ](K=%c"S`Gz/]F=죽عvCU*)(tRP-};h3!$ZK^X* +1üp8R"`݇[/;3G$QQP&|wb1̅CήũTgd2o=$tQ{eIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_briefview.png0000664000175000017500000000150012451473236023172 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME +#IDATX VMkQfLE4(]EĝƸwQ +ąDVnDh~E]`:_ F4^Kwνwe(TGqI+g PEuε$ISQ0RlWJn<~L$KeJOW(ndsHIljP* ĉA,&6 @ Z27<.lXdhnb͸C.= M '#[ti:6(~ M&qK wߗ#UyDq$ѷH\(FcK$}iB 2FaE{w2(98 C_ӳb<-|ӲcUTiQW|  jNDİ`ㆶ`| Ї˲oθ肅$О .*$ 1- u]p֢dEY21 LKJ*(j`po` PQQAT ;cr.ehEs|x%-]0\vTK˭t1U[x1AdJomQ`ZN|ڌpf.8Ip/yE5mTM5VUb\! wMrYV"IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_loadselectionfromfile.png0000664000175000017500000000444212110457565025570 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 5& |IDATXŗ{pT?ܻw&d !1P"bkqSS>qD,:֪T:v:-G뀔` "E $AMݻ{# ;̜ٽy<6>xP|+ L\Tqw*P]}C(l42rP5/P셽=]6i[daBTH4.[OV_=a8RX'N[yz 2ݢ M3dx$wœ7-:ޢ`OySP6V*,]ZTsɎxB8བtsMڌ+Ǟ5,;PSR{OAQv}(H~=ɟJ*}ZLh` x)X>}fOZqEV-u'3m]eetk.\ "AQz6|?gCh/&v %, 0%?b%34Nl[7Nƹ;|CnZ.cvl{#F| ?t&>r+5hS跃%{j_O5]`^"1l=>/4 m&:`ŧ%Q2QX$Hoyپ+:"I[%ׁ`< ~Uyd 7M ᔮwW3?Xھ`%)-_dWvo@f<ܖxǟFV YD*D""쀭hnnzx0>t/J'12!32]ɏq`1G'+.h>{2-7\VQU*gIMZ[#=tυ]xgC@RE ̥Ol|0g$Ȇ[)l5?)੘Sw9 2H5J32;p>XZ"G@ DA~ jvT1, K!i'!ǶQ-,+) S~F-A@8\(DL`E1a$pFA(޶\߇R"$` l$X0S: v\NGu#f&29+a>||UZ!xvjÖP^ps:NUuE%0:Ƒᯥs"[CISُOm3.-%pdoQuBqycǺg5Mڔ+k}UÙ.ri*[tq/βIі|gxVΨdҡw h#)4 `:g255-juz0bCG{?*ZUʆkʺ%6!Lyq uD]TR5e}D0=vПo+*IFulQ` lW;Oi(g+S,B9S}=IsMI ɨƴ_MЁor9Y!B*(f.MuU`K`Fg3vpr57c&=y~ϛ] Yl˳ض1ffܽ8SgŀplU5y2͍eER}a3?Jpj3#Bo!B !lF~] )+ZqsdG@gJb' zIEҹ8^&BF*~7/dn:H{kBہ}?YX%|c}S O =252kdMmGM8] bTu!8#~ւm1j5w.>7bZ@3 4'XPZ_X;[2ckϣz}Bwp1퀤nETuSMƨ# hqd?Z5HIfe 5ضF`޷7Q;< 0y@LH.l i\"pw;^@HWW]vJRqVsر'c/q%/V/hM۲Fk4 $0mb3se@81Tc]WRm1^TdخbIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rightcolumnsview.png0000664000175000017500000001021412467744673024640 0ustar alexxalexxPNG  IHDR szz pHYs  tIME "&ώ+IDATX  fK2 < KL6-n-X-"    >>#%%6?>>??? ,+*/.01 BCBAA@6?>>??? 0/.6667GFEEDC6?>>??? 532<<>??? 876CCCENMMMLK 6?>>??? <;:BfPzKff6?>>??? fGf {Kff +5fPKHq+0y3ȻӼIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_changedirtoroot.png0000664000175000017500000000250512451473236024411 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME -IDATXGVMh\U}$a2UҦ$ h(Q "JEt/ Aƍ` F."v!J%EklD;MĤLf&w{yo~&K0w=wsyou 4y 8\-41`(NᮻOq]`+s5v-̼HF|X \x$o7)ꝣz39\*6rGN|mkl3@$J^Nn-Uk6S;/x7Xp4]l;c*;duu.;Z&w|i\bSۆ|c'Olw4EhW8& r(GbjoQ% =?kf13µט:%ѫ% #?Ru=l_$KYX^^ ָ H <׾r-h*aI2/rj NR!&ru*4QF;||Z Q0"ZAܨt_<+i̅v,DD"SL&Qyqq/B $^`ۙ (ёԁMF+#}B|mxMA{rjwooP.޲Y#ÚȈѯ1e^vw'w_/$IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_helpindex.png0000664000175000017500000000433712110457565023202 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxڜWkpT>6!l@SGiJV?NXgl?iEeM[#3t- I , lv7w{  !9s%ߺ%; Ig$d\ё&?U^J7꿫ֵve+4{ 0ryē:&04:0zۋ'U(OY^xXv vyZ!HD$ə8z%֗z~h>-YPSX8q)D0aG=O UX^mUD/>Ǩ?46 |-hXn=5h Y(yHE6ga r@'/⋳xo_Qƽ#yOX[Th"@(4KT:cqg zV>@)aȲk'.1Tofg{7mX |`CU#*2 K%,2d7>h >Ԍd:ɸ3NCY&W۵ʖ7֨bQ}O 9Y uQ-BOYcfu$դ)d*v? ur`C:{4s.0n$4>4THJx9Vd|ːӢa|!\n66PAn+R%oq.lGwYYwo^c a\*VԌ0:GSGE\Sa͇D"C^$6G K+c?O$0M)I}j{ęB_ںWę)ARR!,nLC.i\u*q!>y#HsNUf!Jw ӧva۲`x. |mi`>0L?>vS$!ei#.xΗOsW6ۛ*t&IN7һ ZHs$zeɶM4ջ55:-bT0\8f4/jlhWТܺ'Wj U.idFD=z+]m$;xQSu:< WG FI<_@Ą`aJVgAsmfhTL6%PfvlJ2` *ca F@j9eXj8zsjA0.]EC{!\Ó꺳=0tS5*@ȕ璉ƎYӰ6WP1NRϽ9JI@Ri)Ks+(,g\%A=Π~jF5} VzPStr>Ut5x _4Q,Ԃ@Q`!hk0X µ@+\njpU, pa~_ 7"E0c] U8 fujQm_ZS>;ڈ~X.,o.se{S5vA7[ qgKSys* "ÿ|ܑ;g;;IPf()\: g%pffJ;%*: ffې::#ߊA0k@' $&,I>zQffff} $6- f:f:::::}  }ې:f::f:}}@\c“aFIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_gotolastfile.png0000664000175000017500000000125212451473236023710 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<LIDATxW=HAv5Hecg!9XإQD!FaqvҤ, ?777wsW̾RJjB(WC^B)ݛo#Ykak3|X4[_x&ɆI КƷZ=g& >RrH_bXBPT*"󐚀X@A{e(l $ e%i3 *Fc(nHF{q 4>\Z:46|RFa#Ph Q. U.țTwW,YGëT$˿_"564АZn ]ET1b Q8.ߟtv_8qUhhq#9?ZT. FvK骘yf-Ig,f`+qVrK1fjB-4&8Zp 7!˘dqZ"3t;zop|}&%%AFr}z(/Yŵڝ:BsIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_options.png0000664000175000017500000000447312110457565022716 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxڬW{PT]vYqQP*ъU#5&aҦ:1$&$?ӦM3Q' NA_a, b_| "bR^~}9X%(-?"s|,[9@1TsxK|1 /bCQ HS f5qyi٧/[]>x cƒ7a i-:iON\VR}ng6-˱V6wV̟a̩88ŞB"/^\i!}Z:Qyb<pϱcٳl,uN26 zN[ܐI)WF~iF2bF"~RDǖ|;Nvڹfd s %<˽;̨=ÌCd 4 ½1 g%[@.Ѿ0 Q{,l0C$C_xǥdTPEu5S?n72OL^FwT"Zh&,3V?gY_܃,e {ǘbUKV_`ًgc+Id!& _Λ7sq=ΡN%zPaQOiM'I*(^ -FRtU+g~ )ˏ(cFWD[5c9@>Nc_IH$%AJ$SHOԍACUZHF8Uz۫Cy!G/''K6>KK}$AVOG7:@(j][*jh?Q^8k*c$9k~m4?;}іtrma'FI@h*4dU Q*GESSоauF򖠃1d"}! DH2 PX7y/`D".AD|=O4_ӼU6?g>?lj#x/rzG tXτnE=Ixbs?B(fXxb^U*JDmx? 9R??bń\mѠc5G\z Mr3JA}rAqLJe{ыpVÍ<5/qѵ䂍#ab cm^e-du!3NhieھnnPԃ~)us^!Ē_g+\`V*a{`k>"e7,k.VD+ Ă#f& ,a{fb)ecc8r2o4 Wm|KaiͅSX3:ch5#Š &H_BF.)R;"z~V ɸ~ń/nx+VO%.j6*FXʬ2RGj 6FaNiPۛ?݈YU?Ej|igDA0ay0+l7_BJT$ E:6vr~EBl) >AZۀ,B73Wmލ̟"02龔*^2Z|$efzrހ( 9եA5} c)f}#]-^.>9G`xRC7P5Tnm_ǭOmr7:?3[BJmp] L'O!8$7zvvޝ(O:)ǹCI1mEiى6嚖-Z HD%aP0K}|2 iuݏ;g_Z˒@o:ԟ#kU>$E{$T ֮̊AqNRf#e5KdT2$5'@I<[Y歚-, &]ڭO{kkQS_WƲbG}4ۀYC!7iBtqJr\RzJ{1 ,4$F9]/-iΔ)B+ 1؞ZK)):.1T݋^`,O׸ͼ4lj ݭ;܇ g^QUP7z%F*%tetxYz{7tno/ "(x7ڌ@] UTc|s0@B *2 0{\IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_open.png0000664000175000017500000000305212451473236022155 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME  `> IDATXGW]lUfvvfm"HiF4A@&F T7%&_$ ICeRhP(t--ngvf hCTjC|x*4WC`*q0?:9W ;=jJiB&P~j^JܖPvAYa;Bw_ȣ<-HiB4p9d7""4>EQqcL"͸b4p)r,˚P,M  2%wB*] t- Ωr[vRi ̞d &Pʟ-H7~ !DJj| GfUKn EMB)3GD]>DNJ`\ύ1p3pzާA }<01p,%5)C/LжW&~QܻtJ=R"dnLDE/zOCt?A8SE<4'ο[й]4nrsRKP: X i%iC%":NnOrryr.@ye JUWvܦ< Xкsg0M:ȯIs8|pUUBPpH7~@I2S3][0ۦg{ ֭C|lWv"lizPUxp J*['jJ687} p$cͱٖp 6{3rA|?jeU0=nMɷѲArvYli 1cT9{]rz\&Ϲ2 l89)r*MhwD UN8  8  {G379;Ȍ[T> VV19chl9         }J#  Vx{hIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_unmarkcurrentextension.png0000664000175000017500000001023613016463506026050 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME  8+IDATX  ԃ`ՅhՅhԃ`ӂ_߆Xɍ ݈ɍX߆ӂ_ֆf $A2_hCXjA:)XⵗyOU6 K. -O 5cݭ} 2#}L ;f'pΕ!DeFJ %SWd? ,,p@d|hA zMUt1 ?#F -* ^+C9 ݱ EO&z(I`  r(H;Pӄ: "  1vZBxZ 0q-|Y%C |(BjS_I  pn %ʞZB 2 8 ! @,J*        b.}]ꙻt"M %e 1fa.QV ' 1^ Ҥ  $ 9. % : ,* #& 5 v  %( =@ַ #E?     3DCߥ      M 6J :K佩 ediA'/,   ")ވ9J ! .)6ij:$ ܇)3+%, vI49"x$ԃ +*2 %/ք~`c5=yN0;Qπsi%2; A8oO> ۉdF% *8 /4 ^zz^d~ފ## "ܥܑ;g;;]: $o:ܑ;pfo$ '@k0Aߊ%#Č:f} -@lfɬې::} -6$ ޏf:::f}  :ff:ff}}:fffff}}AvIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_markunmarkall.png0000664000175000017500000001021412723431627024053 0ustar alexxalexxPNG  IHDR szz pHYs  tIME89J+IDATX  8'A '-*k Kښ^ԃ^ i+{Յf aם.045lUӂ] 'G 5 w ݈Aw⽷"@F 19޿Lֆf $A2_ h8Xj9 43 ľ@G46!kU6  .R:kR1].'o2]ľü YGp ٦ @ <^; hA  N 6+ KVLY #F -* ^+C9 ϶DN8@z*0\(_ַ`m  r(H P 1vZxZ 1  -|Y%C |(B  " "B&W "LD&N2Vٝ| %  矁2 8 ! @,J~$5ۉb.}t1$M%e㳆Ky \& "  ԃ +*2 a& #5   + ~a>JH69%ܴ * +FG×i%2; A$, DPX8 /4 ^zz$MYKWފ"  "ܥ#M0'-"(]:  &p   kg3X  !v+ߊ.  ͐9 ,5!=     'fA#K$ v ޼曂A1,K <%-οD3#d vtIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_editpath.png0000664000175000017500000000230412451473236023015 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 8[R|QIDATXGV[kTW^2331Q|0FcAR`A4BDo"b  _BH4$Te[d΄aϚΞu=s?Iq Y9e|^-s 9gfRlex9p5kj;zne!ZR?KV8=`emt4ohU"DF@) ]Ο/!o߼'zDp>ܬS]) xG(/ tM>1Z";3.=JA^Zaq<)sO ^Ĺϔ]kIˏ berrR.^Uy!25P8|}0ɴaaott'۶b a f<67htKooO` QO|+)i )hXEJiz*ݔWW6ɽ1.dxv4#-"e|V=t. i胖sV EcB&}ET%/:?C?9lɀ@:X ^@yBJqCǁGO|rpkW$<~Ȼ}4T)eF7՚v}~Ϫ9w:ݽ( baXpVfM OcS(M৫b7)" \FgVq>NjEC/ ub[oUPL@B]w=Fnpk8ʅ`mTט18o~dםNϷ\7 ~ZXЫy&_7vqq/Wpak#b[b,Pkar:50~c^ BIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_renametab.png0000664000175000017500000000132012110457565023145 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME,7C.ga]IDATX=hA3{e7("Z`H4JxZjPJ! Zh>P0%ZX(* i0̳H.`7 -")UJ`DbF+~@htx%yݰVd5Dp @!*c|uzaElnx@i 6tC [j\aV2yìUVd!fEJ",fU߷@ҳM*Zwmck~eovsˎçwߊձ\nc,GsJ1WXIWG3O.9ZqK]*OI^ hO5jeF|a"EZw'{H(DIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_gotofirstfile.png0000664000175000017500000000133412451473236024075 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<~IDATxWMhAf7AQA)'E" TDTD7ICz*T@1B Ճ< _"lvw|ov7]b/7޷}RJfBvÙۘprhnwa7Hz/>w?%/Cȅŧrv~HNEp682g'3{/&P8OCN$%=VC|f_/?@M_wQzU@#JsZ$zA {nƣ;P^D qwk1Ubawb/͠fI`t .Lc0Gà^\:w$0 CP† s*y'NX$Ib'!LByS~&,^|'AJ㜎[`_;ts ppmuP Aր3JA#.B3E=Y~ X뜆`V@Q "@,uoBG/XC;_&+^3`=l,:9]v֠a>%R6ःD&z?RNCtCIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_addnewsearch.png0000664000175000017500000001021413017704640023635 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  (Hs+IDATX  wy{wy{ y JJI GGFN0U+6 @ЫGzhlsPv -RsP|dG{gB 2gHOngHyc?ssRRRihhAA@sI3WI3W 0  ;npqWX[RFMx Mfke N tux }Gp lnk    4695 ֳInpr# _'% |hilH:ۻlnoQKIH I\H``_۾oqtLCA?  "#@UVXP L=;9  545JtuxmnkIDDI9:99;;000''(9:99;;000''(  ^_^  ^_^      ;  ;     髐IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_loadfavoritetabs.png0000664000175000017500000001021412653160641024540 0ustar alexxalexxPNG  IHDR szz pHYs  tIME%r+IDATX  ?zL T†V=vO iP; RÊ[ eN: : eM:ª  ^3    ͳ>}Մ ږ7)( Hr E#h]  F:b !3Zݿ(˺#4-hDhLܿ & &ۿhL@~w @~w}+9%%},9 3   3I^J^JIL:Z!z55Z!z>C! y{43^IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_opendirinnewtab.png0000664000175000017500000000264212110457565024407 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME(ZL/IDATXklTE̜V mBRWn" QC K40Ma4Ack0AU niin38 Q9yߚl m~` ͱDdۜo=pӇrDn* q0" ,K tq~: &v$]mPb ~x+ $r zPA}sx_|ώ ZYW!d䂈BFDH&0?W^w>~lD4:hIaD]Ɨ.[=u"=8Rd+PK-k̴Qh_::㜬?C)=ݺliX BSlWmZ8;ԔH _3bLd2q`u!ch8 {2fg;4TƝe+O+9v\BV\`p(=}8m7h"PXګtXU$ z/h'*hr0馻bHr"OQhd* d6ZC7=8|=7k 5#4ۇݶIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_deletesearches.png0000664000175000017500000001021413017704640024165 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  +IDATX  't+5 ]L V94((@E  w%$  AF ' #"nm C C JI  vwu 32 ""<::;<;86655##66!!UULMLCEC >/] 33u5 V94((@E4 w%$  AFrpo   ' #"nm :C C JI;lqqn Zgtv 32  2877SUS  ""U  55##55; LML#! %SS  gvOBDB ~|x%&'>aa_%%#tsqrpo  tsr  ;ln# Zguw  2auw  2ZQ; ;  { ύJIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rename.png0000664000175000017500000000210212451473236022456 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 3%Z QIDATXGWOA~-, xD r2`I܈ƔV  h#G Fc ' z QQbl}owt: dvf{{ӖsO!ޱQ=X1ٰS OUq28!A3lƂA5@ʼn;Xeϓ @5P05U 0s6 -F$R`sC0Dɓk-`4/)ApXOM3fШԗ  ı;D̕fԀ} F=="6&ٲA\|33dϬV+pJt4}h4JJ1X|<)v-wɘz :"G!'a\W,{0 0jH[DrH$v#rU_ A}=196  kp {ׯ*y hy g7!lQFJo @H(ڏcmTp( Bd/DBW7JN8e9M5Cpݽ-(k?3hf<=~=:>bl!>Dкf=NĻ\CoĖZe _7IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_comparedirectories.png0000664000175000017500000001021412467744673025112 0ustar alexxalexxPNG  IHDR szz pHYs  tIME -c+IDATX  K~JPKL6vP9|K nJpK ""    >>AA !b, |EH+**+,,؍-F - .Cٸ50ї @ ؜*e <::  -}-  w 2ҏ +/۱* 2$ ۇ'8?- " %3!  ,,* O$.FL 5Y\׹ !- J*C2x͒* #A);"%@ њ5v1g$P'V 4sTP%l?mr ,A xKg@V5ї @؜;v <::  <f% ,!9 ~12۩* 5rS6= -  #2!  ,,*  Y a߼.F V  ;_=aѴ  (T֌5,I!Pi: >y/ -E-= "D $Pչ '"9/8]{ + TA-ݝaIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_settaboptionnormal.png0000664000175000017500000000110212110457565025131 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATx엿O@ǿvC;B*!KF  [10"$f(D !D;BD:UR@!?}~!~''}߻,9f&[LQߵSOJӒ]E|rg~zCϫcFܧ!ĻLʮ(Pܷ sJ5MO@vI/cM'DLHL`im'CS `p3?Kx"H._ -9eTŇn:?A';/skE~wxC ;S@Hu[T) jDi 4Txr2VgnvErHEͷ 1X%N҅{T*5""ڳ|F[ Dn M*ŕm𺨑GJT!tvBB AUrCHAz Ooo#IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_leftflatview.png0000664000175000017500000001021412467744673023723 0ustar alexxalexxPNG  IHDR szz pHYs  tIME m3+IDATX  g  :%   %-G)P%mmm ;DJU KVTTT P7B Qmmm# KROOO[YYU6< ^;Au  ;@W}Vjmmm ! \ZZCAAQ[XXU !2DAAQV::U  "9 "mmm#&$$\ZZL %V?Fmmm 544544 bmmm6h Mmmm"    %+C&O==S'.mmm#$Ufmmm  3YZ$USS3 *5*mmm#$ROOVTT ><<?<<mmm#&$$\ZZyHr.sL c+rƮUfބ@w۽ 3a@ECǂla@s mCSvMvCr' c*v@TO S‹AX"ƃ=Dle ò3>hbu!`wIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_transferright.png0000664000175000017500000000227012451473236024077 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<ZIDATxW]lUk&&Ő͟mڂ /J V$jH1  h@H H$j;w;ݙLr{w,SJ~>L>ı2yF5?"c RF^쓴-^ YstA9vOױ5LByoL_  - ckLj$! `" AR>ѱ0zE\<Қ!zg! R;ҷY. XOϬV-v~ X`x<ѫ4)^/i?'Ɣel;{&`.%*Z@[ gi pjg{!9Hb\A a7o ԟTRJ!ob[}atuTo)P3V65|Oom3ss N^BKҒ`NC? TRJcF9g ;1Lンh+=$:F*Ji`ݘņ 3ʻ6@@m?æé%eHDIIDȗ6} GnpىGѷT/rv5Dp-H0(XMoa)q4 NY؂Ļ'qrp4{L(B^gϫE8\'!1XQ'w= yOQZ4yi䯾~Cx=^F=zZA 9E4~vh*wUPϬr#؄'@㾸HWB6Mw-2_6Mhk!rhxse/s"]Rjh1 @Ae6cvA)6Vg/hտ\00#WXdc*Szbnhz'b37*3cnoe|9_T`ph9[у I^i`VK#b[ \bU6Sl$L{$.FNotscIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rightsortbyattr.png0000664000175000017500000001021412467744673024502 0ustar alexxalexxPNG  IHDR szz pHYs  tIME ,-+IDATX  fFOxTC: QU({Ufwu$C:!QkHHkH:!QC##C;"Q`@LL`@;"QC33G=%SS6viiS6v=%QE43K@&L1WL1WB*QI!" zD/D/zI 33r2BvI4S|4 7!4# 33>84#'3 V4VOgO4&0V4VIP5d3)-DCV 4V%#3+fccő; f';tIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_copynoask.png0000664000175000017500000000277112451473236023231 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME "lVCIDATXGW[hev&{K66\7Fbn%BE-->T|*^^ j ZDOZh iA؋XS l64gg/9L̤ ;Z|rukKک䲀"eX " X7vk., 7Rעo#sl`@Nqbqߡ 0} >&''Ez{/BSP)g G{yLbbbB!j%RA-rv; H83~&&,-J {Uds!'`6r} Sz:~{gғc`Urr:ki2qv̹JBf,^jcY\'z=WfdGe}%ra:="¢>B7,Ër R&Xk{ܷƐ@k.d2 ߙCpPS=񇱡2Jd&x!p:6o>bH)@wO7i$!q\d6Cee%l6:\@@X4Cw<AE d*BW/CFU 7\ڙ39بԓr)n[MK^_%Yo?x!ʄǸ^ckF%B2IXSjc9@oĈ|-[ 0F `!b9vXe}6Ul։O>J_~>_lVd'SwcjϤ}x@!xa6=z^/I~ʯ(_ܢHLjk$͞\xod,,]wM@Q518_RX 1$G7nۼ-qWی擳x<:7:`(ȺW `JPdV0aD:Odr]l7^?" 8IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_sortbyname.png0000664000175000017500000000155212467744673023417 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME %bq]IDATXŗ_HA?{wՃ?^"$"ɐ@„,: A"!@A!T ͇B)A2,S,Nnoo5o/ }7 YcR%JJg^B϶1=V^@ fsd*QX t |!s']X 4y/'.n@2Y)jz>,vog1ciO}ӈ %Ԗwsik0NfB-Ta"'!L:R`9zS@)NuЀ$fW~6`䱡bُ4y X6ZS1uvX,L9TkdcU@40@Fyu#@ ,R\2Q{iOnߣM"އW~P躾eaMx#P |[u eUkB櫤{Khevٵ@|EG /er״|[2*ٿ&Tܿ'?>_5Dgpr#q l7P7+Xآпϯ z_7-;n#p5Z5Xl,X(͍a)_/ϓrpk5|Cd}XRv-iscXm @ŌN(vLd$H3كT[?=zy޻*.An0<$2M;w@qJ@WSo7_N[_Bel 1`aF)c'ЃaRn[xlt^,cuԴ<Lǩ@U~ag)KNl[ێ]9컇.lyYME,e?͹'>٥8JgcS8&QjS {nx)|Zg !4\<˞ӑBSϨh[De묦4nr6w?D@w+7{29~jY HdC&pŧ6D=>[j8iL!4Y}R)61\4\H34ϣB_]gF4PU'"#>چm(n6SʎJi{\m lLj?:`z݉1fqmuX֯CxCAw2O{4`+m hl_ҦO+bv]L9 }~&mhNȺV͡@X?&@+7k7:ԙ@@%P$MC 4?F*|S[&fx"no'C6Dgƿoj79IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_view.png0000664000175000017500000000314412451473236022170 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATXmh[^]ٖ7َ_j`[RҒMIf4Qؗ 01ePɖt]^x mΛ_f/8NHeɺ{!)v¾큇sAiJß1<4}/ܲf|Vnfx3~V:B21H}{9j'o[KU@)PXBޡu|Z'uouu󝷿Dvr)N S,sQL q;?ā0_}%r|AƁݍwŴž}/'!m{Ť{vos{ÁhNMrQS?4ĶۙGJ%Ⱦ (2/7f "M CZDZ`CT[,3Tϕ\u7e az~ SϰLk E I Kw-r{0t$@y&MsbH`ˢġ9q]L PYI34m'#  N#K* ̭UWW*}}]= /?wPeraFZ1 ~sss՗xloD68+$2** ز`G7CLMMH$n\RѦMܸq(羽w~!#3<꣺B0,F兩n"m5%IϹzcc /Auv2@"6>'m \l{&thNgΜYb!Rz1MVVҌ{*vCs:1I,O?PDQ4Mc|b1,ŋE=j_p(@4Eav6(3wI.'~p8B=LϹ_PQQA0n0??dv>ʵkWL>{Ote5^=A_rUv|8P`]s.8R>EQmx<z\ܿ%]IR,//L&I$$ 8TGbs۳,FZ67 vzzGNS k`)FU¥K;vVw X}Psj W `9Kz& $f`+ ̤WU+q$bL@ i`)`XvR=f/8h4kU:KԗN1͛0hdfXBLiԫTiz>U1g-sxv0d |[oa6[/235E>ѐ6+1}ɥ9RE(j ZZ\} @DPIĘsāMח8,3CV_B00OsEG1`9WL6i!M= K81^_m;3k5 ;װyQJt,JkDDxDDeer~,} ^Uk-N1 O _z!c7lcbE#14t%ʻ}lp+HĹ 1`M y&܋{S1]W~%,@X6۴'~]1_+ثP|lYg-^X0Z#6WvHcAkݓֲHҮ Eh!HjWmW[sՆN?`=AJv DRPZ{~ wB_ĝy=_gNr4#ۯd &FYi=|0~ULM.5^K9$IZkyUɴ6]ļ44$IrO : eM:ª   Ok_2    fff    ]'̳3Mbu ~8-}'ǧHNS U:#H*w/EiD<5( <5(  /\,v| MWג7u[ UN8 UN8 OUJOAų  ɸ8v÷19,{G3H75> O4. YA3  @"'y; &  _{^"g#O k R}jRCZ?{[qsOݻx9~XmEj,0`iyTlP]>JLF^q9ƭ!*@XNwre.f[b20LŲr*r6qG9Z?S+.#S7.`;w_taB,Km}9lLeR C4I*v{,9D;)p;{j*eTv%AIh8_IQf*a Tk ;qv 4\!!1!S 'zH9'nt#^+ٜ5%%lNԅ2~8 nKe0"$X; WxXO[Y,uD}A3fPTC!`ʤ)#w~!YA NlFacF2t[K;!i㮹4hn癴O>Ϛ=y+tǏ&fL8!!Av4lFi;s۠MJg[KX@,Ǔbc)/^L3ڸK!1u{w0 եم~3km/&att,8_.7Ёs ]He`;{fDSRѵu tP{H Q_66y~'$u!qJ:pс"RJ)z@"IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_setalltabsoptionpathlocked.png0000664000175000017500000001023612653160641026641 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME&R+IDATX  ?zL T†V=vO iP; iP; iP; RÊ[ @kT> kT> kT> 8 K              f'.3 /"E+/9 *.8`H..3:,29Ҹ.' -0L?IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/view-sort-descending.png0000664000175000017500000000077511323355446024605 0ustar alexxalexxPNG  IHDR szzsRGBbKGDC pHYs  tIME .}IDATX/O@Ɵn A 3jg`gBzffЯ@&fCz/r-w׎>k7VdrPϜM>!p,7ί7Ϸc]" : 1y9^&#c%P R"x_l=WT@dLθs }s. HOA $~!%u? D4fN4TNt I`F9  ) H$`!X>0[xw;o<ΎY8Xr{yiZE&Y  XlǍm_s1Vt'0OIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_sortbyattr.png0000664000175000017500000000165612467744673023456 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME W;IDATXŗOHUAsZ-hQTGBMK3E$H%ڻ\A\I %%TD"ȅaXBaYF{;-X@D)P-z寫"ӘPcFX17@ Sg2f#.oD$l*R6ϛ@L:iˀn`D8\$9Q`K@Vsr_^j[iR0'ib@=Mi3@tfN &J(I_S#;m^ /A# x c@'p/riA\%"i$M(xQ/:c*ܷf L 'jKX\fN }-( }_o?8ɧ@};ic@τݤi +Wx@JB w$!nbfK$vN+QAo[+_avp-k ,Qz~YwZsxf~/IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/view-refresh.png0000664000175000017500000000375011323355446023147 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATXŗilT޷q ij,\5(%%QBZ〚㦊RRPFE,iIҪ qC Mc xggz7͹;w= 66O7.(;U8[9sX n#u13mǷ[SZ[[Č5~0-ݰXtM#%Lp@`ʽ|s }?EAӢ߷xSt ~]U..eD$IK)s~3@ }Cn#e!XƇE]70-m]=kad^@ q$ %A )$|t}p&_[7U8y^e].jx:0+KrKdaX!P lWr$HlI0m3=6Yͬx)w|e"y`D8S'<&"F: &x\H"خBMb߉)ronmܸ(ۋo2'q>BI˝ vq3kwRgp͖:/177 @M 0f4Iv p*/>, N]YQUmk[cO2idmxmtF.i_pjH$w0XBL }f7{G 9w> kʷ uGkª8eME"9.^%8c_GO, %F,F%Y"/uvj}#_ TGѴPw枹Ա /S֤w?ڌ""/Ep UhP{'dt!qvKA hX~ɚ.q nIoK[6`{Cۉg:9@{@ݘ&n?s퍽ͅ{QZȒEJ)eii cp$`6҆d2&cmf}_y5n̓@r{Q8{s)*[ee5zQٗB 9*׈}8t\?Y 篆L*j~w;8l"1XN~aAX`l#BL ?َ.S!F=HA^UK /x!Nѻ$k >_=ˆm2svIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/view-sort-ascending.png0000664000175000017500000000100311323355446024416 0ustar alexxalexxPNG  IHDR szzsRGBbKGDC pHYs  tIME:IDATX햱K@SuqYŵKAtV&vХk,]\]NEPsRXLz!9@fOכ=gHE)y"}V3"25,5L xauH"7\HhIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_exit.png0000664000175000017500000000254612110457565022173 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxڼWkU{#ͶALM_E B Q(,}_A|I@(Ňkj_TD 4iSLbSj3s;w7"f̽7;lGL_:C~K3r|Gvv~*azE* %$Mp*}kzm޹`Bn@7?edQУAg{ -ܘ2@׌5P*~frٔ(ujE"0bõqwiB+2kBXM dDmtg+M#X+Zn!=97k@+3`K)KQG밢$ Ij~vF||=F&@D7ºJa{I(5@eeh4QgMD$]x7"ʡU@Rr%emGսHxu<ۋ9()T`Ӂ7G*Dt,EBV#r}%u/;9 N"3.9'VHS zWVsncb y5/n"4qyC3:h  ?zc=(mG^6YqOp?xKb T5)p&2d|$x6xbD7IrT}- \& NYXV , XSSPR.MO!3j>a7.D"[сq,lɦR!MCuY0%x8WǺP2xȲqI*Ե8}>u(8ut|_IMi;@ԅ^Wf&&VP:[715-O=".Mm38{}wDk˜JȖIQKyv(byAfȅ6~\cr4#,KVtp zi@گu<xs3!/VfL&(*n֭r簋?Dk p 63Rȷ0M<q.̏&*SXsEDo^&cFrÍh2zKm%#"2c΂ru"rn grŞwm/`o y;^Nd[ɨW](YrIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rightsortbyname.png0000664000175000017500000001021412467744673024450 0ustar alexxalexxPNG  IHDR szz pHYs  tIME -6vN+IDATX  fFFFMC: QU({Uf ggC:!QkHHkH:!QCCC;"Q`@LL`@;"QCKG=%SS6viiS6v=%QESK@&L1WL1WB*QI7# zD/D/zFYr2BvI$C=a^P 4 O]>IXB$Z#-`  @PV/%fső; f?!{ϟIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_horizontalfilepanels.png0000664000175000017500000000110412110457565025443 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxjPƿss;CGBpQp\h u }Bs*EZ's2dd\%7K 7bf@.Ers<򵗣~7 epd3j Jxgx{>#X1hpq4ڀjR sͧK(Xn'&г"rئʚ\:Z{O'ԤXڞj mc*28a 7Sȃmeҟ4y`95\<.CQ& 'X7o뮐q d>"Vjoqu ~z՜OBnK pÅ.pC4ܰ~fL0Ɉ6ޖ2Wpqw|,c8՟jm @ٚ0\o?S-ݸidbʽ1b'IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_setfileproperties.png0000664000175000017500000000261612110457565024770 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME4+IDATX͗}Lu?y^ȋbbě1a J\ͶreVm65G$2C]󥥀AK /pvm{vxԠwc;ʯUv]󆺦0sm'[co{+uU*ee>Bcлyrp(FD-"8qQ/B6QZ'evo+))QϽnbC)-HϱVVz'Kh~4 0jD2 y0bFԘɽAV35.e2r 1u]kc#C`hSm~Dڬmaql({^|^S)RQnLZv p LK+5"]=ۯ-6gcwethJq&n`ם΋ r_-ȒLd=ebH/IMS|ĝ&eӖbijv{v _)/LjCɓ'qr R\\,GΜǪdGu]LfX/Ȭ'͒Cb [KvNu踌 `\=:lHrss !:&X"G*jFhmiT57z{1I"!)ZuO \'3g^Wpk'&8~:;8KG~ 9)yz~)iU 4Lha YKh< 38Px4;d;h@ @(ТSEDB[֞`W4.|Y(o6[vCV<_+RlĔf&';nH\B<DN|;k֬A$#.Fǖ,>^"#4i1/ał-ͼ.a,\ ` ]s{IiXVMf  f?P8otFˆ7 R Na7*{˦-gta3nǍMK'-kKcec UP1i om)OA"P WcܝJ;YEN(իt'w} 3ޑt}n ;G 'Q@]Hå6< 0zd'6IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_renameonly.png0000664000175000017500000000153012451473236023364 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxWnP>:iTj@H$<VނѱD@BWPtT5Ms97NbǾnwkTJ* V|nwEdge[yI3l26$=X*0'McVdVd,UUv\Ƹ {aPlpgnl.hV@Y6yXj=^\w)*$PlqzU,39}$ .ŸB٧)*[`pp,f)qPBTg5jχ:דBpݭ_M˛ѺC21T ēI)yH\N;*J9m@Hd}$ĄOr?x0@Zzv848@US>J.I8S9]]#`||B=}}'JEM³9wDJT[L؎|*942((e mfT"5I,BrBw樲MFo\OQW loPg_Up(pt`F|hIJs+2ceb4!V(3A)MA3BNaS׺ t[RGM--ʀ .?&L( OEA,ŅQH;@ xPQ) ht- ,Qm \tM2A*,H GQW0quvB#igxOrPk-zχ }"R ~J1A~~}=e,f^QoT)pmŕ>DI2nEdDL=UDTSS@l.6 uV.w D'0$ cѐSHM"pIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_copytoclipboard.png0000664000175000017500000000335012451473236024412 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME (IǝuIDATXGW[lTU]ΝW[nAhH%($6 X D"`Ø$1|H"@!IH1菨v\̝LNt㜽Y{}pLu%M8uukkykMdޘhÀ[SUUEJ0hjj%a`в 0-oVq5VV T =2Kҽ&tO^IT!&9Fک ;Ͼ0U] @€ Lj|j:;S/f͞ǶOO_[͇lBm!0'>Y55%%5=#btٍCak~E"Y6NpJl4cH0S 00o}Qӑj3l2\V6=jÉ:zG13U\ci1nDg0E+bKl&f3vi. /J89c]7 F(Ef6NKbGFy~΢<[}ã:KE!*:{08CX ̫O2g6U ?z=*F(hn `/a&'B~/Hqshzik\D0vH5FW2nkQ*Ԁld؈r^s܍gdN^X"'-v`(X>r1 \y(שIdJw=^\&tc?ވa"C7,JCVVlf>!K>ksa\꡵0>1^q36f[< 2M2!Ԉ{`ʝ8PVp(~lCe0xrKvCcw+BA0w - S`NR,̇gEDڐ_huRƚ8 ,AV#;iRqRaߍ8bD͜Mn&1xSL\<^~}O0ܐ_՚Īe/H@T+q;/%Oq2gi&m_<3 U=6]O'OY̹xbڳX~ ijqWTkyWFYBTFqt%BXƳ&eB{ӊQ,F@Tk҆eccZ蔁iU.Ӫ/ef)~"<!58rLz."e`-6ڈ9 %Հ AlYQZ(iQ=)':hw Rd*&)h1'ߋyt*.&?L}R]ĄKxo~k YIr_A 0jm(N%P.86\] rO$HOE<4V~g[f2ԀkCO*gE/h D%nO1 O@k n{LE6n6U#V:_a3** 5g[!҉EÃcM w,;;I׹IHZpo`ʲF~3Th[YE6@\ -$vǫ%yfֶX[J"K* bbHq9#(u,%]+߻~Њ+Žh%Ao ^~w+X0M_E󱭬ig}@"J(ʵı \8k߉CҝJS.ngӂb dYf$Q8[ۻr-=#L.~6n4Ao"қ7*óp~O e-4-Rߗ-yDgOÏߏe_K=ͩ8w^UK5r8,?>)<f79(Q^@ǼRɝTKb-%*"$m:JzGJ@ߙ$nzO= IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_configtoolbars.png0000664000175000017500000000425712451473236024237 0ustar alexxalexxPNG  IHDR szzsBIT|dfIDATX͗{pTǿW6K$A-q$hgdXZ-JY *([iaD bG 3< R((@汏9$K f~sssvt3LIw5kdfBO/]]U+ǧ;푷PM][nڝHQpF Pu'E'{BSݰaz+ݮ]`ZkK)eOΙ=vy.5(3g͜Mr[bMn헢+3˿-aʯG\b; %%֕v1͡o.2iY6ƌR;-(Lf$@"i7 z~vNGh Eͺ=޻{B; _kD륔/+Q/(!/MgsJ ʎ3,9f/6߄DB!a#J2Fa6OsP(uх:d/<q_ww-K5ǼAc:d ~{X| .ľU-p/O?DBs竪ZcuU䛐kؤN*@ڗQGw0|vsME}^uj eYP#G%lKB%h:{#8>'{D RH{j+䥓hmt;+)%"žYǗm}(wcSBwg 4ű:fZ&QJ&>m6t]Gl=!D}لmC'-tJ ܬsL%%%mO:t *Lřr@EYssٲ l;d˙ ,SW0R_6D !t]c j]AEeHrqG}VFճ\ lW/7-.pr/uu >HNREai5FJ- xNlC? prܸx5aH!:VdB % ӔAJ@ROؐHX1uqo!Ћ3.`Dp Z?ōG 0PJWYIT/_ SMQH0Rܶ?pG`9oILT_ mi6G1x=&;ͫ$!'ַњNTuGHKk|Nmjb&L?hiW˶\s0MWc GF)-rJc_7!΀qWa7Eɒ @/ҙ~ @z>_V4T75!'XR5m{3s;n`9|Swp|UU!{TH"!W=|uxnnh,Y^UmbR*mj]ΛO+[`ljP.LH)*.4!6!1@JRZ ]pd cK(cLA啶|j}e foza%  bH~mu 9x"HH)O]dïY۾? iAJ H J)H )OBgT%+a q[Cvm{vOwH{2O{doHviK|IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_comparecontents.png0000664000175000017500000000210412110457565024414 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME34KTIDATXíkU?;٬iRmb-j`ֶ>Ҧ5DD}C҂/}Ʀ" *Fm(&ii&&&3vw̰;άfs y-`Y/\3GPhѨnS h(4[ ,x훑OaOf|Z<~ZPtFѠuJ}TJneɽFN-VQ G+-K*QZS.ܢs{nOLT BтQb9r $gLϞ}Հ0am;X Ş̰V U (H<n.2@WGJAnM h%e(`:Tviu[ZX{><;mkm7 /bC\mGF9;od%mh x,ӱ&.UojF'go k@KHd'8=:))$ Qt5S(:R |v-"" s+=g!ݔ`ks2v]+F@v5Jоn6?9kZˏW\TP(ܰ"DK9+^R'2Za;̘(ZK&?"+MyԊwܷ7_Y5"31|s/dzXqW8aNȕ78hÊ75b쯙Rߐ |8ےO/ת uu @9߸=v܆oTF(aiyRE`[oT+ j58ВoIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_addpathtocmdline.png0000664000175000017500000001023613016313447024515 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME :#C+IDATX  }~;g$ܑ;g;;IPfg%pffJ;%*:}ffې::}$&,$&,IPfIPfg;;;%*:}ې:f::f:}}}~ȕDWke?_R: ƔlƁK KPR_RmÒ?d7} ~~ W3{ٖlEi&Mng\yfv2& aG(< c_K vqw]Du͛ƀbEGuN8}nK3ek1"[,Rqȃ ~d }oq (,Mt    qjb qib pib  <b9~ {gednlkhfe {9~~ǁ  ! aэ-IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_cuttoclipboard.png0000664000175000017500000000372512451473236024241 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME  25bIDATXGWilTUޛfiKvZ EE R%-%р(F_&Ml $F KDR-mbtxyo Àdn={YsTU]c۶hRe~a5.^%{ͪUhSKD444!}Cdжzv,{j_"\5Mss P=iN" YФe|ؖ{E @nլL1 Ia⊒btuv̚= iG^ }z2`od ~46m Evc'B(TUQ3PPX޿m8 ܵ/q6LP9 34Pbvc,-QE`ٶ):]* H=YjB`޲ 3b03Ϣa`;RP]+uVin| DǒiNޠyK ֞ fA^~Q@fzĖF"^0upz2%) OUbv踾@feaАlII$ƞY}_K-[. 뿑y{p'lZuvm| w\!{)pPj:qS7AqxJ/6drlnn} WTJPBZL̳l'5V߆Mw;_+O"_3E>+qI)pS JySꙘgb `Ӱvn$L Q1h([qn~+q^-€eR!~v!(Q ,wb+x?Lim~dll/NDz#}pǡj./RbYaQ/%,azΤ砻, p"BX^ytr]\{ue4gNڽ%| \d]tƇFotbP)KÅbSh)!oj]$͛2K/"6/[i+IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_openvirtualfilesystemlist.png0000664000175000017500000000322412110457565026565 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<6IDATxڬW{PTUݻ oRDA#GtT4E665a3&^6L3Y) 9 R| 0Cey{]hae̷gϽ;{sAҧ}]N_E! 41/KֆN S:Q+D_Q!i)_Zf &#(UtԜP sc\Ig(J@Ԇuxr0hiiR5q˴{O}WܲR #y`q%Boݸw/qa`,zz z@0}(bF>0łr㑴G'S WӂF{=oˮőUxko66[zxm)ҏELG L?H̎39س&vñ]md9%UjcnsJēoU2=fm?Ʋ.1qQaY%XDz>_l70ᛑΕܓXrRz{7P}δO[)85۲uhՏ1".=dr)cuHhi_0]Y@𜋢t)oT6N=YI][v8k౏93Դ r&wbi¼RngB0o#N x[Mq2ؕ41mr7ׄ)NYMBCE펄Cgˍؼq5 NeD@ȳX5 /d7\nhH^ʪQ(Q4ݳ)N"Kn@Bri]rx@Qόn8 ͽx b")!p:I0&sV2@$li+bĨAcDɯHN$+Gnabi),GtPbt"yҿK4 _Wʊ6608P7vB<{ڨ8]|q q,pf&֬ۀc'БnUG 7gD3_Voe1hCsK;,ͭ!!υ%SD]ya2fSҾE88T&oۨI IԲ E~Kgse).YmE0h]6CYgq"7WcJ@gU}}t48z^>3gʎ.@ctwIOuEgIèWui`M`ħ1&xIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_configtreeviewmenus.png0000664000175000017500000001021412705015424025273 0ustar alexxalexxPNG  IHDR szz pHYs  tIME+A+IDATX  m]KL9-3/+\ZXK "$<95024034 !   ;yl[<Koop $"!Ka ,-0mN>0Lg5 +.7+.7}<ghk---bb`F5o  000IHIq@uS2TiFIKL-"D0#0#D=-uH%.%$2$=,B0 r7- +KW~5& j9$l<444 \C,i8F7+Z,@0!??(;86 +'" Uۙc8:bD!=ł+$$ BI-$$2N80H !h3;3Uag{gzfF#}DE|з(.T^ObAͦS3yn_zw;Y}'P.^(Ozq#s1q̷N#y{㵷k}3˾__./d!RBkRJBTU<U@eiV7oޤjcER$I?]#֎o(T8sAR:u c ys]w~g(1Ibiik-ι RJ^{UYyc<À PJaCt:ۍ .ƘdBiZ6V=J)jaͷˁ2A=?,رcIQ cc߇Rs#+eFCnmmO:jW.c EPrv]0??oVWW&>t\}!8 dWF{nuFΏ6_;oFz/_`105c ߒ#>3?&AU5YftYZlngz- w!@ &J*',Iާji. 5ޥh9M?35$g/nB@YKj<5pba71d#Ԓ81kmjGix@"n[K yTE?N3!\cc;&w(%X11H-xQ1P~ pԩO-֖̋jc8Y&NM]\hmkj ؐ1enzL^{1AQjƲӋjj!2unl؍ qf1ZNIFOs`0խ思SnČ$-;GAFߎuZIsnH;0dƍYu gDbl\JNr޵sBBx~4?LcZ _njoy B,?XQhq#a f~ï`Xtb8e!s:w=p>MBxpm!yEf&çrdVs\06:TY,MrG8phRc OJx˄'=X鹣jS;[c(TRI=S F/_a _Ciޯ4-{4 nRz{Teutv WU_2p #oȇ7H3keh aI QWR/*fֱRBPZP8 ~ͬE~co6 s Os&nM0qONNvHW_~q=~cBy 4<אY___߷ l B۷Oe($h>eXM ڪ:'@ۆz3=$If K{YoC5+1%t`G#Qv GG }kYo› jtӴ8hq]j z?|tdz+[@IZް2J5HvڣQڭ,7}in3Wz 9(雎fdѾ4 $|)IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/edit-cut.png0000664000175000017500000000404713110262743022250 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX{lǿ3;ww;M b40U$-U*"l7D@CMTJ64QԪ"`@0X6=vwf9dvl?]ff &ٵ0b/Gæ&v֛c9M6EƋ5fr7<^SI^S\V'w,TW\mwY8RJڝ{/}ʯJN55;Tۂ3.;lۓ]dP!$JKK5'SkJeeNW8R"7ap83%߹sg tWn0!Dzz&RL @?oHHiZXUҥĜƜ g6E8'P8@O8BJ CCAA]5SkRBSss٥) oJ-uRuuu?-`S˖L GunZ'*q~ƆÇtUR0Ŧ-$Ph25-5!!|͊S[V/DŽP hjjB %E=nOA]]:۞ʥ-w)%laD&BENi2cR"aE*7e~9XZH5ѯnթDMUU/ PUU.sıp|*=HR@uKrsX|o ! ݾ~SHt{wOg0 ,¼B,(uE"H)ii-^EEQӲk%3^xS0ݓPXgkXp9k}_ ndBL'*e +S\N'] B5?!Mѧ[7n#TQ,WФC(CDzRS^ @ڻHtFavCKw{_R !h z@nS!@ @EiHN~dNAsi $H{9@ngmmlGҎ`3@t[lRr} cÙ99ߜSͺŹv7`Yo% YV̟5K&{zA]Wcb…yӆ$`lE07Pz:1P@H.lC`$WSؖef:|>@OokkͲh`}Z12P7{Nw2SNɌ=3 gL۰r .LIJ1W~>>2bL]?K?{4HWIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_closealltabs.png0000664000175000017500000000231012110457565023657 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME=,UIDATX[lTU}>sﴅBD DQHkj F LLH"(Ax0RQ {2N;3salg dd%>k0p3&-lA$Vvuy1u&艎UbrXP<[r`ݳO%eV<5 MrXw a6~}x~sY+%tlmut8+K_ ۵@ݔ W0U5)ľCphc1!b& G/Y@R .@)%:XZڸX`Ŀa)J@Ť xUo1O>]%}ԟ?ja=%4!i2wdѵ;-)Ko="9si*p$/>!u+MR^E`|}Ħ&Ϩ^+W~(3oB>GSlXh;ʌ/0m[d9 L̴7=6TuK jchp]'!㽰pH==X>_&[dQ;H|E ,8f*i^k0ףrlSC[C{)=]pLfD)Ii#|CLhܿ@ s^8{5К < \i_Ia/a^䯎'0AUg0LDd ٱH:AL/`Tbt$rܨ:Ȉ3 s&7B`IEodh=BpD>Ta)m47`e~z"G@u`hщ;ñ5XƒaI,)J!'OxM@!h@o;28T;y ayX~emn .(Iyb^}Մ'*9݌zR]o9# ^nPD 1ϔo&,Čig^ByMo 9 EjIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rightopendrives.png0000664000175000017500000001021412467744673024443 0ustar alexxalexxPNG  IHDR szz pHYs  tIME # K+IDATX  K4 < KkH:-.z&"~<           *)'&>MV)**@MW))'XbDbk!\6 <tN=- 1z&  ~<      *)'&>MVL&.5¹584D,Vк:# l <sM=- 0z& ~<  *Ǿ:;4DAJO(888DMP 898 JNO~K@D^; Sv Sv5w85 ō;5 Zg .@ Sv "$&DCC* --0  }x"ϒ"'Y  K   Hq+0 ak#vIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_confighotkeys.png0000664000175000017500000001023613017451256024067 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 5`+IDATX  ht}:4:?rҫ` 'Qn֮MHQY " Q:   1daR (hciL6g\~f֯Q %: V8IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_networkdisconnect.png0000664000175000017500000000346312451473236024765 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  ~RIDATXGWyLWfDԊPV`9@!T0j54m&=x&6V)56X "tKTvewfg7k]Ӿy|oPCV5O$[a@cW,\l^ݞUw\>?ql CC+G|=^pW<*;'%YD<xu-XWڴI@?l%舞څ/p|0+:'Ueb|[|ȏ5^e2lP~2`'뫸m*;R G8|)[w @aDA=Z${Sɺ+v>+< ̉(j_BB}S| ƽҧGC@Ed\UeYO/n9`hcCՓNɘHO|;/ꔯ9 P2a%'ʞ:S* B&Po/>ATP >WK~a|2\ٰ9+O;4!!ӧOf)(a}z' Z;v3)a?:)xQ[F𔦎xzY݁@e"c)cFb5x OBzT.,1gJrYYo uWPrMMϭ(C^ 2}΁7ͨ*%?[E0V+:F˜ (v*\L)rYŰp^6|Fy\T @wٷ uUm ;",N 0Lr&)*VaoK=>|#9Ȫ)+/7I >`Ġ0x`2#3+ߜ :t#gWH"l)7Tg Ll1}' 𸞞gGPӒWΞEGYzyI˺pkd;W ޓ=f8Xt!x@ٹrԿw pJd! ⶓqCۛmbgxl]AmTR9!2CniXâTgu0RM7S{ ixZrVKEZs΁k^[ncaXX g 6|֨5Tܳj&p7?;p@Jpҧ뾂y X~jͭǚZZ*HM q/˭IjIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_delete.png0000664000175000017500000000246712451473236022467 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxڬWklUv-mVABR%`*bDS H h!1BVM!!Ll1ĶZˣЖ햾wwfɳӔnn]v(Nف;qtœjSW@|(L*K+:&*. r]NhsǞt HL9DE"y/eљE =>V<1lp4l,ʭ=}}.rH99A&Yc5%`DE1&1úO$EN8|ДTCM< pZ{st }#SqX1-_3oZKneY02JD$fE )C4@;sX0<$l k "Mj<9r&`nmm:Z3 (V?\Қ}1'2RN5Go*Fuycjr/]DTOkKȖ$99H$ʯ߇?v]#-^}_~e#ؖ.A+#ٵ?eED䨙`fሸ[tҲ a)Mu\Dםh s6}Xcw-YQ>imĉAtJp$#" 6ZInͪǟ ,߳\6 ̺l ~Mo/Wv*,0?F$d>J@FII$ch*VS1 !l<2;M/zӣ&e&IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_savefavoritetabs.png0000664000175000017500000001021412653160641024557 0ustar alexxalexxPNG  IHDR szz pHYs  tIME /4+IDATX  ?zL T†V=vO iP; RÊ[ eN: : eM:ª  ^3    1a kE7%i9)r*MhwD 3nFB?=h#  !ߛ&G1ڡ!e  UN9  8 ӣ{uɇ-w *iE *Px7yӉ79;ߚ8*+ ( E1Ed^> J:d !3Zݿ+˺ `<݅eF          eD޵ & &ݵeDVV17ym'K 7ym9chl958%%68a    A   A      N*n]֒5'# Nf}JoLmgڿ)h&AS>V/ */ '3 IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_nexttab.png0000664000175000017500000000177112110457565022666 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxW]HSa~smndPa aEXADuMMAFWQ%h%eY)TdTVhYm([gȟU{OsnHC}c||t݀TF!~;LFJe$dcŜR>AKTV1!Xd::mR%IcQ*tA JgCYVoF]9=<X ?,)Zml䖥V6r̰~]K$"gДwC R#2)շwD- ;QM7^c^n._$ Eے5tA7L/ W/nFKSsSauD}GB ߒwX="4;Y`e9#1[[EKם^|GfqqR$G[LZEZy-W yoZk̢)4qR9=P  G23a#mrťL(\4l ` {?-@KCF(IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_settaboptionpathresets.png0000664000175000017500000000332112110457565026030 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME^IDATX}pTswl$ D1H`A#Vvp1Sf[Ni(5 8chRJ "`[CiB@ Mv~q7]ʌu;ss?}>+R|Ɨ}+2~ XwR7pU" 3<2nARND!7JNne>.orzW ؁  xi$w k FkWDپ _ Q맥R4ߋ ('.H#cd q=bw86s1ǐacOj:ޯQ3s2hK}eMI (%0 im]|v۲DG[ L˽|\kWN L )h s] Ý~ݠOo3:z':}6. rɂrggC:aYN0$`fؽTIB@9Ri=E5n"#,n*$80@7H֡xѳhG?^SH!tBhwKkӴq,'vcFlVigϼ ƺQ#df_g/:k z?ʟ[aOm+@Pg<߹]z82[ؑ0mś8t?#}Lُ¾^>M;<`5U=,VH˶҈. |fdʓl3L%XͫP-8r 4 2fMg# iG! DFz]hi=PmE 4eB]RwW\֤7x8hh4/#S&,b_Zwb9[L[Mӑd}Yl[&8 W7-VP(e k6^{6"˂ǗcTז>V a 'ywc]Ď'勛׹`ą{Ag'R-BO]IԐ!+U`ŚR ;(-ZVlh}m iӮ0)ZkOnvԡ Tq6}Zܳ;9T\V .R?b|J_j'IKןgqtizLiX˅ ƕs1-P@~_t|5 |.פU>{8 ĂD8:x$j`"!^WXwK {/hUwBIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_transferleft.png0000664000175000017500000000224612451473236023717 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<HIDATxW[lUefvEjфhܾ^0`4zAEI ^4!h 苉Fvnw{sr90c `$.;0f-2 .:B[<e-lik:[@Jl pR0,Kn ˯im[̢j $mJ# c=" A2 8}~-mfQo RD|ƙcȂiꅡ4-#pJtsʀde8hǢQҘ0 ktrFiC|ll2$M$\)H'0dZ(z')']{a܃'w57><:u Բ˧CJ !hF&Մ.߇e=5[TnQmN\)ى6="Co|{ng"rn{׈Ɗ6^jQS*ik{"%/i(18z ٿ1>YU{,^l?8pd?}n;Mk'!9M}Ǐ-E/fsw@q|{|YOIq,dmڤ4i513+Qcf~ԶhDMjx_Ia&k7-`1 H|&w{+dgIIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_contextmenu.png0000664000175000017500000000256212451473236023572 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxڼWOUݙ/qⶀh %jI+6> AL47Hϴ (B%6|-E؏;{Yr3;;wwff,4ACM`PGO)A 2|ˏOjKp; ?b7ܓ$T5$^Q3͠nᡇ<״Rs\s@&J#Ѝ YwB(Ș$JϿZ[H"N?xWAփ:AŦHZ3$ (8P&y V```.%T2_Y&t K3/x3? Bii pE{ޘttUr %ox9rM皤A.䐵a[ c)oA^OVP]S{8mx Kb+ pxCy҆!/be8s@bcΠEK 1|GGGrB!IHzX~{981^0mV]^*g7d4HcyqhDȱU{G9?[ ȿmW"^|hni)H4êkW\v".t / &oǬԤxp-խԿ-\$P| CßFwyׅ0=5KWP$h X__ n ByǙNDϵԶ $`dD%Bb}*~T4@ԝs|>,DFkttmwaJuK/ ŋ\.]Yc^v惡Pve9:^j<2r*RRYw8VnUr7n,蠆E8uwosqmQN.U!8 -Źs*5 [LJ.LhllL]]]2u.$:sDՋs:⛎=\ؠeehkk<@gg$&Yj͏<9]'h ]eD"d@ @umL&3AaiʤgS#K"ҵ<9s&g,ԑ9==cqyO-tk&"M2>%U=yoÞܷ2(:N/t = g\NG@T&jO`_?I}!H&sV(iMe#zm |#M%xXo!IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_dirhotlist.png0000664000175000017500000000277112110457565023407 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxW[lU7{.b/hEI BLHD@|1F10h|ME_| &&DL0@ !h+(WKvwn2snip?;s4M<ȴ ߾tDn͢˘vΝ4L8_{ږ5 0U\6l|>yWt~? wAO%qu1Xi4+`8c:{Za*Ns91 T{~?Y{gk1#-  2@g'+"!j%YdbZJVL<ϐuJ}0'O8L5yYwၻB@3 @?)* ZɊ2Oŀ/ 9p ȤRxPAcP9H߽/E qfTbH |$hZт1s>8Ԋfn .pjb*kZ敭ܔI2M\P_ŏ 8CГq`61$dRbN/@(K:'dRiP5DAԶSDG E9ͭ&)޵F@x~.BXja{A1ff2Yyz5_GZ1)hlldNI*\ՋOoCY MrdF"geWƇt AaP DiY&0Q ӢWPP bSC7eODkmGVETRiN${j}Mfeu@0q>e@䶙RYH_YVJd{|sEǵa GfYLEknΡߤ;1v8"CޮF}#NzzZCUsh_/z7R:%W9mBMe wtWM4D}hysG™aDB(o߉kR~ jRJ \Ͽ|SZCl1<"y`:!!z}l~VI@p?Yt8L{w8U?.r{.> Oݡ(IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_changedirtoparent.png0000664000175000017500000000243112451473236024715 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 42IDATXGWkU>fhKR!XETԇoCPw|ZHEEɃFiЦ-nM4ٝ;33l:Cܝs9;?o18m+^oDQZB}; rC~Ɵ{C!{p~ (u j=elo6"[Cũ'u_"GQG`mMJ^I=>ɂ(}E+`p,V~1!{y4o4oiJR+ + "kS:xm/?9"΃I !I(Q39.TrUY;? gGK6QHyuuRiMR0~K>R$  acw%S\`3V^ ):ÎKg]7BPQx9{F:~J"@(jXH,$K\i#AdbrCa6 P@m(H_Wܼ%cϿ3a? !BK_0{$0[Y C^\O}B듲0r}-O>~#[x"g @d=xL.Č &'_@tXJ.9Ó v`k@ ;`aSd d]&%XNJ-IGe {@ :"@=OErߔklHѣ3O:_ȯ %~9.b\ Eػ uxn2āU.},eDf;,[+u`V6_WGdafFimaza7dbeEZپ 9j!9MN0TMʹǾc ,/Iy\x8.Дwb bLn3o/;6q"ED H bT$,޼"(xl)۶pB pv '(b\ a(`5f0Ʋ=,:e޾B^.јvpQ]N]847+0Lg5 +.7+.7}<ghk---bb`F5o  <'85+qIHIq@uS2TiFtgJgdR-"D0#0#D=-uH%5!~&/2qGK4 .%$2$=,B0 3 IS+ (W =:r7- +K#mwk C7 vj,B5& i9#<B&P 2CK٨N.x \C,i8F7+Z,@0!??( ! R +'" UۙcpĿ$$%n///I 2 7_o,0 5:#\] w8O@×%t۬6Xn2+SV Y{jIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_taboptions.png0000664000175000017500000000231112110457565023372 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME38DVIDATX[lUK۴-]X h݂R .HbpqmCK4CLT(ź-)bR4]. )bx$prN2̜HBC]Jp;VVEO)C3Qeu8vR}\7ttuNpپ,_@o׮HS|.J>WTe 5r:abu[彖̒c)eт:c;% \I&!2gNapE%ھ8iM C:эi f(K DPῇG<~*@؎@ͷTz}>gVq_eM,n>ZдO'A@ LmB>DQN?Lov]s8UWWjU®倩N XT B PZZV b!pbNzIdsޯy~X,oг^o>ߏn$1YphׇeO7<&LY>,w,ɲ~)ԐtOp 30hj@byt(esY(;54B$)iT" 8p?\T"igBG1i<6C[n-C"j@Ku˭6ŀG4˩$IjTk?2k/[ЁM!.Mv\pZ)+\ !tXGTh_9#IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_executescript.png0000664000175000017500000001023613016461404024075 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME -Y2+IDATX  |vUT{oRLjj@N'z sd6cd2[Z/  G DM)  [Z/cE&9:JL&榆eҾ`4Z]0]_2[]- C$^^0ZZ-27Z,)ŭ7 ##ss:...1(* 43   *JJ%   66  ##`12  C5x¾EFN%b: 38%%  -:5Q ߭y2=D!'' 88 A -sW E  S]/m3! Qߞ1FR)%'   FR)'-ú .5:0 "`yQq$$6\jҫ  2 nя?n",J75޳IKJrŢAM+W.޹&VtߺKq5b% #+ 883h޺bьͺwj&; ܸx٤   x*1i۳vڠg'~ڳrW ˋ3vΎ5E/V! k'8냧l( t;yQ6% H;yMH3qpIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_configfavoritetabs.png0000664000175000017500000001021412653160641025066 0ustar alexxalexxPNG  IHDR szz pHYs  tIME ) +IDATX  ?zL T†V=vO iP; RÊ[ eN: : eM:ª  ^3    ý?C8C33$3333molBIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_checksumverify.png0000664000175000017500000000366112110457565024250 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME!43g$r>IDATXŗ{P]eHmZt3uH'&@6b'"7VM h05Z;IlufѦ$ê˲^L3|;9y}Rړ~BPPX)% IEQR౵!ZPX\!H+s-^Wק(*$/'|.H[G0Kx8soC:a\X B 4CF@QEQ4~<!Pe@#PBU L֫Wi7fåKPUuH) }+\9ٙ-h`ۙʕy-W<7CǮ\_hnٿU^$NVm PKaT,4>sذ L&_vv%EE_Qqk>@@h^ V&yOs̙3q\? 0fmh}E BP`s)6Nd1_Ckƌw$>~*N`yB 7κAo=߻}6UQCppOIַ:rWuZGWܱ\gfVߙ[eigiEGWрQJI [m=GEOeYaE5ٷ LsüB䗎5܊,"+OR>~Pl޶{ȥ-|V{7E)d8JU.@߼Bz:sMԙv*atyܔ !RKJddҸ8 <w1_i|#%o$s>o߬I? ڌ &\MLLfquݬG7\#Qؗy!p5`;.۹;i:Nikk[5x<+ O%.+r ! e;o%$$qӃhd2 |i bhUM{W4VN/Y(b~*:䆇 x--`yL AS5yL dMVAw^UUq:ݬކGlk#4<U6xCCؾi1:stơbEQ1 4ch4dhX|=EZ^žJ'/ʉfmޚZjk/aԔK-n--|>חPIǘA[[ee ɔ !B 0 B; -dzX MhЬҎPM4dwu^ݲwD#jjmIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_leftsortbyext.png0000664000175000017500000001021412467744673024145 0ustar alexxalexxPNG  IHDR szz pHYs  tIME /".u+IDATX  f#Eh /ݻ}!Cf(/mD(/!Cf!Cf* 1@+lޒ@+l* 1!Cf!Be*!19'Zߔߔ9'Z*!1!Cf(Or+$22 F2 F+#1"Cf+Qs).4.4/&1%Ek (`(` ,ҫ` 'Qn֮M "   \~f֯Q hDIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_srcopendrives.png0000664000175000017500000000333312467744673024121 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<}IDATxڴW[lU]g@޶!DMT%&~ Â"C#F!HbF&ÆZ,{>grKK&t}g̜}{uք}ia@a;SlX7n"K> %3n71L0[cd B 1} ~N@!zKS0sqOb4mC2ad]ә-Il|%lnE0#t6@ɤ*8P:n۲P*#c;BHi_ە)ܽŮk4dGz븵[R%It-=Ǻ!dHJaWF=c3)!=&"`ӳӊQ]!! 5 >?1G |!f>Y`J$:94DiرF"@(= &=zsX&,/ҊDi?ZǞQ"o #"fA't|9 3Rhu˯g꙯]dpHg^S FO@&ZEf{w(&K~WJEA݈BbrT뚩 +(>Pk 0%jSxR0ؓ)cKy4#l _U*r ٩޶F*-
    w|%Bv /]%+!+nGHlm9<#EE3f iIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_markcurrentnameext.png0000664000175000017500000001023613016463506025132 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME  ̌+IDATX  ԃ`ՅhՅhԃ`ӂ_߆Xɍ ݈ɍX߆ӂ_ֆhW߶(hBjB'߶WֆhU6  .R:kR1].'o2]ޱQ:k.R  ,9$^; hA /,9 t  $?rF d= u #? tz(I`  r(HzP 1vZxZ 1E}-|Y%C |(B-|ZjS  pn %c*H(%?b.}]ꙻt"M %e 1Pт/<$&/fV ' 1^ Ҥ  #  꾚b  % : ,* #&   a  %( #E?     3DCߥ    M 6J :K佩 ediA'/,   ")ވ9J ! .)6ij:$ ܇)3+%, vI49"x$ԃ +*2 %/ք~`c5=yN0;Qπsi&;$ =Fk ޴T |rlS/ssMۉ55sWa&yp#k7֒nZr5sV2v4TB$Ri:ۈDyƩHnHIc<*\ͦ˨?kN4PVrsbw ّP`zvJf\O#q P^pLzb8M1kL c_p??dbA5+(/P);ާR}(f=?a<,S' DB&ee5$ٷ ]p?tK,uGIԠ7o36tMǃO1)>iB](JBã0C7h^M=* ndŋp'?`y{k+] b !me`8h8(O\VQԵqy_ugQ1;7M珬N7 EKK0tںMض8{;ؖ s`T&-AQiJ aįY}4ikm⭯0|**gZa g`"cij=R=,Y/\=C<3CV8 nm g2)/4My+jU8{<'ES,̒(:.Є| R_NPvXqΪE%[(/v=ř:db8[:x-\{J@Hߍzh3|o:ڠWpIZv6i:Ґ1;Ҽϵ,.FtJF: hG@A#yR <@! |󲾪c8 4*.r!*TY6@?FC?a@( 7ɓ-xR#FNp+ʉ{8Mo?6IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_countdircontent.png0000664000175000017500000000255512110457565024444 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxWnE=Ɍc`(BqA$ ,Y!YBql 1 $~pȃ(=X.wDR~Tߺ=un0I6A~Wcqr'wn(w50*ALex@$\pS~kwc[_g#5U,\7Z=u.'yVȫ3x{ᐇC3`" ;_!\X+oq t`$)U3yz.s&{H[@g:" I6uY A)l={{,n]2ΖS4)$ cH8&.\IEs}ȥUߧ$ ك ?9. NbZ/.FSSmRF3fq@$ d:Lt1ν |w$L-ȉЋϒMM?J D aN/G'U`> 38t<80hQhe>%?(Xӎ>ĔfW`Sj=쫨50[ox %r*m!+$.|g% 20@^g6H`_ u"97|PA3v~.\ÇsV!qz~ #aXLN&pejBtwBDq- n C uP{N 6~FHvw1GR_A(("sߝ{ט<#H>ө~C8DTqҡ3#gHd;WBMzX LB E$z]P0e|q' ]ss8VJC$4qX^ %HƴKy XV4 @B+vHBJ|]<4A:ſ<(i) YMBGIN)+YHR"˜IEK/QED$$%/4H pfq%߳g.\5fb$'8T9 #q<ҙlaLuO“,m~w<9b9 HhJx{ ٟG8`WBU8D/BJAJxp{I!+UlY!0GʧG*,CFGTez-ݧ7 lk$Q >Thvf }5zw~::eK;= oIeYoL׳InyCP84K(8~A̐T<p̣!4=F Е6xZ5< @c*=4m(zKX1F34/Uԕ8iH1zFж8jM@J@Qmk*wEGϒbyqy?8/4k.'x=>o51h|NY"!''6,^V;m&ѐy[3O?KH'W,2o5Ϫ$ &!;bCI@VFv2 ΄+se@zNV 3jr1rY˽71SYH˕yKhiqh-!K8PPC{ 1WZtP[B-\V{l6[oZ5,Z %.$]%47%EiyCuEc ld}UV:Z0D$$IOas0L8y -Y֋ND<\anlm 1{C@"KOE GJ_PP`&eӉKǑWd;dTmQz;? IH2H 3a@":pĈ(FVS.YVn|ӳV]= $HDhs{Z$>IM{0㮔 ˁvc,.LX!|[Bn!9#(f'bX|;ˀ,gD:OLF۔l,׬=/ qcckK)ɻD^F(wAZfƑIy n[zU>\I_Y,9FKE0r0!Hx@- p@vtod޺\)Œ X #Xi5P[Em/::!'90eaYy# ; *,4R+6e|T%#hs\y{߶[ѻTӄg[O2YDnvhaNCAY9؉;.nGvnֿ,_N)&Hd*\Ɇ"cg7#ٿF($RNmaOr&7ɴ4Z%Vo `MY#%~Lq tPZXW`9Q4eBJ.&3E-dE럴=\$䠍'GԹ >Ʀ1XB~ܓ|>끐cC腵HRy#N1Jsh1"Bn~KMo^Hh\ǞdEH&3y#,}~e$-jOGʟ,.FQ>r~I@YE98 3N zC86~ oy *u M*^']%iA٘K69!I S&lL:\@ ܼ9f;C1'ߋ]Z֞ vS'n7r'xG}c48y]|Gs`~4Q33#e0TpfUa%MHSܤRLb@kYXdd:>#N ==IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_saveselectiontofile.png0000664000175000017500000000445312110457565025270 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME ;/>IDATXŗyǿ;3;̱3{RvXPDPRBX&5HV-6J&E$mrE`ًeٹvwyǎt]ƤOZ@o?iFkΝOW&>SnZնAQ B xƋw󹁳֓6f nKuz\9Y"0#Y?j 1t&/5J0fKz_UrL/)˛3;_<4.Ve%~#3ԃ#^ZM2%nݒݲx!w (Bj|?UUW ݍ8p݋dRnnV??2C fCswfoP[!9Z@Z_goӤ\X'V-<8t @|ÐMw`;0'bڴJ3 w( 7/\ ؂LхtK5(%gsм f KqhL*ҮW;KW_6qk^!"{U3z`u 9ܫrO%_[ָ$d[rw* @U֚kk^]. d CW1{MG %P0C|SS's~3Uf_$NQj 7!j.58GP[:K9a]AU>H#Zd1Ws` \xt&9tB(@(d?UP5 JR8)*@> [yCQ `.1J&a 7w%0z_Br+ P@\Ĥ*B8 "0mS.Ux`-tW]L|#]u 7@o"KrLG.,S=t(ʗ䦲L6)+!I%lн5ƺ/_jΎkl5{||wBk7aGw~GdF 3 セ]d3F_FKAC (8x SuZ;ZX{,N63@SV>bt%H_ _vUI&PñdRO?ߺlXefg!.vC B cŲq_)z6 [ЪU,dmܞ; {#sÍUH @))l[`W6Pb"8lہșK9 x//(nph7hIםd4@tUx{γ/mWa()}tW)ّRcX=9 oMPix#RE1E'D:|iL|?_Q mE~wZ]=k )33+1B4 ] 8x>&2% G~0q8Mm;;6\ghu[=z;=V3x$G؜F!!(]gun0zJ(MOt4/ēŚ&5Z z 0sV^&(L! 3zQPJ?∄pOms|[fBSTAf2|^!\P$@SVT4F!SGA'3A("U*!1J/ ~?6Z\c,kŠ2ƭW\ pV G0a.--IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_pastefromclipboard.png0000664000175000017500000000333212451473236025075 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME gIDATXGWklU.%}B " *JEQH!D&j$!Gh" $(hXb6 .-}iyv_;3۝޹|qHPYY%$$Ii,[S3p:pw% XȨ)6455-Gz0%ڣX7k BQ.S3u?Ey:Ȋ"H7o$T!&G=7ZL,1arkaÊa 48~68alX%+@+Oڹy1K d: *'"-H"#;~!K/Rt݋#0 " L@DĉejTD bh[?E"=fR YY!t:I0YI2rec-aғy)o{:U3 bU&=d+#T?,QH__xMIwÀH-3Yҵph{^t\!}L8P]_9a6]d-6ZűqrN+b7((3P7w_4 na]KS(nÝ,kj:P)䙁\Ea$+g9ZQ<0@$_U*GLPÇ,12^ft!H?cUE (0 JBQi5,1^goc׏ xrj6'UlA8PgӳWFI]\ܭ-@Y2 ;s MƤ^32jSr}wF{ĊB$=&!U R1;{%5+&aRJq'M+O 輚BM{.(T [OI<^MHl]9:i?drd,du;ނKb_tvxvj &oJd$rǢ]؅NF_"T*{7T ܩ*C'`;NX]P9dF뙓)d|`'upF>eɩMA02f]A_@9hP 'NP2@8!fT1^ު'~znobdwPusFD"2 HBn¾$u]sO9 mSI;Mޟǧ7%K'ܯu/)PeTQRD 3Z> +󳶀oI|Q툹r,-CAZ2 M%WQ T L֟6h=qsE<>VE+}X2kpy%p:pO3{nfN0N+IB?ZrL8ClJ6mﰫdC)]I @ GLwh F͐þo !=/L(|X {!)=f=-mYVJp"ciӴo獭g{NmˈQ"|3+JKVIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_leftsortbysize.png0000664000175000017500000001021412467744673024317 0ustar alexxalexxPNG  IHDR szz pHYs  tIME 06:+IDATX  f#Eh /ݻ}!Cf(/mD(/!Cf>Af!Cf* 1@+l$YՔ߽|N'!Be*!19'Zߔߔ9'Z*!1!CfN&(Or+$22 F2 F+#1"Cfs1C ii+Qs& )44ۻp))G (`(` ,!Oҫ` 'Qn֮My= "  MM  az[fGi!8_=!"a13)B=^^OI[A,\~f֯Q (+YoIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_viewhistorynext.png0000664000175000017500000000233312451473236024510 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<}IDATxW]hU;;&lڀTTl-Bj y}o"*}iER/6`jHMqmlܙɒlDFp2;n9 Rb# H+45+lЅT:R=FUG!!apP/Xw9#$ؾ^tguըDW7k&b^jQӀLN" L*Ȭ혶G0Lf& BM@?Ek"!c@t [G`d)N?DIjL 8X[SW/@@AP(qA lviyOBӰw?k7z҉`3^L@27NcG$F<%vn=Dq9z}@prwƜǵ_/l2>h! 6};8=K =aV*!)\ߚ[[;TIEP %%ǡY˞"Ő_UIE NEa u?+봕 'ñO/B#YIkX un(1&dp+6G! NG`__n< \32~1; 5R Ǽ)pN :}i>\ڳxB HQw~7_x /4\ P ]t M:#4qvQHOX8S$ЀJ>ubvijᨭoΗU{ݻ7HhhiGt#4mvha/\sjF2ܙP@jt(3'}B ed`rf SSzhM!Ut7آQvڱbNne+^yhpNHo7j~;|=N݈;#2+*kgMg6b_i-Yl^-UzX͊IEŤ{WDS{n%ErY-%vF6cIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_leftbriefview.png0000664000175000017500000001021412467744673024064 0ustar alexxalexxPNG  IHDR szz pHYs  tIME 2+IDATX  fh Bj - 4~JP -P. >M|K K     &&fT++, }}nmCBAyynmonkmlj]^1/.01xynmCBAyynmonkssp  !  !`a76667 uunmCBAyynmonk{zv]^1/.01xynmCBAyynmonk~sIP-fe {LlmnmCBAyynmonkkPQ]^{LCBAyynmonkff |LknI+)P'oŜIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_flatview.png0000664000175000017500000000335012451473236023036 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME uIDATXGW{LSWRJyd_Nf6dC 4sdY8qA|$?8b03 esA`JB}Җ>K>9wsǯpV& s6Y z압U;iOMGJ]zzfØ-C9sc5C ֆjaʼq?te}uӋLN{* 089dY>nNN rSj)a;_3mKJW3; Ӳ(u<INqXx]囁dg)J%qz}ԡEqxOMl4Je"d APzr1l~zz8FKt5gr,N|'ڧr|4iv_#O+kٍ7µ Yyq&!046㕖=MDO !6Q엎J.ڥ6<}`N+*c?4wm28G etoLIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_wipe.png0000664000175000017500000000400112451473236022153 0ustar alexxalexxPNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<IDATXW[]Wuۗ9sfN3$M&Ѧ R-xy*} R+} ->ւh*AHiSۦA3Ld.͙9s}u߇ 3әPeֿBmx(C"Rʙo;;o#PJFU`l?z0"fF3_Ms "h`fcŶ&{{ z\ Q k-fggeٶ"yFFF+O;gxZ<=6&8w=}m ODӹ:Nf_wn?8F[crC6^g]f.v3ϝnx:[ND@s։{vt>'_..1sFM(X9!7=|= 3;rFIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_newtab.png0000664000175000017500000000216412110457565022476 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxWkhUf繻6oSLڂQACX4CP(?jEB1j(DUִ>HiUB)M7Itl=ܙ6ƅ s=={3 rpLBtt5AV/V.ƿ`$p<-ێXo6%߷mj@U¬x}Q[-^6 a;];q]pow̉NPO;E"Lv݀p_pɰp*g^n0pїZ 0cSI'!uS?(+α+̜F'mg?=۳m*Kkv'J]h\hbjs xx5ZW3v Rݏ<6Cxdqڼ6tZJs\?O10V7B06 r)9K0e.W/+'# 63F]\)aiC+Nef{Jge55z蓑%Y2TdR'w{Kkė؏x= w͸'c@p0:EPEĚy!yshk%R)~⠥h{f7,dNJe۱>'&wR W *dL% T C6A畫VfYŠ;hɤLgG[XV>ێβeh[iG, D>T iOƑIp?JF$jz?mf[g$7hcg>n؎XX XLXhz e[ $~/DIۭ$_D(! DXdJ?=ۙgL1sodJBR -شWLB3IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_changedir.png0000664000175000017500000000261712617337032023143 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<1IDATxW[lTU]>f-5! !-j &~QlCSqJ[ i; Ncf}νw3 {^{Sf&h*W?}U4 z51Iŷs+ n|ÛGX:d9`ʸk[~SGxN㽇ٶ>twC͡듧hd^#=%i`J.zSi1u6mۂE%8 0^ɀx;nu־K_89.qB4J Ĵ7;u#AvJ:Ә 3H5QI.pwL~z-%Eb@x;B1<1!`+h, JlzC23!e1qofuTm"~ra@.*Gd*~\JzKĀ$B iC%TT@ca`Mf!iRݺL P&!hsxbXb Z$ AyAHKV!:tߜ✒ 1 +ܻ"2m5S!)X5WB?⹟b@} ӻOUy7_MNg =4iQlldNN@e=Nv ,89K)lr վ6:k^ks?~Lb/b[5!Y'w&/pfzFN`{m\jCh8{»sħr͡}%t'->0؂gSX3^yr^=֟^M6%_6Qy5 R9mJ\pę$6r*xu۽ukoڻ}M\\/--Ǥz|= dw|jnģTEvxUyR+-a $Ret,>t"~Ny`8.CiFWRc)*P77ݻ(}y?4>Վ5frmi/ LM7}p3^ƱNS(.D}%tWjMཌྷIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_quickfilter.png0000664000175000017500000000553012451473236023541 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<"iTXtXML:com.adobe.xmp wVIDATxڜW pTk7fC‚<@A^ili;cvƩ6lˌڱNf΀ia:-2eZ0@i;IL(!%l !!n{n b69LoƝgK!K|(T07zC72pye}nT10y |>d0ii݄/H?1#) K`, lU2Spz>q_5<.}5!j!©(p8d"C%$SRΟ||)]GU19S;Oe{|DI-\Ǻgނ˩ŕ)"E(LJT=g"ǒPyI+k:X2Ʉ?N͕m%c7 chRH $td&&z"}!a noBR7!CU,;U _%fQ[č $j$/}Cl յ9C#&6Uϵس`wc뮺C(6|Ǟ|xKX<%sbb"$zSlB"wixRFy e89i, Gʚ gOQH=R9m$n,+˷Xg?".6~VU^]S F]Ɲ;q;.]SF\miHdGC3;K+ ®98G?j)߷k)nf= 5#m#|)f6"*m/5Va S!`QpQIEsm}P,ՏT c8ڰ79nr2p<?{R9u)\ E:eU?Wo[1<܏ Q=>3H\Tޏhw8|2Hi@sCk>}*ܯP~{>K!gⵗ$Cd4 偽G$%Y݁ 2g?'7t ҅+k[^?S 9Kvmxr<ځ'Ͼxu(dYpб}<32%^_E{Wp'VXd" 7zG"[Xk $kә2稚 Ҵ8O%6gcʌlg$ IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_fileassoc.png0000664000175000017500000000412312110457565023163 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxڜWpW{y HH)'f؎@vtc:"0REgZB,X[k X524RHHB# 4{ow߹/PmH`dw{w9u> J)`z~nKeuW\3.j"2~}펧vd|߇?}}Y'Pj<GpWaSMhPT;ɂPY0Y&LˆDpazʬu]448Z eVw((q>爘@ $Z"}g |+uN>3񞞼mM.Tp  Bqt~c(|^i02cKwtl9 ϲDai9BșYꑗ"{Fi(>q\+"i{3u 3eY@@ԫ IH dω^uUp$ =^/A˳"r{B5?W~La v1N(P>6n>EdK /?5/`b sXc"BV/:o/"H20(nQ<IJt FǛw<'Ó@.iTݍYJ/ M@¹n[%_A22ƮxQ VCwjACXOzzzC{7|eϏ{&CO*8`SMqyؿozS|E7L娭Y+W`w^ŷax'$cҥ,VX;8|3!=-bhmGnjv#؟_@ 7p[t[~?8΄ƆgV G¶T*\)-WC]YfژHalswq+kCFcS.QR7ƘJFBEsIaͬxmNeIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_switchignorelist.png0000664000175000017500000000273112451473236024620 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME /3qfIDATXGV]lUO?lK[B-[`bBjը(1L OƄ'#VL $b@IQTʏn)-۲.t?vgvf<ζ4!Гٹs{wslIXZEqmY4硤@&\6:E||[k3 4UgO#] Y x)~m:J*IzBg}$( W&'*4pFlV! ;?pl“{e+AcDLT$$#q7z%Xpv6r`1Dž=_<ӴL4rk(gS`S ( -֭iqΐ`)cZkC/-X5F7.躎kރYZ >dZ?ENTBucXŃH$ħGӦP ނUw((eS@6g`*Df`0lMXV#=H< m2uc z~q#%oÎ;rk|===dH]. ' 0s&zKinJuuu>Jfрr-FSS<OP(H_;ENfOODsImj=qYn|*`\oiiO?!;ɯh<=sC}5 C:93xeK?^rJYls~/'_ Fdٜ"+r=6ƎU[pwU}DplݳgOfc=Sq\M~8a26SԞ )ߡoo봥IAg^R\eO?ӷ4DTXlZ\-rzO G;aS7q35:h,a9Ic -RD —N>9d#G&$IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/system-search.png0000664000175000017500000000424711323654424023330 0ustar alexxalexxPNG  IHDR szzsBIT|d^IDATX͖l[ǿNL֩ I[!-AMnLӤ`eBbRX Bۘ6uu"M)LMeWmc;Ѧ4ؑ޹Ws)HD"rԂÇ !_>AضmB{1CGumBP<σR 0d066QrRy#5#GB+ۡ*4MimAE(ۍR! !/b?8|pP 2 .'JvM+죫ܿ>e| Μ9˲ּKeuj5z g;/&J&oOڥ84P5]R]mk~s1<<ݍYĥJ]u_ZoEY8^9^vҪޣH%HWBT6C~EQ011+l``8%X'O~cOL&-JPUb|tx###f5M[0zf!":;;d`0b/ZD", ؊~3R~__O?-}GGSpT*I 2N:d2~ٳ'k׮=o>0P(`6<>S\p}]ןo[\oO*to7ND"ѳqF^EB@A}}=z{{qڵulVFXcǎڴiS]t:!mۆٹhq URttt@$W^|A---n{rxUe(ku]:ugϞ޷~J6E( B,Bjw/bsNStAg]]dI3~.{,}VFqSgzd:zp?c(!EQ&1z GG'YlIwۄ5DՆo-u ] ==iSV*b@ Zuʍ{tU+C X@, D T2q@Fq S^2EFi 53(5mب65ht j)0%n+?c9'd"‚ cAܵN2;&hD,C8 Ye+ 7-(Ao8zN=UB@9`K;Qe%(g, dsN-M>"(ÿA㊞Psg#ۏ?2'Bh:z.tRKRɑ8W l*5}K}A$! yrWbU(D9mF7 ]W<8GAE[`_?T+ƍf#mKjT_8B&NJb~6t1}@5{5;3 w/UUXw߾w-gfS}`1rb`t/xn3(H=Dx2iipN%eKB:c(N1%ivZ'KtlyS\ȉ`emvh1Lu%*;;q`?ތV8ۇ~\c k֝l}jBۈ%7~k~.f~1EÅ=آqAW[?_ߍ'.Vz<'#BJ>JnXMu>yW'Z1ۆ=:D#rF}ۃ7wĝ -[i+alWkyQ }wh͍h[d#QsB3IZ(l:^f);CM{Z;{n]&|ۄ]$~rr縺[hFՌ2BJ"rRsm7 K}v|FI߭:AmK1*ඟfqQ/茛~=M- e1JA̔ IpYkyTt':C=ϟF vʖ<4XO&s dAMY+l;:ٶ߱N=rsvH!IɔN[T}$<tljofogr"m$99@7ǿ e/F@lIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_networkconnect.png0000664000175000017500000000342112451473236024257 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  UmIDATXGWiLTW>͌VAB&" b1*EMI?-66QhjXMڤ4hBF "b2 o9ofd ;{w9=9RpqlYճFc Kbu)B~Ϛ ,6& Ce1o}aU2 Ȇiw|siA2ܾ8~۳i24LEde CZGIɎSj]VxE .T5$)@ؼQzh4 r .0PDžڃehs@ND6נwȑ#mJ $QѯiHaדYŀу`K@91p}Jt% #{ nqG̱ީ@`z#Abdiדra;*D &̄ 2U\^P; ؕ :0(k"aizG>&L7-F,\||& In#h-KOg}AAtwz ( 2/H 9 #Q%>s\ب0AmV fCMŀ^#ilm=7B PZBٵJv*hx|اyY?ZiZ& #uց0\|#xBR %fC [bSnjH]ֿcxdn^B>n1wXk(W_c#a˒翳jG1Uy۷XU_H- Δ^Eo΄ӥWaѼAz`wYD. ϻ1 -0ٿ٧؉[?BҙF|P"^Wz44}Zr3ހ"1X/ȃVèo] cCِKv-]j@кG-Ll3=rs0,"e E |cVsҚ]D?"9l 1Csx le` &b\ x@{Q*G [L=eg/ͦOMmvjPF~cu߾-z}-?iP(QˈFfTxҎ {V}*n]랜/8m dfU߿f(IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_copyalltabstoopposite.png0000664000175000017500000001023612656270711025661 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME$1S+IDATX  ILLICEECCXedV<"#1$seyHQzC,Ǩ[9X='=g,zv%zNy3DqIe. $G9%=(" ex4ͼx4kHTڬy4*M(*zL3 ֳ1"Tx43KG 9kE]a9k GK3͵t4{bǗǗ﨧@?zL T†V=vO iP; iP; iP; RÊ[ @kT> kT> kT> 8 K              !5g0W  iAY]Lc\t 3 X->Y]5SoΘY34qpV0_a=|Y6Z2_37?ǥA~z(P PP1ǍAJBK"g^=ϩ>>,k\%NE&,o?gjز1#@wG9Kǀ?dfN동q1@%k =@X b{gX @_^F`ٷ/_\BZ vhrGfڑ@{Ǿy 791PCh 4pSvۚR5=`Z466)Yw,F>wBC>F-b9(EAzBD7 :"` 0?޾ F=A" 9$Z 0-޾ J>A#"A$ .9)52ۻ^Uj Lr!Fw8N:_T†V/ZH VG8ű=vRÊ[ &D(: eM:ª  ^3  9      G!) V,3%BpIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/go-previous.png0000664000175000017500000000226011416270327023010 0ustar alexxalexxPNG  IHDR szzsBIT|dgIDATXmhU?̊"ôYݩeVكJ SM{^ ^AA7EM0EJEe|u=޻{y۽׭@?tLa FU_้-; NȄ<&V oG޿sK_*S̵%>C- R xRւ0a MP͌Iڊ9KoKlޤoܣu n2 "Ey@|֔@zRTST #bc}+W'網Y$(_|C9A)xAGjC S-m[o$^ZJoD9YY4auXŎF GvUmOO_vSk#Cr~𗀄{4|il5N|he7vnbaͪ?P&uСd$mBR S$Ч>ןv7-q I`H9ybµF{M] /άGp;^>GpMpt2Ab̶.1CŘYttLT6rõu5)cFIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_symlink.png0000664000175000017500000000201312110457565022675 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 4!IDATXŗMk\Usν3I*riicM,"n܈ 7\bJ446i-}EML}̝vn̝|s?#9Dnۈ⢈AEp׀ D]s񏙭rVvvvƍ(9Z>Fu?wO=ɷ뼹3XZzhՁĴ*1f*{{R*xܹQLhҢ`0077ﷶRA %LLP*>MZ4F3@Gwx~EE p({! _Z&ӵ4wSXE;ls>xy1TRx]eNx0 ]npcZ* hW_DApm[)~r`&L$N jx^fTa}\?N3&krC"Zt޷/=IZAh[XQ k{Kwa} jz)>fX-߼ۛT~fTzlb:\1ua#Nbӑsm`XkiӦ;Χw.C#BmZ#hz"0;f%^!B+;~c T_cV?87@qC  9`^CpeIf%IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_copypathoffilestoclip.png0000664000175000017500000001021412451473236025624 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  +C+IDATX  KZZ[Q KRRRL xEK9x# Lj`P KQ\lR]oK (ڲ=&N{,,[ipbd۲kMh` ;65noRk_]]ƀ<,4A,SuNl^ʌ=)8=(+(L r] A);Hjh\ͅ?':7%vVoB[]GoCjlZfYɖk  3UƪP7jP7jʝ9jS' ǫ  )87ҩYSbykZMl&6&ٖ`K}}C %.ֵocS+4 j[ '3D3 (/# "&" (9#)MZ7ʣ\WNd^=Lr $ifڣ qy ?gTA    5D$ ɴu  lh@u;  hG.IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_minimize.png0000664000175000017500000000533012451473236023036 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<"iTXtXML:com.adobe.xmp t]LIDATxڜW lUfXҢ(ᐂr.mQшbP@ @4Ġ(#[-H aQXBKKK^y٥ЦL;덂?ֱK =K4( a%Y97%f73F֪àu{xF*`-8%2Ch"2VUfaET ^\!?}b¤= @/j{,*zO3TW{,4 Y?y N]h5/4!)!hwAоX>|’)T&cBX@bY:aNSL(NqS3Gœ5;/ ɇ@2P#&&\<4lN8YrIp9ctCz="ekyX% hY*CsEVtr^o y$`WHKR=vċ? @Lr(̥lw69kbMZjdXCГi: 4,b(>zMMxoGU*+ Ԅwǖg%8Q#|yuvgF௚f3*0AgRz$=;9',l=u  ٧ze/YX /f " ; Թ UD{ uxbЋ\9I\drә'' Eo-8qEЏl@5$9۬U!VDu6%X[lFeI*t+(yQx݃CzyVզ;";̲/:N\N,KQ# j,瑣uIK˨f0 $<}ªF`e't:O2X4ꀿxQ{+*;x8ܺ?Dd%Rvu^ p;y0q>0SDRͲY&l한E5}ʨ%i=$k/imc[̋~*b+x0wRS2衎, QОdnOT3JG_bW.4! FUиIR^}RDm740RSb  BPɇ 4=?O5 wЎe 8M6[je1tXpoyQ#[V~чvv6BŅ!wej4 :2 /|s=\da%d7C' nR .g`y{ۍ6@73?-ȠW% 9Pu]){Ra}nxO@PXyA¿}g _%8bcN^6i#R@mU"\z`d<.a͌i#SewH—[Ji4!yVdj h}~Ũu>LTҮAHmvj q.w~zhb|kMh72"x5Oͤ9O6[Ƣ bU>nYWnprs!]OF[V(&,ÏeƷa &+\}g5)Bn4HbT'Kz}W݌6EL}%f 0 FIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_configsavesettings.png0000664000175000017500000001023613005157257025121 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME &i+IDATX  ZZZP MMNK --,663663663663875  LJI #""  '(*HFF ''&\\["##CBCHHH   ()+     EDC **)XWU###CCCHGH    ()*    B@@ ,+*QSR#$#DEEHGH   ')*    m//>== /.,MNJkH< G##"CDEFGH3nFB?=h#'()   8 EDDHGG79;  IIHIIHIIH VV1 9chl9YYY>         3z*IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/edit-copy.png0000664000175000017500000000132313110262743022421 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX͗MkAxI~dA=-F'KтxWR-ţjU!I٤K^f<,;􁐙<8h1˅MY54fByv3/j(ES|>O=t%ʩDF5ոaPV%{˫ p`iiIy "%" a0Y"*Y!"OXqBT*AeIe tС( Dsev`px(@&,T),+ L]LjH BSU(HR璂~9BxHZ_H"D0n~$?T), DM c'a)iƘia IbJ{"~{b`{ fPi&"<|iLp4D>.k*q`n9We7;{7  I*c@O{a=?\I ڵJXup1 `6}9Y.W& TD"i҇1!}3?NP]zo.'[F񩤰nߵ1v0擕յiט{VT MIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_addpathandfilenametocmdline.png0000664000175000017500000001023613016313447026701 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 9D5+IDATX  }~;;g:o$g$$ܑ;g;;IPfܑ;g;;fff:::::::ې::ې:f}ffې::f::f}$&,o::uI$&,IPfg%p:::p%gf:f:::::f::ff:ff}}ې:f::f:f::fffff}}}~ȕDWke?_R: ƔlƁK KPR_RmÒ?d7} ~~ W3{ٖlEi&Mng\yfv2& aG(< c_K vqw]Du͛ƀbEGuN8}nK3ek1"[,Rqȃ ~d }oq (,Mt    qjb qib pib  <b9~ {gednlkhfe {9~~ǁ  ! hhIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rightflatview.png0000664000175000017500000001021412467744673024106 0ustar alexxalexxPNG  IHDR szz pHYs  tIME "3+e+IDATX  ܱi (7lf #VjD0fTm<еJD[< =$>֜#{/U@K8|1ཏUX#u[^csg zb&F 3yƂ zUFdoKqas/@RhBbj9<1jKԣJpݝ_/n 7AFSWrY?]W8i1iqs^E/Ӷ9&P? 2ŋHarfqL9B$7 œ=,7K/@Z ¬LUi&@ו۞ ig"@Jeh):FH<6660f0q4da^jee%bJR8I A՜3![RC0Ҭ,*H*Qz䁻[Y2F譌,UM(cNU\.Ag

    e-<R1߶CiX 3/{q}_Z,\:eʏ t{4tM(\=!BE۾on0awvӯzjwj@fPd8V 0odPk@cYpd☼0 ]q %\d?pV`ɫg+ƎN2z<5Lq@(Gy.MOA{Ocsk OD"lE"Pppl|N~ ;K7uLΕݙ`5mzOǻ%" _s#OξYAOFĴq]cPxJ2 (Eߒ{УDFe͌*圊џ/'յ$,"H# 'KsDF|2((2L OQjttq Oq/'5`*FlDzHNH2:BJJQ5)L:Cn|u2'XeH 4يÖ.MʉӘFhp56t"*,ȰrCEQi[CWc().B!d ܧ6 B0XՊmOT OpEu1n*kB'P~9t|0q sw@0\ΎvKmR˥IZ tPtR Mq7/AiS^5=|C-/ijtVŖJb!5e/Ҙ,JW)s4?&~WR7IR ˑ̥+#'_)&tLvp4WqSirabv WQȤ.s_:Vo<3BI3$'H6txF4KQ4`C082Rq(+k%Ate,wJѲGJ,Z@Z-Rz$qȯ^-O9u*7wamؓ‹p<b?-(r8zs~x^G2*! 5еlYg_ݧo/|\~dV[p 8n2]u @jjSSoUF~˨6ǘ*TBy@@ f Bot! !=Fؠ ֺps =Elj^S*t U<k%4rbǴ܀fa 6kYY0 ZT ̨׋swMׯgZmypZk) :׏ Fp.YHgwFww7nwBbB4b4,/o3|&tܴpoI62t$4|=70t222Ӡ6:j?54hfMb{ AًF9.-っÀcUU%Ux{˜eC/6@;86'&A@D"#" rQ=00L؎?W.) NS 8/Dߚ 9 r55y,M{p`d ==]N6Wc)c 0KǼL=;N1o/+ ޽s%P.3@pZpG%tNgMf{N뙙z2F=ӱ0*& 686t o%&'@b@!V-[ {DAJ0۴uOm>V |w:nfk޽{rQ'ƍf(D^G#q8+#pߏ!^ROe=>6kh8-MpHwΤ |_/66{yZ7C3GΞlaQX]gg>w(9~~IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_editnew.png0000664000175000017500000000346012451473236022656 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 1y)d}IDATXGWilTU޼YLt(*DQԠ҅Z D*Lj .7F"F#MiKYA@)@  Pf>sox>[[in{sw-7i(>\j(?l4BO. FcM8 (@4MZrgg;ݐ$ ^Oe׉D>S]}YYYHJLit58 4,h -+WUGcW)(>q)!9 Q= A%*SmOcSiB* s}1-Tb[[+Z]C+$%&X 7!2Y3a0DP^^G{$d @_f.'@Joa3bҗnc9>-E4VAg +0q?˰`Ghiwnxp)/G?]+HO(akF|-],hhsss9)χ--0-`}bsG5pz}Y?)Nس UHW*q$,fr>} dD ;Aɿى*q]B$\'r.͇t]&-*x/n7N7xosP) @?H M>żp>;@ #PՂ۬q #. AGIȟ.\!$<5c%''8\q5ыmS>U>sJ ClL/]#X5744tׇd44kE/>1V2Q\"Q5UXK.&`ay„ Ms +&'WW(RxcolY&@ mDձ]8H=A0SV/$g,>ɍWGO%WAGpp!g':*Ǖ%QR!D9c<7#{6̷b|iN(nnƖC~ T~DX!L8BLb~wLHQ//J?%!.[rvfIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_keyboard.png0000664000175000017500000000225512110457565023017 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<OIDATxW]lU>ݭbSR! ahHO D_J5'MlV5*M /$ ݔZԖ~.֍̙{sw2P1/M+X1PMVEzI1pG"Wvo?s_gl~퇠W<ա3N|uȯ `x`Gオ#!Ah<~@Ϟ~29sRo`(,+j)C!ɰ MX4V7>߲(a篶$ů۔m2;0@3G&'3+pen@z.E s=!QBalIfkU`(3 cSE:;DŽ~KՕkfZ/赐+aHkV/,ȁf[1rO2&ʥdRz`&:MG'-$vC *5l;s}Z4)MIaYE;~/sBPZk(/Ԛ{%ώѓ[kSGh0#?эuvP@D uz,(A7|nhnfO$lBFKilܼ~ >c*'{:n1KbĊ;K}q9A m\GzSs\^oݪi{}7QCU23˷cK6kzƃqפ * ts=XIʳT'tA69UICQ樓݆c"D3 >+Q޾Iv\W'OK@®6%:-mnYL{1w&%N]άfcv'Nx@6d%P2?>KTdx>qO}g_$=׾OA  qx8v*XfՁ< nhg&4:{>Gik##߰c6Hd-}5 QE\fH>rGؗ*? wKM&w(IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_leftequalright.png0000664000175000017500000000262412451473236024240 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<6IDATxWMlE~?vN q#5+MB"U8'Rnp $$@*T h(OQ8 jTSD6"BmBqgޝc'mJRB*/Ϯ}og9z[8OwͲ鳡=18ys,@^ha >Ϋ W#M@k ~v>00k 4軽le!FsJh=Qc ϔ=NZMS ƕԝ 7O G:6Ć@%|W X r]2)[`呉b "887N0Fbf7 swG5Ň'D.&+{$zSc ՁM&`ngTKUW/{ܱ\qQ|ee88Ǚ7s\1)?CH\&xJ\4q A\aaEˎdU" wA=2ù07FxɉO#@=_ QieIqQc vb S ` / Ö qCS͇AxtP}ש'b::yuN3Qh] V9n{pC1n۲,V-MZ>3=/L!Y-rw3{ W/ͬwE0O"*oo\ fbG );*XbF".kdn'XitT`%k֔3<lm\bT,ȼICc= wKI9 `_0:005YIVZ$AiTO-Y'e #\ ,؍_$$wjv+e%-q3 R[) =m<}sLt6.шk;JݙT 3byV.[<\;v¯`iW@ ئWo4 ,'s=H^hBIJsyﵑItL+H0ZtF!إ2VB.fkIgEi@`uf-0T.d\h"|*h6; VCP`r($[l| 'C_qmM\84ihN)klaLׯOIMbCv(-@>R/Ȥ9Ԓٿm˦廟s.Y8#IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rightbriefview.png0000664000175000017500000001021412467744673024247 0ustar alexxalexxPNG  IHDR szz pHYs  tIME "*u+IDATX  fK2 < KL6-n-X-"    >>#%%onk.CBAyynmB@@/.01/.01 onk.CBAyynmEED66676667   !onk.CBAyynmJIG/.01/.01 onk.CBAyynmNLLCCCECCCE((() onk.CBAyynmRQPOfP/.01/.01 onk.CBAyynmuKt {Kff +5fPKHq+0 I3fIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rightsortbyext.png0000664000175000017500000001021412467744673024330 0ustar alexxalexxPNG  IHDR szz pHYs  tIME -f*+IDATX  fFOxTC: QU({UfgC:!QkHHkH:!QCC;"Q`@LL`@;"QCG=%SS6viiS6v=%QEK<$E+W,WթyNfg کf`F/^` I r2BvIggggggő; fne$IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_packfiles.png0000664000175000017500000000411712110457565023157 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME i7 IDATXíklٙ]^;qiA( Q%H Q? Ҥ"4*A'Q(k+ۙ7w_o Ah({zNx)lF.< kr,˷/Qdtl:)}ק@hjN6q-s:z#*k-Z(bӺ57\BYc\g5"kfcB_`|l-kC6/ B6]C%0rk׭ 7RoԎ==oHzϟ< ˡfNZ<wKߍw2S#ǸJ:Bя-NhM/TKm]\z݃y?VOתVu _YKr5DlЛJ)W:lx'aTәogN>vvo;ʥ=(l|ʕ[MV(E?Í?WñJQhxbAv]EE>gJǞt;ϳONv~#pT"&}Fgav'[ׯax|t]{G#oIҔM8s Krȝw0 $XSs:6<1*ab:``M+/8S˜4t_;v-McKqeX uԹ u}Y dՊ,z\7`R4/k ι> 4,dAg(W@̋4^}s_͚ ;}A~ګ4֧y})Vd4q#rgoS|x9ZJ(`)OBi_e3){%6\"4Lcz?[i/23D^׀# ПBD!cq("`jU*>vԷ,>ۊJ7DB;Ѿ^Q Q(z6BL`- k S#G9JnP)2;Q&(c\+A J``nh8I)D J+ѮrDD!J3RJQlTAI͘BB:ᠴ/Dp\32ֺX4XGc# fZ'8P%恨YW ZDE((!Z#Z'>b`Le勉v4jbM%pn 1f9N V%$<<αA ?~/=0V]S_J˫ rqWmVG[+[1DSAB)Gz74﹃zC(Pf>`Aq:2-ۖuP8 8 sp? bezɪZ>!W0iovvyA{=F'.bk?߹T-atIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_configsearches.png0000664000175000017500000001023613017704640024174 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 5 !,+IDATX  wy{wy{ JJI JJI B B <<>hLML>== R<<>hLML>== RnpqMRoprNR Mfke N Need M tuxlnk IuwyhilQodfhIUlnoQKIH I\Iccb  QZ[^UoqtLCA? 998QXY\Q L=;9/..L x WA uS2% D(I0#0#=-tux= $2$=,B0mnk~IC- +ګB,! J$] }\;9,5(74'vV8IDDI B>: @BBUc BU(&>AAE*bU%6ٴ$f9gefg$4eI%B CvVxvݤ.ƁPX+Ǟ|ygԋb!Ag߃ T| zqbS! nVX :_70WV%Nw#lL]}'y*`vv`]6f)Cqe V=K :`&}gR.pgs^@zF2a` vυuau<5sr{d]9WJ^.Ǹv'T{3nL8<`ۆjZ$jCk&)b3˳GyLOL o<.L tBJBk|4mX&>j$G:'NIܡQ0pؕz4* EKF (M@ʠn;\N[L H!qeL"h0BKcP:!|a=2Ts#sTJG8j.Z@ r0${.j4NkN/ `n:}O@>6P x/^_f&`19Ja2#g.@8CVaO`_Ǥ$tu&4i f@Ԍ'YlRJÔj՘ϢmS}LzN61C5=Tr]Hl@a 1?+*gkzuvs"b`ښۅ!87T;0$>цU~Ӹ[7 X2Eyz/SUr/*ELl ŸN8_Loa@/& ?ߗ9xT Qp2\P,h*و +>:lL Nk{8_ dՌ96'BZMNu% 00P:`0x^-Izufɹԩ?X*So;eQ^@DQ"/_p5^89ܳ*|/PzSG,#Asʁyqg{Lծduq')D`RU0 1oDډ־{q쵉PI6Wu $iXQe#ETzn\gIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_viewsearches.png0000664000175000017500000001021413017704640023675 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  (`+IDATX  ' |GV9}  wF ' C C ***vwutvt###$$$<::;<;866<=< SSQ!!$$#`_]LMLMOM/] 33y  ^ $3} TQL "%1F:99ddcU0jih7nnlB&    p`_p5##;tEA@ F(FA@qqnpol***Zg~('# ="}TY$ ) 843<=<RSQ ##"][Y    >=;MOM- D!*,-0& 7aa_,-+RPJR.!4O##!*** 887=7&F  >;:M$#  WWTtsr   :J3 ׮ 4  445ȒB7H1 Bۧ(QF \`6 Eק> P6j n# Ӿ-D0X>mbuw! 2auw  2ZQV4; ;    K꘣nbIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_setalltabsoptiondirsinnewtab.png0000664000175000017500000001023612653160641027214 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME'fs+IDATX  ?zL T†V=vO iP; iP; iP; RÊ[ @kT> kT> kT> 8 K              f'.3 }Gp  /"E2  +/9 *.8 `H.ֳ)N95 ֳ.3:,29|?tK'% |l.Y/%E<7h.ۻ'     1IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_restorefromtray.png0000664000175000017500000000255012110457565024464 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME  aIDATXŗklU>vD% DMI )0%Rc&ATFc5MD` RUnwv-'_vs?3B)p> ,NTԬ#X*k,KEXffEՐ[J_A6bTuXQ=ؽR@_͟@'_ t>k p<VT`0`~Q e3rގ(i991 ~Qhdr0X}i0&%gSZʀJg&r;@тŝէ-Âg 6{rPeĮ4GVAtZLmF$`""¶h[(:!9_hR@V|ǵTka90=1oڏD8 yE#DlZ:Z}և՟Ԥ]v*kl_> R"cXBe[|}]R݇V64Gت' laDe [9+7{@s8RF;Г1UK0wzKn5e8Lw{z/N\[7bEahYaBm-l<:ڃsm .+C&cu? Kw ~EG}ahY7igߛ0bfZ[Z0 鿭#,֓2"1 ]pg : &g(}EK`OxYgsism6AP?` XSc&157>#@ol^]{Pа,t Il8 ?7q<{ Qp+RcL(M̠#p0t:!ۢ%Z1gx\N&y%_04wr 9q򇎡2<9Mn5icҩ5h#0o,C}Iv (T21xUnIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/help-about.png0000664000175000017500000000426713110277137022601 0ustar alexxalexxPNG  IHDR szzsBIT|dnIDATXŗ{pU{snnn޹ G^"D (Luv3:cgӇm+}MhV)vE ZÃ$JBBrܳw8$i359wo}kK^Jn]ّaFCq#6z_qxHCCmh[mO1Y+披Y>AXke<z h·!\(OՌ_"8ap$MǟY^:9|O>[O8ΆXm}UOIX~7i<ۍ4$!R )/Zk,(d-WS:'X_},>V|hSep'{K!Lba`)1 iHCr)dҨ,+Jpɖk['>@.7ܒn=ʞaibYnpmƤIe0${E\[15ˊ3}sCC-L V˛vT2di PQ GnV:}aZ?A(V V$lݛr .^eûGw47߼zÐyL,Ϫٜj'.IIa8]0rM x]meʻm<8Ri;@LO(  3? ,ebY&4ؽ#4pk 4Z6[^],9K'A<s4 [q|?5; s{Mi \|?$!m\ttssʢk-n^[C1N 7I0xy,,ٮA)1KI, ƕ>!ŎhU45d*,$4ncY N"`͒TZs?ek֠¥!*K Z/ gN_n=Wrf*2 NsRJc8 4?2@m<\tkO nhg0iN`%1lO$ Ȝ̴Td7H!RLc8Ջ(PJa6u^1;NoLR 3S-HM( @ χ8I).+I/+82DWedR/G X8/Թ@ "UfRӍJ)"):{yGHy"CݱWt.MhLB<c4⟲ce=)HH5<thMɲX;'5^>֏Ra$va|FC~Ebu47Ԇ /uMuBיS{4VXXұDMV([9SwI۶d>c|?XWN՝pS">1ĄM"amlN=ZSFia.}wl8KMMhN3\ܪ, M=(ZH"kJs&a;>h&a+D%l]]JV`W}%훪7҄j`sH)q[fZ 7.%h` /5շ63 8 fW[FUK .+ 8o(@v'<#a,([+*0>a_k:v=>>gYHx|ƧW~^<ʩ~Z O0# 'K/\8s0?hSw{p_t-D ~Aov;7,~k+W^Qˣւh*AHiSۦA3Ld.͙9s}u߇ 3әPeֿBmx(C"Rʙo;;o#PJFU`l?z0"fF3_Ms "h`fcŶ&{{ z\ Q k-fggeٶ"yFFF+O;gxZ<=6&8w=}m ODӹ:Nf_wn?8F[crC6^g]f.v3ϝnx:[ND@s։{vt>'_..1sFM(X9!7=|= 3;rFIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_changedirtohome.png0000664000175000017500000000347112451473236024361 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxWilUfyKi&T'kX,P 0 $1*?_Fh FEV#.VEѴZ@@Wh>o}}O&]I^{\=_p< x&=]Qca 'z3uX\dXL%ېiEmY=2`Ђ?=?ӻE >8q#l\GI/_s܀A+1Kʲ@fȏpJΘCB@s>*DQKSS_߄p[9%!V#vB3>IJSpbldEOFnFetߐ?47<M!ѓ+nkbVe!nIHǫHGBG㮇lQ8s!acTkOSh Lv<gZ[GŴ<$b>srD%ss'xѓIsUEŤ>&s@Kx<3f A$<`%- h<څœ>}':_25@.BX/`jg'-0 ĎB!T @`t?]" H$Ѓ_ e6$,%JJ`uD{ &`:ϞFg٦X~n0~>WNzv;hy̹fTi]F$*a̩zH]75_ar?&Y^gt,I1)*h"nA.ǣ K  CH|dYaisg"?co:o J4WLpfF2d'ܰ%FBIH&H%SHӐ =0+֭BY}i2+@o* eA̢aY<ʱvRR{Pe2E#SƆmw!R+zٽ 嶕R5(]*Jv,ZCkY;IߠRz7 R#U;RL]DIgvON0|Һv3(8bB(ֆWe)9o#'S|z},޿t[iG"ʊ(-tcTXz WfSXcwL~&`ҪUĀkk#v(A>oj  }&`ʵeڄJqJGC-!= "`bXĵ42e ;ok8kI->ÎhVHfZ -BQuȪJLcBJE> }cśF@~;'"% 4CѤZT45ESޫUu.OQPULBj91߄"+l)󫖞΀bMkeL=PBm+t&܂W=Y!-EbEaeHl)8!/{XP1NDSa8h4sqWHiJGO??\<^8+RGa_jW}4gxSBF?sj: 5@zeyc( 7>=fv7VoN#@p@\X36hчK\l%u98ܗp.(;7qo.IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_markcurrentextension.png0000664000175000017500000001023613016463506025505 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME )+IDATX  ԃ`ՅhՅhԃ`ӂ_߆Xɍ ݈ɍX߆ӂ_ֆhW߶(hBjB'߶WֆhU6  .R:kR1].'o2]ޱQ:k.R  ,9$^; hA /,9 t  $?rF d= u #? tz(I`  r(HzP 1vZxZ 1E}-|Y%C |(B-|ZjS  pn %c*H(%?b.}]ꙻt"M %e 1Pт/<$&/fV ' 1^ Ҥ  #  꾚b  % : ,* #&   a  %( #E?     3DCߥ    M 6J :K佩 ediA'/,   ")ވ9J ! .)6ij:$ ܇)3+%, vI49"x$ԃ +*2 %/ք~`c5=yN0;Qπsi%2; A8oO> ۉdF% *8 /4 ^zz^d~ފ## "ܥܑ;g;;]: $o:ܑ;pfo$ '@k0Aߊ%#Č:f} -@lfɬې::} -6$ ޏf:::f}  :ff:ff}}:fffff}}(K^cIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_focuscmdline.png0000664000175000017500000000152112451473236023666 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME  :̓bIDATXGV=hAnvo4 J ,QRi-X `PO!ѤQQ{QOlPI'D9er>f͛ޛKPj$q0yW/qYaЄ(<Eunj 瀁ۉ>6!@̓`w8ĀЃؖp]x5V/- ')\n!8_BVBc5Ex~s1a A(n֍ģ'PG '^L?~˲ !EoGEx698x"е, ǟ.)xbK/9PnW!3| > Mú^&7wÞj fF*UySE2p w"'fK,r'$~bYhZc8C^w4l^Go"ʳD[Ѹt6z9CCN,L1uMǀ\ 4t%_FJ(45 gYKbq8 FJsk)W2B.5H,wZpvM`XoQ"k3p'[p}p(x-#@[>>aZ-mAO'uIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/edit-redo.png0000664000175000017500000000273613110262743022411 0ustar alexxalexxPNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<pIDATXŖ[lUߙٝݶR)޸GBT MVcFYD|GQLLKb$5ATB@*ZJwv/s;nn|9̜93Aqx|ڗvܳB~PpUB)O+yX<sY:h9]@ڪze/ *Fn,Rǧ5" <_Ϫ7r5.mmǧh WYf. لrbgO[MfWkO(<9|RMH6a ȃ{f(p%69mOsg- _vW-D B0L)08 lf1;XTrYEoe^=tVN,{lC5:&$[H։'EMҵt\{WO0ԩV/|tGWkTB0nm6OԔr$d '4-X§Uŵݠ> ?${0w$(q@ qnoѿHd ۣX Rf@!Gy0dP98rJmglij@tHMZ|G;X99'@Dw s4ɍKSFPHiQl:ysKoOm:H)ʁƑΎ`aq(|Dpr&wN AMȤ>ND$aJ(i[XtlCN @id6aO$pj{EU_c΋MW0%3(4vz9s;7N tYf<ȔK63ۓ>H2܆D$3!QPuQ݊JW'Dҥ,f@e։U?V!R%lf'$ˤ eS|LI8gM9)r*MhwD UN8   !ߛ&G1ڡ!e  UN9   &=$Õw!{G3Cӣ{uɇ-w *iE *Px7yӉߚ8*+ ( E1Ed^  J:d !3Zݿ+˺ MHr2`<݅eF=ZzaG_Y^];<eD޵ & &ݵeDD;%QE/Z|M!V $<4M"{UҦ/`к|I58%%68{DӠ-b¿cA  AyӞ%‰q N`6`6 NIHB|.L:h&j))h&j>C 3% Z@IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_reverseorder.png0000664000175000017500000000071012110457565023720 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME$5;Q^UIDATX;Ka,ZXD H$[XX%?_ba)VE/`6ga^f0/ |{͹#ǿD hq%4gM>sl5k7:& Г5 qpp1+&lZzۋ_697?T8o=!_+)_ok3 *pՁqG W,_+-Wg2&O (;Cvl].P 8OsZ46BYvb~Nt;D$o8!auL8o1p)2Da8 ~6FYCg% "y,ySG`op.C tgAg;w!<1c.;VENNs; /8z?Y^#z#d},ܮ'l6ϞF loEUe V_ w, ->#o(pG@H=m[݅>fFl!uh$~𨄸}ugmH;R@h0XgCbp 'IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_workwithdirectoryhotlist.png0000664000175000017500000000502612451473236026431 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  z IDATXGWyt75dHXLiPd,BZHYDR9mZ9==G(T(h-($ $L2$L207 P_sn|w}w}~$٦E鏺CrsDAO& 8U \nb|niTj27i>^}'oMcf,]ZobhM S$J6r~\Ow' ֏(T;]9O w̢7<:_d3Ia _N;Bϋw;e;C*%Cb~Լzr'2NμW3ϙo46XN2/N!iSҗ0Bೡd޻m? ƣhb|u \;{ œstBQf@Dr?G [%u*|%(zi5nEOi:V]S>.ݼ_€D8RHxWAexq蘊N|6ϖ{jűW,TΤ 1B.JJi@Xw"2(TlD|6ܞt*tz`ٹX!d0DxJn >Ĕrr&&+PO#ш?# DccXnU:i/E@0f]a%K>>F [*UmçkTª=6$E+gxrt. @$Pe lwDdm2 ",JwٺQݗ2&9|$ʣ^ܾ#oڑ*EKZ s2"Apb=l-mt{uE,ʆ >҆x;ڵAY"v\J(p19VOu;UȵA`[C)=)okrg.cǣPo+g?5p$zЧfS]=pd]VĀmD$ JRʓڵg9K9)9/q/vN@Z/®ri$uk'BRg m(֣rȉҍI9Љ8Aڻ'ͅ o+ 3̡!*sP|k*/y5 #QB`xIiZ xM1t("%0`Ոk܇ٰ\EkIRXmuETqbvmڏ  .m6YzI{!`fBYzFҶl7bd*bO$fR~SǎZ)v}V P&%cDj<>kRM+p#jR VJPK[\o kN&4$ OS !ˊU0HŶ)YhqDP-7fMЧACy+Dz ݏ=H#Nsx:^qם_r|yɩ19BЄȣGwӈUƊըyMةi|l(_׏!d&(;Srp5I.J#:\FY$SyMDvBsB2  i΁qh`honhj{T8b=Yg"΢4+ `i;`2%[=Cf3^BNA`/|zR܄)e(xhY)ꔞŮOdHc 38ѺL?:a0(2aV~-Y6^B4*VȀy50a !;[2=2K>LcmU!s0Ϗ TIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_showsysfiles.png0000664000175000017500000000266212110457565023763 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<TIDATxWklTE޻Zh-J*h,|AШ%bD4@"QBThA"EBki}vKwlw㙹nR4avν;|)fFS;jn _c᢭ǟ$>Y4S%/mi_ƀ'K4&[ϽGWmÀ+w??͊*;B=1=-'4cpE[۸iA=&{ڈ#Вi ?D|5@Oc@@J![oDfcHW =͡&f@&O;TQx[p[hlEW%?cVрa1 f"|BO6a,{0U(T2)ʑ3SU-MD5$&\`z dpj珳] ׉6U0=6ޓ5)p+Ӕsk=:N5@q x}CXy6F1$[3)1HN/@(),ǾcFB [DS/ʫ!)k #lRW˿|"GPtIgLJۗ>B.i?{(,A+&K T+=H@ Q\30U3} bՃ[H0LT/EKRLW+ĮAA6|&YzLpwx1Y)I;Q[%VTք#(|O6wL|'wzQSEsŏr5/,EuMJcrseЇ%sԾUdW*g8w/v`GEW?Z dN/ihAW6' ׬GŸzL:DCt 1*$>-59իT‡ន)UWc= Ǵӟj&q-Ct`KdoC?K]7[n~= x8b]+m%w>j&zS016CEbl@qp!Ŧg77PuMwm̾sYf ?IΝ`0b=uHY - ZSJLrk)V?Cm3DJ,+y4ۋ{YmHT|^SS~zF%j<ʺ{+n@M+Bkn|LI\;&Fr|r^ok "[v6FtCet3#Y1R]ld̷?'2iMѳS-MhD ?EIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_saveselection.png0000664000175000017500000000435712110457565024070 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME ;! L9|IDATX՗{pU<+>`A$EE҂TLGE:S@gӢ*EǙR "T M]t֕7p<  LrO?ni/ F_bm˺lCN(?U5/Ѻw y̘ɷnIt5K\ dМP1oJ_{K$SĂZ?> n\:Vע,P,wU= 9ڧNsq}pWQkޅ)ǁj`Rsmf϶;zUq+`C Ef{Z_ƀT [ P @ckv~j2$@pUnΨ2~KɯJkC Չc1Udj XK~]ОLrpE[z4-T$= :ϱCoX'hU )i"P膫e;HUyɣ+A729gveoݡO7[lȓ).V6z."St`ܷ=v.y<JbmD-GvnU,awIbVqlӿ .m=[қR[-  / [sWdQvlYjVHF1iR'ʫ' Fj^G'1[1x z9ذrJ>Ze rD.!0/;9==& \=@{`@ JQ¦Z%nj|ܴ #0(oBpƯ|5\X9<N*O@@h\ D*D/qK%V9$0+ 3NrLy0j FA (n G@D e4 +/'\_nBM{ކ@pJ ` @E.NP<;c+4 nekE45jC-z=ReyBÈu#<ÆXfhpE8GEYd'KRPt< Xd$X&Ё?bVrZWo~΀c{Fe4];/~Ľͯ#W4HJIA7WsLgiܣsX nQo =և^Ztkedv 5@ >9*| ,?%$(i<\V=rs٬@^b-|b7/Q !p\w& ;U@))9/ѯ5F:]. K iǢCKi8ܥ<`w,gO9Qwj=w6=}|ޚ33x r/< `@"&m?X8л ΞV/ XPly[0B{}9r &0::oّkuYw2* ;@8Di>Yu,ZXƮ(2FbC8'<ȕɠZlOfDZ?l1FUU{ '[%nP$vUvj8/Tb$PU L0w-/;j]Rvrj!bLJ\l@ϑ}wmlJs4gVf]Yzh7^jcg6. /A6$.<7W]υε_ /+m}PL$ ?)jΞ+)z;< vc8?,.{P4~_?mCk \rO#^F$gX 1:9N땃ڞRfH%G^D{gČHZc%Uh25[̬uܥhHm{cǁr˚FhW׏'$~qD1Kٳ[_(c7`ŗ`oesx2hI`￙-ڀOWX+.]sOx,zt,?!e$ /_;l IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_unmarkcurrentnameext.png0000664000175000017500000001023613016463506025475 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME  ):JV+IDATX  ԃ`ՅhՅhԃ`ӂ_߆Xɍ ݈ɍX߆ӂ_ֆf $A2_hCXjA:)XⵗyOU6 K. -O 5cݭ} 2#}L ;f'pΕ!DeFJ %SWd? ,,p@d|hA zMUt1 ?#F -* ^+C9 ݱ EO&z(I`  r(H;Pӄ: "  1vZBxZ 0q-|Y%C |(BjS_I  pn %ʞZB 2 8 ! @,J*        b.}]ꙻt"M %e 1fa.QV ' 1^ Ҥ  $ 9. % : ,* #& 5 v  %( =@ַ #E?     3DCߥ      M 6J :K佩 ediA'/,   ")ވ9J ! .)6ij:$ ܇)3+%, vI49"x$ԃ +*2 %/ք~`c5=yN0;Qπsi&;$ =Fk ޴T vIDATxڼWklU٥ a%5((GIe_*BKL|5 A?b)<^}v[tC3{=~;e%~Dd0- :N<:wJ7ʦWڹ?n!an޾1.|V_Nz"?kN9d>o%Ylki ԯweۄ=G.l %&2IX:8&Ҏc>y[z]C T{tm%Zu֦“:pќըBmt)W fa#SL`Ee? 8'Z:$hE|{7IktRpr<" MR7 bKSx5ML{D0-U<[ $o8t MFB+=0-zN Q(qnc\L<4kLD$ $T*ȣk8qql运Fzc)]`L"d=Zf"5QIh`i\;6+_vք H6*I 9?׍a|2lOeLWǗ86/l\N QXto?I\&c9]diG ͘GVF29n%SeVj."UiS }65'0.xV`ﶵFg_cֵzNvDל_G aW%A3Lf37g~ЩA#T 30qO`sQ _#:VN;@:lGf$\$󥬗|)"e ȕg<_ W?Va'ޡ%8Kfy>u/9}q*4l{H_ϩmoM0lmۥ$$ [Z %-.(1BNM+ቕhIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_unmarkcurrentpath.png0000664000175000017500000001023613016463506024770 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME  %*+IDATX  ԃ`ՅhՅhԃ`ӂ_߆Xɍ ݈ɍX߆ӂ_ֆf $A2_hCXjA:)XⵗyOU6 K. -O 5cݭ} 2#}L ;f'pΕ!DeFJ %SWd? ,,p@d|hA zMUt1 ?#F -* ^+C9 ݱ EO&z(I`  r(H;Pӄ: "  1vZBxZ 0q-|Y%C |(BjS_I  pn %ʞZB 2 8 ! @,J*        b.}]ꙻt"M %e 1fa.QV ' 1^ Ҥ  $ 9. % : ,* #& 5 v  %( =@ַ #E?     3DCߥ      M 6J :K佩 ediA'/,   ")ވ9J ! .)6ij:$ ܇)3+%, vI49"x$ԃ +*2 %/ք~`c5=yN0;Qπs}ڮn # do ޴T ! 羸;E}gJIЛRe>* "ÿ|ܑ;g;;IPf()\: g%pffJ;%*: ffې::#ߊA0k@' $&,I>zQffff} $6- f:f:::::}  }ې:f::f:}}di=#IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_copy.png0000664000175000017500000000132312451473236022165 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX͗MkAxI~dA=-F'KтxWR-ţjU!I٤K^f<,;􁐙<8h1˅MY54fByv3/j(ES|>O=t%ʩDF5ոaPV%{˫ p`iiIy "%" a0Y"*Y!"OXqBT*AeIe tС( Dsev`px(@&,T),+ L]LjH BSU(HR璂~9BxHZ_H"D0n~$?T), DM c'a)iƘia IbJ{"~{b`{ fPi&"<|iLp4D>.k*q`n9We7;{7  I*c@O{a=?\I ڵJXup1 `6}9Y.W& TD"i҇1!}3?NP]zo.'[F񩤰nߵ1v0擕յiט{VT MIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/edit-undo.png0000664000175000017500000000310113110262743022410 0ustar alexxalexxPNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<IDATXŖ}lUw?9޾]vu2d"8%$3ˢs &h2b|&fFq-.dt3h񦡬RFKJi^./K|'߹w{~#Ӭ*|32o.ln:DGca~2G`YfX{-q">cv8ǖ~!9'д'#p++d4roRY ]7%;3X 8. Վw>vP9AD|J_}vTϯ }5If6 qs{1v.jD]{ѥO-k^ ӠYT1Tf#>Wsq<g`oD6  Q&\0jC` 죈SK}27h&}qZI֦Mo^@OM/ ULo|/\A>S~7jE3=bml)|>cG^6Ԣ&& &j,pP Ac" 6̟Ϗu{ G_^xE"*~04H f CbD?e2{[ꐕ`cD?|xASDjwA3h09qOAYv=\WlkwNزY!XwdWŞ߸܂'Ѕ{?:{/cu}VSV5Ț {HJ%7|X놭e^|]ک"vdew<.1|KgPn©X7xC>BBXU3v|6* 5pu-311Η2_]v&!T%Vuf}MǿngG*ڀqmf[d8/e@¨I@#-Ϟ9 fJۅrv~BdUjf vvy̓?[|#mܨI]≄ 36 @&[#cgSඈX0{i "e$FYi:"B@8Hz@(+g}j,A<J/*lD""P9y"D>лp~4ՖW#H<̏&[E\(I$¹|}m!71b́DŽLnԨvn_V3gڦ#uT*FG:N*fU59 Og.}ՕQ$s͝t P87Wՠ0v]* D`**85w5q-u,}b1į^Jhu?5XU]Sx+ᕷQY{3gH&q"A- tRqqo5P$}-,=P3@~YxnGXtS@P T`JaIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_markminus.png0000664000175000017500000000462612110457565023231 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 6,S #IDATXŗyUǿ[fa 3XpAD"R%m)ѴTJ֦(.HlݬZH+5 Vсfͼyr}w;LMlHz;|9;y3-|z({$PSW+[毹'}&8>~ͤN B\ē ].}h^B}S]`^Eb8n_{#/b偋lRI-{—ݲf]p(d_53[)։npdB5V7\W~w.;p Z‚TpQ' $vլWk1 ::A5 pE{4_Q'˰^Dp6![\3L0ϭݔg4c (O1PS& O3Ӱ%p WL- `ٟm;?4δ`X=cE-YHTl0Ff;4rzg-jǫ쟇jTxr@r‚zz Tzۀ+M 7q*HCE|g(\5&_'8<U  8(1_=ӐND02B(P H> Wȼn@ep+ m%b&($zσ3xpLPR޷afy :eJA(NA&z|Rzz4 neT4K&+ ]umDF1qp?3mH{-y$HEQT yl"3퀵P{6wfD'U{>Pτ~to+?Yljg@B.cr%d_'MJWi%Tv`R ,O @5-31xd֎/r<&2w|8T~R΀p*!-چs}?>|=:v3T jFGCe.sB8!.mWo8}mG~OҖɞuW^HQLaCn9=xpDwBf/8ax& #QDɁglR,2A}տ64\n N0#i}ő*5O$13b"W^u˫jTAm 4@m T5;6~aͲ'7tOjb.n ˕^غ`zw ئȒ'gnn±ZpC?5dV'p%H@a}/g'>K 7,Nc)Е>k6 #I+9w0:cUu0T_ @'mk6HuݥkF~Hb6,iovR[@@N@̓pr4,T( XCs7z$ʤ˟9^_D_%,Ng@t,QVE1dzTTvUS@8_?J$EARL7J-;5å,v2*WF JPA(Nb8::>#S0XK !AD{^H PTQ`84}k$8#+P]ٶj٥U[\bИHKks,Qn^ %!(R=?z?ૻ]chz\& ?“_߾w$1 S+#?dvht޽v9dbi9"|!Wφ:6qcZٺ{vѳB6JF/ "44?ғm1C}ilu64|B+)t!Y]8kt qkZ%3PY (B `# a|5c:':6zġɞ]<9D."CfATXlpx; =`s3aff!ܰj H 8#̧Gi B8EU |+^>y"٣cɄ?7%^tӱK97L ?t|ƶRuhjDˌa>u-BT9ѷ(ӏPaJMvuoַ wC7l F*xsDoV(A˺Y`)huױ5pz(LQGl_x_yoS4)^<9ڎ5 Ճt ضhNJ`4U1IR/|4hD (~6þE^Tm@ J ).B,m (Z:NӞ:*glU_.=L3W]|Zx( d#;Nr7YqwsFmYh@"VatxhKJIsh;%m%S||VKkÒ6h Fq< gR?c FC=NGI.Ffw;2 l#"UDftӔ>qXrԮ0?rsIBB-0-g! vkK>ru"OW|1D^ 򡬢=pdA4.|,cҾdA}!/wtlɡx-H@ERF677-߳Z}ETA)ɊXIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/document-save-as.png0000664000175000017500000000345513110262743023707 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATXŗml3wec]JsI0ëi)"DJ~I6}RYV U4T8 IP `H ۘn}3Wېb=zw5 g;Tx^N " e>v=([Vh9j+ӧIya|_q~dwz{_B.{, ͡x]yb̪!maIDJped7.u/u[0y{nDYO+`MR7f$*1Drl>Ikכu{"RцDMץCSw_>s򁊒ȸdڣ0?B, x]sU-l%3%<{_>YXsr+1({pwrek׮ lw-k2&5/WD-̆U|UڈsO6ƼX5rЋ04A5黖W7B(([|= ƘlRJy8ۗ`hm]֭[܌2CW\_ƐGIa>ҎsN1k׮'^O_] qM^x1~ﵽyKl["Z1,Ri5&yu훀kWV} -ˢ~F ?8WdaWXR`[F#`eH)0޾|3ϧZpϞ=>`X.]J20qT`2dw8H)T :w#۶;!V%J)b?IesR7[y)_(+Oosrm<I޸̅ Xe}t^B!U@knnH.CD%xi_! 'Жr2$ SV4DN >=ײ1c]1YAr%h,>?gl&ډ1Y83_c @ #\p=HۍxpՁ vZ12pjb {N;*P{#[*¹5&H!DLߜaOr #h"V{?LC[R Awa2 T*6?_5`,ko~= suHy_ R|,UxU>L䪪E\ l {w5/r5%Izd.wmC͕^ 1R.2001#iHgȍaPq'![ )exg&|!*7Hbqmdl/Xk/_be\hJ!&zG#Z[y Y`"R0׈ ?Q]{S.w$J07qJf{j*foDvѮ%'J鑋|iHpjG)g>ST+@Ms VʋMq"Wxn ]s];IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_syncdirs.png0000664000175000017500000000272012451473236023053 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  8[?~eoIDATXGWmlSU~ 2D$ M4#H1H DI?cLL41&H@]fh $ cLvVv>9,*'9}>9Ɖȷ;0L6ao||[u^]ے&7m.ЍXjt;Ry6BM!; v9҇p986 n9 Ρ8 !EWӉ@l`8-٨Y240| DžKKjx$՞ uu,̙tV*f P:߃r̝qe4U1H1ڳ<޶pYe:V"Wn?fŹ09Xg[Y4MMX ܵs 56"9f79BzW.c1|N\'5%آĞ(`qccUaַ ߍ3BʹO߸p*kZ('Y/ؚQHLF\ٙDm\i` I'hS7I@ 8Dr*q W!Qr FHẀҡ^XG"ol? ,xL)er#xÊhRBDsM˷EsIkFE|kVKP|`)U׷MW@>FxHU;\,ZLJ|݇:e,\q}@HpPuB`lŴ" Y4,5h!Ś:sHg>+$Yk!ݻ81@6(g/|F E4ճ3(E_F.Zoһ͖/N6(]M8Mxs0ŔfƃԪclL\`חhK_H<|7]dsNfVܿi%)HFX$/YNq5 Tdի3K?cds ~#q 8yadGEI(JZx#\9U vv_GO+=K`tduޒGzi&7"o0p apD!(2R:((;zc8}PEQ{(\"YtRg~ ?z >J q:5 HЋJxAZٹp3 3Y,%bNq`K' NA _"Ƃ LD&>7bMO9nI:n`, &*^{4ih%`d)|z8Ջ: !dXϙjH}8\rNmͤdyn^Q}tvK9s9H'qd2Gs4;Uf?tt5>Dn2&!5l>x+ sqcmђjF?d4ADz&U/d4Zűkdb@!.1c*^D`2U &nCEq sY_yNTi:M\d [WW2gۢ;w_K eŌSQOLEYaNRʝ{7+CWzp|ɲכJECTt:U{*™ꁎ/RH2,͜7Kԧ.yZV/"/Z0[ĮiBbL/1+&+'8d*:q HshS po2 c*JY1Y9TSfSщ5bJ [%¦ibet4ۥ7|vMw籝/ 9eZ6tz7~;aQb=W=& t,KxWx3&2/5Ǎ1ƒ{U/[eLVٸ rN9*ᒭsǾ$F/}_qd|= IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_edit.png0000664000175000017500000000276312451473236022151 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX]lWwlk;)%- mBR/A# j*ZT5)Uķ !J%ر "Niiݙ{xgctGGg?{*w' |ڿX@ap,uT555DdEvsL?FÛԗfr ?Õ˯q lΣ3j˲=CggK2:.ul٭lzN,}C>K&j^vo>y>| =ϳ1ߎǗ#3<>L\ xJKes~߾}75"Rx܊Z2[ eף ln8T,F bbgӻGUږ5<i Vb17"ظO9o%U0&֬o|51c̜b6`k0O_CKo 9*k׳1Rg0 @SSST iHzݺMMMs29qGqO $,k尜v};1LMM%Z`i >55wNj.J)6ǒ3K@5r0 C{ӦM3 bkkncţ϶mc9̎\4C@pf|g[9SH(XvnIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_configfoldertabs.png0000664000175000017500000001023612656270711024531 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME&+IDATX  ?zL T†V=vO iP; RÊ[ eN: : eM:ª  ^3    QP%,B0   UN9 8, +G. ⬋Tut$( 5Ά4D*!aE*絣qީb\Y+A0CՑ 2N9BRэCэC8$Aw5$33$=[vIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/document-save.png0000664000175000017500000000366313110262743023307 0ustar alexxalexxPNG  IHDR szzsBIT|djIDATXŗ}pTn6k@0 !"hXc3֑q?ڙRgNu--B:h &;޽}MH̜ys=wE\i̵wh#6Ia"p0⹾=[_ԯ|2mo؂ymӪ5`Hqʿ3Wniϙ?JH1=b[X,)R 9~F$_ ̭vumW7Q63<͊ؕӧ+IKJBCTd볽ySyr+_,17z~zW:{/)(1t_= O 9caNZ18@ߟvpp2ʶ$~)g I ڈ+~H$IJ ~kndvj,ʢg_|/TWJ)w]={';Z[٦Mvvv" 74Ɛwܶi/hmIv;wb3˖-F"͗Xd-|>mcPJ*D9wfO#+(7w\0(#u]:::l߾]^N,Z6P(RQ,)h7sv#ϞF,­sy^cqpyAmxG2dΜ93>"!V\I. 1&D,Ï6si92ϑ`g3>RJRhq]ŋcY֖ ֭^Ѐ8(H)Rrooohw` Ch(++CA.CkMPή֯_o"Q|'HljF!,[CSlJSDQ8dd2y8)%H .Å: u%222 ¶eY$I`ߜN4PQn#Dkz,_ߑRJ{R!L2dddgϢFʱ,+4ԏb1=g!8ZkL@ @8\ Z%>/oX]xIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_filespliter.png0000664000175000017500000000254312110457565023541 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME,,g^IDATXŗKlU=:ӖP5ãmT6&Q4Yh  D]U a3 F" Æ )}B3~Lt:Nܻs `4c#o_K*MHhR$~j`ޗi@7sEA J188H:h4SvHXB a08;b1|G)5Zk-˂c9%P6aJH&7xR/[}I&cXٜyyWz~QR}=[X{W,jVoN~ W .^ׇ-+w0wٱޞ qg46@6go88y"Hv:^%Bߋ lb[[0F2y 5Jq,GPhFFFBnVLO7&4X V¶uJYw" -@kΝ;m]E1fln!H$vm#W^EursdM/fvu` aq7,Yӊl{Β 08Ww7o`uP3ckB3N<~?z׼NSqg bҪB)O6JZ, .zyA %8'Nf҆cs]xPz\xn" d&a-VԬr8C|BmVD@Q-(T-֠Tfw\)֨.lgdAZ303fBHYԕR3I8}&FbO4e^}=r&סBJ*:'q}łf|ߧJ= D"75Q}(d4v5faNlXLXZ:8FfkgU(G&qG;wѪJ<-q"r<RF8B )8wGhhh܃D>0хjXL*<˫z( D"RehN RJArA΅TD*?+Ԕ&o8(ǧU@ A?k< ,IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/edit-select-all.png0000664000175000017500000000116711323355446023511 0ustar alexxalexxPNG  IHDR szzsBIT|d.IDATXŗn@*R- %qP)ox$@SBzhUd6㈹L7+s_m׽ipmmlg`p LMwcu2l 7* @c."s@`SDdnd:qym^VEi8>(wV.•8%]` Ǭ#E-ً/ x\-HխIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_copysamepanel.png0000664000175000017500000001023612451473236024056 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 2o+IDATX  isqvxvzjsqv.wuz-(((þ:)xt M%N)Qyfv2&%%% vqw'''      qjb qib pib  !!!hfeigf       8g4!^XWZ```CCC''''''锖  sqvD@Fe*--=NHN  RNHN+e|u|}A\IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_fileproperties.png0000664000175000017500000000244712110457565024256 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxڼWkLWfg]6i+ ,)/ITLLiI jX[+%CkӤ*h`],VY-[PT`wYwwz0Y`م$'wι~sE -mmMz!"a4jqq1uVq2::*ZVW z j84:sY fsii },5^#BF%U&WNCZ|v&eRI:h4"7+|R V} 6z9]y͍!^MP+fl`ijw9twcvU @FPSBf`1fԀ|H# B;~E_]/Ky8`A9a4srb;w=ץۑ0mk0ky:;j>A 4{/G;ovEPa'?e%-n'QA$ě04<0_)%%yCgA,X2#P\\ٸN>܀_%/t'zzYϤp҉En/o  7obGqO6 U/АiHMI#q;$ XؐqtTTv Kx  b.]+[}}HJLy5ԟh@lZn%Z|q6Y WC̔Up\a/)y+*q @ATl±: -=5Gkuɖ q(ɈZ5YLj.+ŦTDo9,M͘vySMה[ׁ?HC(g  2:1؝vKAr:ټӮiDE&Y10,(N'*3Sا[7:;;FW(moɇ}b)o EEy>b.vw}~hͮ={-))>WۉioNrbYwe+1cp~.J62{H[^~w]_`8OSXIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/list-add.png0000664000175000017500000000113111323355446022231 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX햱kAH$D+AX?B[CF+AA\aai#v"B,LD"hlryMv݋Zx ;70cDU۳z?v{:d֕3vO"ae3No3A d홆9{!K|=Swz"(-g˙Z|w͛ܐOK1ђ<'!${V3K8̈́ N΁u}'l('Aq)m/Ǒp0VLq &o3 s R7~1j>,$jt mPcT&tlV%~~3# jiw] (0[@ 4w$H^wIH|4N rZc'2Se_T0/]X&΍-OV +0JOhC3o? WLvIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_viewhistoryprev.png0000664000175000017500000000231112451473236024502 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<kIDATxW[h\E朙e&n%hj%!JIl-BDPP(}hQbM+*V*SQM45M23캉uC9s9äXb`˺`,[2?$3Lvo$, x|K7^bG_xăDXc~g_aiKs(a7$14&±$‰4~'hI& Ih M(XK]hIt}l˂k[p\jzv]sm^0<"lHnDI@WB ~"Eإ-F0HFOrr/O025G D@̇ G#S8J#w?ּ>MQ$ u1صngUCڽ(q|z ;g|XR,/* A"Uu V a҄x='I/NPy%u.OIOe2*mTU`&Q $+ @j $ppRB0 j`\݌\*|Ddt$HzCBүYܘU]!ޘFףuti% a96d "05sO] r.$j.(Fo8[4%-i"ffqqlv5m~ZOP[X$j& Y1;z ;5+F]?}l l&kgyjF7>V(CjtXp75-Ơ}NV֦U.*l?` m1IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rightsortbysize.png0000664000175000017500000001021412467744673024502 0ustar alexxalexxPNG  IHDR szz pHYs  tIME -3k+IDATX  fFOxTC: QU({Uf%:# -DC:!QkGl<+L{Uf `/ ~C;"Q`@LL`@;"QCr/G;#6R5vzE.v)1-޽{6 Kb- MK>%I.W<'W)/5ܽ( b=12M zD/D/zI {r2BvIaO4  ..(D0&::+a U Pj|9+?`] ,(!9??X1t| #lu x5/ ]*88]w7'  =:!hő; fR"IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_viewlogfile.png0000664000175000017500000000426012451473236023532 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME ;4j=IDATXGW l=3?{6ؔ5ࠢRABiZ6mJKR$RX I[7n!PhIE%ˀƋ?~f羵k{Ҽ̼w{[ 8tPiOڶ5=8G.bp>Msm]wVڹ,%8K^ >|2m$Igv\m:^۽ٺm{ Ue-wX|_aY.^ǶsϢRn !n0M V͝#n֞m[_HYhy6KiH|TX*'GJY3]ذYL.*\釛PɷN]m ?._=ŗKX:$zS6b1!@Ccma)y1N:# |IB(//C X;wmmm 䎀amtʲ-@HJXSRȣ0;^'Ņ|~,O>>w_4ӧzߟbFK8a\R5ŏ-Ľ9@e+㈶|z8BaBqx؂p'.F"I, $,.ts.!fl 8u&`rC8}}H LRѓ(g1zuD"B(RͳAlt:10{?(b`:d7o:V\ƙ7r:rY!i,pgQ̉" ׮]C̫$.Y Yh)9#8r, [_ax88@$k׮ž}2f͚̜|@x<[pD5jåݭx Ғ%Q Xpc!o<  fvx9Nuuri>i*I2=<|2;Pwރ(WHXN0q|rYbzOߏІ 3,|pFn\.RbaA|f-^tf#U"<Ū+YK=>b "W# biFMf񧿆$XzlwA|c8)|^7~U:WaD"YDI8! ޲ ?.ysim%N^؀nT U/q%QJgf 9NC x!O--Z.5#ߟ7oI(&bgaޜ JzDNiJDz|MCtFҴ)Ԝ\з%OYTrxsS+7ߨo3t 55rvB{{+3[TŞDZ;Kb!&ퟏ` |'lÂF HDٸ,YRuAES翺L3}]g8鍬}nO넸kPJ(*+ׯLRA#LJ`Ή'!|j)kv =T8j~-IN/6@'w곪w+u—~eAoIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rightthumbview.png0000664000175000017500000001021412467744673024277 0ustar alexxalexxPNG  IHDR szz pHYs  tIME -+e:+IDATX  K2 < KL6-n-X-"    >>  X">9#!5 \@M?' I-9ڜ-#d*   +Dd+D%&H4K6@!B"˻5EVv#-˺`r\z-5%/:V  zffP    ;K;K OYuYu'0'0 5fP KHq+0o8LjIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_dirhistory.png0000664000175000017500000000332412451473236023416 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME VaIDATXGVklUff}l)',tum9/ C%:Awh% 3N%1 ސT$w\|U0EB#b@4g%#+ӀR-ȳˏsnHfW5%AaK:w8'RU7>80ͭ,P5XWdyL՝!PRN?}} I$qC: d1Dܭt=^n6Xba$m`9)Iȝ7U. ⴸ9>iPx=QM%P5)1Ȣ o|06_ȴOJX҅8H+b2TZ3 lBǤ Tx<"*r,M&[^Evv6 +#$2$=,B0 #Wݨ 2I<u.+4 < B5&h(;#aC  4n$ \C,i+F0HZ,@0! 1D 4b] ! "UԢc ,QN6\ݿ,˺! E 6N S(2 *hD޾" H; 8-%-A%.2(މ "- 'ݿ-rd BJ9' 0 %&A$ @+ +n X $<4K6  4~,9%%},9‡Wd~H4  f&k03  S 2  3†Vd I 2iCd I-pkӐ4!#I3333s-`=Rԓ?ԓ?8$At3( N;Z!z55Z!z>C+ !   ?PIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/application-exit.png0000664000175000017500000000327513110303146023777 0ustar alexxalexxPNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<:IDATXMh\}η ƶƑT0&'Q0V`hM[ȦU7M'fM I?tQhCHƦ"""nbۖFo׽f43 =p7ͻ?̽ 5 \' D:~EѵY u]\Ƕ1 FJEw޻Q]񕟲H"" C(JGH),bիW?ZyUQ 4M,BJ^+PJ0 ǡ\0M !D P*fn88XmH)ZwĴ8CXIJڡ7 #@T]\qض *Z*ض8Q/:3iaf p'H'Y`w /1! TG$4C-4quS'mn˲zIss?oz7oR8wwߵ1 Akt7(ƍT*fggq]wrmO33;}@K#v h )_08qaFGGrܽ{y}>}a4GOh`YmI(yzЛJٳgYYYAG*?I嗠¶4"R;`z۶assjcnmNL,-", (C6 h ,Bm"Ы~zz8i4j ůfLBxf@1rgxc?@oJ%ܺu ˲r:v"g?-/G3g0 ESMCy hX>K}"O}!w|ɱ1gk>p0 D@>zbҠ$ (Xag?g* < RJn7 CÁ1 b&KKuj'=<;˽~'(W@i^1p;uhI3kyQ{.)~m--%.ׁ ( ! Cb@TJS0Mˍj?GklZo r!n'TU\%qx \t?Oŋ !{"C0 j՟7_+eVq  AG27)%<|2vɡCh6wY2c<15Aa6Zi($_Zk@H;9귔%8aZR+vY|@ZC)*JnjV;Eq!R?9m~ѵ~AΓfBc;~x7ݦ3cˍc\IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/edit-find-replace.png0000664000175000017500000000407013110262743024002 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATXypU?wyK#HB5HŶQR[.:L:t:ጴqJ;qDCg(6LD$3yֻ!oνg9sݤK;vqf%IR,ȲeYXa9k{>I5Mۼk׮_I}I0MM<?8@0 <0tv;99.#''ILPz$|h(ǭQ]S** 't:YY߀ `.Y,˚ dρ.p  w41ާ| lٲ9_ cl~!DyCpU9y`%,1s𸟿'nq----ٴq֯&pvn" so- ;.cgCC1uɓ)%4T;l9/QC׃;ANÁ+IEia6y)֬^C8<ʊ+(//aR䭟O4 KQWWGM5,,@QUFphwEK&dff='Գ[> 29aG=0mX)oUj->Ehl ]vH2V6dI)i_.@lh!;Ym*uuu’8z|BNn$ E,.,Ae$IBQΝa(8'>YTW9sd_ yz!Ě˗GF+$UVx< ff!2Qm-חPPq?əx6<oR`d_RZJ'TWՒ]D<GeE0P%c~|ݍ7dr Hct&(`J, Yljmm]ϑ, EQp:N]]$zu5ظ29pT OjGdYu ۂ@MD^npIPU˅i|>LD$"#|w;kĘ 05|FۀLaz+\la92e=I#qr(AװG^~-p!ޖRfa*W~|0T|d#c@-2ΎQ+)ӋaoLEdAPJJA5%Od#z8L(@{6j]c+jݷp85RHjNeL:b$O>bD9iJVvM^:L^'KJ@u81}ָT Ppp9>4 x 8H]JIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_sortbysize.png0000664000175000017500000000200112467744673023437 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME ՅIDATXoTU߹3ZTPj,aHK K/B_ $  dY*h f%)-T(fIՙޙ5{09P//yNb%ToRg]I $=vt.87ddD턥;L&\rSg뚿uN$7@wYsz!">Zghm8%GݷlJl#B> g8>ۼ_ځxZјj [:p[$ KfZ-#J{ֺ&J {֚)h_!T%! YaOSExpԕ1_q6#AHC6<\O?1Yl zb ޛX1@%k5CM? 3Nk 4(`4J -ŏaߊEyX%}QX[CԞ/M`4+rb9AT>"sb[xN|ϴ$0jD(P(e|'sbq\Z1 AJkc*^g{8$ )H S)>wIJkbDZ koҲlM8FCiEǛR*eXz|7nsMo@Ұ%gg&l2UCVe8dNV qhz!w؂ř"iKAomK`,7G _ᣖ TZ\_` [A5<$~^p5p}GqHς$LJYnXk5J&i]@225VF_Dchx4/3oZ+ IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_extractfiles.png0000664000175000017500000000427012110457565023713 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME:HEIDATXŗiU]t;v@ JAJ"ւP $؂e (4KCJJ@Н,Ysw9s K<9ysA}~cr3ZjvܵBig53ԽoSHO◯8 <*#{n]H}yT^E~gރ;yw~֓*$=D- y~ eRr}dRG4LlΥҵijӲJ0}q-tFs(n&PQO-7~c 7 nXrizʢQF#P >DB0Đh fo% Mx__+ t^gk{vᶇ U1zd(DnTE+;v|p<2b%?t{H~h[t5e^ N/A[Z֍e#4ecӔ*I[H !la Di|.P53/H`k;=2?цՀc%-kFe)MYҩK2\.A#} |.m_9EoaN_3tAr8q{ (b@ë_* i1L0 Sbi J*(އmI;7fm2C=>(_= 3ѱk)/ZFewO189hw=ꤤ,H8l" ,T0$[C"5I49@否iڒep<9Կj*[b4B|/w̻HPYh=eE婩IILi',B `(ًTߨ^[Y]IÜl<DJ.Zie`e;z;F8YF4]"ŀTw:{eUm X>D)i$za1B \%ѕdx`#Γ>/Ɯ6PU_hVVUknĴmRS)R׷w)%RJxC+A?Eg;-< c%wj§r1@RTxI ÷ t8OtS.|10IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_setalltabsoptionnormal.png0000664000175000017500000001023612653160641026013 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME&rs+IDATX  ?zL T†V=vO iP; iP; iP; RÊ[ @kT> kT> kT> 8 K              O#o>R Bןzl}=o׏}ǯV."CO>Ys) t(6EW$$tKu1Kw;;aYXGp(*V dOgt ZDc,9@Ƨ1LY-ZNuw'f˭jO? ,oPp>ca yӎطg5~H3^{쀊Lx0 ʿjdR>RΧ;wchLÿΏRVw|7^ qĦhk }erN9잎z6~ 5|>Ewm^TY?{&#GOcy JHG6dO۶=6Ł$n{x3/Z/yuqk'8ÑHK6E]mea qYj*}2N]"zQH%Ja 0E%Z~-Gkc>1˿~ cn֭#C: o02h<%~,I "%H^,$Tz1L!P9i}l4Bbt h NYIbZ4%n߄yI1̥6H|6pj9ͦAIO|Qe.^u1}n-83ng|>F/$5 6w!I*dΞTzI8oYgH$4L?C6ٶ#8ٚK\|F+ڙR}~G.ŨBl|rο{%fڏ_Q>hRi`e쐻a)ݲ)o!}ŋ 2DBZ_h^ɲV;".dӶ]0g-!G:h}xWnC ZK*Jڀ9G;GR,. @*V\ߔ ${v'_X|kez3j4udžwG@,~9*rkB nBiM`x 35tO9BA(qM 'S♧_ i :^_]j"78`%Dru( *dD6W8̬l( nh`ƭ\7W*x(lQc-Ѹާ'Uz+^ \L4/|hݰ=DF2GeSCG'JUenzXx.tÄaZvAc7{eL8U>^R0T;"9A-ѴO,dTQU{ +Ru!aKf-\"<s~C vwܽ_Nljv;95c.[r f |{6Iig4/'ԧ{e5ޘXV@=/rcLcܩ,e`2^8~mkx̌&3%Th5'L5Ln@K>B@ ñE4TBy"صyW=Z$e؉ʋ6޹`?SuoE8o3pi7"wɶuƃl긷d(Ů/r,>ߤJ\@;=ye3kqxm슲;*i)9='SKE[j{IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_operationsviewer.png0000664000175000017500000000273712110457565024631 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIMEk+lIDATXýMeg㌊!H7AFc fBLʈ lBDuqDqcl`Cl0c{,}{^wg6St_]uUD"^SC!i5W\فE~W֩9]z7Oo6Ëϝވx@ZBFh_xv\:_^32a7#̜pwg L #"p nd~ίwIW^\v~-?ݥYADi{3Oލv ђU4hRK#hҜ6i!M.gGx< d]ɩsjrKxWEu75WTQSL^ UL{׎E97lgK DΉG@JceTˋrA"!$⹜<%"AAC{?b!P.8!8kz Qb* IN$f02r cl/;u{5sz`Tfr,qC;Dq^IvLRȃOœgG`a`=XEmO<̌:&?<-TqzZۂXq p$'s/#5q _1]&p+?܂$R2 JRú@Zq LD #K_ =,Rl/ˋ' M9ܶ(́T87^~0`!$6 BJuו&O85 KWHlhjE_BQ/M9P!IQvƵnWЀ8vO807|{|t$U͐\{=$LT0^irӏ?ammb(` K wƥ7 ђ[8ɻ zQhԿZ}_{JS;;80@PJ$8៼iWZqfmyea#  mp+䔹yYǁK;.at9U%5Zo&9 NQL6*i'1: dH<\V$r=} ;t G `>kLx- t/9̼qtve@fS\ ^z r]b^ɂw~cw l< {2(,wgβWva4,SgaNWVԁ2 \- 7G6i; vgC|; Qφu|rٰɉǞ}|K?8sgM?Mn%IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_leftcolumnsview.png0000664000175000017500000001021412467744673024455 0ustar alexxalexxPNG  IHDR szz pHYs  tIME *JV+IDATX  fh Bj - 4~JP -P. >M|K K     &&fT++, }}nmjhgjihIHG\]9oomlljxynmjhgjihOOM  !_`?vussrp uunmjhgjihWVSsIP-bb {L ppnmjhgjih]\[sIP-dd {LlmnmjhgjihdcakGHff{Ljhgjihkigff |LknI+<'IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_hardlink.png0000664000175000017500000000173312110457565023013 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME 49z*hIDATXŗoE?MRA T =4 U()[oZ '8@65(Gn=aDI൳kēVg7ﳰZyɢH NM8Z젱i+Aq٬͍[Hx \ZEάz}a&ң]UQUsOo-4VV6дIAU̧@#G}o* Z b(O/Jaѩ>ja |ڤsZӧO2ߋ(xkq1` . Upvffob ]H2x\<֛Y.1KcH  gp?P:)$WPd4@b ;;B;rPRPTRZ8@s0 W~/1ѵ+N_<֓0 BFOޝDOkwS\hEoh<H27Ul+Ml ^y?m ,i!n8hY\ק"mLz.$Àߡ9Bh??+C&ʂf4;Mʫ]0 rI@=m׾XW$/vٵax8 <2ONGމ: 0Knܣ7fռcfIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_loadtabs.png0000664000175000017500000001023612451473236023007 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME ki+IDATX  ?zL T†V=vO iP; RÊ[ eN: : eM:ª  ^3   fFq  ҵU QMJ\[\ϲTy 9)r*MhwD UN8 A@B  UN9 #KJL  !\\\WWW˝_XoEy$  anɗIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_copyfiledetailstoclip.png0000664000175000017500000000365312451473236025616 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME (^8IDATXGW{T{g S#YY RjZ&6*lӦ5!&Y!&&Fi)MnEdCإbJD`" n1ݹwfIm^o4-ޭzyJip]P[[FTD[,p-:NKkk(UGo|rȮg?k`MXn-<* `'.Iq:=hn a i682ڱATVVb/_7H 76mlxt+wG !0{O{0T8U5CC#~ 4+ec xd-dI,JCf?^ Sf4Q^k!\3Ȁp,-x)'4I ϡ 79Mh-ռNiwb;5gj5I i;uOmNXXvˍr ZLdQbX> tx8R=)2? 6_z[Aww!}Ţ<첏 HqF Ʃa^r'^X,\~HǟbKh;<'ٹVa[@¥_?{'MqO/py$N_dDOnń:gBێNT۬g;CxqHpG]1i'νwƻpU\ՋZdLGR;%Q @@Ȇ$ CG"T&aj#YÝ[6#i}7KU[f{M'/%ELOo1Z|r ſ¯kvW 06ִz6f~- yy@7<.' /]o k5{fx\my zC2 Pp5m*1Sk38Ae9MbDiQx^l:ȹlYܻUUU 8ew&N`(h0 ]R?zbx6%ht| kVV}z ~ ?2#.`ӡXT\,ދR:zu$5pݙ 07ReKZa W0#\SY 0~Tl`ǭUdI[dNKaA's%.,u~ڬZ pOǂ2aLh SS4q3ffIVeuA<$ M@9]f: mfen9N_hnYq``;((گtO–23h_˪iG J.n.eM@,牉Bb@B53`p4>ڛ\ϼpb}:7I}(YXE8ӏdMq)Ťr0jr[A rA~^pm0Z1 [_¤" ma,yYax@& R{g%0EE(-_kC)4ס\Gfw9YA"jߐҡGlp:DcyAfo=GqmdOU:eFBmM5ɑQ"ܶ㓟s?.kϵI%A"nỖrtS`uZE%7rF5 _,)H _0Ay$ȼ.R{M_O~偮+Pl,6 kT> kT> 8 K              !3&-C"Cu!ٱ|!0aK@5r b@tČǪoP*1>f'.3(  P4Wҩ /"E.8 nQ5^+/9 *.8"O R5b̉w`H.?љ *Ӟ{.3:,290htP'.H_Vl.Y/G_\7wYV 7i"a[J#$IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/document-properties.png0000664000175000017500000000213313110262743024534 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATXjI'8c˜!8DP|}|˽+"h$3]{d2q@}_}眪 +PJaZKc*i1ًeƘZYk8ݷ1f4u$ɘq|4e(wޏ2Wi("|q#r(XytrAȲVE$S dY˽8? IJJ@akk cLU15Ng"TEpʕ+JL"P\ݩ "cL%$l:t:cÐW^aeaan-Se4%"4e0fAk <7ny=nǏIp9)pm"»w*klGcx5߿|pHVC)2ׯ_5]077GEcxAf0ESZKx z TIh4XZZ$I$I,"yA1ձbZWiŕR\|<|'y(MFΉ(z=uGv1UZJDQ<.]'Ou떛7BDQDVj1 xYTOg{{/$՝;w)۱8{gΜ1Zfee~_ ~`}}H{Sa)@yfy+jpl)([@yUjaȷo\(=ߟ;;;i BngϞEDNWYvpY@C)ϲh4\{7.P`X~2:׿޽v*6@6`ր'όnP'qcdfCG^tlIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_visithomepage.png0000664000175000017500000000254212110457565024062 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxVYh]Ef朻i4.}IKVb0T *Ji16u"֗H}qbhJK-T Im51Mg97w7l s30nѰVC^#c Wunh)'_jE %8[X c'Z Ē@eXa0hr@d=N[`Uu1DBxuL q!p[UYXFWE`xx_]FݢE'!w8x7L0+cАi X !3iahֹYdSҪ,EkV6] P &qm4_C M3J2òb@@'mۂ8Nh}jz }ƗC2hy{f;R 2J|j|݄QjrO1QJcSE ykyE6wۨWb,g˷҄(Jsq J3䡏97S3ARx,hF gVs&%4VѨHP#,˂*QlhuHf`'IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_copyfullnamestoclip.png0000664000175000017500000001021412451473236025306 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  @+IDATX  KZZ[Q KRRRL xEK9x# Lj`P KQ\lR]oK (ڲ=&N{,,[ipbd۲kMh` ;65noRk_]]ƀ<,4A,SuNl^ʌ=)8=(+(L r] A);Hjh\ͅ?':7%vVoB[]GoCjlZfYɖk  3U ƪɜsnnĕg7/*@a{ƪSָl?  MrI$)87 ҩYSbykZ2  -FusF)-iJ1 ɴu  -z lh@m;  2EIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/edit-paste.png0000664000175000017500000000200313110262743022557 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX݋UǦhx$WJ .^BEb- "( EPVA*zK,٦$s^/3LI9Μ91eNxSӌgN :wit] TJ~Q`#Cp4P\nUK4\_8U6gYY9a Cml;] k"SԐio|XU_Z0.{h 2LHMӘCgdSzy'W??X"Yy* oLK4Y,9O[C7 orjiD=!@V0 _}۶xgmT8/<ի[(5Cuh죔K>?Nj>dsuueV"4u2naa۶Τ!"!Y9uEqۏ$\*B2STJ,>j` 8X4(X(<( 7ZMG3-s8-J ރbvЩ-f&/ً `!B;!@2  oсlۦP(D`gSoD`Xbó6 /ޡe zH*/l&^*@G.BK6hMO> R8]g6@)5fa LϽ :NI >+8g/^۫qh5[RV \W!Nv6砃;Fۙn (fgN5zxڽt7mTe~~Ev$ˀdvBOuIYX6;Xnw D?y|M@)CP `Ht_{#Q{M0u<:,G<@ oUEIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_clearlogfile.png0000664000175000017500000000401212451473236023641 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME :'$϶IDATXGV{l}srH2zcM #UVt1Ι fٌ#6üQBDb N#8@ҦіB o9|yGéa_QӴtڳæ@9>_owe.lMM㉺۹4 6 0l۶Ѳi l݌+a=8080oms?|w:wn$W 1ѥH|{/#uG]4'TdU/4ڜm͋Y>tL6!fGK~;H>&Dt#MF}祕| joƘA,o|?;/>= 2瞜 V*iߢPfH%[QV^ @ 4b1`xܓ3\_uA^iTZh _qM=NMWr'2QӑhyBÅضYȘM]GN@d. B#:W/FKR)$I.-c0s,!C;&t$ѻ;ԀDش+IEmzwMH3(|ϮÎo"T#q)[NY^I/r){W^t R… s{;T!Rzj\!y"d"i L> rc ?Io ^tAs{)̊QFM}Oȡ[/]VW\T֎v}(QVR:">JK"R B T͋Β,8r(D,gܘ|4EW>F EfRXz1*B1_|>̜6݄v='^Q! 0T2yqk ̕|߆B>,mfRb/U՗bڔIC#tܸEY4e C28 7\ɹsg 8U*=x'QXg3-@ӛ7-fa1cS 7-jmzA:PJ v/=$weيxsf{ nDIx%%Z(c@,z᭑{lŪ kID2֒ԒXrVa8E?3Y vST4n9xYl"I 4J4([HTʒA4͔~fO4{|U{|2L=^ le$'=ؙ*[F NO@=IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_showcmdlinehistory.png0000664000175000017500000000261112451473236025152 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME IDATXGW[hWffggvvd5[m^(A7RJ ZЦE`i C-@`FPkQ#F&&$dwvfvgǏKp8s. oq8Im[0o|tgpyip4kǠ}eH\s`[&R]ag4_A*S*00ӽR%u!>遣>^)$Q@!XF RvLCou(A@~k`0[~*wBdD_cq+%jQ$nBH`?*PPd>J,݊`(){\qTGݺ(  ^d?6B0X.tYxhbƫb,HBCyي4}w&,\u8mq BI5$ME&H8v U%i0.Iy"g %`w.-D"AEA_o/N ~;¥ G4"nO.#DB 'T,_#5q;n4,IlWsщ$Vpk0Wt>6@) aJ ÓI:\Nś*"dk=y>,⩧DI8v&2!ǰlWsyC¢wᛖ?N7i&z85"Gw_mhRwa ̋Y`j+ä;.*1 C_}$dOǠw, a)J*~e&T>=تʹ)+K"ܣjqۏ#Ay⌕*v,os19' T$QVFޝߥZ!\B.ӒM)7BlĚc=  oz a૯/쀘fDvTav& Eق}mCŋZdGbt(p +Y?3A IȎͼmy8\5zHz΁^qehjjowep"IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_shellexecute.png0000664000175000017500000000336612451473236023716 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME !&VaIDATXGVilTU-3E(%H"$$V 1)5cbCTLHjфOKb\I@Eb LXLQQk)-]6 x%@!)z$Ud+JoX'qԧ*h_^ZU3múGxUlք/o`m=a1Iy2;3{Ix1LۃAj@3HN"\3M'Cc0F޽ ~×B{s:[XXȈg^vkL eب"ƴc_X#](>/Ġ}g@nJlqQ,>)*! p]i%*~=&ibr,W8DzO6l$SU0/U#W" ڹsm{CDȑf1D*QLiСCHҨߎEssB1 PCʑzӦMغu1;O8"-l1aSR]G-ʝmC0tzfĢeݻEDMD+ Qb JV"s(㰲2]Yu B' umm$P$U/Cizg YVA_ӛ6玛G.f^FH?:Vgʏ؄/VtrjJk1Հ)(WgkA#WGV弰| 7dN7G iA #~{ߴĝ9r "lB `$A ,EF Lh% yb3Q0p+fJ 5K8xEQDrvQ>dr_dl}'|RP\Q_ss~PIsNyG%L̙@ ZF97lpJf#wza+\tȫ9@7y-LyJ%*5#0N48k-BSBsdsV@1F3Jꘖނ>vAB3z8wpH2[r trG~D*ݫ2+"dv<@D0'OD43ޑ_yu—"Sz瀗<&e&\҇ Ϗhg:&ցt:#l#a N{?ɛed] y*<ϠIVg֣\Bb |W@lSsD>DJ"h)q8.mFD[ ehD xE$(0YGUAWNbڵ ʷ]U!y!cv_'w4g6fhCCLGbΝ8X~uυ>XAmvXKaTڤUtĈkD9K걤1Dz&-R..󜉃LvHy;2]1H{HH轀3ZF^<r^*IzK=G7QFdoKIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/list-remove.png0000664000175000017500000000047511323355446023010 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATX!NCA}k8 p pE3 HȈRҤo+7$I$g_>~r }绋ugv.^N@)5Ng= ^HKc/Jj{kT퓦{5Sd L07-Mj%/^^g˶o^UFCj.a&c?pb>RUf/I$I2odIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_focusswap.png0000664000175000017500000001023613112333276023222 0ustar alexxalexxPNG  IHDR szzbKGDC pHYs  tIMEO+IDATX  K~JPKL6vP9|K nJpK ""    >>AAU*,+*0#Z X _Y eTM\} !!Q 6U0(969@#lQ;9 fI_L^9j! .$ tPoMs B~4P6D*9 333zȪ 6 yzmE333;j<WG,~n_E333"""333t_E333}@333/// + ~ -Ny(94@?IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_leftsortbyname.png0000664000175000017500000001021412467744673024265 0ustar alexxalexxPNG  IHDR szz pHYs  tIME /,hX+IDATX  f#Eh /ݻ}!Cf(/mD(/!Cfq!Cf* 1@+lޒ@+l* 1!Cf'p!Be*!19'Zߔߔ9'Z*!1!Cf }(Or+$22 F2 F+#1"Cf +Qs).4.4/&1%Ek\; (`(`*ҫ` 'Qn֮M o1f "+*$ {g0n<wqpgu\~f֯Q 3 NzIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/edit-find.png0000664000175000017500000000314413110262743022372 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATXmh[^]ٖ7َ_j`[RҒMIf4Qؗ 01ePɖt]^x mΛ_f/8NHeɺ{!)v¾큇sAiJß1<4}/ܲf|Vnfx3~V:B21H}{9j'o[KU@)PXBޡu|Z'uouu󝷿Dvr)N S,sQL q;?ā0_}%r|AƁݍwŴž}/'!m{Ť{vos{ÁhNMrQS?4ĶۙGJ%Ⱦ (2/7f "M CZDZ`CT[,3Tϕ\u7e az~ SϰLk E I Kw-r{0t$@y&MsbH`ˢġ9q]L PYI34m'#  N#K* ̭UWW*}}]= /?wPeraFZ1 ~sss՗xloD68+$2** ز`G7CLMMH$n\RѦMܸq(羽w~!#3<꣺B0,F兩n"m5%IϹzcc /Auv2@"6>'m \l{&thNgΜYb!Rz1MVVҌ{*vCs:1I,O?PDQ4Mc|b1,ŋE=j_p(@4Eav6(3wI.'~p8B=LϹ_PQQA0n0??dv>ʵkWL>{Ote5^=A_rUv|8P`]s.8R>EQmx<z\ܿ%]IR,//L&I$$ 8TGbs۳,FZ67 vzzGNS k`)FU¥K;vVw X}Psj W $M?=ps|9s$ 4 M<8^L1i~D.@z bY lyIhNzBK7F b~MwsX݃{Z{'Z\ "1)*bZ vBGMsnQC0,j aUϫ()C:տSDRb5]#\Bk-(ȌD { )i3v|"|6 >S34qK!g a E?2*fg", &8:.Eh2z\ Ơ rlnhG-%䄀-*Sy J7(0@ ZRR4R>YS9 ά, !pMwHq~w3he$dR0aXU]nAKynd"xFޛP9 AEr,ǪgKiyٓ%|>tawm+ ;G1թbٰ8.\C\&U Y"ʊ",b5";+ BI&7YLZyeeeHi^7Rc4>7n7D#I9 F4|pn?蔉QOgw6O$vivLs' /EoEc{"}ڢ7X4 g;I*ؼm?m3 G,hsQ͝.A!Vu&o+8D.IKL9iS,v @1)Hki)ډ`I [H֭[>D$zvIPX7t*DaBOڏ1'qI"܄qzNZߣIr,Ęω$6X>O7Xol~"|EQ7F5S9bF'چn;ū)ejGx$Mw7q/HD"F 3ƪ[G KB3IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_openbar.png0000664000175000017500000000130212451473236022636 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<dIDATx엿kAǿ3{{lK$v   6NզIBIX ,,{w;9Y0~;{̱,P(y8Xjq0j[eD_uޫq^L:-WUV zI4 s b# KovҵS=xlm &i6m6_YO?0;ssS:;w] '>_:acg/Vdb4@/Is?Kvt]`}ƈ6UQZ?:g  +(1 /T#>vmr-!@/?w{rP`/+o ~ H̤@ceD0AA?~7ɽ(vѨ$PasG[ͮpƓ7yqq<9gO\9\@h N%wi{TQa٠,V3fFse&L1 0CO.% 6<mHJLll`VqrHGF* ,Vv-ׁQ3IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_checksumcalc.png0000664000175000017500000000245012110457565023641 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxW]L[u?0BtM֢04m/64~L>*qh`o&&BLtI1ւ Ϲ vxå9ϕa?ED"{ up= R)̩Z[r/2(I>dpFO8+(*3??wňHQ\k\UWW7)T.SJ?)ŒP(K^f߷n233hFGGA& "= O` (9333abbn6\<6+fxcSZZZ -R Lg3 #T3l*սJ.ލ -###?P!$Z>RݑZ-Z!ZuƏ;\[VT-fۆ\P_ڝپ')IF-,..Ғ`|WKՃ#K$^BuZd)n7 PPPfFd3fԿ| 0N6t>lRBԼcqKPz\. {bp@YYlۖvJhNMCC  Byy9h;  R/m6 ܵHORZRv0Lmp#PRG1W,+zs0n=ӭxO;/|u%, (v b^:1ENv#c/x?$҆.KKK  Xor҅jyVinn.TV?9؂|dc|Lpn61AFXb|s'fc0ƙ'rhG8P*@!WD~i@@0Sqhf|DŃjz@lzJSU-V< Jk6@g_XcZ 0-le,_IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/go-jump.png0000664000175000017500000000272313110302615022100 0ustar alexxalexxPNG  IHDR szzsBIT|dIDATXV[lTU]53iki+TmR@J?L5ĠclJM aL$Ah*3myX>g:<̽0SNv9}{f?7]Hx~1 9QFO5}JC' }jCQe8NtuojU)!5.ٍ*D@.$Kqҩ' /\Xbp>U L`a1<I1Bc~ $ D5esrDg)LŸ QLHEhmkS.^m@ཟ!B^ر2'QZo93`t(m5 ;ŸϋK/x^4GXՁ=kzS*?~h$Ui r͉n0;9r L* <ѣ8k=unkO~GJCZL|aZoQ.G-ߡob? s3 'm\,>HJy#3%'kḻ89Xѯ}64{KC09! 椤%5u RWs% oj%7r"٘</XOҋ\[}Ml_ %*8pg ]aXyљ VaG3!^CC$ɘ{NS# j'>yts@{c{4S}H:dlj Iԁ1g& |@t uodВJX:FDQm _|*a2#mհW$K=[)aӊ+z}$^ICtnq o}; 2ML=P\ Ӝ :U)wK:]U  BXTj&x~r\kAOuQMY2pe`Scy# ToM(Y1N{eT4V`.cc<ޜ|_#,FƜ/B yYO>u2%2,g#ڻK׭C jyS5֝`m\XpS@w\2;Hen;%/Pb )٦,g6[gKo,tP`M5U)HM9}t%2MF-i@CV@dH#miH͵ &! Zh積EOid78D:hfuXb"g"@KF-Q<_m-}mIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_copynamestoclip.png0000664000175000017500000001021412451473236024423 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  +X֋+IDATX  KZZ[Q KRRRL xEK9x# Lj`P KQ\lR]oK (ڲ=&N{,,[ipbd۲kMh` ;65noRk_]]ƀ<,4A,SuNl^ʌ=)8=(+(L r] A);Hjh\ͅ?':7%vVoB[]GoCjlZfYɖk  3U ƪP7jP7jŖts 2QvzI$ǫ"ir7 عܸvwO@C\zPAP3VM( :XqqS%KI@ ›uBM=$e /;WPdYH:4L?3 6k- )/.Ȧ[qE!:v_[eGp_*ED>2  -FusF)-iJ1 ɴu  -z lh@m;  9&IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/go-up.png0000664000175000017500000000225111323355446021563 0ustar alexxalexxPNG  IHDR szzsBIT|d`IDATX[lU5{OO{jCXD$JZM1T%DLDD1KO $Q  Q iz93{0rz5>==k ܴ봅;)bn4w=)_*6̼}W~[ -+3-rJ= .?_)vMf&Sl_rg>#0 .lU6LLtb&uk8--NCZ`ĚX~[{SnC:Ѹ=1g֝s "8 !-Xs״es쮉+PQk*]ʲ5'0idOGo#K{?t;JM?P^k/:c3U㿶ӝh5<?CقoNV\:<^1bkX,U-=k`^<&_=meunc ]_s_j:~n %+ }GJw4ڵ_VW/*:]N@U#QQcςg1J@E?{3 `(|~`%5ߐ N5!sHnax-]g\Xm[ۛgݶX玍5liY7hލ5;!1ؙ} $=m8 Q@*5PՁ ?\W~x0[f_p*tg TbAJ^7``PP{;#$䋑P+K_Ə$q\?GB;9wNah~ @ $FZaRKIh$Q:Eya&.] c)MalTfπ+PPoԆ1πg$sH>O m UIQ#:c  022i 4AzGj(VW_?T0R qP554Kgde2&l˂CD3CnPh'Ӵfg<9ioご|~IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_editcomment.png0000664000175000017500000000224112110457565023522 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<CIDATxWmlSU~67ltl&Lf|?DD*QBh4~#, 10cNLFbM)J˺i׮VҲ,Ϛ{<=$l2qSO~eUw$BPv% +ō//}nxƱ؂4ج]VRF5wt~-@^hdC+n#cM? V?$ Eċ::i`(?s":}5}Zr?fBD#l[`YU@\c<>8O=_yv Al~'H7WxDB349;`,`.8NpCZWmy۷=p3'%x*[D pЀVu}[,q<:eMl6NpCZ L'M%.3аwd}:-S3ႛ.H-XHr.9| (RЀ4 q7SΌ@94 ֌82?㞘sQ"$Y6W$!KދQ|>C92kZ@, |R)'-h&vy}Og߰?8 hA3Ԙ74Sn+pcε4SoCj]ñwVܸ Ӝ7(}6J`{#ADP굯MKM&lbiqKoo;Qpk7Wc4Q\Q0pSUbwo{S4fu*=};D'zis]#w1@ڊffS+)lX ͧؐ4c@d'ޛ x(cfD2}KTF>葉/n <્qH[i8@^}W;bDg2rH˶5>3m}b3ͭ_øι[*78t!*cbŎsAwy.ol ]m/8}>{?@1ґQdENf^hu&ɹu,͵rḝ,IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_quickview.png0000664000175000017500000000274112110457565023226 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME"oqnIDATXõT?9;;.m\ #ZӚ֥ $DM@hDciW`ME,jV,syޙ]` ddΙ>nm&K%Ʀ͛I4 5 m«j^Ѭ cGj \h@!# 5<eFGغX 33<ƺ?<ay_UL\=ie6cݺ!hG#p*Ƴޱp`o^޿zʖ-\Edi& 'Qp/1֑?0BT94ӻ[?\636qCѬR,qR[i[BZ=OG:rqn5&r@xG?(|{\cO.WPպ)0\7VZjM~{Ls^{ep)7sa"ח~ή,[`S|l{hVy_ܿ(g 0fsy40}%HۀՈWԞ[9MY{DT1yr?B`XU&2"zB37-'?#IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_doanycmcommand.png0000664000175000017500000001026512467744673024226 0ustar alexxalexxPNG  IHDR szz pHYs  tIME rgiTXtCommentCreated with GIMPd.e+IDATX    <ePei" NhL ӆY.$ '> " A0%  *4<%J -?[ U0! JKH",8 )*(%          -| u"TD), MNa2R2 FdqJ #$&  =J`ߜ> C  H<Z1  +@]Y|?+d0_7 jo$t"G6V$Mq%  ZF*QqP`M8dFxIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_settaboptionpathlocked.png0000664000175000017500000000210712110457565025765 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME8#sIDATXOlTE?3onnwBST֪xJ x11jRI`<czу$ Bb`KPCK mvxm-dg~V%g>~pްrjޥttǛuW~L1{߾߿O66F2|gW_>٫ Ny^qkTtƞu1  b,j &&pי TRJb `l.8FmJƲ&jfc-! }g]*8_JSUڴhk ֘lj!1EWOӆ:>U.:,,y 8q^^<Ƶq|D I6%u$mţAk˺]K'εahLJgWh+䂢OtҲ/pEbGXhh@_oDwYeL:ˉLLZvwl6*BE8F2Զn%^aw *L<Z #Օheߡ^\G h˭YG/"Ly. M~6o.9HGH:C]ncD H `5q tt0 0nDZ{-˗ \5Zrdzg3p6>QWXK kxua*=ŕwދH M 0?>*Uqc/<<,,ꍈ˘z7CC=Wor*^(;HVCT ֨0@6f͒^R]Cuf>l}Y|gmA{3eH3,4dj@S wHcppa}!L_~ ,Epg mOags5*-PA4xEOC8lǠW&e2ݫ`n{ <ʇw։ab)aV M#Õfj..4Q(7* PپO@I0H0PRrmDq`ZdSuהP=Fg%c@rJ(dئD3}$! }T1 8XsIdx`_(3Exsv9 mFŚ(hAGy$\˞J&gAէBkta1"T<6I(Qh8B 87#D28P! 0$HqrFH;ueףG^c}T&xg,KIҖv1Q T0i\U29HW>r&*n| IWUp ,o7P kF䒕Ǟg|gt8eҲF{ޡ-cI*eM|oV[@0|zzI2()WMyɮހzXF~e^Dd b9!"T,]L|$BH 3`Hug:6:*!3"igq*'P*D:5XK0a`qjP4AC5йn.R"$ ʂ؛h ;M eߏiz!јcA[JhjCt]cFğ ͠I:)7mc;NkpS]#dSՈ)Y,'A"w\K`RV'HN亍LO/”vIu>Eߩ[)|'LSȧ1l% DcId6jd:52Y=#d1d7+|{33 4sok#hIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_sortbydate.png0000664000175000017500000000164012467744673023412 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME *]-IDATX_hU&"VAE4miERHQP k(y S!JHR *QDSFXMQv;ׇvfݵ`˽=s?+*wd\w( ;lbP|N &Pv Sama~a* w,;s{O8Q˕};7.-c .l~^LjwZ*twㇳ(Wӭw (F8]G_uwN!i –_uPMXƱQD!зk#6uSsDYq+cOV@%Oȁ"}cV uBZ ij P'H"ݔc*?iϮ @]ZρUpiՐ[ ) mJzcacTTwDbM.ȁ.!mN(jKP gX1@[t@)Եe`:./oʒF$:8>oeɌ6~17vWo 7jYkIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_leftopendrives.png0000664000175000017500000001021412467744673024260 0ustar alexxalexxPNG  IHDR szz pHYs  tIME  R+IDATX  h Bj -2~KP -o@,#ff-GK J ;d" &/4&.5¹8 ,s Lg;)A/~KPxF/%ff.GK J.";d"      ¸ ¸² , (3#ι:β: |~KPxE/%ff-GK J.";d"  *(''`a * (m{ 4D~')*]]]ry()+\^]z # =^  !Υ  Rz ]!X4X4X4 =^9XtM#%Lp@`ʽ|s }?EAӢ߷xSt ~]U..eD$IK)s~3@ }Cn#e!XƇE]70-m]=kad^@ q$ %A )$|t}p&_[7U8y^e].jx:0+KrKdaX!P lWr$HlI0m3=6Yͬx)w|e"y`D8S'<&"F: &x\H"خBMb߉)ronmܸ(ۋo2'q>BI˝ vq3kwRgp͖:/177 @M 0f4Iv p*/>, N]YQUmk[cO2idmxmtF.i_pjH$w0XBL }f7{G 9w> kʷ uGkª8eME"9.^%8c_GO, %F,F%Y"/uvj}#_ TGѴPw枹Ա /S֤w?ڌ""/Ep UhP{'dt!qvKA hX~ɚ.q nIoK[6`{Cۉg:9@{@ݘ&n?s퍽ͅ{QZȒEJ)eii cp$`6҆d2&cmf}_y5n̓@r{Q8{s)*[ee5zQٗB 9*׈}8t\?Y 篆L*j~w;8l"1XN~aAX`l#BL ?َ.S!F=HA^UK /x!Nѻ$k >_=ˆm2svIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_exitfromtray.png0000664000175000017500000000254612110457565023757 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxڼWkU{#ͶALM_E B Q(,}_A|I@(Ňkj_TD 4iSLbSj3s;w7"f̽7;lGL_:C~K3r|Gvv~*azE* %$Mp*}kzm޹`Bn@7?edQУAg{ -ܘ2@׌5P*~frٔ(ujE"0bõqwiB+2kBXM dDmtg+M#X+Zn!=97k@+3`K)KQG밢$ Ij~vF||=F&@D7ºJa{I(5@eeh4QgMD$]x7"ʡU@Rr%emGսHxu<ۋ9()T`Ӂ7G*Dt,EBV#r}%u/;9 N"3.9'VHS zWVsncb y5/n"4qyC3:h  ?zc=(mG^6YqOp?xKb T5)p&2d|$x6xbD7IrT}- \& NYXV , XSSPR.MO!3j>a7.D"[сq,lɦR!MCuY0%x8WǺP2xȲqI*Ե8}>u(8ut|_IMi;@ԅ^Wf&&VP:[715-O=".Mm38{}wDk˜JȖIQKyv(byAfȅ6~\cr4#,KVtp zi@گu<xs3!/VfL&(*n֭r簋?Dk p 63Rȷ0M<q.̏&*SXsEDo^&cFrÍh2zKm%#"2c΂ru"rn grŞwm/`o y;^Nd[ɨW](YrIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_rightsortbydate.png0000664000175000017500000001021412467744673024445 0ustar alexxalexxPNG  IHDR szz pHYs  tIME ,,E +IDATX  fFOxTC: QU({U f 1?C:!QkHZT:)2-߾{3 %<#C;"R`@[R8)2-߾36!G;#6R5vzE.v)1-޽~31(K>%I.W<'W)/5ܽ%3hI:C zD/D/zIB~9)%r2BvI`+16D4",  <:1;?;9gf[b! 6:fő; f L}BN+IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_copypathnosepoffilestoclip.png0000664000175000017500000001021412451473236026671 0ustar alexxalexxPNG  IHDR szz pHYs  tIME 4;+IDATX  KZZ[Q KRRRL xEK9x# Lj`P KQ\lR]oK (ڲ=&N{,,[ipbd۲kMh` ;65noRk_]]ƀ<,4A,SuNl^ʌ=)8=(+(L r] A);Hjh\ͅ?':7%vVoB[]GoCjlZfYɖk  3UƪP7jP7jǫҩYSbykZMlٖ`K}}C ֵocS+4 j[ %(/  ")MZ7ʣ\WNd^=Lr$ifڣ qy ?gTA    ɴu  lh@u;  :ܸgl_IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_thumbnailsview.png0000664000175000017500000000245612110457565024263 0ustar alexxalexxPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxڼW;UcfCvE%(&aMW$$bbQ)RYHaEAZDXQb!>PL*mš Q-I9眙[ܻ{^w9#BȞsL/A!]_. { c-m|KTRsWzN-߄V8&fQg;m!! fcِjzG\(m=MLDxp{Fvl֕[ D0XYY MTVT+Ţkh^8e 1^8oicUL=bTFBeL*kZK/#m:udQp3GAP1;'%n %$5rs^ ΓES~J9FxC9?xФ|5(ZbʃtnntƷs$Hd`ZQz \s;K~Y1&PF:Gyo/bGJE ׾+&rJ <^"vT@|gɸn sրy!,V:g]@2 q?f3 d}v@odS|; π\zKߟD,n;L?&紐.h,};<-0pՐW^ۆdR}b )>P焬K+Mt3'?X5 őj88AIJR3_귨}.=!?zLN~Xb`f=VdB oO P̬^;d؇VXc @w |Iܠ„`Iukb7#7ac0N|d=@S\ҙ̚akthv,=( Gvp—qa[b`&l]ql@J;N Tn͋E5#}F*-}=̟WgB =7][ow}qLe*cr \G̿}akNo v/O {{Jyo ,, j>)IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_panelssplitterperpos.png0000664000175000017500000000223612451473236025521 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME )ϩm+IDATXGWoTU{3 LL(%XMXL[ lqElqR[)(AˇM ICJ&2;wͼf4gڹQ}b0Fˆ9i' &Pa++e͏l-͔ZH [8>b#~%ףn-Ae({ę8r}7!$n!oqE ^Ƃؖ!, N|PT-waq][\&đxJtcC]*>_1P;I<- iRLd UNq!KP&4O@j5Hj L d <-Giq⹖@),+ZHaHᤒ3'q%%h%FxvA+1Z 1`*/U$yrL1`JH -@ ]EgnrO!@83ɛG&b"P8Ӳ`IC7euNjHs8xwvH@÷ }X#<;o?^ⲧy,bw4HMqọE q{'0?*zlB9DC1`٧%\{=Dwy{ ^>A ]Uײ|JzgWݝN1Sa3 ޡr+ᥣc0CRw?{Wbn8 ujU$\.^p~?*Q6i,ݪjnc<Οpt78>`Vى .ߓ YMÞ}[_\GQ(1e1 xI|!0vpA*z#id}/&IJ؟ P 1xzf /n(~0&9(ټ7^g}"]+jMI,ҏK'=Q$a!Gu_#H9VϨWwdҟYcIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_resavefavoritetabs.png0000664000175000017500000001023612653202722025107 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME51F+IDATX  ___L]]] K]!Y" GNP  "]W $ ?zL T†V=vO iP; RÊ[ eN: : eM:ª  ^3    |^?'9%%i9)r*MhwD=y%)=f# !ߛ&G1ڡ!e  UN9 y''(?MW***)`ac&=$Õw! *n|n{ *€KDɇ-w *iE *Px7yӉ7E~'()HVZ}*)*HUZV\\7Fߚ8*+ ( E1Ed^ xwQ\]  J:d !3Zݿ+˺ H! `<݅eF eDЌ$8#K2 '0tz d#[67ym'K 7ym [6[6 58%%68ag_YA  A   GHJ    N`6`6 N       k!hQ!hQkl iU$TΕ4ij3%3$ʿIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/actions/cm_unmarkcurrentname.png0000664000175000017500000001023613016463506024754 0ustar alexxalexxPNG  IHDR szzbKGD pHYs  tIME  힘+IDATX  ԃ`ՅhՅhԃ`ӂ_߆Xɍ ݈ɍX߆ӂ_ֆf $A2_hCXjA:)XⵗyOU6 K. -O 5cݭ} 2#}L ;f'pΕ!DeFJ %SWd? ,,p@d|hA zMUt1 ?#F -* ^+C9 ݱ EO&z(I`  r(H;Pӄ: "  1vZBxZ 0q-|Y%C |(BjS_I  pn %ʞZB 2 8 ! @,J*        b.}]ꙻt"M %e 1fa.QV ' 1^ Ҥ  $ 9. % : ,* #& 5 v  %( =@ַ #E?     3DCߥ      M 6J :K佩 ediA'/,   ")ވ9J ! .)6ij:$ ܇)3+%, vI49"x$ԃ +*2 %/ք~`c5=yN0;Qπsi&;$ =Fk ޴TIlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/text-x-pascal.png0000664000175000017500000000317411312762055023603 0ustar alexxalexxPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[O\U]̅aJiSZS XS륱iҾ*j7h&&5i4hME(DJ "rœ˸wd xۓ}f9{o}}Ea%A0X.'p *[UX Qֱv@F0 5Qu4rBHTQN#jlly9$!@&-ZY&#gbrM64 ڻ2+A4?fQLu]D"hll5jl>VOЃrcGGx%Xe'EW&P* ĔlQeTe$- >SnJQ<8B"3 x/ 66$DT2jz?"-8kXK\5si{|tdD+|> lg7 j^,Q@pJ^vuu$]][#)\/-ra=X&Umμ# eF)܋X^^FOOfgfH zP[[ KNܼy{E]]d࠼VUU%׫M&bJRHBBU]]M<{!^#}x]EjF+d*:8ri"yCŝyQ#h sa syu477jzƜ J۔ˏ? h;Nfܸ+bߑv-755 sdJFȀ5Q{Cc;0CR^ *TB{`]|!`;6{>C37)U }:98MLzE]3wg]´ $-`R)WVVXT4` |094jrڟ~ 'Yv#QX#s ]Y` K:DC[,"^4҇Ȧ#Ӹ2,/x6Tܵ\qmG0 Bj8S@ 2z1&'C%IgϾ`\=TJ^UXA"m+Bzݻwow9 V'}qbbp_m# 59Yg>lQK%@ ot_lKDJ(@TIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/x-office-spreadsheet.png0000664000175000017500000000233211323355446025115 0ustar alexxalexxPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE װබݸ߸ǿ̿@(tRNS $'(+/189::;<>?F;IDATxmjQg۴VbŢdЛR R}ק|;K[?\%Ij4Ls&$3H7X q$qh@J5I(>R)_|@(`i)?w]-<ZSK+1X`Vc?eJ{/ی3`]Y*$/+d *և eFonSC+6d^6Y-`?$y*QT 8'.9æX*XTH} TqK, b9&3`flRI x E!u"m * 2wum( %@ I<2*(0~f{c7ƀ:$^MFQpc 8lqRL PcPXA:iCc)Q8:łn`lRVe 6޹kRE:@@e-.fe>x6Cy?'U)1F#r#ɩ O6OTPZM8~}2! "TbAv"%-U_9+> scWs 0S)Z۞E7 7>Ziwyh!bݝHzadMP(9yek§)UC6%)^=ajF7J0!ɑZ@ \@<@sm NǍ+@2Uڻf$F8Ή^B_E1?awlLH]Qr=6Y"jrvLl.YujQ_q1 +[䮝+g.L&pyR%GuDhl."x&Zs ڃr5S܅qn>HuӘd@LӮ"2&OX+bS>yNꉅ35i<ͤ~C`־'sQ=@ɦl;20NwQr&v H@Sȯc @.!M:zg?@ qFzd#&18(g6qd:y)zŗ,gj6ښ{SnlluE! MGϬ;Rč!ulq]$ fZWVVݻCz  E8.p"ժΝ; ~:'H1R[n} ,ɾ > { ?es_T>a~9∁k!O(P6FY^HܜeDRIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/unknown.png0000664000175000017500000000210311323355446022603 0ustar alexxalexxPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWKhQ=3TX"OVU\D0[,EV).ԅ•u).ݸVpB~3[65 3Ɍ&ϗq/#ys71|Ga5<, (',"x0N%P@D]qX'że!^W " Ժ -LSGj%7\+B %XΪKaTrz.Ts4 vejV(WNfP.6kh@$ 76>98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/application-x-executable.png0000664000175000017500000000321311323355446025776 0ustar alexxalexxPNG  IHDR szzsBIT|dBIDATXsTUǿwNҷ;ktHЀ hʒOS֤4> >X5%fE :AQB;[ol`!I{nbgVꜪ{|WuvtwjL%^ꋿ}$kg~^ CڇmǺN<:Ic缾X8FϸOvtwjC>;-(UD[vtwӅW^{E*+7iYzf§ǒض@[G8zi閧ůA C04߁]0[,< q7utŸ^K--Mvp^+ic 9oGCSےx@[G1p!iϞfD@,DK8dd[J-P<|!TC`|Ufw㘻s[wBH(tRb>~#;>6'g {q%Q9(PaNDvs nv}~h?} L=QpFc&EgGܜ3p{;&IAETp~Awm b4++)pTanaT};@DXLʵƦJݚd dT7kH3طۅ\}}ShO`] &xZGfbQbM Nܽ'®TC(ʃsBm7bmU$rՖC1P]iNDCa;a*VO^g[u$-2? PUPlq:B gm,f?]Noo*`FVk9?zp7dYC*$k()P_WՕiC1 Pf)mr:V_R`DÝS*(@9dQ@nG%"#ܪ08@Ot&P;2<t8jH*2aV Xp * WyxCDӳwdh趟żSPvRjuG"siQ{zӪ9n ߖ@N"hwbɊ*rwXa.)*f"Ғ" ^Oozumtߗ3$@P@Oll<~% M EWR,ch8w{..KW9Fic:[k'bnki:MYٞK|/?~gkn<xN@2DAbf:+U*&rةamƧ'r=7B@QBNB dDd'E+hΛ_0@@-øf1/ s,n5~cHiCRY$h ekq]!nnOÍ1(n׏+?Fx~2M|"IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/package-x-generic.png0000664000175000017500000000135613063505653024367 0ustar alexxalexxPNG  IHDR szzbKGD pHYsodtIME )&-﭂{IDATXW=0}qd7Ynr@=uH ќ T?hit+E8ndN7w>{Oo(\φ8o{ۗCG?a_a0z=Oj1O7v 2@!2 2ͫq-.Ip80lEUJ @c#rq@7h5B@)X`}ӶR8.w=`@aBL57c G'ӓG>Ipn_^~zDv9UD;ד~2!? ka(9H'` fۻ{rte%4s)E8ȗ릍^{r"Z*cC{seD){sna*B IDD1c"QGL#?R_jhLD?bL 5 "H HKҖ>g33ٲ ~{v͙sδDsftuuFP/Sh`F69mڴ݌8omk(1iG c9- , J)X)(5q\qέ;?yt6gy]=D29aB.{PLJ”,*\}P_Xp9(0k98" _E(׈߉i‚7_y]/\LPiiJh&5Pku^Wv.X-5z$NA ν,]Č<CHEo`#M22Ve847N5ww]pvj;fy̝ P9m q a[t2U5=+z=a55zq>͏O{;`FC =} 7F!oI7UQҹEs=>{X1xa,^%<~Tfm^!W@hAXy>|wwq68r';\Θ/ ذvI=|xcajXAD,R8|{pix ϵ8etѫ+wup>=NȪ́y^eEx^ kW-(WAbE[r>2Wq`~>@1.[L݂L_作p|FF&k$WFd]ڲ#δDD!#@:n٣W*?86ƭ(`MD䠀e?Cy0=W FkwP,i.:a$]r:D)EI"H%7g.˘ptR=X;i $ &9:Egdt_!TM=B pkCH+˪cBp-b m_Kt RIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/application-x-shellscript.png0000664000175000017500000000207511312762055026212 0ustar alexxalexxPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWMOW=&dRMHhv5XcV P>ZO4R& ɢڐ a{Ff3J{{~~CN!S? ҀSBi??C)@9L%*?N@YVasX !E9#1K"5bvc (xUJRP{Bq"@WǏ199\EdrFn}d{‚fvR|jj Lpxx8L1uy\#c|k/~ p}4&zZ6Ȁ+WK899JB$ w9 Q86ӹc`qm[rW *h4p̾7oc>˨=qnPf#Q> h<(sدSgRW˗~9\'D㽽=0~@;ݝ5?.Bxe_C? ^w]_ؑ@dg]@ +OO6 FqgW@mǯ ߗwS{aTĄ|lszȃA ~B7j? P0wapZa||VJemnn-4x#.ȍr[r~{/k fff/T8(}BZ .-*Iۿ]`&¢QȧEWҮXdYسlPB𽈯h:T$)GInC/J;VP1٩T*/D| Ni aGXnK.&L?<3 IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/image-x-generic.png0000664000175000017500000000221311323355446024047 0ustar alexxalexxPNG  IHDR szzsBIT|dBIDATXk\U}2I26MlT G/',>7 AKQJhhK-VK[L~ə뙳/ˇImCA^}{7^Ź>xߝf-"xhpNNuNv.&Ja ϥ=8voLԫ\DH,lu~H'P $\{}|}^T*@9 iG_;[A) P:H.86D+@aZ=˩FV]]=#5]<ЭL:HJ-o{ 6"IeO^^* kn,LHro!K\6wt4A6qi6YAìy$7: mOP:BQ!TȌlɤnbi_FWI'e Betnz:sl:E/1t$pS#$Ą2"1KҿMvy]aH2Bq" "!?z}uiET֗9.c-Hy.0@kMP bAGuPG8gTKDi`L*vzsc,Ze<aL-9hFRp|qok-Au;C4[+k+9wf@)ŗ_;w/cZxժk̜319};9y0]]^x܅F ^r~AR\~pff~ ԁ -NK 7</?nײIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/text-x-log.png0000664000175000017500000000356511323355446023131 0ustar alexxalexxPNG  IHDR szzsRGBbKGD pHYs7\7\ǤtIME IDATXŗk\ޛ7#ɑSI#Np %R1!R!ݔ@LlM]l"hUpiJ1I#M$[H3޻t#Kcg77#;|;UED;tܹDQdC͐1,oŁM7ĉş1NZNJ"hϻ۫}t{'|򳥥w޻ҘA5 CƇ {A b~M3宱?Ν @c R:l}S'Hn)DG'O)"d>qB1^QT Jͽ"769TYnQ_xD sD9ӤjEUDvLMM177GIfH f/;FX]];SSDIf1UݕV##edX1չ0")Bt:Xc ENqx(.ɬ-Tu4'!dZdsss̰cǎ qt# 3VK)B18c4a:dY"hہ/P#0ā:X}'jA`] ZK##ƠZkQ0OBeȲl+Y8~=8" s<#$IRUHbWP.<}4z9,Xȑ9f@,R-:k-E*ưS>{ɓ'"jY~[[4rs" IG(=RSlvsB|W+>(q*ֹJ=[La{{ arr3>jqalTر;^v]:>Ev&&&HNWLsf񱲮TjX #gGL:rNY(KQ5HjʫW~Vَk-ZDּ̮V{CPU s( V~i:hYBo1q}ޔC1ަ^ :z{OQ9e9Bl[—j(BQ5ZnU~GE=z=iv}Q5L%`#w [c0"LL^nKEt])`(!Ib:$H5% "R~h w6)F=›WK.… ߼ީxr)zϿZyl6fcc>*y^]?ycLhZW^/7Ft:8s iRx)ScʡTș(l}۷o|e cl^n͛k |O?'xRyzi!cv^TB}yw^r /"[o?_tNLA*Fq1Z+u:/R왞nq\ׯ_iBhbPmPPnQFMBJt\ϙ vh*2! p(p!(#×(]3UMٖW}t$l,q,v"4 Plvz'>qE;u<ՕdA6ڦ][Y2x|6_u[b(roYcCFuzdL8v>^ LA#)ʉ SOWghP@rH2lہx!R1qP(,]U|oZfru17{1s kѼ\D<k$VﻅR5MG\T ?" +Kȍi |Qgbr 6&q3 3y苦?fSHP fD  㚚,@SLmcf)/=ut0{o򦅙Y ã&{°cIS0=[/ |u,5% 7Ef k/=%ƱdM(IVXY >pXu*l:$M]GP@ `L̠r"E| =a]Š Y"eDM[ Tt,[4C#6X2O*Q,ۊΝGuH.C7I$"pfl vP_lіe6ᅕKBt?NdY|(t啋Ey2K.C:Mv\ih_ӆIi3g7t]/#eb\܈D33Al`?zu]6:2*m)8 *'+h6<ʦ"S h<~iwׄƼk% H%GDE1I LnCL.&JB\mt_wNxYbq "(N[.l`YT>R\LxȽ ,& PN1z0 $X O(:G"%#vWpVCfqC AbA98dL&!קyA|x 0j-Gx D>EytIENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/x-office-document.png0000664000175000017500000000160611323355446024427 0ustar alexxalexxPNG  IHDR szzsBIT|d=IDATXAOG38&S;MQUUXȁߡsOЏ[.BBWNqMv;;9YϮg5JO}3~3cH>P<)%Q?aO} v<H7;;;q0 }u=_]} m(T*A`b"v AMh Yzfϳ)(A@V+HPh40*A{R y xrf !h4R0 P 666LOԐS퉦ۯ;av ]777IQο|Р^y)9: 㾭da312rrr2ǗO36Юfo6Ը`)b8NONN5z&>rTbe+++ |Wu||yXJS.IRB*hsU1i3 d}fek K8@_#eq>Vƨ@IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/application-pdf.png0000664000175000017500000000300111312762055024150 0ustar alexxalexxPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<~IDATxڵ[hgUZToJ&A5A( EM| Dˣ- ^@7HLc`4udݝ^fw\vc=0L,H3;|4IӘfSI_!59jf&30!J!N# 34!V6m|^/D6G bGF f2C*`,XݶS۷؈77·s't]s@N@%or}r7<ĝ$~_fFM3G.iRx XMN*J́mJ~& Ey}s`:ٽ?…Ȝ8\< õJ͛Q~M߽͛ ]g,>#m{^f:*u+41κrK"J+\먔JjBe^skh ^^ sP?|Hk@M pbKχ[V["Xg๳!GvxSQB` 8-pRl*Wy\k䳂]RxW)'7)Mʖ`bq"^c{"ʖ9$5LSpzm}*}~wqqVx؄ڼMt N0(^rhHPq\0XF4r\-{ # w.oxF!)蚆ihdPA_ gꊅ-TmO'nWL9!1ضB@kD.kCKq jԠ+\DNDQ>U:RͶZPg s5Ci9& JD c|ri֗143ߘ ^ǵpZʔ &JCdi9^[=Ϣ\}&ե5i*&-7C ÀO) @E03LYp O@罯gtS5JJW)j:cslc8g[cn  oOaejr nk.O>pbͣVD[ph֨^s(| FնazVVf!(>L}۷Šs H>0O:KdiwQi8UU;2>Až'" ǰE|&[`a%`ZϓfFLmPoyv?KV+@Ғ/~~ OTxrC-fm1!EܮR5'N%_ @OfI^-x`e?,Ѫ'Oqҭy)0xjAP+A$qAgfvv6^k333KLHF0R@rR_ ^ť˧O~ܶ -`wzt+ԩS]o&i-G0p+q%iӂ>9qGSSS_?~i`$y4ax`S=B`-Fb|75IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/text-x-generic.png0000664000175000017500000000356511312762055023760 0ustar alexxalexxPNG  IHDR szzsRGBbKGD pHYs7\7\ǤtIMEOIDATXŗk\ޛ7#ɑSI#Np %R1!R!ݔ@LlM]l"hUpiJ1I#M$[H3޻t#Kcg77#;|;UED;tܹDQdC͐1,oŁM7ĉş1NZNJ"hϻ۫}t{'|򳥥w޻ҘA5 CƇ {A b~M3宱?Ν @c R:l}S'Hn)DG'O)"d>qB1^QT Jͽ"769TYnQ_xD sD9ӤjEUDvLMM177GIfH f/;FX]];SSDIf1UݕV##edX1չ0")Bt:Xc ENqx(.ɬ-Tu4'!dZdsss̰cǎ qt# 3VK)B18c4a:dY"hہ/P#0ā:X}'jA`] ZK##ƠZkQ0OBeȲl+Y8~=8" s<#$IRUHbWP.<}4z9,Xȑ9f@,R-:k-E*ưS>{ɓ'"jY~[[4rs" IG(=RSlvsB|W+>(q*ֹJ=[La{{ arr3>jqalTر;^v]:>Ev&&&HNWLsf񱲮TjX #gGL:rNY(KQ5HjʫW~Vَk-ZDּ̮V{CPU s( V~i:hYBo1q}ޔC1ަ^ :z{OQ9e9Bl[—j(BQ5ZnU~GE=z=iv}Q5L%`#w [c0"LL^nKEt])`(!Ib:$H5% "R~h w6)F=›WK.… ߼ީxr)zϿZyl6fcc>*y^]?ycLhZW^/7Ft:8s iRx)ScʡTș(l}۷o|e cl^n͛k |O?'xRyzi!cv^TB}yw^r /"[o?_tNLA*Fq1Z+u:/R왞nq\ׯ_iB,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`doublecmd-0.8.2/pixmaps/dctheme/32x32/mimetypes/text-x-po.png0000664000175000017500000000354011323355446022757 0ustar alexxalexxPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxŖo\G?3sfΞqBc7$PPABBBЂh<A_ԨU%)M+hZT@J)4{;cMd]UBI?9;ߌGdY@oԭs lf( Ä́zܜ Y)yw$@FQ-x[JP}#XSrsm$mqgL-H1 tV* x5 5p$A!e[\(R,ԕk-DNfʦ#㠄@1O9)Y%'De $ZhޤB"lZ*+ A$=a—T`,%%Ž, QdBT(%+h&KNv%D SA7V윈F &&ƹwq'RI6{?~y +>%o6 ֚08 bX%_rc*VO>kI|9` LD8[7 3qr,,*"PP윭jb-/3>3&{MډłĪ(Egw> G$eȎfTDd:xBRaHzV YM&Rne ʛ E|_}3.1], lu%|Q~! M(R8Jd)&wxtSf|޾Af,"mʕTP4~+ȷ3@\B _ JA4N7Q2Z\o`\YqהƈԗwG4͈,Xm҇hjiA#K*),ttxA;hiAd+spz+̎ ]W7m^0Fey fju(h߼gptˇj%[8#1E)35}*1H[ERJ 0e "H(8/Yފ9%N|n8>t?_}sixK$I6t: Jc& C4 a:YE˘_KׯѸzfiJK4>y۶)8MU%K-!D$=O,LJvP;6 k}߳ 큻J]/]x+J9tvs'rkQ0[VEv"E |_?կIENDB`doublecmd-0.8.2/pixmaps/folder_src.ico0000664000175000017500000001712611226363660017020 0ustar alexxalexx  6 h( @ feeed d d c d b b b b a a ` ` _ _ _ ^ ^ ] ^ ] ] \ \ [ [s~|yvtqnlifda^[ \s}|zxwusrpnmkjhg^ \s}|zxvusrpnmkih_ \s~|{yxvusqonmjia \s~|zywutrpomljc \s}{yxwutrpnlke \s~|{yxvusqomlh \s~|{ywutrqomi \s}|zxvutrpnk \s}{zxvtsrpm \s}|zyxvtrqn \s}|zywvtrq \s}|zxwutr \s|{yxvtu \s~|zywuv \s~{zxwx \s~}{ywz \s}}{y| \s}|z~ \s~}{ \s \s}zxvspppppppppppppps~|ssssssssssssss(, [Cvggfeed c c b a a ` _ ^ ^ ] ] \ [Rk{wsokgc [Sl~|zwusqnlih \Sm~{ywuronki \Rn~{xvtrolj ]Ro|zxutqnl ^Rp~|zwtrpm _Rr~{yvsrp _Rr|zxvsq _Qt|zwvs `Qu{ywt aQv~zxv bQw}zw bPx~|y cPy~{ cPzrqpnnlkji5KyjzuklllllllmRzuFssszzzzzzs  ?(  \ \ ] ^ ^ ^ ` ` b b cd degjlnnoqstuwxyzW\]`deijmqrvwz~y{||~} A420.,*(%# Jia[SNKEB<75TmgbXRMID?;6\tlc_WQLGB=9!owqh`ZUNIG?:"yztld^XPLIC>$}vqia]VOLG@&|wnf`YRMKF'yeTH831/-+)~~{xusr uupkjdoublecmd-0.8.2/pixmaps/mainicon/0000775000175000017500000000000013244011205015753 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/mainicon/dc_192.svg0000664000175000017500000003406711765566230017512 0ustar alexxalexx doublecmd-0.8.2/pixmaps/mainicon/info.txt0000664000175000017500000000035011765566230017470 0ustar alexxalexxAuthor of the Double Commander icon is Андрей Гудяк (Andryei Gudyak). The source file is dc.ai. SVG files are generated from it. The "colored" directory contains some early versions of the icon with different colors. doublecmd-0.8.2/pixmaps/mainicon/dc_48.svg0000664000175000017500000003277211765566230017433 0ustar alexxalexx doublecmd-0.8.2/pixmaps/mainicon/dc.ai0000664000175000017500000130231011765566230016677 0ustar alexxalexx%PDF-1.5 % 1 0 obj <>/OCGs[5 0 R 6 0 R 120 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream application/pdf v4_3 Adobe Illustrator CS4 2009-11-23T23:45:51+03:00 2009-11-26T01:53+02:00 2009-11-26T01:53+02:00 256 256 JPEG /9j/4AAQSkZJRgABAgEB0wHTAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAB0wAAAAEA AQHTAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqhtR1TTN MtWutRu4bK1T7U9xIsSD/ZOQMaSATyYNqX59/llZOyLqT3rqaEWsEsi/Q5VUb6GyQi3DTT7kkm/5 yX8lqf3FneuPF4+H6ueS4B3r+Wn3fchD/wA5OeXqmmlzEdiXYf8AMrD4Y71/LT7vubT/AJyc8uFh z0yZV7kMxP3GIY+GO9fy0+77lUf85NeUajlY3QXuQCTT/gRj4Y71/LT7vuVf+hmPI/8Ayy3v/Isf 1weH5r+Wn3fc7/oZnyN/yy3v/Isf1x8PzX8tPu+53/QzPkb/AJZb3/kWP64+H5r+Wn3fc7/oZryN /wAst7/yLH9cfD81/LT7vua/6Ga8i/8ALLe/8ix/XHw/Nfy0+77nf9DNeRf+Wa9/5Fj+uHw/Nfy0 +77nf9DN+Rf+Wa9/5Fj+uPh+a/lp933O/wChm/In/LNe/wDIsf1x8PzX8tPu+53/AEM55E/5Zr3/ AJFj+uPh+a/lp933Nf8AQznkT/lmvf8AkWP64+H5r+Wn3fc7/oZzyJ/yzXv/ACLH9cfD81/LT7vu d/0M75D/AOWa9/5Fj+uPh+a/lp933O/6Gd8h/wDLPe/8ix/XHwvNfy0+77nf9DPeQv8Alnvf+RY/ rj4Xmv5afd9zX/Qz3kL/AJZ7z/kWP64+F5r+Wn3fcpN/zlB5LDHjZ3JXsSCD93E4+F5r+Wn3fc1/ 0ND5N/5Yrj8f+acfC81/LT7vuVIf+coPIpP762u0FeqJz2+nhj4Xmv5afd9zKfLv51/lxr0iQ22q pb3MhokF2PRY/Sfh/HInGWEsUo8wzhWV1DKQysKqw3BB7jINbeKuxV2KuxV2KvOfzB/NC503UV8s eVoFv/M0wBkZ94LRG25y06t4LjKQgLk5Wm0pyHyYJJ5YsJLr6/5qu5vMutdWM7kW8RPVY0HwgDwA pmsza48h9jvsGiAGwofj8bo1LiKAcbO0trRR0EMKL+JBzClmkXOjp4jvaN/dn9v/AIVf6ZDjLPwo rRqN4Ojj6VU/rGHjKnFFx1a+/nT/AJFx/wDNOS8QsfAj+CVp1e//AJ0/5Fx/804fEK+BH8ErTq9/ /On/ACKj/wCacfEK+BH8ErDrF/8Azp/yKj/5px8Qr4EfwSsOsah/On/IqL/mnD4hR4EfwStOs6h/ On/IqL/mnD4hXwI/glYdZ1D+dP8AkVF/zTh8Qr4EfwStOtaj/On/ACKi/wCacfEK+BH8ErDrWo/z p/yKi/5px4yvgR/BK063qP8AOn/IqL/mnDxlHgR/BK063qP86f8AIqL/AJpw8ZXwI/glYdc1L+dP +RUX/NOPGV8CP4JWnXNS/nT/AJFRf804eMr4EfwSsOu6l/On/IqL/mnDxlfAj+CVp13U/wCdP+RM X/NGPGUeBH8ErG13UiCOafRFEP8AjXDxlfBj+CVFtX1BhvIPoRB+oY8RT4UVM6rf/wC/f+FX+mPE U+HFoavqCnaUfSiH9Yw8RQcUVZPMd+u0kcEynqskKUI/2IXJCZYHTx8/msuG8n6qpj1XRoomb/j4 tgEYE9/h4n8Tl0M5DRLSnob96aaB5r8yfl4Y7qxu5PMHkpmAuLRzyntgTu0ZPSn8p2+WZmPMJ7H5 us1GiB5CpPoPRNa0zW9JtdW0ydbixvEEkEq9wdiCOzKdiOx2yZFOolEg0UbgQ7FXYqx78wPNSeVv KOo6zQNPAnC0jP7U8pCRD5cmBPthAZ44cUgHj3lfTZtJ0p7u7cy67q7G4v7p/t/GdxX57ZpdVqTO V/L3PWabTiIA6D7/ANn3oo5hOcsOFK04oWHCqw4qsOSVacULGxVYcKrThVYcKrDihYcKrTiqxsIQ tOFVhxVYcKrDhQtOFKw4oWHCq04qsOFVhwqr2OoTWcrMoDxSDhPA32XQ9Qf65IGmucBIMw/JTzKf L3nOTyo0hOha8HudJDU/dXSrydK7UEiKQR/MAB1ObHFk4o+YdF2jpq9Q/H4+59BZN07sVQVxrOnW 9w1vLIfWUBmRUdyAeh+FTirz3814bzzGNBsNOgkuLCC9a81B+DJxMMZWFSHClg5kPSvTK83FwER5 udoJ44TuZpKrvSdSaY0gYItFQmg+FRQHc+2aeWjy3y+530O08AH1fYf1IOTT7tOqb+AZT+o5E6XI OjbHtHAf4goS29xGKvGyjxKkDK5Y5DmC5EM8JfTIH4qJyDYsOFVhxVYckq04oWNiqw4VWnCqw4VW HFCw4VWnFVjYQhacKrDiqw4VWHChacKVhxQsOFVpxVaqO7BUUsx6KBUn7skEEgc0bF5d12YVSwnp 1qyMo+9qZMY5Ho48tXiHOQ+aIHkrzM9eNn08ZYh+t8n4E+5q/lHB/O+w/qdL5L85wSafqFlp/LUN KvIbu2HqQkH03V+NedKbGo98uwwlE7uPn1uCYri+w/Hp3Po8eYNLIqJJCP8AjDN/zRmU84jba5hu YVmhblG9eLUI6Gh2ND1GKpNckjV7uhpVYq0/1Tirub/zH78Vb9WT+Y/firjLIRQmoPUGh/Xiqg9n Yyfbtoqn9pVCt/wS0OKpdd+VtFuan0zEx8PiH0k/H/w2VTwQlzDk4tZlh9MikGo+QrlAXspBKB+z 3+7r91cw8mgH8Jdng7aI2mPkxa7sbu1cpPGUINCSNq5g5MMocw7nBqseUek2hTkHIWnFCxsVWHCq 04VWHCqw4oWHCq04qsbCELThVYcVWHCqw4ULThStAJNAKk7ADFBZDovkDXtUYMYjbw92cfEP9jtT /ZEZkQ08jz2dbn7UxQ2HqPl+tm+l/lXo9uA14xuJNiQxJH3Div38syo6eI83VZe1MsuXpHkyez0D SLNOFvbqi+Aov4IFH4ZcIgcnAnklLeRJRiW9ulCsSKR3CrX76YWCrzelORoOmKu5v/MfvxV3NvE4 qjtB/wCOXH/ry/8AJ1sVQF1/x1rv/Vi/4icVdirsVdirsVdirsVUbuztLxOF1EJRSlT9oD54CAdi mMiDY2LDNd8jyRBp9PPqRjcxnqPo/wA/ozAzaIHePyd1pO1yNsm472ISxvG5R1KsOoOa4xINF38Z iQsGwpNgZLDhVacKrDhVYcULDhVacVWNhCFpwqsOKrDhVYcKE00HyxqetThLaMiKvxTEbDxp4/51 y7FhM/c4mq1sMI33l3PU/L3kTSNIVZHUXF3+1Idx9/8AT8cz8eGMeTzmp1uTLzO3cyQUChQAqjZV AoB8gMtcR2KuxV2KuxV2KuxVH6D/AMcuP/Xl/wCTrYql91/x1rv/AFYv+InFXbYq7bFXbYq7bFXb Yq7bFXbYq6uKpD5h8r2upRmSFRHdDcEbBsozYI5BvzczSayeE7bx7nnF9Z3FnO0E6FHXx75qMmMw NF6rBnjljxRQpyDctOFVhwqsOKFhwqtOKrGwhC04VWHFVhwqynyj5IuNXkW4ugYrJaE1qCwP9cy8 Gn4tzydRru0RD0w+r7v2vWLOztLK3W3tYxHGoAoKVNPGmZ4FPOykSbPNW2wodtirtsVdtirtsVdt irtsVdtiqYaD/wAcuP8A15f+TrYql92f9y93/qxf8ROKra4q6uKurirq4q6uKurirq4q6uKuriqT +Y/L8Oq2xIFLpB8DePt8/wDP5VZsQmKLk6XVSwyscuo73l91by20zwyji6GhzTTgYmi9dhyxyREo 8ioHItqw4VWHFCw4VWnFVjYQhacKrDirJ/JflJ9Vuhc3C0s4jU1Gzf19h/DMzT4OLc8nUdpa7g9E Pq+79r1mKKOGJYol4RoKKo/z65sHnF1cVdXFXVxV1cVdXFXVxV1cVdXFXVxVMdB/45cf+tL/AMnW xVbdaMZruS5juXhaUKHULGw+EUB+JTirFfNuo6hod/p1tFP6y3sdw7MyRAqYGhUUonf1jmNqc5xg EOw0GjGfis1SR/4x1bxU+3FP4LmH/KJ7nZHsSP8AOPyVovO92G/ewoy+1a/ryce0R1DVPsSX8Mvs /tTO084aZNQS1hY+O4zJhq8cute9wc3ZuaHSx5b/ALU6hnhnTnC6yL4qa/fmS4CpirsVdirsVdir FvOnl4XcBvbdf38e7gd/9v8Az75janDxixzDseztZ4U6P0H8W85bNQ9WsOFVhxQsOFVpxVY2EIWn CqY+X9Fm1bUEt0FYwR6h9vDb5fdl2DFxnycPXaoYYX/EeT2awsYLG1jtoBREFK0pU+ObUCnkpSJN nmiMKHYq7FXYq2AT0xVKdW81aBpSn63drzHSOMhjkZSA5tuPDOZqItiV/wDnDYIStlZNJ4O5oP4f qyk6mPR2GPsjKeZASeX849YP93ZxJ9Ib9a5D815OQOxh1l9n7VKT849fW3kkEEVU6Ci+BP8AL7Yj UnuZfyPH+cXsWmafd3mm2l2966PcQxysgjioC6BiN17VzLdDIUaTewtBaWqW4cycKku1KksxY9KD qcUK+KvPfzPA/S2hnuIrwV+b22a/tDkPe77sT+P4fpYYc1D0Cw4ULDhSr2WpXllIJIJCpHau2X4t ROHLk4ep0WPL9Q37+rNtC8021+BDcERXPj0U/Pw/V8s22DURye95rV6GeE77x709IIND1zIcJ2Ku xV2KtEKwKsKqRRgehB6jFXl/nHRjp+pM6D9xMeSn3P8AX9dc1WrxcMrHIvT9larjhwn6o/cx45iu 1WHFCw4VWnFVjYQhoKzMFUVZjQAdSThCk1uXrXkjQk07TVmcAzzCvL2PX7z+AGbfDj4I08frNScu Qnp0ZJlriuxV2KuxVD3+oWen2zXN3II4lFanqaeGAmubKMTI0Ny8s80/mXf35e202ttadOY+0w+n +P4Zh5NSeUXe6XsoDfJue5g8skkjl5GLuerMSSfpOY127iMQBQ2CkcWSw4oWT/7xzfL/AI1bJRR1 fWukoU0qzQ9VgiB+YQDNo8Xk+o+9FYsHYq8+/M//AI6uh/8AGK8/4nbZru0OQ97vuxOU/h+lhZzU vQLDhQsOFK04oWq7IwdDxZdwRkgSDYYyiJCjyZz5V8yi7VbK7aky0EUh79gD/DNzptRxij9TyvaG hOE2PoP2MlzKdc7FXYq7FUk826WL/SZKD97F8Sn/AD96fRXKs2PjiQ5Okz+FkEunX3PKGBGx2I6j NK9ksOKrDhVacVWNhCE88naSdQ1ZKj93GRU+BNd/oUE/OmZWlx3K+51naufgx8I5y+7q9gVVVQqi iqAFA6ADoM2bzDeKuxV2KobUtRtdOs5Lu5YLFGK/M+GAmhZZQgZEAcy8U80+ab3XLxnkYraqf3MP ag6E5rsuYzPk9TotFHCO+XekJylzlhwqsOFVhxQsn/3jm+X/ABq2Sijq+uLD/eG2/wCMSf8AERmz DxeT6j71fCwdirz78z/+Orof/GK8/wCJ22a7tDkPe77sTlP4fpYWc1L0Cw4ULDhStOKFhwq6OV4p FkQ0ZemThMxNhry44ziYy5F6b5f1ZdS09ZCazR0WWvU+Dfhv75vcWQTiCHjNRgOKZieiZZY0uxV2 KtOiujI4qjgqw8QRQ4q8g8xWTWmrTxHuxaviakMf+CBzT6mHDMvW9nZuPCO8bfL9iVHKHOWHCq04 qsbCEPTPy500Q2DXLD4nGx93ox/4UJm100Kh73le083HmPdHZmOZDr3Yq7FXYq8j/MTzM2oX5sYH P1S32YDozdf8/wCzMHU5bPCHoeytJwx8Q8zy9zCzmK7hacVWHCqw4VWHFCyf/eOb5f8AGrZKKOr6 4sP94bb/AIxJ/wARGbMPF5PqPvV8LB2KvPvzP/46uh/8Yrz/AInbZru0OQ97vuxOU/h+lhZzUvQL DhQsOFK04oWHCqw4qnvk/U2tdSELH93N8JHap/tofozYaHJR4e90vbGnuIyDmOfuZ9658M2jzjXr nwxV3rnwxV3rnwxVgX5gW4+tR3IFOVOX+yFAP+SZP05ga6OwLvOxcm8o/Fh5zXu/WHCq04q3FE00 yRL9qRgg+bGmSiLNMJy4QSej2PRFW30yFEWisOYHsxqv3LQZuwKeIlIk2Ud658MKHeufDFXeufDF Up806z+j9EuJtuZXio9zt+PT6chklwxJb9Nh8TII97xKR3kdnclnclmY9STuTmpJeyAAFBSOFVpx VYcKrDhVYcULJ/8AeOb5f8atkoo6vriw/wB4bb/jEn/ERmzDxeT6j71fCwdirz78z/8Ajq6H/wAY rz/idtmu7Q5D3u+7E5T+H6WFnNS9AsOFCw4UrTihYcKrDircEpinjkrTiwJp4d8sxy4ZAtOfHxwM e8PTYp/UjRz1ZQT8yN86B4hd6gxV3qDFXeoMVY353jEmnBx1Tf8A4ZQPwJzG1YuBdj2XOs487YAc 1L1Sw4VWnFUXo6c9TgHdSXHzRSw/Vl+nFzDh6+XDhkfL79nrcdI41jHRAFH0Cmbd5Bd6gxV3qDFX eoMVYP8Amben0LS1B2di5/2I3H/DDMTVy2Adz2Njucpdw+954cwXoFhwqtOKrDhVYcKrDihZP/vH N8v+NWyUUdX1xYf7w23/ABiT/iIzZh4vJ9R96vhYOxV59+Z//HV0P/jFef8AE7bNd2hyHvd92Jyn 8P0sLOal6BYcKFhwpWnFCw4VWHFVhySs/wBLnL6bbMepjFfmd832I3AHyeI1MaySH9I/eivUyxpd 6mKu9TFUn80MG0t6jYBiSfZGb+GU6j6C5ehNZo+95y91EO+aW3suEqL3sQx4k8BUW1BBjxJ8NNfK VyLjW4kFOhP3/D/HMrSG8gdb2vGsB94eq+pm2eSd6mKu9TFXepirzL8ztSEetwwntAHof8okf8a5 r9ZL1AeT0vYmO8cj/S/Qw79JR5icTufDd9fiOStjwFv63Ce+G0GJb9aM9GwootcgehrhQtOKFk/+ 8c3y/wCNWyUUdX1xYf7w23/GJP8AiIzZh4vJ9R96vhYOxV59+Z//AB1dD/4xXn/E7bNd2hyHvd92 Jyn8P0sLOal6BYcKFhwpWnFCw4VWHFVNmA6nCrNdJ5fo22PYxqR9IzfYPoHueL1n99P+sUXVvHLX GdVvHFXVbxxVKPNUhTRrgk7COU/8kmynUH93L3OXoBeeH9YPIHvD45z3E+gcCg92fHG08Ci92fHD a8DIPy/uifMsK9SyMB9FG/hmXoT+8Dqe3If4OfeHsdW8c3bxLqt44q6reOKuq3jiryL84i0XmC1k 7SWqr7VVmP8Axtmr131D3PW+z++KQ/pfoDAfrh8cw7d7wO+unxw2jgbF+fHDaDBcNQPjkrYGCoup sO+SEmJxq6aqfHJCTA41dtSVrOYH2H/Ctk4lqMN32NYf7w23/GJP+IjNoHh8n1H3q+Fg7FXn35n/ APHV0P8A4xXn/E7bNd2hyHvd92Jyn8P0sLOal6BYcKFhwpWEgdcUKEk6L74LZCJQkt74HAZNgxoK S7ZmCruSaADxOR4mzgp6paQCG0ghH+641X+n4Z08I0AO588yz4pmXebVOOSa3ccVdxxVjfn+YQ+X bk9+FP8AgnVP+N8xdYaxF2XY8OLUwH45F4w8pznrfQKUmlOG00pNIcbWk48k3Qi802LE/aMiAe7x Mq/icytHKsodb2xj4tNP3fcQXvxAJNOnb5Z0D581xxV3HFXccVeX/nnYt9T0vUFHwxvJA58S4DL9 3DNf2hHYF6X2cyeqcO8A/L+14+ZTmsespaZjhRS0zHxwopr1z45JHC76yfHDbHhXC7PjkrYmKsLw /VpBX9pf1Nk4lrlF912H+8Nt/wAYk/4iM3AfPMn1H3q+Fg7FXn35n/8AHV0P/jFef8Tts13aHIe9 33YnKfw/Sws5qXoFjEDrhVDy3Cr0wGTIQQM92fHIGTbHGgJbk+ORMm0QQkk58cjbYIo7yrZPqGu2 0Q+xGwlc9gFO1f8AZUrmVosfHkHlu6/tbP4Wnkesth8f2PWWIrtsvRR4AdM6R4FrFXYq7FWA/mxe +npkduD8UsiinioqzfiEzXdpTrGB3l6D2cxcWcy/mx+/8F5OzHNI9qpsThVTY4qq6befUtTtLz/l nmjl/wCAYN/DLMcuGQPc06jH4mOUf5wIfSts4e2iYGoKgVHcr8JP3jOnfMCFTFXYq7FWO/mDojaz 5SvbWNeVwi+tbjvzQ1AH+sQBlOox8cCHO7N1Pg54yPLkfcXzQTmhfRVMnChYWwqsLYULS+SRTXqY UUvWX/R5P9df1Nk482Eg+/rD/eG2/wCMSf8AERm6D5tk+o+9XwsHYq8+/M//AI6uh/8AGK8/4nbZ ru0OQ97vuxOU/h+lhEkiqPfNQS9CBaBnueu+RMm6MEBNcHffKzJujBBSze+RJbBFCyS4LZiKGeTG 2VPTPIGhtY6a19OtLi7+yD1VB0/X/nTOh7P0/BCzzk8N25rfFy8Efph9/X9TKKZsHSOpirqYq6mK vG/zP1MXWuJbK1UtlJP+tJQ/8QVDmj7SyXPh7ntvZ3T8OEzP8Z+wftthbHNc9ApMcKqbHCqxsKH0 D+XmqDUvKdnITWWFRFJ41T4N/nw5fTnRaWfFjBfOu1cHhaiQ6E3892R0zIde6mKupirqAggiqkEM PEHYjFXzr+aflN9B8wySxL/oN8WlgYDYMTV126daj7u2aXV4eCVjkXu+xdb42LhP1w2P6CwljmM7 hY2FVNsKFNjhVYThQvVv3D/66fqbJx5sJP0FsP8AeG2/4xJ/xEZuw+aZPqPvV8LB2KvO/wA1H4an oZ8Yrz/idtmt7RPpHveg7CF8fw/S87nnO++aQyeojBATS5AltEUHLJkbbQEK74LZAKDtiypknkry q+qXS3l0tNPhNd/92MOw8R/n45s9Bo+M8UvpH2ug7a7UGGPhwP7w/wCxH6/7e56jQUAAooFFA7AZ 0DxDqYq6mKupiqE1W8istOnuZW4JGpJbw2JJ+hQTkZSEQSejPFjM5CI5k0+e9SvZL6+nu5NnncuR 2AJ2UewG2ctkmZSMj1fTsGEYoCA5RFINsi2qbYVU2wqpthQ9I/JfXlg1G40eZ6R3Q9SCp25gAOB7 7K3yU5s+zstExeY9o9LcY5R02Pu6fjzevlSCQdiOubd5F1MVdTFXUxVJ/Nfley8y6NLptyKOfit5 aCqSD7JFf8+3QnK8uITjRcrR6uWDIJx/tHc+ZvMGg6loWpy6dqERjmjPwn9l1rQOp8D/AGHfNHkx mBovoOm1MM0BOB2Spsi5Cm2FVNsKFjHCrY/uH/10/U2TjzYSfoRYf7w23/GJP+IjN2HzPJ9R96vh YOxV5r+bzcdR0I/5F5/xO2zV9qfTH3vR+z4+v4fpeaTSZoiXrAEHI++RtsAQ0jYGQCgxJNBuTill XlnyFc3zLdakDBZ1qIjs7/0GbXSdmmXqnsO55ztLt6MLhh3l39B+v7no8MEMEKQQII4YxREXYADN 8AAKDx0pGRs7kr6YWLqYq6mKupirzf8ANfzCqxpo8D/E3xXFP5Qen0sKf7H3zV9pZ6HAOvN6b2d0 XFI5jyjsPf8AseXNmlexU2woU2wqpthVTbChW03UbjTdRt763NJrdw6jsadVPsw2OWY5mJBHRqz4 Y5YGEuUg+mNG1S21jSLbU7Zucc6Dl4g+/vtv71zo8cxKII6vmufDLFMwlzCLpk2l1MVdTFXUxVIf OXknSfNmnfVrweldxgm1vB9pGIpv7eI7/cRVmwjIKLm6HXT08+KPLqO986ebvJGveWLxoNQgPoVp FdoCY3r037HbofoqN80+XBKB3e40XaGLUC4nfu6scbK3OU2woU2wq2P7h/8AXT9TZKPNhJ+hNh/v Dbf8Yk/4iM3gfM8n1H3q+Fgoy3lnC/CWeON+vF3VTT5E4q84/Nc/XL7RGs/9JEa3QkMXxheTW/Hk VrSvE9c1vaUJSjGhe70PYOWEOPiIGw5n3vN5bDUK0+rS/wDAN/TNH+XyfzZfIvUDWYP58P8ATBZH oes3BpFZysT0qpH66ZOOizS5RP3Nc+1dNDnMfDf7k0svy91m4YG5KW0fepq33ZmY+yZn6iA63P7S Yo/3cTI+ewZZo3k3R9MKycPrFwP92yb0+QzaYNFjx7gb95ee1naufPtI1HuHL9vxT075lutdTFXU xV1MVdTFUt8xa3baJpUt7M1HoRCv7RbpUe/h7+wOVZsoxxMi5Ok0ss+QQj1+zzeBajfT395Ldzms srVPgB0CivYDYZzGTIZyMjzL6Rp8EcUBCPIINsi3KbYUKbYVU2wqpthQpthV6L+UHnRdM1A6Lesf qV637gn9mU/s/wCy7e/+tmx0GfhPCeRec7f7P44+LH6o8/d+z7vc9sdOJ61B3Vh0IPQjNw8atpir qYq6mKupiqy6tbO9tmtb6BLq2ccWjkAYUPbfAQDzZRmYmwaLzTzL+QOg6g7T6Hdtp0rb/V5Bzir7 AkUr7NT2zDyaKJ5bO90vtBlhtMcY+Recax+SP5gaex4WSXse59S3kFKfKT0z92YstJMebu8Xbumn zJj7x+q2L3Hk3zbDIUfRr3kNjxt5GH0MqkZX4Mx0Lmx1+A8px+YWDyp5p9Fx+hr6vNf+PabsG/yc lHHK+RWWsw/z4/6YPuyx1HT1srdWuYgwjQEF1BBCj3zcB87yfUfejY5I5EDxsHRujKQQfpGFgxXW wv6YuDxBJWPcgHoD44qgwQOir/wK/wBMVbLk+H0AD+GKrSSepOKupirqYq6mKupirqYq6mKqdzcW 1pbSXVy/CCIEsSQK0FaCuAkAWWUIGRAAsl4f50813Gv6izA8bOI0gjFQDTblQ/h/UnOc1mqOWW30 h7/sns0aaG/95Ln+pjTZiO2U2wqpthQpthVTbCqm2FCm2FVhJBBBoRuCMKvdvys/MGLWrNdG1OQJ qcA/cysf7xfH/mr7++270mp4xR+oPDdsdlnBLjgP3Z+zy93cz9kKsVYUI6jM10bVMVdTFXUxV1MV dTFW1d1+yxX5GmKrjK5+0Q3zAP6xiq2o/lT/AIBf6Yq6o/lT/gF/pirJvLgpo8I7cpaf8jWxVJdb /wCOxP8A6sf/ABHFUHTFXUxV1MVdTFXUxV1MVdTFXUxVSu7m1srV7q8kEUCCpZiBWnhXIykIizyZ 48cpyEYiyXjvnfzxca7P9Xt6xabHsidOdD1Pt/tnsBoNZrTkPDH6fve57J7IGnHHPfJ9347/AMGI NmA7tTbCqm2FVNsKFNsKqbYVU2woU2wqpthVdbXVxaXMdzbSGKeFg8ci9Qw6ZKMiDYYZMcZxMZCw Xvn5c/mbZeY4E03U2W31eNaIa/DIAOq1/V1Hyzd6bVDJsfqeF7U7JlpzxR3x/d7/ANbOXjZG4tsc y3TtUxV1MVdTFXUxV1MVdTFXUxV1MVZP5e/45EP+tJ/ycbFUl1of7mJ/9WP/AIjiqDpirqYq6mKu pirqYq6mKthSTQCp8BiqUa/5p0fQoS1zIJLgj93boakn6P8Aa98x8+phiHqPwc3Rdn5dRKoDbv6B 5D5n826pr0/K4b07ZT+7t1Pwjwr4nNBqdXLKd9h3Pc9n9l49MNt59T+ruSBsxXZKbYUKbYVU2wqp thQpthVTbCqm2FCm2FVNsKrGwoWxyywypLE5jljIZHUkMrDcEEdCMINIlEEUeT1/yF+diqkemeZ/ iQfDHfjan+uB0+fTxp1zaafW9J/N5TtHsEi54f8AS/q/U9dge3uoFubOVbi3cBldDXY7jpmxBt5i USDR5uphQ6mKupirqYq6mKupirqYqyby9/xyYf8AWk/5ONiqTax/x17j/Vj/AOI4qhaYq6mKupir gpOw3xVtk4CshEYPQuQv68VSrVfNGg6Wp+tXIMg/3UtQ33UL/wDC098oy6nHj+ouZptBmz/REkd/ T5sC1/8ANG/uVaDS4/q0J2MjAcz/ALGrD7yfozU5+1SdoCvN6bR+zkI75TxHuHL9f3MFuJ5p5Wlm dpJXNWdyWYn3JzVmRJs83pIQjAVEUAoNgZKbYVU2woU2wqpthVTbChTbCqm2FVNsKFNsKqbYVWNh QpNhVY2FU88seevMnlqYPpt0RCDVrWSrRHx2qCv+xIy/FnlDk4Gs7Ow6j6h6u8c3sXln89vLWpBI dbjOnXR2MvWMn/XAp/wQX55ssetjLns8vquwc2PeHrj9vy/U9CtLzTr6JZrG7iuIpPsMrD4vka0P 0HMsEHk6ScDE0RRV2idPtKR8xhYraYq6mKupirqYqyPy/wD8cmH/AFpP+TjYqhtQ0a8nvpLiIwlJ FUUk5ggqKfs4qxvzdqE3li0tbu8hilhurgWq+lzJV2jeRS3Jl2PpkfOmVZ8oxxMiLpy9HpDnnwAg HzY/P+YttA4U2lahWBCmhVhUdZPfMCXasB0LtYezuWQ+qP2/qQU35oUH7uz3/wBgv6xJlR7Yj0i5 EfZmfWY+SV3n5n604IgjWIH+Zmb8E9MfhlM+15nkAHLxezOIfVKR92362PX3mnXruoku3RT1SKkY +nhQn6cw8mtyz5y/Q7TB2TpsXKAvz3+9JWJNSdyeuYzsVNsVUmwqsbCqm2FVNsKFNsKqbYVU2woU 2wqpthVTbChTbCqm2FVjYUKTYVWNhVTbCqm2FCvp+r6rpkpl0+7mtJD9owuyVHg1DuPnk4zMeRas uCGQVMCXvZfpX53efNOCq1xHdoNuMqFdv+eRjqfc1zJjrJjzdVl7B08uQMfcf12yW1/5yRv1UC80 hZW7ukqgf8D6Vf8AhsvGu7w4E/Zofwz+z9qZx/8AOSWimvraRKp7cKH76yrkxro9zjn2cy9JR+1M NN/P7RtQvtPsLbR7h7vUrhLW2jPEVeR1jUn970LN+By3HqRM0A4+fsTJiiZGUaHv/U9i/QepEfZt h785T+FMyHSptpNnLZ6fFbysHlTkXZdgSzFtq/PFUXiqS+cvLieY/LN9pBf0pbhA1tP/AL7niYSQ v8lkVSfEZGURIUeTdp8xxzEh0fP9o81/aTWs8Rt9Z0p3hvbJvtoUJ5r78WqQe6n2zmdTppYzwnpy 8w99ptXGYEx9MvsP7UFIMwnZAodxgZKLDCqk2FVNsVU2wqpthVTbCqm2FCm2FVNsKqbYUKbYVU2w qpthQpthVTbCqxsKFJsKrGwqpthVTbChTbCqm2FVNsKF1tazXUwiiG9CWY7KqjdmY9lA3OEC2MpA Cy9g/wCcbvI7a75ybzRLGTonl+sdizjaW7YEKQCP2Axc06MVzb6bDwRs8z9zyfbWu4h4cfj+PsfV eZDzbsVdirsVeZfml+Vl3rN0vmfyvKLPzRbqFkWvGO7jT7KSeDjoreGx7UhkxRyCpOdo9bLCf6Ly CTzLpxu3sPMlrL5e1uM8ZhJGxgZh34j4lr7VGafUdlyG4ep0vagI7x+Pxuik0/61vY3Vreqehgnj Y/8AAkhvwzWy0s49HaQ12Muby9q/++P+HT/mrIeDLubPzePv+9Rby7rH/LP/AMOn/NWHwZdyfzeP v+9TPl3WP+Wf/h0/5qx8GXcv5rH3/ept5d1j/ln/AOHT/mrD4Mu5fzWPv+9Tby5rP/LP/wAOn/NW HwZdy/msff8Aepny3rX/ACz/APDx/wDNWHwZdyPzWPv+9YfLetf8s3/Dx/8ANWPgy7l/NY+/71M+ Wtb/AOWb/h4/+asPhS7l/NY+/wC9YfLOt/8ALN/w8f8AzVh8KXcv5rH3/ept5Y1z/lm/4eP/AJqw +FLuR+ax9/3qZ8sa5/yzf8PH/wA1YfCl3L+ax9/3rG8r67/yzf8ADx/81YfCl3L+ax9/3qbeVtd/ 5Zf+Hj/5qw+FLuX81j7/AL1jeVte/wCWX/kpH/zVh8KSPzWPv+9Tbyrr3/LL/wAlI/8AmrD4Ul/N Y+/71h8qa/8A8sv/ACUj/wCasPhSX81j7/vUz5T1/wD5Zf8AkpH/AM1Y+FJH5rH3/esbyn5g/wCW X/kpH/zVh8OS/msff96mfKXmD/lk/wCSkf8AzVh8OS/msff96m3lHzD/AMsn/JSL/mrD4ckfmsfe sbyj5h/5ZP8AkpF/zVh8OS/msfesbyjryrzlhjhTu8s8CAfe+SGKR6MTrMY6/ehZ9O0ez31DV7eo /wB0WVbqU+1VpGPpfMiGimfJxsnacB9ItnnkH8n/ADP549MRWcvl7yc5Vrm+uP8Aeu8QUICVAqp7 UHAf5RGbDFpo4/Muh1vapO17vqzy55d0jy5otro2kQC3sLROEUY6nxZj3ZjuTlxNvPykZGymWBi7 FXYq7FXYqlHmHyj5a8x2/oa1p0N6g2VpF+Nf9VxRh9+ESITGRG4ec6j/AM4y+Qbhy9pLd2lTXh6n qKPYA0/XkuIdQ5A1mQdUvH/OLugAUGsXAA7cD/1Uwej+az/P5e93/Qrmgf8AV4uP+AP/AFUxqH81 fz+XvXJ/zi55bDfvNWuWXwVSp+8u2NQ/mr+fy96//oV3yl/1c7z7/wC3BUP5oX8/l73f9CueUv8A q5Xn3/241D+aF/P5e9r/AKFb8o/9XK8+/wDtxqH80L+fy97v+hWvKH/VyvPv/tx9P80L+fy97X/Q rPk//q5Xf3/24fT/ADQv5/L3u/6FY8n/APVxu/v/ALcfT/NC/n8ve1/0Kv5O/wCrjd/f/bj6f5oX 8/l73f8AQq/k7/q43f3/ANuPp/mhfz+Xvd/0Kt5N/wCrhd/f/bj6f5oX8/l72v8AoVXyZ/1cLv7/ AO3H0/zQv5/L3u/6FU8l/wDVwu/v/txuPcF/P5e9r/oVPyX/ANXC7+/+3G49y/n8ve7/AKFS8lf8 t939/wDzdjce5fz+XvWSf84oeTyB6eo3KnvyBb9TrhuP81fz+XvUJP8AnE3y0QPT1aVT35RM36pl xuP81fz+XvUJP+cTdH5fBqvJfFo5FP3CY4eKH81fz+XvWf8AQpmlf9XMf8BL/wBVcPFDuX8/l718 f/OJeiE/vdV4jtxjkb9cy4OKH81fz+XvTKz/AOcT/wAvUcNeXF3cU3Ko/pA/OvqH8ceMdAg63J3s 38tfkz+WflyRZtN0G3NypDLc3INzIGHQqZi/A/6tMiZFqnqJy5lmuRaXYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq//9k= xmp.did:1909C3C878D8DE11BA3FC4734EDA5420 uuid:79f4e077-af0a-49b0-8661-3c88af079b47 uuid:4BC73B30D582DE118E9E833D7C53E1E9 proof:pdf xmp.iid:1809C3C878D8DE11BA3FC4734EDA5420 xmp.did:1809C3C878D8DE11BA3FC4734EDA5420 uuid:4BC73B30D582DE118E9E833D7C53E1E9 proof:pdf saved xmp.iid:1709C3C878D8DE11BA3FC4734EDA5420 2009-11-23T23:40:14+02:00 Adobe Illustrator CS4 / saved xmp.iid:1809C3C878D8DE11BA3FC4734EDA5420 2009-11-23T23:44:22+02:00 Adobe Illustrator CS4 / saved xmp.iid:1909C3C878D8DE11BA3FC4734EDA5420 2009-11-23T23:45:49+02:00 Adobe Illustrator CS4 / Adobe PDF library 9.00 1 True False 100.000000 100.000000 Pixels Cyan Magenta Yellow Black Default Swatch Group 0 White RGB PROCESS 255 255 255 Black RGB PROCESS 0 0 0 Charcoal RGB PROCESS 63 63 63 Graphite RGB PROCESS 102 102 102 Ash RGB PROCESS 140 140 140 Smoke RGB PROCESS 178 178 178 Latte RGB PROCESS 228 188 150 Capuccino RGB PROCESS 213 151 88 Mochaccino RGB PROCESS 139 92 41 Chocolate RGB PROCESS 90 61 28 Mars Red RGB PROCESS 143 0 0 Ruby RGB PROCESS 191 0 0 Pure Red RGB PROCESS 255 0 0 Pumpkin RGB PROCESS 255 64 0 Squash RGB PROCESS 255 127 0 Sunshine RGB PROCESS 255 191 0 Yellow RGB PROCESS 255 255 0 Chartreuse Green RGB PROCESS 204 255 0 Fresh Grass Green RGB PROCESS 125 255 0 Pure Green RGB PROCESS 0 255 0 Spearmint RGB PROCESS 0 163 61 Holly Green RGB PROCESS 0 107 51 Sea Green RGB PROCESS 1 83 83 Caribbean Blue RGB PROCESS 4 115 145 Mediterranean Blue RGB PROCESS 0 160 198 Aloha Blue RGB PROCESS 0 96 182 Black Light Blue RGB PROCESS 0 60 255 Pure Blue RGB PROCESS 0 0 255 Sapphire Blue RGB PROCESS 34 16 210 Tanzanite RGB PROCESS 66 16 210 Brilliant Purple RGB PROCESS 93 16 210 Violet RGB PROCESS 130 16 210 Purple Orchid RGB PROCESS 171 16 210 Fuschia RGB PROCESS 208 16 177 Global Pure Red PROCESS 100.000000 RGB 255 0 0 Global Squash PROCESS 100.000000 RGB 255 126 0 Global Yellow PROCESS 100.000000 RGB 255 255 0 Global Pure Green PROCESS 100.000000 RGB 0 255 0 Global Mediterranean Blue PROCESS 100.000000 RGB 0 160 198 Global Pure Blue PROCESS 100.000000 RGB 0 0 255 Document endstream endobj 3 0 obj <> endobj 122 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>/XObject<>>>/Thumb 148 0 R/TrimBox[0.0 0.0 100.0 100.0]/Type/Page>> endobj 123 0 obj <>stream HVMo1 W7wN=}a *$NfUZ3dz>ݟ=kfӿK}>П_K=}C}I.QeJt.L>.@kuāLe*uDS:MW7;Ʋ۪xx&XN!v|TЪxS{긦X { CC\lNz}T7_`}EtR+^s]w:#EJ>ɜ3E/ʐ f}gO*3-.mҋG "c2%%3f&/aNM,rBޡ ܊ė@`3amUH״xɩI`tFKjHL6RTD\ȅmL1|!#vƒ!`wUC.\ĴX4w϶ i xvo#?Ē} 5f("fJlH&< ֣}sTEH!3_s{mJ٭d@=U`BF'vHhn "G k %|AM$N`c8B hB#F"bHLiUs-ő̆eg00;P֡eG v'Ly]h1`A򤌉UlgCc}K/ ?Y9^;)5SKFLҸ;F4$4:ۨiiI6jjч\9L&8v qwPkFfj^&7濻Oku endstream endobj 124 0 obj <> endobj 148 0 obj <>stream 8;TH&Yml4;%(iAMQZNRi0YmpAU7%IPRh*W\fQTk76<7pUNf5GP5e+@-2h3.j-C=c[ X>?7'ff1<=MJ!eeY$4!s/8sW4K8q\C--cHIW\"sBhR',F>s<)t)$&!h:Po~> endstream endobj 150 0 obj [/Indexed/DeviceRGB 255 151 0 R] endobj 151 0 obj <>stream 8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn 6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 136 0 obj <>/ExtGState<>/ProcSet[/PDF/ImageC/ImageI]/XObject<>>>/Subtype/Form>>stream q /GS0 gs 103 0 0 104 -1.2519531 -1.7480469 cm /Im0 Do Q endstream endobj 137 0 obj <>/ExtGState<>/Shading<>>>/Subtype/Form>>stream q 96.212 15.058 m 96.212 8.931 91.243 3.962 85.116 3.962 c 14.845 3.962 l 8.717 3.962 3.75 8.931 3.75 15.058 c 3.75 85.329 l 3.75 91.457 8.717 96.424 14.845 96.424 c 85.116 96.424 l 91.243 96.424 96.212 91.457 96.212 85.329 c h W n q 0 g /GS0 gs 69.5471954 0 0 -33.9607239 63.3984375 19.1269531 cm BX /Sh0 sh EX Q Q endstream endobj 138 0 obj <>/ExtGState<>>>/Subtype/Form>>stream /CS0 cs 1 1 1 scn /GS0 gs q 1 0 0 1 93 13.6084 cm 0 0 m -25.587 0.464 -43.041 26.396 -33.12 50.419 c -28.93 60.568 -19.768 67.936 -9.37 70.94 c -5.22 72.14 -0.952 72.174 3.324 72.174 c 4.029 72.174 6.644 72.262 6.644 72.182 c 6.644 67.061 l 6.644 65.776 6.838 58.987 6.461 58.987 c 2.456 58.987 -1.518 59.179 -5.454 58.312 c -15.31 56.142 -22.082 46.627 -22.181 36.807 c -22.256 29.279 -19.142 22.479 -13.3 17.724 c -9.507 14.636 -4.445 13.187 0.386 13.187 c 5.256 13.187 l 7.01 13.187 6.644 13.519 6.644 11.56 c 6.644 0.959 l 6.644 -0.574 6.697 0 5.212 0 c 0 0 l -0.006 0 -0.006 -0.727 0 -0.727 c 6.647 -0.727 l 6.651 -0.727 6.651 -0.382 6.651 -0.363 c 6.651 13.55 l 6.651 13.568 6.651 13.913 6.647 13.913 c 1.272 13.913 -3.796 13.736 -8.885 15.822 c -16.377 18.895 -20.912 26.35 -22.019 34.097 c -23.294 43.028 -17.92 51.391 -10.417 55.671 c -5.163 58.669 0.841 58.262 6.647 58.262 c 6.651 58.262 6.651 58.605 6.651 58.625 c 6.651 72.537 l 6.651 72.556 6.651 72.899 6.647 72.899 c -3.479 72.899 -12.49 72.064 -21.092 66.079 c -29.982 59.893 -35.861 48.978 -36.065 38.143 c -36.462 17.169 -21.49 -0.336 0 -0.727 c 0.001 -0.727 0.01 -0.001 0 0 c f Q endstream endobj 139 0 obj <>/ExtGState<>>>/Subtype/Form>>stream /CS0 cs 0.584 0.584 0.584 scn /GS0 gs q 1 0 0 1 99.999 86.4976 cm 0 0 m 0 -8.302 l 0 -13.343 l 0 -14.996 -0.466 -14.557 -2.103 -14.557 c -12.256 -14.557 -21.036 -16.68 -26.366 -26.228 c -29.246 -31.387 -29.334 -37.473 -27.891 -43.036 c -25.236 -53.265 -15.646 -59.047 -5.554 -59.047 c -0.591 -59.047 l 0.405 -59.047 0 -60.057 0 -60.909 c 0 -72.331 l 0 -74.685 -4.432 -73.544 -6.389 -73.544 c -11.539 -73.544 -16.433 -72.595 -21.206 -70.663 c -45.354 -60.88 -50.09 -28.242 -32.323 -10.372 c -23.38 -1.377 -11.978 -0.061 0.001 -0.061 c 0.002 -0.061 0.002 0.061 0.001 0.061 c -11.299 0.061 -21.256 -1.08 -30.389 -8.501 c -38.647 -15.212 -43.442 -25.866 -43.442 -36.442 c -43.442 -47.266 -38.896 -57.359 -30.929 -64.642 c -22.124 -72.689 -11.302 -73.666 0.001 -73.666 c 0.002 -73.666 0.002 -73.608 0.002 -73.605 c 0.002 -58.987 l 0.002 -58.984 0.002 -58.926 0.001 -58.926 c -5.466 -58.926 -10.659 -59.158 -15.828 -57.009 c -23.162 -53.962 -27.593 -46.601 -28.671 -39.005 c -30.005 -29.606 -24.512 -20.828 -16.31 -16.705 c -11.27 -14.171 -5.458 -14.678 0.001 -14.678 c 0.002 -14.678 0.002 -14.62 0.002 -14.617 c 0.002 0 l 0.002 0.068 0 0.068 0 0 c f Q endstream endobj 140 0 obj <>/ExtGState<>>>/Subtype/Form>>stream /CS0 cs 1 1 1 scn /GS0 gs q 1 0 0 1 14.8452 5.4121 cm 0 0 m -7.936 0.536 -9.893 6.795 -9.893 13.469 c -9.893 32.113 l -9.893 75.597 l -9.893 81.944 -8.775 87.948 -1.341 89.471 c 1.944 90.144 5.865 89.562 9.176 89.562 c 54.925 89.562 l 64.029 89.562 80.164 92.408 80.164 78.776 c 80.164 39.824 l 80.164 18.135 l 80.164 13.798 80.814 8.887 78.813 4.905 c 76.173 -0.348 70.332 0 65.428 0 c 45.917 0 l 0 0 l -0.004 0 -0.004 -0.5 0 -0.5 c 69.621 -0.5 l 81.847 -0.5 80.169 11.979 80.169 20.255 c 80.169 66.216 l 80.169 74.311 82.756 90.062 70.197 90.062 c 36.13 90.062 l 0.292 90.062 l -12.077 90.062 -9.897 75.947 -9.897 67.797 c -9.897 23.346 l -9.897 14.734 -12.484 0.343 0 -0.5 c -0.007 -0.499 0.015 -0.001 0 0 c f Q endstream endobj 141 0 obj <>/ExtGState<>>>/Subtype/Form>>stream /CS0 cs 0.051 0 0.231 scn /GS0 gs q 1 0 0 1 96.21 15.6602 cm 0 0 m -0.51 -8.207 -6.845 -11.073 -14.005 -11.073 c -31.712 -11.073 l -75.974 -11.073 l -81.106 -11.073 -85.64 -11.367 -89.66 -7.347 c -93.249 -3.757 -92.454 1.974 -92.454 6.579 c -92.454 51.744 l -92.454 61.266 -95.718 80.139 -81.072 80.139 c -45.235 80.139 l -11.168 80.139 l 3.628 80.139 -0.004 59.402 -0.004 49.96 c -0.004 -0.603 l -0.004 -1.31 0.008 -1.31 0.008 -0.603 c 0.008 69.019 l 0.008 75.759 -4.091 80.954 -11.094 81.389 c -14.36 81.592 -17.705 81.389 -20.977 81.389 c -66.85 81.389 l -76.392 81.389 -92.466 83.879 -92.466 69.668 c -92.466 37.513 l -92.466 0.048 l -92.466 -6.693 -88.367 -11.889 -81.365 -12.323 c -78.098 -12.526 -74.753 -12.323 -71.482 -12.323 c -28.145 -12.323 l -18.302 -12.323 -0.883 -15.476 0.004 -1.205 c 0.027 -0.829 -0.018 -0.293 0 0 c f Q endstream endobj 142 0 obj <>/ExtGState<>/Shading<>>>/Subtype/Form>>stream q 0 12.893 m 0 27.511 l 7 27.511 l 19.56 27.511 28.824 37.6 28.824 49.23 c 28.824 61.688 19.354 71.88 6.794 71.88 c 0 71.88 l 0 86.498 l 7 86.498 l 27.178 86.498 43.443 70.131 43.443 49.334 c 43.443 29.467 27.178 12.893 7 12.893 c h W n q 0 g /GS0 gs 0 73.6044922 73.6044922 0 21.7211914 12.8925781 cm BX /Sh0 sh EX Q Q endstream endobj 143 0 obj <>/ExtGState<>/Shading<>>>/Subtype/Form>>stream q 0 12.893 m 0 27.511 l 7 27.511 l 19.56 27.511 28.824 37.6 28.824 49.23 c 28.824 61.688 19.354 71.88 6.794 71.88 c 0 71.88 l 0 86.498 l 7 86.498 l 27.178 86.498 43.443 70.131 43.443 49.334 c 43.443 29.467 27.178 12.893 7 12.893 c h W n q 0 g /GS0 gs 0 -73.6054687 -73.6054687 0 21.7211914 86.4975586 cm BX /Sh0 sh EX Q Q endstream endobj 144 0 obj <>/ExtGState<>>>/Subtype/Form>>stream /CS0 cs 1 1 1 scn /GS0 gs q 1 0 0 1 0.356 13.2451 cm 0 0 m 0 8.438 l 0 13.143 l 0 14.115 2.06 13.55 3.32 13.55 c 13.909 13.55 22.95 17.372 27.326 27.653 c 29.708 33.251 29.104 40.175 26.962 45.689 c 23.033 55.81 13.212 59.351 3.217 59.351 c 2.514 59.351 0 59.261 0 59.342 c 0 63.506 l 0 69.293 l 0 70.263 -0.188 72.537 0.183 72.537 c 9.645 72.537 18.18 71.9 26.43 66.685 c 35.703 60.824 41.198 50.575 42.517 39.882 c 44.149 26.65 37.354 13.875 26.674 6.444 c 18.582 0.813 9.46 0.363 -0.003 0.363 c -0.009 0.363 -0.009 -0.363 -0.003 -0.363 c 11.069 -0.363 20.82 0.816 29.774 8.043 c 38.14 14.795 42.738 25.448 42.738 36.089 c 42.738 46.924 38.443 57.006 30.446 64.339 c 21.808 72.259 11.113 73.263 -0.003 73.263 c -0.008 73.263 -0.007 72.919 -0.007 72.9 c -0.007 58.988 l -0.007 58.969 -0.008 58.625 -0.003 58.625 c 5.372 58.625 10.439 58.802 15.528 56.715 c 23.021 53.643 27.556 46.187 28.662 38.44 c 29.937 29.509 24.564 21.146 17.061 16.866 c 11.807 13.869 5.803 14.276 -0.003 14.276 c -0.008 14.276 -0.007 13.932 -0.007 13.913 c -0.007 0 l -0.007 -0.41 0 -0.41 0 0 c f Q endstream endobj 145 0 obj <>/ExtGState<>>>/Subtype/Form>>stream /CS0 cs 0.584 0.584 0.584 scn /GS0 gs q 1 0 0 1 0.0005 12.8926 cm 0 0 m 0 8.303 l 0 13.344 l 0 14.997 0.466 14.558 2.103 14.558 c 12.256 14.558 21.037 16.681 26.366 26.229 c 29.246 31.387 29.333 37.473 27.89 43.036 c 25.236 53.265 15.647 59.048 5.554 59.048 c 0.592 59.048 l -0.405 59.048 0 60.058 0 60.91 c 0 72.331 l 0 74.685 4.433 73.544 6.39 73.544 c 11.54 73.544 16.434 72.595 21.206 70.662 c 45.356 60.881 50.09 28.243 32.324 10.373 c 23.381 1.378 11.979 0.061 0 0.061 c -0.001 0.061 -0.001 -0.061 0 -0.061 c 11.3 -0.061 21.257 1.08 30.389 8.502 c 38.648 15.213 43.443 25.865 43.443 36.441 c 43.443 47.266 38.897 57.359 30.929 64.642 c 22.125 72.689 11.303 73.666 0 73.666 c -0.001 73.666 -0.001 73.608 -0.001 73.605 c -0.001 58.988 l -0.001 58.985 -0.001 58.927 0 58.927 c 5.466 58.927 10.659 59.158 15.828 57.01 c 23.163 53.963 27.593 46.601 28.67 39.005 c 30.004 29.606 24.512 20.829 16.311 16.706 c 11.27 14.172 5.458 14.679 0 14.679 c -0.001 14.679 -0.001 14.621 -0.001 14.618 c -0.001 0 l -0.001 -0.068 0 -0.068 0 0 c f Q endstream endobj 146 0 obj <>/ExtGState<>/Shading<>>>/Subtype/Form>>stream q 100 86.498 m 100 71.88 l 93 71.88 l 80.441 71.88 71.175 61.791 71.175 50.159 c 71.175 37.702 80.646 27.511 93.205 27.511 c 100 27.511 l 100 12.893 l 93 12.893 l 72.822 12.893 56.558 29.26 56.558 50.056 c 56.558 69.925 72.822 86.498 93 86.498 c h W n q 0 g /GS0 gs 0 73.6044922 73.6044922 0 78.2792969 12.8925781 cm BX /Sh0 sh EX Q Q endstream endobj 147 0 obj <>/ExtGState<>/Shading<>>>/Subtype/Form>>stream q 100 86.498 m 100 71.88 l 93 71.88 l 80.441 71.88 71.175 61.791 71.175 50.159 c 71.175 37.702 80.646 27.511 93.205 27.511 c 100 27.511 l 100 12.893 l 93 12.893 l 72.822 12.893 56.558 29.26 56.558 50.056 c 56.558 69.925 72.822 86.498 93 86.498 c h W n q 0 g /GS0 gs 0 -73.6054687 -73.6054687 0 78.2792969 86.4975586 cm BX /Sh0 sh EX Q Q endstream endobj 171 0 obj <> endobj 167 0 obj <> endobj 126 0 obj [/ICCBased 174 0 R] endobj 173 0 obj <> endobj 175 0 obj <> endobj 176 0 obj <> endobj 177 0 obj <> endobj 178 0 obj <> endobj 174 0 obj <>stream HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 N')].uJr  wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 172 0 obj <> endobj 179 0 obj <> endobj 180 0 obj <>/Shading<>>>/Subtype/Form>>stream q 0 g /GS0 gs 0 -73.6054687 -73.6054687 0 78.2792969 86.4975586 cm BX /Sh0 sh EX Q endstream endobj 181 0 obj <> endobj 182 0 obj <> endobj 184 0 obj /DeviceGray endobj 185 0 obj <> endobj 186 0 obj <> endobj 187 0 obj <> endobj 188 0 obj <> endobj 189 0 obj <> endobj 128 0 obj <> endobj 183 0 obj /DeviceGray endobj 170 0 obj <> endobj 164 0 obj <> endobj 190 0 obj <> endobj 191 0 obj <> endobj 192 0 obj <> endobj 169 0 obj <> endobj 168 0 obj <> endobj 165 0 obj <> endobj 166 0 obj <> endobj 193 0 obj <> endobj 194 0 obj <>/Shading<>>>/Subtype/Form>>stream q 0 g /GS0 gs 0 -73.6054687 -73.6054687 0 21.7211914 86.4975586 cm BX /Sh0 sh EX Q endstream endobj 195 0 obj <> endobj 163 0 obj <> endobj 162 0 obj <> endobj 161 0 obj <> endobj 160 0 obj <> endobj 159 0 obj <> endobj 156 0 obj <> endobj 158 0 obj <> endobj 196 0 obj <> endobj 197 0 obj <> endobj 157 0 obj <> endobj 198 0 obj <> endobj 199 0 obj <>/Shading<>>>/Subtype/Form>>stream q 0 g /GS0 gs 69.5471954 0 0 -33.9607239 63.3984375 19.1269531 cm BX /Sh0 sh EX Q endstream endobj 200 0 obj <> endobj 201 0 obj <> endobj 202 0 obj <> endobj 203 0 obj <> endobj 204 0 obj <> endobj 152 0 obj <> endobj 155 0 obj <>stream H1 Om x0) endstream endobj 153 0 obj [/Indexed 206 0 R 0 207 0 R] endobj 205 0 obj <>/Filter/FlateDecode/Height 104/Intent/RelativeColorimetric/Length 973/Name/X/Subtype/Image/Type/XObject/Width 103>>stream HOhfpK#L3]a9a RH ;١)%<ׇQF; g%i^V^}IlFؑ%e R{zby @ЉAC A>ae4eX)Th&lHfBS^; AN3gɴAI&&FdL! ongs\pۙ+s~';ޚl{E8߻~v+=:ޟ$f/fύVoHrl`+(D/ޅ8^4h9|~^\Xfa:z4^9>^U 7kU6Q3q'wJuLM`;dX_M<[1fIL0%ScZHCIN0e5:n3p`I0 `0 `0 `Ť^N'9t`/@+VDd]/McR:cAlݚ9ˑ.9j L&݀Af(X. 7eX|XagG5vNZ߿9ۇX խQBq k d=廴QC6YfEF7 M|zDIeEm_%q1whu^zIZGZ/"7]xE"2M㯎[zRriwMԩ /Iv#~bf/[k?nݺ﹩Nm帶WȘA>ST9Gޛ K/ED/'hr97qCѠu}`9&T`*43sqp~^ IR6FDr1ldUFA^W (F>stream endstream endobj 154 0 obj <> endobj 208 0 obj <> endobj 209 0 obj [0.0 0.0 0.0] endobj 210 0 obj <>/ProcSet[/PDF/ImageB]/XObject<>>>/Subtype/Form>>stream q /GS0 gs 103 0 0 104 -1.2519531 -1.7480469 cm /Im0 Do Q endstream endobj 211 0 obj <> endobj 213 0 obj <>/Filter/FlateDecode/Height 104/Intent/RelativeColorimetric/Length 973/Name/X/Subtype/Image/Type/XObject/Width 103>>stream HOhfpK#L3]a9a RH ;١)%<ׇQF; g%i^V^}IlFؑ%e R{zby @ЉAC A>ae4eX)Th&lHfBS^; AN3gɴAI&&FdL! ongs\pۙ+s~';ޚl{E8߻~v+=:ޟ$f/fύVoHrl`+(D/ޅ8^4h9|~^\Xfa:z4^9>^U 7kU6Q3q'wJuLM`;dX_M<[1fIL0%ScZHCIN0e5:n3p`I0 `0 `0 `Ť^N'9t`/@+VDd]/McR:cAlݚ9ˑ.9j L&݀Af(X. 7eX|XagG5vNZ߿9ۇX խQBq k d=廴QC6YfEF7 M|zDIeEm_%q1whu^zIZGZ/"7]xE"2M㯎[zRriwMԩ /Iv#~bf/[k?nݺ﹩Nm帶WȘA>ST9Gޛ K/ED/'hr97qCѠu}`9&T`*43sqp~^ IR6FDr1ldUFA^W (F> endobj 134 0 obj <> endobj 135 0 obj <> endobj 215 0 obj <> endobj 216 0 obj <> endobj 217 0 obj <> endobj 218 0 obj <> endobj 219 0 obj <> endobj 214 0 obj <> endobj 220 0 obj <> endobj 221 0 obj <> endobj 120 0 obj <> endobj 222 0 obj [/View/Design] endobj 223 0 obj <>>> endobj 127 0 obj <> endobj 129 0 obj <> endobj 130 0 obj <> endobj 131 0 obj <> endobj 132 0 obj <> endobj 133 0 obj <> endobj 125 0 obj <> endobj 224 0 obj <> endobj 225 0 obj <>stream %!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 14.0 %%AI8_CreatorVersion: 14.0.0 %%For: (Administrator) () %%Title: (v4_3.ai) %%CreationDate: 11/26/2009 1:52 AM %%Canvassize: 16383 %%BoundingBox: -2 -2 102 103 %%HiResBoundingBox: -1.25195 -1.74805 101.748 102.252 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 10.0 %AI12_BuildNumber: 357 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0.627451 0.776471 (Global Mediterranean Blue) %%+ 0 0 1 (Global Pure Blue) %%+ 0 1 0 (Global Pure Green) %%+ 1 0 0 (Global Pure Red) %%+ 1 0.498039 0 (Global Squash) %%+ 1 1 0 (Global Yellow) %%+ 0 0 0 ([Registration]) %AI3_Cropmarks: 0 0 100 100 %AI3_TemplateBox: 50.5 49.5 50.5 49.5 %AI3_TileBox: -247.6001 -370.8701 347.4199 470.9902 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -110 120 4 1252 620 18 0 0 69 109 0 0 0 1 1 0 1 1 0 %AI5_OpenViewLayers: 7 %%PageOrigin:0 0 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 226 0 obj <>stream %%BoundingBox: -2 -2 102 103 %%HiResBoundingBox: -1.25195 -1.74805 101.748 102.252 %AI7_Thumbnail: 128 128 8 %%BeginData: 27134 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FDFCFFFDFCFFFDFCFFFD1EFFCBA2A87D7E7D7D537D537D777D777E %7D7D7DA27D7E7DA27D7E7DA27D7E7DA27D7E7DA27D7E7DA27D7E7DA27D7E %7DA27D7E7DA27D7E7DA27D7E7DA27D7E7DA27D7E7DA27D7E7DA27D7E7DA2 %7D7E7DA27D7E7D7E7D7E7D7E7D7E7DA8A9FD20FFA87D4C4C4B4B214C4B4B %454C4B4B454C4B4B214C454B214B214B214B214B214B214B214B214B214B %214B214B214B214B214B214B214B214B214B214B214B214B214B214B214B %214B214B214B214B214B214B214B214B214B214B214B2145214C4CA2A8FD %1CFF764C6FA1A1C3A1C9C3C3A0C3C3C9A1C9C3C9A1C9A1C9A1C9A1C9A1C9 %A1C9A1C9A1C3A1C9A1C3A1C9A1C3A1C9A1C3A1C9A1C3A1C3A1C3A1C3A1C3 %A1C3A1C3A1C3A1C3A1C3A1C3A1C3A1A1A1C3A1A1A0C3A1A19AA19AA19AA1 %9AA19AFD05A176702152A2FD19FF7D4576A1C9C3C3C2C29AC29AC29AC29A %C29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AA09AC29AA09A %C29A9A9AC29A9A9AA09A9A9AA09A9A9AA0FD0E9A999A9A9A999A999A759A %999A6F9A999A759A9AA1A1C9A1A16F4B52FD16FFA9774BC3C9C9C2C29AC2 %C2C29AC2C2C29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC2 %9AC29AC29AC29AC29AC29A9A9AC29A9A9AA0FD069A999A9A9A999A9A9A99 %9A9A9A999A9A9A999A9A9A999A9A9A999A9A9A759A999A6F9A939A75A1A1 %CA9A4B4CFD14FFAF524BC9C3C299C29AC29AC29AC29AC29AC29AC29AC299 %C29AC299C29AA099C29A9A99C29A9A99A09A9A999A9A9A999A999A999A99 %9A999A999A999A999A999A999A999A999A999A999A759A999A6F9A999A6F %9A759A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A76A19A4B4CFD13FF7D %4BC9C9C2BCC3C2C2BCC3C2C29AC2C2C29AC2C2C29AC29AC29AC29AC29AC2 %9AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AA09AC29AA0 %9AC29A9A9AC29A9A9AA0FD129A999A9A9A999A9A9A759A9A9A759A9A9A6F %C3A14B7DFD11FFA821A0C3C29AC29AC29AC29AC29AC29AC29AC29AC29AC2 %9AC29AC29AC29AC29AC29AA09AC29A9A9AC29A9A99C29A9A99A09A9A999A %9A9A999A9A9A999A9A9A999A999A999A999A999A999A999A999A759A999A %759A999A6F9A759A6F9A759A6F9A6F9A6F9A6F9A6F9A6F9A6FA17645A8FD %10FF5276C3C39AC2C2C29AC2C2C29AC2C2C29AC2BCC29AC29AC29AC29AC2 %9AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AA09AC29A9A9AC2 %9A9A9AC2FD0A9A999A9A9A999A9A9A999A9A9A999A9A9A999A9A9A999A9A %9A759A9A9A6F9A9A9A6F9A759A6FA14B77FD0FFFA84B9AC39AC29AC29AC2 %9AC29AC29AC29AC29AC29AC29AC29AC299C29AC299C29A9A99C29A9A99C2 %9A9A999A9A9A999A9A9A999A999A999A999A999A999A999A999A999A999A %999A999A759A999A6F9A999A6F9A759A6F9A759A6F9A6F9A6F9A6F9A6F9A %6F9A6F9A6F9A6F9A6F9A6F9A21CAFD0EFFA26FC9C2C2C2C3C2C2C2C3C2C2 %9AC3C2C29AC2C2C29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC2 %9AC29AC29AC29AC29AC29AC29AC29AC29AA09AC29A9A9AC29A9A9AA0FD12 %9A999A9A9A999A9A9A999A9A9A759A9A9A759A9A9A6F9A9A6F7DFD0EFF76 %9AC2C2BCC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29A %C29AA09AC29A9A9AC29A9A99C29A9A99C29A9A999A9A9A999A9A9A999A9A %9A999A9A9A999A999A999A999A999A999A999A999A759A999A6F9A999A6F %9A759A6F9A759A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F76FD0DFFCA76A0C3 %9AC3C2C2A0C2C2C2BCC2C2C29AC2C2C29AC29AC29AC29AC29AC29AC29AC2 %9AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29A9A9AC29A9A9AC29A9A %9AA0FD0A9A999A9A9A999A9A9A999A9A9A999A9A9A999A9A9A759A9A9A6F %9A999A6F9A999A759A769A769A4BFD09FFA87DA8A8A87DA8A8A8A7A8A1A8 %A1A7A1A19AC29AC299C29AC29AC29AC299C29AC299C29AA099C29A9A99C2 %9A9A99A09A9A999A9A9A999A999A999A999A999A999A999A999A999A999A %999A999A999A999A759A999A6F9A999A6F9A759A6F9A6F9A6F9A6F9A6F9A %6F9A6F9A76A17DA1A1A87DA8A8A8A1FD06A8FD04FFA8FD0BFFAFFFAFFFA8 %FFA8A8A1C3A0C29AC2C2C29AC29AC29AC29AC29AC29AC29AC29AC29AC29A %C29AC29AC29AC29AC29AC29AC29AC29AA09AC29AA09AC29A9A9AC29A9A9A %A0FD129A999A9A9A939A9AA1A1A8A8FFA8FFAFFFAFFFFFFFAFFFFFFFA8FF %FFA8FD04FFA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8AFA8A8A1A1 %9AC29AC29AC29AC29AC29AC29AC29AA09AC29A9A9AC29A9A99C29A9A99A0 %9A9A999A9A9A999A9A9A999A9A9A999A999A999A999A999A999A999A999A %759A999A759A999A6F9A759A6F9A76A1A1A8A8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FD04FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFFFFFA8FFA8A8A1C3BCC29AC29AC29AC29AC29AC29AC29AC29AC29AC2 %9AC29AC29AC29AC29AA09AC29A9A9AC29A9A9AC2FD0A9A999A9A9A999A9A %9A999A9A9A999A9A9A999A9AA1A1FFAFFFA8FFFFFFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FD05FFA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8AFA8A19ABC99C29AC299C29A9A99C29A9A99C29A9A999A %9A9A999A9A9A999A999A999A999A999A999A999A999A999A999A999A999A %759A999A6F9A999A6F9A759A6F9A6F9A76A8A8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD04FFA8FFA8FFFFFFA8FFFFFFA8FF %FFFFA8FFFFFFA8FFFFFFA8FFA8FFA8FFAFA8A1C3BCC29AC29AC29AC29AC2 %9AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AA09AC29A9A9AC2 %9A9A9AA0FD0E9A999A9AA1A8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFF %FFA8FFFFFFA8FFFFFFA8FD05FFA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A19ABC9AC29AA09AC29A9A9AC29A9A %99C29A9A99C29A9A999A9A9A999A9A9A999A9A9A999A9A9A999A999A999A %999A999A999A999A999A759A999A76A8A8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD04FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFFFFFA8A8A0C29AC29AC2 %9AC29AC29AC29AC29AC29AC29AC29AC29AC29A9A9AC29A9A9AC29A9A9AA0 %FD0A9A999A9A9A999A9A9A93A0A1FFA9FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD04FFA8A8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8A19A99C29A %9A99C29A9A99A09A9A999A9A9A999A999A999A999A999A999A999A999A99 %9A999A999A999A999A999A759A999A6F9A93A0A1FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD04FFA8FFFF %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFFFFFA1C39AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29A %A09AC29AA09AC29A9A9AC29A9A9AA0FD099AA1A8FFFFFFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD04FFA8A8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA1A0999A9AC29A9A9AC29A9A99C29A9A99A09A9A999A9A9A99 %9A9A9A999A9A9A999A999A999A999A999A999A999A999A75A8A8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FD04FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFFFFFA8C39AC29AC29AC29AC29AC29AC29AC29A %C29AA09AC29A9A9AC29A9A9AC2FD0A9A999A9A9A999A9AA8A8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FD05FFA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8A1999A99C29A9A999A9A9A999A9A9A99 %9A999A999A999A999A999A999A999A999A999A999A999A759A999A76A8A8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FD04FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A19AC29AC29AC29A %C29AC29AC29AC29AC29AC29AC29AC29AA09AC29A9A9AC29A9A9AA0FD079A %A8FFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FD05FFA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A099C29A9A %99C29A9A99C29A9A999A9A9A999A9A9A999A9A9A999A9A9A999A999A999A %999A999A9AA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD04FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8A19AC29AC29AC29AC29AC29AC29AC29A9A9AC29A9A9AC29A9A9AA0 %FD0B9AA8AFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD04FFA8A8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA19A99A09A9A999A9A9A999A999A999A999A999A999A999A999A999A %999A999A999A999A99A1A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD04FFA8FFA8FF %A8FFAFFFA8FFAFFFA8FFFFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFFFFFA1C29AC29AC29AC29AC29AC29AC29AC29AC29AA0 %9AC29AA09AC29A9A9AC2FD059AA1A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFFFFFAFFFFFFFAFFFFFFFA8FFA8A8FD04 %FFFD05A8A1A8A1A7A1A8A7A8A8AFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8A9A0BC9A9A99C29A9A99A09A9A999A9A9A %999A9A9A999A9A9A999A999A999A999A93A1A8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFFD04A87DA8A1A17DA1FD05A8 %FD09FF9AC2C3C2C29AC2A0C3A0C9A8A8A8FFFFFFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFFFA89AC29AC29AC29AC29AC29AA09AC29A9A %9AC29A9A9AC2FD099AA0A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFFFFFA8A87DA1769A759A6F9A759A6FCAFD0DFF9AC29AC29A %C29AC29AC299C29AA1A1AFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8A8999A9A9A999A9A9A999A999A999A999A999A999A999A99 %9A999A999A999A7DAFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8A8769A6F9A6F9A6F9A6F9A6F9A6F6FA2FD0DFFA0C2C3C2C2C2C3 %C2C2C2C3C2C2BCC3A1A8A8FFFFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8A79AC29AC29AC29AC29AC29AC29AC29AC29AA09AC29A9A9AC2 %9A9A9ABCA1AFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFFFFF %A1A19A9A939A9A9A759A9A9A6F9A9A9A6FCBFD0DFF9AC29AC29AC29AC29A %C29AC29AC29AC29AA1A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8A0999A99C29A9A999A9A9A999A9A9A999A9A9A999A9A9A999A99 %9A9AA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8769A6F %9A6F9A6F9A6F9A6F9A6F9A6F9A756FA8FD0CFFCBFD07C29AC2C2C29AC2C2 %C29AC2BCC2A1FFFFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA1 %C29AC29AC29AC29AC29A9A9AC29A9A9AC29A9A9AA0FD059AA1A8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A1769A999A759A9A9A6F9A9A %9A6F9A759A6F9A6FCAFD0DFF9AC29AC29AC29AC29AC29AC29AC29AC29AC2 %9AC2A1A8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD049A99 %9A999A999A999A999A999A999A999A999A999A93A07DFFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8A16F9A6F9A6F9A6F9A6F9A6F9A6F9A6F %9A6F9A6F9AA8FD0DFFC2C2C3C2C3C2C2C2C3C2C2BCC3C2C29AC2C2C29AC2 %A1AFAFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A89AC29AC29AC2 %9AC29AC29AC29AA09AC29AA09AC29A9A9ABCA1FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFCAFFA8A1999A999A9A9A759A9A9A759A9A9A6F9A9A9A %759A6FFD0EFF9AC2A0C29AC29AC29AC29AC29AC29AC29AC29AC29AC2A0A8 %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A0999A99A09A9A999A %9A9A999A9A9A999A9A9A999A999A9AA8A8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA89A6F9A759A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A %A8FD0DFFC2C2C3C2C2BCC2C2C29AC2C2C29AC2C2C29AC2BCC29AC2A1AFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA1C29AC29AC29AA09AC29A %9A9AC29A9A9AC2FD059AA1A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8A1999A999A9A9A759A9A9A6F9A9A9A6F9A759A6F9A769A6FFD0EFF9A %C29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC299C2A1A8A8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD049A999A999A999A999A999A999A %999A999A999A7DAFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A16F9A %6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F6FA8FD0DFFC2C2C3C2 %C2C2C3C2C2C2C3C2C29AC3C2C29AC2C2C29AC2BCC2A1FFFFFFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8A19AC29AC29AC29AC29AC29AC29AA09AC29A %9A9ABCA0A8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFAFA1999A9A9A99 %9A9A9A999A9A9A759A9A9A759A9A9A6F9A9A9A6FFD0EFF9AC29AC29AC29A %C29AC29AC29AC29AC29AC29AC29AC29AC29AA07DFFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8AF7DC29A9A999A9A9A999A9A9A999A9A9A999A9A9A99 %A1A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8759A6F9A759A6F9A75 %9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F70A8FD0CFFCBFD07C29AC2C2C29A %C2C2C29AC2C2C29AC29AC29AC2BCA1A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFAFA89AC29AC29AC29A9A9AC29A9A9AC29A9A9AA09AA07DFFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFFFAF769A9A9A999A9A9A759A9A9A759A9A %9A6F9A9A9A6F9A759A6F9A6FFD0EFF9AC29AC29AC29AC29AC29AC29AC29A %C29AC29AC29AC29AC299C29AA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8A1999A999A999A999A999A999A999A999A999A76A8A8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FF7D9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F %9A6F9A6F9A6F9A6F76A8FD0DFFC2C2C3C2C3C2C2C2C3C2C2BCC3C2C29AC2 %C2C29AC2C2C29AC29AC2A0FFFFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A1C29AC29AC29AC29AC29AA09AC29AA09AC29AA1A8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8A1999A9A9A999A9A9A999A9A9A759A9A9A759A9A9A %6F9A9A9A759A6FFD0EFF9AC2A0C29AC29AC29AC29AC29AC29AC29AC29AC2 %9AC29AC29AC29AC27DFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD04 %9A999A9A9A999A9A9A999A9A9A999A7DA8A8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8A8999A6F9A759A6F9A759A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F %9A6F9AA8FD0DFFC2C2C3C2C2BCC2C2C29AC2C2C29AC2C2C29AC2BCC29AC2 %9AC29AC29AA1A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A19AC29AA0 %9AC29A9A9AC29A9A9AC29A9A9AA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8AFFD049A999A9A9A999A9A9A759A9A9A6F9A9A9A6F9A759A6F9A769A6F %FD0EFF9AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC299 %C29AFD13A8A09A999A999A999A999A999A999A999A99A17EFFFD0FA8FFA1 %9A6F9A759A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F6FA8 %FD0DFFC2C2C3C2C2C2C3C2C2C2C3C2C29AC3C2C29AC2C2C29AC29AC29AC2 %9AC2A1FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A19AC29AC29AC29AC2 %9AC29AA09AC29A9AA1AFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A1999A %9A9A999A9A9A999A9A9A999A9A9A759A9A9A759A9A9A6F9A9A9A6FFD0EFF %9AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AA1 %A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8AFA19A999A9A9A999A9A9A999A %9A9A999A99A1A8FFA8A8A8FFA8A8A8FFA8A8A8FFFD04A89A9A6F9A999A6F %9A759A6F9A759A6F9A6F9A6F9A6F9A6F9A6F9A6F9A6F70A8FD0CFFCBFD07 %C29AC2C2C29AC2C2C29AC2C2C29AC29AC29AC29AC29AC2A0A8A8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8A89AC29AC29A9A9AC29A9A9AC29A9A9AC2A1 %A8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A0999A999A9A9A999A9A9A75 %9A9A9A759A9A9A6F9A9A9A6F9A759A6F9A6FFD0EFF9AC29AC29AC29AC29A %C29AC29AC29AC29AC29AC29AC29AC299C29AC299C2A1FD11A87DA0999A99 %9A999A999A999A999A999A99FD13A86F9A759A6F9A6F9A6F9A6F9A6F9A6F %9A6F9A6F9A6F9A6F9A6F9A6F9A6F76A8FD0DFFC2C2C3C2C3C2C2C2C3C2C2 %BCC3C2C29AC2C2C29AC2C2C29AC29AC29AC29AA8A8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8A8A0C29AC29AC29AC29AA09AC29AA09AC3A8AFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA1FD079A999A9A9A999A9A9A759A9A9A759A %9A9A6F9A9A9A759A6FFD0EFF9AC2A0C29AC29AC29AC29AC29AC29AC29AC2 %9AC29AC29AC29AC29AC29AC2A1FD11A87DA1999A999A9A9A999A999A999A %999A9AFD12A8A16F9A999A6F9A759A6F9A759A6F9A6F9A6F9A6F9A6F9A6F %9A6F9A6F9A6F9AA8FD0DFFC2C2C3C2C2BCC2C2C29AC2C2C29AC2C2C29AC2 %BCC29AC29AC29AC29AC29AC9FD12A8A0C29A9A99BC9A9A999A999A999A99 %9AA8AFFD0FA8AFA1996F9A939A6F9A999A6F9A999A6F9A9A9A759A9A9A6F %9A759A6F9A769A6FFD0EFF9AC29AC29AC29AC29AC29AC29AC29AC29AC29A %C29AC29AC29AC299C29ABCA0FD11A87EA0939A9999939A9399939993996F %9976FD12A8A16E936F936F936F996F936F996F996F9A6F9A6F9A6F9A6F9A %6F9A6F9A6F6FA8FD0DFFC2C2C3C2C2C2C3C2C2C2C3C2C29AC3C2C29AC2C2 %C29AC29AC29AC29AC29AC3FD12A89ABC999A999A9999939A93999399939A %A8AFFD0FA8AF9A936F996F936F996F996F996F996F9A6F996F9A6F9A6F9A %759A6F9A9A9A6FFD0EFF9AC29AC29AC29AC29AC29AC29AC29AC29AC29AC2 %9AC29AC29AC29AC29ABCA0FD11A884A093999399939993936F9993936E93 %99FD12A8A168936E936E936E936F6F6E936F6F6F936F6F6F936F6F6F996F %936F9A6F6FA8FD0CFFCBFD07C29AC2C2C29AC2C2C29AC2C2C29AC29AC29A %C29AC29AC29AA1FD12A89A99939993999399939993999393929AFD11A8AF %76936E936E936F936E936F936E936F936F936F936F936F936F936F936F9A %6FFD0EFF9AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC29AC2 %9AC299BCA0A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87D9A92936E939293 %6E936E936E936E936FA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A16893 %686F6893686F686F686F686F686F686F686F686F6E6F68FD056FA8FD0DFF %C2C2C3C2C3C2C2C2C3C2C2BCC3C2C29AC2C2C29AC2C2C29AC29AC29AC299 %A1FD12A89A939399939993999393929993939299FD11A8A9A1936E936E93 %6E936E936E936E936E936E936E936E936F936E936F936F996FFD0EFF9AC2 %A0C29AC29AC29AC29AC29AC29AC29AC29AC29AC29ABC99BC999A99BCA1FD %11A87D9A92936E9392936E9392936E936E926EFD13A86892686E6893686E %686F686E686F686E686F686F686F686F686F686F6E6FA8FD0DFFC2C2C3C2 %C2BCC2C2C29AC2C2C29AC2C2C29AC2BCC29AC29ABC99BC99BC99FD13A8FD %049392939293929392936E9392937DAFFD11A89968936E93689368936893 %686F6893686F6893686F686F686F686F6E6F68FD0EFF9AC29AC29AC29AC2 %9AC29AC29AC29AC29AC299C299BC99BC999993BB939A7DFD11A87D936E93 %92936E936E936E936E92689368A184FD10A8A97668686E686E686E686E68 %6E6868686E6868686E6868686E6868686F686FA8FD0DFFC2C2C3C2C2C2C3 %C2C2C2C3C2C29AC2C2C29AC29AC299C299BC99BC99BB9AAFFD0FA8FFA8A1 %9299929392939293929392939293929276AFFD11A8A16893689368936893 %689368936893686F6893686F6893686F686F686F68FD0EFF9AC29AC29AC2 %9AC29AC29AC29AC299C299BC99BC99BB99BB999993BB93A1FD12A876926E %9392936E9392936E936E926893689A84FD12A86F6892686E686E686E686E %6868686E6868686E6868686E6868686F6869A8FD0CFFCBFD07C29AC2C2C2 %9AC2BCC299C299BC99BC99BB99BB99BB93BCFD12A884A092939293929392 %939293929392936E9393FD12A8AF768C689368926893686E6893686E686F %686E686F686E686F686E686F68FD0EFF9AC29AC29AC29AC29AC299BC99BC %99BB99BB99BB93BB939992BB93939AFD13A86F9292936E936E9268936E92 %68936E9268937DFD12A8A16868686E6868686E6868686EFD0F6869A8FD0D %FFC2C2C3C2C3C2C2BCC2BCC299C2BBBC99BC99BB99BC99BB93BB99BB93FD %13A87D9992939293929392939293929392936E9392A1A8FFFD0FA8FFA89A %68936893689368926893686E6893686E686F686E686F686E686F68FD0EFF %9AC2A0C29AC29AC299C299BC99BC99BB99BB99BB93BB939992BB929AFD13 %A8A1929392936E9392926E936E9268936E92689275FD12A8AF7D6E686E68 %6E686E6868686E6868686EFD0B6869A8FD0DFFC2C2C3C2C29AC2BCC299C2 %BBBC99BC99BB99BB99BB93BB93BB92BBA7AFFD12A89A9292939293929392 %93929392936E9392936899FD13A8AF75686893686E6893686E686F686E68 %6E686E686E6868686E686E68FD0EFF9AC29AC299C299BC99BB99BB99BB93 %BB93BB92BB939992BB929276A9FD12A87D9392926E936E9268936E926893 %6E926893689268A1FD14A86868686E6868686EFD0E6844686868A8FD0DFF %C2C2C2BCC2BBC2BBC299C2BBBB99BB99BB99BB99BB93BB93BB99AFA8A8A8 %FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8A192939293929392939293929392 %93929392936E929AAFA8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A168 %9368926893686E6893686E686F686E686F686E686E686F68FD0EFF9AC299 %C299BC99BC99BB99BB99BB93BB93BB92BB939992BB93FD15A86F9292936E %9392926E9392926E936E9268936E926893A1FD14A876686E6868686E6868 %686EFD0E68A8FD0CFFCBC2C2C299C2BBBC99BCBBBB99BB99BB93BB99BB93 %BB93BB92A7FD13A8AFA1939293929392939293929392936E9392936E9392 %9368A1FD13A8FFA8996893686E6893686E686E686E686E6868686E686868 %6F68FD0EFF99C299BC99BB99BB93BB99BB93BB93BB92BB929992BB92A1FD %14A8849A8C926E9392926E936E9268936E9268936892689268926FFD14A8 %AFA86F686EFD0E68446868684468A8FD0DFFC2BCC2BBC2BBBC99BCBBBB99 %BB99BB93BB99BB93BB93A1A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFFD %04A89393929992939293929392939293929392936E9392936E93A1FFA8FF %A8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8FFA899686E6893686E6893686E %686F686E686E6868686F68FD0EFF99C299BB99BB99BB93BB99BB93BB93BB %92BB92B592A7FD16A876929293929392936E9392926E936E9268936E9268 %936E926899FD15A8AFA89A6868686EFD1068A8FD0DFFBCBBC2BBBB99BBBB %BB99BB99BB93BB99BB92BB99A8A8FFFD13A8FFA199929392939293929392 %939293929392936E9392936E93929368A1FD15A8FFA8A16868686E686E68 %6E6868686E6868686E686E68FD0EFF99BC99BB99BB93BB93BB92BB93BB92 %BB92999AFD17A8849A92936E9392926E936E9268936E9268936E92689368 %92689268926FFD18A8A16FFD0D6844686868A8FD0DFFBCBBC2BBBB99BBBB %BB99BBBBBB92BB99A0A1FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8 %FFA8CAA8A8929392999293929392939293929392939293929392936E9392 %936E92A0FFA8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFAFAF76 %936868686F686E686F686E686E686E68FD0EFF99BB99BB99BB93BB93BB92 %BB92999AFD1BA86F929293929392936E9392926E9392926E936E9268936E %92689368926893A1AFFD17A8AFA8A16FFD0D68A8FD0DFFBCFD06BB93BB99 %9A9AA7A8AFA8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8 %AF9A92929392939293929392939293929392936E9392936E9392936E936E %93689AA8FFA8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFFD05A8FFA8FFA1 %9A6F6FFD0968FD0AFFA8FFA8A89AC3A0A09AA09AA17DFD1EA8A97D939293 %929392926E9392926E936E9268936E9268936892689268926892689268A1 %FD1BA8FFA8A8A1A876766F766F766F76A8FFA8FFA8FD04FFFD05A8FFA8FF %A8FFA8AFA8FFA8FFA8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FF %A8A8A8FFA8FFA89992939299929392999293929392939293929392939293 %6E9392936E9392936E936EA8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FF %A8A8A8FFA8A8A8FFA8FFA8FFA8FFA9FFA8FFA8FFA8A8A8FFA8A8FD04FFFD %2AA8FFA89A9293929392939293929392936E9392926E936E9268936E9268 %936E926893689268926FFD2CA8FD04FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8 %A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8FFA8A0 %929392999293929392939293929392939293929392936E9392936E939293 %6E936E9368926FA9A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FF %A8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFFD04A8FD04FFFD28A8AFA8A19293 %9293929392936E9392926E936E9268936E9268936E926893689268926892 %68926892689275FD2AA8FD04FFA8A8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A192BB929992 %99929392999293929392939293929392939293929392936E9392936E936E %936E936E9276FFAFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD05FFFD28A8A192929293929392 %939293929392936E9392926E9392926E936E9268936E9268936892689368 %926892686E76AFFD27A8FD04FFFD05A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8 %A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A192B592939299929392 %9392939293929392939293929392936E9392936E9392936E936E9368936E %936893689275FFAFFFA8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8 %FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8FD04FFFD24A8AFA8A0929292939293 %92939293929392926E9392926E936E9268936E9268936892689268926892 %68926892686E689268686FFD26A8FD04FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A092BB92BB92 %9992BB929392999293929992939293929392939293929392936E9392936E %9392936E936E9368936E9368926FA8AFFFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD04FFFD22A8AFA199 %92939293929392939293929392939293929392936E9392926E936E926893 %6E9268936E9268936892689368926892686E689268A1A8FFFD21A8FD04FF %A8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8 %A8FFA8A89ABB929992BB9293929992939299929392939293929392939293 %9293929392936E9392936E9392936E936E9368936E9368936E926892689A %A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FF %FD04A8FD04FFFD1EA8AFA8A7999292939293929392939293929392939293 %6E9392926E936E9268936E9268936E926893689268926892689268926892 %686E6892686E686E686F7CAFFD1FA8FD04FFA8A8A8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8C292B592BB93BB92BB9399 %92BB92999299929392999293929392939293929392939293929392936E93 %92936E936E936E936E9368936E9368936893689275A8A8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD05FFFD1AA8AFA8A8 %9A9992BB929392999293929392939293929392939293929392936E939292 %6E9392926E936E9268936E926893689268936892689268926892686E6892 %686E686868767DFFA8FFFD19A8FD04FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8A8A8FFA8FFA8AFA7A093BB92BB92BB939992BB929992BB9293 %92999293929392939293929392939293929392936E9392936E9392936E93 %6E9368936E9368936E9368936892689368926892686F75A8A8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD04FFFD12A8FFA8A9A8 %A9A1A199BB92939299929392939293929392939293929392939293929392 %926E9392926E936E9268936E926893689268926892689268926892686E68 %92686E6892686E686E686E686E6868686F76A8A8FFA8AFFD13A8FD04FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8A7C39ABB92BB93BB92BB93 %BB92BB93BB92BB939992BB929992BB929392999293929992939293929392 %939293929392936E9392936E9392936E936E9368936E9368936E93689368 %936893689368936868689A9AA8A8FFAFFFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8A8FD04FFFD06A8AFA8A8A8AFFD04A8A1A1A0A099BB92BB929992BB92 %9392BB92939299929392939293929392939293929392939293929392936E %9392926E936E9268936E9268936E9268936892689368926892686E689268 %6E6892686E686E6868686EFD05686F6F9A7DA8A1FD04A8AFA8AFA8FFFD04 %A87DFD06FFA8FFAFA19AC3A0C29AC29ABC99BB99BB92BB93BB92BB93BB92 %BB93BB92BB93BB92BB929992BB9293929992939299929392939293929392 %9392939293929392936E9392936E9392936E936E9368936E9368936E9268 %936892689368926893686E6893686E686E6868686E686F6E936F9A6F9A76 %7676FFA8FFA8FD0AFFA19299BB92BB92BB92BB92BB92BB92BB929992BB92 %939299929392999293929392939293929392939293929392936E9392926E %936E9268936E9268936E926893689268926892689268926892686E689268 %6E686E686E686E6868686E6868686EFD0A6844686868446E4477FD0FFF6F %C2C2BB99BBBBBB99BB99BB93BB99BB93BB93BB92BB93BB92BB93BB92BB93 %BB92BB939992BB9299929992939299929392939293929392939293929392 %9392936E9392936E936E936E936E9368936E936893689368936893689368 %926893686E6893686E686F686E686F686E686F6845A8FD0FFF7792C299BB %93BB93BB92BB93BB92BB92BB92BB929992BB929392BB9293929992939293 %92939293929392939293929392936E9392926E9392926E936E9268936E92 %6893689268936892689268926892686E6892686E686E686E686E6868686E %6868686EFD0C684CFD10FFA86FBBC3BBBB99BBBBBB93BB99BB92BB93BB92 %BB93BB92BB93BB92BB939992BB929992BB92939299929392939293929392 %9392939293929392936E9392936E9392936E936E9368936E9368936E9368 %936892689368926893686E6893686E6893686E686E686E686EFD04686E6F %20A8FD11FF776F99C293BB92BB93BB92BB92BB92BB929992BB9293929992 %9392939293929392939293929392939293929392926E9392926E936E9268 %936E926893689268926892689268926892686E6892686E6892686E686E68 %6E686E6868686EFD0F68932077FD13FF526FC2C399BBBBBB99BB99BB93BB %93BB93BB93BB92BB93BB92BB93BB92BB939992BB929992BB929392999293 %929992939293929392939293929392936E9392936E9392936E936E936893 %6E9368936E936893689368936893689368926893686E6893686E686F6868 %6F9A204CFD15FF4C4B9AC399BB92BB92BB92BB92BB929992BB929392BB92 %9392999293929392939293929392939293929392926E9392926E9392926E %936E9268936E926893689268926892689268926892686E6892686E689268 %6E686E6868686E6868686EFD0768936F70204CA8FD16FF524B6FA1C2C2BB %BB99BB99BB93BB99BB93BB93BB93BB93BB92BB93BB92BB939992BB939992 %99939392999293929992939293929392939293929392936E9392936E9392 %936E936E936E936E9368936E9368936E93689368936893686F689368936E %93939A704B2077FD19FF7D4C206F6F9A9AC29AC29AC29AC29AC29AC29AC2 %9AC29AA09AC29AA09AC29A9A99A09A9A99A09A9A999A9A9A999A9A9A999A %9A9A999A999A999A999A999A999A999A999A759A999A759A999A6F9A759A %6F9A759A6F9A759A6F9A6F9A6F9A76764B4C20214BA8FD1CFFA24C4C454B %45704B6F4B6F4B6F4B6F4B6F456F4B4B456F4B4B456F4B4B456F454B454B %454B454B454B454B454B454B454B454B454B454B454B454B454B454B454B %454B454B454B454B454B454B454B454B454B454B454B454B454B2145204B %4B77A8FD20FFA8A87D7D52775377527753775277537D537D777D537D777D %537D777D537D777D537D777D537D777D537D777D537D777D537D777D537D %777D537D777D537D777D537D777D537D5377527752534C534C534C534C53 %4C535253527D7DA8A8FD70FFA9FFAFFFA8FFAFFFA8FDFCFFFDFCFFFDA1FF %FF %%EndData endstream endobj 227 0 obj <>stream %AI12_CompressedDataxkɑ-CFXn#axVՌbhPjĽl/=~n+U̇gd<͎?eX=~|zOz~w~?n×ӷ>~>GϞqwOohl߼~$ OssU5>Կ;|͛o}34wz/Wt_]|xߦ/]W]ۡx/ rm?~Oa7~/̛a~3[_ n~[/޽ꟿOoa4Ǜ/q}|ۯ/~ {c|p??y_ӧ7{oz/wަX鳿~Ʒ'OWvf4}ۿ+fSS΃>}7緿ͯۯyg ٮz~=y>?ZWUW{ <#X9~S<ǻ-/4l۰A7?޿} 񱑎>~=#qz/*޽_73A?Φކo~˺\o~z[ =\RըZo8Ɛ_>˻_ӻY@+<gRޟ? W;sW"||:"x/l>C|  |K8bC/;x7>~o?ׯ?3_gpV@wp]o= oy}3>WO\3߿>cwϼG]5wWlDz!o#zʭ_>f~ۿ>:2{gzϏCť'/o޿Oo?/<tޫ΢?^/}b~? ;} ނ(_/pxɼ2} z_a`=o>8^Ç7_/P}aa^ׯ~UnjXMRnXRork]F7mM4Mׄnnfk׶k};~n]չwc7wk_uzߏ/oW$O~_6TC=Zn0`0˰pNc5#l،ء/ql;~5_vX֢uh=GF5d_me;Ubu^Κ֥#W?6i#^z2+)zXU x^ ~]ݪg>oq]:6wjj/-{(pe3}3eSWwB3}7?tkӃwׯ QH}ɟ_Ԩ'?E'eJx&M'P䣢 ~Jl`ȮFvmj'1izG9cMvF_mC4q#^xŭvW`;~#(3x E* *F++'Wlq2?YTOZ'ޤQrΣO!2W/z+Ywϲ%aːO%z53kbPx#,@pN\.'5̳O^I25bQx;;bW\=z3&i%U5Zn#\Da-sB4[4nr2ӅI"'XcifS .DPnEWpщ \aDsy\naV_p, <.Up(t#/=x 嘊㕘VZm9\qeeWNv5_ `[ٖ wqW[{Wn5Fr: ?uTomC?%XuSdI_խrZe|qڥYgֈk մnM]lwpcF_!I{.UxxF86`q(ʺWR{LB31fi^ 2oZ̐58jUj0Ri) f7N^Mf~ɣ9fFkpΣyOlL(]t6vŴͲmlnN[u`{7moȰVj fL/BHBU1ԇ|l/և:8'źr BuS+1UW_qU")ت*7 _H'{+@cTpꠂh2l~ )Kj qj2ZVIWgWTTQUEFix*euJG.+5YZя=M?ч؍cB/첦0Za^s:D.;w0cW0uk{[8NW4xl¸q#;.m.S8 Rh͗[j-\y2, |G\~23W\F%MpX[%vT oXrzgy<,2[e]Vt|RzDp+h]m=m`B5"~:gOh[6xm',>>d#6$>AHl|tM:a0no9۹ϼy1`_r0⚜\Fs.R1 }sι3Up6cG g熇h' g VHy8:88jLmp-˼LxXtxsۊɷ a:0搂;an4܈d2ANi:iG~x!Ai2 6NXI0&) S_\.G-LlȚ0m19rt҆ G,`} Gc6x5x]&bϐ8I&JpL#1^nG0tEت Ͻ+3/.&D; EȈ ^.'o*&G}7|AG-0Oc_ yFGpf<MzpYaJ7!'MxrmԵ)CBX)O{w_SnhO5Ӟr񔄨B}09~1fYw\h/C8˅Hg}`'Së \cAu?ZE0ߎqK N= [W)zG]6ؿ/h7CK.8d 5wbG1\㮩0t zo9Xsu\r*f\xǃNl9蘽{!L|=娿`5Ec ;q6븼_]/=Lxwhj|}qӀvc_CW)+W:C0?}&?vmiq9Bm{߾}kM$A7mkoĴ[H0 44NXQ-  ܭX{{U iMW_PV&BZ"W uCg&5mgҤYi3Q6HI 3&NI %:,oP/!$:7g7Lo0Df8x );ǭ9Ŭ:m(<avh14S@!s qcI5̌ :ht%%,='FpY]}Jik6љ:, .pyI&&_׬{um{P0Pr1kKbϭ.ǃե j HAҮ/եY_j6Wq+fL$Mr"ZB1)@}Zޫ0)Vg%ݷw[^;dYR|Q=Jc~Dm<̗[E4jr_Ù>cB\љџ,ӒJNŐs.z-+H%+&]`PҥO}`dJПdB0fVX$[ Op* D35lN`\UArI K^s^X0`>m05&[إ ی[GqjpJ`rˉ\]0Jٸeekh$z,|E  ,R/%W%?EWW.G׳V͙MBfSz#hlVѱ#Nh[H"p΂^jFO51DžHr$*_9Ԝ:/# cnBdbpP`!3>3I0MˆTp""[OjJgӄqyk28r_[̪"vS/Y&2Rň/IH 7PT.O$-Y󳣞!=s5rϓOϔOBBE-‰ ڒ'4AŁ m|'_=]Ǩc$.j$Ab,#I Qd?r{DG|rG]Lq9̺d>W~fJF. "4ʡp{Up#x'&az=qqkt`ƿ ?p .#}s\Zy"`b6BJա*Cφ@:ՠ8: vU㏮J87w [ĚXY-lJh>-ݒtW۝wT@ !Rs9C *Zbڲ`2X`Zilnl]3vg`M.|Z*Ҽڍhv*1,m|XhOZxϙv 3올c_a}Ȅc>Խm =ߗl!O$1IFsR'MJdnrᙄ-7=jW L 4~Y~cʴe39h>M'9pO k83 ,厇'˜m AaJ!pyUEUɟKr.$Wעo'|ހ{F7>^0%igJ#Yc V#!IE,x2 $ZA&Gd':FNH<$~ڐTUǬwH}v\mcs1S;뚊1-U4 {wDwS]-n~0!/6|\C>9̞$k)YIOE1`Ky$9XjUMjɮfd%+&D=94?^KGP?I:?Vs}mrek99 Xlۘ-`}*PJt .y)E&KfEϨK%/p( 0TP RHF &_hy͞.o#kCb8t~I@ )1`a%=p{pt*:1m fF5gsQ{IA Vw)s*VY<7NZWUQ g Y2SkZU<1 3'=k,,fiŬz&p9 y5hׁKBEQ)cTT'j5$]Ϟ\c9#8gȲM[C03I\* Te7>s✼9|ěx; ?JU& }ҹoG-pȳW1idfK eSVR>'J`ҫ е-|,.+>K9'Ũ/,dL%J'p r9VXR@zH_𙧁P&r̭>D)#^#VMéwІC3Z?ѲrdہFuhG4.ڮ1PQigw4Heq4 ,iߵyL~ X4~M gf[;_z xZWpA;Ha}pAr K= `Ln༲Į8{ɓ](8uRGڗ fa w]2x} ʗ{b)o#AdZ#>Wr3U:L`XRYy8ٶ0–c蛛A_q'?_C.di\m"ae3qֿmmAZj„Ieq8떯#:C,X[h0 6 ƊAhXg ZWBڭkVB] *ض+fE?ia2m?mڏ"!ʎ\1r3ZYόۂ9pZZҹB׷ɒ4.><|, (5.eRř&XBb- ^"1HAϷ$,}OpRۆ>IPTiFD)"K?0W&)22[|npuԥy1ڔc2/xDOU#=zBd䟁q02 qڽs82?Rbq_9W]MJdzC()݈j7o'D[`{R} XS͜#|s|gaskO3*FwlgPpT=v>yW9c5\t~ 8~@ݺV`e_ gt9$ƪ+6,֯r#SR5@!>lVrb%Sh<ΒOpf௙H58dzq"KА𔐂Pƙ̑Pq'Fy:yru]*4s4#In.'S%Z<1sVr3*&&;Ay3N dd 82J ,Ӝ潾 LT ]*<&-ǩ=1Dpv +]+`ipz@qk-և`2{O祧`:Ά '4q(L>Oz=&'rRG>Rm(>l2Dѐ./s^9BTbŠ}5z^n}#]ǟpvM_3&Hֈ`ʨItޠ!tW/hfh p Im"h HjzXe6Kb%Ṿ#Eۏ,`m4`]t=+n)7 IwClr He-ڥR(3|-.e vS Q>7 D>'.i4% CQGayD 3i܊[zp W2UJ1:,;n.H} 8Cdq?i<5 {Y] C`lO9>%Z+4~55Zí+ud=$Mն8miApwnm1v(,b3 }2/[ 0&b Ls혜!,]'Xzd2Lm?in#Ƃ3S_ Om^lēV'c;^ؒ`Ĝ4<ETw\ЂrrM{W&0o#NnO4}YF (%DpG0Uݍt!ěPc8%XBX*Ske*XIIe&&g"52p> Z馬^j\Lt6I^䀳%ß5غcQo I)åk^\1Z(0B23}윥P ^sh;T#f(qcКy26)#w "DN0͵0jXTCew3/1 \d"N^5gv[AMp]V"&xliΩtfPWPHg `^`9qV I(]C|=2_JkpR,$ FBEDP,Bp ϰ(~M,ڠh8 Ԕ3 %Lu7dU܁AkNgAwW9̍ޏ%@|5KV+q 6EqXη(W\AHJ0D~{Q_B4ߞ;xph<<z 7ehp5ӤNB7V>FYKH@PT՚bCpi!"|4"d!Y֌xփnJ"fDs&XE,}Z-'d*Y)s%*،!㿪*9x/ޝ] ϶90#1w-9i\,4J]'\Y||12}}' L~1;©&Vy3FôGzn/G2֛wOn?(Xǂ}6[Q^<"=hIv:m >?VFS[ή2ٴyTj/).Y[D%hWqj-s˨Aqx* r9wjt$H[B:5?0rmj`Β;c}L#}:=Xҭ>nr;:ǓsC29?P> kN] gV =1er߀tXN7a.&+cEA:1i=蛤GHn | 5kƅlŤp|mxՠzq'|>=Fkx19Ƙ3+!&5nTDsGZ.?yTf|v6*߽Oݿ[2Sc$pSl,|qp s/nڮū Ӫ=+jFk=?>Խ*LmdUb]wkV/W7N{m~ oW{~gpMuoc=:]IߒN+NYdW]6{UgS?|m[^+yuv'߿\6kbeaJypKW67/V_ gaf-#xI7Qvc߱_ӬaWW\} oߠjjqwpNL Is9U~*ӟ1᮳:?TEaC~|]5ZmCc1lkE^A[( ּaC<۵0u`!.#f|~+2Y.?";bUX |H?{I&A\rsR!ACc>d(OBtԪ^ Q:_tjrj0MuDՠaҎI h|FeY96k!@$"fb#e'65- 9Dۦ--F£Ȟ[>Z`,>Y^_&9l㼳ҷܿ=H8 6lޘv φ@$,{^MErRG|^ңzYf/}g:q[ m=g 6n)^|oCKe=NٯJbvoha, x)h!eK`trlG|c smdۍx~a%;b((\Zw%#.؅ 7 FZvmߌ+]0] 2l|-GHVAr M'5Y C _Oyb s# ]8b-) DŽg8'mjۢxWohu_ τaZ{Yh+ƊTP`"grG{WETʗ7\JF+7epX-mMie&?16OՊeGM&Igh̨wv5JW`LL Z I\m횈}<21_2.7JN5[4O%2 <`D&`\L@2eN G,'ĝ Y0\;$B,x 9#f<IW@>}@'4kab/w:yC/SF$y2rVJ8x#o؂pkfUHO}'jT l:`1[}0k$"es-7cHeW[ynfhlffU|̅OBzgw|n~̲<s~VGyar>@16g?3%uoٓN/bN( 'V#&ƿ Y=y+`!Rص^G'w *D^ޣE~BU3poqfs(6p~Q2cV#j6<#e,Od)p5,Hq,$HD=)\6U4,k@q-jJAqa |" [9DzűTq&q})yaFeAZrJl &O,&n]Gc 3H;E(ntC΢!Y'>Ɏx9#>%s|M)^G-kEV[`xͱ,ثgJ/l}2'ʭr&_=Wʙ`~ IK+yx CLɝ5D }d$]JcWp0XYN#+m 5&ur|PHI.?IG2?zpI>yFGhԬ2vkB>bI'܊Z|6D g3v 0Ds&MD Zs~+JʺM Ů. f/݌fgA)m si9蔌c,)7glrRQ& C}-^5:KN{ [{` A]>_O' 얼ܓW!(-uXJѺv`22nԺ!qS8bݘ-@(biMI'7cx;~B0ӄseb\&sʕ͏E#%$t%kVRbפt!C@+兟!.o)0KzXRĒ&6̂g5m,cI7ՓN0/'M(IjbG6} Ŕ]T%0swq7"oP 3JSUO4h@u,^Hc=PĂӆ_QVTQ{i:6󧋃 3apLOO=BZv;<)@ g%D i#LYYZ֚{ik紞amGA)YLM*hi/Ή\Ea`Q=ЊgiČ4r4=zٰ.5%أuL ŠjLκ"ФGA&9[ O<(3DoLIQۊpM'6Ad5_*D'*u,Zd7 }m#u'i3{9d'F^?կ4wZ#CHXA>G@^&@KR~rzʏlz+]Tj捕ɜ31~Nnt2{o;߇'{{ГM6%H2HL1HrE3yr &?xދF:C kP4VZ voZ$豵?ߎJs>xh0bϷ%ќmMPbXPD2{&ϕeupˈA)x8MZʢrhX&!Pa|8d42I] T^ (̚elRo5B6ڍ Unj&f΀\eo#OV Oc+-v0㒉vC7([auR2"MwWL-ZCs˽Љ=8 #v̠d/#>om[O3,65[(6 OҌ+2`;묭@0xAsY3i:U25%UT1$HV8ͪxVDVNn@tGEl#:TQXPzJ ińͶ[V Ǝ,T,o  X"rS0W %S:i#OԌ3 ~3ԌǰYt<74Hi:mt:m _.,xҧT n2z+$Ҝ\%z觌+`HI!:~ggrI)sq'r@S*S;I8VFCl8o0Wj?=Ed0"q(XǐpP؆Y"Xb F I. Tn Jhk34P!g|{Hc|-ZgHOޠNVW]#Tz'L`>jyIT=%??+#nju̐_c{BeB9=4b}t鿿طj+?bRzjmŶpÐ~hCHĔIU/enŖa ⛋ `F"BOQ$e,jg6`D;!9Y,w&e̦ Cާ]= k)T2uϠʼnRޔu~‹Gӄ?8aR1TT)mVkNz峲G5+e dHUjKL`kYsߧ<#`0b ;~M h0}r.xuWnƟ1z(АOr(Й\qP[k(GF ({@i%>!5, jDQg1iض[ F܎WO22tQDO5Q#OI#یl!鸕mVgQg@O#]y4Zn` lp$f a}1+AgzpsmE$%’F, j3hBD‚2,+GP;_ALzu`荕EMJ+q[Q1 _w?2ˈ7[,YjNJRFs!3iYTA#>ƪ{+qˑqF<Kt^0`Ļ"dyer! !d-^cD8g|k?!h&Z-@WEu*Vh`hA>RExSS/m[p@槵]! m75^δ^/[r%C=̓ƌٙv[23 L]ݷ-Io}apCZI? `C3cCVaUGդʩ)|@{ :K f\*ֆN FQHx"l9ia#&"ۇNLIyVߌ;aPZc1a8bQXLBK ؕwc=9SO'E69WOb{G©b-Ss_WVZ^Hj'+6V8;aѓkG_NsWP"xi(<{, SD\/b׀?^Cwp*?uPk=eBTbQN3(v**,-wX.X+Z1|'|GT׎94&˳>؏a4V:ln_␺`mWGoteie)D"P5P˂˟1dJlBzp¤)3ˆi[BJ <sl0"ssss,J,rV!{aR\ t2R"2OCY"'=Ipo&uLJf%\K$j 8¹~tf^{E?{Jq^UP@+{08hk`G2avH4b !0\o΀ H & ,*8A[Gr=P )*5R[PNHۮzoĉ:VE?v!Qv%@?AZ9mkȔ35!F|}4R_? Xs?@6L8$vP/Dà lD K30-Ru&$Y m }gA;IF$8Q[HW@#BN";EOCNx7c"_184>qPaH1+1,O Sڊ~҃Z.>x ܠXBKfKc~0;&!Y b"Ixo}b,,C兕 ~pD oCO±'\;Gh qY]lGVb=GP/!PR^v&KpssDQZe般eyQlg͊Yv)!ňG*(SοiZ2)!qP8\}c eR Xp#]x|hۆ'փ_ɵQ`m.<M>lM.3]z[NyJ$Lgw>bBZ#EՁ+kT-#%+.7!$W 7[_CH-n`>5o,>~#]dQQ. c25B.`co []}!͸9js s3Z]25Y*5^ է3<ZKҿߙO P#u=\@vÓJ:lEbZsQ6qV׌ t 2_3H'Q3 3FpYDq%-<6"SrܳJ5JKEl9vn I":RB[gKs.@_I|rV} ^dc]mC&ܫ^Y<`]dn:>g6$;`U.5˰kʮ\Cڕőn{~`ۺ&DaiWYH PKC; FU^2pֆ!QpINdαi@޺};{K \r7+M#>b/F$1 6-*IL V/r;…f;Eͼ\(i%l)鐋rWӠWkrדm@ҩ6!>p2$iXXٕ]VL-q1$iG0pot3YNӞ@_2ľvN:p%51KSF%(fB<jm Xu@/ΐ KܐP~ݚ٬bE8 ,!:?e6`3.szvd?jUϲLj/#TKQKXhl&V!ʤע_ |,XW$3)θ`2-p9k " ìΈ'CxWؚ`' ժHGqG䠪NˆKD JCNB E_ py}Uc >f.%SX{eħ7(?gTINgJ݅svbKT)WBgN #R{+i*:]$4 9wl5L 5wlLsvO(:ZtX2sF|Q{Q{Q{Qy5oZ/V_j}6V쓦P~D ,ELxNں=,sE^+~S̙0F%+M9'f4+e,&f_ ԨѪcV#djaJ%̂b%\HMFͣc6VnŕY4TEJmbt7̥7[wl0g65xu/ }݋B_ƁjǑS#EQ ]Rx/`=`c3CP\4c#oؕ *k#jj%jש*O?N%a>pq=?B~)ێ4t@1hq`s `yH>> fG!Z]{*Y3aA[4٬B_ʨF) }?vd6Sƻ<вf\㪶qoDc>׎ZGWzZ|H=bwGwphEܗNtKs`1uh9mք1M@'V+&: >W?%cWg"0HF_pKpG\{xLʇ# aȚq' DZz t\dRӟr6r^t'-Ų9=މhA)]Դ]gu)ԍLNe9Z|vJ좖-mF.-Qa%j9]8ƅdDWtn3b#@>rջKэ]qvm􇴖X{ ˸(6)ڳ|"pozIco`⟱pߜeܳjo*]J< PgIhqi\XbZk^x%48p*RQL?jF.Ip"IS;haTttwD">r&Q,cB3il6i]:rb -)nH!v*cGgJ\.G^Jp_shD+˴[T+AuR lkӸtk5p"T-q{R2btܕuSX/^Ki֚#K6Ui:du9Qޥ&HQzF".Dr&[\J6+ґnP+ɘH,EW+]vYPJmt9DvZR.svZi+k(:L0>r \bh8O5^:+LF`בBJU0'"6 l"|T`mi0E' 2(i>+pb&#F?Wٝ(zG&K E= =D0i#f|6h.XbB#6?e c1b3# btf;oz5#j&{m)m'z RD$ztAW#*kNl;f\/ d/7> x[\3+!,j:hVXϊ̝L7s|7X&JIv%bsܜW?Y!9 kGQw8[֛k\0b*A[! o668U>ޱ𝕽kݍ a:1 ĉ5_IE;MDj5#+g-pYyz(هGpFu"B`CF τpNX>z|FsCܲ 6C=ɏr(=y~ڨ,7$9<3Jj- k2vO՟Y/(U`6ٍH`6 r%ț7+EzNIpE(3HP"Rr㏫2y GHd_\<>^U0fw\znܰJ4kFm,&~fC~mNXuF&kr/ MVu*j֪f>x_ȭ6 ɭY{av&{'aNVkLYNK Opg>t ?{pV'p?Xb yA`ØEapz61KVlI6m,/6#㦽ĝōp{s.ĎDV}V0s_D E!;֝|T .d  *;LdpGg&9*K:tL9G5<"ǽ$Z&9͆GLgZDRtV"t<8{aSǢLb< 5}eei7ed!Ec!OJpVƖ3pt=5{h!bMxdxrt3l{sE_Nh@RrKI KR.1}*{5WCIRozZA<$t0I&K]kpqDݎ6U5 2 VY`Aٯ"jl,+U`oI EAkjŅ+z^XE`^xNnwRp :gyއB`|LWv>yyo=?>A -ox]O.ktv۴/4vbAh{>]nPHϲhtU-dDᤑ7az6JdBR2b%9Z6=ޟZmE V2( #|SHպ(QthЈYLaTH:*kQgif"4XD ~b?FeL<7>\~^0 89>p2;mQtlJ9# J$`.aLJo|]Oz& D'3M[dotHK| Qޱ.p=6QFz0iM!wt`((;8*lWJq+&C׿XSK1o(1ã{3ߕ,|^ˎ8 2CC;\6;>tORS3Fo#iZغ63jwc{|Ï3ёgş {3rн=ݢ_cac/,|fs( ˖FZ:N90@#2 . j{?LKmRaʒ4ǹ8ƋMO pk;'9m0m,idIct4G[6Ɍ"tMY pkPGq/${9/d]Ykq='nD,¼>@㞌r@pm<}==Ks! t]enN}c-3^"V͎2WX~Y"aWh!@Z!J:#E܏7c.іa,{'UÞ6/ =hk`^djA5[lE~SV} X7UuO9}8_ΈW鼳\Sqe͊ nWXr؆D٬cCmik&5}O\7[ ȫDz@YRq8dQd9 e]|iMs.\_)fT74GtazkY=pN!"uĭs~ħ>= 5ᎇ>jBߘ .Kỻ[Χ0tI^쓚u0:pqO1Py5@1 \ xê,sXޅB>X]gGo#rw6ZD( 'wt{֬Ti RI:E^=L>ԴfC9*u3O+A'9+^G=޴?v}=س>5*Ē&d&Ǽ%SJ\Yinq^C.iʶ*iҶ2P|cJ"]Qp]quae}m2dI Oq8u֧=6sKS,R1E8Sƌ/3k\q3f]`dA/dY4$KYGv$K$gVB)./'|i"N*Kbo9Nsan#ݭ޶%J{[$ECT7n)'@"}d0bV~XXJXb BJq9lAo F>Y ෭orkˈfMMGdX]#vIaY0?LD31ųj{Arf1!3#zi?#psKgZQ8 X~7pn0b>'4fbG=cqBcSRD]d􎓖&ژ9HoL'z0{UC_n[xtRr)$@h?\~ȴ+v,+ !T}vv4!'l{J[Ψ@2DýIݪEګ/G:m&;(X\i"3m ` M"۷(Q'7ڲd[&8,-K'ŊMJ,MD͌GwbRV?(:JAY4T¸aI͇e'*n@kdE+fwzchZ !^b!f0Rr" ,zHKδ}GD1ϣ>+fO#~o0}7{I;1x .3Aq!`v@0) B~=d- ?ڪ[LW43:d)j@B8OBIߧkqG "%$U^lZ&_K+V"^CH"_,Kw 3Ŕ#@rȍ$jߵzARZh:݌=utsO 85*z J]pm dqC )MPvsôMiNMWS1p2(IŵbhMij' 0lȾ[|_Y %C8<3QntzSXQ;s-;ܷܼ߿oOQ~ڃ[Q;֊x&.UoZŅE\/Qd(z$|HqM: [(:9\;/ZUJowZmE5'6UZQ:j+*T"S7#(%{(Dl6\KJ+K  浯 FAx5kd߿+>bԍ F&Bo<0sD#w6('MSWr!4%չ*V rְUTjEf\\mÃԠx@sYre(T?:Mͨ@³@QMx#tYEq =Aۑ3!.'@@<Da&*PsjU}TbfHo*dz .#rP͹4=)yLufDccƥ]T ?+FȚ-a$c ܤi22I޵b4k1"TtL`0+f\M]sccG41L )[G;^q4jU{Sv8̶cbvfVln);M46+*nl֠ g]TV!K%KѺͨ<+E.dÍڌں 6&Q¡ Q 6ɒݲrR3UI@jFaEV#C,d*A6=1jP6niӮOopO(wWb]iY6Ś&O򊷾e6Ԩ*>{)d3 <m{;_%;5TO_쐃;SO#:!0j\mGL3[q*}W@UPݾ~* ݛRv?{k4k7`-Fgl4c['Sl q(Txf3k'iO:RNj7ѦfEkxq8wyvO]\$-2ou.31Af.|2ouEkҴ6zYLSeM-cr|]>{L7y!هᚏ49GYԪ|y ;2sFN>w{wIyШaj <N;qVz+n#@7x8U'ڑGrc:u#*(3:7,ߘxl/3uSHXif޼fx]Ļ3rxdw4||3|Nlfre]1ÿ__> ?^>h4{׽!zg{=3`L0*N7e-g2QM {S.K֓O]jl훹v/ g;s+˨XHp>Ggg)_se{μg/`1znz@Ս!Fi1V5!جrivOZt.3 a`4,x6 %HiZZs\ՁTA|B7߿ThӸܦDn$I8d.=u_ ̈f P|<78iFN+v0 ͂,4_(7I# b@Yii[h|q5ӭDލ/@VC@)yuEpAG} ;ܛSGl爭T'H.2wEuLnf=Rw/Y۳|Y3 ,srfh /+3xrsɝIAqՌˉ[?;f"l[Ӌ??S欴kgF+b'ǃe3 >_!᳓ɶ3⟚ w7U3ٱ=kb\ *XWB+]xwcl] s/_&|0SKLUcNsRFQ=#I"\A3pW6oWh`$:;c8sU_;|8%ěɏ͛= YȐNyu |PNQa)3FXbD7Mw ټ^g;íqB_:^n*#'g548J˔܅)qq|N/ Hi`fl7LJs'p487Q=)X ^G<7_U7 ZlWV u6coMRsfu(=nc*SblCR\` ZThEZ78&C\3éd2=`og4R%;n|Hg<Ć@<"P3X#UN1#c%^;.~LhԮt^hvU juKy~F#uQ[zzE"cI>O17͕e\G (:MϏX-:cH~zV賁6 ~ ڑQ0W1"C1;!J$(41pvάb_5Q=l>g#H{jXyGƜ%UWN;(T BibŢ>;ΘSfjR)*y<;Ikba;ב㝘x cb8bL:ױdVח+.沐^Z<;h;R.!\Gyuo%NY0-kEV.ɹ|{\zYBRl.t;mUsk7oh_pm(ogpq#mC:]pET 5*5QyRfT78}x=ػs=ŪwܫR3ɰRW:KUNhw3vTk5 7J47DwHt$cpLvGZ8XEF UIֆUDifNKTaQ}g]]xڕRwb&QA^q~_dPGE 2"<2-Umڥh=ZQP{WVPJNڽՆ;Ak(i4Ycx5QC'8{uL[ͨ~Oe$b#wsswOUPD/ɪy%3M}*-=T5.9*G~CCPpKJl咰R_!_!mT{1ѤڀF0c3] {&tG*5(1T'Yg#+~+43@ìAJ:*5-E}\s !s{{h{OJ|Xʛ~&7GVgkx@VucGu*/v4lL1FNvFW2NyZq3gɴHѫǸ$xAǸ֪;z5 OH*+ʻ3_辭e\hvwǔ O_BH..жNW3/uxߤ=sSwܷ_C<]Zw:|~Axҍ6  ;FPwntWZPhY Ӷȴ^ ~>7,#|x3HLΰ1e;6)MdgSnɞ:S2Kl>sr:o)f8YROYdw; !*^bz72J/tr=e3#}q"%6t RV1ת0[X*\s$l*MhvQ=oh_ݖ)2:'S66{oQ޳1v`#?cYg'S%PTK 8_VP |3XsxB[Hĵp)/+p SLyE|/b6=/<>jmbCR9N ("_9t"2TY6 8'4M BZPOMI쓖@~dNgVuN0K<^exS]y]ٟ&'K-4MS&&E3ҧ'.nʔs)}_ "U!ㄶ=Rӓ%RS:WI<9׶{~;`/xjǛ=Vи?ڹ#<,-S3v{G;go.;n6aH҆ZX/6  .$sw{BU|uJ([y!eTø 1n/.;(̤ؑA:# [RQeȟ:7cF؀>-(;v{[%5$df[IgW4WoK,jPVJuq lQ66VTim8>SlkmFGo|TYmh f._Q#.S+99_bF%v>>3z'~9+3z.l$,zwYىFHss6h=-hJ5>@1b0sEZdppdM&k왡atŵ፸0D@`YΠb[׉&$Yuitʸ7 ҞOOy LwN \ uL}~-j7H܅Yb;saݵ;!慯աEe.ܵEhxܣKuhr#yr9vmgMԡU1Ez23LAxݗ=.x-e%Wjbҕ*v9j፤\%k$%6gY4wO E<  H=$Y6 qe*4:K蜤҂iq2 mNX^ &6V63SYe[v~l OUWC\Ԟݫ#V6PGیNZ5N#;1!#bYʄϹX= ھy3OKj5gҊSY 4N]

    W@7PɭglDq|=xGtՋr+=SKzײڸobDB 1^Gҟu𥏋v[קw8~I!4cM7oDjs,T`];>I&&n&4Ҏ3$^X|ѾO+bW(o>̬Ҙ~f+SX.w7}GKwŀ25mRR'-vxG|yGw?OaQeYAQ, o"@cgKg%h$[*  W`^9@J0ajp((:f1d0 ,u^¤7H'@-^؟\Ѱ6AxSdgy3组 33SK(HDz)mL[ aDVcïދՃcM+o=i9tV(dM Ldf?k@t#}.i`IOb6rbx;-;n*3`p2ݢ}.`H4 "-$/d’l΅d].Uv&(S{D2B6RE$8}^u]P/>?$KS/Uv 2W|i*5cd&0YX.uc(X =0*W徫[%SI  ++[-$Ue*o$ )fk4:xNqsRQR_8d5QjZKle6$srј}#XA8xs%J\$(15d]6u0 /}F[QL_\"ڝ[B(^9>ߡxwΒHMF@f-g%HAK80]`t7b p@E)*AAKL'A 4@ YM ,N i o E[= x ysęi !y4[4d 3!.eY;7wG{%_'ߓOS9d1QB2nB.%tχΫ˟z_ QYl+{̀c/{ȉ=zlOW-)eedI֤B̊grVMiaZ%*2,M@*h Ӌ̼T2JHW,LߋbG_' D@sw=ܫ ؇_ߵ5}+@QܵŝE7}iȞ^,BW$D})PNhn"ex>\ tR+7_1ƙ r&,fR&,d2&H=t$_;?=~#C]TZK]j$-ku;rR(EGi^r·S#Nm3rJ{UJW'*I{b[{sh]ϵcōPt1ah|s_*ǀqRHOY3#v`lQ3rMX7Wv*q@ yd#KF9z&iՍFgȕ7D"1q[Z!'$vI+#x0e.1 躯݀ד|-p$r &_Sa&kT/`L3.?Mu u.,ڮc->\:8c}jKΏ?qGWG. {s?rV\8}.R/}tC͐@QCNNDio:ڒR A8V\>LzT ﵻ1*ظ0g1:b-QՋ{g5V,{YuW/e*=Lb=[<sK=Ѝm1;D4'5kV_}J3_"'"ODR#y###;jo/㎣3cO wUdZi$c{ G8(x`My^. xÑ "R!FND)>mE5:R<2:QXy B^t]-"Trooܢf2NQL io+lT^ղ-jVj:)A}QU!y=ri'2{,AŃh,r0p3סzFou1oc=뼱~zzP2VoNnesU6ӝ]NH=(Ш8u'cg#|١^/;!zc@A5”,&1L@ǡaH {QF},($͍ݷ;^.uǫ=Fs|'K+ƳFFc* JNfCS .7 .Q'j͢ ɪ) B*)V/)q(*ӿ#;US=t4աm(duIcNZG5d͓R}x7y׽k'N$&#~0(xV)uEj~fεBZr:F6jֈ.b%GZoy}Nq{#w˝JKcJp [հ[k+f0VZb!kCV"FLb_bfz>OM`^ MP 6 Bn`Rr_ |Kr@h'wr[{G!jV~gZQs~$?Bpke(`E6郫QB6cZ޾ӏvK>!A(#]`@eq]>̝|u ho'/4λ Z),Xw9H^iucN%tSn o! !݃'=qߢ#HG<.UBh$RP\zL_Uī/?I(*=Pbo+vĺo"K$O_YwHnun`{}Ryc (L8az *`ox/T<m7KV6MB7*#|"3:l{q w:IXyrrj[ uZaRACVS0䐳8,5ROb c:HP! {Qlᤇj`SR|PNx"cIb5CV#('?*PWO #)ZK)R\"|^Fzq=XI|^{L1>̨[zύn<7&mbκz7SҦ62ô oJeD TB+HP`wc{p׏^@2P3@/'-=6oV_o3pQP_xGIWIJ;tmw+Wy("]Y W?Il8" pp*D{CrI4\F,bYZM`iJW +M]q VGZ3 JL)GP`6A(daR e~:Ҙ Yx"oF||ۀaTa.kU|5mWW3XrM.Um!.N0.5aG(D!^^\ }eK~u 0.]zunv }SfdUPfg6d\2yeL ~eESǍl>9C=R,Wǜ~C;KҰ&m;]\ cg'woǝWH 2_7H)f>QN?SxcOJj qGX1 z2 U,չx7 w3V,ڰ޳% fš(!KTW `ʌ7 _vcMn[$> Jq189͵dGMsRQKՖ2T1.uW:]t#ƍPd=%Bnb͈b>jur)Qx`DQmnFȚ9")c񉎥&@^īO~-(򖱒'Y Vf\@GM|]=.遶W8 8WPr('eX4C*؇g8 Ʃ>!tͦ,Y6A*=xg+=vSӓwN-AcCL?f Ϛex,\5Bf8ny  ӓڃvH+:5Uj>r 1xLVș }O 4,DpaZ')5&$ÆKu%9e+͜suKs`'l.aQ6Lb3e3\,xrNWjԱrV 4ˆ_6,_'r/dqLHV}m*{㼐JaZ'K8>!ꍟоU!ux>(f!>AsBwBE*%Ui!FJth X%G&~(PO8cu- 5//S+Dp"ϜafBlHDMgOz'mi)Os#! |=|}Hfw?qJG_D*,$:d%T!Qٹ9uBu0pB !GH@ߐV#>qWh)EtȫxI-qK[?#j$@@)LČRqR#Y6񬷝]M2܄5,pX1f q,%!u D$KEHH@9PdZ^F*s༡ӃNs.ѕԪ\UOD\=Ra& %UV$)^XB bL"o4QVӮ"d>fJlVQslwZƥEdTg>6٤]JM>Acm}n)Z Yhěj\-TXHDB^¬)ڲl^5LTa25`F<[*Qq˩\@]5sCUX2hCH4Û̀@0`r\TCAZҲ{,EeTKS]9_㱗eQօi0PFNq, R2x&V693 Q047S̮(M*BR*w&=vRy* n5Z > +^.TIXWgxdrd >0ҁN{fJ <`pgQu5b@Q9uţ?}Z̟>e>2Qtf>128jF[SaЖ{\2w9WW+/c!X+ P *B%ت ܯ*'JS]{Oך>e \~'p \~\k w+x;};T*%qB([73FraaF΢Ƞ H\**p sfo-^SBJJ?B4 ;.;fVEP(94FJB-Wl:w..Pz@^3u"nV%ʄq F0_q֕_J鸢I;TV%j_ҮkiR޶[_k& ( mj\dG/<9[#c~}&)|8Umw jƞU 0d稄(x%d`րXnrQux`q %d6p<4)jxf08tƫ&A))_WE ;}ǧ gAB]u׶'h PpO4瓊u=MaBҡS\ Pa;'D._Clnqs=s#Hv0<vs/xmnJ"*Zg =n, irAJSSjP*Fb $-oQ iG$ ;VtstkTJS' N2L[/_NݹK=!zUۅzY6g$C7:kx LJa2#Sքl;gDwnhyա],`^H}uvT3, ~܂9]h=_$Y uoȘIWsw*J:yȭ_e.(ez\2 Oe-3]cY0 O5FQuϮyYMBpNZĮ{F# -rWI2ӸVj֕ByULY.= QV]On;R; j7\e:Tv&w Nz-^Ϯ^kk|<1%<=)1bZ1^XTx:H!ͣDZ4ܝy0 g`bp=$$8 !WHnMeZ5Eb 84N)!Dv d>ziI6XƟD%a_֫ QZ]2i@n?/9x5 .K)H24DRkR W뫻p't34SIXVZu!|ajt᫋ےEgΊC 6do|g>1>k- &u 8_|@x_$ƗiI lw,s!tm Tf"SΆ˽ ^GpLO,l PlsJ#JJ|,4xu@k6*NR=&v(z}`t&t)Z25e}\drOs`B޺bVӉW]WՑHP VpZIv'y.3;\~ӑb䟫jI>%$G2^ Wop,/K²"+[!Y s*+YjqqLi ۥCB@"q3՝TCvD$, >=pP Qnurq??tU|# y)'J(Y&++INu31AsLb#){c_k[w}S/C3H[c1Y $X'P.7H0HM@L)o+52޽!ibdGi(F1Ѭt@)o LQW%8u F"3K1$"=ҾXMy9.TrsO<7sy|/w)S:d)J +fǑ5e" v$kz*yusꧠs1K 0gܵsvҝ!`dVHV\C,$ Upm^Z֟jgRh21O3:g2,chm'%+EZS=b#U]!gW\=ouZq|VʵI}W|}P5?cC;C퀙*L㇝?((%ԃTOԿaYI#9 gta|m&÷h؉EV "5fw'nMuekܠϞUP =et')UƂTl)&aWB[f*jlQb3l#Og>cݿ~2-Il> o-_im?@F&Px(УO@\/AGx:堡G U-kVOO~ 9X)eOPD1R~~Gx6\Yqo)K4!"/fZZ2#3b%Kveq,onO%)HKy'Q2 umJ?qU }ql{&=ag[yRe}÷wo@4 !Њ^0)f6R4 TP  KS* w)g{0}!`-D5fii ,LuuNgtbx@}sRXy;sqTX=WUqg/ :`P;ܑr'{ٵ}^{U#k{t,c/6ઓ;t |tN Zi 馵Tܗ{vJ\nGЂ4 < xgs~8bW=6ơΟ6, -={rgl^ؑDZGRz~Y?v Ÿ؎Pq$IuTooUyp{id._1OBAIJSV5FiZ2HR#e*uSb6(-#yۿQ$o`4w@nu PnlBgP7ʲDY\yNo AWe0b4ɲBv_Ӫ& 54M=@"69;v܊?߰ 6B3[*{ADx#qWAA`ū(?3BV¸&^Kkqz4 ?Kk/Vɀ-*v6.+,ۨ!r[4>ʟڽ:)/Wf{^z<,5KI*gc` hE6]ۓ_ÖّLYQgE Gd<tjV~pf&Np:B|g<b͒J']9,TENxez Wg8D3 uJsp4I *蜷('ɄՐD UY4m42ijkJƘ^D&_7d3U!QRXl!3!=!ɐHPurzmnpuf"t&{຦>l ݊=zxaN~=Gpm$ξoS]@*<(N<M4ΜZLS5U2Q赐{. MRf&$wuqv{B>ZHDqD%ӑ"O~r-$77=(odjU'm$|ˍyVh?*O$؋pIk! }~pUQќ dΌ2*wrrS |Y;,d5A)켧{+'S0^Wo.Y6l&*N7njV閵3o\5SA3)N_a+#DGVC;P'ST LW;LȽU2o&3o ^of,y4sQEj꣐nK"J`2q>guǻC)L`R`)L 0ԀT/2:7ǡZl#0nWøH@O pB+d/)w "V}S3Cp o\":CtG SՉV!1Q\lh;Z-RS㤸]{zslh"zuJTi9B=頲=:Z-1$ɍ"A]dGg&1 A`ĩV@5 rh (fwg2I?1>4cGuS*TԣfToRE4(EP%[A\js`WsF (wYX;0,gm^Qdb'T@C&D*I:I0-%JPNP3"8╶$W\@ QR-QM\oؓtbޱ7sMHe4tȦqQ14xIZ#Wrٙ;d$AZ "a!8Ɖ#2Ӈ{' V tpm4&Ҷf㶕BOjrzζҺwx?FV=_4Y]hKQƊ Z6e|g[֒rcKkoD(_]_wo<;z4z/tsCx!Ǩ*7߅滤$fʧ  #*(l fZ}9mqb[J[6WckcB=Z/Z[r9˔`6Rsz[_i{`LouLu_oG] lX/hȁo@ 1&W!|]%YT%zŒ?-y|>fD-2d,9 Tp0~o2ha0RXu u hoTzIu̍E\ϭ;*^vN2b=HjORG[bJ-6lZ- *bRX.@$Kg,WbCmK?dIAS0h. Z[-xZE*r^: s EV @1` lT%00HԌxL U$H+BJ)pB =|nI'>1X>I['I9G|&MƆm0FГQ]Wޚ/cp5u;]?Zp=ɤm?BpItfRYBn3 [Kn9}u>Ug^;`-bBoo@j$h&f2/XYĚMztE֧wlS*Ld>?#{@<'|PME3u.d>lڎ EN$9D$q҃5 ɋd=Ӈ 5=ХzFg4JZ{)NaS9B| }KvGvfM|z;/d!8QQ\vm{|́l=aqac4 Z5l8FqK8#8&MA+EVwp WŢE6^YSiNmBu+ `)U ˼H&Y3|!nf9{Ya8z|erRSI+ns(;VʧH8wXǂTS}6X\5H[HheU}V}\kvOm%t~VuQ>;6.7Ū.!WɎEFzF̀1dIb^@$x* Ivyw5 <k<&X?wB1f1ıi6-y'whnvFiXR{(!_bwC<}XPv2ġՋ)Sh{K54l!KF`D{Ӟ}A'ub!\㿟HH%) 80H]7";bdHWAH6<d*g|Ů(r$vO x  mWn0WfV(/DIX~24=\(c#\8UtS{.T*C39V͡'P>×X|.K>cdv] P~ 0怦Tf)0SnaU3r `Ŏ4%E7^^:lF_fCvͽw:@~w^zr*^v2@aUȢ3"+"x*q7Oðrxo9c^ O`OB\'@P"Wt.Z{mޗWt5煴Uİj ϤV'ΜXOz2˓ ≀Uz!)9t>-RFn$MjVDNj6qHM:ٱ+mb~3'mqiS4k!mWYWsӟ*[u hOg9  5㔞'f4c5b^'#c~.Ɯ4FIOg(ű &fXEg I S뱩7C<`b;Yy&X9)F1rX*Gv۹BBjZ=qz8ݔSyٕѵpѪ_ ]r•գ'L:cذ"WqՅndr S{2?3.+yJcr߀ns?n?c󗏍0 tx֥SMԤ79UOtR39 @I2Fv(p.u'cd%FU`lIU6`g(RɅ&(RUH0JTBeu! *6 :AHq-_c  _׌d04k 䚍 w6 WY19A7ق[q:RWd8/VrYiT:uJ+ߴOj5xOg7q@rraliW\B[:iw^iGyP7}?=hZ&|1 (Iٜ0*5M,7Ek0ٳ1=WѲ=_QRB^N(^B,+4ū mF0C %dD1udS&dmڕأZ_w?+J4?+J45+k3Fn+w篢ӟ\dž6Wb8VƱJ>7U -DL0kFw ɻhX__rC &|E;SP3zWƒ+9}yމ6$Bg;?! ֒ZK5jX t 0똧«@XJ(p;QY9pjEt|U} ?W(;*wVq_#\~ohាI5UxL{]#5w 0j? l&6ᗓ WK88?}Q3l<]+^[&5?G榡 b(r>DRlEA4/wfd  8gQ@/Hψn53N9zt!l1^"OUxzD1zGM1"5ycd%ԛ@6F8qμ@H@RE<ʕ:qu#Fr\cڿ|՟oίKVw5JZV;Xq ?Ú̦(Ɇ(ءH`(Q1BxdYdF UQ9pJ%Qh#lij]{u"{WIcM 3|~אUd _tbc,`To(r(:iݨ>s6|(w%K#"yc0*Ũw-9_vN Qݳ,tz@7vp:/j8 <;]"ZqlIg򇢃d+qׂܴ6Hf!(w/-J: :qc r8JύF;3fs)#'Z&Jg_r'&9]V ׮NYV{hO^!C:/XBX" Q^KQN(F(89Ej<_qy'X\W-YtݝøR,3;a縖cREQecyHgѓ/WHRX4N&>Խ6unͰ,an&\f{;*|Sf M{5|ײ-_xu7)Dkr;ci<6с+W',t|YsH=lr.Tk=¹o66۾\ݟ}uMdvyvzfANVןA8ۭYL7U, TEOq8>8S1S~ 5nV^hO?<ρY+cw.h^^1dto^o ~f.tjn҇^t'#tsT4.[꽫0w.Ai9_ʙҺW"^mjPkVk%65?GJ{/$q `EnQ-~6uO;ij>yY=/uTuTϫoɞ\ԽU)|{ B;SdDwɂU.䓞+7gOʎy"+e&07t (d !-@`{LX7zesKY R.YBP{Ŧ r~>VY>a#$)%Q%LF5CL﫞ICqsΚ!}8-~n+}txӏlO6UɅǺD~?w`_xW.oCfƸ>6%}thO0_M<[7z!g% !pҙ кx\wrbՆɺ}K2U[^ltMhEc|uaW\];j~Smh!pʍ0˗oqzlaIgHf{};]3K v<ǻe5~3oż7ƳJ#hr_|m_m>M⯸-$MeLɚ{i'{};4N:_rE;bp imq^ІMS7!?cȿא 5C`%2}mDbCs S~qcT@N%a,c9B*`c,7c_&0>韂>xn ->T|#/@T{" 3({ W&&3HF9} xL50lY"x3'Ѳ ۳@fM>Vcqƨzb+6M tN`ӳ-)e߿tiI+<0m ̱G_.hƖkbG:! %67V}fEfֺK&gk9A|ͼّY2^= eVsΤ 8q@if"vI %b8\ݯWIfIm6!6KۄK @.ނNh4%OIޅ E(e${s1R$QJ3#W s¦.j"m&qi o:'C@JLBKA`;$,)VJd^op\7fjV2/Ҧ56fӲͭ'kuuhW^YVcGa`KYq=S[Ny`iy>()kb`|Yt-'϶~dmwm G0^@a Y]벖Oi {E6O VJvʣh-$1M1!a;[y{{vRc΅LVr|8%R&urc$dǴzD:H KNm&ނ,Za 3Sg;e_x$:H"ͼ/D+{Ȓ+.x-qw5W4Weⵛ95yJi 3ٳ'y5I,pk5[ t8?"I (-iΠxUU0w;@֙4 f~u{5=on5AAs':mi~ͦY!@mVDJעYUd F O'TRnsHd2X$pDӕ<͓OCLmiffT0óBzLN-*rz5)=1=+/EeIKE} P&DQ(8(@ܠ!'w'3ȉ:2’uɘ 6m`n+h-_7\fi$6.7XQfx=vGf-ɔ3'ɉq%)iG`|c7o&%{̴A<]Ǽ[4C;,bN6=܀vZoԈHJ{˫CP2B◺0pplB??)+o*qRX7!\_6>n@/azcaˁʼ}ץꛥkR퀿/=ƕ wNp /p`[/ ӸK;e*2{K_#R) .Oxg2ST9[^pp1a` @|d\  T89;f2TF}%ҞBsU>%硫YhɲdUf[Mr +iL*@Xo K $gBY- k%3<ݾך,c:dIut{nn@IsĥoRʎ,tq3.qǕ>!.m`㚻\wC\ӓ&'}-1o͞ MdS/q-kI"gw;mvYY]|CZ8 WI$n,^y>=u]w9)HQGK:Zq&RǟgZ9+z `]0&")ZY_WƑ|"uO$|B8PTLzDRRh:$fFē땹.W"~Ŕ:7W40>TᘯLe6;ZlZ04H|}3$\vwRfDN8qN.RV€ԙiu[8xD֌njZDNw(Fs.ݰ,?)с4q-PO駦&,w{STc/}:oxcY)+O9A\۾ħÎ_M=IMn ujy7!'CHX\fݗJ1\iuQu0U2Hax)rG\ef. 7ٿ-hcR?%r ;Q`i|nwY+̑C!h>C~ύ e "fSDL<֩<+O4ys! ΒbdN>nQOL~%WgO<=dq_@ElG (3eO]>6j#qbv4,$ޑEViܡ6Ғ 92AF6L}إcUr߫lŬ0'nbH=(Q+:yM<+[*',I! JeTJCm%9f.C9s>~$;/s$V ͷ1LHί3 0Bб cdg+-btDޝz{&@4A?ԄXp"ueu>q!Z۫mt͡>dR^}s"<a&Bxaî^"cbG&@&q2RvI"ȸ_P' _ E_1ҍ*c~_T,QR`6]y='|R?P<"=f}َ_K!8@NOdA2SR)޶ŮC0J5kPq^Qɩh>SJƺI.ɐPbX M|c^d"R~C*g,Mn+>؅$Ǯw 9*FVa<2 3G)c|q @yfgbv8gjzi dޘ `˒mɴy\.~l| xsb;% }ٸwAJk&g3,,|%E1&Q4Śt;nJK3#pﳙ+V܀ƚj S6Ҙtn5TLVKnfLq=wm^svEkҴN>93Īo1 l:l}C9b ܛx,Vu@C2H~vXv^gh Æ)|A_d(hhH.X!L)BUr!r'(ٗ,=6m&:06dѱg~F/v@Tw! g%)5?< =>$3OhͰ?z + /Ό!3/̨ǚ'ý[=cbĆbZ0~Qx1!1yeZ q Uvtyҕ }%X`L, 9k  #4 8asb[ ѭf#1Ʊ\i҃bс-g4pÙջx!cJ#8A qԹ`ƶb00qp^-~ZW /v?~7^Qgn?|gt% bA Z!FPH6mHtP ~81i 2%؅(A:F F[qMn>stream ѰWOj`8Ӻ|fQ4A|uP~g4|ZOt–QM,Ƙ5Fa^Hx1G@-1iX@oJ}wc yT# 6 ie[UYzu\U9Ua9 wKr8}ZG H>LԱb,P\.ѭ81ug4+c|5FDg"V(+ī&xeC/B!|7E'\ e@tjMj}c5ρ,jbF%%ňCcxz+~4gn6lq^gΩQv()~IɘXKiRQ/SYt :~]Z!r1n 1'ƪg@tBWL@.qa "C"MB_Qq%!a<`0F㭣a0#B" oDy{F& a؈Wb`F0\@Wb-Ȑ][W$.R֟HkCZ'l,,yoX!-51= 3eU[=3E@u_@CC2A*e"Ʀu|R9nW}K~kQF-ƈ_mJ# co_M ciGtqLq?Fe;A<>$ȶ.+$fR*818tŒ,Dt8t1H}0DrfvfpS'隷$H%:;YrKIھu|d]j9\ǒ z9a!ǮOxkrI SE7#.G*;+RuGuuvB@,! hՆ*fk ̽f`oAr=bWAE| ]Dngqyدr O]܏`Q ZDV7y7WKɠd/X'zg`K'_YX#}! LDF%Ϊ^v?u w,=vر3AÌK#"d Dn*k>L TҪhnI-uM$RI vgOp(shKf-MXPlG5;6,'"5ai5bVRXkXɅ=wwKʘ*P/,#8QYܸ +!aVn7fF3fm8zPEyۙZQ/i;\ \a~P' \P.%t%7Jmwn;ޤY>Q\?$MQ6IzDgcGRmXN_0mV`I* E E eT5 34M8VcUX)Ii?Nr:0逓k, 6x5kB&odQRD)ƌZM-PQ٘X l|QĎ#1hմWcX(wQDs'If)8V[_(j#Dφܑɉfc%bLKHZX[ ȿmu,`Iy9R^Q&MG",a)eT0ҳ=-ָT)RC0$ֆYMS f%%GЃ`by.) $hbemU&",f\D%rQ1KIƼѼFL,+X90Y53is1 sҗ#0b:m.aD46{^ x6geszcSgPЉa"W@S,?E 1͉.kc%lUĖelC)XoʖdÆۂd-(Z*kTWHNNy0,/W_rxE ؠM"Jۦ$;]nV! OD[nt=ʤE#e I\Q d)%qUJĊ<,RqG {S[ؼL%]Եjjh)QYhh`IXE[ FѥR)Sa:-v%:*rtvUUVSasVK.1:hFMtlɎ!~Hs I ^Jcz0m V6 @bB1C;0PѢD!s?ǚNVNawzqudU>!Ư`|~H|,]BC&N27磘[M=6&R:c;]AK@.ȔؾjŦy!AvTKyOWY?o*!+f2e{%D]]ܺӱgc3sR#Hƀ"X!ե ukw0ӳ{6cڳI}<@ jly: E+%rU| H;(reDÌ CaV݈۽9gx{{NZN"֝ßtVz\A(irw''fr+笜gǩ=FhËZ:5@CWpp:3ݡɑGRooĵ+IA kEAv3-kƩB \b$"/$+JV׾G #b)1bZ.#O2E'ڨY!gN/TMB_<- `lH5TP}<|<S̾{8. RH@`x$pwID!>mO|{5˷{FӢ|"ȎL 9 M0U\*@F*AG D3'L<:SsψB9_/:A}(Xk&ʁKd=||wWCyUdsx)])3)N\ *kALf,|+][NWKZુ^qL@ n?D(:l=}|Ƥn iOX%m S{4C**h[-M;!H=wώ[BH>;ޙk v)dώwB;P"P/{(Y\ 85a8kMmŹ͎L $$ >|D-hDT'0c̺/Sj)\c9T>]CPqݛ=8= l1_ 9,O{%L-h: 9`ޱBNϯ)Ԩ(fYrx,c6ߧ݉&X\K*eOr~;e;mKƸvWaE! +oL=X4al`h *Bv;RӮO|%&Kɪ(G4.TvEXf;eʷ#O#J yh*s5IkԕlGIufh#M@"nȵl8FW &_;jUxw8(O.,~எE[!<'$xO.ܿ^q1yd0")k;UFh)iO<۸-)75,=4lhVA8FB&iB5`Q{D38p4BQ,} FvmF; .m3H gPz:&] ]u%k^&t)=r>/]8/=jrZ}@j` )rrJqxtރfS7@fh0u1GLU9e65zvިO AU'Pޭ(-|GYZJ#7ew$־™>hO'&}L; f\K_~AgcOG1YtFK?]EOu*d(E.<2 l6܁IQX,0n3RZ%nشמk>kRX:($!rlW:CL$G`<)"۠JqQ8ֵ]}vBp$v /($1ll2Q)G61@ .E JlۑF%ƕ[6gq>71d ıX^ OFAfBيoEpX3PRb6ۿ`yb&ZvscO$dZ8g 5'Vqb/2imb2 Z6zHA=T&@JB[Cu,!Q k0jJh~FVzx6Hha_yDc%QIT h$̈ϼ [Z=8MDl(OG񵟬^XsI3C>FZ*HeܛW'zȚ WCTФ'-E狈YI q =Q!K낊" ]LWA#5F$jZbg!o(T`flM?݁xO\Vje֫NG uf~vUz>{l0k?_ȔAxǟ4?R'RA}(^ G|ȒE(n!'3:VkZv~p껹{=])X t xP,H$Bˀ Ѡ $APk"@*eODގDE[t>$yԄu8,"3IƘ$oӒɎ]ChtL˜8Za2,+̽S2C9͝: ]E7+GkXK8$*z;zC"N6ڊP/Fp,7Ʒ'<N2R}fƒ9S6XHݭf,(R |g4#sxI3:_?_drÀxj@f_FS;*~7O|gbLvu$3a~5Q}gK3?3c )J1N_OيcC5aVIz~KgPPWIϞ )&=4FLQ>ze`gP6ٹu+|^'}`'h~75B=vK|Ζ";5eyPe˻&r%ti<>܄!jpj w: 4mS%&deGdi('K#Tw]>+c|+i<}K6GS`[H.pIP|lno|,"]+9pi#\ZbHk!afRAq.D*j9 X(J@)ht]ֱ7%.8Ũ ݨ zatT(E'd]>AJ0ubr`bCa26HKtX {XyS >^p)E"._B\n@ X)j}!&=cQޠErUq^Q8Zb8hÙ 6%! z{73;$gn]_~eC-JT$m[Ew];+,}34՟|wFɊqsHn%A'\ȵl#U{R;+QTS@ (%i7 @gȟ#kq+\z? {DNpo1@fNRNT.Hsx "k |m.#|xG3zG I% !ϡW0S17Z-ۦ--IJ{ה fXċ1` baAs8R;p(7j[[;@kAB uRbhvFUfT_*aݩ"IM2.<e1ՁO(y!mpuʸ!oZ;``.gY5)Dkf Τ{ɌםJjR8Jt^zL**vjV6mE"u$}5 J͈}\ ic:UUR&}33ʛq*uәX*#9N M%is 8(<+QƐ0+I!~w\s^"Yup`C@w\B$(HU0Ju°AL Z+k[cxf4/- 7lĥG8ƨdndgLɊo.>ͅWVOSDS祃ϸu*c4+-.΢oMcLo$ C5p[hhtS8ObQ8b8I] 5~gwz?TJd,CH-Qj bIw>NL =USG'UBGp럆rUHP{drlv8&*\)d&.Z:ͦw"+yNRA"7IHgĦZ4>h@%ў"=n-k". XÒ/-S?1QjFU_ԿUYZ u=onTYoOG)kvT&$\$lTxuv<,p(y] 0l71H kM]nktp_8XM +A*~;_:7aF}l T̥8)fcN@S>0wj˚ڱhN + F9v&XVeިa{ԬK/ 1l"n~*b e,({![F*pQ-b&MnqԨِnt[zbӭ4{_O`|x2cf瓍L GQd~u 50#xOͰÄAfc!ME&>5zafhV~c#OuFQ4`%ͺч`7Jo G=DP id@ ņf-Eߕ XEc<0FmDo)z׵*㙅τ6@ q #;24JvLnBGhO9/.*^HKk)s,?BUkU"x(OPCr8\>wB xPۏH`Zv֎<V]@6/; 7C-f{z߇)7tTvA9%!`5a(JH `ȳ͊сD@ V)@^P1}i@Q_ -+ItSqJe^XܠJ}NJ` cާ'RIHyDvVF_m@ڠB qQc22:b= V FxU#KoIz< %B,= :J:2!e8CD6X!x+uǮ"TW-b+0 ZX!  $Bag2s)>y;_6P܌w F8]z\m }'1M x >y $0apw׀&4}+@䁮e{@Q !pKgX 0f>2@ƫ뻕_ީb`qLp1IOR_@G' ٢͉cWc-^x7$ ^{qu!VkFܔhQZ²Lv I0AчrmqDS؈ [wt(vj w5 e-%3aj)5ĨlRARxsDN<@4[mRNFY3#1-)?W Ox^8OdP>( 9|&UNr?07m.͝Kz.C[y1`Ʊ`61enDVUVn'#3m#ClUrrNl #R'Ƨ ^rJp}z,]'p=W9K=|[kћ9'%+Qdadw'u|,`fb˕9pTtHA{Bs~_*| ? : S4@x|p=z"׌/E}b75jf \Ʀ`\4.(Â'Wd$/_*BoDwM(wJ+V-Wf*o?/ ~Sb?s95畳Dj 7Bzh+̙SixbNv9,\ | U,@!k`B2 6(<=j !DFFn0ÄPQ9FcGe.==ҪѿpYœÉ`;"0.]Z+4' Qn_6pvHĺxV90pQ9EEqVgϋrnZӳ# &G^ΚF>B9ֻ\u'zW:kMzG;[|wt7YP-я`F;Ñ@=Bk)"@'xFbT+jQ㻞 WW'PߧSV&J%3ʂܦv=gk\dyN~.E-a@$fIh(1TbNpZI3hH~ܠݨR V$yU j0 _{ᷞog939?^o0m!ꩿ>wjo7"N 0j񖙝XfZT0г *js Kܧ⮔=AO(FSOOIWgp uG^O@υ=djzvK={zUAڥϵVmo^δpδSCv(w ]Ιw=\gsFN5c.&ޟrc["ծF -Ϥ[&㝛-~Z '_ Lm-fUi#^40oi)ǘ~` `Ot@*Q  qcvSk'@'. L*E\Q%㴢:$גKjse5Tc jFٷX\y=cw1hgo|3:k-~Y ,zfR16mkH[ J8Zm|!e}%]f@-#rCX 4ehl^83"> OC9Kq"8}-'o.SF1&=mņѦJKRZa=$ANKTN |>Ѧ:DɪEqpzQ ,stb66#ij`6jL,Xi&7d 5B:t8-dDa&\|Mh4}4g'Ls?` ]`38QyL}nt+C]9_a5`>A26-# Y;44vgO3zsj9M  d ̊NO>ыG:P" hOΠk$YuDBB*^GFo%C@$q^wa- 1-cIifJTR~-hA{eN0N{T&U߹ M5mWWd ♐ʴz]$L;$fƫ@b-# j\!ȓ4!#7v1==Kѹg$ P|:ڣp⠋3fXfӔ9h>ΜVMG '.%nQ˼KQ2ڂo |dSaC3m;8\yG[be~bmp(f͢[׺B,{&{F/WB%Ja%iPI(6;T;oA&C7U~>Vc CD⃻@2-wL'TfCOK]%JDհjazT:m JDU Df$֍ B_lH^XZZpH+q$Ƭ^Z*Yr\{b Q-iת=~J:ԁɰ5;:"un/< x2Bf|G">:fq`p3Sg4=Ĭ"b!XDL!x){$^WܯŞ@4M2-E qةdl?B}dJl.mQĔxF)iB=H⹆X3 6: @cc-AJ?gC$p=s򽆪>F>7YkPGn3=0nFbdh7xɍsxoҞp졶yx>xoS(FQ]0YLc@^.h!5m=æpF:|k Ϛ$XǃDHtoH2W9TV":0D Kd܎:Աʈ8BL#:v_rmˎ;x^>Z X @!/UPf;;Z7:wdXБlp/95iP;27Y^E07 Ĭaޘ,0^:1Ɇi9c*fDq2[j'ICndVʃ뷐K֔M$@757|ìr!ю啭=Ì$?^CtD !OTAzA{|܋ƘlDcePS}1Cq`uC7jZ j@P\*;,%͆JfۑxvLO"Z^a.Ϝ9fcKܷP`1Bݨ-l+RT12>/vjO{ᾬ Č )]a">/Z'8ET%QZ!;z(Y_NK"菟? .Cuжѡ6 .[}}n+ϚJ2E0cErKFRFҸÄg#Kg3"1\QIx@=gՎz;tI'2#!$J &G,F3 oD3+bYi"d]VwEܥ)1o 1Ůb`6zQ^&vˢJKPպ,V%)TJ;&q:\kr>HJ+2fǟ:cӆj Z#X;FbƑM𽘭A0 ZZ)NQuNŠ_ʳ7 慝O8zf^Pr8GJQ/` (`8C u0 かD 6X'|mP ' /lpxAL%݌mFn~n;-C5`btJa#u8[ԷKzr~Vf#8)hqK'2JP&ZP%,[8D͊l>-կ٫dR-aUi N)ŷIxyP9 G CXm|dmGak9ciK_?L|+cf AQ/T]HU1ڨ+['$0b\E=y Ϧ6eʒ9/ SyNrGBnrZEܘ:}OE= qخAz`qJVƩщI7mX`[Bu'г mUݪamjs_ Pd?a3^TK>[yao D!!ZPAÚ |Ngъ`Cu=a{e| kYc{glNi[?J5_I! sՏTw'  ظ{o'=60y_Hv0ȗ㕞ދw :@?*cz'$@1! Ҋww~Qޚ[ӕ9Bi xUa 4ib-l cS|/g _OH KMb#5RB,y#@Fxx_]-uF[QpeCn[*HG*=LN{qJr`ъVkB.imPk5Íw %Jh.f q}xލ!c:,4Q- 3S#ײw>W.)wYY!ERFܳ-@[%AAU+pC@juQp[`HE6;dl A͂ -1Q# d;Z6E>`G|Alk$";gj s&dlli'Gc.)wL0>XOVa?X5}FF7 U<"H&Qܘ3zV`S`=%4ll6Ax*<&8+qU§tϑ)'ŃoקM[_w e[ TA-0gK- '4`{&Fq3L3L؍ toè'xooeh=ޥ<<`:b=0[ZxnV\2?j:AkPN;v/0{y`v08R) z-d O[T_?c&,7,~7:Ȥ}M#~pk|1 .һwz3.­:'vǏ^-bx;v }kq<7^5VAfu^f'z (9xCD*ιrD(lsKpe]|RgǞmep֪ϧ>>>>N݌ q ں%$и {/G8IGV"Ji5"whRUT*;iga!gދtr'ƉHCxTO+/n%',ͳ ;}}IIϝ%:YzW}.?$:?GEjܥ̩sq#`:}WS~WァN=@ow}x/4yp⪧:6|*ɦ@3zq.نϢb-JAqNAD͝!{)͜V\51 |R+Yb&xE.!:V5.9G,gѨԄ o6#[Vf8ļ 2t?zzKT>qP D YVA=Ğ"FXzXN8%(MQErV?'XDk$L4Ů1vhu S=UD9HVChu>0 z:N'Rx`"$^)E 9sWcu#9]k&*M2wg%JF {ّf+ 9~9-'I 73l{ΘU[BbVPOOs \6b@ac-P[-qJV>I3,4 \i"3*G;p4ӕ_QsUjqlrtc^ QUmI>!UZ (ܫw ;@d߆'4!ޭ/ĽLXM!+P !=`E;ʠ7ZOµ$R|ȣ`1wgަOgjЎ#Eu0N,Zf7ʳp|вƲj iIS,'uay]MZ=:J(zxL\jYż^I^fE+'TOVUޙ̢IYdXkJZZs0(^{Ly} 6ߔOޕv ;*?qeuO@q5;*WGJ_'q$Vy}8Vs}κTQ^w|#ԭ{֩MDoߍCl̋ھU>WFw=MKG4::ioVZ5‹*,%-m*ۖ396&0#]j0:۬V5rq96Q*LI$[T (_?&.[޵C)@, 9EʴI[6ೄEBR_N{6b)k?OŒ" yO9|% a vm,(n@<:0`I #o[y rVam6q Zn-ظԢ9M-@N I6V @RB ڒOQd+#^z| H@F5%D.b8h -2Y9ob8ǰ>=KO[`|.rv 1"C!N;—q|X,}o ӭܩlNna{CڑZ3r"~VK u z9?7tI:Jɤyoдt>DP?{`VY *U0 B3@[ 襤B+^0I*S%:<k!SL"IMvO݌鱵#ZZai%a3(w>3&  t^F*!)e$::#7@v0^ހ#D^4hF6Zl4o q9`2>dRofox:rCa0B@R9(!p癚 UmZi}C4|C0MD] wgI':ܛ#{>1 XUeU^:%{ؗ{KgtJVbCLdQ-Wav>`i'&㳑?^k=ä+tuQisF svjvIQJHUbdB2߫Nվ)ԃ^:w`GHBBApK+!<דkyuWtXޤa򆪰Ƀݦb'm=k@Qr2^!b@n)GڬCzDaFR; Th߫qbfo-o"} P_['zq;~ϯ~l9m>MSfzLN5`b!@'~hd304d3 7qߜ/ 4J8yЇqPc j U`;ea6 bn8v}#kXOxp1J;jNu h50 C@jwXJaBRŭ ߅wf3L5\WMwT"x W; -;p_~ftN14*cTwB>m\j繁r,(oP6FҐrFXTpݜS!a;Pz.RM/NNKKdRoLRMWp”4suҟ?>B_$`$#S='{RAǹ{Ah6P_2zE"lMmf<ن9 B")(!CD[JPEQb9:*j5 KtnGSY#MO ŕัD!E-r bZ#VY?9]:m3{tf+N9k{66y%C]g?)c=z%Medwƻf+NIqK^b"?_5.aƃTk)[?CٲktPӏ b QjU#EeF٬â.pOl$z oe[+ǚVf՞U]] ؞vcaׯlW8OQT`Zt{Ԥ:58XLж\8N5%k_007QmziƎ#Jx$zfHR2 uMs ATT؎`g+7.SS"MJTڃm.z}M;Q7,vnj J?j~Q|if :7-hz>0#S(=lHeugPxI<<~%xw@]h@cJ~&YcہP3 B>2FdU?m5OU:C1x"@Inu|U~ks15uSS/kwԗ!pб]7]יʊ*=r!JY$BW6vPS01x~`) iO(yIchB>Ni)X)L ՞: h8? 1\ÌÓ47Œ^'q60w) EHFdըF=FV)[#;cP[a Af@yq[h*"0;\ޖV&$[=Þ{"c*Ks vBf_7/^[ΘH>)B`a 辥>=qy=_yA\=q޳Ǭҥ:L"&3t*B\$VwelA h*~qNC[d?>è6.Ĵ* ,ү+ƿN ke3_}CS~xO;,s;~7F: +:gtzٱFQtO{quqaK]w4&UNs( 6y&#D롶CT"j3 Ɋdj*vx>N_ss9"3&8i_/a-+a 7r.Xm0.(@xF0%wW} Z0|>DZ0V"ތОc YlV 3ܞ(. жj V?Г _"1&c#̈?J[lJdYx#=eMwGs>ŒθQTўR_0|$,˰$$x,'Q/0 # gHjIy" %ޝƾ?x0I&*RR&Xȳ$!, H"z$1Af!!7;FX I"-vtTCbH"  KD&6|cS\\zH#S5&M@:S2d$Sa~>ŒWS÷x_|WNtG]\S8}0<1pWnQ=*{]&q?Y@%nn\>?ފF^V+mۚFPk)-GjT/} g aH uF콛]/gHr?FvPTqj}kJ㒊Aɏf]bWh\e}){{pl /3v NՖr ,2[%ĉsWxb> kQAO%AΜ"hх$a"Ksً/ϝ[t U "ۊMlKNKǯyZPG(ȏN|pjM1|:4]_w4 TjBi>n66k?`d|Utda]>h|Х/ȃ?j/4<'!jjj{3Tn$ le*ؽs$@Q7dT" me4qn| T۱ z"[DphN+hBkb@{s)𦩡hƦ X;)zoR0YЛ1Ɣ1QC.9)}$uFX6ԶوڲӚ)#_E@A#a? gѹzt-:բTMp Z0AUE~!Dկ1oUuTևdQ+mEpDrBJUELhhvf2*j\q?%+q:Cne7XT68ja'*>4$%m"x7\>,qqf 2j"S0fĥDAriN"U`@!X՛d5cFHZ70*]  mP'_ v5xJ @D@iϺSt&^5o4hِ$ʴҐmgw~f9g;Q݇+C U[&퉠#\)k猱s 3=~yƣ@U.B+i{/vm=< xQծ33_z2\䖁3F0RU;.rWq[(]̹ @ii:16]rCV073wV!!zbHqkO:NKX\zEiX"6o_8;!뻱8^a']['$ߕK]ے+Βɭ:"4 eKO Ed;1T ؝!e i҉"{>V$գX`6qʅ=()*Q8֥+k~ʨM;ѓ{yɷ Wv߁>i9W+2Ne9d\Z.n^ij0[Bc00ع 6tq37ra4@̛bi i}xs\wk*c9'/bFJHT||t"v+-lle\ۡk0z XZ\"}V!Bii`求m?LM_\&`]7 -c :v}n|Sk )VW^ױMw芆SwNؗ>3UI1;AN .w/ZrܠzK{ kKВV;t Rz-&S<%kc>9uI*GWj6&$r&Epy {}33JhϳgL0㥞KJxNCX! I\Z#2Fxn,[ϭu3 Tਤ)`*9!S*Djn&8nS;&\1uG;9|.d̜xH,^Q."K,qn:9xȷ3sOe!.2|)ŐrRBjf 髍|}8p9% geA *2wL(mf@+VSql$P$MiU}2U>#JXY;՘1sUO8i^U|"X,%Op~$_ v{yet%|@VҸXh7QJm0ߤUGWPe*Ӛ@ju}}oAVȻu5S֜vOnXXY㼅x(CMi^ϝ[@ "]6)nM?1ewq`R3~`Xƫ U'[q&W\s4Įקf8Np8+q.4;=#=oqL~58Tp jwqoyo*l+x#ZӦ")eS6[ݡ^0np?Z*Ԫ*kuYzECPrPXyq%=D[*^Dϖ߁A3^3>W~ C^mO1q.[\Ϥu7ODϬ DҲCFnn!='\(1/#ѠXeC|!(Ė\0 vjW&Q1>0W]09az$WFzR{>@TG̩E5PÏ" ,>GecFnԄg_[NqR?rIL֫AO 9Rb7>j5g [v#d~]:P[Ɯ3HYZ&f%}{ $0_eG< _O_Q|s+5oQef<W7j7ga5[ǟ:?$Jڼ]` !ыb;cTdwԊNiU\*h=V2GXP_6If`LQ;5dO^O{Ph ḡ(_ uĝ4U yTn쪲L;*i*&We 8DQb<{'Oj/Sg\׹s_i, Y%Q wBA=$yv8 %ZyP;k BD!`<yrfd#<7Eؿ%ɮ ɱ@Lpxc 39.nD\Ltc;nip> c{kׂeO)k鯞ڀnD_w'+Dz-^fbi>Pە!Vp#܃[Y՜a`N =^Md7 <,RlWԎX4ܥNz _%o5>a{r/)) i3'Ou⒇\I^^r:-jI5` #33 F֊7zũ~CxXPN3\ׄ {E9HD~EhJ7_\x낶VwNqgt`Ao)F+7׉^+ d wY7X@͂56ϘҞ;y7!hT;u+W`daV)A| Wc Y>rR3PN W6JjL=WJ6(D_X ?لx٘26[XNp9NЂD٘$cFy\J0wx2xsŻ&=ٺԆm_n?GBټL,`1`E!{M&^ iN`E:Fhnq>(_~WL@$/ů{* '`Q{gC}s?٥laFOuژ t[533nT/\^hjޫ 'Uôv8aHxcQ<-u _ً΋L?yQW3p0>v1F[3_%_N[װwK*GQfFaSR8aPaRo0NP0EйQ8nWQ5c,ct܄t eD؄4&/Q}ܵXKݕ:Y3<#uGhC$D.l"Wj]lGh0*7MEQBJwf./D 6olضE5% ̈́É"3=ɸDɌE#0cu瓯1Y;_&Q^{[r<cc  ` og0F$Ӏa#4iCۛߺq]5Ugoނ\\o%M~BOdѲ@{P(9!A bC1fL6SGa9;${%aFQa׍/0(jQ ":Z<¥{~*%oFЕ9zS`7 6d*zUҫ>I&]2In8GunIri5Φv/&qxKV:?_\I~aw<Cr(~gq'ރ(@& Aq&%ٮY%|'Y%1"Y ?>ڥM9sN/ KI .@$HJ~L:ї9 HLf8d gR3S71!lFY@ψ lBYތ=ћo2h'dFmP0k-ޅ> WlI*܂T3Mh2L0]sՕ 8zKd1_xYKZt䉯}RajL}lQH< a~tד8\TtwssO%G ծ]>c<{캰 fisfz>qq%'3A%Exd fN3g h9@=n#84ja"y9e%\ m,:g`R0@<*VpVb4_inݙ~!WށFpATvs@ü8ci@s5_ߩRbkVNNhIpFXM H"VӌpשO-!"#`y8"(9@V۠VpWӶun YGGplr6;M)p|7͉kPUHNs@l9El9s9%?8NPzdES,\VGbNjcCƢr2>{8@.{צhz޵) yaFm g(ܱS݉kSi&4$vm X8/@|O/ňwUqC/ł6U.RܥNV Y)h淸)+9)ocx-Y O|F^lv/?ﴵ␷v?lg-uG${qTrQt$luJ/!_^@[Ybܷ(hJRV' >udEf7œ`7sVUFmca@+SSVZ%cHD}C8(c*:vVTH)r,*TF b ߙHEtP'AtJj9b88H5?Iy/}K}NEדձlq][ WkD]b^G)^QJ+᪴N|xOe~5hr'O`TÒ~"h޻K @&jC?O,y3seI$ TY>,]Ã),&(G2lt 4_Z$1 |6;/KcI0nEA~,eS%qźhbk9{9vmkzpK>8^jׯsS'ʼn`ur9Zcpﺲ^k_ |:՘>{?]Ƿ_aT*guG\Hv@nN;&Z."6m/GѶ =`8:w] ù8dۜCh4 LV+#TIϮzO`<\ҥZ]@S KKxk|L)1;輕\9ȵNv3vWO"r٫]G_ߥ}J;^nn=X۳}}ܻnNit d}yoϮnu5^Xu ~|zx((>̀| ~@tzT 4Cӟ$]/YR"t- t[ZMXnc8Y -?',^sf\.yFs*/2}zUkO@:^䗩+8gw?| ,{ыfFz?z8[MM_nބD ͹l/ xGfGbw-YN;s~pylp""{]scG:2#U~)Ѹx^sK*)gu?\5W&wp>x݅vU~3HR+]uŋkt{1Mq*'IŬ J KQ:?}T̏O7 XgI6H%%hВH ސ&j-㘱 KEgVNF :o۶:ke+64so& %BIDO.ySK.w8<t w]|7\W|_#ׯ V/i__̓N%z xk:|5Sޏ^ƷZ1xB8? G~~18/βO:N\cs%wA5ƒu̲IyL]euL:K꯳[Q$zv=ZzY%!hm_QCgk tUPl`=FZbY| K pdkWAQ?XVw?j_1G&yBBNY ]&my]j`JkӘ =ߗM]|4 #5{q!Slxpwq{4$:lrFԻt7=XוUX ҝps3~NoӮz ^ gTQ;RMϡcPL`!^ս:ktAX|Pd];)D FNA)@@x!Uҷi‡ki 6FBc|4uO8n,Bౌ%Lh)g,e+d<;cg=_-Ly^3|uӽQ mB<涒tA:Uz,''DLaϒv4jcZĘƋ]R>f97fɻ0 0 `-N/j׫d;#o"S>sNBH0 A_~'(#cK@ȱlj[9пjָExlp]kOqs|7g{9%Zu6fE2+ :|¯~Uw_-誙E|| &nDAR;Mаޔ(!;2KNc\9Qt RI,9]L2R )ȮI?=9n40Y|_%l)e-k yIX:?'~Vx} ;/`^$L~Yyݐ0Юt) O35BQVD{ۓ:w~9ݵܵk"/vv4&K%UɌm=Nnڶ*J緙YZhL$U}s6+=O$ s,> >Y蘺St Nם!qzSPL:Pݷ[iޫNt Ht9zS3e&/QשtKjQsQ,>k~l/s9.re8~rW~5vዸï'b8 $lw]9d@@=TޝN9AĚ`n2H$J8GRӲȋ$%i}s540DGA$* ɢP"x:uY$}}J*&"sp$}AK*@5 TIg2\o5Riʥ,*_;;u!*Ǽ: U$u +|'NF񅀷6?OIU\&rp9 !)b Hp5 A1I0 uԕH8,6:Vz^:VM]ݏǥ&o j./j'AsXMXY&`fOV!X?Y&̼;ULS-#J˽\yKZ"‹]zO.wޮ>*dL$xn ѾX.-BwM5vmUk&ƵS7\勀% W~5Nɿ=,z~K#r5fgj;gri:QH˹Oh0}5>LSޛ.zƻ^]5ZUV )\R PНR `~-PqqޝzJhB;Ƭ۳BX]MZf ѲCbHe=Kg|賝@Pgqfe鳌d1g9gk#bLSڃZXѬ55R03_.g\~}fko 4퉸3Mk@-aHiݛhǕrvM*M hՐ)Qer(=+3z&n?g!-b>y+53TJFquJ^c.GR"3hؔ\6$ %25^Q@r_̗zW~5^-;rŕ|Ӛnd/ZӚ.Em_dxv{Д1<;k^y귙3]rLEE3s3J~ o0GL_خnȉ܅9L&䚣7P<ٿO;4X@]dҳPəTtsoem_e!>:C3mNS',;/Ks?VTn]DAWcs(B$V%D."LrŠܶK_tm$Q˱׬WD PZJ'/{ J+JnpMCY막1'f8L部7ç[ܢNhA{f}8s}[wY<̓y+Vӳ?ʫԮpoM?88A!gH,z -d_Qx夷Od:Z g2W_򕝐HDanfwo7/ƣ|xCT- sM22ijXIc\B_=<K@2^ѫoIQ%m `5WN0:쨾,^Rw*>%\Gd!$W:5T9waq 4Kr`:LbhX!j޴ӨRwZ:nO\}!//0s+SsfGD.HG[,BrNH I8rpѢ$N@]4By4>(WBy|N@>-:$!A ]ͳGd_ourV5JkNUkC_fr.Rss .̋ג*P'Di( (q0&Z;YJjo;fU%:8ױ*Ƌ!DTEwnY}ɥ-fvuZ92uٿlyAmo_G 5 t׿P4̎udd'E֕ONL KSR~錑uf}Y!l#W:eW!=jK;Y,2{*A muUNy^WS`ċkG6A RK /(]g$B㦐vlfI^ ٻHu"p=hd12  zjpo0ցL k8=n @ȆE4 YwtrX6Ӕ 4#N `_{O0 |=OgctbވDn|*ҾF 2\Vp[֣ X_Ⲕ`DK~9*ad(rR;Xt }>_m.4Vw)T-zm!}OP5GAOJr(5{Nhv8H5+KםKÁ!k0%[_n]d%򫷭t.D<s>Ɓ &\䇨^953@ ((ۡthĬ30\`r@T-<t X@LT 2ɻ7taŌ ψtq %q0qސbMpp ߟմdO_]^_o=ݑٱgwTlȈmdOm4mFi,\|.El_}$hbLv?3JRd~^w׽owW;Hc6Coz55ܗѭ]jS Ŀ 5ivV&~Bsx}6Zë=rl,Y崿0,DgH~-dWU};/OdOHm$.T_!@*Qʶy-6P㓰=(%w~-v7˧9T[U/7u_otp ,aUrb5ujw:}bH1|}mw^>6]K}o~l[V;}.}[uߪ@'뭎* bK_vݹYR0P';+mv&Vo$XP|%1'_zѕh%k`]207]u>we#k.tJw9VyVyV?=櫜 jdTއ ʺw ,e$O|q!4d/n&qGyi/ۛP@j&:R}Gj5ߕ;po|^V)ޗӗRGd R{'GɊ:5*! rP@Bh#(1F1{!{I>瓭B:+c纄F`O{ n9/Ty Y KF)aD^qJi u<*>5^VJi\emĝpgyC[k^x_m\ kq<)7k#>&6m:d]v($KƞQQ5: [:4wo,90mxxדw1I߳(=բnJ[hȑ\WbMSv#D!2WiN+sHi6H:acW$Dc &.wc#εNN(fEkx@%Rəd$ 9E܉ &) J3Kɕ8d,dw+}|\:ͺEj_.^o[ϾNAѿ+Yg[=u:oZٞʼnuVڜJ>Zg5~YkN 35f}mܛu<E{IY_sLJ Z;"׵"뉒!Ea1ˈxxGN 92e6 a&1xfFŨM5S A <9~R|^e{%{lyr_ @ |זxxqy]SLxjԲN ),q,,%у xA@1OxQws(VA<Q0 ŗLǝ UwT>'|~貛Fb@; x-ųV |sbFmv_b"YE$F]IJin}<YEve[V(uA{@i Z9Wzhh 5’Mڍ60RDnYWc}ڏ®Z(^.1}` R::ƈtY_ d$5@wݧ;1޴oT89=xitYKVZkL) 7|rO\ss%PE@T/ @2N}fIW~Vˤ2Q WZ Hgj?VZ/)ėW͔}QT}wqrs0!siլLm.d+\ky4EP 3JFKA >j4&߸s64FK9GgǯtI/f..x-QŐnwq)ϮZϼtN#]Φ]$O~m%SdTL02ngd܊+Wh{^sWM2^_O! 4Z|n\ȈRNߺ~>q ywOs"ps;{gi.&'v[d|o}e"C58k]?O;d˟2̋K (;!o72w9;Yq}y}ޜj-ZB%5П3ѷ\¢ew%l}^!7P(4,cz|$I7]S(gyrZkJ_U=R;r`U8ri<4_#7;JÔE6X;>! %a*-O)I%0`AﲡA]AhNx?9U] I~G #voN;Jr<'LJc1.6>ufLf[񬾔S [D<,ϞR4$6 ᳛'lzK9\7GpIT925)[X =v}/irDO(,+ Z Ǻo0 ?F(˵$!~qBey< Z %tw-G4|,u4{F NsHYLښnr b Y^ 5h2 3`7TBxGLF.!*ԅ\aܼ Єm^ rpK >e@ K QA=.b 4&ZjDw,M:r{Fh[B.KtȊ]c&Rr,XgOW1%5+؂A`Y9U/ZhhRj"M~8 ,mWQi '3$ǏE¡89 {1mgP4L4 1;y2jP49ersMDzL% ؄?P[0͡~j&\{7yB8{zB_&.CpXK`^W8 hfJ)y}*^K됒dLxSJQa}Jӥ(iZ~[0Őվ3u = ɉǔ}bbXՇ NZ9H'ynw} \KS-zjl5ibLE(:r0tIpsOL>#jwF$/:0RWOdU.ꃩlEKXRO=Dk-NZ҅?LS$AL]zI+5QA+E' J_;' %QB 8ǁ_ Ѯ_ǭkJ#:dБXXFdzSGHoґtt Fk#߫5N2|ə_o]K"8nUYbCi4KG?po!ܬ޸Fp9ۏB/LÇn䈔("bܨdEp[#圪t-G_c⾲0 ey,kTʼnmH{^3(Zm4j+\WʙI'wIpX|z*|.Zվ3?wDt 7o8po8pzQ"U|ba\Z7U(iَo7A M&}R7A MWôߪ 6 X-O??;/_|_-o?cd~$MJokm{YPnr~ooe/(_0i^{Ue*7~{j(܆fMpWuۺo lk"4$xZOX%*#o|$0Y+~X8oӶ?{ }|>"Yk+ۿ?6[WB4Ulڻ*J%?GŶݷUJ_IePnxpYsi?|%wMkmgmEWmM\o>ҿuh\R8c¡m*;5ԥF C7dغ2j>C-u(uƖ>~ݮ/m=~6MW4ܺD-4YyKhH$*ec˭O5GSWmPc!u.+>'*N_~yΫw@VTW6}ZQTIY7+B}UTia^Q>D{&JVT7'idMuecۭWFu%<_ͯKE;eZn}rT{4=}o7?!oZ{Է3ק/)uТ x}>Ml-JYק֒.nz3cpz^J1>lMO^^ק uD3ӱmPI[ٸO3wGU73e\T-[%Vm *.\dŦhF-ݞ#wi'e>-{fpC'8 YQ,Wv S;lm sz0M<4љܣ#y~e|]QWOskC 8ezKBa-a~t+t3~b^a }1]yeO범N|73{ LYΣm#n}[1}A3]\^̄3HkyӾ2yyzyӮ~b23“3S;Ew>A8젳6E5WwR==_Ν}.?_n 4Q\VA 6nhkUF 5?B]PU|? bJl^7T+=85QmYl$flbcW[GFXc۬ G+HBEs'"P)b(t}`KXeCK 2&ŕ(6+OoڗXH u,%܆u+ZJcԕPڅQT}V\E_-Cl$1eR M}"V"X+nXWjSjEQday"^obYm^c]G euZQo W?m^.6%D%(1St^l{]?LƾoGݺ٪ zz\*'ӝ%kֱߔ:\>nݏzoSuS(Rzg%2j3{A{\RWgVVWvD/񴡂gy 9cVyue=ýnRgȈ$X)r.lCCi %UQn$;!WSq_sK=Jq mNֺԇp[ѵlE+Zj BtƝun{zgX]*OaD; ҍvROttnCRw6Zgj[Kܥ[aBKFX镂v\[\iS(c"&u1[-^y!az>宺hsݞ(-Z=Vqj!`8 UJXLn^_q_mOT.C0걾QTTOoQv#YIJ/ug+ ֩Dj De_ud (UŪ9\%6vkBf}_jtm5fI+G]{"á/9`D!*\ˍLj#Ɉ,e4=cfs=_7 Z6{sebtXT_Ӳ1/u EwMOhX'-q`m8jCqE 7pIvTJF*TrV^D l2%`zk=Snu %kD/KRn%juXY:Ԭ3 25)98̝Ku,=mEeycƉ_kَ^ 4%PW:H⊬=FϦLo/+-^]%pumG}t !Tbv4>=8V]Y/ZL =L݃.z\ۋ!dxViPjT9Jp7F㋡R1h-ںC`%X7Z 07^cw{bfΦ*+{QŢEzHtbDl;|=[K^iu;JyغXHT%n@9\BjϴnԦ#6QZ3Ya76Ur@d9"@Yl׽@<ИpȪ:걲%>,!AwCmR K;@YPɨ-ʬڇ:8ZJ~ MГğ:ɯmL*O?^tF=ā{+xUVI6)0jP&8lЯn\ida!Wq,nNVWmEܑf8FZAUWLJbriv5knl#6)f2]eRDQ *-+0 rJzk xg8AZ@rvӑ0Pk /4&/)8}8G=%`z/B[-t,aU$ƶ06Nr"0 E`J̝>vrq| b@9Q,SΌ;+Pڎ !3߰?'Lj?2i3$A,L1m*L d b#%#6ZRb#*(y7ymLkTnEҦ> 9ᄀP6u]M$ߏBIUra*B:Y hş.*A7X'3Pe"sUJ Fl@)mzH r>-2VT+_-?@<<*[tO * *KAqMTŜ9XRgOP^$ٸ3Ԉ9K:XÇ!C f0OY0褜u o)@|el `_b#ۜF;qtpj6٢2v{x‘ gi[)bBí)E*?hS7s^=]ً*dZ Yn6 i@`Pj|D,Q~z k v*ڔ9gQ\YFP9T6»u wɰ] 3 װBE\ 8V}<.(Y{Od2]+?(/'gd 9#x#pJ<#{Gmf$!=O#tSV$=;%CTYJ޶[2|L=s&\&(gu3Mx6h`Xh:];zn{&*k4K-3ɠNQgi;YN'u)0q .Qg"h{XT}}t褙;[{6QQ-21~PmL-"t:Tu^! FQA#P<H"+ŗZL-p\ 9&r6(*UN5'N^7y|{8fB0Ov$N=@#n-:3p,E !SӱCX)!K іfQ];MBa2)AV#J1E 4a\BX/Z3F ŴzkƤ 80G .zEأBMb#,%t 0+/G{DnbXc eEΤ}USS m]7(AY!k `)-ɌiySY%M|X B:`ȭ~h]am {NQ܃"SW[Ǖ9#Br]qp YJo $QdnU{yj.(B= W+u%f [䅃kOq.i5vZ0$.K gq!gj3ޱljyZ3Սnq _7wOqP Me>\47#>;Hz=@?ޙB)4p3}е9ܓқQ_WΪz%:9AÚ$Gc; n@m*'HX"p6=wh7aj{b]Zi<ͫs8!cy-i B=K͂r HgNu7s\7+o!`'dCQ.d_Y:rtbS6^8\SWNtv*!3v+D<"g=r}.}Cn:VVcQaٵ0y e2FM rU .&9F Ξn.B6?]%UIԣ9.ùª}kwyl QlWIZ;Z2p΁{r[ 2)كkp$~۵^a7w'܍#r z:CйB5DyqvqPL6͊R+pPnG] ͂i-s͚sP%2-f޼UB\y9Q_%9X j=+!kU- tf3g-qk16gJ@!7oG碊q@]MF4RZj-a*HAzm9P5 7B[NE[Np~>6R夆4'rBNN[NTw<.\YW[Np `ʴ-'Cr6B9DɃPI($,r>B*LpՄi  [Mx>V(ɞe2(a)$SHapd$"i|%PJ/`adE4 FxHႝOzZAfIJ@-JH'Hmou?_"5)Eme!oz?٣M pD( ~7$Lvh`^+k40O$#@(M"'7aA}ԀZ | óA'AKI!ifəޛm%^kR9i,1^yQl PlFC f*+x)kp¸XLON;!:M<ڼĶ[V|. 7#qQ;?`hϔeI"(濈i˖ҿ0 4kþp,e`5,,^b\0Ʉ)0hXVys *{~ ;* ;U}I/#B*iUcÔh7|N)XAuo |T "sT=-)X&P! [K暖T.m9҂(0h #Z$o/ !|6Xa@ jTH5%] v>&ԭ`_*F0kkWth25+ѦZW(80HVwaOhF)+AJV_w sAV5HmoM K Q]ZĎ}B`Y079s)̅&-;3a"i@#Akes,Q^jp@P2KE,Jڵ/`P6u`v7``%K-PsKڗ"y(v"Q녠d ҥWa%qu$ƝX- )Fuf~ǃ=T{y}Z=Y8,ĦG:1Z)M)WAN6|G(Tq W a7FvX7q:;?tidJw kaB( d1Írw>I `wj"2m?i:WlGrSvE|aT* h7hg8@%[;2qywSpaKl,a*5ٝr3ZARZ9Տ+ ]$Z?kCb eCh)d' vf DqY0E`J(XZ \ {iLE?kS`E{`(R ʜCcM%B ٦ăn0nQhErP̢VCGt8ȀrЖ_bC݂r73#frPߥfr"3?.F%mJYZ=BC Ɵ"Qk4ͨ9vp6ReHe oh 1@o7/aU4`hA_(d.V&㽖 E5' LNۄ=%.`2~h=ݏ =d̍B/p_Zq` ۋE&%i0M-dW&UD5" ^[@X;zNc68E i, |ؚm OP0:.l°R( 'j\v+b.\k/~]@8O/3ZgHpwIS/H{B z7ט-mI #*'p \2( 8lƚF!_BFvm%zjS\#s\s>.Հ+Sn4,&H?@dL ڪE,}(rg/s52E2X$@վylA)733d%+ m78/)tq d5l'@BP, $yPNj#ߝU.#0E'ijH#b˔*7i ;Ev@6KE ghbc48@ݔՈ=&|ڬa@V̛O, 0sd1K|E f5@!1yu=!2ȋra"<1ɥ|E5ДCN@^3 #?Pʉo醉9LK0у[>Xΐ 'x (>+SmtnQKXuHs 9须]YGj Gt"#&b7DzgЌ"K %D<D7gf$Ly ʹ{--(ߺ13|{T4xN˓Y%tѡY*{R.5dBrCXkJš1AKӢs0`t C *j-8+/9D"mN@PZ PڡE 4>J|_93QI_덻x++vk<8bv4Յ!,g>k?-ĐjՙAnv.űfVcbrJڅE?d*X"XlzΕQJ` [唀r!P8I"j2E+mmn]dz,8"%ZeQ.U11)N#B7C^¾FGcVw/TܫS |^hRĭ*Xjid 6s\ԑkukGMG|PΔic@C SZHuz*e4)+soZ5yh+CrSkIDE`Cy,K[$g1Z(Z+Uv[NUv)#m$=%l};oG·cǹFE -ǻ2%\+(̺'];@ 1T V޷[;+zK_06ФJ5>KoE] ;GxS-][j(ՂkKS!I[ T']! b;FK]J^4T!-mhi-iwM}%ۤ?f_vgBV: 32*&P+Mq$-]BbI}hi-iwM}%iӧ#ZaD\}N%}H VIZJ}K)tcJ1 ?VXąmjCKoIn+&-Qöwk%H δ#r%}H X%޷ћPIIYer^&d!kۄv$n7!0vS*}KkJ%n;4im: _Lr]q>n+Z҇P Y%ah)-qwWNZw^4pE] YA}B>lԷi!-B -ߒvGoچJIK *EL;.h/חҋ)g:YDw۩={J7qehO 9v6VM>LUw ZmqØu%r-8V9.c(q[qVQC_%<W^D+q,9f톻\Yߪ=jŬlSahUg7Ʊ:nS6O]!,i/7%^@zlSwS_ڷq`dZtܺ70il8 e$))Tȍ|Ze"utdx* };c][aVs_[$%(QZY!z~ϕڣVUNUݸ*A WuǠr8:05:=aFm皺A+%m*-EޖO5IMOEBVʝNQA[Irjw&An;ԵhZ)wUu-}Ԕ&-ޏDi"uqVH dCm)-ڃVʝnU[mTS0ՍR0ah-} euk c=Z-YgN(<xd]B7Ht 9{NKɡURמzIs%cpPWHr0aJo*qߣH *9גuG ]wqL5kؼXJY+=(|)*Xm+9."MXEyl/wimCEeҞ pn_Jzj@RNCwxuBTQמ=mc{wKos߄eҞlnEyXRqh_5Gy[T޷hZA򅋜REGgᰎƚʤEųX*4FOFmr[+}{\$#q( q@ ^okJE_TBu\/d{9Te}9T&v\b\oBc"aЭ5[&U3خZgEzi 6ߞu6T4S-V6/h8V)[ؘe"u3R֔-RI-eb;Ö"&Eud )D9vly*o+!.UԺ72iWP(+`, kMu?Cn*C%oj*ICKon+9,2+(dR)Is'7ԷOY!-xӪن-tܖQ˗2 ezwW8k;L={K\* c{ºn*Z'Ow8P_Hp4::5UMe4z#7ԷOY!1VͺmZI[Q(Kl٭^`J,=TUv@v7-Co!ܸ©5jױq~fd+%UmɳVƊJߞ=$nԵr __;;/j)zfgo9\Wߨ=jfS*+Ƒ:*P+%Um6Zհn*Z9+%VQ:--kCwNK7?&䟐; * %}H ٛH*9ï1펻䘴$Jo^n,'cIX`HAJbߒ>ąYB<;mtW&-kOՓ|b&@`%Jbߒ>3CKoI74iWr(I]!utϽt&J}땤6TMT:jCK^aћPI$%RJb~ VZ"_PV>6G܊A6wP#Id`uHDPI[҇PC8i7IKq]!L\)mx`t;d;Mc%gRuhi[H-tN6Fx#{ k^|׽oKBŽhլC[k:$7屖ݖ̿zҺf;p4з  h Z]sFY&lu.セWqֽI W23ʄo{ڮiaqŴ.>}$`WnDiUd8# kUɳ|LBiBvrN0~?d2'Rn]S}Pgw. nPsiWXub}{]sE2~ԓK2 iA H+X!i-Qb $~w0ݠҍ 2{ $p_eL>+]kB_s.\uҺf'eSEL _0]E kݰX&&`8!<3&7-=Kb ̊ɧɕ2Yt[}V53)e-}u{JwQ]|4$JR'gꂱd0W~X6Rm3:FXoCە2?a.,_T7? äDY?alۧ љj6{ϖE2Y\)bVHFʇ2ҳ!LY\/o˟A0q'Df{ψXl#۞4WQkB_s.\',_(.ofR[/ H2]/wR>LR0?*j>tY}4MW^\vҿ /ٟ\)ŎiB|fln\"[brLڱ #ۓ좂zS@J1o]pҕ_L7? W 2|>MhΌ-=oRL7(j>kJ-7\ړ<Ө׽kˌ-g['|_&oFֹtٳYRlԫEN\:Ms-*Atq՘nj\?!A}&[[8X_r?}5, ("eU ?6w&enLeuvFk_֟2=tkiǸ>_CwrtкM'$t GD"ÄY{R/3%^eI𧓩w;cezN n>L>:9􈡟~4MF CW8Y>Я&|b2%e&W^`cODP:CjH=k:JQHא|zCq7'vκS:U-ZgQ:s7 W^{xؑn:)ivtRMA8B?!2#ZzðG?^hQ5FJ7m >gl!=:[T+j~6Y}?ҵoePi˓AG>#}ܤ"(y"9^.G^K"0˅a"3==avnJ%Qi]}!tΦ]0#3ώc3Ӷv4ʂʷۈR |>C]o_^7'ӹXC):UR5]wϴeSZ)e] ?}eL|q6 R·np?C'ۜ3ežE=4Lr X {ɜYrM|PfN&;(=Opkzz #]'}lJ VOw]Ja|I~Jź+/EdggL (qYRN۵2@qGݬM[C^I@XY@J!ZU|MU׻)7qc|C&ٶkц,] pw,)v—8Oq::z{ܿ91}ƭ1sŪ;4ӧh_ˠ:FKn/ tҽ }hͱ.nOlgkMB]i)WM{ NItn~obکMbgOQNiJ; q:ӗ4?_EmO¦_ W7}[bSIj=5}KcMq2D$P^{+lJ8HO[nJ*I  F}&1X5gW^ Xgmv}ueAd;xJc+zɇSbΪ1ʱґ A|UɅw9v봧Tgvon9;ю[W oGgbOO4pŠk)^C3T|fO}1hQ|zQskC#?4Pk~?r.uº]P6xMj Dg'5.(=f~h9oK+j|^[Axq>IwټV4ߴkeht|UI*o~OǏ3@uK;]ڟRq6_*e`ݟB<9݈γ2XF`|+Moq)qB"=::{ bGh"⡯$uxYo{{SJkrwHNgiiiiw|$|C]OXO뗰 %v>rGb>KOKOKNKNKBv;#.<-<-8-8-Anףn'}$֣~?/$w}4=Nr/UOqۧNNrDNr}(InƟO+OKr{cO_(In>In_~Z~ZvZvZ'ϯ$o%%|BNrDNrG}GIzO.wǼ?Ru}׎߫\{q8}ugԚ6G`Bvm}֫ZC$0j';'W6۾&G58Nvʣ?[z4XOO6ghi0'ؐ1#xܶ%cxBoGc?!ȧSc@|40i6ңvtm,}x4z8 _:vah?6^NCcv: ?~soG4|ih:/nKOÏia<ӀǮ|ZrZ#1+y>.[9Бv 暈E:i>6piivZOdpFGb;.<`}"EO˧=~^;~z e4󙥞|v"*N_OIâRQ!=8Mb7βݙ /R/ +EEģyȫ\dF8%T&ۗe*!O׏goiTGO؏slDIe{, ^+գU%5pzyk#wU%mmCq˿,6{ }gK~pF 嫦=9T[3[ +_9okK"7V)\Ś>yUvRI{6zv_wU j*e {褞o[@֔,RyFl=Eʳ|:ɟgGgGG(1ȷ=/aly2gln/XC3mkؾ"W/ 甔&HSnxϞ-W]}"˯Ϟ޴A:*ztZv ?ЉL3a]N M'w\M9X[v,!=6. pq[xmG4G vgw| UÎ)X"S7 `aweu":a \>>?5}x ]<.{m{,v͑1Mǹ?SlIF=]f6g#l=cls8_v%uZs pJոnư 86c=EMξ[j\'ф\ H<]d90Sz \Iw?Dw병kG-]#ggoCbux#5I~R OXm*}w(7姰h|4jZ7I]|4SgGWO Z:~n^h~R3γpptFoۑ+UNR]-bPlTg#Z"ܿp㣋DoվpCm,壚l4Ѧ~Fή|;xPو}ݬO)h|?\g[G} _-3C.m ~)olOYlC,>\gGo}()/5ZDpKI55? fܥYr¯V>y~;'<&w 3H߅)ETM0S9oO _+l 0zۡ)e¿j?Aל/ta˟7COy|Sş+. t \?vgL_OyT. x}o_3a|3`}Opmo=)$|8?+W!???]og?3?/O·?OE,-\fHR5WnW:>W˸w+Ekr~(Sb6J)(%H9yƣL3o>\9l9q{Z =6qE:yrb,9i8;vu{Tõ'{SWBG+m endstream endobj 229 0 obj <>stream o51Ы1QI+'hԱ}th틕;y'$@6d|ؚBO=![Biⶋ b).b~>)t]a~ڽ6]$R3b 1%chɞ2mߎ=xUߥs^̚*_fSFr9JtͧaX.uf޵Bڵd:]dka}'q1;v$_Z:n7w5ǽ&LEiVwYk-`"pm^'q~[t@~h&k\{dW`@ bq_>Ep^XxM 97ۄBԂB,:1bbMlOlY}_0B%V۩gky/ 8@p"NRz X"Ո N;Ҟi;Rk>umO۱Pl7YcuƩFX-s:"DiXi:!:&xdp,rżdpcSE%qEp aHD0EaCmz5.X4e Jlixɘ鯅IosҨBﳋ$S;>ߐJ>C;q4BE|_c2~ &UNB&<#W{ȠFe>Kы"h  A?&8:>[ߎ}KrKCl=uW;.u yIH.èC#DH!hIHUcrڽFv(vg;,4ȃ݋0 :8D@kr/y٨rΫ,v .zXNvS!۫y3J擑K^a$vfr4 ڮk{4Kx"!MqF̙w./K%mȋ*]J/a. ]m V% \ g4#j"D}pf?/ M~9LR֘6d>.UYTW˴nLL2U>ptU |1{н_ g8&jMd5"EhM^u䀑%#3b&Ķ+Z\ P %V)a-r> mc|L|kHzz=Gz5܊wr} lɡm͂cv^i%UGm $[(Z9ςD%:c[YF.lIb6@)٧"]עr4Ѩ.f/5Z ZfnUKvvhNoF՗H[A$IZچ|QP^C,bN Y6#Ν"a9{{56B 8U(l"Z)ri!HJ)f&ȩ{o+vUw#$u"*!vas/eT@bH ;Sv\3@jH Sԍ⒈ZƓ| -Wӈ]aN+I5&30ƑRBZ r9Ќ'nlY%N*'6a4%KN5?kZ\NWgRLEl#sb4IB !OAiw$RI:W0HֵjxUPDф+>)\; 5y_bL~чӒbRRG`;_rQw})-4%qۺDy,J"U9(BmZݬB+GuS ==!yny,+\\Ѯ Dmx\DQ|jơ\ Xߩזfe8D\IUa+ިy#5ʤ1>*y$K笑Aց` .)`s"AyF=L!DDt-M 8Cê^Ҳmm C[iVXZ0{ETzd Rr6k #Y;[Z+tЗ8D75F{s|SψfRhr;5%Y۝)MDDN& m,QMW.BF{FdFZr%cb-ô ]q40ye["؏E E z/b_&y dZ"6e\6t.et1(QΙ6mRf" I#I8p#Q \_8 q\ +Ƶ4^jge,kL\P5e}WCk)znu]ͲocR0)j%2fvWii/ 8g Ȳ!^I/}`b2x;"}>T]xkI˿\ v3j\'TLU.wԶ8\ -״6q0 KGi(҆7:Q|0+n9h,eQrO U㉠zLjPԘמšGlQBߕ/FWՇzBݠԵᨉƢqQ"*-`C :`:(q%c-bM[{1C ΙlmpyUfDMh'Gf1 &q5j>Fɹظyl]DX|GEe&R5ۉ X֎R"BV+^ڂXWDE Ϭ 'mZrP!gG)jߖF·WzNU2Tvb7 ~'U ]R#8 =GX}tWȭRݡ&ﱎgxSb=鄞;9e|65/WE'aI;@Cl\QKBu4ʹuXs|Ft[s{%D5AQt:+9h %k$Q WЈP`)fN87B^&,~n-鿈-Iܚ -k+[tSI"eL~h'_D:"vcbU9ab9 ?GGV07[Rm ʇ0+a]G{vD'ra!4 @⚆ 3"} l WQGFح fFi_\f'8Z!X&jP STLjKeaҦ}LKORTnh渘d)HKkBVF~yqA`uӱ9}T? +BLe1G{])Ћ /d+Bju2"X.1=qR6KG E=&68݀kЙ$ԩUʶ"@Hwr褩]yn 6D CͶt OA+άƤ{i~TZkc".qA@ACO`C0%vI D?VCPe !uY@-Y;2 ?(t>%!>[-&D*Uv08$w&3#=3(Α/u| HJ|,Z6n"1:Bp$00}b+b  =zDa_0Za&Ҹ@g)t~e>?¨2=~)\}?9e40XHW6{5̜S d>=ˈe-t Q?D]bKnz`D6 ۳Q\ݽҞ$ֈ\DK|lBjw\HVŖ(a f@mԈTFWIXb(灡];V TX߅H\1vȜ.s e-+9,W6Ur *ϔ}o!㭣BnGAǪs4nShcb(SA㣨]&0@[u@musf]$l+}r&j&w$J aI. Øp- 29CSՓlt\ 9gdB60"BQGr F; 8 efK=sԊaXޚȈ m F &m }4 E=pJȀo7'P7hDckc&3]mWΡg U׺AóI C1;<“8#V )#vognxC.zb:U w&pSA*>6bE'[儚IE&pv@ +ű 9vAwaq\cxw@hMͳUƁ]. P 9-MPbaX-8 ۽,'Er{҈S/Lh[ZAòDwzhA6sL2)q.v/anon0;G RJI׈Y?ǜ\aMk05`k?7 D L{|e%.nj}͋AM)~hn.e?'J ΅uvcH(i#>?x_MAO3 |tWb"qr=Ψ[F7Kp6QJԫ]LYo e>tRx#t Dfb _?`1qQoӢ,P/U bg@f@oN3 0˒%1 ishU9rmIe)eNnc!ox\W=E Z'źA8QS`5)C}@C,|5FJ fy+v[{q Eo̜O4Ywk< jG i됾C{Y~7DE"ewD KzyJ_]rFKs0k {bnc.Q4lnL[F?R\--o Tb BAKmMڌT&'bG@ع67Mrb WҩVޝ0O6]%=B׉i.vF9vۍxH:I9FwlGu r_.BL]$gj R, ÅY?}P4[dNc @KG|e8x1=3#/3q 0Ac`B3u-S6d= Q~E5ȇ#8G:m l!b|ZTzQ-6`Fqp=DzcXV̆ E"Q[lW ^y9ߙ]1uAn}-֠eBsR?vaqsߧi:Ku%GqRqdtN_2RrZ  >pKD\>zXdIou3Nx6jAcW7L|Of$xx= " lv#JGҗ$8uQkI.چν'i3z4pbF)KREcpw,pB.gOz7pqCo3X[{YaK~ͲuH7qtBZQaɕ$zn-x LP0ؗ!)0Nc]3Vb:#wstF#Lb%܍XO<$[xstb2^C^tG";hSU|^Oo!r?)M}')+Hnc|w}m;_-*oh/0["[hYc_0|?ng@[#U^}GQ18yrŶ+syBm w"jr@0Os'ŝgV f2=`T[XSK i"5+bHc焍yf{$T ʖ!6XP}1#14u-U3 {ܴQ$3-<:弘z]jJ`?WE(K ^YϯKsvJ9adn=臇 ,= I7]J~}5tљI!ݥڦʨ] NvaI" = -3z;ݔm LU5PϨz| K"pr,QmoJ8y|HJtBdǼ@2bv?R21,!SD.!8>`p_oIzI&ʄ r ܶ)yNι5zK< s(6Wp O-R:͉_xrmQH_ Ȗ=XQ0RfGDdG|ZBhX>8QnY_I'$|XƢWM+{v@+35;-1QU'9?N̶2Lf?4"˽²z$O_vKv׶  1 A) &F9{:70DzoNo +Hi1G!70_3>-Dl`U^>q,SRGQNmߟq4bw̡Hcqj;ŻW|t|o3 EfF |32*ĕoImAMS- u[4ѽnW=fA(e.A[ݏL5 K+Jǻ.nz#Xy,iVf|W߰1cVX'F @7`s|#wR8d+yi;[~w2WT0#%fUsW>sEƛN-/[J59NKR$b 0i4X{Ɖ逓JN7@gÓ! ҙ& \=x0s2~N+eb,Qy?=xqkw/H| >P 31|F;|՗ewP dk,8ciw pmVi[MӰ;{> B9Q[O2h,tIwM\2 ;Y$"zdF6G,^$Y(x߃aVl=゜z%}-댞cxx9G/q~?_/&?e>,W_}[*Ze\YIMR_Xz'W}%سYFХuGg Jq&K"NS弗Tt(IMJ`&L+y^ڒϞǰ 8Kw+6/{UrgQCeXEV8b\(\2XUmmJljd.p43X5DEk6[MhIȁH3z'`+G0۩ 읂^-d[JA1HȤR Ӻ0*Q=/dyn(WM؅w; RzISӣ #J>7%քNJѯnozQ[}k g ;@.?!_D6kaw(&y^t9=E'9h'% N#MJhydjlQC+:%n v_Gs ơ7GPk+r(]w6  D+єE%: D(0RiY?[Ո,6DB~ 9mnaBU Qo12B_dB/"tg1;S3)Je@Q9[.rF׋& lu4hT_'Bj&SYbT6)>U`-u'`UTLBh*FA3lC1 ITǭ2QBBɡ.0eZ*ύLrHK ^i<川VD7^* 3O:]+_ Pzx!g<}vdB#/Suُ ?W=ZFbHCЮ զ"bs4)Tۊg eu@899 Uh9m : KP0/NI,dJWimDRUZHy=nd!kk@\EֻVM2I;fQA}%aN'bef$ lָ͆=oJޫ%pv ċDbSkp7Ud{v6c,f'Tdd?r)n/0vuv$OTpW ^dFkoվ~`;MU.tIb'F$/ZA, 1EDq.ݧV8 tS^! \d/,T̟fSh.q-CT5k\rjZ@ꪪ;tz5* PujhruLNKTp旳4hjpS-A54Uؠ*j>!vն #j\s 6-9FhBZM:I<꾈1,/ #*{@l] pqN4VT<Ih'V%[@Zc 'tͨa[BX1Y4km. 0-QDhIQ\,?JN&gEpQL,I 9oRZ ux:aegKD&pX LSmcV5XFk1f@Iך&*49AL%ee֕h`&>NyϨjgI ɷ'UQ^^ Шl dĩ d\˖VJkj_@h[Vsh)8 dž'%Uvj6zoXWЈ٭'!Jj ɋsk@bn&PZv%A^`V +LWl rQf t_IU.ZEQ1$J;[߯VY8A[QEY_K6X݇̚E<BT()]m^0j0 EG1ۈd&6KL? RHUET7Jq?J5d|kkKW-Y WXNWz Xx7Z+ǵ3M =l0h&3\iRңI%a *S.3jN$nYm'@[fJSRYM1m`[ZWXjRQ;^o e #vQd1CJϞ^&7w}JiF8m`*Gt.fٍ8$5^W0"<}=f^f 5mMvJi @#OhWR1uu3W=3Y1E!&g6%Y1S}jgDJ "X1jUB#=)2/GΛ+fU**OV71,oEԼ+lfAde.J}LBoɁ*>!e+DTKD/t-= 4Fۺя>=%Oo -;'W v(ό nI_\>/6Xνy%v5I6*sG] D.V1N>D(}:QTg]7} $}1 xI(5iI܅<}fUQL<9@%~i?ï&?o??۟_ůϿc}[ tHW|`AZ Hm<ӕ'k#{[PNSaY@e0ѴeCIF9YUX{iԫ Ž:*JAQG3oSWq eOky6-\||n|Kx\F0N(3 X\ ʔ=Vu>ve,c$py`U/N%#P_c`D)jfAL!:]k@!.xuߒ#? 2cЗ3cPo'ߖ%s\/3̬i|?ʌV濰{ $$=C2zۦz*Q/l`Z pP`0Bb3n0-d efZd)4~5x(Tu닇4%5J6Ƅ$s5mVq Cْ̺}AJL\ZfrlCt"UȦYK OTt-BC"O~zŌͶn\ +=""Ȉl>|#*^T7"N-k|r<=ګ#y|Yrk1Żc=v1UfG!yh4Fd:0tnP[].C*SGfu6LY;k ΌAq}&3I*DRfqEt;^HsCȼ!>[ -8[?Ccmdžd3ߐumCmK{`v]i ׳o&;XluJi3QpF>/}@p!jģҋVwf2fԏ[8z`LJtkV+/?Mԉ߯]GLSͭUB_5xd]C=eVn{=qk6R/>uO7ч(nXu;޺V!%ΥthZy^:g<;{9{{dz,ّ}5Ґ4 $iSݍG݌tj}>9m7l|ؓVRm,pu a&RÚIO&aZR",0U ;X(O[xeų4C[`f`-Ie y#8G3 Κ EhU<%A֯A_UN֙HZze3`QhPVKec˵ HW9nY,2)ŬOP*d<^W_mٚGUQMia~鈊P$71Ua/9 n" u&昳lk=x{$p L9?WONȈGLSj]^ܵQ7EbdcJ^T^޷n;|yǞȂO"?L AyU&aQ,]W ~Kf^υsAD-"'u̪id*?olj=ƞf$Y`IXăO?R l Yb .m*JD:JcXeYKfn/i_8DtN(PIJsDIB4, ġE(-l<*$FBAdKV`cҒ!-)o_(Ry/D9V$BikY7eU*ͬj lNƄț|[J*Dhi @+]VIސA ڴӤ"ׁGm:BK1XT T"3&Xm^CZp\6bM,<PJΠ#bG6W^ ݲ<@eqE6J$^ sq(O_n^^0qC vF1l.QQ isn:]zo~ 'Ks"[RYm\$8T9JMX]GC!z<]ֻK0,YfjL+fV)P]3U`V3k841vn "5* ڲPc| 5#Khp1a #؞#Hie-ini7@fᶨLf𲥬^XVЫ2[XVj@/72dOl+!~`jBmd/ }W#\&^=N`ĸrlD[ɍ5!񔈝0v۲V{dý kM ob"/9!z/cL8Oؒ+zY-ZBH$*LS/l %ªe%š뱕˜؅,όU" 6$KyX6D`)R۵Ŵ+1 B j#˵ٟiU@91ԮAkL"݊S44su~M'CwdN\imk9 ﻶ̛U^ǎw:٫jt\@nBM u .pYċUޭ1VBēP:qJ1 Iga~y#xziGZݦ ,=f(D쑬E u&DձdQ63mT|SLw|'`Lx=_Ϥ2M3{)vi*Dwh[s1+QBD_a d.# DlSVvБJz)!Bb2ٓP :j]KO=* nM@jdNX*y+.}x&PlB8U>ld~iNv~9e:UG%O-F &НzP1,D}վx)yX.Jvаpɫ[&ˆ:,$h%3gKoǺf&1ho_cͬnIm fu3N/4!tNC"Hn&۴l/x% `'n%`4-V+RG4њ^cچ54ψm1ʸC%Oxfm tAuΓW8`TBonaaaG1V [*2;Z=!w4ku$t#+\"*ޙ^[J ڶ`p9}!OLxmOMl扥U]^תװ, +K^[F`/Kcm- ZF:Grl,ָ.lF;akdeoH+_KP5rx]Β61gw{􊟸5\d%+|J}w>@V6 KUKRki,[>hAVnIcx%/enaYJVcKYxm]('˸J" ila5?EH%Yi?;5Wtg{VNSᝯ\mrV1h I-`**rdλ:V^A3~Wa Lq"#{q,u0YOkj`[W讓unaϠc[ ``47XVyKGF L'}Ri[VN> &`FWӰRa@G61 B΀6B%&N#C9&rX5De(s7- mnt;;-իm s`ӣbwC!(I!qfڭtJ/-׃֪-m\7o 0$V+x/{. MLS.af/p!:b1_oI Z #"! vVu9nD~ q& Iyw /ڜv㱖P̋[Rck& \$8GyHuO$ ag%)^IfR)A2z,맥ޜ6OP.UIBlt>/zɔ67g(i.^%Z5#‰@S1vd6þ@$a|p '[ype{6+)Zj bk83ӛӝdB9gQN )SU3=CQL{PPeh-DֳVێT͓,$]tܶytL,vFhꗽ5Ĭ%C-!6/Ir'R K~ ڵ(Md2N gZ6sH q<鋯[g;" Λr"7Tf/jGܼD'Dh%o]|$S72s:ӣBCN=.5T-S#谵)bZN؇%҃7{ݺ2VT*9dDszYf U94}1Djm90K e3xf3{e+EmN<(δliBro#O7 `[&\ `Q:t z_iu;Rf4 ]HP$iCBiQvK(VY[*HyMFE5M\&s#x igܷI l |ugbUӚm6JaډWtw,+1KR~.Q]~G#\M<5Ԧ5DMhK˛̃p8x1]hV/NaD:qgOlLE<'X@wN v#[K %rB"Io;[օdJj\w'颦d)]'Zׄ^MFK2_l}O}&:\soԁޙٛ'/2&*+Qxƚ/-!"FW-no_n{#xN(N Vz7}34J]B\'GB*L vj"/iK&jcwFr4С u;Kk?:4w3y"-GMۑY^[+:Q-Uɜ-o+0WJ*D {q X`-OEuMezsgF`!ڵ)yO6A܈ } arzC*{qnZb8bq(lsxyإp״u{ѣ:3C?6LQ(6?;8 onށ "|;e+ɂ2Fdmó9HNR sFGb|tHDֱ8ؗ4C8j"(f݀b<ۚJ…鷐oeٓ% fRI)$TO0grX Y)w,6v2ᆰ f\YNpDMu5"R:dmhRgfz 3J$± AՃʰo%Œ"AwaW}:yb8#.պ d)v;BR0u[>Rxgo ŀb' [W/ nۈLm ϻMыxxkzqE~uk ْ=I[=L@8Djo8Hv=tUȴ_wϏ3];*Aا0z\'W>iq@ǽqqZs.>~R8©/3QN$qQ[t`[̍+9ܩեzp>SZY sfv֨Ii[{n"؜ns#L(Ү=,F,dO_ IܙWO8 4食#@9#yoR\OR~%zL^QA} A,6XEo8&QTg*D^ͱmxضhcZ"Lq/*xFZ(LʫC2ΐ{B`i|==kxy>NHY5RS3H1Lz>K낑>@Y4/㛭nI$jT`-ⒿkvX.5E<͒ЂF3X|j1R+c2N_fS:@p-ӈhcT=If91ϝD#3 Y5^:ʧ9]=kZ-zlAߧƾdR雱BQ%c@\jA*u#x.u(3xaF0`)! Lw.,F#7,%=.s H,vDQ)p)b)飮F\UW ߰1:@. X7FJ{]; y T\#iE4QAтtK:,R"[ ΁/ʈHF!{Gq|)1놃&k=+ݭkaT$xw++O#z8vp0 "RYVYIKD[ *ٔ4W+ jrJ;,T(W[(zdSbbt"6.A^E2T0{d"TvݫHh=kKJae/Xhi2Qq=Ũ;p~Tud6X K!׷GGzN, -x:#χEqkM-$kL.mrq1٣cg0DT E *j"['L #XI^M˹6륓:n)#Y=my*MH=afF?sRɥ )q2xS;P@2㦢 EN rr7f"ڤ˄/f)_jKՋߪg2Юc&=Ğ9i`=eGKH8=,Ŋ2+ξf+D~ū$Cn'Gd\9!W-*:#没U^ >'0RvP. )>4ZOݫL" m-`5R_F3ɴRf%$t{ K+xWd?Bɸ۶T<)@hnpH\k{x15I˺\/໴otZ$M +DV¦r6VVa ED yB#yvdۂ2<ٓw'f턹ɷΜ=c~%Rˬ BGBJ9'+4%z6T<}2)YyoZٕY"?އ'*fzYErMG#'r+=vHmx薸:QmE76Mu}U=Vc)0ӁP5#rwA1AV7sEB͋^]Q#߉DdB[J:!{4H錑@o+Tt4K1D%B5  gT56w-c^VsgY(Ak>D P#zG'H{Ƕ,Y$f yw {Jde4x1ZC:S64Τcݥ64 [OH6iR\vfK&w4N$h]iwUBf(N[rDp[_0e58c֮jfr2o7es QdڙdOy=I.O 3Cxӈ{v{Ξ]nBOB~stR0wzᄎ^J=)=ap%* т1ٓGo q4Y_f }6[6 |kbyzs}{.2WFpdHjuޮgː3(LQ@ZD!r/r:,+gr]%@:B`T=Nehq9*XZ& 0p'1CZm^8X b pU 0:I*<ۂ%%"D6rA.+Dtwz< ʨ-ېa a;(vBfHoBeBJgVN!A\z S(-YwC|o K"q#u8 ~;pjMZ"i c}x 㖧7] ߱OBW[rnIp,ci&%v'8Yƻ$BwM/V!2Z^;v]{l,dKnػ[Ț]Nj{Tv ݳPnz$C* ԕd0>8!˚uSPp9u]HͱϽvl^4ѽiWB}c>LZ;}ˠ%3 JT|p@sʆ+M-҈Cְ먲֚^WQ–XF輍(2/"bZzw@ _Bu+[}K)Ԝ öiлŠEBXKK ;ֈwGWbq6dDÚA+V[vgY}e9 :54JI'0q"-}=UxdWty^UCvlնk`Sk1n'N?ʹ䓆TY  #ozN;v uDWdE1`CrpȌm`` [zu!fu&\QL| "vJ+nfq(|;*m»T8:/(Oylp ElUbQ8,>o-J.\71Ӷd m3ywXƼ@MݞB:LF 1{۞a&{1K~㈂G/ޖ&Qѻ9-IėZWܨ+6+Ee"roqyOɍ^X?>6F~uS*Q}[uIrݻ`ClA7y [:ϪulX͸<b::]LmDNN$~/;bҩH`;;Yk=6p|ߝ@5"\bOwCW \bm2Yv4}7Lv0#3Mml"OD2D##s\rBcϯƉHxbd1?N6rjBf ! P_xI$ ;j,s[p oH/\חz f"B}0T#}!"xͪ2İȽ),@Qm҂,ڊqLDV\  q"%6koŷ^騽MѬ#Ҋ 3@؂˓sB_qk0P/ݫ_V՗8@T *Y ?ы牏ԗnσp*I%h2wL@7+z\;LoAN\,abkjoO9_YFԸG:$S)W*8 `yfT%|+ar;#aFB&ʧblsW"-| V_9Q"6+KNIGȳ;Hh:q8œ&2FTtȀ([^)eU(;:+xQ_ AX64|cO*VL4׈UNƜ跶;ΧxɕK J'nw')=' l\wP؋O1:.zCGC}h8@5>TR!]LaUu7prx}0|x&Y| # _$G>]:w\A*[p|^'YDLBN=NxyJ.tbT*L QKH*A:\pPv\8-Ľ17hSfBm[eĠاkA` .2Df.C!;+Otd3㊄=Zp5b?I2@F7>ciI:tAuz^mfĎh~p)CoU;j:W9'{eOXY! 8v?.yYhvQMbאַtu1ԯoS{.`*aD'O"t-DJ! ނ_oxaRw7a$#ǟ݆6-K ZfZq,_X.Iix74QgM:P YLV4kqlu~Dz(1S-&1_IӨ' CU'13>2S& aRR}@vGE@DisI#xr򎆁 8Q.4PBy9+׺ d=z;-6q#1y[6{Q{n0 FmEOw1k 7z 8@:-* a,$FTH}xpn"SZ!Ai#îF9Ն]Wj%AG UD*NX`iڢdG$@K8\*k.0@*?;CטOx~KspɶuV)-bkO1n޸y˛hEoXN[Tͩ#:rJ*98:YtjL9A)IA՜ b``Ŏ_ Bq9lIڨ*vcmZAX PW։[5o &hlmr^8< dN ;$JX#E~hZ9*1o V@0P#"UEWۂJ*F ;BatUXB,)\Jfbi3k8>56 O\P;ƋFe4a0[{B+=Vj-5^s5n$6P0)9,]$wŧ f^hjWdUPL`.*=p2?sȽV{r`cQ)"l;fAJ(9(ͨw`o $\L\uԳ 3N;Jf)A§Fw)VB}Y=j[O@٤+N9dП[T#UiNzcXioPi5ӈ-%~ɸ>t@ `߶'zX~W(eR}rv+x;Ő_ԻT66P;82~ 7OA\PK:NFN)<']Ŗ쓖vKh#?W";"Z0\jtv49:p+<LM.?kiH #vǛH oѿ::+jQbxEk]W~;DȣLdlEqg| ^D,CXbk7T#۹n|mIiL*\}?`ޤ9 &Tzt( 0=:=Rϱ=֏6f}S */``$8 x7Ԇv!INRO-?Mhb{Pd& Fs.^ -me8rRP^9pl?_hz} 9x7U'A&]!N\.[ eW{9rLy[tS|nX؇GKIC*L ezVtdzd /sQնVTb;XX(] ֨#p6hZZn.6/ 켌uK 7e&󲟇~S4W)1?ZlOzmVΰIIqo碒]unboag@B+nPzD:kZ&{=}2R;]o6#.ɓB]º.b>V" flrM֐A"V2}pe ݅K 8YIK*A}ӍteS=[u܇]ٕW[^#=t B1Oۗ\=^/{P_ĒRHS/Rb`]&E%R 7ዬ1g dpd1c;O3g|tUso0{)~Z.d.zO.3dfԒ\ U UQ"1CO\`ŋ4V/Rk|PI$Oh.N)b/ـB%V!.l^6^EirP aa=XC76.2EZr{ Z= U%MnMJpOVWgLAtœ"W,9Lr"R(vDR:fJJJ&'*"ILwiƭ* Vl<LaN몳 tx9v5VXܪ`7y ]V S&́2x7k[qiA;߽v|6,2bX6C$Qn}8c*ʞņCfނԸqURǍVB} UR;XA=-Dܿ3W,,ݕwLeM ް yY9k}TOP?rJ֏w2 pc:):!0C|.T3JIm> "/s+y h hqh0Ȁrp0#撸{7g~)sjK:U{47Y_#ܬ/%>,Qˮ<" ׿+PacF*|/P0IGnFS p\0w'>@\7|[a" :`G΍`d}I&z93xڝ^=Hcc8o+FĖIDA2 FO{{BBN9럕\# g_]O kCL-\ ΖeL/ b;̅{1=,-i"Y/5)k2 5jW:Ox8/+ trU\t+ր )O14\Ŕ2 z0H!= k\LH.AOB{z N&_^ -rjm9ˇ'!4 kOJ$}3x013+Yh "p;۔-KF3"/f5L*F+LDlq1RbgQ<LǗ?x42!G_Ex+ߖ.>ݱ] g[mIƜ2LvuɞC:2fmc+oU9!] -R)!,zٍ{p}x߃%m &[YJ!NzU,?ҟBBKKT !s`7A W HOB$K8FʙidDĞBȊG1Qpۢ7<V(vTEݔ by eB&inxP^KI#t>ZEq#'擖ͩy9'/K2°U6bkS/zhe"s6 om ،X;y`JԾzS de:5p FG҄lG/Į+b7 Is&4t3bݨAq2DQa`ӝq3I;>M>=&y0V³H wC9|mąx"JÉlDe25N{qM=<1U&Y;!=Y{#2mA.6K@} T:p Ik?,"&V!Q8P;ۊxBƈU <ª3.F ;21xW$y!P$ stq$j\K}y?<6a41}Nc:to wS6iv¡Q;3c0#ov˕9}وë[*qxKCi\u" ;wZv\#M:MpA}о wS!{۠Gp׷*2"dY?uJ:z 24Y;WnTۼ4̏&Umi[qcF0 168gc'8H`Wxxk ?kS /v;6`4gJGK#ie2.;'wA-MߢxŎF*Fe݈dq)o)eﵙCm1f DzN P{.[O|gN'쾘9N^ݝ{굆S3 ǰBt=yeKتS|mkM" Z /ЗU38u7I;~f2dpx 0Q2|uw-\ZV>ȈFXpdP Cvr;lxp1S7teּg$?{E{${YG"_O ?^@&^k-NGX,c8 ~^j$j/Y"zF@Q9`-L;HT4M99"?J:[DHԾ(+h*D eKGIa_m2U uC̭?`$SMHhp[ȳL\BDž 4ٶ7' 5M;QPdZیp$J!mDR(N͜_Y@vCUѺ (G1Û@Sw_8{?u!F^D 8n֝ic鎊>4O~-o%}xl ȪFDln"I Ccmh>`4HEqLZp䖧:ޢ/o>Co,[#{|40Q闗[ç9E[%3ebkuhFi &?v๟y3RC'C QDPnz5$ׯ/.M/n*E>OD6/wV9?SO顗.?~5jNUQg;?oyJ‰j`tKJߋ ʺa}'1PgB$$y(arc@exʱQO'%BIFIR s9c!/{`[[^yo&k;RCtDj,5Sn&NM߿i=w'e( vxvTXDiID/SHPs.Pot"q\V{m0oRGks$EVCyM 0wrRPUmօTf]HX#8/@=TY]o55cH&C3QCv(|,anXT]I\#%'3Ͻ'l)hbFl`u ]G'*׾$ f7; r"2ky첡S!Ub1:ƿ ܅t>LGρ>M-fV}(޹x 0S%sĢfwDV^d7?@>Jx*2 )Np8x(˩qᾙjn2$Q#&j:y JbX=:v]YP!U^JCفi!`1"VHPuWH yBC]ӋnIN+Hp,<8y5'#iz8BZ VNph3bWVl#G ~/*Mt r.Ұ]V.Y4.qQCj"YbT 2+RޠDNxy1DZ# 'J()0n.t'JNAӡsPx\."&)p\dhz.v fhu8a w-~uPz=2?RlzQ c (nHX@;׾; j -'v=9W0}S$/x I;Fۀ+j[ʳ9:5Xhb 3p-Nxt9PV;Tw/⸥9߾̥Ui;(z[kfL;rӜp>XO[7ĸlȖvWN&jum-yݘ.VMwoo*>}Z;y=Gk;|VlbBD>hg6 BvHFK]ԛ1wй]E W߈fAJݩbzX ۣ6̍󗠲1Ej!8\c]Ln*-#Ϩ( ,ʠZEwOB%#xOeJ IۉF3D~6Њ˃a]=xR-h̘'* <-I8kT|'a0#NZ z[`sP>S,~ɼ= $ׂڡ7 ycOux0a E&7E|J>$u`fE%ؽ:-D 7r&_5kHoRM) Y/d,^Uw ̑bDV_T`R>rN´VU@Vx͝ OPbIiV .eJyVl^~ҷwdφlP  ?)S f lLڶ2޾yxFBI/?)j b 2q3B0 e߽/#a0#~)Ԧ—xDyb@_-O&߿o츨-m6( H ok|uv їN(\:N\|6_}y wv*^Qsڛ߿n>~AbP[ e(rd(؂

    5,;v/ N%9!QP vfCRM" L}"xJlW_ݝnOrW`;ɓes/sKM<#uҗĞ,cc7=ݏxQc[^QͫR4|䬻WcEZ(ZI"Rm</! YG{߯8 LgM<|;1QWߥ{ls@|O]mu8DZ,9#QO8=bdt=U !n4>-wEL{5_DyGɫi>sODa7B_sЌa!o/l :8b˴;f:2tJ*8I<.{c: /rV7l_=siSrǥEVE"CeJtߔhk޴rܛPRﰷ͹^ 9A/FgNՎ:}mnIVqaʊc)lX} Mga% jڷO?nh}l5Mp7qo_'߄fμђɍYX7~vz$>spRh@b0/MQX *q7yb]JU2Ji@bG[geAC["*dyF+$68_ށhVO>>`?D0cP=Տ`s"3W:vSbImGpF+Wq1c[=+v/r&!o۽wJ ,[|U~T)!Rn"P#ς@DIj#)\kqg2/yIOq|{6څn"A .F>ֵ̈́7b)܋4Be۫ x0wxK>$]!@OBoOkO2,Kw=koETJn4V?5}(+bߐopJBr_?K,JAITBO/xZC ] Q4kN`~H:;Wڝ+1J+(锚-( ~#JrBaZ: v!yB笥~bŝsX+D{X vd܅d^P6q:Gq:.| xlXZX; xPG+v8NćC:"r(vK:cAFp:^zCiTiQ]Nᒿ`F}דn_!<3't7Us uV4be||{0-F)870!g8X a˔]mzho|w=sciDg|v]8YZʍ6\) l|™;"y$8"qo? _=U0bg=^.} TۼHZ)V? ͨBp%n1&.\C'!yړ+A\!_\ apJk'oQzEIN!!8/2pkvWyUqP\K\wC;IJi^[P=y ';򛛹˔kQհ$g>rpd{*qɱ"0ʮ bcKkuv-$FQ;Pƙa(օn~ߩvu/ݔ+z|w2mXg/9k+:\psU!g8 k˄HԹLiYU0fY ^ke|H`^P K6cKTj{8xXR~l Woiꔃ'нBO >ZCNZ&]>$sةP})cYQTT0~W5[sT.zhVGif.~nl-~})UJI`S R^ܸ+u] ~ |'Fac=xBPyktX5`@Jg+CA+ jfP@[8FYN>0P><üu>KDֿjv/>6vwr?$k?) 4P@I )>p@ts-mS|^i`47قǾN>ы;[\Uk"hXNs|X`{C*T(YM-Ls8%Un|.l ,[qa<҅:RE*ǖx271S;d19[/Oүk)X.__HAzЏkO>n}-f;k=t,F ԅ!Kj?^&L_m-G5Mb\yY{j;Be4_׫UP/︚^G!S _?Po ,ww#1Zݯ7j1ݣF1x}袊=pp< /܇}vIpfTbtxzF `.{ݡASk/,O%yaW$U;m4oxxxN"Vj]ѝ vNA hURI'V azHUۖf1n~ǘSMO|~1ޔ{,yaDXRQn2ovtӈ~0װ*z`8\y"q(8d:}]zH=*3M<҇i@-S\,?cM&ds/@ᴖ.fP(Uο~o;d*xuwaո 7[ n\ja=6A(L>)ti? f1zrJDWrC^W&lxMڠɢt?<.Ycn_!{2yA"+.`eqv|h(9,bx[>yN )-"A>f}}hJC[DU-p 7t/'A4ԇ̃3г|&]ܢȼJ>CWcI͈ k%"x9H*Lc tC4V ?E.n3f4Ju@0xaῤ.ruKDk"~`GM0tcTYqL%GvDKK.2Ck~,R2 LZ+ Q/Ȅ:^${vtT#T/(1#t̷ٰs*ܯpqsy4g<0w'(?ܰ _mjйIv.X4JL3QHUrsVh4b{ŊccЩ\WJYຍ)"''8s-}q~/m&&N* JMXpoɿp̞fLVgj _ʵtΡX;ACcjFxL@dM_Qwa`ז©`7)E0lS XAUAW-8sl¬۳đ~8:"'T;`q}U 8;dܸ_B*]̬%Q7\Y'# p.CyTV#W2}oTB*7Ox 7Hh]R|L |x@(Qa>[|.+`N6@Ӊ1PDR&ٴ"*z sPhnA:љ kBD5{Nh{ƙهBJ/"WЯ肪Ab1GVmڡg2T"r|&2 Pi cSc.A@o2gGϪTx(a>d'p3[N$9E ,nml"ȟiX?I\5 nmkDhƥ !G4Jna$e3@\pvN N]fJ# DV%1ڪ{Wq"|Z`>J^nX;C}c) ,k6PB~ FRYgO}aҕI>+1VD>qS#)0fǭ^Cf/B X->1Ad\J T Ard R)7j}#N>߬uOBKV1Sc3%6PEohV)[y'3b!T7ǵK:1#J!+2#pdzMX]k؅žc.ao:Q޼"d`?{_@RiRջV?Fhwdul/ɶWI 1/SCMTQc۬JmTz'իk-C=; ?3j8#4–17^!$=gP!Hz d_C"XP.37Xl)A0KtH+I]qODS@~m! )#l/,I& +_|1Z }!{hu;(Tg;g]F;mCgU2(ʧGmUZ\/T* R'KțRI7r]1"P$ /r myi{2Z=!tU ڌ5*9BV tփ "l!wkQބ c>Pn7LtT*Q 7ܱG;s}Ư̎&},3]3Ll}-[P͝sIا@Eb ;j)Wy=FnT@2蝰'\ w[?8' pQh5>N# 0^pK( 5booMlCtq2'rI YY b+^wy]A-`lvX8i5^ ^:u ˪-Ql0E6g1R Yk:/rYi*=`"6@y$=ŇxK:$~tꜴ>#2OܤV==wEdre|-uB87:ˁ^ah=;<Υh!|[yqP2FŰ> e-7H{=1/*ENҸ>xg*q~3J #J|z +M)/T9Nc30c\ bwpAWi%ѵ͞n ǿ2$[GBІ  t w^IpbP.t׾ۖ[+pCx$ίlaİT5:6.Y\ TFH?AyȆ#~K}Kk1oYW9nTv VB\Ď ":c 8Âkb&t"|}S2X E,. 5ZTՀ=\(D6 3f㵱8ø)Dl5ŘjtWT&*5quBiɉ@,j,ast1#\p9FP@G%G_9=_I^D}7i#S.kF u %%dQ~=5LUsNC R*‹]l m!Y 21Irud6wh?!P'Vv`>?`G|@Q4rQZO/#f^jD5WĸՈЁ^~|1FѠ ڇ#5XvDO4q¿B7KyU[.l8E|6}MeH%ɈR^<%BD10~)<`Ii i WCiP4Bd`L^qFq(zfƾI]r^9pbv-zxZ F >l#Wc!m(5X=c{@Qcͬkע׎?n͇t2,dƶP| sov/$([Ǭ0d$+J9E{]qjj?o!\AI`<e](@cw5bbԩحIbI]ť6z􋡏qMݢ^)_. ײSߴq/1a {ŖW7D5 Z:о 5W۟ǿ?on?۳_?ƿ]6_T_aǟO_OzfSIB+Y$e,';NO|gO&'p XE5%f=`I>B9(ǐnDpwIڒuv_|qHi:Z$mJ܍612N^'df8fWVBV1ļh$R*]Ltdub u/82oA vKTI)dᰟHJ\/}Q0TJG^1H8`>d](z}l$4 gKK7 H+" ^OFKޜ\Y0K BV\VCEɠ6P s 'Ι$ט!`+r аJ-%UaBxq0/Q/mrqGg4re#=9#&ўIZ7HAVP,J2&N%ELP/ÌrzAolZ#5E5͚RBhASMk$k? v- <, ڰ'hI 1D1Hc[X2o`"|X5AΌq9B!7Eng<Ī~y˲' I%oM3_ٴ`'pI )VaI 6/ lKBO(0^#X?V]W@VV(t,xɈGuلV(Pwҹ 9jNLʹ nub-;Y]tq2NecDmOV {L^0zTL&:,c8I~T F]s z6'I11 X|}뱊ao^C'A#ϱtk!0pC'*jbXA/`ą\D$Ⱦ%Փ\@Ӎˇ]p~ÜLTڊ 7q1< V;KOBNDha!^(MA sj[-`EWoDj$-Tŭ.XpF6xj߶QMZ JQ@^d<*5 aއHb【Py(Xj'RS+bYIdD.Zwॸ/>vT| >Brr{B{I- m 4&c# d4r Ua_vՉJ_1c%I{p6@/@:< OQdZAn;ZM%l \/<7N(~O@g\;pʨMn>Qx=DP݌U'ߦ+ A@(nMA!Ru9j*bc1y=/B &`AebSz@H>_Es4X etf8&sT|7Ztt֬5edX ?.}3ԇ` fl/jPҀt`zDSK[B{aIlC]؊ Do{\-AȘ MIUš͍\C7Iۋ}zW隃(zrde˃.Ղgi>H?I y%TFRLP/_@JD/L1.=aS>H.q&!Gu╅ J!ga㹬8 xPYMo3u)"R1A8ua$zɝ+UQ  ODQ$M}Od XP'.E2@ + :Ϥvsd}K@r_xP)$iQd5O߰.!".}@t.V4%( }f >OqR2mbl1Xmbfd=,q!ݐJk6g9gb6a%c\w%j@ híъ*Ħ)7Lyܰ{1a$=-򯊛Ca*XHb?Q0o$ yF}kI+ƹ"tQrBwy$~t\:Ë XVЁ\JztdCqN@峴l][,NSB)u72Y=lBEru;Pf1}0_XWVbv$HӺNE˥"Iŋ"Dز)t |e~F~糧@ Ha U@jX^CUW' $ũ+.NSx-BBǚZpؚ޸qpϺ ޒѠrT- 6ӊw_U:Pssu]LQr^SBx_Zƞ7u䇚:u}g^j-5im`Zh?hbi)y{Mu׍RZJ 3; } XJ#9oQ(ܝ|_K: %H5qFwҏ;Wqnl%a ;} R4R?Mc7 Q3.H6zdAyVNK/ͥyǴ y;EmqC #0/Av^j2_GXa'uWC/Y@.~4~#gp H)#bUIRJ:Ĵ9F>OxZmMp\C˂䒇G%x~\&F79qP pӁ'Cna1f٤\{:a"fbPf'FA$Nۇeԟ'zcp*o䌴cсʫ}^xc283SU55.oxC72[}r/!Eª=prX˓\:=Mݳتt{H*//&d }`rn@,WG[{뾛2ˮ+l<"UO1Rv4pX~=prkN.w#~4~&aNlW;U2@WU]4HSR&o׉B,dZx'HDy9׉Q!͉hD;;HD]V9>x2JkhTzX #]$oZޛ`k< k*ZHVttJ;';* ju3yQO?r^rK>H~h(ZhC,\/W}#W粚6*JMrBRon\XNQM,g:6b( &HۙAhU5@Wf#gk19W 6'fL0ezdľH<QY\ɫQ73}-ib:Plr湽`_6_-l*o*۬l7I.8t0Mk%syM'4s| |& p-Jll !i#t6뎭T<~z  oL|&~/V ^ƽAg [ e}9MMzriGA,bik >1KN剖9)5IP 3-Ei-TQRn.`ʝ#4IsBoavGA aB~EM-iBe:Bm6716塸6U|PHPC[җH5R`6+RB$A'`;֜pnjK>g.9h ' Ƹ mW Ҵ.A ŪKҤ' IN*=|/ZYʁ{eU, ͚ҥE@X.!:l]jo$^m W j8Zĸd~Pc#^RviB;-=}<έ "~Z .v8ċU\b'*YF- ΎrD3|$j2SĦdk!kljca |Vq}3,%*5q_nR%6hOHGÈ]ʌшnE`uoȞ/e{=# OwV^i!3H<s&d Hg-o""i_D_C{;aH#-6\~D 8ei+}~ MPв-3m[=dRgv-uΰw 8%@hr2Qi16<)*Hd>8Y?؇6Em`0-uBdTyEVħD2Lbl9-4-XkX$@@J&!!cAxJͿ'+ɜ);Bߴß BpYZɤ9L,DHSJ ]=t]x#]M%~ɺ!u;!B )7ƽȊ}2&jWܬU&0'I|?s?x0<-#}E0x=[jZ֝EPV^F&&^Kb4V)--@GNUg֖cx|u|saNL*IJZ QIl`4> ï& !>1壘K1y.cRRN9\H2ZW՘JU`~h]EꑋqZXy @qqxte|igb,X`Il`բt -<j"ڂ։P)8L3Ǿڱ:K{+t()*uUWg.&ܾe}iħ;v-\Ǎ˫)?x (ղXkFBRj %zQQbjg[V%Gv`@HOu#goF-v@[y"5BNb @ }WhYfDʧcYx2Ԁ9iC)n5W$B%$Hl:±bKЄԝ*}C Y.TS,KH6-#fbҍBG.W_КW2)Vpe0BN7zh a j([ށ&*\u!A@ O;[w]GB>O{:.B7bRHF-u-5m7l*xJf-q4cݒ{ܼf,'{?6cqSr(> 8>H͋d,(79(t:7IJBՅ65[pr.gCHX, I[.l1Rغ?=լt:[xfQ6rQA hih{0n)@?u*`wM\b± F)ı|,Jr2FWG/&+^7ҭ3J ]ƛ䙬GDZ^VVvK_L<E^-c#6c EFWsjAԲm ]*jz-2d|_3/ooIBBx1 y٘oBB&!$/aCLb`csU붺U]ۖ=P˨ Hc%"QYNJt> Q @vcM!xBu-¦xBkbѥVf{I8u\r&Ŵ!/=}5H lydZ`QA 7cW$q߿2%l,:1d-.m"F0:NI6.`"뵢l $PX2:-za^gkBcrЁiW:4TKZ8vL̲&%Ɏ|y^.f*Z X564&)S#" BZ0q qBg# C^%!A3 3669n9gd*;aع 1jח$βr^a>i`ԓ۬uE+)%=6Ai).(g864 Qu5$C롪&\ă ߄g\܉p Jx E[LAt+dJ~҇( ,_A=%KӍQRR))S] #I6RBc3 RAJlagN ;FcS؃Q'x8E -buN7K{iX28E`؜J2̸p %<[pN< B+ÈL.o{0R CAk0 mQO!dp 9y)^)rRǑqJM: W(tHĴ,EYٲ%GxR;/BaHt^&Mb1;JrbR_ʳ4?6ݼf2PVa ٕ=f(iCk^FopεC I=:RW' 0樚J$ l m& uBH΀ڻSՄ٣iFV:CND0t 6DnQG8刯gc6wu$yߩ[OYe7؃um6e (]ف BȜ3]F]RocM-K#ıX/"|R9H{"G5 %~"rtNmṊ\&hvƜiR%&[.eydVdBR9Br=2Y"N@%tҙD&DrI82Efa< h7JHƁb lR2¾T+!)(y@ܷYx]BPI8"'Ƃi+`lۄ}bAUZgvDq>zR[#.K@6 u*m+yؼ_:3H@#a\ePL3A976!W*,m !Φ8ƨ1pLI&qa px cJjD[U)2A'W GM2倓4:\i j%Ú\eIR%q݁o#Feҥtt@)ҘӮ؆,ZJnsi|g]+}הZ~;L# Y |NN8hZ"Q c"QߘƗ̬%XpER30cf)):,)d1=U#$ `.9UPfgFS1Qh9hʌmn$[KNY9vqڒ03e"^XMg 'Y,t<m,7l}=oZ9W rGā ;?1g ϴ pt ǜu9>;4,X9I*b-Xqjڀm0 '.wiaWgc}MX^+-,4oҫ8Q+)+^٤uva&^vٶdsɇ̌}aUH-r1CK<\@Ҟg3jpGg3ydEY(ّiz՟qHo$%'֡y)ߪv0@INũ i4k veӤ e3+Iz zr@6q+1 WDӺZ@!x#u2<{FYspdG/nFZoSLzi,Lb'hӂ|qL[ȩw&<I$ɞjE Z6w`xSqS?}GE@S.ObzG5+|e(/IȬj {Xjy>#[g:9=Լ A3Q6r<7hYAb #9>&Ű]ǂUBZ~,[JN V[~T 4 -YC)p*zAJeTx4=A5zY q66:j Գ^Y;S_L1^"ܺbjc8C:Mys+zhgüh-ȡh1ԎN将;s6ifO&ɤ1w*KT, ڳI`' pR4)Z|4NLT\Nht̅ ȅ]2l{v%F׳h2c'{K u2-gmEH 2fTγ$j2BX){(d.+ExL̩ƾ*-3 %*HPk߫SR(2j6]t }W+]omFa U-0܉DFx-gD(4M&(lP6֎N9.BF>-|496nPG{؆G'D-C.)=`X{ئYi@Q~Ĩ:.s]˹s]/'0eXTijiRmR+w+?e;7&e JH! ͜Ɉ6ǏkCT=!8*'%y mҔ׾M*Iw 8'BU9"(OY= b9~y<ŶU37\* O>sy{ sr,g1XVgWNsT{d[uVڝj:8;p{w]M_Nzg׷(nxhf TzN,1~FndXLiC(ҒYLQ.A3(*).hoU  3> (ƫ)'V)m))u\b&Q`w*["!%.. #dF-⬒|DΠz--aFDeE:Ji/O..qgIKA+؊ %)Њت Y7 J&5#T Y:a+CϺ'En'vj \8;M87UゎZ{i&+9?Lȗzu*,Xv ۳KX!r:n>e땸zR8j+фΗ=r&R@([ Ӹ9TFhYG0Zn_M"-V2NXJYn1B"OYI3bRS-HIc%%"c͔ GR8'XjQ)K1N+ Y0 m %8Ցs1|%' ]mmc6k2Ѡ`=BԴسclg=An8'Uqsm@:uQЪ)Z7,O:'Cyӆri"udBJItgϞx_!m\w :hJEjb +)`6yh"J@Y_J#Y7v<Ä3u;G^8 govmSy7Ԟv> ymݹ}ΏWj[uRJkf˰m3{=?[:+ʩ} KN{vŲ-iίJS[lJ a xl[|B>7!`RGҽOKONw\}n&w𖙃'3j)2xkмѸ=}ٕCPw €vey-=thjveu|3yQɽjlybKWض-)go.nZjkyl\S#ϳpdvyOE>3vV+kPD23=4"45l>ń"q[wdQ+cٰcեKœihgjw&q;kg&]l-5WK,}b7k]nv6i=['j*9tNC+9 ȡ~%r艥&pu˕$:ZDGR Z Z Z wnzۉ4!¨}2S@aP͹dDy Էq|~u :=mB>5fvr9;:y5WM9َit9:6,prOMTW3A9MKmԻGԻ;+ӢxֵuLP״p-r%ٓŠO3)ƕhUƣ9F'.w#nש+15X܌$pw3211P<^9l%N0n.WN.VJʊOX:8]-\׉Jm;:ʑk4Peh&EQ8&CMTudqMuZwn"⊶_\j:`9^->xEWbFs%f4;&Mk7KxL|kwidw{ש32~(Dӄ[ Ab]&ӛOP#Fge'G'?JH dt?*A*AmKٝ*+vĸN }JFn:tZZRڌ'5GX{On//7g[ ʭʼn$j Mnt$Ik^WrG>},}_'Lp: Tp)MRk #ofdC7)ht {bS4nD?nr~j'󥼸'aO,uJ̊ZkVוn ;fkA c'u"P6sqM9o"\*G5qMptbm4Q'ظ<6goΕgĸvFrM,[Mn+3όkK-ҭ>ϹJ2tOU:jv vG"G*1 UTH[W]BM ~H%4ijtnGRtF6ltwR(J2I^$I.,vk>b`YԸx2durrRd}w2oqd׭-q`*vb }699ɕҩR:UJJT1I4P{NҩR:0JT)*٠t-RTi.f HK[iRTj;$lPVa>~aJd0%hBÔфduJO om2L0Tx"*U'ƥFm1msm[zc's{irM"cL(1zJ*腄NA<5WbFk܌t1)8{rkRk? 8N\qf|6 "Z"jt,HE8 Bc]{G>%11T#|o)۞+*65Sbj'[kffۏkrJJ_d*ĩdJ%3A\xT2%fTd*L{OJo*$dPh\iq3D'2Xjή4oK.{X&8URI-6Ҥ^cLRǛ˭ZZmufK=k%uV޹L3b{l2;w4Єm̍>](1/j=y^bh[oN2ِHUWyFg5<_cu<`ԒY'D ޹jDJDJD- UEGf+Qtށp gclYtyVh%n=Rɢ,Zɢ*նFKMiB`ʣe6tsw-5KJ~S.D~m. U^c*ne>jL;1t};]|s5uS7Q//:4mwjB/MxD'#f\b*l 곀%8#; >,zI̶[wV悭AF';w̐lhߌJIr3211G]61txr^K`"\j\hZT㭏'фń3b\O ^_O2-D|Uv2X3A*&gw6uy>}']|Ic)ΞUVKYF&.'}rNKR~hǤś&?֕owtvΊ*$]o|6gJ6L(GprMh)ޱW>[ N *Nn@IfQ"2b~/vM-j<^b'Ikk[Ih\R-{hX~lD5vv#:ېࡱ:)XjvORf އuM7:iT9<3VʜJSGxp~6Vn8GP"ރ(oΜLGA3u;GBT]Nݻn[~|ةyV[z -lsݫwrgzx.vjJ1p 8JE:CU&!A{&Ѻvg;>Rw^`ڭݫn߽+Q Oq7Py84BFv- BWkwA#wk*Z78jk( #(] #n(?IjAC6 S (M OA/u`A!ACE:0zlop0b-F`! 5#kCX4ch%54C@QC Bu,@״iD@7?05S*%nO!̵ &o x`i> mN8 HG.1 "؉$,R>LO! endstream endobj 230 0 obj <>stream pTɠ - ))y. 8݉]>D&`l' 6IE0 1Xhp* 3³w#KFe76л]8¦M6 cYJGn# #1E ң3Ͱ$LjT|a nM i1,f;((Ib4.8|Cbʂ+"TB!1>Bdh!†baghIq'!a"0=.%"I8p;\h/Ŝcj\N~XOJPkmc y_k|@\8`'74)N\˄4 Sgx&p瀸H6 gƀAFa 8*2>tOgb-!Ujc )pA@>#Y2%F1atdiab-c|ք[i!a«'":f&M~h݇qL<$Yt_"O<ViY>ሸZؒ$ P3#i!j,'+U`,@+}NҍS䮲l ܊ef|D|̅Vؠ$e'sbOn/~ y"Nǫ<"o.mXq&#޾ L q>*@["m)/ .D⧍(X^fœ 5N$u*p"AgV:L8'8xx]'< /7BC*}Qo;uae\S kiXT5(ք CdT:E<*xE3hd_ D}34BZ 24nR]j>b_?NŹy2zrṚc5֞%Mߤ XMбDG-mP)58#"TPFD7C2JVWπϘn%!Vdً`88R$&,byteLr4~B$W wMJP| Oe-'Kj9%.4QBz?`v54TK7`o2,ѩ@ɩC=b։Y"D\Q;4@ dFJ˳>ϷK0y+2:_X&@lCĹi،[ ZneVN6kJjl4/nN9bP !eLl;4uJrD^N3PSlv7srI* #aQ E`({PKKT3sdp jѨPkO:/`,qN0c9T&j}fQ+I Ch( şÀ25e7"X {_8{#~I Wҷod5iļP(#RNhPAz$n!3F%g+QtFau·S⮧%| K#dJ<^Hm>&TѠ8j`Q;rWvBv=O9ߤkf(nd*ChK)Df ¸\ٝF@e=y~i(pL)a>BSh# XxpE-TX T1SB:(f5D"Bz\$Cd9I_(ֆ!\BS∄CC rPB'4rE8wQh' @%NȐN,)x9tlЕ$& @EEFвNH,4'IE .ʈ*[nՏ| @HH%YڪP^P( Cȼu .Z;DEԊ%t0*F5a5ۅ:$ tSB1s_-Č,a}&-jXI EF#"2MS|J&0Fbbf5MSag344"͜ɤɤ isfkQΊۀtx@ON j܏,me`aTe^LلabQ熽x" jk#OYؤXkJmX0W~YQ?=aP;L+Jeay`6i(5Ӥzj=6i#j̠_2&r֭\gz}{FCDv!%? i#RfO3ZJ"=&26dePO:dJX3Fut {Hh0uvVe/Fctz$#B2#Ð Q2!I|U%cwd }'% 8T gF eb%U&q>RI +G-;nAbȳ%ŘuU"MEu4 A .hvɴIDl?G*d!GP-!&GVҒ%V%)" /Ҏ8GdcK"d&])/jU@ 5ˑ!)В~b)Jx–Q)QOMŨh7&DzLO06A}`/նbV):@a#VQʸM!"Y;FM>P @Hr5Na!{&*%=~$Sg1Ynquc{ѶEhWaܢ;(+T޳؝Q+𷶙@^^lS+@/-KƇOބk[mM߼D AUhV"g+V;'DeNs"O EDr 35Ȭļ;<@GMl`Y]PJaRʕ>?=+Y)r5`!H$$-$!#S'0e1dS"/$ĥVr#G%p׻bpi%wg@Nvd=ůJSS[˭r3grIP i Ցf!t&p("2{ƔrYFVtF-,l{q*z/

    d||k'&ofԡ<ߡhj Zjε[8/u!6z&I*а_X% ` 'Ђ(nxq5Bh``ADBMZsU'㒇)w%?O~k_SW]龷緱==oݗk=k)q]9{?hoKn?}18~ob׶''xΣعƟ ۮQP_-?3BEػVqk5}o=x9{߭-,==}xںA<ѣǶ:J_mG_{Qf˜2gY/sJ2w.)gN/Sz;8u>\]L~mрBڲph0%ѬW9ZxsΡ4v;shS޽ץ)6\t>%٬> gܧ zK׈N՚b+QPSa`X>. N α~ʠ{hWI#hxSshѾ:z% 1D]]|qH9"wnй),1;ϭ(@ut6`[jWW5}wgo%9r|tOkn S3jvPmmݕ[ݥ98󌇟\Mf9w.-B8rj5!t;Di>@dDǐϠ_Ԡb=Eގ&L/9n5|vs1V)%lG)ľRPT/tց{JdLrӐ>zž/[w;__39/~?'8 :a#rv;scCFucRxixKSk;xvN39'e|rxBGܧO=? |/ c?v5^\l ?^bsk hOZ҇6{ςB;o=J|_>?7v|_ݯޜ}4[@R`bz]A;4'N^NϷ6x$}Tp<.F3D >)L2Ÿ1~ƘdžY_833 cÇtب!mH=#}:FY06vH2҆c1~˵sc' Mw{svs?w s=Ͽk{͕}>򫯏_w[o{bυر9{o~__ݿWyNs}m>z nS>0??7yoÏ?ھ;w]|;ʾO/Wvڟse>O=mh~OwƗg8o?}?6[_{mŗ]pN:{O>~}s~]CGw*^yO}5ԟ|?=W:Y?p_~`wB }sO[Mlk7GlOqs7;ysc/2ֽܮ<3%Od)^/>{>]u >o 3O>38W-bc_CB#_ß:dp$w: ~!o z'_ {P?|ox0ԯm^5Ц74 m10\(_w,3᳔ HW\qՔ70`&kRm~kĎ"GY;b`:\Y"jaԐz" }ΜP,@ Ibt8{d e)wtDE${p8DlG}3@K\j9V ޗ6)d=ű芏5Gc?qTKw0ߢrCݹ4%Ktp1CUv|:ʧp,l>7`ic${!aSLЛH?̹WQRknl{qY4@L$;?s.BPxL&b;/:?J蓊˩aI&Il *1_8cn"\ *֛56TӜ rOcYO*`t( @pSZr(oR!1mUnI*E{THҼ/*"< wSI; 3 RAtQ\{('v!Qh9j5,ET)aSnD$s5EUOCH[O`fBc$XHQb G5sܻܷ8wc Zُ>䋛/"<꿽 |OX~+=}c73>7g_7{n˯ /^ώg>gSK7>ē}hxgһ{]ݷދ>F84g~ }xvތv#2y']g#k5>?Ƌ>9WkrÚ|O~~`'3_ jC/ܕ$YϺ?YCt:~N=?V~K#_/D{P3Yx/<` u3Yfq-,3&TiqaDRR9i/^k2*p XP@Uq\52;wcQfǎ>ssP;㣱 /yK^v5{uUJl89+W{ ~Wswοy/~{]کc׀ҋ\r~s_x˯~ ~(hx_>ǎpy]+U QpCG{/<;ً{tnHw+~e{v˔0W6t%^]jhc_\]^{~7^ ?0W] /d׹{&^nj_{v^]- AWv0x#iG{~[*?Jn|_h~bX=nlm/:XYë~4`qu n\Uyzιݥ^D>"8Wyn49ѥА+_I&#sv ^}^LnE]׷V |e/fpŗy/{ \]@]pK.K. 1 ~v: wVfLC(u`+ic8ݘs4εTufʻ"aymF$E CUqG9֕ThXV # ^׋7If `jPohEnrCe \^^Ma}[j'=_>w@~ozz.7 x8u/p'~ji;OG~.}_t#MG^ntk)f<τk5?8ↁ[oBoX!:7}xQCǑxLwnMF {cx)݈%^j"dxciIcO-֫iASAJ5@LP'Fa_HgD00ۋ$h:blz$0!}n,Kj&t&ӵ{ҎNΌ}DS!*3'PQk*H d`\mgv$ Π #YGR8ͬRFe=xQ"ⶾ7w7?ٵ:_ k|u|dªjM[vSO_"D~m3oqr//<G2lƑ< U$~ W#OҩHZeSQ^Rn8z)I+ 9nS };+ >wĠeD8F٫6]Xvj'Bwիsڹ[:\Yi-u̷;KZKgwtNtI˚_3Qzp= u&F `fBiɂB$U@J_呉)1A@Mu~//6 l`*ۯwO`uyt枴}]v̰zfT}ɺ@_i"!LeR x1 -q h a&HTV8tKʔұL~H3Úy,$ 8 \:IA/A,9Lje8P.GChj0 0(6Hi N@0B$ hiR}(=44tlY~_)V*  Сxb8ꘐp71ʧO5\:++^$-l`'{Q`7h"E 0;)#~U4NT¶ F#*,kd Xq6G2~|"& : 6Cy 8waGG!\A"_؈ Ja JA@8Vc6O+ edANclIE3JLP ^9C"K15MF!puA " ;)CE)E\x6cTOw3[@ > >6pWӠdt0cI{xN ރB FL,Ht0ԀcI`3}hAxM$2@gnvVL7wݶHUVOnmvwjG@ނƗ5v9?{d{VﯙJvd4V>M͕Z)B[c+Ođ{GڳYoxo(x}PƱr<\k w׎.o'rl94i- y*ߞd3VEvt`Ħpxd:_ǰ' vxZǠɎ$2tX LpWio}*?uC^u'OH)oO&] f Ԧ;f1i )4<O暰C&;%fq#F"Ccm:c5fc&!Cc&uoM4)8t&R+ǷbNc5!w0p@ G4(6r9hpMљ_sv69 kXvO5?%0qz`S& fwzT"s{ $:-JL'\Kݻ[e%y{jy e5jbt]:lЀqFQH.FMP=Q;P۽/3h5khh3+\R6|itaY[j+T~e$ƲƤwc]V#ʺк:w7-n9277xcwѮA\/f{.#c r_wWFZzl4B:%~uVJ>p4>?pKgYnOާ"/?΅ʌ6\P~i"Nry_8lAxvUuEoY*vԍwLal/QGSEn˫K' L_je뾕%`WNڷtⲝO24=,[-WwuOku-| ۗZti%/7S[C<OD!e+, G4 :G?'s)(vxgW67 T~e8S[z|wyw[c+-yaKO[[ep#O5o^ GQ n//7O\sò^Ks>ԂYu*IG[Kˋ-bq\j.,N{ݜo5@cK{BqQ?w|-wrqvyiwEK fvG'u!u7Óݥw`9*r>>)>l t]QW$iCYxƅPQяԯ?gy3 s'1}ϼ1y{0=2;[6cTP(CI'JAoa^p3:f-)MM0~㤸$Lr"/P6T>gps α$:XR"۝{X}+T^vOY&r:y^fa+P1rTQ~KR͒G@5h#~>O_W诤$ ,>z[_|=U"ֹ̀.\:(#3?LR\"E{_aluHil KY1듣uqT1ÅQi驔53Ir&PP1NtNZ*d6Bf*l96q C}&gS+|;2sc1'p5eh]ۘ! [g-Bb3*gCnFad}YӶ;2M7dQ^*xYCx`Z % SD[֖X sjqni,Zjt΅s %,b*X%lW/p~5؜=9&Jd'b(Á֚9nw,bsNls5gVy ,l;>]lxuث{b-y+oI8Ǧ=8g^{dy{w@)54/XíZ2Tϛ"T':CN9c,)!`730++++qa-US8Cl|79֎m`glj@ݕ*n*nV^^ܟLݟƐRIv}:)[W`Ø+L7VZ_e8;lev+6XL)'ZQeU .H8#M<<1h axF8/9)BdPFɧW>!BO,67p1nS[T'ST@)fl3g s_MekWb@ܗ :c?S{7ث(3Eb"T#u2Dzmɧ7*{f9*fbr鳊Y&YUXw}0 ׮IgdFrpZS ֺ,[fwK(*q:=}5VE?69*48jDv_W,r"o!}-^g .ⴐoiņؑ=*h<؆2TRkL^Xڌ{ʢQ\ފnA[ym/zGΞK*=gX9+=疑EOjGf!"00۔t А6DHuU`e^y}4n#lϸ \LIegkgw:0~~ֺ7":Lp093J Yg{a]$*] 0%5sY)7F1ʍQnrcXGn,2u׼dXWf/du7/i~'_פGx8cS^0ɋ-|tyMVl15kv5?XQ![Q[)1bJwTze+;+QIΥ"Ϙ{rKj-䇙6Ks} @a[#i$ߢv%mOr}m{!$cSW[㬁h;j̨yzH].d'7#ak1 ⪈)83VC'õ&-V5YB0} v(3ɋ_Eg|U/ak'ϸZk?|˸]Dvmfgmf5Ge\ɢ)LJA Œ7$1 ճL\vqEة3 w5ú' f}*![RmWgM%6)!S0RrGBK-~Fj,6ͬ@E TTKhBczda팈dcjڀrzYY z#F.2Pq =ݾ 9:`'TDޔDD),&mQbEtV1K!kkz7^mbp`ڿv?ܨvH[n3/d^ܱ0"%Q@&90A& $xq ݚVhQ|caDiQ+I%pd "Snt[ÇeC;dd|ÒWϾDkah<5HCmfe;nh)nG)%ஶ8Y.)5Ж{wmPS48Z; FɗDdEvӮ\ O%%m1PCEtL7of^H_͖jÜakb̻0aJ/v9es҃ë8(X-ņDupHg$Be~,OgOkðB8Qn NeKc$&֏O!Y(4VGGc?b% w8`ל$[dIIdIp>/߱n[^b.๝=w`W'4 ؞>_ xT oy#^$R [bֈw+BCά4L( eZ"~J +rYS0R*۞Wr5D,֜dPu4Gf6s!)}=#\fHZB~3JES ?I:?xڿx*xS< cw%$NG$YTd; (!Ïx9N9C}4CdJ@Wp"#fdvddا!m%^NͽڈNRybNP@}j^-hEZk[WыxErZ6 g/.kYyϳK1%W}q]AkUX@tޞ R:Nw~]԰u!ZZx$.}8+'1U4,c)d|sF5tBE|ބ/1rF15ܿ;L:]h~ØTڏC~jYAK BWV\.ahu}y^,&l0s"}pIdF6]A]ZL-dqD9igo &lF\q+ Vpߋ'n,#,wǷKUgDě) WK"] ;V2C.S/; 0t)8kn Ac=EEL׽ q_q0^T){I_e,qU$o2W\"X-ZEA[>>A pFquALxM۪aeK ) 6yERtYR[t/(.X,!YIdٟ?\l(ChKN{Wq0lj8Ù>b E8tFÂI)U]dUOƋ*a)5bSO&_|Q|lm a[(b\PQ LCF.>蹭y㡣c X<: Fn~i AJ5m?%ljqZXRs$@~brt SeGF@~zC[b^IUwYz0d˪|![%0X\.{H2eb^&ѐV d,oш_rң@VLzui,G`bY%Qf =HYi<먔5"M)I!h`(A_Z-<Ě@ b~&ԤԸь.wvLwv(Gs>LꍨC12 ')QGUkU2!; ˶SvOC R@l'#вyrPձќq43/R\3U*SKO)ix%RH4O%~*S\"&K_$EMb9FCyB P"O -,/uh6TF_s@K.(H@J?!vPT_d⿩FӒ"bM=-g]1RڕWd362Lj4ZOol-$CndN65?VxHqߏms芄 e$.Z$FVb9I:I˷QPA*PF)o%B2^OUHΡWˈ& LTSӛS?BPtYJ %#U6Gfu "6k6;xKXcG$;#祕Anmd!g(>+C/e I$V@%(q^EѰ[||El=5eE(w2܉7,X*B $$Up(9#rZ~# !wEȊ$ËZ8I1Ĉ,XbȒHWxyXI1 6@:54A+M!j,BsԀaM`Q3,(:`77 EYHqS%*۵rRA$GwTh7FE;*ڍhwG v-M:N 86OUG.cn~Dy_ߩR2͢uPWyXc0LT,b,eAlAp,P+q V0N"p":- 2']{?4n [< Gee iqO闽g_E Jl{q53{./$gZ|b4Tam`<˾y^dHNJAD8!~$dbLcOsTCU1Ӏg=/&I~*q1qb?"V*x*FjmNxkI*D"V"{EVvB VFeʻȐ?'qƟ^d+j%_2d?]ކv^t}ӺV n`Szql2d?r:M>ZfZb,*=7u/홌߈z[9sF@ i :^X;/Y| Xދlq% j.@(TK4\ݩypq;}DRHWgB~i1)i1Zw@/p0,^1bLŘZZVX< Hb(tBS/H%pl"0&NjDII2feQF$ 2,xrvjL:kgiIK׈nax_[x!gh.ٓ-}Fߋ{?kN+8vZe B-5Q1p6(6Gv?)j/ղSԞ -;y<G '0!A8nq, vh!*Hj Jkcox{@ǫ*@FZƲY5]|*NgRo.ǛƔ8PTCQͷQ5L34R - 0S/ѡ{""8  ,SʄdؗL(3}@XpP` 21$ /Jv0,K h%!4Ѐ@4Ѐ7A%^9OJ+3#MUD~JT}'@"㈲ m{d+r|ok[r}p$ =3qwb lYgkq ge36 ڊۯL݃,;ؗvddk2dF1~$[}L98b-WPtX:[i)WuFY%n1 dbƍSe䈔HcP9+K1ÓDBU!+qv~mMMZ3i˄: [Xk3 X 8t`J0JX^?@g24VJP"Bc%y"5c+͵qtg@ht4d 2ϠZ!/2<vE(~xΟ IBl0~XOBOV 1VFo2Ӑ@CxLR*( J!JT'D![Z>cUB?hd*!3Fhp |o?u>:sٵˍёA fJk/gهmlPd8nr<߻Tdk @~kE_4?eO:f Rᔪ{mz3ޜZ }Sh%D NRaN)AaGゝQ# ;SM7yqcwT8cY g/ /$g%ta4B/`DV63#1UI[XN`{ȣ^j:2A SK&wTvFR$Sl]0R`tTUVSY'U8՗M $IX) /ID{ J#U\yJZ[q.g"^mT0GjSՐ`+R~Y^z."ST6P=CUj֨fCR q΁Ph+NS3(YO'M4iԬ-+ 8)~yK\T6@8jRV*5ϓA8JЃԃըZmT0`h$(oҢ>}:ꈜ2~:yӧBeʌLUʜh+DD N.b$U4>%ԵꀨP7`ˌ]{[!c*{M)" [敩Y,bk }1%ETh_A].2RQ_/BT8*iń+M*]=F5i~ ]Q:sz6i!{'(q%]1ǂ_)yoFkRvꛩ ?~8|)O~7cfjCq7qyf \$JgoWR< EȊĨ+NpNHN;'VL3|@SOK{9,_ߩQ-(ٛԚe%#$ GrKT d'Y`(BV[)Y2dR@ARF2SK)#HARFpA_NY eYbd8L!g`eM`֥V) HY@_-9 HP8!ZKD>`f^{ !# X0H2 %dG`#hyTF-4(J-[H2J }{-o}ΡWSfPOmOvMt rftXkNP2rx( Qџj6/msK!|3IԎsZ|ooRF(d`I9r V_ O2dN59e^r]@|!")>@&r=[1;Ի(g7tMuQ;$w|&? P B2.&SSlPQES+>\JET[!^bx/,ZZH)ʐ2=&jQS$"+ X 򵌮rVONz"ӔA艼H>F3S~! :8vJ '0p感S6|%(tG>0+{U׍?TFl "I^"(đ&HI 4nLo #8A$r4^e <Ẍ:VGk%PyrPUz؇ d#**62 /4iL0XMcPD]`U} ˽Hn4JdN iPQRN!pP Yd\%Y%% }?fM?WMҋcsF!S&ߨ"*b<V$D!52˓0D9/D2O//p+0V1ԑ ğH"tB?ޒh;U|.OtNq ^a4q֊eE6Yb ]iX;P"yGF=#^OT3-CA5`8\VS[o,s$\שJjQ)8=5Ed Vl}\ f6|}TeۭPwZVV(\/\~ҰOAݣ5x^7bղ7UpkeVoE}z*/H8'~Q#Ks3ANX :,Y@hދ,$  -6/ÉQ́!BƼd+&KȌuvC4Y5%Ui^$A+8!kC'` /6ʊ0TJU>։=A 6UhV ZR mJW p~HVܓuJ ~9 P?ߩ+O)\W~U*Ca'׫NX Ct'µmV$v_@ȤCxо+bftКLLqaRQ-%PTzTm)]k>٪By&Cc+ߥ?\s_]+fɤkM/:C%SX:_;Vؘj" (ﱡg_a2>$FSHT~,w:>iM[m"=ɭkajn5t؆ څ]o?J3#|;Şs_c_v/v-b׬BBi)% Hڼ||}_-:\ͭn+e5g%[C~s;'Z`]2#(E3ዾё\ WS),*8,_ߙam|xj`y(j!rQ_,FAʺro9h4uMŦRwimMceAs`?XAh@\F5+Zw-ɝ>Ҩ"M5VV 0}E7ViMtb!,]e 56~ZƷ#yxXn-2V#'~XF:((gd5%@zܪTGxԈ冗m؆Z53b7{cZYф.%5j.k]lwx)04ԙ뱅z\"9(,OkY]V˕73K@m˾gODOhRao yQZ #qc!0ZH4JJУbA}vUpC~߭}4*L@FխPNNKB}/gem *2mzju08ތުQ70a޶d0֏ɿ?%?1|藂Z11m=mxtX̷XDPgΌ2\6GtRAKypwzru7}K"jP*hjEHm+Db_ =緪ل>vI7y ckcV̠ ~`&VjXhcA7tߔBSg>6~px4bҌFY{?ޠ |&*=˺4A׉ lEɢ\-C"=zn9&+{,Yz/i:ksx;,e 1pf+禆Dپذ?&V8&`<Dbd5ߞl֒s #'%b*Vpuh[12m[E>=g.1(XW-t(JX+k^ n_Z#GQrRWۺGlP|jЫnmCj*(+VK$ѬJ݅ Tqė/QLZV+JԫJygB= M;]*jj&6~;J'̚g7]4TΫRk2lCS)K -鿨g-`vz=Ұ=q=׷[%Ja_,UkMw`(ŷFv-ΆL> J9͇ƍDұ;B/6݈4ud|%<`zo[7R4v3MinEfD|RHKC'f|a9R嗻ODpbU9:8WWgYÜ؎vۖ|x[+[ӊe?='@ԍ7&Bw7N wIq㼈.]8E5t31tQP EM[5tr--L{}BX/u;YشR ZZ.7XI" biL/ (KZDov}5t!?pϯK ]'gfch`ӊzwV%=@6J]5 VͷB>XEvi5ӫQ{twX ftmTF̗6`O95ަ) lVicoF:H45,DBضfjY+[cJ]#fw=jaFn;@Zd݉KqSvZL,HsXI6Y%Ҭ'zNR" >v⟛FcQK3̨ea)[3׵OҲq]*V)(@ 4F m,v.nZcRVMW,hsPz̢k3Ќ:4K])Ag(Aj$3] %n8~^BW ZCn5qE hg69XݒRrM0#E#[u(ts<[}GԱ}A1妙Ѻ>>7μ殙eh] U$nwJf(v&7k:4D"K)%3[pE5} akaJ}CKwӋ A["VQ1yd߮Ҩjz.A\\EUC2i˼ݑ٨ͼ6/40'T`~A/?Rhca+Q WPnoWkYGXd:ʟVFP=⨵w! V'ױ5{mLf =u=(jUSۊM/9~(9c| e>5Q ~|, Kl.ejd47( ?KXꊙoE w…Gy> hchv`>z\^ȮPVC=N\P3 }+aïs&ڝ׫!~=?BK]<~Axf+>aM"+qOgA ]fv±Yh)ood>pDջ={n؂B#T0ު9雈};={iq5v?\5zؿS1E{G^1epXx F{{g*/u|N7V fyc0s {:օ(\Lռ/%j8fC ES!)fO\4|z|#? YD3w?z#5#~Qt>݇eC^!n.jbޥgm6dH?xWo)ܿYxϮEsj?/[}.[vGr,iW7ՋxM3ąEV\#?\}K{_k3^;;Gݛ7^+Qq[0Ǟ`?Y.,gV#LgNg3̥~Q\3>3Τ h!;] RB:TLҜ]wsZv6fnuV*(٭_ٽAϞgOv`~vyqY.* ŜUߒw 3[f Zmne?7l œ1s\E`q NWo˵mpci&1l>eOss_\oV0 wg'ŧypa%:u3fEnx{y>)g*w/zc>_R6]Xg~a1X.J 8 {Zh oNŅ텇Ԃh›*<.j`vq|X wspqbi1|lbigwV[*-TsYxX89|]v16\/TY7N\*&RtT ,/zd5,,ヤr",Enem K|cu%8+|~倛SW. eP_VRמW**+3/&zWoOUe<~*W+3"fmu6ֶZٵ m`xwVF }@>x Tj4Rzp/Won7'[sA #nk=pyZ2zz~Q^8 b<+(q樒enޢL".a8[^8TSpm,HvC *ct8rޭY"M9/"¯k.!gyn{?ys ïW"ݯw+s^+en,W*|+ȼp~,o"•.'e%~ Ey9nNab4Vr[i$G¼y&i{+qB/ܔXnKΡ/mmh?B_j]mG0sǺGby*|=Zܬ(4+lE޵D.}HO[ه_ہJfyLɥ_o掷KGllGS;g+;vJZia7wwIbWEw͒"ﭟDnq/49G-ܿnnE%^ʿj!|\bKx6\2ӫhHlؓHR9dS7ѹj&*G`6~&c ;Z,,,ǮR/޾99~Jy߿/3<|tcu<`A4arŠvvusZ^~?~LG}hʞGɫQF9^:,o?#FFS,I+$C+'e9‘ӫk=}oVŷYnٳS:n\jg2糥DWXa>_;2cjoqٍS~witϬx=2L9}[c6_+{[k^]GmMQ%vpqūɈo-cdрb4>!>Wa!*'e$Wr;psw} 2G͉rVx| ]E7Gml񼷕?m|5ɢa~!>ߊw *\;k!'{[VGhۋ>-|`?Blњĝat,-\,ErVh[X ¶xD6i%?iI0hjs6LX] OIr/`yo(mpy/TL/VO7Ӷ+nZQ휸" :dpXSú(Xk?ߋndpvG/[7 65L)Σ%Y|,^V0`Mϳuek!_}00Bz!M0Lj'_Vw[ر>e޳՝}۶;̼ӬwaPQm )KJ3_>t*ͮeq. S[םU.] %ҧ+ gKݯjm,uAKޛh6ː-E*˫;)0Wz{7Now)IfBt+kaC~iM*pqWX{]]Guf >YyU ]Ut [ϰkB[UBi9UMsQۛX;Rێ 0W8=| X*%? ǡi<=p#=ma?zr>n6wyt??.nmnF*,ngM{yX6A: vy𠾮Muc2#gԷ'8~5S%E׵AvNC%.0[L쩶#ؚq:K?E M/<. \K+. y2 'زRN׽+qBpp66Up S1w^k"n/Ce\ծp|:<=~\5m) D`wѢ\AXGz^ZԱŌscwiiꀊg wx5la +m/Qxv:dsIhMNpjMk[טs)!dhW=qL5~_N?vه6ߓk>y͑-ge&@j4 ċ[@0P0枳zN}ln?mmS~6\8dŎ*[]V> PpnC۸6xcWD|9Иoy=2KH>lF 1 ?ә~r(\)>GWQ Րzrek33by&tuhҞ"eѩ߮iz,d-OzGyUCR7k3t̘Oė y7:9d}H.Y ,8,ɠuqv;r6(]+[&LꣵC  󡫨ޛH]a- L=վ733 0|00IyaBAh @chAl1(RܔsnmOﭪ{rO]%0\f>qG&6mD3Gy+v 73+ly.Ijaw%7GŅǽit Q--. t[FsoWA> $LZMi w4!O3Ov\뛲=>UEǷ`黗 blK ġjer`%t^RPgV/jŀ^YX#ɏg"eM߇F~oŻ͘|֜.F Ձ4̮2ť&q}+gs#ƪŀlgrn6/=ŅX)[l"aMFI(XR%wG`Nފrt*wOW| O N):?A:i%"NxZsۮmX/&io7B `폈׋+ַ*ǕʉHsJ=\>% quZ_)׮)䝕xRHMc,ŮǓwҶ9<vLYrl+MPv87r[Oo5F#;J>=7?]6s[;\;Ņ=tN*RZv ]>f.JTNJ}b&Q2>, hڀmcE Y|q|ad҄kN_y5(N)@NӥwŅˍb,VFyTz_6@/{E]vnu DK6&k3/Y8/0 GiǶ0Fbvv|v#oFF㵙cnWNJoǟLvܜ&`EZr4smBP *) !PߟoGK'鈵hFp&~8#eƃ猪}UI$SVk4tW,ȩVU>8U%wј mY<>ti'{|ne0ddxrs-R]XS`S7@6^)OT{So jo4]\LDEhTn͙:,yKlJO;I0ɕ}f8a23q9! tx S6^xH"nȺTkB9;sK>./Y:.? h.5a`<`'sHRpY4?j6Z5Jr[12o-˝>ގ3,fnoCȧbv4 ttu*ʘ:=kر;uXᲓnP[ɕ#4`:V8(Clji}#S!tҼpC3>)]rZgk*qf*Uns30d_׽2B;x9vݱq,H<*\:-۠N3rEmPGidAE0dGu}NRT,zA-2+';ԅ*Ȱ֠nMMP[<(l#FTmcPw'5ve0BM<n᥍.VG$ r䓰q~4[XCm6!P#$!rG]|9\v#ٶedS쌟>f=8`w^3ճWϻ@#hax6rq^&RNﴴN^ʭ7<.rs#]qb)Lw)FkN[HO;nU&s֤]G+0G']3-D [/q/+Ԣz0~Mtwi.'gW4o *&fS:u=Qw= H:AvFfEyewH8|;mfnf@FJ׳tFiDi4`)Б;T*w'TF*1\)l % U*-v9>;&us;'TT<^f8jvD7 *#PN,88j uO\Aը$'<A*J6bK_xކϝ?x>ѡ?:6)^اӍ<8D>lRƔצNgƷ{?s&?Om]G:~2ۋf;cfQXyB1OrQ@d̓i2Nu8f٤iƶf>\D0zgsFw֡8$Z[Ӊ35qҳ,ccȤݪ >ݪN$99 dֹ۬02‰#$5$.eq,FNzC[ k菥I;W(mR/ؼ Mz}y^3?}..H#"J-Bdd__{*DF+R:^hlv6rӒ9X,%?w$s}bk{F?B)tWuWkO j/H(І%P۷s?,>/z,U򉭏NT477~Lc"41x!t5t>\R/G_V'X(a(A8pdqI,GЎ#0BI[[0Du FRq똆-/g/;6gYDB$,(UZl &A9z\W^k.+8-AUxʣŋE>mZCFpK]Ø>2We>F+Pk[xTL_Juݰn~F5nȌ@GЈܬX=W.ԝ]T,`ǯyI7Et]hmw8Oqѱ2][@ذr3#y@ FU8Zq3 h[Ť51[^w64?Fp2GKQ!}ȦgAppo@)s&+t;~akx}[H+9HCl4ԍ֊J?Z=Q^g Թ0GtvQ^zhОSPk, =wh3rCS.ܕ`{tϤPX:Ўq`Jw3hA(t?тdփSҩ6NUH{wړMGtk`8{8?>×C{5[lWߏ}mSKS``vhcc5kv Ƕ?E{\[޾aW}H^j8QNS9Jt>\>!HC6t>\>3t>\#ut>\>DER{L0I3=G &/g(}=fL' |퓌>QޤwQSM>U@zm/@)w*Q.B >#1NiwvCW>y[ߩO ]~SUg T -/1䋿4D3\T{aprRrE,1 vbf@iw]Ǘ2b%[QrėYtPT[ %2Gk/M8;{@ ]/wӌ B5y9+ o7gkUx}tWOт&A S1|sƥMtz'txw^݄%\VV/p4V~0& ZhEK Z>ivEv1ii;=)wǐ'T"R:qѓ(wƝ=3}^GtWAwB x ݩ gX.T+:R o Y}{`]PkqAtG~4q۴/U.af[m)K7B[MCpiY/Ai }}kLw ?{pO#/T]we1tu2I(zR} #A~ El3Nzn/F_zo Rh?UͦbYHpBa_~ڂz Zo [ D!^:X E%XkkG?AID<- L5fUjec] {u:M)~?{[ .w0.g"MdV[}-ܴ l~98gi;#Xf^AdE/;zgk̼vNJڀ3}Ltfe=O$@f- ScyۙzSf٩aN]0vz  "!>9uAB/;R-߯ [h-U4;#P)SwHzG6uc07a~@l-zb ߍhm9#C=]xZ'\^ԧICFJ:Xtw:KĦcCޙ0Ħ{?/OZ&/@Yp5@I@s{i^N-I>R 4I>rޗmAHdd1om I@d`h#^  ؏v4fS^cǤѿs+4I~ocmK/ŏ(ּ3fbg3<' ^=$vE0v?+"!ݲҼY{NƣnuNZ_kkΟgK󙗉By{N> gK\U^,(%@ 9:h|]kRg˒j띓v\^pxhs1?:s"O՛>gybo[`fzn(mmz>^/aDWStOk7MN >  jh}nVz=a}nXblHs3iGo? (m ] %װiA'5Օ8Xb[SnRg}ΦJĤH%yal`0}n Ddq~q>a:/sb[Ħ>$eQ>ܲ">gVF{b_{/>^ܠ:݂/k?ӓ}iK}]O?NkwBL:A{I:u9c"֑{ :UnRST:Uuɋؐnu0OPVH!))^Bz8;+>GM ?u s!:}GN}gnOL,*m4ots;`N_Zji)@qS6 n&gRD&5Zx&S1\{.FƈIBS,%zp4`|q/ ւ|o/`$!@"G=m~PD_3k3pV}8ֹpv ;mVl߭~[G:B\)f9gq._dI]PD%Fv eegz)ڲ7Ra|F#por]'uP).r4^1Z ?HH|熼b 7Qh_5gq<wIi+.G_v_{dJ͇Mr_D;ܿHܨ,PG0.ەuns~_WQMٝh 4#fistHv~>GǗ8aS5=.̴v8/ 0bN*:ص|ZCf R.tN/oQMN"nyi.Wh'\JǤ@ݪ]}O-VnSԳO6me'*t.} ͤZtPQ{hefl.Zv9inҖcڲ=F|DM9%Z7SKI kGJL{#`AeJ['ݦ$]#{˔Ġ4A9$&훒)h1EiB'B qXa:0R+tHBWs.g6BBwXOO6 SƲ끇U'wimx[hoO@jEx?$1zUiA{vNð><;yࡿ4o'}ic"tB]x68K8K#އtw琈zo0ya<#VR C#Hq=Y]^<îĴ<O;t{?п7f CgjÈk"fg@vXyqLCzO;tFpaǔ_v假Jq+2.% _f\}ԙ`7bHa6'kvi,֥9V6GknZC2tզ.Mu= lfq8q:doeSTǬѕم4{\= |z<{wnLRs^ϯyi~ï1Q=oϷG.~z)+Y~vg=VƪkŅ⻑ͥcc.\ǚ(Hco#%KRMgwvӉay71OƔKybHkVT:oGf^vb&Kꈑ.l? |jԝPVS55wux;6_^t/20fvaU' Dc={=;̔95zw9|FkIXŀ!9+oo1K[KOa$z߳9HmEk'N*jrd>2`3˩]/0s\U>vvEclVƌ΃&Wq[۫%JU^Kcq̊M]17^4/6Fl0-I g 3IRvԄb!mVF\Vh$ɱr&'kFW nH7}Tn2•ynTϘְ:I΍W+0m5MNd 2Q*xxV6A7~~Hj\YQD$˳!_"]g/p6v/6vHh;9O`3T\<%nM B0S;ߥ&soK [1ӧPkcv4ūi&ڋ8md^|YmTNMrqs'ze2<0mmj9DCQ@1??X]sx_K 4u/A͡d킬ax1Q8!7FwyFvtq2w9;sq1A'{_"/W&~v@KLz8O42ƍ?{6e~E#8?޿0L, tj&8IVfKX&`E 4QEh0%rrF0T) Ј>I̤K)*dٙw%?ܙsva9b՚Ff ]ơ ZFj+ iX/Y&]9\?ԕWML{R7Rȍ/ ZqMX!ѹ%p1aR722;Wa.$-Y)-_e#b&M̶e*w81m KS)~|ꈅi.&}4ݓ!V wqbkG'􃡹 ۇtىɍB8b’c&yDH,!h8 6!Bv<dbQڤ_ؼNH%2.GshSnZ$Eup.Vlj+Gڰ-ߛz%p#"a $f\z~J/Ϊbd dxN\*yb쏲Mf`_,lf&n=S뮇xi&Yd>9i/ŌX;0nLk΢F-&Y:N|t )VL2sJ1NZ)|7M9?3  W"^hʋ)^h3SZд~tz\-1oO-mB'2MӰK b @a/i[c]6uƽ*#ʴJLLwV*OYKĺ1*-#rZcf M-9blLZ9M0'e#k.R[`%g/k24{qxjA9YٺE* U\\ʚs0QJI5z.;&rH inDۙtkOW<I6mM'v쎰O.cs5gjgq[Sibu ^ZeXm/Dz=:%W_ܕ r81-36^7&r2uμ!9C͔g)-D2<왙FsdO ,MaH5N=1]->?|A{^쿤5=&MZŏNꒆݪ7r\f2;4i~@M mnL7U bVq2@mЄZTn FS@ d1!?׻Fsysu0Xvl4xzxxer[E,6./C%I<)YP3Nlj~ZF7gŷ,!% D 2avzx. 'maH4-6Rbeya xw^zY \U̎GUnK^KB"EPհ{_Ƈӫd .ãE%3cpbcdu8q^sé9\ٯO>G.vJNJrʹ?RF')WP\TuSϐ"_BҋNG5etx}1TzZQ ؾE18haƸQM^X7`^kyT7^Tf&:4!(x_''A<&C6Wɒ"P\2$&5 heZI< @# w9ux !NZ1S^=L씧K;N :wPtkO0 ܤYKd|QPJy~]\w>kPm&qZu}F5B_: >ϰ qRiOYu:֯.҆qHCq?~{N-;&g^ԍa!Lly+m@^3Ig ˴ݚNi͝4M8qd}kIQB"$1R]c@g)UcnnQNԅpQ8Lf2 }hVY2r=9Hdbh~e '5) @vL^u`ӏL;-P!b] xbb{J5kr *t5g2܌infak6h,'6gwj%pb8҆CnaydJkZhoFuJoak`hNri9Ījͺ C= ɭg>vyj{\ ZkÆqJZV+ژ;4yZLf~nV>n#B;yDD׍yc`j=%(fK{<yI_ zG3N"_-1Yh4~Ť] FR/DIe,?CaRheJirm 27.X?^4|Rh(Е,gLeA,+ .QKtz}!eI/5M)9IkvAH a[ U4^jZN*G֚`cDMgLjRڙr;Sgky){4nۻ7#y+ZaBΗBxZ&xĵ_]MnP*aJ4T$4N{O9Jo+E}4LZK@Wthnpz ho M ,[+=\V=yDW7/57῜(*r<&FCer͗C,_YY(ekP q'vcf(ybҲbKxg~f2o(ܑ@s@ (&*7b 7J~h#s)6͉* QrCWqd0Z/ϱ/ '>p#Oz~ '~곟O ~3؇GO}?I ۇ'R3G>񙨴T{/}Wt}~O,(n?}t}w,O?~W]?ٟć`>_/w33ӆO¿?G?ƿ룟G?#_ CG|/Wp'p>o~P?3|՟|4~_wÜ?_܉,͗᷾O~׾'G_08?+!L& `B0!L& `B0!L& `B0!+0#nvi`޳CN}7ޗ{tHG>?Yӽ~*v˿p,pwx?//|`窿?8?o/gёz(ON?-clΟ|w?Ŧ|𱿫>wptGД_|ϾM_~W.?{_|KG?o篾Wv;}~_?z;y:l?f_џG]E"[f}G{_Oi󟢃>|Wٯo/iaU3|__/V2t 1Ó/_:*L ޲K_΂:s? G$?#L\f]ż[fhB6~?~茷ÏO~S~ӟ*޲§?1}m@ :< XXGW#or b j6뭗F3f55=E0Ckb_Q4Dz+Q*%$ lxnOCfY*y!UyeVTOˢ$) }9E—I /i-AW `F7dTAF*cTF(uV8w}rYi< <g&5)A)ZwaVT j4ƤU|{5 iIy[soyhwIJ OW/xUH}/DeRZq̢VFbaTq05h=³ieD,ENWDfS YVXЯ(ryҌFU؃|Zd(ˆf+dEf*pBXojQ2l?Y [M"v`U9p o!*oU2F`GDP̲K< j>ÀdJD#0$Qpp*v2L ćɊcXw,# !,)&f(e^08v,Q%iN% ݓ`P15`Xdx(2̸$rVS-eX O\R5l'Ud @bTF2ˀ$35p^E'D)3) x,"B{`3K 2J[h#e"K8p*oVqrQx f,/+w$EIddEE5vI`-r((kA0cQVW8d}0&򸰲((JBb/< %FCBp]آSX1T~7_[CۏwqB(a@x1Ǘ83eϫjȗ%J g恎Ȍ,pШ Iy5_7/7旆X7zi<\ i7.kP?r(6b^7&7UB-|eHUv l|8 b <+, s8Ӫˀt@| 82`5_۔%0Y*gKfdnzm4kaDy \2]IZGImwO;PAC H!"꡼%fN6d@̲|MU74`5%U m dQer*Xd贠hDBuP x*eFīD1@$^< :bD l$EH8Hj(F3*72>W(K(L6PUIUҌ'e ֞c iT UPb2 1#3JSfEF{y{ V8C@e $+2 n8T`CAHPa)}A 9\5QzCTaqV*s+ *bU2< (ļ/l _H #BePiEӯH')1*fŭo@X_Zf b9l dN'm#ȜBHK:hTAu"%v%Q_e؉Wi$DDDIjDbɊ(XyI0A Xˢ+ |)+E.h~<-iki 6wVuw,0{}yL7i#n.ƚy,RK56( `Df~>\56.&~xSo@wHphWWqV /d/d rn+_Yxh.5t_\k\b'oط10$mD'_-P}p"8ԟEd,IUɬ&p Kz "3Di6Kh &x 24D+Y@1(,cAͣj@ V*&( (C_`s-C~vPݽ)N $JT\VֺR =<+IT%£ƒ؂~W8-nC $o5Zz/Qot ~s }0;n㉜VTv@`oJtqdYvѬKce81U'" 2um]a1;Ʀ ^)̥~Mc,2| )jT57 :"#ښbQ~Qҝ-Ewx(J;@-=6/K +/*DN7Dk"zۇѲ"vQɩ6"C6^6Xͨ`8E%[-=>^[we[-` X#]UǨ$8YXͨ ʣ@_?6Z왈Uje:IS J2U!]ĪDX*4Ȳ%Ypz!#K$Kl5'YqdVaSl8( [KMTF`U/ P/ =Kwh-N`RjE(e$e٪@F>:I$ Ɍ01^w_,31b3,$1 rzpA:dh"y:2-RNr$OAȊ2 1]U pD3Өjp@7贷'X*2TTKJɲ! z%i؂2"?vt$f1n7 ^5Q`D4QI@Ҍb.'B֣yQM0hwDleQ45t)a&(DlB46~FU|V<ϣF@E# 8 i(X ? 7d8x=H(;6DxRQOl$(N^ #J >)*8^9^f(ij 1 e"/"J{ *C_Bi=I¤*?IS5%Io* Uq%`eD,Nj((<)DQy0 [\բ`B)ƭjQtb_v쨁fGX# #UI HbJDp HRQ"_.yQ2]zׅP^yb7C՛ks^w<0%_/7*@I0镘ɬH1D7B e[mF-XOjI .J$tȪG 'Ĝ!Y@/a7)ZGOL"+OAު(7悠|WˢUPʄ\TJ29(2,2W;c,3*_$gzMLz ^ f4M**jZbCDҳ!o238ͧ\t:K_s(rY7c(aՈLzEp#RZBj)FBG}0*>$D@-aQt12 $ДA'UB[b 0@$!-+i`U 7ʚ_,;zErGH 'I 6t/Q6frUUΦM)'UL-%V:IH2`RHN`"DIATV&~yFXl"đL9!/KBa  yt˘l.0`+J+)tY0$+FLY6.̠:2;`BrU@kHf))Iւ!I!42"Z|@0m<<4G4$-Jd1*1| B&B3؄@_hq[eUâ2+U%+KWLBu+XPj6}} k]7묉t&"m2+a0+A 5|Z&()0Z+ʊ7aԐ*I+ffLl#jފC/ 2@]1C1S&z"2(+^cD"!Hu,2tG A*yCH4B V̆&|D# 2/fѾ6@=,9-\e 2Ћ iҋFR'@kDW0S I] $" lOy"̊B| R!֨1*I^9])H  (@ } u(a#"*QET$@2^VW%ⳖC,h}$-GY,;241=$aQE"hS]{9 sEuY76jUG0 z;ٖF~:WÖ2:@I[f"@k4P T󦨚~YL6 2 w,P9F-cQW9XqN%ǎB VlcFM6.Bu/YEʒeEIT,(/ BU9I=)˥8lbP6`E(/y~$.Z0#0hP5D|>  ,0$f7_j4S)[_5;UPѣc1Ժ~"K ccr ݇ endstream endobj 149 0 obj [/ICCBased 174 0 R] endobj 5 0 obj <> endobj 6 0 obj <> endobj 110 0 obj [/View/Design] endobj 111 0 obj <>>> endobj 108 0 obj [/View/Design] endobj 109 0 obj <>>> endobj 121 0 obj [120 0 R] endobj 231 0 obj <> endobj xref 0 232 0000000004 65535 f 0000000016 00000 n 0000000174 00000 n 0000042784 00000 n 0000000008 00000 f 0000356296 00000 n 0000356368 00000 n 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000356558 00000 n 0000356590 00000 n 0000356440 00000 n 0000356472 00000 n 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000068464 00000 n 0000356676 00000 n 0000042837 00000 n 0000043488 00000 n 0000044387 00000 n 0000069392 00000 n 0000055904 00000 n 0000068656 00000 n 0000060385 00000 n 0000068771 00000 n 0000068896 00000 n 0000069020 00000 n 0000069144 00000 n 0000069268 00000 n 0000067167 00000 n 0000067313 00000 n 0000045286 00000 n 0000045612 00000 n 0000046165 00000 n 0000047533 00000 n 0000048898 00000 n 0000049830 00000 n 0000050885 00000 n 0000051441 00000 n 0000051999 00000 n 0000053292 00000 n 0000054546 00000 n 0000055119 00000 n 0000044451 00000 n 0000356259 00000 n 0000044721 00000 n 0000044771 00000 n 0000063567 00000 n 0000063890 00000 n 0000065250 00000 n 0000063631 00000 n 0000062156 00000 n 0000062590 00000 n 0000062220 00000 n 0000062092 00000 n 0000062028 00000 n 0000061964 00000 n 0000061900 00000 n 0000061836 00000 n 0000060592 00000 n 0000061228 00000 n 0000061292 00000 n 0000055758 00000 n 0000061164 00000 n 0000061100 00000 n 0000060528 00000 n 0000055694 00000 n 0000059153 00000 n 0000055941 00000 n 0000056503 00000 n 0000056112 00000 n 0000056203 00000 n 0000056298 00000 n 0000056393 00000 n 0000059270 00000 n 0000059325 00000 n 0000059622 00000 n 0000059697 00000 n 0000060499 00000 n 0000059843 00000 n 0000059872 00000 n 0000060043 00000 n 0000060128 00000 n 0000060217 00000 n 0000060301 00000 n 0000060738 00000 n 0000060854 00000 n 0000060975 00000 n 0000061409 00000 n 0000061464 00000 n 0000061761 00000 n 0000062374 00000 n 0000062495 00000 n 0000062707 00000 n 0000062762 00000 n 0000063058 00000 n 0000063133 00000 n 0000063287 00000 n 0000063408 00000 n 0000063483 00000 n 0000063936 00000 n 0000065160 00000 n 0000065197 00000 n 0000065366 00000 n 0000065432 00000 n 0000065463 00000 n 0000065755 00000 n 0000067054 00000 n 0000065830 00000 n 0000068114 00000 n 0000067459 00000 n 0000067630 00000 n 0000067751 00000 n 0000067872 00000 n 0000067993 00000 n 0000068235 00000 n 0000068351 00000 n 0000068538 00000 n 0000068570 00000 n 0000069468 00000 n 0000069715 00000 n 0000070958 00000 n 0000098299 00000 n 0000163889 00000 n 0000229479 00000 n 0000295069 00000 n 0000356703 00000 n trailer <<7592BE616E403549899ECDF72B80D9A7>]>> startxref 356872 %%EOF doublecmd-0.8.2/pixmaps/mainicon/colored/0000775000175000017500000000000013244011205017402 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/mainicon/colored/v4_5.png0000664000175000017500000001334311765566230020714 0ustar alexxalexxPNG  IHDRe^:ڡ pHYs  tEXtSoftwareAdobe ImageReadyqe<pIDATx t[WOeٲdyQǻ%5{ڐd2PJ,@[Z8sPsf:90 P 4ӆ6]HC$MqR;݉E}idKO4,=w[wqHCrq%E''{\%{XAo\3W_s&CLt=rx=s>":($.AI35a+ryKfMFM1 )1{Xqy*+9jDL99I{}v؇z~ H >ߺtOWrݵPRZ.)15텏}<-ڹ) o3}8^8]8g/?/Gzf9[KXT*5|=p⭿O ~> J?-wZWZ6;y0qBǺF B/}T@l@c})-xaaCvKBoVT61LL2c>0d k4d*6^e ] A!b.isͶ;W^ dO̡?8-Z`{ '쮥'?u&C%˷nݺ _qnӘ|ivY?_vXиC2>v+)`YC{B+/Ϻe:t9`յ otҖ\cNrWj/`ȃŲRP&¤ݻwdje/L; JؤVߵs|WYi. M:, ^T,6}7JvY0(рHQYwU$=v| S{Xز(g"eRK"=Xf{ǩ6{ Ȧ|]5***d ,(DᔖOYpNG=ZV41ȴ$(.%K𥻚P_BޕnkFyyyЛv(je!2I vﹳNJ[TQ!L&D5ۛQTT)^0IQZ Z]%(2g?2]dqۇ*w@U_T@(FGd4,G:96c@rrrX=*AxuN |. :j4~'cdנ€%z=x@P98Wy7Zg |ąq`tC`Ӗl3Ra1硳ow=>o㻾F+eVf <م\F]&`ODa>ۏN r1Bs~oo{4Σ͑3~lX-YL(, }_x3LF7l I ^>؉3z0eWE$uq={8\}[6uf*YSc m>_`r-j:' hd 8QuoD/:JT}$2*+%YfUTM**? ) Hj ,62˟c PUOj$ ySalv(Ӏ0M``Gz'\@u! $.DIIHj. (Wtig!>J",[#}]trLRfOd"T*-B)RCapt @ m-,9KA4+F1dÌ?Q;wގIG&Sa@Da?p;ң c6fyB` OG)[ Ս6aXeݧR#h/a B`טK&IOԄXM:j8E">-A%=]Z\4Zvg\P$s}AXNS DžmˠB@"U[J bH !C%\>,j#c2` RRJt(FS,CM尾U螑j,1L{ ϊjLMJ"2/F$bY.8nB4W8uVZ2ɕnЈ; "L4$NrbzJ %Àa!# @踪Y5(Чos\p A+ΝIi2V8:AdӘ#UfAԜ}1t{<);x:~+gLT0ˍRn"k̋0 <#WԚOdRCҳmcjL:IOk'FŋZ%NzՓ)sK Aw$b7ȰR;R$)rxmd2^u\{M`el7#v>fb5`~FSk 1*)(t+ՓK^,< _C[mKJ*TyOGN09X̌B<~7U^UwR>oVŒ\xt\!N5=9 dE9`#dbcaЋEV҃vdvfOi.TR3x3j+rV\ HHEf oN(} q:wU%H ٓco)'85e |=F9 a(@ J6I[>TUd(vQ/}m>rsMaե6:>q慩I ޻TI{H}Q<)O Yr<߾Yo=콫$]owHwzrD5l[}A"P_hb1E=)_ ѾgعUc j;ml|j gO[ln 1{$[mBP/̝mGFHBEB[?|h9CQ,Dؓ]0%+s߾odctiJЭ aTݻ*7haKb??=T&I̝n#_Uͦ/M T#(4̭>Z7mJx㉧G$)I }'1T$bx7aϏ8'3P(ކ0uPg0~ri=.SxvUm@e;cݍT/a05 j ַԪN-tHƇiҪ:F? |ҋSgqp?ИC}V]P鎎MϸJQRK;7k:27{?:#IsP|-|,RoF{1: :,Y;e6O)1>ŋw*POW")S Ixi 'ֽ9ZåZaN&Rm6<4~J>7e{gjD$M%?s<4 +?b@iE+khI{_v_+%{?9ֳ fAz.|Y=;{끓AIuӟ\A}_|MRY# Q/VHrov6Jd]Rˣ/m׾;./!UvCm#&뒒 Kۻ_ HG3k^<3V{6WϊPg}ϝHĭ_xM?e6L7RU~9uz>1uk+X#8TwS G 3Ӓd8ޓ1Aw|U3* ]Kc^  {xM7^8DG_>4&Q4յګkG5jY\~%șlLA VfxMc4 \wRΏr0s~u%+o=vtۤ<~ f+ P]aƆ\f^cG |ֶ}#۰*lKo;:=9eWGP*V:7H}.ICYM_yb@}Mgp6|QK&xLCRXՓ˖h-yN:gCs_k # p(աyi)99~eSxuvqiAp͞,uܬyp%IkV,O@+M(C\=c^4 _EL&I0@wwPŔ،6W;yqȽ7~" a^0ٵ^ 7us@BP(\iiox9LLz/.90(fv\#{c;oi˷mUkk`^%@EGMV3$&& yYW_2^|)z]}_yKtyokKPl4ot j=Ø@eãQyTKC1]= kt9ZnG&$8u_帢 И*]nQ<\1P@q֚ؿ$Eϣ^l'wA>ߪ~O{Bx.`IENDB`doublecmd-0.8.2/pixmaps/mainicon/colored/v4_3.png0000664000175000017500000001550611765566230020715 0ustar alexxalexxPNG  IHDRgh, pHYs  tEXtSoftwareAdobe ImageReadyqe<IDATx] třhf$HIdY-6` 8!1`BBM&Yݷ<솗l^ 6vsuY1:f4W_S3YC2vLwW_GU7pbHY/q-U ' =^*v $C(/  i* QEUY 2EJ0r93dݗp-EngMAF<#8/%p`̂Q!ۿWss$!٧dwLq_rJKJa,pTR?;i-@8F kAa-)n{wAFT\iܹs-((ܱhp866ƁANC{eP]xX [\L3@3Ju*A]f@Ic텉d4q ^Za(1K![ˢPPRyCc0s 8 IAnDSq1 a8:N ʂ%E(`LmNu؜ReBv:(^|u8xv5E]SA6SϥmxHQo^#szM4GЅJ5Wr(**#T1gMԳHϻ^pS.V#7'$'+kQnBۡtf0GluaZJV%'7h+.g`H`2t+/Y;Vmʔnt5:no*g0Uup~ x XgN^QQ'j3VQ>rVLq]4VY;E1Qݦ/.9ڎ )V)PXX3vQfYJJJ _^[~֟w±Sܛ ZwE<:"l6v.<_ɒ=g |㭨0;C'sWnillt j߶kYc#^&Yr Y:KWT bĥӓ!=_|zPvdOV\KNW:1AAA v^qd5XIs?u_:FXa`lڴ)To]Y4 gf; 0^5HHtҵW3g[f# ʫ*!Lww7 c02`,l,'a?9y",a$^rAvyA/}͐0xUXǜ)>|=34ӗufgNȺ󎕎Bс]x,lq)G|Rrvj{DժNMEzգy5ˌԬXUUiqo7rJIN[H2ú~:VH u`p \n-YJ3yZkT]ެD*Nʟy)Ɨax,X{m?[XJyyQvR4ԉϢkr V7QJJiX@sOet7>}3gxcrهfק^#K`S7; o{ N!d<,@v``` j^%'q=Ԅa!d)kaWJهnc5 xHozxq+ÙjZ@Э,d64OtVg"Lvck.pwj\Vj S lve-PlLң9NilC;^|ެ+k'0B#-Gsssѕ_;BϪ3IY-GdWYd,:QZ5G$U `]0>' [3tIS0Zfd(p k5_C 7)|p}|f_i*.3\91.p F52™tqܒd-VbΧQk!?#A#(`R䐝=g sɓolSvLv$Jɫ>~6MYͭa`#sB K 99L9r8WH!YPT¥ јDb&@aG#;h4F"x"ɪV0U Q ktm(4ծu !zb$Fւc0 ѢMFLGKrhQ KȨ:Wyge&lBQ7I̸Ycs(N? E!ψ%`K#ƗN:*Nv*'Lni繷SQˠHUah9[A"VAbc,o09ᠰ9qK(vq5G\R<ֆpL"ؤ}q IS.}GZ0B `B%q|dlH/?(h@QT+uMQ=S ,sIS!צ'Qb hDNpdU @(98"JCE_.LJ#ozP<WQ&FUΆ;0ШDF:&)JVrp GG$D ҀoY%xGbcq'2on%glga>W\*Vb''oj,0ўĀJ ;A+yH {={1$~_gF&@i&mq)G@ {J $&KQe-oH:\o wwƪ4HKjC~EzE@MQAQE YH 6쟻 ;COo3~ޮCd38達bAHQYWX+QW0G4P;:^A {HW-$AշW_)l9Qu I kF|_xvF鍗aK_9kSH)o}j4HIC]cW+Stpoy1uoz϶#mi@{+_J$hwgeђqr!Y+aЫlanZތ9N]g*a|>R1 <:GQnZ,c(049n<Q,ZFUC;L{XW|Et9{ix.?C0Ou֕3;T6 !ʮk.Xlv57EY[6/P@R3!]c|X?o6lBw~z9]mpFE˩ۖt'.p]5(EJ|ɏSUJDJRP/,z MUX/ b}HT,,tt'.z̹Q&SyZ6Z^߉CKX3>z#@rzd*Fd*B֓z0Nka{8wg3w Lp>дjc7M;8:@ޣ?e;J ~ vF$(#ić%2Kٳht(z?a{!cfC?NH(f&vi = |ϋ?#RilxdF/> ;L[Q/qØn.d+m~Ӡ{ù70ҪM\%4|}=M7sud"m0 < gP|hB*r<=@=_Bͪ5~s'3E3@] hniVuténq3 ;{r:uB  K. og_~)$X^nV52hs`v,e?S=ş|{;E])E^&dԸ 8Aqx嵫+{a{ .\&!@$( L.fm܄oc[_XB0 &Sk;/BswBZtL嵚-h%|$)Oc]+}vSH_Qi$v{`6k.o[> Ko@=.1X'q$_TyeK+/GU ?GfN@W;818{vO8xUy-uP[¬ B=mAH7b%ă]#]uߋq>Wݕ&׀;y^>kwT7AktaIσYWko[MKq(\p+{+vׇfF LF.-@a^cK!(Q0|$-SM<BUsb~c~aUk}|pl (u#)!+ӤxówPvMF u>3YP0 $IQ`T1]f +P8x`TX{m6ǖkU/Z{VtwyH=¶+N4LdhM gRf9qiC&<DG 罂?~1 kUy>4RdԀdTR,$*>EeJ@Qem7M$:AH%tـ)}8)2jT!ACLW 4<0 j/kƅcp8@o P| @3ZRmoXIENDB`doublecmd-0.8.2/pixmaps/mainicon/colored/v4_6.png0000664000175000017500000001723311765566230020717 0ustar alexxalexxPNG  IHDRe^:ڡ pHYs  tEXtSoftwareAdobe ImageReadyqe<(IDATx]yl}f#x߷(uٖhۉlNa$ îhu.?i uAHRmMq⤎8,[m]EEJ<^3-I)p۷;;|k~3$]+7[+IbI["YyRj@+.A4b"EQ/*AF DcwS|hW'EVMkHȤU dk~ P|lV_j^kkCq$>ľ gM*ީ"Nk=slOj7  %b tb"g>R 5BDmAD97Zvٰcl^:ϰ0(+b1V_9WŁuS߶c}A0yc BEDhuKZ/Ɛ{g@cJB Xbh"4:0THeKu9AM"7޹~!n,, /kz"lo:>.c4ow~ns\/QwISf{v/ElmCSnSPJ t|<]IT9XzٴB>^Z\n}N:Hq_Y4۩|/M}&]n:f5!衺3Ise=C:c!ljb2u8hseLWy\g7LvLB}mtq"(SO >ڊd*pv*qc:@_ |L,r5eq,jdP\Bsh+O15ڧhA ڧSBOq`/),ۧI/9ƬQtrtӨ3V u1(ȠXmBV򭾾w67#J)9و$ڄe5dcBD㘒ؓ 3$!H gI\ .  .Ҹܵx1 7a 59 8Ő{ &@ !TX;TU."Kh7MMxYm]@7ޓ*++=>1NOȀ qMOi)E|?RA?6s7/Wze52XpZZZ@COHӄ$vt$1C@H1d(Qb<+2zSسMF0˺mxnՋ{;PIduʢD3 E)iMT TSyݳ eeek3 n͜1Vmʠӵ&wz0TWWs.c )t0,R Gr~ˍޭ&E5cƸKFmv7 ?$.;7g S|-6Ck]ˍDoCœUoQ"YLݡD s{;:ր8K/k|OY؉`YG;эМY^~7מEooێ[p eXsÂ3x` U99tWͲJ VP3hk*s.SJxSߘ6`ao޼AǙ\lB6Q圉|Չ8>Pc{#1zӊv2JWeD(EykS k qlw8c:ouHPVw3ggxbdbbg/cl)x3re F\Jo@ɞ+_`9+ańYZzNNqܽ35ZQv Gcj"J(V]Icw<eM̸x"1I6 [XΣ&-CAd!B];~~ ÃMxyt :\wvNÛ[7xi;J Yvi6#Rҧ (OV~tpYCs-46yͫ90n"8}b\Oe',zڎ!^R =[՘S֙pGW :ZY_ҁ~k1ZhYX%xbs9kqzҪ_{Fk-uBN)"/جćDݫWs!Vʔ)Rβ+%GX  :HȀ9:ق؁wN ؽEd*2 P9 X'%I^y 80=R &g/Y3!?=?g(Y= u6bhh(0؍Q ]4c˽rs`ꉝNbdǎ#`r+<4!0BGr [L26@e 7_kz-20h^%Óry$5P3kc^C#8EٶM 7[ɮHŐ/,z QKRƸX1&Df;#1$gM)wpNmii W)"K@B8J_zrys8Vq Op:]UTT`WˌK,}8YǂOWH*Euޠ\kxKdZT&XfeJ Xe׷p%C\`ٰMs=7 oE\bM$r|{Ǘ*PPG{Ch$`DE,]`_(@cGp%`\CՓ.S3{TemPEQͷ##¤U Gw5FKaDAA"^^b{!>L7ZpӶya㗺% t]l ;`H9^xU1h4L&q.IBMjoH! w:i[D#,R9ǴMѣڔ"na28n8"Ru<r uzgʁPiS`PQ5"Ǻ,7>"%$Hq284ePYF#j &z$kPJh :G#~F W/6RKF;W7ZiXHS/^("Q@fxv ASrB!",8JdMGMJI?əfOF*u "S𵒨k똵P5/:ALS:1#(YeT)Y*$6&TKB&3ӕ]Uz P,|]|9,+)'eb:H$nchr{TKX] H!oRW O=u1&v\:p!r#tCdɭc9dD! q& g"w6zG4B[IH2T0ÇMҴYb-[U,^.|*%; @M1j;H>QF TMZ'+j+r>G (6cPJiEUsŘ'Qkӯsdp|# Q!>C\E9LIm41\`YؽJ?y1"/H`Q]H9 aڂD$7[*ScS<5m8~r A@.dZk6(%Z_ħG"TE}:FexCX3%*^!~$ ;;qKRgI(+P+iΪ i9b8f^Rŗ) Uc\y.T7EjE|ʍ߸ׂSMG`c! nȳQy9γb>|.˦W@.{\UV34ZWȵ> lcI&RGT9KwLD*af}`mG`a[7m?s'ӕR@j̚jRb[ux3 /z@X7{k 2yR4$S1Deα9wL%JvdʝH; y:23)S1 J1yX??E--M, Qdmq\/,?\U2-sxyB ~E1y!q)8I ,$ }A M]E1k-KB Y9)^1ჃחzOλ3;jej1v~²Db''.⌔RQ2ROv~bbj :s }Ѣ|w} )GkߺRY[G$Sv~[ZC\`b'(:I h%{F- }F 뾾ˑ3ͶO$ dV9lQ6{QNJz?iL|z%?0cH: +S DA3{vƭJD_D/&JdKV"^溨vs6@YA霔#3xwZ*s1J(/׻ydpӉLF#7/v֛'c߸i+ Ea '&Mb]i cD/9oVjm"tGK x4Pjc5{#7KE&|nJf +,af|f1ߔ?y ^Xg8H .YaoT3,zuq;ESz'؂uQer86)ĬY+c1ux!YG˾gBGuy2)rWpF ]JFJЭn %00vVai[D)%'K|D#b)YvO5`b)P@2晱ěu08;P[O-`\c]-iM,w|p뽈sxrpŵu ?\D6pػq|z|w)Cb%y%5oGwkڒA7z:H96ۄU=/_?g>P93^{SzŁ c"oMsןC,}ծe=_B˯ /T]H$st36>T9vo9>}  Xt5c},X|Yu=έtY* 1:iE+]Yu-7(d{~XBȐ)|o_} ,V!gi~x`2U +_Fz6)V*col>[}=6Β:!P6)3O-jH ߩb:Gf膺0!Uys]+$vsI)*+7&{BD) qDȽP4\|vlm:vkb;_}3ؙ {+/B4L-z MJ,,wN{脅6ȉs-_"+`,F"@K2|@?\SPzeճLMjq,@Q ѳr2V[e'jm^ܛ~8>'HPR\?j ? <] \͵E7sK⋷(:B) \n|٤䋭)Wrsk- w-a.3h>co^#ҽ"<^Ua w6$ϝ J(XyBM_dg*AOr_^܀O{|Z&݁UpQ/G$Os,|F_2c(G| R2WUK7♳.m>Qz)==qOnƏNB&ʭ#&, ~3ּN|e7<ܩ8.Ϊlzd޽k*֔r`MxW?oU4p*_?Ϙ?]]zJu Qo {{ьNI4}B~g(vtWjEкֳStDHpA&-QWrfr/\^:<[{o20:8kNsyqK (Y{?)&#655z  9O;pP}hItI'[n!gb``caketK~HR@V aJ> r@ε+\Z\W' 2ٺ1]W EG0<Қ`&-֥]<=ʁ܈ZY3@>[e58ѻ wFbjLxa¶` IENDB`doublecmd-0.8.2/pixmaps/mainicon/colored/v4_4.png0000664000175000017500000001514311765566230020713 0ustar alexxalexxPNG  IHDRe]U pHYs  tEXtSoftwareAdobe ImageReadyqe<IDATx]y\G}zcg[ڕVuYucc)\_IA2$e*EP1|#cccK6`Z[,jW{ưwfv8R׾ury:3<jfg>ѹ.{AN*QUØ \"w5v=N?.\TXJ$ҿ|pѠşTֺæ{Vׂ8fqD-6ve~1Ai퇓4|LfՒ;?vd?c=g=Sl^[2cQD$InxN4_"IJ#y:17T-TnB\AifߝRnAq΁=~Ï}a PZ6?ܱկ~;WH3!!!L/rɓDYO9@w}*`=O irF#'75ٚ/+C)”ϕk_FЭIQ1Ux\H ܔhI h%o4y$=!Fc(hQPP5xD6M>Qp(-,!SHvb3,ՁKušP ̭TiAhaת eʒ؃^r8kN4uOJyT34)e.|OGvۤ=1Iz8;FJ'+q_U_C*SOz//I‘0"0$;l6'2S[;"j5OGWH^fΜ~ll?, }UUjjsB011#\$:Xe ] 'ՀdE MY D CV!Fk ?+o9@$fJ١5NtFpYKee%nA0ĥqfΎy[EZl qф֘$wNaJ& 1PJ=>@}kry߳I%E izva?'.cbFքV8&kZjc`.e h8RVSdk[jBE,\.>~:GFƕw4bZM#i J%PH #P$cd3¦:;/P`@)F Nmm-0s B B5ih?|odyQucX*P Qt[cswEXMk;[ݲE vˢV&%ýݏu0b,HEj<]kRQD4=+P]]J+◌SFx^|#Wf1*yuM ,s$ZjIܵ\DtSRo dYaD04Eˍ v.'Zj@r/~nggs+c!&rC= ̅z5hk[`"'|ż ~+(/Y?Y7,zMvԻWUGRcp,P 3[֔yqjj 'f0>x/90ON+.s[Sw^Jг]:=E'؟y"a=$F4>TGzO g[WL?\[d-:; l]\R.LJy8.gmު)e3+s7g?g43e1.2_w.X ̦bTak>$"O l ED2&}9ec[E&RCCC8x1ڴa!sXR)2ziMm,*~qɍCcY|q[[@d1ßl_&/g2/Ϟ:B/GKKgI# ţ82UT/ 8o< I48|nҮn#:=2;yqNd?^W7~kkz0 ?[:&]Nmg,`1__ `0SAƔ:w%eɬg >) *JSs>6?[梼ↆlv/kcY P49D܎+~era3ÜnӀp7^@^lq)1gR29Uac:t9aD r̨.9Os 0 L M%!D`k#[^W jfB+`#Qb9%!zEa:Ƚ!՛ȊK֔3N(q]Bpm|jD^X4ŕk:%&ZQ [ "$Q|;}namfQe9~}&љ&4S+œ| {4"wU\BI(W358jwTy- ]L72\V(~F!E 4RFs %%7pA*:ʀ)@߈AuF0<@wse5 3]քn(Tdr+w)u(*@QKO(҈@z6ԎsȍMIQpAϴ׸e/{<lxRaٲ)E%HK_xH[UYA0 WN1nQcgφEC5VQqcr?- UPCH\a&b9=zvc4a?B D\ FEp8-6K"e ȫxE=~O_ֱRENN[U~LQ-cI"\w"xAPByɁ*S(H3τ=MxhQj`*+ UM"ZulY_+,]sZW\CzcLrn*T[71/Qeups.b0l\B"M{g tYؘ(HH-T9 ^QP25ˉ`r ~5PfU>$ 0%D]x~SKffA(Y,KTK c`04/ V \_+9 tN>l_X^Z<ɩ01/j쳡BKZL|AiuTkf^'f*M~bPQrLnJSO/ys .:,Fjs*GĪjp$^hn̾]1uT[hJjwˣorܱ 4&4/PȂkXTni^}^/1>[|ʍM˙1fۥՆ>ei)MyyfS||΢{&QK-WOZ08{G#|bs`|=3|W Iz*Y):h󢹡J^6ǩZ.;0YϷgirz^pC(|C0b(h>ZN_Ǜz2h^SηUgN#;:n \)IUW吭)N֯%IfA8nzւWzt]2 P %975o\]}0)&$ܿqA?*wgN|뾍9c_Hh+~T/v #<3H^'NOlv bkgOѼ@֙k#zNΛqC{BZ>27{ /Wxqh~;njNZ6(rYʓ"juJt6;[p꾡x4cT$+~wuW߸}YTҔj,2=5+02mlm<5TU:nk*mUiZVSv;>@ASxefzшOC-gyRJIENDB`doublecmd-0.8.2/pixmaps/mainicon/colored/v4_2.png0000664000175000017500000001467711765566230020724 0ustar alexxalexxPNG  IHDR_^EP pHYs  tEXtSoftwareAdobe ImageReadyqe<LIDATx] tչFZdyf'N:!!&!%Pвe+ByJr(=}4%@YZ KHH=!dKp8M,Y}sG3HdY#iՙhن,l+K`tB_؍0NYZ/lKuWhHZa|aovogP`~Q/Moي֬Þvm~|mKj7Ϙf w"C  '+~yI 0 c`x׻^.'@(c_u-];:vEybd1)R?sގIўmcd~& .voLbjn]{g_"饫reӰ۵, ߆kg\'<LJ`μ P%`hI;1{lXƔ,/e A'v ׎MbGTZx5pg =&WAg6\'|9|?MujaAo^i {x,ߘV ?v JZO$@rCxSj]H/|]^uTш cR[y<Hϫeod5nn9ßǻ?倭j?YG`ҘPGA7-1?ǎ 4|pucjajs.](Iȫ5'$=r `1f5MN }NʬcX?a5# HggW+n, [9SNC|P(O3\Cث. < oYF4nrf`R9{_ ,3mppp|y~<FèqVui_.zvGO q=o5~W} NMyg=]= Uv"bN\ms߇Jkʠi䩠[dv"4/2 (<Q6nw.?9BQǤ *B='j\1geٱoVx u bڼnȖnV|+9koa MA7ޟ,LdwNI] +V++[Ǧ[poL%]Oܰ\@>' H=F*r ;Һ1 nN`ҭ]A&I0cU!pZq~Þ?$gT9T![hq<-M] (7S ja3&ԥì9q+;;g~!;DtVuj`?zVԃ~PNi نL"3v|+\{A=CA.\fE$!'!Q BYqJVXILSNڴVFs :8}ѹ$@?yn [ѠLځ a ?;s9# a^F+Lfm $E1pr (_ ?y('$S;H@J)~z쟷%> jmYm¥=L/?743L~α*WHkp `B? iPU9& T†=SUObvt;(G'Sm/z>$'`1fؿ+j< ̖v/Ӛ>X4dpݺOt^AmV;U;HgSӓ)T& 3'nz!@ ~ 4r(ʨ1e^0ѕq%8m ҄qeTOQv/爴}uI`aHd s,"N!ҪBMg|!%v\vmx3l/?op)<>_Si^'6Ք!J$3tNL;0Hp Tɧ!^^8#9z ?O& 6 $$0¨#dFIT;^1w"FSFOCG6_Y|t#Ӊx@T/>EWF@d/IcLvrC:jO`E#u())Q ]Y{~\; lZ`~Hl>(T73 l%HTWE%^%/e:hz&Y  GQ-bP6TR) )騂+!k$8b* "R8 ģ}$nD$^"\|V䇔O_{BxV =&~9IE$ N PRA ~(5  Du1Щ6C ʲ_kC[ڨ/5QL[u5E3Uc( QDb[x~)իQ_ܼ_:FxGloy94. c+hye}ݹB+A= ҷH=уCNӌ%*_8IG4It3 ^P4r1I4 <@NPQUS9nXh6V0 O2Zhj94N72yUN:}O #B ~Ȍ3'Jꅂ)bRDHr )/%Gw[pat#VEk qe] }F!zDF4% )^aQ/D#n=U+;bN I R_1Ák,SP$ol{Q+z^15Q$y`@m`d-{bdj*b3$3&p^:Hl G8 {.]PtũB\=2E^Ζ`oA/=!뤩[mUD}eM&!IBLC*D38? 4(H`<).PQH!Wɕdm*yYʤ~˾ plݷC=rsU?*l!j$[å@r6 t.Ht.*E 6rxl~ѡw&(vO"CoX?a2$$""N 爀G4GXt:}:d3n54*p/#R ܤ R$VIKVˢQ)SQK9XWcJ cT=ͽAZkPi(^c;`PTBWgŚ"?Ο3pٷ.7@fѩjsRLϱŷV뿟6ymհ@Ʃ7^(ćyo',}HPLG:э*(ԏCi8QhxWFۂO'&T˂G=کO6qvKi2Ͱ_{ǝwP#M R)[>z08Ak ÔbzYE'u|~)lU΍ϊL;fT??_İ=Ūz9cymI )3DKi.jGSY+VYu}*'gˎm_]Γl868붽d?5ɺtǒNvcG?LyHx:}663*es(w)W5 ;41+U0r/ -ֈ}ޫI|ѹ.!lUGgOmqyw n{7$>l8) ЕڀOjNaS~ .-/oR-Zh 54Dpa9WKoϓ_g/Т LR kG|/p`On[O;57ۆ7=ZDPc'RO#W= +g.&On^ЌmV=)UWBFyj FZku@BxxS({ӂk.Esrb -cc? yVt_wFݓ1g ~jԫX%4VNI hPJ} *JcGS19r&'c ègǮq zP؏փ`1Ν܈c&CTOU4=5֣a^ y510퍑_V*-.4V @W_q=ۭa3&-2!5{-HL7\ĝ/GS/=\L7;\w~TLU7y@L&@(}9릠\}/yi/A (sQc}Ǝ)ylTLU.1Xf;-ȌI-q^ 4^PlsR+遦ؿ{raߊ siJM穭Q< Fk~H>C0T 8I46]; {Bgi<wy_Jv`J7s>IENDB`doublecmd-0.8.2/pixmaps/mainicon/dc_128.svg0000664000175000017500000003403111765566230017500 0ustar alexxalexx doublecmd-0.8.2/pixmaps/mainicon/alt/0000775000175000017500000000000013244011205016533 5ustar alexxalexxdoublecmd-0.8.2/pixmaps/mainicon/alt/info.txt0000664000175000017500000000010511765566230020246 0ustar alexxalexxAlternative version of the main icon by Ivan Dzikovsky (vanyasmart). doublecmd-0.8.2/pixmaps/mainicon/alt/doublecmd.svg0000664000175000017500000006664011765566230021251 0ustar alexxalexx doublecmd-0.8.2/pixmaps/mainicon/alt/256px-doublecmd.png0000664000175000017500000003670511765566230022117 0ustar alexxalexxPNG  IHDR\rfsBIT|d pHYsIIEtEXtSoftwarewww.inkscape.org< IDATxw%Unɉ&0 H$I@AQ @_e]װ|W  KNa<=g:\u?n{V|zVթsN;y!DPL3P(C B1QP`(3% F B1QP`(3# sY+r$=;s]:Z1ގQ>Ru]R??>܉o̹'5==whsK+;ҩ;n߹%;: D&k^y7GKXd1H'|dv"DSNi ~ #ZWҁ$\B$+Ⲋv( @Ymf1-n@֤4]:g!r$_h VP\q%綵ݶpEHSsV5k_tvvD1 a`:a e_3 W(Åxx,v98^`!)O4TW(Kvaig'G/^ re[w!D3w{\hW(ÈgID" _,VƂ }N?=b¯P4 I5cVef/8?b]]J# E#7;X Apky p=O~nW(Z@FB qK|V%/5z,ܓ4ΎNU+-]蚯(_D.Bvvv":(֑i,5SV')Op;< z)Ux'7]ZK+rk!ef%Pְ[v7"4Mf~93^dY@b " UMR*M=bޛ.r{N>'*Lk'`=!H$H)d27E4#{oSRV|tz&|Sʹ_mc&lַڱ~.@YbZKKbޓv  0cH#QwRz5P0AY)Fg6tT`bhL&eYat6Dkt,\̢}AOJ~V~e0bl6[z9A<, W5JL|iehF<EYu`5@4F saX8E(nfJwb|H" ϓB4bKWorΠ7#.Z}Ch4jԉeYd2ҎBſ=RM ӬJ]MΓOg?K$33TPM)iTt#1oxsRf9q 2ogyopU51զS0IɤIyyT3&@Q?K.sKy*h]d2!0= Q#"^1RG/z"z-cyUiN2to~1/qe6 -dW˗nxg.Jm% 8!O `zl|KWKRB^kC'ڂ$.. 0WMd"|g> ;kV!/DzQ`/=Ļ>)Dלs~Ø;+aՅ޸ xYI\ !}В,?ct|*ʹwP$"[D⒏ U&BD,ৈ,Zbo]ފJZIK0=SEh:/(k}(3V @IRM7I-X-{e$<_ީYڡދR###vOBܝ7nf_6:N>Od"l7cADSA ,t,-/Y L(ei =%-@7 s&Yܾ)KtJRwۙw y) `"FM[S>"t/FRfFZ h$ n 37L-6|%Gc VB|>?~\Lu0f@8ƛ5ě#7a[c*t]I݈RJLt ӊ^rv\ {eaYoyo0D"V8##vov4S!Uk|kHs[;D)I;N{{{:Cwno޹K@hn{cK_@!h A$]s @Xn)k6O_RJuf3Eb_pMViGQ,˝Z~%ܞ=X4f6`e3 4G?! /;p&WzÕ_`Zdb k8HaTwiόBY #r*[4ʐRs`( r9X} J)3i` L31gRJ"adlXi_[,#gglHvg/AZTKs+=ޡ!־+?m=췾1w>^t( ^-mF[`;Ry d2(HiI7%5 m:1')/hǟBlv.ӄ X)q)šAv3j0=|!䆧xۄ86yR-2OݱB[Eᅧ̦k/Lh$^~ބALu>x~v:̑5ncͦo)r²,FFF&|NJJG"vyy賺*kԽnFx_ᗒݿ;?ӮtQCwbtP622/Y[Z'8VB^))V.}}2Zٷ$vd2}p;/ʼn|ToE8 U=zV =fYzUǖ"CO<:o=;0RmdYwD/FP|WՌ"s\d y=gao #}ToE@zߕ  n=a Mv;܈qRc642^G{=880;> 0_/n|h :ٸV@ ڠ0 :^ZT64Ғnj !@Jx9Vv901gB"|q3'uv;SV< n:B>^xoͿ?ouچ'z~$zs.~y0ϒtz/ZxorS%oSs1;6%ǠfA=MN?A[Nㅇ?:v^z2cHI9_\.אѵ {jh;N<҈̰;m]3+!YHQ@LYȡG":f54cÏlθ+~shW߾lo}=^ ߋ[jѣ_>n8N'el_fޗ— ~Hn)\` J}0M;ǻZN,̀ԉ=h(T ~njԥ5JF1r?zP(~<)\ 6CdADZZ_ȫ50c7 IL̔: LP{Ҩ{ ;004xf0$T>rb܉QEǟֈB(Kk X[Y((zaviU=Arڬn"oUOؚ#ܞzTi99f pĴ{Wʔ-/:hN -Id2rJ;nmNOTAc>m+uy.HQʗLb'I쐗Tv3i>u%`>xD]DIqwqb [JA؋c-NkpTYa}ݍi (>z t)thf7RB1D%Qȫ._%i3 yOCN?gqZU 6d,>B+➸}dsӜO3~/|IڋX5&wG[TW܍iWW+'n_]qTP#溿m@$oZG'Z2mךF|5F,BTTN3-oX}bqB7c5j4Rz/QλGzݳ 鏲ڱɷ=ދZ h7i-X^e 9xgd7X3%u vc[ٶ9MtSiPI^71w/mhu+R߽aC83ffrw ! dzE'B>nF>"/PP'okNMV<C@tjpN^:8 @,K7?zqQ@{$ &Xs|SlZhj^@6{vC @li^flؖX&@Xjrg:^٪ &@ 0':948YZ "ڂ&@,Ko/BB!ta@)%ooZhblFi @f۷ۥI_`aD"D$2;:mE":-f|v~c+e9|3ٿ#vPx` X V& "H$i#Je/ԺXX,V.9ZХS "_ RZf.ˎ^8Z,COԉ=pܘR`G03iLb&A^+HV7}-ٺU|+0oZ4O'z<ZaPP/eN _X V.f:͂,7,{?MYٖAZ$ґHu~ND;8d6#aN oFHI1Nc att`:tt%0^da/-`P6IDATZ/H "DRɔ(P"@@9X$O)!0R)N]]DR4: G|2~@8AAAgaH)) "0&Mt֬}TP'bBtX@:\uAgiX"پ}dH,$a ԉ6*  \M^tVZmߊH`tucE%n{:;EM fZqz pElA@稵 f:CZ"'&g='ŽBӓ=;}i,O+?@+l%+ag6b B6-,:8:J@;P @гeio4gri/ԁ0 ڵ]cK˾Io-43<ᤀs^b9<5k',/!HD5jG @d!GaN#c3KO`w: [_fӘv,nin3 87/<@nFطY, :s |xV)9<<tr&Fs(d>GqO]nJGO9tE(` B6ܶM<`87PJnE{`aq:r=QIgl'`XDX,ͳy_pnڃ)mm]9?nX} / Waʭ0Rӏ<'qQ#IXpnόsoJtN#^dGF2vS гݾ3Zw` 0mzBV\h]sy`Xa B}þ˲\;?i+4)&y wLjɄg)]٧ lV'"4~(=+-c;pnBž^roWUDYDϺh4Bh ~!w4ݎA t1Ƭs^|m6?y`BTC{P9ɏ@ @$.~O //f[ah\ڼEο?-ӟu= ӗ?,(Xf.I~R8͟ghăJ:FƏXb ''Rb#FW7N!Foўl%L5=T`wĄ uϫ# -/؝xZ$O|CX& t_8mܳOPܻ3܌p( ?=%[D [(ni.B#mHk?r_x 6t]]@'Wa׾.2 %恽52co~0^v`mxp$vdk`?pn3p(Jy#؎9g}2G `eog;BsR;/P>9D"7t RuArv R244zzwU0TiRܳ \IOϹ+x_0fbCE= !_: .xSj=-smoU~F?/0"n0rm2#3o4]ТQ|_fOW*9 ;6a["Aoyy-a_ӎ4÷2~5Ty}`ZK/#{-FGg9k Eazd&8p/\-N͖` _{#pdl  M٧1?-+X hl1i7J/=$788ji?|,q'X~0ߍĊӛ>笹4\{(@jo#~ŷHڦ\P|D"ng?d svǠ~XN?cV/ޏYw&0<Ş}'_D ǙdBd2 c~tjwŽr: Mg?}C 5P"2 g|*zX{U"Holߡؿ` CK&Y N?sX$*bf{b>]}W E4#wp[Mf3 HjEur~ФLSܺk5*!f'r'D+-:x Ju.WL+Bj33ZJXO!2Ԩ_Ka ,ψؿRg]7000}u[ 8G#³+l' %߀awqa_:QZsvbx@r4o gzky2L[|ޫϿ^K tsH& МhF"ݤuxq8}?O!p5O!{brX~(ښc8(\T(3i/N _g\{9R)b 3X:&9]/;*LģA;#[6l1# ;vdq. $hnk(MGƒv'$"] eMԩ!¶4w5kO^Z׏SǼW&}5!^SRǝ̪o^ßnhxc!L͌lHfvCG( c Sq>%Gw ok_@%K< zzz8ŶtC2tMeWWz R  !ljAN0(zzzn.lURJ,²,Lt}3h4JGGgHkR|ƪo]Gq'4]M4 ]?g_WVE嚲74.X};L o980CJCk4X̙2 dYV[umGtvvD\4:;;E+K6= tÿZy,WΙ1OXP":::\op1=waD|T*UZ籿06nv|+ v۠vE @I$Zyb>/X !HdW>Sv(&ݗ}_T+c?[vF @b~} @k7̑!6}}wv06<]Px _4з W\3J%$4d2Ybs~vle'.࿯ơxk*sN|}sվd6\Lg෬A @pz9m ripڟ\vb)bX7b("NwW/ipΦ}Kz!ʪD1(Gc?>.e:+fz?~w'`5kVXֶ-J&I,?15d!Ϧ/^ޛ~X}&<08sۻS[ *Wfl`YlWlIJ|JD",:pj{dvcϯBFU`(r? |eqs6sI{uA5&@4ɤ[|O#s.k?Lk̑a6~ {W|-wtZ04xke|v~%w(_ŘsXxE>t6vرW J4 ]!wnZ8ֺ'IN!PPSJj_gtuuItx2/?5Pe~B4, 4}P.y kb̟wihVrNuO`{BxL @Mq(iFOE  Ptʪ];{j2OzYk7`gI!BQP__F׎~:t¿w6&l/怴, ٜj(5 '/F's?epLIξsxٗ`~,E!b /`/? x5ù) ǝCg߹q8ϗSŽFsHIPLFLՅX1Sр8 ,m{ ^heypnhyhXsW%|ԙDQ iQaԠtf=oH lCN=<{)ȿ-I绾 _]=/Ur*N44Xk(_+ˮcߓjϡZcqXg묞o Ҟ<];Iύ+WP!tt9V#U疎W:wSwca9ιP.rcaN$WJ٦~6kY';_JNp! T@ {6EڳlK ڳW-#Ym!$T;\ @m!~~Zߟy]7ZمP`Z@)w^u 3@( ExQP`(3% F B1QP`(3% ӌIENDB`doublecmd-0.8.2/pixmaps/mainicon/alt/256px-dcfinal.png0000664000175000017500000005632311765566230021557 0ustar alexxalexxPNG  IHDR\rfbKGDtIME ?6 IDATx}w$GyV潽t9(¡ @1cgA&cBDd0 ID| w:r{'tQU==3fgvNz7TRH"E)RH"E)RH"E)RH"E)RH1Ag9ճe$Z2!B=SpMFw5lăm0G焄؉2hd|2ezs +)oI1~Iy2;i'/} xMLJʗXj# t$7MbBv&N?xyBFO~Jǭ]yF C wt,_xc|.<^xca¥.}wI ұx>36Xޥϟx,1'_I7p{7+}0)wN*) "'M7}j헭Ͼ|oV"P/f3 GV\eti+@g+R78. XH V&YǏ{?I@?C3ƞ#.,Tהȷ˾KDž,D#xUND DQB JL_\07L+//)Rb6nx $Q !n.}Fo!ߏ(xMc`~חN_|% Y0{V:ەڇ:VpI:%iC/O=zuV;bLPW7 0gl̛7lxAI ~RJ3y;di?Q25&;.]Q@;:hB455E ""flȹZ/ΏXe9IaxVݷZ^]ruBڕW.}.R Gv#Z^f=+YKwSH_F8 ep }\ڹ 3~upJ_Ũ7ξV|B,^.FoADp $@T )RLX/>T@ʹ' fŚsͺ8?`xYw $qɪxٗdr*twD%!. ')R( XAH fu`go/5әYgCEKWo5MMMX|25ɰ㺠TS E>&2,]}(x9u5l@)dr*d3L61lRHQ >8!mr,¶c=( ʺ[*>c";.Y~2@\Ūp3sw)4 8rvqp\g'݁iv`uQ ;Ze/YYuL"0a霖f\bZ}}y]u5gy'GŸ"c%UK;;q)jͼe鎊d,>j['"dL*)R{ً9ft^Y"6ۋsOV`mDxֲ+0Zܷ&o1۳w\iE)FaqX2+8ΠhJ8#ج2?{ A8H1ȱj0dnB X0Ԓ}H4clՉY8̪ )f+'miN+}I0/09ɬL"ܮpڋIb*jY.SG|1ó̙k%GpY2(GdL" v%pZZ&!ؗ%|HFd_Rh$Tr<+]HHKYY%:\i)f_*n>[ cRClkmS#Ě.%8i B|݅餻]&3Q0dc0bl*1äV#ÔŻ,AGpmo> <j#No~%p13ii'q,-}9a @ BODjcg&f81Di%EDг%(Rt8 Ge{{]  .x/+n_= E_V$YZE4AXiFb RE)Z vf6Z\]0؄f7j@fHc)K@@G,Ωs'G@ĞW%=59mNj XkvE &5\lR2H1$ =8TEgX)v̰ &'ah/#`Y5" [0=\Y4egǀO)=ҰD,sR @[ сL%"t"+!{20}|0ȑ􍠇7 ]AmHK)af`QBo! hw,ʽS;A32 >s@R|iY HV vl@JʣL"0Z J'@Ge2؋fz&)L<ɐ҇_(/  {sbx ڊ⡽0`4n%GoBkX3T"κ ?}~KG.o>DQ=Jvjj)C|K3ẍ5l Kcm-N5ǣc̞Cٶ6d[67#85,Dš(<bB!X"袋Jz Vj0n .2&z,FR"?8Cڷ7oDc?hz P :ʂX q5^H2 hw ϡ/Y>!i=ǝ>=]+VRǂhiP6ʵH4wt]Wy1A ߍA~v584րZ 4AHBX0PH|@k1-@aVfsjwʩ4gr4MAp˵h(Ѵ$]}-e( w<'N _ "E"\:>#Y3_CuSv-sd8-XqXzsduJHr-->Ttx*\}p䁻o_ȫXC `] _$05 D|-ƴ Bt-]z;^fy! `\`KҲ$ j`Rk1^J؍Z_UߩuFe8’ϥlsKݞh D"܂Eg_@ :{vbǏ}= >1$$A`Z` "lBmo|p]7^EsAbYI "t-Yw^GC=GΟ;~@de, :d0[[7Q$fbm )>zej敯IW:έM>fh='ʹWa/oD6Hb8,8hm XABc D09 ~<{Pp^y=j4iG8C^Jl|wC>va V Hl EmQI뇑{~}H'%<|qHm]]61c sN˷QWo753\LpY5}aa Иe[f=Zd9tO/xO|?O\=TeMDBP@VCa!)&M~ƪeqh4͝-\{ڌ)X "t?~3mՏyO GB\AqnHĺ4@8_E`dLKV oEMK}[q_E87uWǿQ.١ 8{)Be%.xP&>KQUq>L_)T@{hn| T-IjU[L! yaTo}g ]NӭD#%*B`ŗS\Dž#h @f #tl `BJGsG$~ݼ8\OѬS)= ܏~= |/Q%REKR-LSt H~1OQ}}+_*KHH-Qq]i3y> H3>O P~#tum"ц<UR88_>J>ٟH-1`g9Dz_G*SK?*zR<;w>.{' 6^bK `^>v e.LԔFr/M=)*Xm}ƹxE3uG w!%q Ԅu!+BC+ܔʣ7zT߼SE_Jq#ұ VQJOź~|vu90f +'Kx$-O5jiFG PCYT4 W|Z`S<-Y<`D4t []{hzJ@¶L:7%ĵXJ!KЄ5`:,<8lΫ-8iS'!* c-\^oCJkWdBW|O~?#6`'QJ`񺳒ӫWƤx5׍5(Sv\K{ЯGjR C /fO#Vcً_ϿF*7jՈfXJ X,BJM]]ffLD['+8zpSۓ"ӄEKfXOSP CvEۚh[ PhұAW@:.2B%'#9tz a0i_sd]*5Ihצ8,ղOw*H> \oo,D I@ؿ}vrO';z6JLO ]-0ρ̝{÷7EIytZg>ʒ#]RcBV@/c΃]֠RJp Ԍܼt5{1:O8/T|SwCljq3)q@+0U`UW_V`*iZծ/w{202Dz:HBqb P> eց$=+M:#FSEAWF[N fa66cf Fa%W"^3Φ×3beI MAF+Pb7V5V'%_ ,~SR+_ĞͷG6<mͱT}:X}_=ޤpɪFЃ*RGM82 p'e-4Bu AY[-D}Ҭ+'*y]@l>De_o a_Xc!uy8lx~b5 \HAƭWך.ad@h]FGD:dIM]p58Џa Ab!! k59HEN̚RksSK+o ȝ.`>B^sC0C0J\iFGdF<Ij@~p;~{?o)\(fGoEZ~7ًG `Ah1:=/fq 8"+Dl9~"V'_EbH aǽXR5<:/NlaT_HK`j 0idm\t,\)a/w|mFn~`[nowy&HX @Zdz !@+2.:2ڿ%"QvƩB8`!1C6c W o*/MXqE9ў~΅@RqEDЅ0јV~fXU)&Bk M/B@`\Whz%/ZwSyALSqV1d bϘV ƵmSty#DߪO߷|3|l P V`}9*|:NѤx%lyFhۨoa7RmіP$A>5/{aENմO%|ᕴ?_*R bw8ĵlk}#nzѕA;zx?'oVwj%9~IVB?J`ߵJ PFf`XfWbm%PJ”{ !U"" !KY/k(2\8⤫0e,ahW'RDZ&=fJ1#Iw('؆Ǒ$_X'|~ Ph掼Pcf t:G +oFf'hZu6<?p51<mbx }}ҩh?~mA& IDATX tVۦn=Ϙlb`; %i։kuzID7Ynt?wܻqd.kzqеb P.Ie^h5B1""0͓@S7~k^QblGZEw%8ǻԐa HV>(P`\=ZD]7Fsܱl;oJw1Mհ.b&~ {l]K@g|'F5u1 G7]#hǾӡd-ZjB$Z#IHV~1<'#hO6حٟ o0%v TD5$…4kw7=kH@ \x&JXo4) 9~T&v!extڀ./aʈaK?Sۈ-Sh;K`.7#[=k$G{Urs~um aڳJ֚vJ 'M3ɓ ^m %> y5A[d9o|<`C"P_XA $ 8xO_gB^Nǚl*etI6!>3VVMm|$i'|ۏxo CW FDm~9LZ@În,t##:2:VEK"% s-iǣ]+Gf<Ȟ#F@urtW%hزLL03gfrF>}NUt lڀ?^KZ\if"}> k5m^h a寴K6@,O(3MQac,MJ7׋?))HP[lEjRםKd  @` v#I+3#=}TJ;M^IkZuUڮ@kk@sQ"B&ǟT!OJRbw$e.ı4k#f3բ+ } =7JO:?D&ϼ(0C"`ǮgF0g]Mzc}qD<Cϣa/h䃙# " ~B8b5P?L+"{ˆZ.w~>bvtD`ip?ib4B^-rƓ:ov EEY5 {wH:^rΕkc56iTk/8Cb&Mi'aǝ`'AN=]3M5fWXAasU hH;$+2Yt}F6L4\``iπ.#Ҏ_Οo$`31LPе\Ot3!p[ #u$:LOK;i޻27|=&P0{,f0z'Hֹ#o4u-VAGu)l'?ǎ~MUx`@V􂘩r? Irh3ٹ#RV Krf|4.|)eʌ= +gZ# & [ѦY&hQN9#l&Uaf=rz$ϕ\J"~l*]+%vsv(g3 V4ph WIuŝ`]7a`K>c;z9)*dq+ @8=?I``[Aˌp䞻 ☴yҾjB^.mfF˼f+X@ Ҋ <r8xߟ,"?H @)>~1'yx[\7m2,ڗ 稁7 &.h]2Q.etч\-BBJ5?"CG v4FR[D@<@+u銊2w1dp?icWi % Z{!Byt-˥ PD+*`}$ÜWȓff}jcYcA $L1 el% ~@sXuIRc5[,䵀}{@߳yqrE+w4A IZ=ƃ5 f G(קUc!%r0c+4&;+d4ՊNKKI\-ލ?mM H `0Ub~Pv$\pk Sh֝{sz>PS7`dH `0Z%ρ\f _;^4/RBfq. !Q8`D«־mߠP QZdx^_/@  H< 8]݀S"7Ạ`ijY,:IH `W)~G\45qH/+PPP("/"y<7<`t},%wT8Ll"e45C45f/RX1K#T2Aj=Yz֬?zf!!a#%6A4ijܬ:g57ThH `0m ʙ)侥Œ?7 x27ox2? 0'd>XE$W1rPQNs +2݈x8uJ5H ~n X}]c DTE`V9Cdp[බmoS(RH `M/|G>PaWDKF'/pM#ˊC ( DpZභ!]=$#%Qtd2 a0p4 jrC~mi#n@r@ "wnWфL{܎d;&<AwAo/X$ #o?V:PNxPu ;k2@WKC/<[ 2]&?s kv}jvѠeBܗ8yF;rശiVLP5%"-^XX{^]GeÁP AxܻvBYம1[)A` =>Sqª{k:8hSSo.YNX´X$kd &;z#"Ypgu4%DFa c"Fe[(ij[>l%`F VԿ"A$'6pgF RZ;;P~XDےeo!OZM hi|Q";1y&amU [V0sɠR(;cHyٚR08D"crLʽsN;# j3w! |5C`3G| A@y !žcvoʞ ִr4}YD:'upJIH vA2ɪ[~.]Y,woPZM7Qڤ>{큝['cgm qjH @WB{Ez#s3r{wB>Zwv;E|ZQܾFwN8=~40`6P8|^u 1 &PGI B7`pƐ'!03u5m(8Sh\gAJ{#mr >gg7;3MpJ؎/==7_<2@SmkV@)R s9Fn쁗ׅF}DsfuA `#}sY>Hz{{hWJbҰ袋!ZZ#qCB)f4}܂M(;~ zh?B:N֧!p<|sc0msM;R8-A @s$`aKǎ Ivo?44ׁ@S.aMA"M,XML=w_"2#6Q`߃wx?[6x`7` ];Z3'V1qk9}R@sOFq2oR+ iO\,x`7[6;r ⯚H+j RD,*0з AB`@-K J %zͺj6̻,8Rmg5q {辆/-ֈ`f%)O\)4@j̇V j".Nkc 8COo;}Oa, jAB ىe/{~C3,p1ooGe{EH蜃/ ^}zI1/c_5]aml"K0S1Pؾ_r-z~!G\ګiWq@ ͻ%Gw6,e::pM@Eg+0uڋ¶'KBbIc󉧣ϛ>?8 Z6@ R LRNFN]?(H]'f=TTШ7_jk_*+.](5o,(W+V@y8tj1}$Gy+jL#&9ЇŽM6T o 1D 9 ͋OcLW,@ZC[Xfx-o pӹr V/#`TAj$9<(i;ZX?4McFvXpK޻׾}01g$:Nxۨ;[ͽF_Ѯӝ+'6Cs$a|-/uci3vV|k8 P ]e0ӆ} LcD C~!v<9~ >P@Xt5(`#whm뗐^%Z,iyDA@X;;wxߘHz7fK#e?Wsݳ}Z Z7[ײ/@v`yry=8;&)7âqj⎧F݂l;&G_LucFkLC8m ;E:L6LAM nلCF!p?J@(QK c0ޖdz`RK=Qܵ@\+;xTw[e50_I8[}`f[muq m(?48M87R5A"͇TF!?ݛ I2hCk$ŘӜn,{H4XS_Oo@c~2_ z}̍N)3Id@+n Ԝ`?;Z%2/å`4eX~g) |[&ocPہ@!%j`[۾ssCGK|רeي1$05P3`߇'ĤR_6MpϳPJ3Nk?C9Zow 2I ^`~G;E'1wGE _SNKew*(hډpL=Tv &Xz섷'0"6M~f?X5tϠ?b'ˤLXU0IVʯz}o!in9 -eA@.G c@Ed0aCv>=.rDMk4cUҢzA85,疯CD]A p"j}W?{uiuLϸ::뉛[2D~5XA# @Q(rҒ ?( %4%_Y ֯ AKMALE2gv(ࢯ~ZVl j%#JdPoR3-Q4#]a쪡va8*녁ge.4)(n,=/ Pn-;\8Sl V9_-J^FBҊ QbTѠKb ]IDAT9`fdGqVB!j3~(@A - ;?-H8nТ7D&;WR?CJj?޿H K/<47hVpE8MX7L+We[@T {{0QB\uE~E>1C ( hnL5s-&?bfYgCڳ?G#M 4/TyPMMm߈RDk7-+ t{~;*;L\=<ͯ7<!  -6="'8ͱ_7bŒE&"I&}G~S`1#X /9o#>s_7際 xq)ߟCӟBj$o`JW$@ 0C H`?ɳo>uhA^&,rz+7;~b ˫"l&CpG!.c떥QU_Ueܢ7y2P2@R~ː#o,?^_*7<'ۣ1S"t$w\,Ӭ _@N*L6v}s{r=\A/ pIk ?L! 2/)5Sqh^;F|ȴ<\z9s9nK0!BT:갤R7 ~N|]J+:؁V d+<{0 rf6 %!IZ'f`\U|2oYBK@fqeאMyG=\-.(V5f_d-.vF T HbO1 0Y9cG87_o6O凕BKNbCPja*}X*Zɋ(l(Nn#dw/M3Q,R]iuXlTEk1KgCL]mos{vZuaZڏS]Ү 1iox։ߥ9S[,>:;n9}ana !P^O/(0~M,@Dp !p2T`_=A`{f8nM u @h:z6u|d6P]Klǘ41*`b0gH0\zaç? 7Xikʗ+_ ܷ;s_m:`S0TMq٢SDc'Q~$Bt}=-#A e mQ7dݍ֡330Uz#}6<,\b,9IG1W6.u( `|c[n:Vo Gۢp߂>t=x?-#2pU i5ݗ d[U .[&-Sd)<A@R28쏟ࣨB̠݋]%YMKL?-_==$&j@YW*ZnJC"oҼssL{>_~_~yI܁۹v؎|_ s ;%cT$wi3pT#m 8 tΪmhi }BoZ!7߱ %BY~?c]g6i_|m]TO;in_UUfF `pK;·u6PEQ{?/ Yʵf13ZXI"Rʧ^~0~Ć@L&̒Up.\E& ]ׅS)>]_ÃWU~5x⮀d\̪}Cf08G|gn&qGi%5kaH 8ϾhPSd `)T7R؄hpd?dZ`o?ez %oÁ"so;:@J|?Sgٿ)ƈ#wߎߺ3'4w]]3 j܍& xO2Zrًƛ{]aw?~vw_;vk0dH-Zo3aY,вN9H `qg?[0"doUߠ?Sg>-8 1%~ lR`Ʀ?|_%)LG?^Iϵmn356  2%IXoAy3u)L+b7>˽=`/V~H1&;?5M$X>l:O&r;^opsnzÆ>&.36 E&J`S8;~ORnHǁwq~zd@_Vj?7o4$ SYNP6 S=˃w-)݃׿}JlI*FBamtw>Ցh )z3" ? DH$ ᧿u,=E1Qp ޴2Ic>L>TG ˳fq13c'!j_OMqa~~D%0ր‘2:F[^{wW?ՐZU `}]}v/75MHj,$]M :S Yx}xχ_ۖTBJ˗{#+jN%tA {k8 Z :TӔXp?)z/-S)$sy|@3dMxp.c&+jg`;;.Pɴ#u.&ZuY)XV1凑t FͺTOIfҒKv2ݿ̫pz_@d2uyFDJn*9Dh7&)d0^3u_-`g0(gc-RP;C'袋'13\?~"w,-G_KDME R?U=uᄫN8.(08oГ%zG⳪LBdK;}Y{~+pXtנ!__Ϗ~>\踋Lԟvj3r`0۲}Y$,v7>X +" A Q0սq$J@H?߃٧gO ;]ǟ){&-r[7p~zF9YBGÀ= W`F0 )&)1-P3MG}D@ZdпGг!/i<9}fv[w&֜rz1\n߻Qܳ {k+&P=L;#&A&"og/$ŸPa" blbˀ~"xGoľ @4`։'sjtuZkmHr&̳W?7>} wQ$>r%8q^k{7ag{z~x`TWtUW4n5| ͫ1_Hf=ku$YHHc9V@UЭ^;z | T/l+ՉHECHEu$p JV %:K̠Vۙ_ R(A+,_;tN_lg@zh h# f@]'jEJAވtyHhϒ:^QIؚ^Tpz gyYY+EhE+\@1edfVuiDum2re9p.\ѓ 0=oX^''ˢYmիS{ 7bJGvMq"eq2@:h+O22VY[; # ›Dd0Tb 3o\]g [Dсa bRB#$hftm yټϸsS/N)š] i)ߢw5Gnx[Z[ vJnJDw B00=> t2HIFK`9c/ \ 1i@oXǑj7 UI5ɾ689LgXVe0zk;Bf[o<C(~7! |ۏx M4ip=XEN/9]X{vDaFY*ڶ,e8j_=B*?}@"=S`N fGY̫p fj l+:%ȸ7WӮ[hW _g&9XͧPq,m$@9)$q_Fەlw p[SV|UPFಋ/N(Seddl0$_5Ɠty}niZw2ʳ.X*6bRNFFm`(g0_-Ow`Zzk:h`λeD1de###c=`?3y8kROx:7\|dzU&8w bnAkRC(p+\[L&Y ddl$l0ġ59VkV`'.0֖-J$+ CIk_C Z_Yԁ`ʖ>Y{D.^(\,3GlY2pFF4`3oe@OFzX>vg\P81L'j-H̏32ւ# xi",Ff=x To,"lqE"֖bK+"<:9#n` svGnu[Ps塳O)4btmW_~ue1u{t44C`,JhK oWol6> <Ϸ a$;MR z\9b; tm9 ㉾ӐNRP_o^ONaui6IqEq9%DH$ߴz~ :]o[.1n T+751\S~a_<{/(<m6-b#ք [g-Q>{TXˀ7UkeJCKK@l]ɫ?yjA¢ZH %hΌ!p) ͮ$̋WscoՍ݉{dy8~4^4_EfsΥ-h&I] HQNnSjg`]w Mϯ%ؾ?;|e/)ζU ЅmI[ Y߻6죮%mf{N̘޺cmO JGz䠲C7{pW&ޣx&)>^WGL˟6kWXLˏ\ V0Т⊅\=̋nߵZ]}nMˋK} ?m6GȃkD:Wø};?T2xVeSVY `Y-CwM]zػwx^eL~5QTwZ+saI܀6 0cGBr6Z960_|q8W# Y|ܾKW}l_7k쯺 ۄ:t$*ruW׈zSE,Xk!p]GTAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_a <IENDB`doublecmd-0.8.2/pixmaps/mainicon/alt/dcfinal.svg0000664000175000017500000011261311765566230020703 0ustar alexxalexx doublecmd-0.8.2/pixmaps/mainicon/alt/128px-doublecmd.png0000664000175000017500000001736511765566230022116 0ustar alexxalexxPNG  IHDR>abKGDtIME7KIDATx}y\UwRkoIYl@MD6eQqeMy#AF>*7sA~Q!DYe K$@t:Iw.UVuUuUJ,s~;ι<1y *OG݈1UD#T9s!!BrL8ߋFV#֝8_XD/S(0 F_ Ľ(s/~IX0B~*P>?;/~s.JDWpfzS-B^]EGO[nk*Tb "0:f++A^pŅʙ(D =/|\)_B*(}BBqSDHs(|UX&*~%-#iFڱZ $[~6ꚜ@Xw˘-Psǂ BƅqI\}1nQeY%3D=)_4.J S>*>K/8))3HD[8yQʹ5`J}Upe ("IG"/*2__'ZR ?R[BQ0 -ɣZlq+Hs(t5QEWOUIEN fdlol{){*Ыw0xK+/[NBBi Tܒ0/v:eW7=|x+@E'3t/ϔ اl*N >^"KBqʔOq_0@=--:0ztvI]3!e @vsYFmaЪF"B؟f:ƤKzR\wGc1CBh0 IJQ1P,LhkŎ[sѦvK,65-$3(0 ]L4HiL$ [V x 1hpAZ$r& kt!\y4?,ÚEb=e=BxG,|] )ݎ0:3ӎ;ڽ o@/x+!3rO$%سWy  ^)$0,'ưp͚u^+V>\WǸ,(FA@>kl<$dO^7grz_qyRM\ &]4DZPKQ{)BKbh(xJ[Oi cʙܼ@RwND9 k;sf`i\ػރaSYIs?86M&fmېRN"3޼ڟw Yu0ZOdXP=dKSADD"s-$4D%c927 hkB]KbfW`?@%Fs|W Ήd5FX+"\CCZ)9]Xo֎X,6jJ.w_)UMN Gx<#_xigEGkIFUt\-nC,&-ZI\_E4sV4jJf $p{ `̗ ,&V(>h-c]8Mgiu]DϿ}9ȦSBb_$@u]z\KXus'/"̓xWC.`0;$Ym? |4gjg@ `u/qI^xr"C@_|V9}SJ]wG_:^yR@U1>J M֋OiZ1sᱫZ^*c5E7qv@ ȟًL&Sԗ3@u:Ģ0<>p#}ì~^˫ޝpwous 0䝷2 $hĽYJbO(ZN?(!as>u`xl:*j4eW LGXZ~LvMԼ_  uOsKjV-w sJ`& rQr%+ ]?[|6Pm :(t`q Ȝ{ rq_ 41-O[b *Lpa~e y`SB}o-[h bANj/f滏v79oZ_J2kOl)jP7h RW!0xrrTK{id= MCpz}:#B83QKe5 #7+V;!n/75ּayB^V镔\9R_5?Z MEPu]+K-wOJ ca 5=UjS ܋.ɧk4ar+0 Mݥ̓|BK7, X>ByrP0 t 㯾԰,3.ۛN42h-@DbjޱiHm|,gvj4pߛ-uX_.T&Uw<-m|>(ׅ5:k4Gr2 a--U6'@ VI8SW!#@tiSm#w!⭹RNjQM  h98Pw_"vs[J)E-vZLR##ZBSVRpN;-"8}udzwb9@u&t`KVmO`M;տDήM3$ܑp)= vEk_w\w>x %rm' u!(ARBvA8P AY{S-ew,@ vZAcn^.ܽ:S!۶~@{m9ln`V gp'?bӪ-[SjE|LJm-P b0f3Y\ T6 gW!G+΍>~19 d:`[n~42o@{w]R), (رXWՇΡ*5ӏ}?Rzej=j&[8;ނ;4zw]o币<ѿikrp'3 r ]&kE}9si|`e193tﮟp33$Ģ.¥}"k^Ƚn̬RB_˯bR/њ hn6?|_i{y7{*X5a.wfm\P*MTu _D ~Rhi"3 6OlF`~?,$}.Ghg/fQ]pw#1hg~!+(d2)X ?>kӆ/Ex@n LVt=N=]-^}qgDc.%1@$Xq8$(MG:Hח"CXq۬}̇p*E".JaYlF(ނU_V]u =0i8cc3gϞGzŰH C $D70B`3 {=&SւfT@0z7X&_(opύ#q(3#²,躎ο(A)mDfVNn*w94uwGvNiD8okW)%l.c!@[[R ɟ~'S߱jX+[K|sH̰[`4Mm_. c.{_ )} ICJͼś |S4 kSfWC,6@{_O:q,36(Kt 4D`J}ˡ]s-]?.eufx3HaA+:&6@]ųH@\3 ciP 9zPz"O>̹kESadSH|Kl\4%=lXIд4 mmm{ l<"Ռo?j.~L)  uR;Z#G[[[P (tH[Mwh2o^A_xt:ůAi,@8Fkk+Wl=~\w6]Iξ2ښ)8L؄T0M37bASe>n;]Wp#+%ѾL&B\  #,\ÿucNը4x ]&,z#V B0M*9Js$Oo_]BK?sY#5Bt]d{7w)ϙ^"G_~]EW뺅!3efD]aFaΚ#pYncJ?Ht~|90:us/z O"DY (w(x?",l``)kw6cu;ǟDG -GJYhuJCΜ2J48c~`p'xyO?䎷N*<j'@1bUZCѕ]zk Vhx#' x'}w aC!. 88u% P 0Y*a#Y4HCkwVXbD}&V A\m΅ڙGBeE dIL5P7D `דq&m6ҒY1uesgΣ,@@"f½j,%YAV@C'x\8Xe% p]fQR `I}\؊B2]%Ё<5N@g "|RޗYګtb8ּ%hfH,4RX_IK H0l"qabKGDtIME5" IDATxy%Uuk3ݡzlD@FA|$/?O38<5!>38D ($34|izC{QU=w;=|νuNڵk^{<1y"d\{ޑˁƹU#ʜ̉ӭ"FFO(j99^Sλ%y!Aۺv1 L_9#SWpsR*(W =*I=%ټ3ג $j}*QwՃ/)-?{~z)תryR ŤJE)KXejG3gk % pƓ5+lyq%=l]dILUŋf嚿hڼY)qelyWFzP=dzu <"r& Ɨ:D.+dAg+;}P4{=;<z%[Ar06ε|!ym!eಗej3]S}1Fyjq~ܹ hM_觗ǩ1?qKYt)F ""BFg =JFc((>U\į{{PǓbK2x'oyUBTVj,]c XH̢i(R9 jω P}X%w Á%/~ǮYNt/@vU(TP]st]p̑0ceX JU+VمXy:E xʕ :s+G/}Ogg.]y:ZyʊNY::ҎJZZ|?/gJLӏ8B0U ;;( gQ!<B䰎5"×uj+: CAC#rJ|"?.7'![2Vy8UʪrĂD/2^2X* TBG( DʂTwBv0o7N YQp1' N)8@pB^`IG` ߣ̈ %@,|[PTk6+}b$!͊`DkI҈$y2iv(.ѴKZ:D흙?H1b@>b9*0t:D06j,KJ' o F3+` aX+W5~$KT<.!CF(, '@$PD0<ީ oFD^Q,)Je9Eh䈢" }{ڡO2{I V`3``D4&4 ?4KDN;%rzB0!Cq r2s]H:1z ÐrT*D䚳:UTUD&`,wtҹtl8qqRfg}ޥ}wނ؏o 1i{<w)1"İvQ@(x1^r?xݑK/w$GXb ,YAchs>}29cKri5dU}*)(łTbks^,]KzØd!"t.YF_S~w_Q ϒy>ZFJEBG9ja3yA]L:0ưp:ʁvݷΛ[Ks%g IFςn!c"G]D-rT^z!{{9)!%@]Kq%W O|ߝY 5<)Q (9yٻc9- Ei"N|e>R,yOL<|&YD! qNa R,YEl{_Q6HvAC'|5rTˆrqܛΆ.Mq.ǟC!BRTKZx]S𮣋s?ds]8t$pZN/pzH5"s클OuCa`}l+H ےBS!Y1XTˆ r1Du[x_Dr/O72kڪ h?t1#Vh;uw0Lc()'}?^!#ϵ~sc ښ`9׽ !XH?^85PcMfiJvŪΒ#q_ԣ u`ez;Ywr<^qҏ4E)cLU\s PG2b b-ss?WJmn8!g!qS*aD%Xu%<‹$+aL$ \6WFaDVe\!P=K9 =RTcl6Z k9tukbW!Ɋ_;(y9+IðYs?97,\?6)Zӎ^}Qm|! ڸJ E<W H͎P/yօΰ1X$LQRюԶ=-8U/WIaKfUCX~T~WWFX1Lfkp;X;Li'*#Ҫһ};onZZ`0FNW*%QrVbgː@ q|x x"JBad/po]5VY|Y#Bi"6Cg/WO ր;+MD(⤿[).X'#QђE=_w؊/O (lUF(/5'm puF[X3T5 B8Q Q߻-kݲx9G=ha剧IS8, HiΩ*'ƪd7>|2]A{/7ǂ$$_4X r6d7aؚa7ŖN<#xI Gt9 9jwxr|';wvҷP kZH}阿9ֿM6氫/'|}g\YđRGZZ|FM Ą`y,(tunҙ/~ baC?SH^%/ʙ~o7nwEw߯Z.ϣó9OLìٲDP=]y i[Z {E@{i$vL+Z)|`P|~C+;{ IR{,߳]A9噬 56_#@7|Q1ڊ pժ:q c&\4 Qv4sDn5ڎĺ 0AOj&hꄵ PPVlGi۷`DDJܿ( rz\l;hK4n\?,R!,q2QFT: ԓAh0}]n9 |[(` XDfp$&j،2,D}D2^mϰ!@X<1IbiqÈ!хWS-ڎJ\nڝdmgnӄ1(_QjyB±Q WSo_؎n&64ʆ3>lyF4+MeW$ߕYXE>T{k[҂`Ǯ"ڜu.viOm6 'Bՙ:FXm LULF@~w>= 7]OM]V)7TW0! sT*#ڶ!d"qTW÷ ,=udKX` E:>d=چLAxIܳ-Hahr=ۧ]E? 0*=[}贻? x)*2j9!ឧ>0DA@.pJ ϛ?Hh,&/l-pH*e=[myh{MCZTyyL=xěFM 7`J:Vs_J]{ΤwpUhJ}f6G"M}5 n=]tI~V<O<{=#r:,)uʳY!u]۩oy 740zb4~N,8 +VM^׷K,D{q3.sZּ - V (9½;o~HهS*-ZW^6#]c*' r24Ȟ;oqY̲ -αQ8#P ڿG'dMm b,Gi@$NI$݇'/fDF^IԌ 62H1½;E%Rr .~tt@wCܕc<6モ3R'\zrʪTS"O}룸 Ozbx&G]2S}u䍐K759#<}38J|Xb* !wMZlpWxWbaZCU5&sL3; x1h_é,~y#Hp}%M taRS_c pνUoz ӵ2&^(fC0'B;6}\V^U)+TabFNNسhӣGOf|J51loz2o~ԫgj >7c8'ǿR/R(R%-e3MqlۈVFFiR%vĂ c tGϪ,|Kf`֟baM3wk/|Nx>CRQ S =LTR۹(atХ/JNuQl S\D}ϧ$r4::Elg`hy+{ɢk:?p30蔡D#4@L nO IUM6(TSJ/Y(ݴ1٘!86;idЅK<Yt΅=W_lh>ڛ7(!!/Jh`pl?87DXgK.M]ͦo}CvSJrM40$(!KڣxulzT#Pb%1 N] \SD^/d/LZ{wi=vFBe"D+O6_;`ۍ?]?VbgBpWjSⴹrCF`5JAVaWDq݆]4}j(Ecșxfar *DNyg| -\4kcXy٬v^9}[=C-s MI՝(&N%s]ڂ"t }߿Bj.O(Yv۬JH'UD?bg7qУr+`KQ *Cu݀#xFMHoE${,EByAyw;~b:\5XV֬t)^_*wtwvMʖ(٫\̄b=H$(I/-Uo6%gb>p3hm O%c!c>f;Ĕ%ѿJ$>]'%yQ_#N)rT^ 4g `zvXŌGF?GICҿK[YOٙԣ舅)H#e_-inq"= xP/Y6[:=k ۹[5V* ;KT F fwM;Hi%B X%1@r]dqNX#'B[[x1<&lOb2(IcxL: SE~L&"8+ 6QQQ+K%-647Tv(bb+=#koU"&0u:/gR@'K/򛣥uP(A]-g&AcTAϫhF%~nO#A+g <(8яo3[]4oa( < B;mbx2^kW?35cXϼa@tY\j2b1= '0܋U@Wc]7c؁s)yW{#%Fmt_]X2U4QτT/[uD7 X5aoD$8QvꄯM]8&F??kÌT3kܰ|2# ׎V7gP=^&M(:_~פ!ixuPDs5 :3~RDԗf?kx7O[i/¥eQػor\SAd)aFr5鏎 Ӽ5q3fd \۸) B?*U_ڍL6.sSjw*Gd+;&?k0Ietg+12~V woD߳|16=lGht*8WWv$J3m_R]]-N;hb9z5}#UĈ3w#i3E-'Gky#oU7$v rO1yc<&#<IENDB`doublecmd-0.8.2/pixmaps/mainicon/dc_96.svg0000664000175000017500000003764211765566230017437 0ustar alexxalexx doublecmd-0.8.2/pixmaps/mainicon/dc_256.svg0000664000175000017500000003431011765566230017502 0ustar alexxalexx doublecmd-0.8.2/pixmaps/archive_src.ico0000664000175000017500000001712611226363660017166 0ustar alexxalexx  6 h( @ feeed d d c d b b b b a a ` ` _ _ _ ^ ^ ] ^ ] ] \ \ [s~|yvtqnlifda^[ \s}|zxwusrpnmkjhg^ \s}|zxvusrpnmkih_ \s~|{yxvusqonmjia \s~|zywutrpomljc \s}{yxwutrpnlke \s~|{yxvusqomlh \s~|{ywutrqomi \s}|zxvutrpnk \s}{zxvtsrpm \s}|zyxvtrqn \s}|zywvtrq \s}|zxwutr \s|{yxvtu \s~|zywuv \s~{zxwx \s~}{ywz \s}}{y| \s}|z~ \s~}{ \s \s}zxvspppppppppppppps~|ssssssssssssss(, Cvggfeed c c b a a ` _ ^ ^ ] ] \ [k{wsokgc [l~|zwusqnlih \m~{ywuronki \n~{xvtrolj ]o|zxutqnl ^pddddddddd~|zwtrpm _r~{yvsrp _r|zxvsq _tddd|zwvs `uddd{ywt avddddddddd~zxv bw}zw bx~|y cy~{ czrqpnnlkjiKyzuklllllllmzuFzzzzzzs  ?(  \ \ ] ^ ^ ^ ` ` b b cd degjlnnoqstuwxyzW\]`deijmqrvwz~y{||~}  E86420.,(&#!NdROIF@;9 Wg**VQMHC?:"^kZUPKFA=$hm**]XRMKC>%no`[TPMGB'sp**b_YSPKD)ur*ca\VQOJ+vtvL<7531/-qq*jillfedoublecmd-0.8.2/pixmaps/folder-link_src.ico0000664000175000017500000001752611226363660017757 0ustar alexxalexx!  6 h(!@ fddcbba`a_ __ _ ^ _ ^ _ ^ _ _ ^ ^ ] ^ ] ] \ \ [rTFQ}|xvxwutqnlifda^[ \rwF1Phrxwuutuutrrpnmkjhg^ \raƿN"}nb|zywwuvwvuusrpnmkih_ \rTN-؆\~}{yyxxxxwvusqonmjia \rN/\Zö~|||{yywutrpomljc \s6 5N~|{yxwutrpnlke \sd83NNw~|{yxvusqomlh \sN6HNNNw~|{ywutrqomi \sNBWPkN4Nw}|zxvutrpnk \sN>+uXzN?4N|}{zxvtsrpm \sN="}0+ӑNNNN:n4N|}|zyxvtrqn \sN4zy57>>>;jn4N{}|zywvtrq \s1/Ϗ@vuuuutxkhi4Nz}|zxwutr \sN?5wwwuwvohii4N|{yxvtu \ssN?ܚ<+Հ"z#|$}wyhi4N~|zywuv \sqN5=֕4440݅yr4N~{zxwx \sZɱNNNN4|4N~}{ywz \sN44N}}{y| \sN4N}|z~ \sNN~}{ \sN \s}zxvspppppppppppppps~|ssssssssssssss(, c2q9J& !Cvfeccaqxvqpvb\ \ ] ] ] ^ ] ] \ [kP!t\~yyxvsokgc [ls^)Kzxvussrqnlih \m0(֏ S{yxvuronki \nl9ݜ Ro8~}{xvtrolj ]o]ROu\>|zxutqnl ^p^9mD|%s0ڄ0~|zwtrpm _r_(݁/ z V V*yl)|H~{yvsrp _re4t(ڀ,܄,݃(jm#u6|zxvsq _t[ȳ02tvtvogf2߇5|zwvs `u90Ɇ8ד*ف)܂&~zk({&w{ywt avf-]]'xz)|@~zxv bwo4(y}zw bxb3~|y cy?~{ czrqpnnlkjiKyzuklllllllmzuFzzzzzzs  ?(  \ \ ] ^ ^ ^ ` ` b b cd degjlnnoqstuwxyz$kn"qssW\4~]`!deS"iljKm;śLqrQèxԋv?̛Tƫlw%؇[ÿz\ƺZɳ~Fَa˺֯el0`%߷g_PQyO{||~} fXUQKGB<3.(%!nsMOurojga\Y#v5'zwIqmid`[&x/+Ay2plgb]):Z" Nmld_,^9LF7-6$mhc0J1TV=C>ple4}DR@tqok8{v*;WSPHE? ~|doublecmd-0.8.2/docgen.bat0000664000175000017500000000017411740433676014451 0ustar alexxalexxREM http://pasdoc.sourceforge.net pasdoc --marker en --output doc\en\dev-help --define MSWINDOWS --source units-doc-win.txtdoublecmd-0.8.2/pixmaps.txt0000664000175000017500000000066712014201074014727 0ustar alexxalexxavi=video-x-generic bat=application-x-shellscript deb=application-x-deb doc=x-office-document htm=text-html html=text-html iso=application-x-cd-image jpeg=image-x-generic jpg=image-x-generic log=text-x-log mp2=audio-x-generic mp3=audio-x-generic ods=x-office-spreadsheet odt=x-office-document pas=text-x-pascal pdf=application-pdf po=text-x-po rpm=application-x-rpm sh=application-x-shellscript txt=text-x-generic xls=x-office-spreadsheet doublecmd-0.8.2/clean.bat0000664000175000017500000000335613110070213014252 0ustar alexxalexx@echo Clean up output directory @del /Q /S units\i386-win32-win32\*.* @del /Q /S units\x86_64-win64-win32\*.* @del /Q src\*.*~ @del /Q src\*.~* @del /Q doublecmd.dbg @del /Q doublecmd.zdli @del /Q doublecmd*.exe @del /Q doublecmd*.old @echo Remove generated help files @del /Q doc\en\dev-help\*.* @echo Clean up tools output directories @del /Q /S tools\lib\*.* @del /Q tools\extractdwrflnfo.exe @echo Clean up plugins output directories @del /Q /S plugins\*.dsx @del /Q /S plugins\*.w?x @del /Q /S plugins\dsx\DSXLocate\lib\*.* @del /Q /S plugins\wcx\cpio\lib\*.* @del /Q /S plugins\wcx\deb\lib\*.* @del /Q /S plugins\wcx\lzma\lib\*.* @del /Q /S plugins\wcx\rpm\lib\*.* @del /Q /S plugins\wcx\sevenzip\lib\*.* @del /Q /S plugins\wcx\unbz2\lib\*.* @del /Q /S plugins\wcx\unrar\lib\*.* @del /Q /S plugins\wcx\zip\lib\*.* @del /Q /S plugins\wdx\deb_wdx\lib\*.* @del /Q /S plugins\wdx\rpm_wdx\lib\*.* @del /Q /S plugins\wdx\svn_wdx\lib\*.* @del /Q /S plugins\wdx\xpi_wdx\lib\*.* @del /Q /S plugins\wfx\ftp\lib\*.* @del /Q /S plugins\wfx\gvfs\lib\*.* @del /Q /S plugins\wfx\samba\lib\*.* @del /Q /S plugins\wfx\sample\lib\*.* @del /Q /S plugins\wlx\simplewlx\lib\*.* @del /Q /S plugins\wlx\WlxMplayer\lib\*.* @echo Remove backup files @del /Q /S plugins\*.*~ @del /Q /S plugins\*.bak @echo Clean up components output directories @del /Q /S components\chsdet\lib\*.* @del /Q /S components\CmdLine\lib\*.* @del /Q /S components\dcpcrypt\lib\*.* @del /Q /S components\doublecmd\lib\*.* @del /Q /S components\gifanim\lib\*.* @del /Q /S components\KASToolBar\lib\*.* @del /Q /S components\multithreadprocs\lib\*.* @del /Q /S components\viewer\lib\*.* @del /Q /S components\synunihighlighter\lib\*.* @echo Done.doublecmd-0.8.2/doc/0000775000175000017500000000000013244011205013242 5ustar alexxalexxdoublecmd-0.8.2/doc/changelog.txt0000664000175000017500000002435112014201074015736 0ustar alexxalexx-------------------------------------------------------------------------------- 08.10.2011 Release Double Commander 0.5.1 beta -------------------------------------------------------------------------------- 08.10.2011 FIX: Access violation when open archive with symbolic links 05.10.2011 FIX: Bug [3417849] Typo in options section: thubnails->thumbnails. 01.10.2011 FIX: Bug [3402974] Problems with SAMBA resources with authorization 30.09.2011 FIX: Bug [3416235] Incorrect default path to Lua library 30.09.2011 FIX: Bug [3411184] Can not extract empty folder from archive 30.09.2011 FIX: Bug [3415942] Editor->Search&Replace field order is bad... 28.09.2011 FIX: List index out of bounds on deleting separator from toolbar (bug [3415074]). 27.09.2011 FIX: Copying full paths of filenames from search result. 22.09.2011 UPD: Czech language file from Martin Štrobl. 10.09.2011 UPD: Russian language file 09.09.2011 FIX: [Zip plugin] Slow opening of big archives; speed up test operation. 09.09.2011 FIX: Force date, time separators to /, : in case they are UTF-8 characters in current locale (Unix). 08.09.2011 FIX: Try to fix access violation when accessing empty DVD drive (bug [3404533]) 07.09.2011 UPD: Traditional Chinese language file by mlance_2 07.09.2011 FIX: Build libmime with large file support (bug [3403818]). 06.09.2011 FIX: Multi rename files with not ASCII names and using range 04.09.2011 FIX: Move files when can not copy attributes (e.g. move files from NTFS to EXT3 file system under Linux) 03.09.2011 FIX: Delete HotDir with item index = 0 02.09.2011 FIX: Access violation error with some wcx and wfx plugins -------------------------------------------------------------------------------- 28.08.2011 Release Double Commander 0.5.0 beta -------------------------------------------------------------------------------- 21.08.2010 Release Double Commander 0.4.5.2 beta -------------------------------------------------------------------------------- 15.08.2010 FIX: Use case insensitive compare for verify checksum operation 20.04.2010 FIX: Bug [2989234] Does not work with icloud 10.04.2010 ADD: Korean language file by Lee, Cheon-Pung 02.03.2010 UPD: Use Escape key to leave editing command line and focus files panel when command line is empty [2961106]. 01.03.2010 UPD: Ukrainian language file by Ma$terok 01.03.2010 UPD: Polish language file by Krzysztof Modelski 01.03.2010 FIX: Sorting files by size if size > 4GB (bug [2960850]). 25.02.2010 FIX: Bug [2957145] Directory hotlist hotkey issue 25.02.2010 FIX: Bug [2957145] Directory hotlist hotkey issue 25.02.2010 FIX: Bug [2957159] File type color dialog color selection 24.02.2010 ADD: Polish language file by Krzysztof Modelski 24.02.2010 FIX: Get content plugin name 24.02.2010 FIX: ContentGetDetectString function 23.02.2010 FIX: Cross compiling unrar plugin from Linux 32 to 64 -------------------------------------------------------------------------------- 22.02.2010 Release Double Commander 0.4.5.1 beta -------------------------------------------------------------------------------- 22.02.2010 UPD: Better error message when error in CopyFile. 22.02.2010 FIX: Crash in CopyFile when cannot read file. 21.02.2010 FIX: Bug [2955066] Split file 19.02.2010 FIX: Unneeded separator in Actions submenu if no actions were added. 19.02.2010 FIX: Some fixes for bug [2954358] error with write permissions 17.02.2010 UPD: Ukrainian language file by Ma$terok 17.02.2010 UPD: English help files by Rod J 14.02.2010 ADD: File search in multiply directories 13.02.2010 FIX: Hangs on load string from incorrect language file 13.02.2010 UPD: Czech language from Petr Stasiak 12.02.2010 FIX: Bug [2947859] "terminal window size+Apply in preferences". 11.02.2010 FIX: "Open with" under Windows 11.02.2010 UPD: Language files. 11.02.2010 FIX: Changed '=' TargetEqualSource to '>' RightEqualLeft and '<' LeftEqualRight (bug [2947845]). 10.02.2010 FIX: Bug [2947846] '..' item always becomes current if going up inside an archive 10.02.2010 FIX: Crash in drag&drop on Windows Vista/7. 07.02.2010 FIX: Create directory on empty disk 02.02.2010 FIX: Bug [2944649] Copy files 02.02.2010 FIX: Check if application is active instead of checking main form's focus if FileWatcher should not work when application is in the background. This fixes the issue where refreshing file list is not working even when DC is active. 29.01.2010 FIX: Don't execute hotkeys that coincide with quick search combination 27.01.2010 FIX: Drive panel alignment 27.01.2010 FIX: Encoding in Zip archives 27.01.2010 FIX: Rar stores file name in OEM encoding (from RAR documentation) 26.01.2010 FIX: Find files in hidden directories 26.01.2010 FIX: Find hidden folders 25.01.2010 FIX: Don't copy last LineEnding when copy file names to clipboard 24.01.2010 FIX: Bug [2938523] Console 23.01.2010 FIX: Case insensitive file search for non ACSII file names 23.01.2010 FIX: Debian package: Section name 23.01.2010 FIX: Debian package: add "Maintainer" and "Depends" fields 22.01.2010 FIX: Debian package architecture for Linux 64 bit 21.01.2010 FIX: Add Wfx plugins from options dialog 20.01.2010 FIX: Stretch bitmaps from file associations manager 19.01.2010 UPD: File properties dialog interface alignment 19.01.2010 UPD: Options dialog interface alignment 19.01.2010 FIX: Unpack multivolume archives 16.01.2010 FIX: Show only actions names in "Actions submenu" 16.01.2010 FIX: Incorrect save/load search/replace history 16.01.2010 UPD: Use new icon in About window. 15.01.2010 FIX: Case insensitive quick search for non ASCII symbols 15.01.2010 FIX: Viewer/editor window getting bigger every time it is opened (bug [2924166]). 15.01.2010 FIX: Error when can not read/write file description 15.01.2010 FIX: Delete to trash with file paths containing spaces. Fix reading error from gvfs-trash. 13.01.2010 FIX: Skip all files in move operation 13.01.2010 FIX: Bug [2930960] doublecmd.sh -------------------------------------------------------------------------------- 10.01.2009 Release Double Commander 0.4.5 beta -------------------------------------------------------------------------------- 17.05.2009 ADD: Feature Request [2777123] Show occupied space 14.03.2009 FIX: Bug [ 2650798 ] WCX plugins not work property... -------------------------------------------------------------------------------- 28.02.2009 Release Double Commander 0.4 beta -------------------------------------------------------------------------------- 31.01.2009 FIX: Bug [ 2513089 ] panel 18.01.2009 ADD: Drag&Drop to external applications under Windows 18.01.2009 FIX: Bug [ 2513084 ] tabs 12.01.2009 ADD: Pause/Start file operations 11.01.2009 FIX: Bug [ 2496645 ] sort files 05.01.2009 FIX: Bug [ 2403796 ] removing tabs 25.12.2008 FIX: Bug [ 2434007 ] translate mistakes 23.12.2008 FIX: Bug [ 2433957 ] hidden column 13.12.2008 FIX: Bug [ 2421650 ] colors submenu 13.12.2008 FIX: Bug [ 2423750 ] scrollbar in about window 12.12.2008 FIX: Bug [ 2421607 ] different fonts 12.12.2008 FIX: Bug [ 2421601 ] border 09.12.2008 FIX: Bug [ 2403863 ] rubbish after copying 07.12.2008 ADD: Feature Request [ 2404017 ] context menu for Drive button menu 05.12.2008 FIX: Bug [ 2383944 ] drive buttons 03.12.2008 FIX: Bug [ 2379193 ] font at first line 16.11.2008 FIX: Bug [ 1696012 ] Copying in Linux 26.10.2008 FIX: Bug [ 1989488 ] Don't change interface language 15.10.2008 FIX: Bug [ 1741043 ] Copying 13.10.2008 FIX: Bug [ 1874281 ] "No enough free space" instead "Permition denied" 07.09.2009 FIX: Bug [ 1971187 ] Don't work with user rights 07.09.2008 FIX: Bug [ 1934572 ] Zip plugin is down on open read only archive 21.08.2008 ADD: Feature Request [ 1938593 ] More suitable and powerful plugin configuration 18.08.2008 ADD: Feature Request [ 1870517 ] Don't show not critical error messages 09.07.2008 ADD: Feature Request [ 2014247 ] Drive context menu 06.07.2008 ADD: Feature Request [ 1996336 ] Drag&Drop support 06.07.2008 FIX: Bug [ 1947579 ] Quick search by letter and non-alpha characters 03.07.2008 FIX: Bug [ 1945378 ] Crash on changing icon size 17.05.2008 ADD: Feature Request [ 1951507 ] Wipe file 02.05.2008 ADD: Feature Request [ 1880894 ] Open in tab directory under cursor (Ctrl+Up) 28.04.2008 FIX: Bug [ 1953396 ] Error if "Directory hotlist" (Ctrl+D) is empty -------------------------------------------------------------------------------- 15.04.2008 Release Double Commander 0.3.5 alpha -------------------------------------------------------------------------------- 12.04.2008 FIX: Bug [ 1938948 ] Drive chooser shortcuts missing 08.04.2008 FIX: Bug [ 1870771 ] Remove plugin. 04.04.2008 FIX: Bug [ 1934290 ] It is impossible reassign icons for some types. 23.03.2008 FIX: Bug [ 1870551 ] F3 on directory. 23.03.2008 FIX: Bug [ 1921004 ] Error with display drive name on drive menu button. 12.03.2008 FIX: Bug [ 1888653 ] file panel and copy/move 06.03.2008 FIX: Bug [ 1860836 ] "Show" does not refresh 05.03.2008 FIX: Bug [ 1860660 ] Non-translatable strings 28.02.2008 FIX: The filedate of the copied file is <> to original file date (Windows) unlike TotalCmd. 17.02.2008 FIX: Bug [ 1880539 ] Context menu for directory. 04.02.2008 FIX: Bug [ 1886005 ] Быстрый поиск - завешивает. 03.02.2008 FIX: Bug [ 1869787 ] Options -> Colors -> File types and attributes 03.02.2008 ADD: Feature Request [1880515] Enhanced quick search 03.02.2008 FIX: Bug [ 1870552 ] Alt quick search 30.01.2008 FIX: Bug [ 1870808 ] Execute files under Linux 27.01.2008 ADD: Options page "Configuration storage" 26.01.2008 ADD: UnRAR plugin (now it working under Windows and Linux) 26.01.2008 ADD: Feature Request [ 1869250 ] Try to open archive by Ctrl+PageDown 18.01.2008 FIX: Bug [ 1869790 ] Options -> File types colors - illogical 17.01.2007 FIX: Bug [ 1869784 ] Directories and diff 17.01.2007 FIX: Bug [ 1870772 ] lynx navigation, "right" for "up level" 13.01.2007 FIX: Bug [ 1869757 ] External editor 13.01.2007 FIX: Bug [ 1869786 ] External diff - DC not send file. 11.01.2008 FIX: Bug [ 1869243 ] lynx navigation and enter in arhives. 11.01.2008 FIX: Bug [ 1860652 ] "Run Term" Opens terminal in last accessed directory, not in current panel's directory 11.01.2008 FIX: Bug [ 1861911 ] must add version.inc 10.01.2008 FIX: Bug [ 1860271 ] lynx navigation and archives -------------------------------------------------------------------------------- 26.12.2007 Release Double Commander 0.3 alpha doublecmd-0.8.2/doc/COPYING.txt0000664000175000017500000004325412137141242015130 0ustar alexxalexx GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. doublecmd-0.8.2/doc/COPYING.LGPL.txt0000664000175000017500000006144712137141242015671 0ustar alexxalexx GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! doublecmd-0.8.2/doc/COPYING.modifiedLGPL.txt0000664000175000017500000000235312014201074017353 0ustar alexxalexxThis is the file COPYING.modifiedLGPL, it applies to several units in the Lazarus sources distributed by members of the Lazarus Development Team. All files contains headers showing the appropriate license. See there if this modification can be applied. These files are distributed under the Library GNU General Public License (see the file COPYING.LGPL) with the following modification: As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. If you didn't receive a copy of the file COPYING.LGPL, contact: Free Software Foundation, Inc., 675 Mass Ave Cambridge, MA 02139 USA doublecmd-0.8.2/doc/COPYING.FPC.txt0000664000175000017500000000227512606472177015554 0ustar alexxalexxThis is the file COPYING.FPC, it applies to the Free Pascal Run-Time Library (RTL) and packages (packages) distributed by members of the Free Pascal Development Team. The source code of the Free Pascal Runtime Libraries and packages are distributed under the Library GNU General Public License (see the file COPYING) with the following modification: As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. If you didn't receive a copy of the file COPYING, contact: Free Software Foundation 675 Mass Ave Cambridge, MA 02139 USA doublecmd-0.8.2/doc/INSTALL.txt0000664000175000017500000000437612667357511015150 0ustar alexxalexxCompiling Double Commander 1) What you need? Double Commander is developed with Free Pascal and Lazarus. Current version requires at least FPC 2.6.4 and Lazarus 1.4.2. 2) Using the IDE to develop and build DC. If you want to use Lazarus IDE to develop Double Commander, first you have to install a few additional components all of which reside in components directory of DC sources. You must open each .lpk package file: - chsdet/chsdet.lpk - CmdLine/cmdbox.lpk - multithreadprocs/multithreadprocslaz.lpk - dcpcrypt/dcpcrypt.lpk - doublecmd/doublecmd_common.lpk - KASToolBar/kascomp.lpk - gifanim/pkg_gifanim.lpk - viewer/viewerpackage.lpk and install it into Lazarus (menu: Package -> Open package file (.lpk) -> Browse to needed .lpk file -> Press "Install", if "Install" disabled then press "Compile" instead). Choose "No" when asked for rebuilding Lazarus after each package then rebuild Lazarus when you have installed all of them. After rebuilding Lazarus open the project file src/doublecmd.lpi. Compile. 3) Building DC from command line. From command line (Windows) Use build.bat script to build DC on Windows. First you need the lazbuild utility of Lazarus to be somewhere in your PATH or you need to edit the build script and change the lazpath variable to point to it. Execute the script to start the build process. Make sure you use all parameter if you're building for the first time, so that also components and plugins are built: > build.bat all or alternatively without plugins > build.bat components > build.bat From command line (Linux) Use build.sh script to build DC on Windows. First you need the lazbuild utility of Lazarus to be somewhere in your PATH and if you installed a Lazarus package it should already be there. Otherwise you need to edit the build script and change the lazbuild variable to point to it. On Linux two widgetsets are supported: GTK2 or QT4. You can choose one by setting lcl environment variable before executing the script to either gtk2 or qt, for example: $ lcl=qt ./build.sh Execute the script to start the build process. Make sure you use all parameter if you're building for the first time, so that also components and plugins are built: $ ./build.sh all or alternatively without plugins $ ./build.sh components $ ./build.sh doublecmd-0.8.2/doc/README.txt0000664000175000017500000000373212667357511014772 0ustar alexxalexx******************************************************************************** Double Commander ******************************************************************************** Double Commander is a cross platform open source file manager with two panels side by side. It is inspired by Total Commander and features some new ideas. ******************************************************************************** For details of compiling see the file INSTALL.txt. ******************************************************************************** ** This program is free software; you can redistribute it and/or modify ** ** it under the terms of the GNU General Public License as published by ** ** the Free Software Foundation; either version 2 of the License, or ** ** (at your option) any later version. ** ** ** ** This program is distributed in the hope that it will be useful, ** ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** ** GNU General Public License for more details. ** ** ** ** You should have received a copy of the GNU General Public License ** ** along with this program; if not, write to the Free Software ** ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ******************************************************************************** ** ** ** For more details about license see the file COPYING.txt. ** ** ** ********************************************************************************doublecmd-0.8.2/components/0000775000175000017500000000000013244011205014662 5ustar alexxalexxdoublecmd-0.8.2/components/gifanim/0000775000175000017500000000000013244011205016274 5ustar alexxalexxdoublecmd-0.8.2/components/gifanim/pkg_gifanim.lpk0000664000175000017500000000305012334444240021265 0ustar alexxalexx doublecmd-0.8.2/components/gifanim/gifanim.lrs0000664000175000017500000000351411376245253020453 0ustar alexxalexxLazarusResources.Add('tgifanim','XPM',[ '/* XPM */'#13#10'static char * gifanim_xpm[] = {'#13#10'"24 24 31 1",'#13#10 +'" '#9'c None",'#13#10'".'#9'c #959595",'#13#10'"+'#9'c #E1E1E1",'#13#10'"@' +#9'c #919191",'#13#10'"#'#9'c #848484",'#13#10'"$'#9'c #888888",'#13#10'"%'#9 +'c #EEEEEE",'#13#10'"&'#9'c #E6E9EC",'#13#10'"*'#9'c #D6DFE8",'#13#10'"='#9 +'c #FFFFFF",'#13#10'"-'#9'c #E7F0F9",'#13#10'";'#9'c #3783CE",'#13#10'">'#9 +'c #FFF7F7",'#13#10'",'#9'c #FFEFEF",'#13#10'"'''#9'c #F7F2F5",'#13#10'")'#9 +'c #F7FAFD",'#13#10'"!'#9'c #FF5757",'#13#10'"~'#9'c #FFDFDF",'#13#10'"{'#9 +'c #FF4F4F",'#13#10'"]'#9'c #FFD7D7",'#13#10'"^'#9'c #FF4747",'#13#10'"/'#9 +'c #FF3F3F",'#13#10'"('#9'c #8D8D8D",'#13#10'"_'#9'c #EEE6E6",'#13#10'":'#9 +'c #EED6D6",'#13#10'"<'#9'c #EECECE",'#13#10'"['#9'c #FAFAFA",'#13#10'"}'#9 +'c #F2F2F2",'#13#10'"|'#9'c #F6F6F6",'#13#10'"1'#9'c #A2A2A2",'#13#10'"2'#9 +'c #FAF2F2",'#13#10'" .++@ @++. ",'#13#10'" @@@##$$$$$$$$$$$$##' +'@@@ ",'#13#10'" .++$#$$$$$$$$$$$$#$++. ",'#13#10'" .++@+%%&**&&**&%%+@++. "' +','#13#10'" @@@@%==-;;--;;-==%@@@@ ",'#13#10'" .++.%==-;;--;;-==%.++. ",'#13 +#10'" .++.%>,''--))--'',>%.++. ",'#13#10'" @@@@%,!~>====>~!,%@@@@ ",'#13#10 +'" .++.%>~{]~~~~]{~>%.++. ",'#13#10'" .++.%=>~^////^~>=%.++. ",'#13#10'" @@@' +'(+%%_:<<<<:_%%+(@@@ ",'#13#10'" .++$#$$$$$$$$$$$$#$++. ",'#13#10'" .++$#$$$' +'$$$$$$$$$#$++. ",'#13#10'" @@@(+%%&**&%%%%%%+(@@@ ",'#13#10'" .++.%==-;;-[}' +'}[==%.++. ",'#13#10'" .++.%==-;;-|11|==%.++. ",'#13#10'" @@@@%>,''--)[}}2,>' +'%@@@@ ",'#13#10'" .++.%,!~>====>~!,%.++. ",'#13#10'" .++.%>~{]~~~~]{~>%.++.' +' ",'#13#10'" @@@@%=>~^////^~>=%@@@@ ",'#13#10'" .++@+%%_:<<<<:_%%+@++. ",' +#13#10'" .++$#$$$$$$$$$$$$#$++. ",'#13#10'" @@@##$$$$$$$$$$$$##@@@ ",'#13#10 +'" .++@ @++. "};'#13#10 ]); doublecmd-0.8.2/components/gifanim/doublecmd.diff0000664000175000017500000002410212334444240021073 0ustar alexxalexxIndex: gifanim.pas =================================================================== --- gifanim.pas (revision none) +++ gifanim.pas (working copy) @@ -26,7 +26,7 @@ uses Classes, LCLProc, Lresources, SysUtils, Controls, Graphics, ExtCtrls, - IntfGraphics, FPimage, Contnrs, GraphType, dialogs; + IntfGraphics, FPimage, Contnrs, GraphType, dialogs, types; const @@ -193,7 +193,7 @@ procedure DoAutoSize; override; procedure DoStartAnim; procedure DoStopAnim; - class function GetControlClassDefaultSize: TPoint; override; + class function GetControlClassDefaultSize: TSize; override; procedure GifChanged; procedure LoadFromFile(const Filename: string); virtual; procedure Paint; override; @@ -203,6 +203,8 @@ { Public declarations } constructor Create(AOwner: TComponent); override; destructor Destroy; override; + procedure NextFrame; + procedure PriorFrame; property Empty: boolean Read FEmpty; property GifBitmaps: TGifList Read FGifBitmaps; property GifIndex: integer Read FCurrentImage; @@ -237,28 +239,9 @@ implementation -uses LazIDEIntf, propedits; -Type - TGifFileNamePropertyEditor=class(TFileNamePropertyEditor) - protected - function GetFilter: String; override; - function GetInitialDirectory: string; override; - end; -function TGifFileNamePropertyEditor.GetFilter: String; -begin - Result := 'GIF|*.gif'; -end; - -function TGifFileNamePropertyEditor.GetInitialDirectory: string; -begin - Result:= ExtractFilePath(LazarusIDE.ActiveProject.ProjectInfoFile); -end; - procedure Register; begin RegisterComponents('Wile64', [TGifAnim]); - RegisterPropertyEditor(TypeInfo(String), - TGifAnim, 'FileName', TGifFileNamePropertyEditor); end; { TGifAnim } @@ -268,7 +251,7 @@ inherited Create(AOwner); ControlStyle := [csCaptureMouse, csClickEvents, csDoubleClicks]; AutoSize := True; - SetInitialBounds(0, 0, GetControlClassDefaultSize.X, GetControlClassDefaultSize.Y); + SetInitialBounds(0, 0, GetControlClassDefaultSize.CX, GetControlClassDefaultSize.CY); FEmpty := True; FCurrentImage := 0; CurrentView := TBitmap.Create; @@ -295,6 +278,59 @@ CurrentView.Free; end; +procedure TGifAnim.NextFrame; +begin + if (not FEmpty) and Visible and (not FAnimate) then + begin + if FCurrentImage >= GifBitmaps.Count - 1 then + FCurrentImage := 0 + else + Inc(FCurrentImage); + if Assigned(FOnFrameChanged) then + FOnFrameChanged(Self); + Repaint; + end; +end; + +procedure TGifAnim.PriorFrame; +var + DesiredImage: Integer; +begin + if (not FEmpty) and Visible and (not FAnimate) then + begin + if FCurrentImage = 0 then + DesiredImage:= GifBitmaps.Count - 1 + else + DesiredImage:= FCurrentImage - 1; + // For proper display repaint image from first frame to desired frame + FCurrentImage:= 0; + while FCurrentImage < DesiredImage do + begin + with GifBitmaps.Items[FCurrentImage] do + begin + BufferImg.Canvas.Brush.Color := (Self.Color); + if FCurrentImage = 0 then + BufferImg.Canvas.FillRect(Rect(0, 0, Width, Height)); + if Delay <> 0 then + FWait.Interval := Delay * 10; + BufferImg.Canvas.Draw(PosX, PosY, Bitmap); + case Method of + //0 : Not specified... + //1 : No change Background + 2: BufferImg.Canvas.FillRect( + Rect(PosX, PosY, Bitmap.Width + PosX, Bitmap.Height + PosY)); + + 3: BufferImg.Canvas.FillRect(Rect(0, 0, Width, Height)); + end; + end; + Inc(FCurrentImage); + end; + if Assigned(FOnFrameChanged) then + FOnFrameChanged(Self); + Repaint; + end; +end; + function TGifAnim.LoadFromLazarusResource(const ResName: String): boolean; var GifLoader: TGifLoader; @@ -340,12 +376,13 @@ begin if (not Empty) and Visible then begin - if FCurrentImage > GifBitmaps.Count - 1 then - FCurrentImage := 0; - if assigned(FOnFrameChanged) then - FOnFrameChanged(self); - Paint; - Inc(FCurrentImage); + if FCurrentImage >= GifBitmaps.Count - 1 then + FCurrentImage := 0 + else + Inc(FCurrentImage); + if Assigned(FOnFrameChanged) then + FOnFrameChanged(Self); + Repaint; end; end; @@ -365,27 +402,12 @@ end; procedure TGifAnim.SetFileName(const AValue: string); -var - fn: string; begin - - if (FFileName = AValue) then - exit; + if (FFileName = AValue) then Exit; FFileName := AValue; ResetImage; - if (FFileName = '') then exit; - if (csDesigning in ComponentState) then - begin - fn:= ExtractFileName(AValue); - FFileName:= ExtractFilePath(AValue); - FFileName:= ExtractRelativepath(ExtractFilePath(LazarusIDE.ActiveProject.ProjectInfoFile) ,FFileName); - FFileName:=FFileName+fn; - LoadFromFile(FFileName+fn); - end - else begin - FFileName := AValue; - LoadFromFile(FFileName); - end; + if (FFileName = '') then Exit; + LoadFromFile(FFileName); if not Empty then GifChanged; end; @@ -441,10 +463,10 @@ end; end; -class function TGifAnim.GetControlClassDefaultSize: TPoint; +class function TGifAnim.GetControlClassDefaultSize: TSize; begin - Result.X := 90; - Result.Y := 90; + Result.CX := 90; + Result.CY := 90; end; procedure TGifAnim.GifChanged; Index: gifanimdsgn.pas =================================================================== --- gifanimdsgn.pas (revision 0) +++ gifanimdsgn.pas (revision 0) @@ -0,0 +1,41 @@ +unit GifAnimDsgn; + +{$mode objfpc}{$H+} + +interface + +uses + LazIDEIntf, PropEdits; + +Type + TGifFileNamePropertyEditor = class(TFileNamePropertyEditor) + protected + function GetFilter: String; override; + function GetInitialDirectory: string; override; + end; + +procedure Register; + +implementation + +uses + SysUtils, GifAnim; + +function TGifFileNamePropertyEditor.GetFilter: String; +begin + Result := 'GIF|*.gif'; +end; + +function TGifFileNamePropertyEditor.GetInitialDirectory: string; +begin + Result:= ExtractFilePath(LazarusIDE.ActiveProject.ProjectInfoFile); +end; + +procedure Register; +begin + RegisterPropertyEditor(TypeInfo(String), TGifAnim, + 'FileName', TGifFileNamePropertyEditor); +end; + +end. + Index: pkg_gifanim.lpk =================================================================== --- pkg_gifanim.lpk (revision none) +++ pkg_gifanim.lpk (working copy) @@ -1,15 +1,21 @@ - + - + + - + - + + + + + + @@ -33,15 +39,16 @@ - + - + + - + Index: pkg_gifanim_dsgn.lpk =================================================================== --- pkg_gifanim_dsgn.lpk (revision 0) +++ pkg_gifanim_dsgn.lpk (revision 0) @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: pkg_gifanim_dsgn.pas =================================================================== --- pkg_gifanim_dsgn.pas (revision 0) +++ pkg_gifanim_dsgn.pas (revision 0) @@ -0,0 +1,21 @@ +{ This file was automatically created by Lazarus. Do not edit! + This source is only used to compile and install the package. + } + +unit pkg_gifanim_dsgn; + +interface + +uses + GifAnimDsgn, LazarusPackageIntf; + +implementation + +procedure Register; +begin + RegisterUnit('GifAnimDsgn', @GifAnimDsgn.Register); +end; + +initialization + RegisterPackage('pkg_gifanim_dsgn', @Register); +end. doublecmd-0.8.2/components/gifanim/readme.txt0000664000175000017500000000024712043464010020277 0ustar alexxalexxGifAnim http://wile64.perso.neuf.fr/download/download.php?cat=4&id=8 Version 1.4 (14/09/2009) Some modifications done for Double Commander (see doublecmd.diff). doublecmd-0.8.2/components/gifanim/ressource-file.txt0000664000175000017500000000075212014201074021767 0ustar alexxalexx 1) Gif in ressource file ------------------------- - Create ressource file with lazres ex : lazres mygif.lrs gif1.gif gif2.gif - Put TGifAnim on your form - In the FormCreate add (see down) [code] procedure TForm1.FormCreate(Sender: TObject); begin GifAnim1.LoadFromLazarusResource('gif1'); GifAnim2.LoadFromLazarusResource('gif2'); end; [/code] - And insert ressouce file in initialization section (see down) [code] initialization {$I unit1.lrs} {$I mesgif.lrs} [/code] doublecmd-0.8.2/components/gifanim/gifanim.pas0000664000175000017500000007214212334444240020431 0ustar alexxalexx{ Copyright (C) 2009 Laurent Jacques This source is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. A copy of the GNU General Public License is available on the World Wide Web at . You can also obtain it by writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Version 1.4 } unit GifAnim; {$mode objfpc}{$H+} interface uses Classes, LCLProc, Lresources, SysUtils, Controls, Graphics, ExtCtrls, IntfGraphics, FPimage, Contnrs, GraphType, dialogs, types; const EXT_INTRODUCER = $21; EXT_GRAPHICS_CONTROL = $F9; EXT_PLAIN_TEXT = $01; EXT_APPLICATION = $FF; EXT_COMMENT = $FE; DSC_LOCAL_IMAGE = $2C; ID_TRANSPARENT = $01; ID_COLOR_TABLE_SIZE = $07; ID_SORT = $20; ID_INTERLACED = $40; ID_COLOR_TABLE = $80; ID_IMAGE_DESCRIPTOR = $2C; ID_TRAILER = $3B; CODE_TABLE_SIZE = 4096; type TRGB = packed record Red, Green, Blue: byte; end; TGIFHeader = packed record Signature: array[0..2] of char; //* Header Signature (always "GIF") */ Version: array[0..2] of char; //* GIF format version("87a" or "89a") */ ScreenWidth: word; //* Width of Display Screen in Pixels */ ScreenHeight: word; //* Height of Display Screen in Pixels */ Packedbit, //* Screen and Color Map Information */ BackgroundColor, //* Background Color Index */ AspectRatio: byte; //* Pixel Aspect Ratio */ end; TGifImageDescriptor = packed record Left, //* X position of image on the display */ Top, //* Y position of image on the display */ Width, //* Width of the image in pixels */ Height: word; //* Height of the image in pixels */ Packedbit: byte; //* Image and Color Table Data Information */ end; TGifGraphicsControlExtension = packed record BlockSize, //* Size of remaining fields (always 04h) */ Packedbit: byte; //* Method of graphics disposal to use */ DelayTime: word; //* Hundredths of seconds to wait */ ColorIndex, //* Transparent Color Index */ Terminator: byte; //* Block Terminator (always 0) */ end; TGifAnim = class; { TGifImage } TGifImage = class private FBitmap: TBitmap; FPosX: word; FPosY: word; FDelay: word; FMethod: byte; public constructor Create; destructor Destroy; override; property Bitmap: TBitmap Read FBitmap; property Delay: word Read FDelay; property Method: byte Read FMethod; property PosX: word Read FPosX; property PosY: word Read FPosY; end; { TGifList } TGifList = class(TObjectList) private protected function GetItems(Index: integer): TGifImage; procedure SetItems(Index: integer; AGifImage: TGifImage); public function Add(AGifImage: TGifImage): integer; function Extract(Item: TGifImage): TGifImage; function Remove(AGifImage: TGifImage): integer; function IndexOf(AGifImage: TGifImage): integer; function First: TGifImage; function Last: TGifImage; procedure Insert(Index: integer; AGifImage: TGifImage); property Items[Index: integer]: TGifImage Read GetItems Write SetItems; default; end; { TGifLoader } TGifLoader = class private FGifHeader: TGIFHeader; FGifDescriptor: TGifImageDescriptor; FGifGraphicsCtrlExt: TGifGraphicsControlExtension; FGifUseGraphCtrlExt: boolean; FGifBackgroundColor: byte; FInterlaced: boolean; FScanLine: PByte; FLineSize: integer; FDisposalMethod: byte; FEmpty: boolean; FFileName: string; FHeight: integer; FIsTransparent: boolean; FWidth: integer; FPalette: TFPPalette; FLocalHeight: integer; FLocalWidth: integer; procedure ReadPalette(Stream: TStream; Size: integer); procedure ReadScanLine(Stream: TStream); procedure ReadHeader(Stream: TStream); procedure ReadGlobalPalette(Stream: TStream); procedure ReadGraphCtrlExt; procedure SetInterlaced(const AValue: boolean); procedure SetTransparent(const AValue: boolean); function SkipBlock(Stream: TStream): byte; procedure WriteScanLine(Img: TFPCustomImage); procedure ReadGifBitmap(Stream: TStream); public constructor Create(const FileName: string); destructor Destroy; override; function LoadAllBitmap(var AGifList: TGifList): boolean; function LoadFromLazarusResource(const ResName: String; var AGifList: TGifList): boolean; function LoadFirstBitmap(var ABitmap: TBitmap): boolean; property Empty: boolean Read FEmpty; property Height: integer Read FHeight; property Width: integer Read FWidth; property IsTransparent: boolean Read FIsTransparent Write SetTransparent; property Interlaced: boolean Read FInterlaced Write SetInterlaced; end; { TGifAnim } TGifAnim = class(TGraphicControl) private { Private declarations } FAnimate: boolean; FEmpty: boolean; FFileName: string; FGifBitmaps: TGifList; FOnFrameChanged: TNotifyEvent; FOnStart: TNotifyEvent; FOnStop: TNotifyEvent; FWait: TTimer; FCurrentImage: integer; FGifHeight: integer; FGifWidth: integer; procedure OnTime(Sender: TObject); procedure SetAnimate(const AValue: boolean); procedure SetFileName(const AValue: string); procedure DefineSize(AWidth, AHeight: integer); protected { Protected declarations } BufferImg: TBitmap; CurrentView: TBitmap; procedure CalculatePreferredSize( var PreferredWidth, PreferredHeight: integer; WithThemeSpace: boolean); override; procedure DoAutoSize; override; procedure DoStartAnim; procedure DoStopAnim; class function GetControlClassDefaultSize: TSize; override; procedure GifChanged; procedure LoadFromFile(const Filename: string); virtual; procedure Paint; override; procedure ResetImage; procedure SetColor(Value: TColor); override; public { Public declarations } constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure NextFrame; procedure PriorFrame; property Empty: boolean Read FEmpty; property GifBitmaps: TGifList Read FGifBitmaps; property GifIndex: integer Read FCurrentImage; function LoadFromLazarusResource(const ResName: String): boolean; published { Published declarations } property Anchors; property AutoSize default True; property Animate: boolean Read FAnimate Write SetAnimate default True; property BorderSpacing; property Color default clBtnFace; property Constraints; property FileName: string Read FFileName Write SetFileName; property Height; property OnClick; property OnDblClick; property OnFrameChanged: TNotifyEvent Read FOnFrameChanged Write FOnFrameChanged; property OnMouseDown; property OnMouseEnter; property OnMouseLeave; property OnMouseMove; property OnMouseUp; property OnStartAnim: TNotifyEvent Read FOnStart Write FOnStart; property OnStopAnim: TNotifyEvent Read FOnStop Write FOnStop; property ParentShowHint; property ShowHint; property Visible; property Width; end; procedure Register; implementation procedure Register; begin RegisterComponents('Wile64', [TGifAnim]); end; { TGifAnim } constructor TGifAnim.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlStyle := [csCaptureMouse, csClickEvents, csDoubleClicks]; AutoSize := True; SetInitialBounds(0, 0, GetControlClassDefaultSize.CX, GetControlClassDefaultSize.CY); FEmpty := True; FCurrentImage := 0; CurrentView := TBitmap.Create; if not (csDesigning in ComponentState) then begin BufferImg := TBitmap.Create; FWait := TTimer.Create(Self); with FWait do begin Interval := 100; OnTimer := @OnTime; Enabled := False; end; end; Animate := True; end; destructor TGifAnim.Destroy; begin inherited Destroy; if assigned(FGifBitmaps) then FreeAndNil(FGifBitmaps); BufferImg.Free; CurrentView.Free; end; procedure TGifAnim.NextFrame; begin if (not FEmpty) and Visible and (not FAnimate) then begin if FCurrentImage >= GifBitmaps.Count - 1 then FCurrentImage := 0 else Inc(FCurrentImage); if Assigned(FOnFrameChanged) then FOnFrameChanged(Self); Repaint; end; end; procedure TGifAnim.PriorFrame; var DesiredImage: Integer; begin if (not FEmpty) and Visible and (not FAnimate) then begin if FCurrentImage = 0 then DesiredImage:= GifBitmaps.Count - 1 else DesiredImage:= FCurrentImage - 1; // For proper display repaint image from first frame to desired frame FCurrentImage:= 0; while FCurrentImage < DesiredImage do begin with GifBitmaps.Items[FCurrentImage] do begin BufferImg.Canvas.Brush.Color := (Self.Color); if FCurrentImage = 0 then BufferImg.Canvas.FillRect(Rect(0, 0, Width, Height)); if Delay <> 0 then FWait.Interval := Delay * 10; BufferImg.Canvas.Draw(PosX, PosY, Bitmap); case Method of //0 : Not specified... //1 : No change Background 2: BufferImg.Canvas.FillRect( Rect(PosX, PosY, Bitmap.Width + PosX, Bitmap.Height + PosY)); 3: BufferImg.Canvas.FillRect(Rect(0, 0, Width, Height)); end; end; Inc(FCurrentImage); end; if Assigned(FOnFrameChanged) then FOnFrameChanged(Self); Repaint; end; end; function TGifAnim.LoadFromLazarusResource(const ResName: String): boolean; var GifLoader: TGifLoader; StateAnimate: boolean; Resource: TLResource; begin Result:=false; StateAnimate:= Animate; FWait.Enabled:= false; ResetImage; Resource:=nil; Resource:=LazarusResources.Find(ResName); if Resource <> nil then if CompareText(LazarusResources.Find(ResName).ValueType, 'gif')=0 then begin GifLoader := TGifLoader.Create(Filename); FEmpty := not GifLoader.LoadFromLazarusResource(ResName, FGifBitmaps); DefineSize(GifLoader.Width, GifLoader.Height); GifLoader.Free; Result:= FEmpty; end; if not Empty then GifChanged; FWait.Enabled:= StateAnimate; end; procedure TGifAnim.LoadFromFile(const Filename: string); var GifLoader: TGifLoader; begin FEmpty := True; if not FileExists(Filename) then Exit; GifLoader := TGifLoader.Create(Filename); if (csDesigning in ComponentState) then FEmpty := not GifLoader.LoadFirstBitmap(CurrentView) else FEmpty := not GifLoader.LoadAllBitmap(FGifBitmaps); DefineSize(GifLoader.Width, GifLoader.Height); GifLoader.Free; end; procedure TGifAnim.OnTime(Sender: TObject); begin if (not Empty) and Visible then begin if FCurrentImage >= GifBitmaps.Count - 1 then FCurrentImage := 0 else Inc(FCurrentImage); if Assigned(FOnFrameChanged) then FOnFrameChanged(Self); Repaint; end; end; procedure TGifAnim.SetAnimate(const AValue: boolean); begin if FAnimate = AValue then exit; FAnimate := AValue; if not (csDesigning in ComponentState) then begin FWait.Enabled := Animate; if Animate then DoStartAnim else DoStopAnim; end; end; procedure TGifAnim.SetFileName(const AValue: string); begin if (FFileName = AValue) then Exit; FFileName := AValue; ResetImage; if (FFileName = '') then Exit; LoadFromFile(FFileName); if not Empty then GifChanged; end; procedure TGifAnim.DefineSize(AWidth, AHeight: integer); begin if (AWidth = FGifWidth) and (AHeight = FGifHeight) then Exit; FGifWidth := AWidth; FGifHeight := AHeight; Height := FGifHeight; Width := FGifWidth; if not (csDesigning in ComponentState) then begin BufferImg.Height := Height; BufferImg.Width := Width; end; end; procedure TGifAnim.CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: boolean); begin PreferredWidth := FGifWidth; PreferredHeight := FGifHeight; end; procedure TGifAnim.DoAutoSize; var ModifyWidth, ModifyHeight: boolean; NewWidth: integer; NewHeight: integer; begin if AutoSizing then Exit; // we shouldn't come here in the first place BeginAutoSizing; try GetPreferredSize(NewWidth, NewHeight); ModifyWidth := [akLeft, akRight] * (Anchors + AnchorAlign[Align]) <> [akLeft, akRight]; ModifyHeight := [akTop, akBottom] * (Anchors + AnchorAlign[Align]) <> [akTop, akBottom]; if not ModifyWidth then NewWidth := Width; if not ModifyHeight then NewHeight := Height; if (NewWidth <> Width) or (NewHeight <> Height) then begin SetBounds(Left, Top, NewWidth, NewHeight); end; finally EndAutoSizing; end; end; class function TGifAnim.GetControlClassDefaultSize: TSize; begin Result.CX := 90; Result.CY := 90; end; procedure TGifAnim.GifChanged; begin if not (csDesigning in ComponentState) then begin BufferImg.Canvas.Brush.Color := (self.Color); BufferImg.Canvas.FillRect(Rect(0, 0, Width, Height)); with GifBitmaps.Items[FCurrentImage] do BufferImg.Canvas.Draw(PosX, PosY, Bitmap); CurrentView.Assign(BufferImg); end; InvalidatePreferredSize; AdjustSize; end; procedure TGifAnim.Paint; begin if (not Empty) and Visible then begin if not (csDesigning in ComponentState) then begin if (FCurrentImage < GifBitmaps.Count) then with GifBitmaps.Items[FCurrentImage] do begin BufferImg.Canvas.Brush.Color := (self.Color); if FCurrentImage = 0 then BufferImg.Canvas.FillRect(Rect(0, 0, Width, Height)); if Delay <> 0 then FWait.Interval := Delay * 10; BufferImg.Canvas.Draw(PosX, PosY, Bitmap); CurrentView.Assign(BufferImg); case Method of //0 : Not specified... //1 : No change Background 2: BufferImg.Canvas.FillRect( Rect(PosX, PosY, Bitmap.Width + PosX, Bitmap.Height + PosY)); 3: BufferImg.Canvas.FillRect(Rect(0, 0, Width, Height)); end; end; end else begin Canvas.Brush.Color := (self.Color); Canvas.FillRect(Rect(0, 0, Width, Height)); end; Canvas.Draw(0, 0, CurrentView); end; inherited Paint; end; procedure TGifAnim.ResetImage; begin if assigned(FGifBitmaps) then FreeAndNil(FGifBitmaps); FCurrentImage:=0; with CurrentView do begin Canvas.Brush.Color := (self.Color); Canvas.FillRect(Rect(0, 0, Width, Height)); end; end; procedure TGifAnim.SetColor(Value: TColor); begin inherited SetColor(Value); end; procedure TGifAnim.DoStartAnim; begin if assigned(OnStartAnim) then OnStartAnim(Self); end; procedure TGifAnim.DoStopAnim; begin if assigned(OnStopAnim) then OnStartAnim(Self); end; { TGifLoader } constructor TGifLoader.Create(const FileName: string); begin FFileName := FileName; FGifUseGraphCtrlExt := False; FPalette := TFPPalette.Create(0); FHeight := 20; FWidth := 20; end; destructor TGifLoader.Destroy; begin inherited Destroy; FPalette.Free; end; function TGifLoader.LoadAllBitmap(var AGifList: TGifList): boolean; var GifStream: TMemoryStream; Introducer: byte; FPImage: TLazIntfImage; ImgFormatDescription: TRawImageDescription; GifBitmap: TGifImage; begin Result := False; if not FileExists(FFileName) then exit; if not assigned(AGifList) then AGifList := TGifList.Create(True); GifStream := TMemoryStream.Create; GifStream.LoadFromFile(FFileName); GifStream.Position := 0; ReadHeader(GifStream); if (FGifHeader.Version <> '89a') then Exit; // skip first block extention if exist repeat Introducer := SkipBlock(GifStream); until (Introducer = ID_IMAGE_DESCRIPTOR) or (Introducer = ID_TRAILER); repeat ReadGifBitmap(GifStream); // decode Gif bitmap in Scanline buffer ReadScanLine(GifStream); // Create temp Fp Image for put scanline pixel FPImage := TLazIntfImage.Create(FLocalWidth, FLocalHeight); ImgFormatDescription.Init_BPP32_B8G8R8A8_BIO_TTB(FLocalWidth, FLocalHeight); FPImage.DataDescription := ImgFormatDescription; WriteScanLine(FPImage); GifBitmap := TGifImage.Create; GifBitmap.FBitmap.LoadFromIntfImage(FPImage); GifBitmap.FPosX := FGifDescriptor.Left; GifBitmap.FPosY := FGifDescriptor.Top; GifBitmap.FMethod := FDisposalMethod; GifBitmap.FDelay := FGifGraphicsCtrlExt.DelayTime; AGifList.Add(GifBitmap); FPImage.Free; FreeMem(FScanLine, FLineSize); // reset FGifUseGraphCtrlExt flag FGifUseGraphCtrlExt := False; repeat Introducer := SkipBlock(GifStream); until (Introducer = ID_IMAGE_DESCRIPTOR) or (Introducer = ID_TRAILER); until (Introducer = ID_TRAILER); GifStream.Free; Result := True; end; function TGifLoader.LoadFromLazarusResource(const ResName: String; var AGifList: TGifList): boolean; var GifStream: TLazarusResourceStream; Introducer: byte; FPImage: TLazIntfImage; ImgFormatDescription: TRawImageDescription; GifBitmap: TGifImage; begin Result := False; if not assigned(AGifList) then AGifList := TGifList.Create(True); GifStream := TLazarusResourceStream.Create(ResName, nil); GifStream.Position := 0; ReadHeader(GifStream); if (FGifHeader.Version <> '89a') then Exit; // skip first block extention if exist repeat Introducer := SkipBlock(GifStream); until (Introducer = ID_IMAGE_DESCRIPTOR) or (Introducer = ID_TRAILER); repeat ReadGifBitmap(GifStream); // decode Gif bitmap in Scanline buffer ReadScanLine(GifStream); // Create temp Fp Image for put scanline pixel FPImage := TLazIntfImage.Create(FLocalWidth, FLocalHeight); ImgFormatDescription.Init_BPP32_B8G8R8A8_BIO_TTB(FLocalWidth, FLocalHeight); FPImage.DataDescription := ImgFormatDescription; WriteScanLine(FPImage); GifBitmap := TGifImage.Create; GifBitmap.FBitmap.LoadFromIntfImage(FPImage); GifBitmap.FPosX := FGifDescriptor.Left; GifBitmap.FPosY := FGifDescriptor.Top; GifBitmap.FMethod := FDisposalMethod; GifBitmap.FDelay := FGifGraphicsCtrlExt.DelayTime; AGifList.Add(GifBitmap); FPImage.Free; FreeMem(FScanLine, FLineSize); // reset FGifUseGraphCtrlExt flag FGifUseGraphCtrlExt := False; repeat Introducer := SkipBlock(GifStream); until (Introducer = ID_IMAGE_DESCRIPTOR) or (Introducer = ID_TRAILER); until (Introducer = ID_TRAILER); GifStream.Free; Result := True; end; function TGifLoader.LoadFirstBitmap(var ABitmap: TBitmap): boolean; var GifStream: TMemoryStream; Introducer: byte; FPImage: TLazIntfImage; ImgFormatDescription: TRawImageDescription; begin Result := False; if not FileExists(FFileName) then exit; if not assigned(ABitmap) then ABitmap := TBitmap.Create; GifStream := TMemoryStream.Create; GifStream.LoadFromFile(FFileName); GifStream.Position := 0; ReadHeader(GifStream); if (FGifHeader.Version <> '89a') then Exit; // skip first block extention if exist repeat Introducer := SkipBlock(GifStream); until (Introducer = ID_IMAGE_DESCRIPTOR) or (Introducer = ID_TRAILER); ReadGifBitmap(GifStream); // decode Gif bitmap in Scanline buffer ReadScanLine(GifStream); // Create temp Fp Image for put scanline pixel FPImage := TLazIntfImage.Create(FLocalWidth, FLocalHeight); ImgFormatDescription.Init_BPP32_B8G8R8A8_BIO_TTB(FLocalWidth, FLocalHeight); FPImage.DataDescription := ImgFormatDescription; WriteScanLine(FPImage); ABitmap.LoadFromIntfImage(FPImage); FPImage.Free; FreeMem(FScanLine, FLineSize); // reset FGifUseGraphCtrlExt flag FGifUseGraphCtrlExt := False; GifStream.Free; Result := True; end; procedure TGifLoader.SetTransparent(const AValue: boolean); begin if FIsTransparent = AValue then exit; FIsTransparent := AValue; end; function TGifLoader.SkipBlock(Stream: TStream): byte; var Introducer, Labels, SkipByte: byte; begin Introducer := 0; Labels := 0; SkipByte := 0; Stream.Read(Introducer, 1); if Introducer = EXT_INTRODUCER then begin Stream.Read(Labels, 1); case Labels of EXT_COMMENT, EXT_APPLICATION: while True do begin Stream.Read(SkipByte, 1); if SkipByte = 0 then Break; Stream.Seek(SkipByte, soFromCurrent); end; EXT_GRAPHICS_CONTROL: begin Stream.Read(FGifGraphicsCtrlExt, SizeOf(FGifGraphicsCtrlExt)); FGifUseGraphCtrlExt := True; end; EXT_PLAIN_TEXT: begin Stream.Read(SkipByte, 1); Stream.Seek(SkipByte, soFromCurrent); while True do begin Stream.Read(SkipByte, 1); if SkipByte = 0 then Break; Stream.Seek(SkipByte, soFromCurrent); end; end; end; end; Result := Introducer; end; procedure TGifLoader.ReadScanLine(Stream: TStream); var OldPos, UnpackedSize, PackedSize: longint; I: integer; Data, Bits, Code: cardinal; SourcePtr: PByte; InCode: cardinal; CodeSize: cardinal; CodeMask: cardinal; FreeCode: cardinal; OldCode: cardinal; Prefix: array[0..CODE_TABLE_SIZE - 1] of cardinal; Suffix, Stack: array [0..CODE_TABLE_SIZE - 1] of byte; StackPointer: PByte; DataComp, Target: PByte; B, FInitialCodeSize, FirstChar: byte; ClearCode, EOICode: word; begin FInitialCodeSize := 0; B := 0; DataComp := nil; // initialisation du dictionnaire de decompression Stream.Read(FInitialCodeSize, 1); // Recherche la taille des donnes compresser OldPos := Stream.Position; PackedSize := 0; repeat Stream.Read(B, 1); if B > 0 then begin Inc(PackedSize, B); Stream.Seek(B, soFromCurrent); end; until B = 0; Getmem(DataComp, PackedSize); // lecture des donnes conpresser SourcePtr := DataComp; Stream.Position := OldPos; repeat Stream.Read(B, 1); if B > 0 then begin Stream.ReadBuffer(SourcePtr^, B); Inc(SourcePtr, B); end; until B = 0; SourcePtr := DataComp; Target := FScanLine; CodeSize := FInitialCodeSize + 1; ClearCode := 1 shl FInitialCodeSize; EOICode := ClearCode + 1; FreeCode := ClearCode + 2; OldCode := CODE_TABLE_SIZE; CodeMask := (1 shl CodeSize) - 1; UnpackedSize := FLocalWidth * FLocalHeight; for I := 0 to ClearCode - 1 do begin Prefix[I] := CODE_TABLE_SIZE; Suffix[I] := I; end; StackPointer := @Stack; FirstChar := 0; Data := 0; Bits := 0; //Decompression LZW gif while (UnpackedSize > 0) and (PackedSize > 0) do begin Inc(Data, SourcePtr^ shl Bits); Inc(Bits, 8); while Bits >= CodeSize do begin Code := Data and CodeMask; Data := Data shr CodeSize; Dec(Bits, CodeSize); if Code = EOICode then Break; if Code = ClearCode then begin CodeSize := FInitialCodeSize + 1; CodeMask := (1 shl CodeSize) - 1; FreeCode := ClearCode + 2; OldCode := CODE_TABLE_SIZE; Continue; end; if Code > FreeCode then Break; if OldCode = CODE_TABLE_SIZE then begin FirstChar := Suffix[Code]; Target^ := FirstChar; Inc(Target); Dec(UnpackedSize); OldCode := Code; Continue; end; InCode := Code; if Code = FreeCode then begin StackPointer^ := FirstChar; Inc(StackPointer); Code := OldCode; end; while Code > ClearCode do begin StackPointer^ := Suffix[Code]; Inc(StackPointer); Code := Prefix[Code]; end; FirstChar := Suffix[Code]; StackPointer^ := FirstChar; Inc(StackPointer); Prefix[FreeCode] := OldCode; Suffix[FreeCode] := FirstChar; if (FreeCode = CodeMask) and (CodeSize < 12) then begin Inc(CodeSize); CodeMask := (1 shl CodeSize) - 1; end; if FreeCode < CODE_TABLE_SIZE - 1 then Inc(FreeCode); OldCode := InCode; repeat Dec(StackPointer); Target^ := StackPointer^; Inc(Target); Dec(UnpackedSize); until StackPointer = @Stack; end; Inc(SourcePtr); Dec(PackedSize); end; FreeMem(DataComp); end; procedure TGifLoader.ReadHeader(Stream: TStream); begin Stream.Read(FGifHeader, SizeOf(FGifHeader)); with FGifHeader do begin FGifBackgroundColor := BackgroundColor; FWidth := ScreenWidth; FHeight := ScreenHeight; FLocalWidth := ScreenWidth; FLocalHeight := ScreenHeight; IsTransparent := False; end; ReadGlobalPalette(Stream); end; procedure TGifLoader.ReadGlobalPalette(Stream: TStream); var ColorTableSize: integer; begin if (FGifHeader.Packedbit and ID_COLOR_TABLE) <> 0 then begin ColorTableSize := FGifHeader.Packedbit and ID_COLOR_TABLE_SIZE + 1; ReadPalette(Stream, 1 shl ColorTableSize); end; end; procedure TGifLoader.ReadGraphCtrlExt; var C: TFPColor; begin IsTransparent := (FGifGraphicsCtrlExt.Packedbit and ID_TRANSPARENT) <> 0; FDisposalMethod := (FGifGraphicsCtrlExt.Packedbit and $1C) shr 2; if IsTransparent then begin // if Transparent bitmap change alpha channel FGifBackgroundColor := FGifGraphicsCtrlExt.ColorIndex; C := FPalette[FGifBackgroundColor]; C.alpha := alphaTransparent; FPalette[FGifBackgroundColor] := C; end; end; procedure TGifLoader.SetInterlaced(const AValue: boolean); begin if FInterlaced = AValue then exit; FInterlaced := AValue; end; procedure TGifLoader.ReadPalette(Stream: TStream; Size: integer); var RGBEntry: TRGB; I: integer; C: TFPColor; begin FPalette.Clear; FPalette.Count := 0; Fillchar(RGBEntry, SizeOf(RGBEntry), 0); for I := 0 to Size - 1 do begin Stream.Read(RGBEntry, SizeOf(RGBEntry)); with C do begin Red := RGBEntry.Red or (RGBEntry.Red shl 8); Green := RGBEntry.Green or (RGBEntry.Green shl 8); Blue := RGBEntry.Blue or (RGBEntry.Blue shl 8); Alpha := alphaOpaque; end; FPalette.Add(C); end; end; procedure TGifLoader.WriteScanLine(Img: TFPCustomImage); var Row, Col: integer; Pass, Every: byte; P: PByte; begin P := FScanLine; if Interlaced then begin for Pass := 1 to 4 do begin case Pass of 1: begin Row := 0; Every := 8; end; 2: begin Row := 4; Every := 8; end; 3: begin Row := 2; Every := 4; end; 4: begin Row := 1; Every := 2; end; end; repeat for Col := 0 to FLocalWidth - 1 do begin Img.Colors[Col, Row] := FPalette[P^]; Inc(P); end; Inc(Row, Every); until Row >= FLocalHeight; end; end else begin for Row := 0 to FLocalHeight - 1 do for Col := 0 to FLocalWidth - 1 do begin Img.Colors[Col, Row] := FPalette[P^]; Inc(P); end; end; end; procedure TGifLoader.ReadGifBitmap(Stream: TStream); var ColorTableSize: integer; begin Stream.Read(FGifDescriptor, SizeOf(FGifDescriptor)); with FGifDescriptor do begin FLocalWidth := Width; FLocalHeight := Height; Interlaced := (Packedbit and ID_INTERLACED = ID_INTERLACED); end; FLineSize := FLocalWidth * (FLocalHeight + 1); GetMem(FScanLine, FLineSize); if (FGifDescriptor.Packedbit and ID_COLOR_TABLE) <> 0 then begin ColorTableSize := FGifDescriptor.Packedbit and ID_COLOR_TABLE_SIZE + 1; ReadPalette(Stream, 1 shl ColorTableSize); end; if FGifUseGraphCtrlExt then ReadGraphCtrlExt; end; { TGifImage } constructor TGifImage.Create; begin FBitmap := TBitmap.Create; FPosX := 0; FPosY := 0; FDelay := 0; FMethod := 0; end; destructor TGifImage.Destroy; begin inherited Destroy; FBitmap.Free; end; { TGifList } function TGifList.GetItems(Index: integer): TGifImage; begin Result := TGifImage(inherited Items[Index]); end; procedure TGifList.SetItems(Index: integer; AGifImage: TGifImage); begin Put(Index, AGifImage); end; function TGifList.Add(AGifImage: TGifImage): integer; begin Result := inherited Add(AGifImage); end; function TGifList.Extract(Item: TGifImage): TGifImage; begin Result := TGifImage(inherited Extract(Item)); end; function TGifList.Remove(AGifImage: TGifImage): integer; begin Result := inherited Remove(AGifImage); end; function TGifList.IndexOf(AGifImage: TGifImage): integer; begin Result := inherited IndexOf(AGifImage); end; function TGifList.First: TGifImage; begin Result := TGifImage(inherited First); end; function TGifList.Last: TGifImage; begin Result := TGifImage(inherited Last); end; procedure TGifList.Insert(Index: integer; AGifImage: TGifImage); begin inherited Insert(Index, AGifImage); end; initialization {$I gifanim.lrs} end. doublecmd-0.8.2/components/gifanim/gifanimdsgn.pas0000664000175000017500000000137412334444240021304 0ustar alexxalexxunit GifAnimDsgn; {$mode objfpc}{$H+} interface uses LazIDEIntf, PropEdits; Type TGifFileNamePropertyEditor = class(TFileNamePropertyEditor) protected function GetFilter: String; override; function GetInitialDirectory: string; override; end; procedure Register; implementation uses SysUtils, GifAnim; function TGifFileNamePropertyEditor.GetFilter: String; begin Result := 'GIF|*.gif'; end; function TGifFileNamePropertyEditor.GetInitialDirectory: string; begin Result:= ExtractFilePath(LazarusIDE.ActiveProject.ProjectInfoFile); end; procedure Register; begin RegisterPropertyEditor(TypeInfo(String), TGifAnim, 'FileName', TGifFileNamePropertyEditor); end; end. doublecmd-0.8.2/components/gifanim/pkg_gifanim_dsgn.lpk0000664000175000017500000000245012334444240022303 0ustar alexxalexx doublecmd-0.8.2/components/gifanim/pkg_gifanim_dsgn.pas0000664000175000017500000000061712334444240022303 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit pkg_gifanim_dsgn; interface uses GifAnimDsgn, LazarusPackageIntf; implementation procedure Register; begin RegisterUnit('GifAnimDsgn', @GifAnimDsgn.Register); end; initialization RegisterPackage('pkg_gifanim_dsgn', @Register); end. doublecmd-0.8.2/components/gifanim/tgifanim.xpm0000664000175000017500000000234111376245253020640 0ustar alexxalexx/* XPM */ static char * gifanim_xpm[] = { "24 24 31 1", " c None", ". c #959595", "+ c #E1E1E1", "@ c #919191", "# c #848484", "$ c #888888", "% c #EEEEEE", "& c #E6E9EC", "* c #D6DFE8", "= c #FFFFFF", "- c #E7F0F9", "; c #3783CE", "> c #FFF7F7", ", c #FFEFEF", "' c #F7F2F5", ") c #F7FAFD", "! c #FF5757", "~ c #FFDFDF", "{ c #FF4F4F", "] c #FFD7D7", "^ c #FF4747", "/ c #FF3F3F", "( c #8D8D8D", "_ c #EEE6E6", ": c #EED6D6", "< c #EECECE", "[ c #FAFAFA", "} c #F2F2F2", "| c #F6F6F6", "1 c #A2A2A2", "2 c #FAF2F2", " .++@ @++. ", " @@@##$$$$$$$$$$$$##@@@ ", " .++$#$$$$$$$$$$$$#$++. ", " .++@+%%&**&&**&%%+@++. ", " @@@@%==-;;--;;-==%@@@@ ", " .++.%==-;;--;;-==%.++. ", " .++.%>,'--))--',>%.++. ", " @@@@%,!~>====>~!,%@@@@ ", " .++.%>~{]~~~~]{~>%.++. ", " .++.%=>~^////^~>=%.++. ", " @@@(+%%_:<<<<:_%%+(@@@ ", " .++$#$$$$$$$$$$$$#$++. ", " .++$#$$$$$$$$$$$$#$++. ", " @@@(+%%&**&%%%%%%+(@@@ ", " .++.%==-;;-[}}[==%.++. ", " .++.%==-;;-|11|==%.++. ", " @@@@%>,'--)[}}2,>%@@@@ ", " .++.%,!~>====>~!,%.++. ", " .++.%>~{]~~~~]{~>%.++. ", " @@@@%=>~^////^~>=%@@@@ ", " .++@+%%_:<<<<:_%%+@++. ", " .++$#$$$$$$$$$$$$#$++. ", " @@@##$$$$$$$$$$$$##@@@ ", " .++@ @++. "}; doublecmd-0.8.2/components/gifanim/pkg_gifanim.pas0000664000175000017500000000054412677725617021313 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit pkg_gifanim; interface uses GifAnim, LazarusPackageIntf; implementation procedure Register; begin RegisterUnit('GifAnim', @GifAnim.Register); end; initialization RegisterPackage('pkg_gifanim', @Register); end. doublecmd-0.8.2/components/CmdLine/0000775000175000017500000000000013244011205016175 5ustar alexxalexxdoublecmd-0.8.2/components/CmdLine/ucmdbox.pas0000664000175000017500000020421212747700216020362 0ustar alexxalexx{ Copyright (C) 2007 Julian Schutsch This source is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. A copy of the GNU Lesser General Public License is available on the World Wide Web at . You can also obtain it by writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Changelog: 9.27.2007 : Seperation from another Package, first Release under GPL Version 0.1 10.02.2007 : Licence Changed to LGPL Added : History Added : Password Input mode Fixed : Blank Screen when Resizing so that TopLine disappears. Added : Fixed Prompt Description infront of Input, moves along with it Etc : Functions, minor Bugs Missing : FreeLineWidth full support Version 0.2 10.08.2007 : Removed : Fixed Line Width Support, Source now less complex Added : Paste/Copy/Cut Ability, Select with Mouse and Shift/Keys Added : TRTLCriticalsection called FLock to make Writeln/Write Threadsafe Fixed : GTK 1/2 Linux support, several changes to make that work... Removed : LineWidth, can cause Property Loading Errors if used with old Apps ! Workarn : GTK Font height gets 2 added on all plattforms, means, win32 have two extra dots unecessarily, can't solve that ! Fixed : Pos 1/End Key changes Scrollbar (Different GTK behaviour !) Version 0.3 12.06.2008 : Optimized Color String output, still needs testing and PWD Strings are not changed yet. Improvement visible on Win32, but still to slow, any hacks? 17.06.2008 : TColorString changed completly, now using Arrays instead of linked lists 25.06.2008 : Fixed everything for Multispace support Added tabulator behaviour Caret type and Color now customizable Input Selection Colors published Speed improvement using precalculated Sum-Widths for TColorString Lots of minor UTF8 Bugs fixed 26.06.2008 : Escape Codes for some sort of Graphical output (Tables, lines, etc) Better moving Input Bug fixes in MakeInputVisible 27.06.2008 : Add FGraphicCharWidth 28.06.2008 : New Escape Code preprocessor Support for different modes (ANSI color, CmdBox, None(ignore)) 29.06.2008 : FStringBuffer added,Works without WakeMainThread now as well Fixed LineOutAndFill Added AutoFollow Todo : Input Masks Todo : Docu } unit uCmdBox; {$mode objfpc}{$H+} interface uses Classes, SysUtils, ExtCtrls, ComCtrls, Controls, Graphics, Forms, LCLType, LCLIntf, LMessages, LResources, ClipBrd, LCLProc, LazUTF8; type TCaretType=(cartLine,cartSubBar,cartBigBar,cartUser); TEscapeCodeType=(esctCmdBox,esctAnsi,esctNone); TEscapeMode=(escmNone,escmOperation,escmData2,escmData1,escmAnsiOperation,escmAnsiSquare); type TCmdBox=class; type TColorstring=class; type EOnCmdBoxInput=Procedure(ACmdBox:TCmdBox;Input:String) of object; type EOnCmdBoxInputChange=Procedure(ACmdBox:TCmdBox;InputData:TColorstring) of object; type { TCmdBox } TCmdBox=class(TCustomControl) public constructor Create(AComponent:TComponent);override; destructor Destroy;override; protected procedure Paint;override; procedure Resize;override; procedure UTF8KeyPress(var Key:TUTF8Char);override; procedure KeyDown(var Key:Word;Shift:TShiftState);override; procedure CreateParams(var Params:TCreateParams);override; procedure CreateWnd;override; procedure WMVScroll(var message: TLMVScroll);message LM_VSCROLL; procedure MouseDown(Button:TMouseButton;Shift:TShiftState;x,y:Integer);override; procedure MouseUp(Button:TMouseButton;Shift:TShiftState;x,y:Integer);override; procedure MouseMove(Shift:TShiftState;x,y:Integer);override; procedure EraseBackground(DC:HDC);override; private FLock : System.TRTLCriticalSection; FCaretTimer : TTimer; FCaretVisible : Boolean; FLineCount : Integer; FLines : array of TColorstring; FLineHeights : array of Integer; FLineHeightSum : array of Integer; FTopLine : Integer; FPageHeight : Integer; FVisibleLines : Integer; FVSBVisible : Boolean; FVSBPos : Integer; FVSBWidth : Integer; FClientWidth : Integer; FClientHeight : Integer; FCaretX : Integer; FOutX,FOutY : Integer; FInputX,FInputY : Integer; FInputPos : Integer; FCharHeight : Integer; FLineOfTopLine : Integer; FVisibleLineCount : Integer; FInput : Boolean; FInputBuffer : TColorstring; FInputVisible : Boolean; FInputMinPos : Integer; FUTF8InputMinPos : Integer; FOnInput : EOnCmdBoxInput; FOnAny : EOnCmdBoxInputChange; FOnInputChange : EOnCmdBoxInputChange; FBackGroundColor : TColor; FCurrentColor : TColor; FCurrentBackGround : TColor; FFont : TFont; FPassWordChar : TUTF8Char; FInputIsPassWord : Boolean; FHistory : Array of TColorstring; FHistoryLength : Integer; FHistoryMax : Integer; FHistoryPos : Integer; FInputColor : TColor; FInputBackground : TColor; FInputSelColor : TColor; FInputSelBackGround : TColor; FMouseDown : Boolean; FSelStart,FSelEnd : Integer; FMouseDownInputPos : Integer; FCurrentString : String; FCaretColor : TColor; FCaretType : TCaretType; FCaretWidth : Integer; FCaretHeight : Integer; FCaretYShift : Integer; FTabWidth : Integer; FGraphicCharWidth : Integer; FEscapeCodeType : TEscapeCodeType; FEscapeMode : TEscapeMode; FEscapeData : String; FStringBuffer : TStringList; FAutoFollow : Boolean; procedure CaretTimerExecute(Sender:TObject); procedure SetLineCount(c:Integer); procedure SetTopLine(Nr:Integer); procedure AdjustScrollBars; function AdjustLineHeight(i:Integer):Integer; procedure MakeInputVisible; procedure MakeOutVisible; procedure SetFont(F:TFont); procedure SetBackGroundColor(c:Tcolor); function GetSystemMetricsGapSize(const Index:Integer):Integer; procedure ScrollBarRange(Which: Integer; aRange,aPage: Integer); procedure ScrollBarPosition(Which,Value:Integer); function UpdateLineHeights:Integer; procedure TranslateScrollBarPosition; procedure ScrollUp; procedure SetHistoryMax(v:Integer); procedure InsertHistory; procedure SetHistoryPos(v:Integer); function GetHistory(i:Integer):string; procedure DeleteHistoryEntry(i:Integer); procedure MakeFirstHistoryEntry(i:Integer); function MoveInputCaretTo(x,y:Integer;chl:Boolean):Boolean; procedure SetSelection(Start,Ende:Integer); procedure LeftSelection(Start,Ende:Integer); procedure RightSelection(Start,Ende:Integer); procedure DeleteSelected; procedure SetOutY(v:Integer); procedure IntWrite; procedure MultiWrite; procedure SetCaretType(ACaretType:TCaretType); procedure SetCaretWidth(AValue:Integer); procedure SetCaretHeight(AValue:Integer); procedure SetCaretYShift(AValue:Integer); procedure SetTabWidth(AValue:Integer); function GetCaretInterval:Integer; procedure SetCaretInterval(AValue:Integer); public function HistoryHas(s:string):Boolean; function HistoryIndexOf(s:string):Integer; procedure ClearHistory; procedure TextColor(C:TColor); procedure TextBackground(C:TColor); procedure TextColors(FC,BC:TColor); procedure Write(s:String); procedure Writeln(s:String); procedure WriteStream(Stream:TStream); procedure Clear; procedure StartRead(DFC,DBC:TColor;const Desc:String;IFC,IBC:TColor); procedure StartReadPassWord(DFC,DBC:TColor;const Desc:String;IFC,IBC:TColor); procedure StopRead; procedure CopyToClipBoard; procedure PasteFromClipBoard; procedure CutToClipBoard; procedure ClearLine; property OutX : Integer read FOutX write FOutX; property OutY : Integer read FOutY write SetOutY; property TopLine : Integer read FTopLine write SetTopLine; property History[i:Integer] : string read GetHistory; property InputPos : Integer read FInputPos write FInputPos; function HistoryCount : Integer; published property Align; property Anchors; property ShowHint; property CaretColor : TColor read FCaretColor write FCaretColor; property CaretType : TCaretType read FCaretType write SetCaretType; property CaretWidth : Integer read FCaretWidth write SetCaretWidth; property CaretHeight : Integer read FCaretHeight write SetCaretHeight; property CaretYShift : Integer read FCaretYShift write SetCaretYShift; property OnInput : EOnCmdBoxInput read FOnInput write FOnInput; property OnInputChange : EOnCmdBoxInputChange read FOnInputChange write FOnInputChange; property OnAny : EOnCmdBoxInputChange read FOnAny write FOnAny; property LineCount : Integer read FLineCount write SetLineCount; property Font : TFont read FFont write SetFont; property BackGroundColor : TColor read FBackgroundColor write SetBackGroundColor; property TabWidth : Integer read FTabWidth write SetTabWidth; property PassWordChar : TUTF8Char read FPassWordChar write FPassWordChar; property HistoryMax : Integer read FHistoryMax write SetHistoryMax; property InputSelColor : TColor read FInputSelColor write FInputSelColor; property InputSelBackGround : TColor read FInputSelBackGround write FInputSelBackGround; property CaretInterval : Integer read GetCaretInterval write SetCaretInterval; property EscapeCodeType : TEscapeCodeType read FEscapeCodeType write FEscapeCodeType; property GraphicalCharacterWidth : Integer read FGraphicCharWidth write FGraphicCharWidth; property AutoFollow : Boolean read FAutoFollow write FAutoFollow; property DoubleBuffered default true; end; type TColorChar=record FChar : TUTF8Char; FCharWidth : Integer; FSumWidth : Integer; FWordStart : Integer; FFrontColor : TColor; FBackColor : TColor; end; type TColorString=class private FChars : array of TColorChar; FSumWidth : Integer; FPassWordStart : Integer; FPassWordChar : TUTF8Char; FTabWidth : Integer; procedure MinimumLength(V:Integer;FC,BC:TColor); procedure MaximumLength(V:Integer); procedure UpdateSum; public constructor Create(AFont:TFont); destructor Destroy;override; procedure Clear; procedure OverWrite(S:String;Pos:Integer;FC,BC:TColor); procedure OverWriteChar(s:TUTF8Char;Pos,ADefWidth:Integer;FC,BC:TColor); procedure OverWrite(S:TColorstring;Pos:Integer); procedure OverWritePW(S:TColorstring;PWS,Pos:Integer;PWC:String); procedure PartOverWrite(S:TColorstring;Start,Ende,Pos:Integer); procedure LineOutAndFill(ACanvas:TCanvas;AX,AY,ALeftX,AWrapWidth,ACH,ACB,ACaretPos:Integer;ABC,ACC:TColor;ACaretHeight,ACaretWidth,ACaretYShift:Integer;ADrawCaret:Boolean); function Getstring:String; function GetPartstring(Start,Ende:Integer):String; procedure Delete(Index:Integer); procedure Delete(Index,Len:Integer); procedure Insert(Index:Integer;C:String;FC,BC:TColor); procedure BColorBlock(StartPos,EndPos:Integer;C:TColor); procedure ColorBlock(StartPos,EndPos:Integer;FC,BC:TColor); function LineCount(AWrapWidth,ACaretPos,ACaretWidth:Integer):Integer; function GetLength:Integer; function GetLineOfCaret(AWrapWidth,ACaretPos,ACaretWidth:Integer):Integer; function GetCharPosition(AWrapWidth,ALine,AXPos:Integer):Integer; private FFont : TFont; FDefaultBackGround : TColor; public property TabWidth : Integer read FTabWidth write FTabWidth; property PassWordChar : TUTF8Char read FPassWordChar write FPassWordChar; property PassWordStart : Integer read FPassWordStart write FPassWordStart; property Length : Integer read GetLength; property DefaultBackGround : TColor read FDefaultBackground write FDefaultBackground; property Font : TFont read FFont write FFont; end; procedure Register; implementation procedure TColorString.UpdateSum; var i : Integer; LastWordStart : Integer; SumWidth : Integer; begin LastWordStart := 0; SumWidth := 0; for i:=0 to High(FChars) do begin with FChars[i] do begin FWordStart := LastWordStart; case FChar[1] of #9: begin FCharWidth := (SumWidth div FTabWidth+1)*FTabWidth-SumWidth; LastWordStart := i+1; end; #27: begin case FChar[2] of #9: begin FCharWidth := (SumWidth div FTabWidth+1)*FTabWidth-SumWidth; LastWordStart := i+1; end; #10:LastWordStart:=i+1; #32,#46,#196,#205: begin FCharWidth := Ord(FChar[3]); LastWordStart := i+1; end; #33,#47,#197,#206: begin FCharWidth := (Ord(FChar[3])+Ord(FChar[4])*256)-SumWidth; if FCharWidth<0 then FCharWidth:=0; LastWordStart := i+1; end; end; end; else if FChar=' ' then LastWordStart:=i+1; end; SumWidth := SumWidth+FCharWidth; FSumWidth := SumWidth; end; end; FSumWidth:=SumWidth; end; function TColorString.GetLength:Integer; begin Result:=System.Length(FChars); end; procedure TCmdBox.SetTabWidth(AValue:Integer); var i:Integer; begin FTabWidth:=AValue; for i:=0 to FLineCount-1 do FLines[i].TabWidth:=AValue; UpdateLineHeights; Invalidate; end; procedure TCmdBox.SetCaretWidth(AValue:Integer); begin FCaretWidth := AValue; FCaretType := cartUser; end; procedure TCmdBox.SetCaretHeight(AValue:Integer); begin FCaretHeight := AValue; FCaretType := cartUser; end; procedure TCmdBox.SetCaretYShift(AValue:Integer); begin FCaretYShift := AValue; FCaretType := cartUser; end; procedure TCmdBox.SetCaretType(ACaretType:TCaretType); begin case ACaretType of cartLine: begin if HandleAllocated then FCaretHeight:=FFont.GetTextHeight('A')-3 else FCaretHeight:=-1; FCaretWidth := 1; FCaretYShift := 3; end; cartSubBar: begin FCaretWidth := -1; FCaretHeight := 3; FCaretYShift := 0; end; cartBigBar: begin if HandleAllocated then FCaretHeight:=FFont.GetTextHeight('A')-3 else FCaretHeight:=-1; FCaretWidth := -1; FCaretYShift := 3; end; end; Invalidate; FCaretType:=ACaretType; end; // TOdo : Use string buffer instead of string (speed improvement expected) procedure TColorString.LineOutAndFill(ACanvas:TCanvas;AX,AY,ALeftX,AWrapWidth,ACH,ACB,ACaretPos:Integer;ABC,ACC:TColor;ACaretHeight,ACaretWidth,ACaretYShift:Integer;ADrawCaret:Boolean); var LineStart : Integer; LineEnd : Integer; MidWidth : Integer; LineStartSumWidth : Integer; x : Integer; LastLineSumWidth : Integer; ACHH : Integer; ACBH : Integer; procedure DrawLine; var SameColor : String; SameForeColor : TColor; SameBackColor : TColor; SameColorX : Integer; SameColorWidth : Integer; LP : Integer; CaretX : Integer; CaretW : Integer; CW : Integer; xp : Integer; begin if (AY<=-ACH) and (AY>ACanvas.Height) then begin Inc(AY,ACH); Ax:=ALeftx; Exit; end; SameColor:=''; ACanvas.Brush.Style:=bsSolid; // TODO: Please try to reproduce this Ultra-Shit Error which couples GetTextWidth input to // TextOut Output. I can't solve this...i am not Stupid Enough for such errors! // (Is in bug report, should be fixed somewhere in the future!) ACanvas.Font.GetTextWidth('%%%_$%_Hallo\\\\\\\\\32489738'); // End of shit LP := LineStart; CaretX := -1; while LineStart<>LineEnd+1 do begin with FChars[LineStart] do begin CW:=FCharWidth; if FChar=#9 then begin if SameColor<>'' then begin ACanvas.Font.Color :=SameForeColor; ACanvas.Brush.Color :=SameBackColor; ACanvas.FillRect(SameColorX,AY,SameColorX+SameColorWidth,Ay+ACH); ACanvas.TextOut(SameColorX,AY,SameColor); Inc(SameColorX,SameColorWidth); SameColor:=''; end else SameColorX:=AX; ACanvas.Brush.Color:=FBackColor; ACanvas.Fillrect(SameColorX,AY,SameColorX+FCharWidth,AY+ACH); end else if FChar[1]=#27 then begin if SameColor<>'' then begin ACanvas.Font.Color :=SameForeColor; ACanvas.Brush.Color :=SameBackColor; ACanvas.FillRect(SameColorX,AY,SameColorX+SameColorWidth,Ay+ACH); ACanvas.TextOut(SameColorX,AY,SameColor); Inc(SameColorX,SameColorWidth); SameColor:=''; end else SameColorX:=AX; case FChar[2] of #9: begin case FChar[3] of #46: begin ACanvas.Pen.Color:=FFrontColor; ACanvas.Pen.Style:=psDash; ACanvas.Brush.Color:=FBackColor; ACanvas.Fillrect(SameColorX,AY,SameColorX+FCharWidth,AY+ACH); xp:=SameColorX; if xp mod 2<>0 then Inc(xp); while xp0 then Inc(xp); while xp=FPassWordStart) then begin SameColor := FPassWordChar; SameColorWidth := FFont.GetTextWidth(FPassWordChar); end else begin SameColor := FChar; SameColorWidth := FCharWidth; end; SameColorX := AX; SameForeColor := FFrontColor; SameBackColor := FBackColor; end else begin if (SameForeColor=FFrontColor) and (SameBackColor=FBackColor) then begin if (LP>=FPassWordStart) then begin SameColor:=SameColor+FPassWordChar; Inc(SameColorWidth,FFont.GetTextWidth(FPassWordChar)); end else begin SameColor:=SameColor+FChar; Inc(SameColorWidth,FCharWidth); end; end else begin ACanvas.Font.Color :=SameForeColor; ACanvas.Brush.Color :=SameBackColor; ACanvas.FillRect(SameColorX,Ay,SameColorX+SameColorWidth,Ay+ACH); ACanvas.TextOut(SameColorX,AY,SameColor); if (LP>=FPassWordStart) then begin SameColor := FPassWordChar; SameColorWidth := FFont.GetTextWidth(FPassWordChar); end else begin SameColor := FChar; SameColorWidth := FCharWidth; end; SameForeColor := FFrontColor; SameBackColor := FBackColor; SameColorX := AX; end; end; if LP=ACaretPos then begin CaretX:=AX; CaretW:=FCharWidth; end; Inc(AX,CW); Inc(LP); end; Inc(LineStart); end; if SameColor<>'' then begin ACanvas.Font.Color := SameForeColor; ACanvas.Brush.Color := SameBackColor; ACanvas.FillRect(SameColorX,Ay,SameColorX+SameColorWidth,Ay+ACH); ACanvas.TextOut(SameColorX,AY,SameColor); end; ACanvas.FillRect(AX,AY,AWrapWidth,AY+ACH); AX:=ALeftX; Inc(AY,ACH); if ADrawCaret and (CaretX>=0) then begin ACanvas.Brush.Color:=ACC; if ACaretWidth>=0 then CaretW:=ACaretWidth; ACanvas.FillRect(CaretX,AY-ACaretHeight-ACaretYShift,CaretX+CaretW,AY-ACaretYShift); end; end; begin if AWrapWidth<0 then AWrapWidth:=0; if System.Length(FChars)=0 then begin ACanvas.Brush.Style := bsSolid; ACanvas.Brush.Color := ABC; ACanvas.FillRect(AX,AY,AWrapWidth,AY+ACH); Exit; end; ACHH := ACH div 2; ACBH := ACB div 2; MidWidth := FSumWidth div System.Length(FChars); LineStart := 0; LineStartSumWidth := 0; LastLineSumWidth := 0; x := 0; while LineStartHigh(FChars) then x:=High(FChars); while (xLineStart) and (FChars[x].FSumWidth-LineStartSumWidth>=AWrapWidth) do with FChars[x] do if (FChar<>' ') and (FWordStart>LineStart) then x:=FWordStart-1 else Dec(x); LineEnd:=x; DrawLine; LastLineSumWidth := LineStartSumWidth; LineStartSumWidth := FChars[x].FSumWidth; LineStart := x+1; end; if ACaretPos>=LineStart then begin if ACaretWidth>=0 then x:=ACaretWidth else x:=FFont.GetTextWidth('A'); AX:=LineStartSumWidth-LastLineSumWidth+(ACaretPos-LineStart)*x; if Ax+x>AWrapWidth then begin Ax:=0; ACanvas.Brush.Color:=ABC; ACanvas.FillRect(0,AY,AWrapWidth,AY+ACH); Inc(Ay,ACH); end; if ADrawCaret then begin ACanvas.Brush.Color:=ACC; ACanvas.FillRect(AX,AY-ACaretHeight-ACaretYShift,AX+x,AY-ACaretYShift); end; end; end; function TColorString.GetCharPosition(AWrapWidth,ALine,AXPos:Integer):Integer; var x,MidWidth,LineStart,LineStartSumWidth,LastLineSumWidth,LastLineStart:Integer; begin if AWrapWidth<0 then AWrapWidth:=0; if System.Length(FChars)=0 then begin Result:=0; Exit; end; MidWidth := FSumWidth div System.Length(FChars); if MidWidth=0 then begin Result:=0; Exit; end; LineStart := 0; LineStartSumWidth := 0; LastLineSumWidth := 0; x:=0; while (LineStart=0) do begin x:=LineStart+AWrapWidth div MidWidth; if x>High(FChars) then x:=High(FChars); while (xLineStart) and (FChars[x].FSumWidth-LineStartSumWidth>=AWrapWidth) do with FChars[x] do if (FChar<>' ') and (FWordStart>LineStart) then x:=FWordStart-1 else Dec(x); LastLineSumWidth := LineStartSumWidth; LineStartSumWidth := FChars[x].FSumWidth; LastLineStart := LineStart; LineStart := x+1; Dec(ALine); end; Result:=LastLineStart; while (ResultHigh(FChars) then x:=High(FChars); while (xLineStart) and (FChars[x].FSumWidth-LineStartSumWidth>=AWrapWidth) do with FChars[x] do if (FChar<>' ') and (FWordStart>LineStart) then x:=FWordStart-1 else Dec(x); LastLineSumWidth := LineStartSumWidth; LineStartSumWidth := FChars[x].FSumWidth; LineStart := x+1; if ACaretPos=0 then x:=ACaretWidth else x:=FFont.GetTextWidth('A'); if (ACaretPos>LineStart) or (LineStartSumWidth-LastLineSumWidth+(ACaretPos-LineStart)*x+x<=AWrapWidth) then Dec(Result); end; function TColorString.LineCount(AWrapWidth,ACaretPos,ACaretWidth:Integer):Integer; var x : Integer; MidWidth : Integer; LineStart : Integer; LineStartSumWidth : Integer; LastLineSumWidth : Integer; begin if AWrapWidth<0 then AWrapWidth:=0; if System.Length(FChars)=0 then begin Result:=1; Exit; end; MidWidth := FSumWidth div System.Length(FChars); if MidWidth=0 then begin Result:=1; Exit; end; LineStart := 0; LineStartSumWidth := 0; LastLineSumWidth := 0; Result:=0; x:=0; while LineStartHigh(FChars) then x:=High(FChars); while (xLineStart) and (FChars[x].FSumWidth-LineStartSumWidth>=AWrapWidth) do with FChars[x] do if (FChar<>' ') and (FWordStart>LineStart) then x:=FWordStart-1 else Dec(x); LastLineSumWidth := LineStartSumWidth; LineStartSumWidth := FChars[x].FSumWidth; LineStart := x+1; Inc(Result); end; if ACaretWidth>=0 then x:=ACaretWidth else x:=FFont.GetTextWidth('A'); if (ACaretPos>=LineStart) and (LineStartSumWidth-LastLineSumWidth+(ACaretPos-LineStart)*x+x>AWrapWidth) then Inc(Result); end; constructor TColorString.Create(AFont:TFont); begin inherited Create; FTabWidth := 1; FFont := AFont; FPassWordStart := MaxInt; end; procedure TColorstring.BColorBlock(StartPos,EndPos:Integer;C:TColor); var i:Integer; begin if StartPos<0 then StartPos:=0; if EndPos>High(FChars) then EndPos:=High(FChars); for i:=StartPos to EndPos do FChars[i].FBackColor:=C; end; procedure TColorstring.ColorBlock(StartPos,EndPos:Integer;FC,BC:TColor); var i:Integer; begin if StartPos<0 then StartPos:=0; if EndPos>High(FChars) then EndPos:=High(FChars); for i:=StartPos to EndPos do begin FChars[i].FFrontColor := FC; FChars[i].FBackColor := BC; end; end; procedure TColorstring.Insert(Index:Integer;C:string;FC,BC:TColor); var i : Integer; l : Integer; Pp : Integer; OldLen : Integer; SLen : Integer; begin OldLen := System.Length(FChars); SLen := UTF8Length(C); if OldLen=FPassWordStart then FCharWidth:=FFont.GetTextWidth(FPassWordChar) else FCharWidth:=FFont.GetTextWidth(FChar); FFrontColor := FC; FBackColor := BC; end; Inc(pp,l); end; UpdateSum; end; procedure TColorstring.Delete(Index,Len:Integer); var i:Integer; begin if (Len=0) or (Index>=System.Length(FChars)) then Exit; if Index+Len>System.Length(FChars) then Len:=System.Length(FChars)-Index; for i:=Index to System.Length(FChars)-Len-1 do FChars[i]:=FChars[i+Len]; SetLength(FChars,System.Length(FChars)-Len); UpdateSum; end; procedure TColorstring.Delete(Index:Integer); var i:Integer; begin if (Index>=System.Length(FChars)) then Exit; for i:=Index to System.Length(FChars)-2 do FChars[i]:=FChars[i+1]; SetLength(FChars,System.Length(FChars)-1); UpdateSum; end; function TColorstring.GetPartstring(Start,Ende:Integer):string; var i,n : Integer; Len : Integer; begin if Start<0 then Start:=0; if Ende>High(FChars) then Ende:=High(FChars); Len:=0; for i:=Start to Ende do Inc(Len,System.Length(FChars[i].FChar)); SetLength(Result,Len); Len:=1; for i:=Start to Ende do begin with FChars[i] do begin for n:=1 to System.Length(FChar) do begin Result[Len]:=FChar[n]; Inc(Len); end; end; end; end; function TColorstring.Getstring:String; var i,n : Integer; Len : Integer; begin Len := 0; for i:=0 to High(FChars) do Inc(Len,System.Length(FChars[i].FChar)); SetLength(Result,Len); Len := 1; for i:=0 to High(FChars) do begin with FChars[i] do begin for n:=1 to System.Length(FChar) do begin Result[Len]:=FChar[n]; Inc(Len); end; end; end; end; procedure TColorstring.OverWritePW(S:TColorstring;PWS,Pos:Integer;PWC:String); var i : Integer; CPassWordStart:Integer; begin MinimumLength(Pos+S.Length,CLSilver,S.FDefaultBackGround); CPassWordStart:=PWS; for i:=0 to S.Length-1 do begin FChars[i+Pos]:=S.FChars[i]; if CPassWordStart<=0 then FChars[i+Pos].FChar:=PWC; Dec(CPassWordStart); end; UpdateSum; end; procedure TColorstring.OverWrite(S:TColorstring;Pos:Integer); var i : Integer; begin MinimumLength(Pos+S.Length,CLSilver,S.FDefaultBackGround); for i:=0 to S.Length-1 do FChars[i+Pos]:=S.FChars[i]; UpdateSum; end; procedure TColorstring.PartOverWrite(S:TColorstring;Start,Ende,Pos:Integer); var i : Integer; begin MinimumLength(Pos+Ende-Start,CLSilver,S.FDefaultBackGround); for i:=0 to Ende-Start-1 do FChars[i+Pos]:=S.FChars[i+Start]; UpdateSum; end; procedure TColorstring.OverWrite(s:String;Pos:Integer;FC,BC:TColor); var i,Pp,l : Integer; begin MinimumLength(Pos+UTF8Length(S),FC,BC); Pp:=1; for i:=0 to UTF8Length(S)-1 do begin l:=UTF8CharacterLength(@s[Pp]); with FChars[i+Pos] do begin FChar := Copy(S,Pp,l); FCharWidth := FFont.GetTextWidth(FChar); FFrontColor := FC; FBackColor := BC; end; Inc(Pp,l); end; UpdateSum; end; procedure TColorstring.OverWriteChar(s:TUTF8Char;Pos,ADefWidth:Integer;FC,BC:TColor); begin MinimumLength(Pos+1,FC,BC); with FChars[Pos] do begin FChar := s; FCharWidth := ADefWidth; FFrontColor := FC; FBackColor := BC; end; UpdateSum; end; procedure TColorstring.MinimumLength(V:Integer;FC,BC:TColor); var OldLen,i:Integer; begin if System.Length(FChars)V then SetLength(FChars,V); end; procedure TColorstring.Clear; begin FChars:=Nil; end; procedure TCmdBox.ClearLine; begin if FLines[FOutY].Length<>0 then begin FLines[FOutY].Clear; FOutX:=0; if FInput then FInputY:=FOutY; Invalidate; end; end; function TCmdBox.GetCaretInterval:Integer; begin Result:=FCaretTimer.Interval; end; procedure TCmdBox.SetCaretInterval(AValue:Integer); begin FCaretTimer.Interval:=AValue; end; procedure TCmdBox.MultiWrite; var DoWrite:Boolean; begin System.EnterCriticalSection(FLock); DoWrite:=FStringBuffer.Count<>0; if DoWrite then begin FCurrentString:=FStringBuffer[0]; FStringBuffer.Delete(0); end; System.LeaveCriticalSection(FLock); if DoWrite then IntWrite; end; procedure TCmdBox.Write(S:String); begin if ThreadID=MainThreadId then begin MultiWrite; FCurrentString:=S; IntWrite; end else begin System.EnterCriticalSection(FLock); FStringBuffer.Add(S); System.LeaveCriticalSection(FLock); if Assigned(WakeMainThread) then TThread.Synchronize(Nil,@MultiWrite); end; end; function TCmdBox.HistoryIndexOf(s:string):Integer; begin for Result:=0 to HistoryCount-1 do if History[Result]=s then Exit; Result:=-1; end; function TCmdBox.HistoryHas(s:string):Boolean; var i:Integer; begin Result := True; for i:=0 to HistoryCount-1 do if History[i]=s then Exit; Result := False; end; function TCmdBox.HistoryCount:Integer; begin HistoryCount:=FHistoryLength-Ord(FInput); end; function TCmdBox.GetHistory(i:Integer):string; begin Inc(i,Ord(FInput)); if (i>=0) and (iFHistoryMax then begin if FHistoryLength>v then FHistoryLength:=v; for i:=v to FHistoryMax-1 do FHistory[i].Free; SetLength(FHistory,v); for i:=FHistoryMax to v-1 do FHistory[i]:=TColorstring.Create(Canvas.Font); FHistoryMax:=v; end; end; procedure TCmdBox.WriteStream(Stream:TStream); var c:wideString; begin while Stream.Position-1 then FInputBuffer.ColorBlock(FSelStart,FSelEnd,FInputColor,FInputBackGround); if Start=Ende then FSelStart:=-1 else begin if Start-1 then FInputBuffer.ColorBlock(FSelStart,FSelEnd,FInputSelColor,FInputSelBackGround); end; procedure TCmdBox.CopyToClipBoard; begin if FSelStart<>-1 then begin ClipBoard.AsText:=FInputBuffer.GetPartstring(FSelStart,FSelEnd); end; end; procedure TCmdBox.PasteFromClipBoard; var s:widestring; l,Pp:Integer; begin if ClipBoard.HasFormat(CF_TEXT) then begin s := ClipBoard.AsText; Pp := 1; while pp<=Length(s) do begin l := UTF8CharacterLength(@S[Pp]); if (l=1) and (Byte(S[Pp])<32) then Delete(s,Pp,1) else inc(Pp,l); end; FInputBuffer.Insert(InputPos,s,FInputColor,FInputBackGround); InputPos := InputPos + UTF8Length(s); FCaretX:=FInputX+InputPos; AdjustScrollBars; MakeInputVisible; FHistoryPos:=0; if Assigned(FOnInputChange) then FOnInputChange(Self,FInputBuffer); if Assigned(FOnAny) then FOnAny(Self,FInputBuffer); end; end; procedure TCmdBox.DeleteSelected; begin if FSelStart<>-1 then begin FInputBuffer.Delete(FSelStart,FSelEnd-FSelStart+1); FInputPos := FSelStart; FCaretX := FInputX+FInputPos; FSelStart := -1; end; end; procedure TCmdBox.CutToClipBoard; begin if FSelStart<>-1 then begin ClipBoard.AsText:=FInputBuffer.GetPartstring(FSelStart,FSelEnd); DeleteSelected; end; end; procedure TCmdBox.MouseMove(Shift:TShiftState;x,y:Integer); begin if FMouseDown then begin if MoveInputCaretTo(x,y,false) then SetSelection(FMouseDownInputPos,FInputPos); end; end; function TCmdBox.MoveInputCaretTo(x,y:Integer;chl:Boolean):Boolean; var h,sl,q:Integer; begin if not FInput then Exit; y := y div FCharHeight; h := FLineHeightSum[FTopLine]+FLineOfTopLine+y; sl := FTopLine; while (slFInputBuffer.Length) then q:=FInputBuffer.Length-FInputX; FCaretX := q; FInputPos := FCaretX-FInputX; if Assigned(FOnAny) then FOnAny(Self,FInputBuffer); Invalidate; Result:=True; end else Result:=False; end; procedure TCmdBox.MouseDown(Button:TMouseButton;Shift:TShiftState;x,y:Integer); begin SetFocus; MoveInputCaretTo(x,y,True); FMouseDown:=True; SetSelection(-1,0); FMouseDownInputPos:=FInputPos; Invalidate; end; procedure TCmdBox.MouseUp(Button:TMouseButton;Shift:TShiftState;x,y:Integer); begin FMouseDown:=False; end; destructor TColorstring.Destroy; begin Clear; inherited Destroy; end; procedure TCmdBox.ScrollUp; var n:Integer; Firstwidestring : TColorstring; begin Firstwidestring:=FLines[0]; for n:=0 to Length(FLines)-2 do Flines[n] := FLines[n+1]; Firstwidestring.Clear; Firstwidestring.FDefaultBackGround := FBackGroundColor; Flines[High(Flines)]:=Firstwidestring; end; procedure TCmdBox.TextColors(FC,BC:TColor); begin FCurrentColor := FC; FCurrentBackGround := BC; end; procedure TCmdBox.TextColor(C:TColor); begin FCurrentColor:=C; end; procedure TCmdBox.TextBackGround(C:TColor); begin FCurrentBackGround:=C; end; procedure TCmdBox.TranslateScrollBarPosition; var GLine,Line : Integer; He :Integer; begin if (FLineOfTopLineFVisibleLineCount-FPageHeight then CurrentPos:=FVisibleLineCount-FPageHeight; {$IFNDEF LCLGTK} ScrollBarPosition(SB_VERT, CurrentPos); {$ENDIF} FVSBPos:=CurrentPos; TranslateScrollBarPosition; end; procedure TCmdBox.ScrollBarRange(Which: Integer; aRange,aPage: Integer); var ScrollInfo: TScrollInfo; begin if HandleAllocated then begin FillChar(ScrollInfo, SizeOf(ScrollInfo), 0); ScrollInfo.cbSize := SizeOf(ScrollInfo); ScrollInfo.fMask := SIF_RANGE or SIF_PAGE or SIF_DISABLENOSCROLL; // Dont't know, someone told me to kick it...so i did:P // {$ifdef Unix} { ScrollInfo.fMask := ScrollInfo.fMask or SIF_UPDATEPOLICY; if goThumbTracking in Options then ScrollInfo.ntrackPos := SB_POLICY_CONTINUOUS else ScrollInfo.ntrackPos := SB_POLICY_DISCONTINUOUS;} // {$endif}} ScrollInfo.nMin := 0; ScrollInfo.nMax := ARange; if APage<0 then APage := 0; ScrollInfo.nPage := APage; SetScrollInfo(Handle, Which, ScrollInfo, True); end; end; procedure TCmdBox.ScrollBarPosition(Which, Value: integer); var ScrollInfo : TScrollInfo; Vis : Boolean; begin if HandleAllocated then begin if Which = SB_VERT then Vis := FVSbVisible else FillChar(ScrollInfo, SizeOf(ScrollInfo), 0); ScrollInfo.cbSize := SizeOf(ScrollInfo); ScrollInfo.fMask := SIF_POS; ScrollInfo.nPos := Value; SetScrollInfo(Handle, Which, ScrollInfo, Vis); end; end; function TCmdBox.GetSystemMetricsGapSize(const Index:Integer):Integer; begin {$ifdef LCLWIN32} result:=0; {$else} result:=3; {$endif} end; procedure TCmdBox.SetBackGroundColor(c:TColor); begin if c<>FBackGroundColor then begin FBackGroundColor:=c; Invalidate; end; end; procedure TCmdBox.SetFont(F:TFont); var DC : HDC; Save : THandle; Metrics : TTextMetric; begin FFont.Assign(F); Canvas.Font := FFont; DC := GetDC(0); Save := SelectObject(DC,FFont.Handle); GetTextMetrics(DC, Metrics); SelectObject(DC, Save); ReleaseDC(0, DC); FCharHeight := Abs(Metrics.tmHeight)+2; Invalidate; end; // Still a Bug: Try having a cmdline with more lines than fit on screen : update doesn't work anymore... procedure TCmdBox.MakeInputVisible; var y : Integer; begin if not FAutoFollow then Exit; UpdateLineHeights; y:=FLineHeightSum[FInputY]+FInputBuffer.GetLineOfCaret(FClientWidth,FCaretX,FCaretWidth); if y>=FLineHeightSum[FTopLine]+FLineOfTopLine+FPageHeight then begin While y>=FLineHeightSum[FTopLine]+FLineHeights[FTopLine]+FPageHeight-1 do Inc(FTopLine); FLineOfTopLine:=y-(FLineHeightSum[FTopLine]+FPageHeight)+1; end else if yFVSBPos then begin FVSBPos:=y; if HandleAllocated then ScrollBarPosition(SB_Vert,y); end; end; procedure TCmdBox.MakeOutVisible; var y : Integer; begin if not FAutoFollow then Exit; UpdateLineHeights; y:=FLineHeightSum[FOutY]+FLines[FOutY].GetLineOfCaret(FClientWidth,FOutX,FCaretWidth); if y>=FLineHeightSum[FTopLine]+FLineOfTopLine+FPageHeight then begin While y>=FLineHeightSum[FTopLine]+FLineHeights[FTopLine]+FPageHeight-1 do Inc(FTopLine); FLineOfTopLine:=y-(FLineHeightSum[FTopLine]+FPageHeight)+1; end else if yFVSBPos then begin FVSBPos:=y; if HandleAllocated then ScrollBarPosition(SB_Vert,y); end; end; procedure TCmdBox.SetHistoryPos(v:Integer); begin if FInputIsPassWord then Exit; if v<0 then v:=FHistoryLength-1 else if v>=FHistoryLength then v:=0; if v<>FHistoryPos then begin if FHistoryPos=0 then begin FHistory[0].Clear; FHistory[0].PartOverWrite(FInputBuffer,FInputMinPos,FInputBuffer.Length,0); end; FInputBuffer.MaximumLength(FInputMinPos+FHistory[v].Length); FInputBuffer.OverWrite(FHistory[v],FInputMinPos); if FInputPos>FInputBuffer.Length then begin FInputPos:=FInputBuffer.Length; FCaretX:=FInputX+FInputPos; end; FHistoryPos:=v; end; if Assigned(FOnInputChange) then FOnInputChange(Self,FInputBuffer); MakeInputVisible; AdjustLineHeight(FInputY); AdjustScrollBars; Invalidate; end; procedure TCmdBox.UTF8KeyPress(var Key:TUTF8Char); begin if not FInput then Exit; if key>=#32 then begin if FSelStart<>-1 then DeleteSelected; FInputBuffer.Insert(FInputPos,key,FInputColor,FInputBackGround); Inc(FInputPos); FCaretX:=FInputX+FInputPos; FHistoryPos:=0; if assigned(FOnInputChange) then FOnInputChange(Self,FInputBuffer); end; if Assigned(OnAny) then OnAny(Self,FInputBuffer); AdjustScrollBars; MakeInputVisible; If FInputVisible then Invalidate; end; procedure TCmdBox.KeyDown(var Key:Word;Shift:TShiftState); var s : String; i : Integer; begin if not FInput then Exit; case Key of VK_END: begin key:=0; if (not (ssAlt in Shift)) and FInput and (FInputPos<>FInputBuffer.Length) then begin if not (ssShift in Shift) then SetSelection(-1,0) else RightSelection(FInputPos,FInputBuffer.Length); FInputPos:=FInputBuffer.Length; FCaretX:=FInputX+FInputPos; MakeInputVisible; Invalidate; end; end; VK_HOME: begin key:=0; if (not (ssAlt in Shift)) and FInput and (FInputPos<>FInputMinPos) then begin if not (ssShift in Shift) then SetSelection(-1,0) else LeftSelection(FInputMinPos,FInputPos); FInputPos:=FInputMinPos; FCaretX:=FInputX+FInputPos; MakeInputVisible; Invalidate; end; end; VK_LEFT: begin if (not (ssAlt in Shift)) and (FInput and (FInputPos>FInputMinPos)) then begin if not (ssShift in Shift) then SetSelection(-1,0) else LeftSelection(FInputPos-1,FInputPos); Dec(FInputPos); FCaretX:=FInputX+FInputPos; MakeInputVisible; Invalidate; end; end; VK_UP: begin if (not (ssAlt in Shift)) and FInput then begin SetSelection(-1,0); SetHistoryPos(FHistoryPos+1); end; end; VK_DOWN: begin if (not (ssAlt in Shift)) and FInput then begin SetSelection(-1,0); SetHistoryPos(FHistoryPos-1); end; end; VK_RIGHT: begin if (not (ssAlt in Shift)) and FInput and (FInputPos-1 then DeleteSelected else FInputBuffer.Delete(FInputPos); FHistoryPos:=0; if assigned(FOnInputChange) then FOnInputChange(Self,FInputBuffer); MakeInputVisible; AdjustLineHeight(FInputY); AdjustScrollBars; end; end; VK_RETURN: begin if FInput then begin s := FInputBuffer.GetString; s := Copy(s,FUTF8InputMinPos+1,Length(s)); if (FHistoryPos=0) then begin if (FInputBuffer.Length=FInputMinPos) or FInputIsPassWord then begin DeleteHistoryEntry(0); end else begin i:=HistoryIndexOf(s); if i>=0 then begin DeleteHistoryEntry(0); MakeFirstHistoryEntry(i); end else begin FHistory[0].Clear; FHistory[0].PartOverWrite(FInputBuffer,FInputMinPos,FInputBuffer.Length,0); end; end; end else begin DeleteHistoryEntry(0); MakeFirstHistoryEntry(FHistoryPos); end; FInput := False; if FLines[FOutY].Length<>0 then begin if FOutY>=FLineCount-1 then begin ScrollUp; Dec(FOutY); FInputY:=FOutY; AdjustLineHeight(FOutY); UpdateLineHeights; TranslateScrollBarPosition; end; FLines[FOutY+1].Clear; FLines[FOutY+1].OverWrite(FLines[FOutY],0); FLines[FOutY].Clear; if FInputIsPassWord then FLines[FOutY].OverWritePW(FInputBuffer,FInputMinPos,FInputX,FPassWordChar) else FLines[FOutY].OverWrite(FInputBuffer,FInputX); end else begin if FInputIsPassWord then FLines[FOutY].OverWritePW(FInputBuffer,FInputMinPos,FInputX,FPassWordChar) else FLines[FOutY].OverWrite(FInputBuffer,FInputX); end; Inc(FOutY); if FOutY>=FLineCount then begin ScrollUp; Dec(FOutY); FInputY:=FOutY; AdjustLineHeight(FOutY); UpdateLineHeights; TranslateScrollBarPosition; end; FOutX := 0; FCaretX := 0; FInputBuffer.Clear; if Assigned(OnInput) then OnInput(Self,s); if Assigned(OnAny) then OnAny(Self,FInputBuffer); AdjustScrollBars; Invalidate; end; end; VK_BACK: begin if FInput then begin if FSelStart<>-1 then DeleteSelected else begin If (FInputPos>FInputMinPos) then begin Dec(FInputPos); FInputBuffer.Delete(FInputPos); FCaretX:=FInputX+FInputPos; end; end; FHistoryPos:=0; if assigned(FOnInputChange) then FOnInputChange(Self,FInputBuffer); if Assigned(OnAny) then OnAny(Self,FInputBuffer); AdjustScrollBars; MakeInputVisible; If FInputVisible then Invalidate; end; end; VK_C: begin if (FInput) and (ssCtrl in Shift) then CopyToClipBoard; end; VK_V: begin if (FInput) and (ssCtrl in Shift) then PasteFromClipBoard; end; VK_X: begin if (FInput) and (ssCtrl in Shift) then CutToClipBoard; end; VK_A: begin if (FInput) and (ssCtrl in Shift) then begin SetSelection(FInputMinPos,FInputBuffer.Length); FInputPos:=FInputBuffer.Length; MakeInputVisible; if FInputVisible then Invalidate; end; end; end; if Assigned(OnAny) then OnAny(Self,FInputBuffer); end; procedure TCmdBox.InsertHistory; var i : Integer; t : TColorstring; begin t:=FHistory[FHistoryMax-1]; for i:=FHistoryMax-2 downto 0 do begin FHistory[i+1]:=FHistory[i]; end; FHistory[0] := t; FHistoryPos := 0; If FHistoryLengthLength(Desc) then Break; case Desc[Pp+1] of #9,#10,#32,#46,#196: begin if Pp+2>Length(Desc) then Break; //Incomplete Escape Seq...ignore l:=3; end; #33,#47,#197: begin if Pp+3>Length(Desc) then Break; //Incomplete Escape Seq...ignore l:=4; end; else begin l:=2; end; end; end else l:=UTF8CharacterLength(@Desc[PP]); FInputBuffer.OverWriteChar(Copy(Desc,Pp,l),i,FGraphicCharWidth,DFC,DBC); Inc(i); Inc(Pp,l); end; FInputPos := i; FInputMinPos := i; // FInputBuffer.OverWrite(Desc,0,DFC,DBC); FInputIsPassWord := False; FInputColor := IFC; FInputBackground := IBC; FInputBuffer.PassWordStart:=MaxInt; InsertHistory; MakeInputVisible; end; procedure TCmdBox.StartReadPassWord(DFC,DBC:TColor;const Desc:string;IFC,IBC:TColor); begin StartRead(DFC,DBC,Desc,IFC,IBC); FInputBuffer.PassWordStart := UTF8Length(Desc); FInputBuffer.PassWordChar := FPassWordChar; FInputIsPassWord := True; end; procedure TCmdBox.StopRead; begin FInput:=False; end; procedure TCmdBox.DeleteHistoryEntry(i:Integer); var j:Integer; Temp:TColorstring; begin Temp:=FHistory[i]; for j:=i to FHistoryLength-2 do FHistory[j]:=FHistory[j+1]; FHistory[FHistoryLength-1]:=Temp; Dec(FHistoryLength); if FHistoryPos>=i then Dec(FHistoryPos); end; procedure TCmdBox.MakeFirstHistoryEntry(i:Integer); var Temp:TColorstring; begin if FHistoryPos<>0 then begin Temp:=FHistory[i]; for i:=i-1 downto 0 do FHistory[i+1]:=FHistory[i]; FHistory[0]:=Temp; end; end; procedure TCmdBox.Clear; var i:Integer; begin for i:=0 to Length(FLines)-1 do Flines[i].Clear; FCaretX := 0; FInputY := 0; FOutX := 0; FOutY := 0; if FInput then FInputY:=0; Invalidate; end; procedure TCmdBox.Writeln(s:string); begin write(s+#13#10); end; const AnsiColors:array['0'..'7'] of TColor=(clBlack,clRed,clGreen,clYellow,clBlue,clFuchsia,clAqua,clWhite); procedure TCmdBox.IntWrite; var Pp : Integer; l : Integer; s : String; EscPos : Integer; EscSubMode : Integer; begin S := FCurrentString; Pp := 1; while Pp<=Length(S) do begin l:=1; case FEscapeMode of escmNone: begin if S[Pp]=#27 then begin case FEscapeCodeType of esctCmdBox: begin FEscapeMode := escmOperation; FEscapeData := ''; end; esctAnsi: begin FEscapeMode := escmAnsiOperation; FEscapeData := ''; end; esctNone: begin // Simply ignore it end; end; end else begin l:=UTF8CharacterLength(@S[Pp]); if l=1 then begin case s[Pp] of #13:FOutX:=0; #10: begin AdjustLineHeight(FOutY); if FLines[FOutY].Length=0 then FLines[FOutY].DefaultBackGround:=FCurrentBackGround; Inc(FOutY); if FOutY>=Length(FLines) then begin ScrollUp; Dec(FOutY); AdjustLineHeight(FOutY); UpdateLineHeights; TranslateScrollBarPosition; end; end; else begin FLines[FOutY].OverWrite(s[Pp],FOutX,FCurrentColor,FCurrentBackGround); Inc(FOutX); end; end; end else begin FLines[FOutY].OverWrite(Copy(s,Pp,l),FOutX,FCurrentColor,FCurrentBackGround); Inc(FOutX); end; end; end; escmOperation: begin case S[Pp] of #9,#10,#32,#46,#196: begin FEscapeData := S[Pp]; FEscapeMode := escmData1; end; #33,#47,#197: begin FEscapeData := S[Pp]; FEscapeMode := escmData2; end; else begin FLines[FOutY].OverWriteChar(#27+S[Pp],FOutX,FGraphicCharWidth,FCurrentColor,FCurrentBackGround); Inc(FOutX); FEscapeMode:=escmNone; end; end; end; escmData1: begin FLines[FOutY].OverWriteChar(#27+FEscapeData+S[Pp],FOutX,FGraphicCharWidth,FCurrentColor,FCurrentBackGround); Inc(FOutX); FEscapeMode:=escmNone; end; escmData2: begin FEscapeData := FEscapeData+S[Pp]; FEscapeMode := escmData1; end; escmAnsiOperation: begin case S[Pp] of '[':FEscapeMode:=escmAnsiSquare; else FEscapeMode:=escmNone; end; end; escmAnsiSquare: begin case S[Pp] of 'm': begin EscPos := 1; EscSubMode := 0; while EscPos<=Length(FEscapeData) do begin case EscSubMode of 0: begin case FEscapeData[EscPos] of '0': begin // No Reset Values know here...just assume FCurrentColor:=clSilver; FCurrentBackGround:=clBlack; end; '7': begin // Reverse? What now... end; '3':EscSubMode:=3; '4':EscSubMode:=4; end; end; 1: begin // Just collect the expected ";", not sure what to do if it isn't there... EscSubMode:=0; end; 3: begin if FEscapeData[EscPos] in ['0'..'7'] then FCurrentColor:=AnsiColors[FEscapeData[EscPos]]; EscSubMode:=1; end; 4: begin if FEscapeData[EscPos] in ['0'..'7'] then FCurrentBackGround:=AnsiColors[FEscapeData[EscPos]]; EscSubMode:=1; end; end; Inc(EscPos); end; FEscapeMode:=escmNone; end; else begin FEscapeData:=FEscapeData+S[Pp]; end; end; end; end; Inc(Pp,l); end; if FInput then begin if FLines[FOutY].Length=0 then begin if (FInputY<>FOutY) then FInputY:=FOutY; end else begin if FInputY<>FOutY+1 then FInputY:=FOutY+1; end; if FInputY>=FLineCount then begin ScrollUp; Dec(FOutY); Dec(FInputY); FInputY:=FOutY; AdjustLineHeight(FOutY); UpdateLineHeights; TranslateScrollBarPosition; end; MakeInputVisible; end else MakeOutVisible; AdjustLineHeight(FOutY); if not FInput then FCaretX:=FOutX; AdjustScrollBars; end; procedure TCmdBox.SetOutY(v:Integer); begin if v>FLineCount-1 then v:=FLineCount-1; FOutY:=v; end; procedure TCmdBox.Resize; begin inherited Resize; AdjustScrollBars; if FVSBPos>=FVisibleLineCount-FPageHeight then begin FVSBPos:=FVisibleLineCount-FPageHeight; if FVSBPos<0 then FVSBPos:=0; end; TranslateScrollBarPosition; end; function TCmdBox.AdjustLineHeight(i:Integer):Integer; var LineC : Integer; LineC2 : Integer; begin if (FInputY=i) then begin LineC := FLines[i].LineCount(FClientWidth,-1,FCaretWidth); LineC2 := FInputBuffer.LineCount(FClientWidth,FCaretX,FCaretWidth); if LineC2>LineC then LineC:=LineC2; end else LineC:=FLines[i].LineCount(FClientWidth,-1,FCaretWidth); Result := LineC; FLineHeights[i] := Result; end; function TCmdBox.UpdateLineHeights:integer; var i:integer; begin Result:=0; for i:=0 to FLineCount-1 do begin FLineHeightSum[i]:=Result; Inc(Result,AdjustLineHeight(i)); end; end; procedure TCmdBox.AdjustScrollBars; var LH : Integer; begin FClientWidth := Width-FVSBWidth; FClientHeight := Height; FPageHeight := FClientHeight div FCharHeight; FVisibleLines := FPageHeight+ord(FClientHeight mod FCharHeight<>0); LH := UpdateLineHeights; if LH<>FVisibleLineCount then begin FVisibleLineCount:=LH; if FVisibleLineCount<=FVSBPos+FPageHeight then begin FVSBPos:=FVisibleLineCount-FPageHeight; if FVSBPos<0 then FVSBPos:=0; if HandleAllocated then ScrollBarPosition(SB_Vert,FVSBPos); TranslateScrollBarPosition; end; end; if FVisibleLineCountFTopLine then begin FTopLine:=Nr; AdjustScrollBars; end; end; procedure TCmdBox.SetLineCount(c: Integer); var i:Integer; begin if c<1 then c:=1; if c<>FLineCount then begin for i:=0 to FLineCount-1 do FLines[i].Free; FLineCount:=c; SetLength(FLines,FLinecount); for i:=0 to FlineCount-1 do begin FLines[i]:=TColorstring.Create(Canvas.Font); FLines[i].DefaultBackGround:=FBackGroundColor; FLines[i].TabWidth:=FTabWidth; end; SetLength(FLineHeights,FLineCount); SetLength(FLineHeightSum,FLineCount); AdjustScrollBars; end; end; procedure TCmdBox.Paint; Var y,m : Integer; CurrentLine : Integer; begin inherited Paint; with canvas do begin if (csdesigning in componentstate) then begin Brush.Style := bsSolid; Brush.Color := clBlack; FillRect(0,0,FClientWidth,FClientHeight); exit; end; Font := FFont; Brush.Style := bsSolid; m := FVisibleLines-1; y := -FLineOfTopLine; CurrentLine := FTopLine; while (y<=m) and (CurrentLine doublecmd-0.8.2/components/CmdLine/COPYING.LESSER0000664000175000017500000001717211077656332020256 0ustar alexxalexx GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.doublecmd-0.8.2/components/CmdLine/COPYING0000664000175000017500000010574111077656332017262 0ustar alexxalexx GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read .doublecmd-0.8.2/components/CmdLine/cmdbox.pas0000664000175000017500000000053212677725617020212 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit cmdbox; interface uses uCmdBox, LazarusPackageIntf; implementation procedure Register; begin RegisterUnit('uCmdBox', @uCmdBox.Register); end; initialization RegisterPackage('cmdbox', @Register); end. doublecmd-0.8.2/components/CmdLine/demotext.txt0000664000175000017500000000355712014201074020600 0ustar alexxalexxHello This is a little Demo for TCmdBox You can type commands while this text is written here ! Available commands : * help : Short list for all commands * stop : Stops me from reading this text... * pause : Interrupts me * resume : Continues at the last position pause was called... * start : Restarts reading this text.. * clear : Clears the output buffer * clearhistory : clears history buffer for previous input * exit : Exits the program A few details to TCmdBox... To put TCmdBox into Inputmode use (example) CmdBox.StartRead(clRed,clBlack,'>',clSilver,clBlack); If you give a string parameter to StartRead, it will be displayed directly before the input and will follow it. Input is received through an Event called OnInput. Changes can be watched by the programm by OnInputChange. To keep TCmdBox in Inputmode just call StartRead in OnInput again. If you resize the application or use splitter in the middle you notice lines are wrapped, there is no fixed or limited line width. Input is also saved in a history list with limited to HistoryMax entries including current input. Output content by using: CmdBox.Write('Text'); or CmdBox.Writeln('Text...'); These calls are supposed to be Threadsafe ! You can use all font and background colors possible on the Operating System, for example CmdBox.TextColor(clRed); CmdBox.TextBackGround(clSilver); or CmdBox.TextColors(clRed,clSilver); The background color of the last character in a line determines the background color of the rest of the line. The component should be able to show correct UTF8 codes of any kind (up to the whole 21 bits), therefore: €, ä, ö,ü should be correctly written as Euro, Ae, Oe, Ue (the last three are german) if you have selected a UTF8 capable Font and LCL-Interface. I hope you can use the component, if you find bugs or have suggestions contact me by email : kccmp@gmx.dedoublecmd-0.8.2/components/CmdLine/tcmdbox.lrs0000664000175000017500000000252711077656332020407 0ustar alexxalexxLazarusResources.Add('TCmdBox','XPM',[ '/* XPM */'#13#10'static char *tcmdbox[] = {'#13#10'/* width height num_color' +'s chars_per_pixel */'#13#10'" 24 24 8 1",'#13#10'/*' +' colors */'#13#10'"` c #C0C0C0",'#13#10'". c #000000",'#13#10'"# c #000000"' +','#13#10'"a c #000000",'#13#10'"b c #000000",'#13#10'"c c #000000",'#13#10 +'"d c #000000",'#13#10'"e c #000000",'#13#10'/* pixels */'#13#10'"``````````' +'``````````````",'#13#10'"`......................`",'#13#10'"`..`...`....`..' +'``...``.`",'#13#10'"`.`..`.`....`..`.`.`...`",'#13#10'"`.`.....`..```.``..`' +'...`",'#13#10'"`.`..`..`..`.`.`.`.`...`",'#13#10'"`..`.....`.`.`.``...``.`"' +','#13#10'"`......................`",'#13#10'"`......................`",'#13 +#10'"`......................`",'#13#10'"`......................`",'#13#10'"`' +'......................`",'#13#10'"`.````.................`",'#13#10'"`.....' +'.................`",'#13#10'"`......................`",'#13#10'"`..........' +'............`",'#13#10'"`......................`",'#13#10'"`...............' +'.......`",'#13#10'"`......................`",'#13#10'"`....................' +'..`",'#13#10'"`......................`",'#13#10'"`......................`",' +#13#10'"`......................`",'#13#10'"````````````````````````"'#13#10 +'};'#13#10 ]); doublecmd-0.8.2/components/CmdLine/wnmainform.lrs0000664000175000017500000001436411077656332021126 0ustar alexxalexx{ Das ist eine automatisch erzeugte Lazarus-Ressourcendatei } LazarusResources.Add('TWMainForm','FORMDATA',[ 'TPF0'#10'TWMainForm'#9'WMainForm'#4'Left'#3'?'#1#6'Height'#3#224#1#3'Top'#3 +'Q'#1#5'Width'#3#208#2#13'ActiveControl'#7#6'CmdBox'#7'Caption'#6#27'TCmdBox' +' Example Application'#12'ClientHeight'#3#224#1#11'ClientWidth'#3#208#2#8'On' +'Create'#7#10'FormCreate'#9'OnDestroy'#7#11'FormDestroy'#8'Position'#7#14'po' +'ScreenCenter'#10'LCLVersion'#6#6'0.9.25'#0#6'TPanel'#10'RightPanel'#4'Left' +#3'C'#2#6'Height'#3#224#1#5'Width'#3#141#0#5'Align'#7#7'alRight'#12'ClientHe' +'ight'#3#224#1#11'ClientWidth'#3#141#0#8'TabOrder'#2#0#0#6'TLabel'#6'Label1' +#4'Left'#2#16#6'Height'#2#14#3'Top'#2#8#5'Width'#2'#'#7'Caption'#6#7'History' +#11'ParentColor'#8#0#0#7'TButton'#7'Button1'#4'Left'#2#16#6'Height'#2#25#3'T' +'op'#3#184#1#5'Width'#2'm'#7'Anchors'#11#6'akLeft'#7'akRight'#8'akBottom'#0 +#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#12'End Programm'#7'OnClick'#7 +#12'Button1Click'#8'TabOrder'#2#0#0#0#8'TListBox'#11'HistoryList'#4'Left'#2 +#16#6'Height'#3#29#1#3'Top'#2#24#5'Width'#2'm'#7'Anchors'#11#5'akTop'#6'akLe' +'ft'#7'akRight'#8'akBottom'#0#8'TabOrder'#2#1#0#0#7'TButton'#7'Button2'#4'Le' +'ft'#2#16#6'Height'#2#25#3'Top'#3';'#1#5'Width'#2'm'#7'Anchors'#11#6'akLeft' +#7'akRight'#8'akBottom'#0#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#5'C' +'lear'#7'OnClick'#7#12'Button2Click'#8'TabOrder'#2#2#0#0#9'TComboBox'#10'CbS' +'etCaret'#4'Left'#2#16#6'Height'#2#21#3'Top'#3#141#1#5'Width'#2'm'#7'Anchors' +#11#6'akLeft'#7'akRight'#8'akBottom'#0#16'AutoCompleteText'#11#22'cbactEndOf' +'LineComplete'#20'cbactSearchAscending'#0#10'ItemHeight'#2#13#9'ItemIndex'#2 +#0#13'Items.Strings'#1#6#10'Caret-Line'#6#13'Caret-Sub-Bar'#6#13'Caret-Big-B' +'ar'#0#8'OnChange'#7#16'CbSetCaretChange'#5'Style'#7#14'csDropDownList'#8'Ta' +'bOrder'#2#3#4'Text'#6#10'Caret-Line'#0#0#7'TButton'#7'Button3'#4'Left'#2#16 +#6'Height'#2#25#3'Top'#3'a'#1#5'Width'#2'm'#7'Anchors'#11#6'akLeft'#7'akRigh' +'t'#8'akBottom'#0#7'Caption'#6#7'Process'#7'OnClick'#7#12'Button3Click'#8'Ta' +'bOrder'#2#4#0#0#0#9'TSplitter'#9'Splitter1'#4'Left'#3'>'#2#6'Height'#3#224#1 +#5'Width'#2#5#5'Align'#7#7'alRight'#7'Beveled'#9#12'ResizeAnchor'#7#7'akRigh' +'t'#0#0#7'TCmdBox'#6'CmdBox'#6'Height'#3#224#1#5'Width'#3'>'#2#5'Align'#7#8 +'alClient'#10'CaretColor'#4#255#128#0#0#9'CaretType'#7#8'cartUser'#10'CaretW' +'idth'#2#1#11'CaretHeight'#2#13#11'CaretYShift'#2#3#7'OnInput'#7#11'CmdBoxIn' +'put'#9'LineCount'#3#232#3#12'Font.CharSet'#7#12'ANSI_CHARSET'#10'Font.Color' +#7#8'clSilver'#11'Font.Height'#2#240#9'Font.Name'#6#5'Arial'#10'Font.Pitch'#7 +#10'fpVariable'#15'BackGroundColor'#7#6'clNavy'#8'TabWidth'#2'<'#12'PassWord' +'Char'#6#1'*'#10'HistoryMax'#2#10#13'InputSelColor'#7#8'clPurple'#18'InputSe' +'lBackGround'#7#8'clSilver'#13'CaretInterval'#3#244#1#23'GraphicalCharacterW' +'idth'#2#10#10'AutoFollow'#9#0#0#6'TTimer'#11'ReaderTimer'#8'Interval'#3#188 +#2#7'OnTimer'#7#16'ReaderTimerTimer'#4'left'#2'B'#3'top'#2'K'#0#0#6'TTimer' +#12'ProcessTimer'#7'Enabled'#8#8'Interval'#2'd'#7'OnTimer'#7#17'ProcessTimer' +'Timer'#4'left'#2'h'#3'top'#2'K'#0#0#0#10'TWMainForm'#9'WMainForm'#4'Left'#3 +'?'#1#6'Height'#3#224#1#3'Top'#3'Q'#1#5'Width'#3#208#2#13'ActiveControl'#7#6 +'CmdBox'#7'Caption'#6#27'TCmdBox Example Application'#12'ClientHeight'#3#224 +#1#11'ClientWidth'#3#208#2#8'OnCreate'#7#10'FormCreate'#9'OnDestroy'#7#11'Fo' +'rmDestroy'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#6'0.9.25'#0#6 +'TPanel'#10'RightPanel'#4'Left'#3'C'#2#6'Height'#3#224#1#5'Width'#3#141#0#5 +'Align'#7#7'alRight'#12'ClientHeight'#3#224#1#11'ClientWidth'#3#141#0#8'TabO' +'rder'#2#0#0#6'TLabel'#6'Label1'#4'Left'#2#16#6'Height'#2#14#3'Top'#2#8#5'Wi' +'dth'#2'#'#7'Caption'#6#7'History'#11'ParentColor'#8#0#0#7'TButton'#7'Button' +'1'#4'Left'#2#16#6'Height'#2#25#3'Top'#3#184#1#5'Width'#2'm'#7'Anchors'#11#6 +'akLeft'#7'akRight'#8'akBottom'#0#25'BorderSpacing.InnerBorder'#2#4#7'Captio' +'n'#6#12'End Programm'#7'OnClick'#7#12'Button1Click'#8'TabOrder'#2#0#0#0#8'T' +'ListBox'#11'HistoryList'#4'Left'#2#16#6'Height'#3#29#1#3'Top'#2#24#5'Width' +#2'm'#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#8'akBottom'#0#8'TabOrder'#2 +#1#0#0#7'TButton'#7'Button2'#4'Left'#2#16#6'Height'#2#25#3'Top'#3';'#1#5'Wid' +'th'#2'm'#7'Anchors'#11#6'akLeft'#7'akRight'#8'akBottom'#0#25'BorderSpacing.' +'InnerBorder'#2#4#7'Caption'#6#5'Clear'#7'OnClick'#7#12'Button2Click'#8'TabO' +'rder'#2#2#0#0#9'TComboBox'#10'CbSetCaret'#4'Left'#2#16#6'Height'#2#21#3'Top' +#3#141#1#5'Width'#2'm'#7'Anchors'#11#6'akLeft'#7'akRight'#8'akBottom'#0#16'A' +'utoCompleteText'#11#22'cbactEndOfLineComplete'#20'cbactSearchAscending'#0#10 +'ItemHeight'#2#13#9'ItemIndex'#2#0#13'Items.Strings'#1#6#10'Caret-Line'#6#13 +'Caret-Sub-Bar'#6#13'Caret-Big-Bar'#0#8'OnChange'#7#16'CbSetCaretChange'#5'S' +'tyle'#7#14'csDropDownList'#8'TabOrder'#2#3#4'Text'#6#10'Caret-Line'#0#0#7'T' +'Button'#7'Button3'#4'Left'#2#16#6'Height'#2#25#3'Top'#3'a'#1#5'Width'#2'm'#7 +'Anchors'#11#6'akLeft'#7'akRight'#8'akBottom'#0#7'Caption'#6#7'Process'#7'On' +'Click'#7#12'Button3Click'#8'TabOrder'#2#4#0#0#0#9'TSplitter'#9'Splitter1'#4 ,'Left'#3'>'#2#6'Height'#3#224#1#5'Width'#2#5#5'Align'#7#7'alRight'#7'Beveled' +#9#12'ResizeAnchor'#7#7'akRight'#0#0#7'TCmdBox'#6'CmdBox'#6'Height'#3#224#1#5 +'Width'#3'>'#2#5'Align'#7#8'alClient'#10'CaretColor'#4#255#128#0#0#9'CaretTy' +'pe'#7#8'cartUser'#10'CaretWidth'#2#1#11'CaretHeight'#2#13#11'CaretYShift'#2 +#3#7'OnInput'#7#11'CmdBoxInput'#9'LineCount'#3#232#3#12'Font.CharSet'#7#12'A' +'NSI_CHARSET'#10'Font.Color'#7#8'clSilver'#11'Font.Height'#2#240#9'Font.Name' +#6#5'Arial'#10'Font.Pitch'#7#10'fpVariable'#15'BackGroundColor'#7#6'clNavy'#8 +'TabWidth'#2'<'#12'PassWordChar'#6#1'*'#10'HistoryMax'#2#10#13'InputSelColor' +#7#8'clPurple'#18'InputSelBackGround'#7#8'clSilver'#13'CaretInterval'#3#244#1 +#23'GraphicalCharacterWidth'#2#10#10'AutoFollow'#9#0#0#6'TTimer'#11'ReaderTi' +'mer'#8'Interval'#3#188#2#7'OnTimer'#7#16'ReaderTimerTimer'#4'left'#2'B'#3't' +'op'#2'K'#0#0#6'TTimer'#12'ProcessTimer'#7'Enabled'#8#8'Interval'#2'd'#7'OnT' +'imer'#7#17'ProcessTimerTimer'#4'left'#2'h'#3'top'#2'K'#0#0#0 ]); doublecmd-0.8.2/components/CmdLine/cmdbox.lpk0000664000175000017500000000242612144672601020200 0ustar alexxalexx doublecmd-0.8.2/components/CmdLine/CmdLineExample.lpr0000664000175000017500000000050112014201074021536 0ustar alexxalexxprogram CmdLineExample; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Interfaces, // this includes the LCL widgetset Forms { add your units here }, wnmainform; begin Application.Initialize; Application.CreateForm(TWMainForm, WMainForm); Application.Run; end. doublecmd-0.8.2/components/CmdLine/wnmainform.pas0000664000175000017500000001511412014201074021060 0ustar alexxalexx{ Copyright (C) 2007 Julian Schutsch This source is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. A copy of the GNU General Public License is available on the World Wide Web at . You can also obtain it by writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. This Software is GPL, not LGPL as the libary it uses ! Changelog 10.8.2007 : Added "Buttons" Unit to avoid "TButton" missing error on 0.9.22 (Linux) } unit wnmainform; {$mode objfpc}{$H+} interface uses Classes, SysUtils, LResources, Forms, Graphics, Dialogs, ExtCtrls,LCLType, ucmdbox, StdCtrls, Controls, Buttons; type { TWMainForm } TWMainForm = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; CmdBox: TCmdBox; CbSetCaret: TComboBox; Label1: TLabel; HistoryList: TListBox; RightPanel: TPanel; Splitter1: TSplitter; ReaderTimer: TTimer; ProcessTimer: TTimer; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure CmdBoxInput(ACmdBox: TCmdBox; Input: String); procedure CbSetCaretChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure ProcessTimerTimer(Sender: TObject); procedure ReaderTimerTimer(Sender: TObject); private TextPosition : Integer; DText : TStringList; Rdpw : Boolean; FProcess : Integer; end; var WMainForm: TWMainForm; implementation { TWMainForm } procedure TWMainForm.ReaderTimerTimer(Sender: TObject); var i:Integer; begin CmdBox.TextColors(clRed,clNavy); for i:=0 to 0 do begin if TextPosition=DText.Count then begin CmdBox.ClearLine; CmdBox.TextColor(clYellow); CmdBox.Writeln(#27#10#196); TextPosition := 0; ReaderTimer.Enabled := False; end; end; end; procedure TWMainForm.FormCreate(Sender: TObject); begin DoubleBuffered := True; DText := TStringList.Create; if FileExists('demotext.txt') then DText.LoadFromFile('demotext.txt'); CmdBox.StartRead(clRed,clNavy,'>',clYellow,clNavy); CmdBox.TextColors(clWhite,clNavy); CmdBox.Writeln(#27#218#27#10#191); CmdBox.Writeln(#27#179'Type "help" to see a short list of available commands.'#27#10#179); CmdBox.Writeln(#27#217#27#10#217); end; procedure TWMainForm.CmdBoxInput(ACmdBox: TCmdBox; Input: String); var i:Integer; begin if rdpw then begin CmdBox.TextColors(clLime,clBlue); CmdBox.Writeln('Your Secret Password : '+Input); CmdBox.TextColors(clSilver,clNavy); rdpw:=false; end else begin rdpw:=false; Input:=LowerCase(Input); if Input='help' then begin CmdBox.TextColors(clLime,clNavy); CmdBox.Writeln(#27#218#27#197#128#0#27#194#27#10#191); CmdBox.Writeln(#27#179' Command'#27#33#128#0#27#179' Explanation'#27#10#179); CmdBox.Writeln(#27#195#27#197#128#0#27#198#27#10#180); CmdBox.Writeln(#27#179' help'#27#33#128#0#27#179' Gives this list of Commands'#27#10#179); CmdBox.Writeln(#27#179' clear'#27#33#128#0#27#179' Clears the Content of CmdBox'#27#10#179); CmdBox.Writeln(#27#179' start'#27#33#128#0#27#179' Outputs the Content of Demotext.txt from the beginning'#27#10#179); CmdBox.Writeln(#27#179' stop'#27#33#128#0#27#179' Stops output and resets to Start'#27#10#179); CmdBox.Writeln(#27#179' pause'#27#33#128#0#27#179' Interrupts output'#27#10#179); CmdBox.Writeln(#27#179' resume'#27#33#128#0#27#179' Resumes output from the last position'#27#10#179); CmdBox.Writeln(#27#179' clearhistory'#27#33#128#0#27#179' Clears all history entries'#27#10#179); CmdBox.Writeln(#27#179' readpwd'#27#33#128#0#27#179' Read a Password (just as a test)'#27#10#179); CmdBox.Writeln(#27#179' exit'#27#33#128#0#27#179' Exit program'#27#10#179); CmdBox.Writeln(#27#217#27#197#128#0#27#193#27#10#217); CmdBox.TextColor(clSilver); end else if Input='readpwd' then begin rdpw:=true; end else if Input='clearhistory' then begin CmdBox.TextColor(clYellow); CmdBox.Writeln('Clear History...'); CmdBox.TextColor(clSilver); CmdBox.ClearHistory; end else if Input='start' then begin TextPosition:=0; ReaderTimer.Enabled:=true; CmdBox.TextColors(clLime,clBlue); CmdBox.Writeln('Start...'); end else if Input='stop' then begin TextPosition:=0; ReaderTimer.Enabled:=false; CmdBox.TextColors(clRed,clBlue); CmdBox.Writeln('Stop...'); end else if Input='pause' then begin ReaderTimer.Enabled:=false; CmdBox.TextColors(clPurple,clBlue); CmdBox.Writeln('Pause...'); end else if Input='resume' then begin ReaderTimer.Enabled:=true; CmdBox.TextColors(clGreen,clBlue); CmdBox.Writeln('Continue...'); end else if Input='clear' then begin CmdBox.Clear; end else if Input='exit' then close else begin CmdBox.TextColors(clYellow,ClRed); CmdBox.Writeln('Invalid Command!'); end; end; if rdpw then CmdBox.StartReadPassWord(clYellow,clNavy,'Pwd:',clLime,clNavy) else CmdBox.StartRead(clRed,clNavy,'>',clYellow,clNavy); HistoryList.Clear; for i:=0 to CmdBox.HistoryCount-1 do HistoryList.Items.Add(CmdBox.History[i]); end; procedure TWMainForm.CbSetCaretChange(Sender: TObject); begin case cbSetCaret.ItemIndex of 0:CmdBox.CaretType := cartLine; 1:CmdBox.CaretType := cartSubBar; 2:CmdBox.CaretType := cartBigBar; end; CmdBox.SetFocus; end; procedure TWMainForm.Button2Click(Sender: TObject); begin CmdBox.ClearHistory; HistoryList.Clear; end; procedure TWMainForm.Button3Click(Sender: TObject); begin FProcess:=0; ProcessTimer.Enabled:=True; end; procedure TWMainForm.Button1Click(Sender: TObject); begin Close; end; procedure TWMainForm.FormDestroy(Sender: TObject); begin DText.Free; end; procedure TWMainForm.ProcessTimerTimer(Sender: TObject); begin if FProcess=100 then begin CmdBox.ClearLine; ProcessTimer.Enabled:=False; end else begin CmdBox.TextColors(clRed,clBlue); CmdBox.Write('Processing ['+IntToStr(FProcess)+'%]'#13); end; Inc(FProcess); end; initialization {$I wnmainform.lrs} end. doublecmd-0.8.2/components/CmdLine/tcmdbox.xpm0000664000175000017500000000172411077656332020411 0ustar alexxalexx/* XPM */ static char *tcmdbox[] = { /* width height num_colors chars_per_pixel */ " 24 24 8 1", /* colors */ "` c #C0C0C0", ". c #000000", "# c #000000", "a c #000000", "b c #000000", "c c #000000", "d c #000000", "e c #000000", /* pixels */ "````````````````````````", "`......................`", "`..`...`....`..``...``.`", "`.`..`.`....`..`.`.`...`", "`.`.....`..```.``..`...`", "`.`..`..`..`.`.`.`.`...`", "`..`.....`.`.`.``...``.`", "`......................`", "`......................`", "`......................`", "`......................`", "`......................`", "`.````.................`", "`......................`", "`......................`", "`......................`", "`......................`", "`......................`", "`......................`", "`......................`", "`......................`", "`......................`", "`......................`", "````````````````````````" }; doublecmd-0.8.2/components/viewer/0000775000175000017500000000000013244011205016163 5ustar alexxalexxdoublecmd-0.8.2/components/viewer/MappingFile.pas0000664000175000017500000002202512014201074021063 0ustar alexxalexx{ **************************************************** } { MappingFile unit v1.0 for Delphi } { Copyright (c) Razumikhin Dmitry, 2005 } { E-mail: razumikhin_d@mail.ru } { } { Use under terms LGPL license: } { http://www.gnu.org/copyleft/lesser.html } { **************************************************** } unit MappingFile; interface uses SysUtils, Windows, Classes, RTLConsts; type EFileMappingError = class(Exception); TMappingFile = class private fHandle: Integer; //file handle fFileName: string; //file name fMode: Word; //file open mode fMappingHandle: THandle; //handle of mapping file fBaseAddress: PChar; //address of file image in memory fPos: Integer; //current position fSize: Integer; //size of real data fCapacity: Integer; //size of allocated memory fExtraMem: Integer; function GetChar(Index: Integer): Char; procedure SetSize(const Value: Integer); procedure SetChar(Index: Integer; const Value: Char); procedure TryMount; procedure ReMount; procedure SetCapacity(const Value: Integer); procedure SetPos(const Value: Integer); public property BaseAddress: PChar read fBaseAddress; property Size: Integer read fSize write SetSize; property Capacity: Integer read fCapacity write SetCapacity; property ExtraMem: Integer read fExtraMem write fExtraMem; property Ch[Index: Integer]: Char read GetChar write SetChar; property Position: Integer read fPos write SetPos; function Seek(Offset, Origin: Integer): Integer; //read functions function ReadCh(out Ch: Char): Boolean; function ReadStr(out Str: string; Len: Integer): Boolean; overload; function ReadStr(const Index, Len: Integer): string; overload; function Find(Ch: Char; StartIndex: Integer = 0): Integer; //write functions procedure WriteCh(const Ch: Char); procedure WriteStr(const Str: string); overload; procedure WriteStr(const Str: string; Index: Integer); overload; procedure WriteBuffer(const Buf: PChar; Count: Integer); overload; procedure WriteBuffer(const Buf: PChar; Index, Count: Integer); overload; //insert functions (expand + write) procedure InsertBuffer(const Buf: PChar; Count: Integer); overload; procedure InsertBuffer(const Buf: PChar; Index, Count: Integer); overload; procedure InsertStr(const Str: string); overload; procedure InsertStr(const Str: string; Index: Integer); overload; constructor Create(const FileName: string; Mode: Word); destructor Destroy; override; end; function FileResize(Handle: THandle; Size: Integer): LongBool; function FileMount(var MappingHandle: THandle; const FileHandle: Integer; ReadOnly: Boolean = True): Pointer; procedure FileUmount(MappingHandle: THandle; BaseAddress: Pointer); implementation { TMappingFile } constructor TMappingFile.Create(const FileName: string; Mode: Word); begin inherited Create; fFileName:=FileName; fMode:=Mode; fPos:=0; fSize:=0; fCapacity:=0; fExtraMem:=1024; fBaseAddress:=nil; if Mode = fmCreate then begin fHandle:=FileCreate(FileName); if fHandle < 0 then raise EFCreateError.CreateResFmt(@SFCreateErrorEx, [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); end else begin fHandle:=FileOpen(FileName, Mode); if fHandle < 0 then raise EFOpenError.CreateResFmt(@SFOpenErrorEx, [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); end; fSize:=GetFileSize(fHandle, nil); fCapacity:=fSize; TryMount; end; destructor TMappingFile.Destroy; begin FileUmount(fMappingHandle, fBaseAddress); if fSize <> fCapacity then FileResize(fHandle, fSize); if fHandle >=0 then FileClose(fHandle); inherited; end; function TMappingFile.Find(Ch: Char; StartIndex: Integer): Integer; var i: Integer; begin for i:=StartIndex to fSize-1 do if Ch = PChar(fBaseAddress + i)^ then begin Result:=i; Exit; end; Result:=-1; end; function TMappingFile.GetChar(Index: Integer): Char; begin Result:=PChar(fBaseAddress + Index)^; //Not control the bounds end; procedure TMappingFile.InsertBuffer(const Buf: PChar; Count: Integer); begin InsertBuffer(Buf, fPos, Count); Inc(fPos, Count); end; procedure TMappingFile.InsertBuffer(const Buf: PChar; Index, Count: Integer); var MoveCount: Integer; begin if Count <> 0 then begin MoveCount:=fSize - Index; SetSize(fSize + Count); Move(PChar(fBaseAddress + Index)^, PChar(fBaseAddress + Index + Count)^, MoveCount); Move(Buf^, PChar(fBaseAddress + Index)^, Count); end; end; procedure TMappingFile.InsertStr(const Str: string); begin InsertBuffer(PChar(Str), Length(Str)); end; procedure TMappingFile.InsertStr(const Str: string; Index: Integer); begin InsertBuffer(PChar(Str), Index, Length(Str)); end; function TMappingFile.ReadCh(out Ch: Char): Boolean; begin Result:=fPos < fSize; if Result then begin Ch:=PChar(fBaseAddress + fPos)^; Inc(fPos, SizeOf(Char)); end else Ch:=#0; end; function TMappingFile.ReadStr(out Str: string; Len: Integer): Boolean; begin Result:=(fPos + Len) <= fSize; SetLength(Str, Len); Move(PChar(fBaseAddress + fPos)^, Str[1], Len); Inc(fPos, Len); end; function TMappingFile.ReadStr(const Index, Len: Integer): string; begin SetLength(Result, Len); Move(PChar(fBaseAddress + Index)^, Result[1], Len); end; procedure TMappingFile.Remount; begin if Assigned(fBaseAddress) then FileUmount(fMappingHandle, fBaseAddress); TryMount; end; function TMappingFile.Seek(Offset, Origin: Integer): Integer; var NewPos: Integer; begin Result:=-1; case Origin of 0: begin if Offset >= 0 then begin if (Offset > fSize) then SetSize(Offset); fPos:=Offset; Result:=Offset; end; end; 1: begin NewPos:= fPos + Offset; if NewPos >=0 then begin if (NewPos > fSize) then SetSize(NewPos); fPos:=NewPos; Result:=NewPos; end; end; 2: begin NewPos:=fSize - Offset - 1; if NewPos >=0 then begin if (NewPos > fSize) then SetSize(NewPos); fPos:=NewPos; Result:=NewPos; end; end; end; end; procedure TMappingFile.SetCapacity(const Value: Integer); begin if fCapacity <> Value then begin fCapacity := Value; FileResize(fHandle, fCapacity); Remount; end; end; procedure TMappingFile.SetChar(Index: Integer; const Value: Char); begin PChar(fBaseAddress + Index)^:=Value; //Not control the bounds end; procedure TMappingFile.SetPos(const Value: Integer); begin Seek(Value, 0); end; procedure TMappingFile.SetSize(const Value: Integer); begin if fSize <> Value then begin fSize := Value; if fPos >= fSize then fPos:=fSize - 1; if fSize > fCapacity then SetCapacity(fSize + fExtraMem); end; end; procedure TMappingFile.TryMount; begin if fSize > 0 then begin fBaseAddress:=FileMount(fMappingHandle, fHandle, fMode = fmOpenRead); if not Assigned(fBaseAddress) then raise EFileMappingError.CreateFmt('Could not mapped file ''%s''',[fFileName]); end; end; procedure TMappingFile.WriteBuffer(const Buf: PChar; Count: Integer); begin if (fPos + Count) > fSize then SetSize(fPos + Count); Move(Buf^, PChar(fBaseAddress + fPos)^, Count); fPos:=fPos + Count; end; procedure TMappingFile.WriteBuffer(const Buf: PChar; Index, Count: Integer); begin if (Index + Count) > fSize then SetSize(Index + Count); Move(Buf^, PChar(fBaseAddress + Index)^, Count); end; procedure TMappingFile.WriteCh(const Ch: Char); begin WriteBuffer(@Ch, SizeOf(Char)); end; procedure TMappingFile.WriteStr(const Str: string); begin WriteBuffer(PChar(Str), Length(Str)); end; procedure TMappingFile.WriteStr(const Str: string; Index: Integer); begin WriteBuffer(PChar(Str), Index, Length(Str)); end; //----------------------------------------------------------------------- function FileMount(var MappingHandle: THandle; const FileHandle: Integer; ReadOnly: Boolean = True): Pointer; var FileMappingMode, MapViewMode: DWORD; begin if ReadOnly then begin FileMappingMode:=PAGE_READONLY; MapViewMode:=FILE_MAP_READ; end else begin FileMappingMode:=PAGE_READWRITE; MapViewMode:=FILE_MAP_READ + FILE_MAP_WRITE; end; MappingHandle:=CreateFileMapping(FileHandle, nil, FileMappingMode, 0, 0, nil); if MappingHandle <> 0 then begin Result:=MapViewOfFile(MappingHandle, MapViewMode, 0, 0, 0); end else Result:=nil; end; procedure FileUmount(MappingHandle: THandle; BaseAddress: Pointer); begin if Assigned(BaseAddress) then UnmapViewOfFile(BaseAddress); if MappingHandle <> 0 then CloseHandle(MappingHandle); end; function FileResize(Handle: THandle; Size: Integer): LongBool; begin FileSeek(Handle, Size, 0); Result:=SetEndOfFile(Handle); end; end. doublecmd-0.8.2/components/viewer/viewerpackage.pas0000664000175000017500000000057212756114647021536 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit viewerpackage; interface uses ViewerControl, LazarusPackageIntf; implementation procedure Register; begin RegisterUnit('ViewerControl', @ViewerControl.Register); end; initialization RegisterPackage('viewerpackage', @Register); end. doublecmd-0.8.2/components/viewer/viewercontrol.pas0000664000175000017500000027675213243752341021631 0ustar alexxalexx{ Component ViewerControl (Free Pascal) show file in text (wraped or not) or bin or hex mode This is part of Seksi Commander To searching use uFindMmap, to movement call Upxxxx, Downxxxx, or set Position Realised under GNU GPL 2 author Radek Cervinka (radek.cervinka@centrum.cz) changes: 5.8 - customizable view area of transformed text(transformed Values per Line) - customizable separators - added view as decimal - added class TCharToCustomValueTransformProc to handle parameters of customizable modes(at this time - Hex and Dec) - Hex and Dec mode handled by the same mechanism(potentially can be added any additionsl custom mode) so added properties FHex and FDec - added property FCustom which is nil if current mode - not custom, or is equal to current customizable mode - Added CopyToClipboardF which copy transformed text to clipboard 5.7. (RC) - selecting text with mouse - CopyToclipBoard, SelectAll ?.6. - LoadFromStdIn and loading first 64Kb of files with size=0 :) (/proc fs ..) 17.6. (RC) - mapfile (in error set FMappedFile=nil) - writetext TABs fixed (tab is replaced by 9 spaces) - set correct position for modes hex, bin (SetPosition) 21.7 - wrap text on 80 character lines works better now (by Radek Polak) - problems with function UpLine for specific lines: (lines of 80(=cTextWidth) character ended with ENTER (=#10) 6.2. (RC) - ported to fpc for linux (CustomControl and gtk) 7.2. (RC) - use temp to new implementation of LoadFromStdIn (and mmap temp file) - faster drawing of text (I hope) contributors: Copyright (C) 2006-2018 Alexander Koblov (alexx2000@mail.ru) TODO: a) File mapping blocks writing into file by other processes. Either: + Open small text files by reading them all into memory (done). - Add optional custom loading/caching portions of file in memory and only reading from file when neccessary. b) Searching in Unicode encodings and case-insensitive searching. c) Selecting text does not work well with composed Unicode characters (characters that are composed of multiple Unicode characters). d) Drawing/selecting text does not work correctly with RTL (right to left) text. e) FTextHeight is unreliable with complex unicode characters. It should be calculated based on currently displayed text (get max from each line's height). } unit ViewerControl; {$mode objfpc}{$H+} interface uses SysUtils, Classes, Controls, StdCtrls, fgl; const MaxMemSize = $400000; // 4 Mb type TViewerControlMode = (vcmBin, vcmHex, vcmText, vcmWrap, vcmBook, vcmDec); TDataAccess = (dtMmap, dtNothing); TCharSide = (csBefore, csLeft, csRight, csAfter); TPtrIntList = specialize TFPGList; TGuessEncodingEvent = function(const s: string): string; TCustomCharsPresentation = class; TCharToCustomValueTransformProc = function(AChar:AnsiChar;AMaxDigitsCount:integer):AnsiString of object; { TCustomCharsPresentation } { Presentation one char is called Value Function for convert char to Value is ChrToValueProc } TCustomCharsPresentation = class public ValuesPerLine :integer; // = 16 for Hex by default MaxValueDigits :integer; // the max width of present char (255) - 3 symbols MaxAddrDigits :integer; // = 8; StartOfs :integer; // = OffsetWidth + 2; // ': ' EndOfs :integer; // = StartOfs + (ValuesPerLine * (ValueMaxDigits+SpaceCount)); StartAscii :integer; // = StartOfs + (ValuesPerLine * (ValueMaxDigits+SpaceCount)) + 2; // ' ' SpaceCount :integer; // = 1 - one spacebar between Values SeparatorSpace :AnsiString; // spacebar * SpaceCount SeparatorChar :AnsiChar; // '|' CountSeperate :integer; // insert SeparatorChar after every CountSeperate values ChrToValueProc :TCharToCustomValueTransformProc; // procedure which return presentation of one char constructor Create(APresentValuesPerLine,ACharMaxPresentWidth,AOffsetWidth,ACountSeparate:integer;AChrToValueProc:TCharToCustomValueTransformProc); destructor Destroy();override; end; type // If additional encodings are added they should be also supported by: // - GetNextCharAsAscii // - GetPrevCharAsAscii // - GetNextCharAsUtf8 // - ConvertToUTF8 // - UpdateSelection TViewerEncoding = (veAutoDetect, veUtf8, veUtf8bom, veAnsi, veOem, veCp1250, veCp1251, veCp1252, veCp1253, veCp1254, veCp1255, veCp1256, veCp1257, veCp1258, veCp437, veCp850, veCp852, veCp866, veCp874, veCp932, veCp936, veCp949, veCp950, veIso88591, veIso88592, veKoi8, veUcs2le, veUcs2be, veUtf16le, veUtf16be, veUtf32le, // = ucs4le veUtf32be); // = ucs4be TViewerEncodings = set of TViewerEncoding; const ViewerEncodingsNames: array [TViewerEncoding] of string = ('Auto-detect', 'UTF-8', 'UTF-8BOM', 'ANSI', 'OEM', 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254', 'CP1255', 'CP1256', 'CP1257', 'CP1258', 'CP437', 'CP850', 'CP852', 'CP866', 'CP874', 'CP932', 'CP936', 'CP949', 'CP950', 'ISO-8859-1', 'ISO-8859-2', 'KOI-8', 'UCS-2LE', 'UCS-2BE', 'UTF-16LE', 'UTF-16BE', 'UTF-32LE', 'UTF-32BE'); const ViewerEncodingMultiByte: TViewerEncodings = [ veUtf8, veUtf8bom, veUcs2le, veUcs2be, veUtf16le, veUtf16be, veUtf32le, veUtf32be]; ViewerEncodingDoubleByte: TViewerEncodings = [ veUcs2le, veUcs2be, veUtf16le, veUtf16be ]; type { TViewerControl } TViewerControl = class(TCustomControl) protected FEncoding: TViewerEncoding; FViewerControlMode: TViewerControlMode; FFileName: String; FFileHandle: THandle; FFileSize: Int64; FMappingHandle: THandle; FMappedFile: Pointer; FPosition: PtrInt; FHPosition: Integer; // Tab for text during horizontal scroll FHLowEnd: Integer; // End for HPosition (string with max char) FVisibleOffset: PtrInt; // Offset in symbols for current line (see IsVisible and MakeVisible) FLowLimit: PtrInt; // Lowest possible value for Position FHighLimit: PtrInt; // Position cannot reach this value FBOMLength: Integer; FLineList: TPtrIntList; FBlockBeg: PtrInt; FBlockEnd: PtrInt; FMouseBlockBeg: PtrInt; FMouseBlockSide: TCharSide; FSelecting: Boolean; FTextWidth: Integer; // max char count or width in window FTextHeight: Integer; // measured values of font, rec calc at font changed FScrollBarVert: TScrollBar; FScrollBarHorz: TScrollBar; FOnPositionChanged: TNotifyEvent; FUpdateScrollBarPos: Boolean; // used to block updating of scrollbar FScrollBarPosition: Integer; // for updating vertical scrollbar based on Position FHScrollBarPosition: Integer; // for updating horizontal scrollbar based on HPosition FColCount: Integer; FOnGuessEncoding: TGuessEncodingEvent; FHex:TCustomCharsPresentation; FDec:TCustomCharsPresentation; FCustom:TCustomCharsPresentation; function GetPercent: Integer; procedure SetPercent(const AValue: Integer); procedure SetBlockBegin(const AValue: PtrInt); procedure SetBlockEnd(const AValue: PtrInt); procedure SetPosition(Value: PtrInt); virtual; procedure SetHPosition(Value: Integer); procedure SetPosition(Value: PtrInt; Force: Boolean); overload; procedure SetHPosition(Value: Integer; Force: Boolean); overload; procedure SetEncoding(AEncoding: TViewerEncoding); function GetEncodingName: string; procedure SetEncodingName(AEncodingName: string); procedure SetViewerMode(Value: TViewerControlMode); procedure SetColCount(const AValue: Integer); {en Returns how many lines (given current FTextHeight) will fit into the window. } function GetClientHeightInLines: Integer; inline; {en Calculates how many lines can be displayed from given position. param(FromPosition Position from which to check. It should point to a start of a line.) @param(LastLineReached If it is set to @true when the function returns, then the last line of text was reached when scanning. This means that there are no more lines to be displayed other than the ones scanned from FromPosition. In other words: SetPosition(GetStartOfNextLine(FromPosition)) will be one line too many and will be scrolled back.) } function GetLinesTillEnd(FromPosition: PtrInt; out LastLineReached: Boolean): Integer; function GetBomLength: Integer; procedure UpdateLimits; {en @param(iStartPos Should point to start of a line. It is increased by the amount of parsed data (with line endings).) @param(aLimit Position which cannot be reached while reading from file.) @param(DataLength It is length in bytes of parsed data without any line endings. iStartPos is moved beyond the line endings though.) } function CalcTextLineLength(var iStartPos: PtrInt; const aLimit: Int64; out DataLength: PtrInt): Integer; function GetStartOfLine(aPosition: PtrInt): PtrInt; function GetEndOfLine(aPosition: PtrInt): PtrInt; function GetStartOfPrevLine(aPosition: PtrInt): PtrInt; function GetStartOfNextLine(aPosition: PtrInt): PtrInt; {en Changes the value of aPosition to X lines back or forward. @param(aPosition File position to change.) @param(iLines Nr of lines to scroll. If positive the position is increased by iLines lines, if negative the position is decreased by -iLines lines.) } function ScrollPosition(var aPosition: PtrInt; iLines: Integer): Boolean; {en Calculates (x,y) cursor position to a position within file. @param(x Client X coordinate of mouse cursor.) @param(y Client Y coordinate of mouse cursor.) @param(CharSide To which side of a character at returned position the (x,y) points to. Only valid if returned position is not -1.) @returns(Position in file to which (x,y) points to, based on what is currently displayed. Returns -1 if (x,y) doesn't point to any position (outside of the text for example).) } function XYPos2Adr(x, y: Integer; out CharSide: TCharSide): PtrInt; procedure OutText(x, y: Integer; StartPos: PtrInt; DataLength: Integer); procedure OutBin(x, y: Integer; sText: string; StartPos: PtrInt; DataLength: Integer); procedure OutCustom(x, y: Integer; sText: string;StartPos: PtrInt; DataLength: Integer); // render one line function TransformCustom(var APosition: PtrInt; ALimit: PtrInt;AWithAdditionalData:boolean=True): AnsiString; function TransformCustomBlock(var APosition: PtrInt; DataLength: integer ; ASeparatorsOn, AAlignData:boolean; out AChars:AnsiString): AnsiString; function HexToValueProc(AChar:AnsiChar;AMaxDigitsCount:integer):AnsiString; function DecToValueProc(AChar:AnsiChar;AMaxDigitsCount:integer):AnsiString; procedure WriteBin; procedure WriteText; procedure WriteCustom; virtual; function TransformText(const sText: String; const Xoffset: Integer): String; function TransformBin(var aPosition: PtrInt; aLimit: PtrInt): AnsiString; function TransformHex(var aPosition: PtrInt; aLimit: PtrInt): AnsiString;virtual; procedure AddLineOffset(const iOffset: PtrInt); inline; function MapFile(const sFileName: String): Boolean; procedure UnMapFile; procedure SetFileName(const sFileName: String); procedure UpdateScrollbars; procedure ViewerResize(Sender: TObject); {en Returns next unicode character from the file, depending on Encoding. It is a faster version, which does as little conversion as possible, but only Ascii values are guaranteed to be valid (0-127). Other unicode values may/may not be valid, so shouldn't be tested. This function is used for reading pure ascii characters such as line endings, tabs, white spaces, etc. } function GetNextCharAsAscii(const iPosition: PtrInt; out CharLenInBytes: Integer): Cardinal; function GetPrevCharAsAscii(const iPosition: PtrInt; out CharLenInBytes: Integer): Cardinal; {en Retrieve next character from the file depending on encoding and automatically convert it to UTF-8. If CharLenInBytes is greater than 0 but the result is an empty string then it's possible there was no appropriate UTF-8 character for the next character of the current encoding. } function GetNextCharAsUtf8(const iPosition: PtrInt; out CharLenInBytes: Integer): String; procedure ReReadFile; {en Searches for an ASCII character. @param(aPosition Position from where the search starts.) @param(aMaxBytes How many bytes are available for reading.) @param(AsciiChars The function searches for any character that this string contains.) @param(bFindNotIn If @true searches for first character not included in AsciiChars. If @false searches for first character included in AsciiChars.) } function FindAsciiSetForward(aPosition, aMaxBytes: PtrInt; const AsciiChars: String; bFindNotIn: Boolean): PtrInt; {en Same as FindForward but it searches backwards from pAdr. aMaxBytes must be number of available bytes for reading backwards from pAdr. } function FindAsciiSetBackward(aPosition, aMaxBytes: PtrInt; const AsciiChars: String; bFindNotIn: Boolean): PtrInt; {en Checks if current selection is still valid given current viewer mode and encoding. For example checks if selection is not in the middle of a unicode character. } procedure UpdateSelection; procedure ScrollBarVertScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); procedure ScrollBarHorzScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); function GetText(const StartPos, Len: PtrInt; const Xoffset: Integer): string; protected procedure KeyDown(var Key: word; Shift: TShiftState); override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override; function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure Paint; override; {en Scrolls the displayed text in the window. @param(iLines Nr of lines to scroll. If positive the text is scrolled downwards, if negative the text is scrolled upwards.) @returns(@true if the text was scrolled.) } function Scroll(iLines: Integer): Boolean; function HScroll(iSymbols: Integer): Boolean; procedure PageUp; procedure PageDown; procedure GoHome; procedure GoEnd; procedure HPageUp; procedure HPageDown; procedure HGoHome; procedure HGoEnd; function GetDataAdr: Pointer; procedure SelectAll; procedure SelectText(AStart, AEnd: PtrInt); procedure CopyToClipboard; procedure CopyToClipboardF; function Selection: String; function IsVisible(const aPosition: PtrInt): Boolean; overload; procedure MakeVisible(const aPosition: PtrInt); function ConvertToUTF8(const sText: AnsiString): String; function ConvertFromUTF8(const sText: String): AnsiString; function FindUtf8Text(iStartPos: PtrInt; const sSearchText: String; bCaseSensitive: Boolean; bSearchBackwards: Boolean): PtrInt; procedure ResetEncoding; function IsFileOpen: Boolean; inline; function DetectEncoding: TViewerEncoding; procedure GetSupportedEncodings(List: TStrings); property Percent: Integer Read GetPercent Write SetPercent; property Position: PtrInt Read FPosition Write SetPosition; property FileSize: Int64 Read FFileSize; property SelectionStart: PtrInt Read FBlockBeg Write SetBlockBegin; property SelectionEnd: PtrInt Read FBlockEnd Write SetBlockEnd; property EncodingName: string Read GetEncodingName Write SetEncodingName; property ColCount: Integer Read FColCount Write SetColCount; property OnGuessEncoding: TGuessEncodingEvent Read FOnGuessEncoding Write FOnGuessEncoding; published property Mode: TViewerControlMode Read FViewerControlMode Write SetViewerMode default vcmWrap; property FileName: String Read FFileName Write SetFileName; property Encoding: TViewerEncoding Read FEncoding Write SetEncoding default veAutoDetect; property OnPositionChanged: TNotifyEvent Read FOnPositionChanged Write FOnPositionChanged; property OnClick; property OnMouseDown; property OnMouseMove; property OnMouseUp; property OnMouseWheelUp; property OnMouseWheelDown; property Align; property Color; property Cursor default crIBeam; property Font; property ParentColor default False; property TabStop default True; end; procedure Register; implementation uses LCLType, LCLVersion, Graphics, Forms, LCLProc, Clipbrd, LConvEncoding, DCUnicodeUtils, LCLIntf, LazUTF8, DCOSUtils , DCConvertEncoding {$IF DEFINED(UNIX)} , BaseUnix, Unix, DCUnix {$ELSEIF DEFINED(WINDOWS)} , Windows, DCWindows {$ENDIF}; const //cTextWidth = 80; // wrap on 80 chars cBinWidth = 80; cMaxTextWidth = 1024; // maximum of chars on one line unwrapped text cTabSpaces = 8; // tab stop - allow to set in settings // These strings must be Ascii only. sNonCharacter: string = ' !"#$%&''()*+,-./:;<=>?@[\]^`{|}~'#13#10#9; sWhiteSpace : string = ' '#13#10#9#8; { TCustomCharsPresentation } constructor TCustomCharsPresentation.Create(APresentValuesPerLine, ACharMaxPresentWidth, AOffsetWidth, ACountSeparate: integer;AChrToValueProc:TCharToCustomValueTransformProc); begin SpaceCount:=1; // count of spacebars between values, =1 ValuesPerLine := APresentValuesPerLine; // default for hex: 16 values MaxAddrDigits := AOffsetWidth; // = 8 , count of symbols for display caret offset StartOfs := AOffsetWidth + 2; // ': ' MaxValueDigits := ACharMaxPresentWidth; // hex char (FF) - 2 symbols, dec char (255) - 3 symbols EndOfs := StartOfs + (ValuesPerLine * (MaxValueDigits+SpaceCount)); // +1 - take in spacebar StartAscii := StartOfs + (ValuesPerLine * (MaxValueDigits+SpaceCount)) + 2; // ' ' SeparatorChar:='|'; CountSeperate:=ACountSeparate; SeparatorSpace:=' '; ChrToValueProc:=AChrToValueProc; // method for convert char to Value end; destructor TCustomCharsPresentation.Destroy; begin inherited; end; // ---------------------------------------------------------------------------- constructor TViewerControl.Create(AOwner: TComponent); begin inherited Create(AOwner); Cursor := crIBeam; ParentColor := False; DoubleBuffered := True; ControlStyle := ControlStyle + [csTripleClicks, csOpaque]; TabStop := True; // so that it can get keyboard focus FEncoding := veAutoDetect; FViewerControlMode := vcmText; FCustom := nil; FFileName := ''; FMappedFile := nil; FFileHandle := 0; FMappingHandle := 0; FPosition := 0; FHPosition := 0; FHLowEnd := 0; FLowLimit := 0; FHighLimit := 0; FBOMLength := 0; FTextHeight:= 14; // dummy value FColCount := 1; FLineList := TPtrIntList.Create; FScrollBarVert := TScrollBar.Create(Self); FScrollBarVert.Parent := Self; FScrollBarVert.Kind := sbVertical; FScrollBarVert.Align := alRight; FScrollBarVert.OnScroll := @ScrollBarVertScroll; FScrollBarVert.TabStop := False; FScrollBarVert.PageSize := 0; FScrollBarHorz := TScrollBar.Create(Self); FScrollBarHorz.Parent := Self; FScrollBarHorz.Kind := sbHorizontal; FScrollBarHorz.Align := alBottom; FScrollBarHorz.OnScroll := @ScrollBarHorzScroll; FScrollBarHorz.TabStop := False; FScrollBarHorz.PageSize := 0; FUpdateScrollBarPos := True; FScrollBarPosition := 0; FHScrollBarPosition := 0; FOnPositionChanged := nil; FOnGuessEncoding := nil; OnResize := @ViewerResize; FHex:=TCustomCharsPresentation.Create(16,2,8,8,@HexToValueProc); FDec:=TCustomCharsPresentation.Create(15,3,8,5,@DecToValueProc); // for set bigger ValuePerLine need to improve method GetEndOfLine end; destructor TViewerControl.Destroy; begin FHex.Free; FDec.Free; FHex:=nil; FDec:=nil; FCustom:=nil; UnMapFile; if Assigned(FLineList) then FreeAndNil(FLineList); inherited Destroy; end; procedure TViewerControl.Paint; begin if not IsFileOpen then Exit; Canvas.Font := Self.Font; Canvas.Brush.Color := Self.Color; {$IF DEFINED(LCLQT) and (LCL_FULLVERSION < 093100)} Canvas.Brush.Style := bsSolid; Canvas.FillRect(ClientRect); {$ENDIF} Canvas.Brush.Style := bsClear; FTextHeight := Canvas.TextHeight('Wg') + 2; if FViewerControlMode = vcmBook then FTextWidth := ((ClientWidth - (Canvas.TextWidth('W') * FColCount)) div FColCount) else FTextWidth := ClientWidth div Canvas.TextWidth('W') - 2; FLineList.Clear; case FViewerControlMode of vcmBin : WriteBin; vcmText: WriteText; vcmWrap: WriteText; vcmBook: WriteText; vcmDec,vcmHex : WriteCustom; end; end; procedure TViewerControl.SetViewerMode(Value: TViewerControlMode); begin if not (csDesigning in ComponentState) then begin FLineList.Clear; // do not use cache from previous mode // Take limits into account for selection. FBlockBeg := FBlockBeg + (GetDataAdr - FMappedFile); FBlockEnd := FBlockEnd + (GetDataAdr - FMappedFile); FViewerControlMode := Value; case FViewerControlMode of vcmHex: FCustom:=FHex; vcmDec: FCustom:=FDec; else FCustom:=nil; end; FHPosition := 0; FBOMLength := GetBomLength; UpdateLimits; // Take limits into account for selection. FBlockBeg := FBlockBeg - (GetDataAdr - FMappedFile); FBlockEnd := FBlockEnd - (GetDataAdr - FMappedFile); UpdateSelection; // Force recalculating position. SetPosition(FPosition, True); SetHPosition(FHPosition, True); UpdateScrollbars; Invalidate; end else FViewerControlMode := Value; end; procedure TViewerControl.SetColCount(const AValue: Integer); begin if AValue > 0 then FColCount := AValue else FColCount := 1; end; function TViewerControl.ScrollPosition(var aPosition: PtrInt; iLines: Integer): Boolean; var i: Integer; NewPos: PtrInt; begin Result := False; NewPos := aPosition; if iLines < 0 then for i := 1 to -iLines do NewPos := GetStartOfPrevLine(NewPos) else for i := 1 to iLines do NewPos := GetStartOfNextLine(NewPos); Result := aPosition <> NewPos; aPosition := NewPos; end; function TViewerControl.Scroll(iLines: Integer): Boolean; var aPosition: PtrInt; begin aPosition := FPosition; Result := ScrollPosition(aPosition, iLines); if aPosition <> FPosition then SetPosition(aPosition); end; function TViewerControl.HScroll(iSymbols: Integer): Boolean; var newPos: integer; begin newPos := FHPosition; if (FHLowEnd - FTextWidth) > 0 then begin newPos := newPos+ iSymbols; if newPos < 0 then newPos := 0; if newPos > FHLowEnd-FTextWidth then newPos := FHLowEnd-FTextWidth; end; if newPos <> FHPosition then SetHPosition(newPos); end; function TViewerControl.GetText(const StartPos, Len: PtrInt; const Xoffset: Integer): string; begin SetString(Result, GetDataAdr + StartPos, Len); Result := TransformText(ConvertToUTF8(Result), Xoffset); end; function TViewerControl.CalcTextLineLength(var iStartPos: PtrInt; const aLimit: Int64; out DataLength: PtrInt): Integer; var MaxLineLength: Boolean; CharLenInBytes: Integer; OldPos, LastSpacePos: PtrInt; LastSpaceResult: Integer; begin Result := 0; DataLength := 0; LastSpacePos := -1; MaxLineLength := True; OldPos := iStartPos; while MaxLineLength and (iStartPos < aLimit) do begin case GetNextCharAsAscii(iStartPos, CharLenInBytes) of 9: // tab Inc(Result, cTabSpaces - Result mod cTabSpaces); 10: // stroka begin DataLength := iStartPos - OldPos; iStartPos := iStartPos + CharLenInBytes; Exit; end; 13: // karetka begin DataLength := iStartPos - OldPos; iStartPos := iStartPos + CharLenInBytes; // Move after possible #10. if (iStartPos < aLimit) and (GetNextCharAsAscii(iStartPos, CharLenInBytes) = 10) then Inc(iStartPos, CharLenInBytes); Exit; end; 32, 33, 40, 41, 44, 45, 46, 47, 92, 58, 59, 63, 91, 93: //probel begin Inc(Result, 1); LastSpacePos := iStartPos + CharLenInBytes; LastSpaceResult := Result; end; else Inc(Result, 1); end; if CharLenInBytes = 0 then // End of data or invalid character. break; iStartPos := iStartPos + CharLenInBytes; DataLength := iStartPos - OldPos; case FViewerControlMode of vcmText: MaxLineLength := Result < cMaxTextWidth; vcmWrap: MaxLineLength := Result < FTextWidth; vcmBook: MaxLineLength := Canvas.TextWidth(GetText(OldPos, DataLength, 0)) < FTextWidth; else Exit; end; end; if (not MaxLineLength) and (LastSpacePos <> -1) then begin iStartPos := LastSpacePos; Result := LastSpaceResult; DataLength := iStartPos - OldPos; end; end; function TViewerControl.TransformText(const sText: String; const Xoffset: Integer): String; var c: AnsiChar; i: Integer; begin Result := ''; for i := 1 to Length(sText) do begin c := sText[i]; // Parse only ASCII chars. case c of #9: Result := Result + StringOfChar(' ', cTabSpaces - (UTF8Length(Result) + Xoffset) mod cTabSpaces); else begin if c < ' ' then Result := Result + ' ' else Result := Result + c; end; end; end; end; function TViewerControl.TransformBin(var aPosition: PtrInt; aLimit: PtrInt): AnsiString; var c: AnsiChar; i: Integer; begin Result := ''; for i := 0 to cBinWidth - 1 do begin if aPosition >= aLimit then Break; c := PAnsiChar(GetDataAdr)[aPosition]; if c < ' ' then Result := Result + '.' else if c > #127 then Result := Result + '.' else Result := Result + c; Inc(aPosition); end; end; function TViewerControl.TransformHex(var aPosition: PtrInt; aLimit: PtrInt): AnsiString; begin Result:=TransformCustom(aPosition,aLimit); end; function TViewerControl.TransformCustom(var APosition: PtrInt; ALimit: PtrInt; AWithAdditionalData: boolean): AnsiString; var sAscii: string = ''; sRez : string = ''; tPos : integer; begin tPos:=APosition; sRez:=TransformCustomBlock(APosition,FCustom.ValuesPerLine,True,True,sAscii); // Result := LineFormat(sRez, sStr, aStartOffset) else if AWithAdditionalData then begin sRez := Format('%s: %s', [IntToHex(tPos, FCustom.MaxAddrDigits), sRez]); if Length(sRez) < FCustom.ValuesPerLine * (FCustom.SpaceCount+FCustom.MaxValueDigits) then sRez := sRez + StringOfChar(' ', FCustom.ValuesPerLine * (FCustom.SpaceCount+FCustom.MaxValueDigits) - Length(sRez)); sRez := sRez + ' '; sRez := sRez + sAscii; end; Result:=sRez; end; function TViewerControl.TransformCustomBlock(var APosition: PtrInt; DataLength: integer ; ASeparatorsOn, AAlignData:boolean; out AChars:AnsiString): AnsiString; var c: AnsiChar; i: Integer; iSep,Len :integer; sStr: string = ''; sRez: string = ''; sEmpty:string; aStartOffset: PtrInt; begin if (APosition+DataLength)>FHighLimit then Len:=FHighLimit-APosition else Len:=DataLength; iSep:=1; // counter for set separator aStartOffset := APosition; for i := 0 to Len - 1 do begin c := PAnsiChar(GetDataAdr)[aPosition]; if c < ' ' then AChars := AChars + '.' else if c > #127 then AChars := AChars + '.' else AChars := AChars + c; sRez := sRez + FCustom.ChrToValueProc(c, FCustom.MaxValueDigits); if ( iSep = FCustom.CountSeperate) and ASeparatorsOn and ( i < (FCustom.ValuesPerLine - 1))then begin sRez := sRez + FCustom.SeparatorChar; iSep:=0; end else begin sRez := sRez + FCustom.SeparatorSpace; end; Inc(aPosition); inc(iSep); end; if AAlignData then begin setlength(sEmpty,FCustom.MaxValueDigits); FillChar(sEmpty[1],FCustom.MaxValueDigits,chr(VK_SPACE)); while (i FLowLimit) do begin prevChar := GetPrevCharAsAscii(tmpPos, CharLenInBytes); if CharLenInBytes = 0 then Break; Dec(tmpPos, CharLenInBytes); end; // Previous end of line not found and there are no more data to check. if (not (prevChar in [10, 13])) and (tmpPos <= FLowLimit) then Exit(FLowLimit); // Move forward to first non-line ending character. Inc(tmpPos, CharLenInBytes); // Search for start of real line or wrapped line. while True do begin LineStartPos := tmpPos; CalcTextLineLength(tmpPos, FHighLimit, DataLength); if tmpPos = aPosition then begin if aPosition < FHighLimit then Exit(aPosition) // aPosition is already at start of a line else Exit(LineStartPos); // aPosition points to end of file so return start of this line end else if tmpPos > aPosition then Exit(LineStartPos); // Found start of line end; end; function GetStartOfLineFixed(aFixedWidth: Integer): PtrInt; begin Result := aPosition - (aPosition mod aFixedWidth); end; var i: Integer; begin if aPosition <= FLowLimit then Exit(FLowLimit) else if aPosition >= FHighLimit then aPosition := FHighLimit; // search from the end of the file // Speedup for currently displayed positions. if (FLineList.Count > 0) and (aPosition >= FLineList.Items[0]) and (aPosition <= FLineList.Items[FLineList.Count - 1]) then begin for i := FLineList.Count - 1 downto 0 do if FLineList.Items[i] <= aPosition then Exit(FLineList.Items[i]); end; case FViewerControlMode of vcmBin: Result := GetStartOfLineFixed(cBinWidth); vcmHex, vcmDec: Result := GetStartOfLineFixed(FCustom.ValuesPerLine); vcmText, vcmWrap, vcmBook: Result := GetStartOfLineText; else Result := aPosition; end; end; function TViewerControl.GetEndOfLine(aPosition: PtrInt): PtrInt; function GetEndOfLineText: PtrInt; var tmpPos: PtrInt; DataLength: PtrInt; begin Result := GetStartOfLine(aPosition); tmpPos := Result; CalcTextLineLength(tmpPos, FHighLimit, DataLength); Result := Result + DataLength; if Result < aPosition then Result := aPosition; end; function GetEndOfLineFixed(aFixedWidth: Integer): PtrInt; begin Result := aPosition - (aPosition mod aFixedWidth) + aFixedWidth; end; begin case FViewerControlMode of vcmBin: Result := GetEndOfLineFixed(cBinWidth); vcmHex,vcmDec: Result := GetEndOfLineFixed(FCustom.ValuesPerLine); vcmText, vcmWrap, vcmBook: Result := GetEndOfLineText; else Result := aPosition; end; end; function TViewerControl.GetStartOfPrevLine(aPosition: PtrInt): PtrInt; function GetPrevLineText: PtrInt; var tmpPos, LineStartPos: PtrInt; DataLength: PtrInt; prevChar: Cardinal; CharLenInBytes: Integer; begin prevChar := GetPrevCharAsAscii(aPosition, CharLenInBytes); if CharLenInBytes = 0 then Exit(aPosition); tmpPos := aPosition - CharLenInBytes; // start search from previous character if tmpPos <= FLowLimit then Exit(FLowLimit); // Check if we're not in the middle of line ending // (previous char is #13, current char is #10). if (prevChar = 13) and (GetNextCharAsAscii(aPosition, CharLenInBytes) = 10) then begin prevChar := GetPrevCharAsAscii(tmpPos, CharLenInBytes); if CharLenInBytes = 0 then Exit(aPosition); Dec(tmpPos, CharLenInBytes); end else begin // Bypass possible end of previous line. if prevChar = 10 then begin prevChar := GetPrevCharAsAscii(tmpPos, CharLenInBytes); if CharLenInBytes = 0 then Exit(aPosition); Dec(tmpPos, CharLenInBytes); end; if prevChar = 13 then begin prevChar := GetPrevCharAsAscii(tmpPos, CharLenInBytes); if CharLenInBytes = 0 then Exit(aPosition); Dec(tmpPos, CharLenInBytes); end; end; if tmpPos <= FLowLimit then Exit(FLowLimit); // Search for real start of line. while (not (prevChar in [10, 13])) and (tmpPos > FLowLimit) do begin prevChar := GetPrevCharAsAscii(tmpPos, CharLenInBytes); if CharLenInBytes = 0 then Break; Dec(tmpPos, CharLenInBytes); end; // Move forward to first non-line ending character. Inc(tmpPos, CharLenInBytes); // Search for start of real line or wrapped line. while True do begin LineStartPos := tmpPos; CalcTextLineLength(tmpPos, aPosition, DataLength); if tmpPos >= aPosition then Exit(LineStartPos); // Found start of line end; end; function GetPrevLineFixed(aFixedWidth: Integer): PtrInt; begin Result := aPosition - (aPosition mod aFixedWidth); if Result >= aFixedWidth then Result := Result - aFixedWidth; end; var i: Integer; begin if aPosition <= FLowLimit then Exit(FLowLimit) else if aPosition >= FHighLimit then aPosition := FHighLimit; // search from the end of the file // Speedup for currently displayed positions. if (FLineList.Count > 0) and (aPosition >= FLineList.Items[0]) and (aPosition <= FLineList.Items[FLineList.Count - 1]) then begin for i := FLineList.Count - 1 downto 0 do if FLineList.Items[i] < aPosition then Exit(FLineList.Items[i]); end; case FViewerControlMode of vcmBin: Result := GetPrevLineFixed(cBinWidth); vcmHex,vcmDec: Result := GetPrevLineFixed(FCustom.ValuesPerLine); vcmText, vcmWrap, vcmBook: Result := GetPrevLineText; else Result := aPosition; end; end; function TViewerControl.GetStartOfNextLine(aPosition: PtrInt): PtrInt; function GetNextLineText: PtrInt; var tmpPos: PtrInt; DataLength: PtrInt; prevChar: Cardinal; CharLenInBytes: Integer; begin tmpPos := aPosition; // This might not be a real start of line (it may be start of wrapped line). // Search for start of line. while (tmpPos > FLowLimit) do begin prevChar := GetPrevCharAsAscii(tmpPos, CharLenInBytes); if CharLenInBytes = 0 then Break; if (prevChar in [10, 13]) then Break else Dec(tmpPos, CharLenInBytes); end; // Now we know we are at the start of a line, search the start of next line. while True do begin CalcTextLineLength(tmpPos, FHighLimit, DataLength); if tmpPos >= aPosition then Exit(tmpPos); // Found start of line end; end; function GetNextLineFixed(aFixedWidth: Integer): PtrInt; begin Result := aPosition - (aPosition mod aFixedWidth); if Result + aFixedWidth < FHighLimit then Result := Result + aFixedWidth; end; var i: Integer; begin if aPosition < FLowLimit then aPosition := FLowLimit // search from the start of the file else if aPosition >= FHighLimit then aPosition := FHighLimit; // search from the end of the file // Speedup for currently displayed positions. if (FLineList.Count > 0) and (aPosition >= FLineList.Items[0]) and (aPosition <= FLineList.Items[FLineList.Count - 1]) then begin for i := 0 to FLineList.Count - 1 do if FLineList.Items[i] > aPosition then Exit(FLineList.Items[i]); end; case FViewerControlMode of vcmBin: Result := GetNextLineFixed(cBinWidth); vcmHex,vcmDec: Result := GetNextLineFixed(FCustom.ValuesPerLine); vcmText, vcmWrap, vcmBook: Result := GetNextLineText; else Result := aPosition; end; end; procedure TViewerControl.PageUp; var H: Integer; begin H := GetClientHeightInLines * FColCount - 1; if H <= 0 then H := 1; Scroll(-H); end; procedure TViewerControl.HPageUp; var H: Integer; begin H := FHPosition - FTextWidth; if H <= 0 then H := FHPosition else H:= FTextWidth; HScroll(-H); end; procedure TViewerControl.PageDown; var H: Integer; begin H := GetClientHeightInLines * FColCount - 1; if H <= 0 then H := 1; Scroll(H); end; procedure TViewerControl.HPageDown; var H: Integer; begin H := FHLowEnd - FHPosition; if H > FTextWidth then H := FTextWidth ; HScroll(H); end; procedure TViewerControl.GoHome; begin Position := FLowLimit; end; procedure TViewerControl.GoEnd; begin Position := FHighLimit; end; procedure TViewerControl.HGoHome; begin HScroll (-FHPosition); end; procedure TViewerControl.HGoEnd; begin HScroll (FHLowEnd-FHPosition); end; procedure TViewerControl.SetFileName(const sFileName: String); begin if not (csDesigning in ComponentState) then begin UnMapFile; if sFileName <> '' then begin if MapFile(sFileName) then begin FFileName := sFileName; // Detect encoding if needed. if FEncoding = veAutoDetect then FEncoding := DetectEncoding; ReReadFile; end; end; end else FFileName := sFileName; end; function TViewerControl.MapFile(const sFileName: String): Boolean; function ReadFile: Boolean; inline; begin FMappedFile := GetMem(FFileSize); Result := (FileRead(FFileHandle, FMappedFile^, FFileSize) = FFileSize); FileClose(FFileHandle); FFileHandle := 0; end; {$IFDEF MSWINDOWS} var wFileName: UnicodeString; begin Result := False; if Assigned(FMappedFile) then UnMapFile; // if needed wFileName := UTF16LongName(sFileName); FFileHandle := CreateFileW(PWChar(wFileName), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if FFileHandle = INVALID_HANDLE_VALUE then begin FFileHandle := 0; Exit; end; FFileSize := GetFileSize(FFileHandle, nil); if (FFileSize < MaxMemSize) then begin Result := ReadFile; Exit; end; FMappingHandle := CreateFileMapping(FFileHandle, nil, PAGE_READONLY, 0, 0, nil); if FMappingHandle <> 0 then FMappedFile := MapViewOfFile(FMappingHandle, FILE_MAP_READ, 0, 0, 0) else begin FMappedFile := nil; FileClose(FFileHandle); FFileHandle := 0; Exit; end; Result := True; end; {$ELSE} var StatBuf: Stat; {$IFDEF LINUX} Sbfs: TStatFS; {$ENDIF} begin Result := False; if Assigned(FMappedFile) then UnMapFile; // if needed FFileHandle := mbFileOpen(sFileName, fmOpenRead); if FFileHandle = feInvalidHandle then begin FFileHandle := 0; Exit; end; if fpFStat(FFileHandle, StatBuf) <> 0 then begin FileClose(FFileHandle); FFileHandle := 0; Exit; end; FFileSize := StatBuf.st_size; {$IFDEF LINUX} if (fpFStatFS(FFileHandle, @Sbfs) = 0) then begin // Special case for PROC_FS and SYS_FS if (sbfs.fstype = PROC_SUPER_MAGIC) or (sbfs.fstype = SYSFS_MAGIC) then begin FMappedFile := GetMem(MaxMemSize - 1); FFileSize := FileRead(FFileHandle, FMappedFile^, MaxMemSize - 1); Result := (FFileSize > 0); FileClose(FFileHandle); FFileHandle := 0; Exit; end; end; {$ENDIF} if (FFileSize < MaxMemSize) then begin Result := ReadFile; Exit; end; FMappedFile := fpmmap(nil, FFileSize, PROT_READ, MAP_PRIVATE{SHARED}, FFileHandle, 0); if FMappedFile = MAP_FAILED then begin FMappedFile:= nil; FileClose(FFileHandle); FFileHandle := 0; Exit; end; Result:= True; end; {$ENDIF} procedure TViewerControl.UnMapFile; begin if (FFileSize < MaxMemSize) then begin if Assigned(FMappedFile) then begin FreeMem(FMappedFile); FMappedFile := nil; end; end; {$IFDEF MSWINDOWS} if Assigned(FMappedFile) then begin UnmapViewOfFile(FMappedFile); FMappedFile := nil; end; if FMappingHandle <> 0 then begin CloseHandle(FMappingHandle); FMappingHandle := 0; end; if FFileHandle <> 0 then begin FileClose(FFileHandle); FFileHandle := 0; end; {$ELSE} if Assigned(FMappedFile) then begin if fpmunmap(FMappedFile, FFileSize) = -1 then DebugLn('Error unmapping file: ', SysErrorMessage(fpgeterrno)); FMappedFile := nil; end; if FFileHandle <> 0 then begin fpClose(FFileHandle); FFileHandle := 0; end; {$ENDIF} FFileName := ''; FFileSize := 0; Position := 0; FLowLimit := 0; FHighLimit := 0; FBOMLength := 0; FBlockBeg := 0; FBlockEnd := 0; end; procedure TViewerControl.WriteText; var yIndex, xIndex, w, scrollTab, i: Integer; LineStart, iPos: PtrInt; DataLength: PtrInt; begin iPos := FPosition; if Mode = vcmBook then w := Width div FColCount else w := 0; if (Mode = vcmText) and (FHPosition>0) then scrollTab := -FHPosition * Canvas.TextWidth('W') else scrollTab :=0; for xIndex := 0 to FColCount-1 do begin for yIndex := 0 to GetClientHeightInLines - 1 do begin if iPos >= FHighLimit then Break; AddLineOffset(iPos); LineStart := iPos; i := CalcTextLineLength(iPos, FHighLimit, DataLength); if i > FHLowEnd then FHLowEnd:=i; if DataLength > 0 then OutText(scrollTab+xIndex*w, yIndex * FTextHeight, LineStart, DataLength) end; end; end; procedure TViewerControl.WriteCustom; // this method render visible page of text var yIndex: Integer; iPos, LineStart: PtrInt; s: string; begin iPos := FPosition; for yIndex := 0 to GetClientHeightInLines - 1 do begin if iPos >= FHighLimit then Break; LineStart := iPos; AddLineOffset(iPos); s := TransformCustom(iPos, FHighLimit); // get line text for render if s <> '' then OutCustom(0, yIndex * FTextHeight, s, LineStart, iPos - LineStart); // render line to canvas end; end; procedure TViewerControl.WriteBin; var yIndex: Integer; iPos, LineStart: PtrInt; s: string; begin iPos := FPosition; for yIndex := 0 to GetClientHeightInLines - 1 do begin if iPos >= FHighLimit then Break; LineStart := iPos; AddLineOffset(iPos); s := TransformBin(iPos, FHighLimit); if s <> '' then OutBin(0, yIndex * FTextHeight, s, LineStart, iPos - LineStart); end; end; function TViewerControl.GetDataAdr: Pointer; begin case FViewerControlMode of vcmText, vcmWrap, vcmBook: Result := FMappedFile + FBOMLength; else Result := FMappedFile; end; end; procedure TViewerControl.SetPosition(Value: PtrInt); begin SetPosition(Value, False); end; procedure TViewerControl.SetHPosition(Value: Integer); begin SetHPosition(Value, False); end; procedure TViewerControl.SetHPosition(Value: Integer; Force: Boolean); begin if not IsFileOpen then Exit; FHPosition := Value; // Set new scroll position. if (FHLowEnd - FTextWidth) > 0 then begin if FHPosition > 0 then FHScrollBarPosition := FHPosition * 100 div (FHLowEnd - FTextWidth) else FHScrollBarPosition := 0; end; // Update scrollbar position. if FUpdateScrollBarPos then begin if FScrollBarHorz.Position <> FHScrollBarPosition then begin // Workaround for bug: http://bugs.freepascal.org/view.php?id=23815 {$IF DEFINED(LCLQT) and (LCL_FULLVERSION < 1010000)} FScrollBarHorz.OnScroll := nil; FScrollBarHorz.Position := FHScrollBarPosition; Application.ProcessMessages; // Skip message FScrollBarHorz.OnScroll := @ScrollBarHorzScroll; {$ELSE} FScrollBarHorz.Position := FHScrollBarPosition; {$ENDIF} end; end; // else the scrollbar position will be updated in ScrollBarVertScroll Invalidate; end; procedure TViewerControl.SetPosition(Value: PtrInt; Force: Boolean); var LinesTooMany: Integer; LastLineReached: Boolean; begin if not IsFileOpen then Exit; // Speedup if total nr of lines is less then nr of lines that can be displayed. if (FPosition = FLowLimit) and // only if already at the top (FLineList.Count > 0) and (FLineList.Count < GetClientHeightInLines) then Value := FLowLimit else // Boundary checks are done in GetStartOfLine. Value := GetStartOfLine(Value); if (Value <> FPosition) or Force then begin // Don't allow empty lines at the bottom of the control. LinesTooMany := GetClientHeightInLines - GetLinesTillEnd(Value, LastLineReached); if LinesTooMany > 0 then ScrollPosition(Value, -LinesTooMany); // scroll back upwards FPosition := Value; if Assigned(FOnPositionChanged) then FOnPositionChanged(Self); Invalidate; // Set new scroll position. if LastLineReached and (Value > 0) then FScrollBarPosition := 100 else FScrollBarPosition := Percent; end; // Update scrollbar position. if FUpdateScrollBarPos then begin if FScrollBarVert.Position <> FScrollBarPosition then begin // Workaround for bug: http://bugs.freepascal.org/view.php?id=23815 {$IF DEFINED(LCLQT) and (LCL_FULLVERSION < 1010000)} FScrollBarVert.OnScroll := nil; FScrollBarVert.Position := FScrollBarPosition; Application.ProcessMessages; // Skip message FScrollBarVert.OnScroll := @ScrollBarVertScroll; {$ELSE} FScrollBarVert.Position := FScrollBarPosition; {$ENDIF} end; end; // else the scrollbar position will be updated in ScrollBarVertScroll end; procedure TViewerControl.SetEncoding(AEncoding: TViewerEncoding); begin if not (csDesigning in ComponentState) then begin if AEncoding = veAutoDetect then FEncoding := DetectEncoding else FEncoding := AEncoding; ReReadFile; end else FEncoding := AEncoding; end; function TViewerControl.GetEncodingName: string; begin Result := ViewerEncodingsNames[FEncoding]; end; procedure TViewerControl.SetEncodingName(AEncodingName: string); var i: TViewerEncoding; begin for i := Low(TViewerEncoding) to High(TViewerEncoding) do if NormalizeEncoding(ViewerEncodingsNames[i]) = NormalizeEncoding(AEncodingName) then begin SetEncoding(i); break; end; end; function TViewerControl.GetClientHeightInLines: Integer; begin if FViewerControlMode <> vcmText then Result:= 0 else // Take horizontal scrollbar into account Result:= GetSystemMetrics(SM_CYHSCROLL); if FTextHeight > 0 then Result := (ClientRect.Bottom - ClientRect.Top - Result) div FTextHeight // or Self.Height div FTextHeight? else Result := 0; end; function TViewerControl.GetLinesTillEnd(FromPosition: PtrInt; out LastLineReached: Boolean): Integer; var yIndex: Integer; iPos: PtrInt; DataLength: PtrInt; begin Result := 0; iPos := FromPosition; for yIndex := 0 to GetClientHeightInLines - 1 do begin if iPos >= FHighLimit then Break; Inc(Result, 1); case Mode of vcmBin: iPos := iPos + cBinWidth; vcmHex,vcmDec: iPos := iPos + FCustom.ValuesPerLine; vcmText, vcmWrap, vcmBook: CalcTextLineLength(iPos, FHighLimit, DataLength); end; end; LastLineReached := (iPos >= FHighLimit); end; function TViewerControl.GetPercent: Integer; begin if FHighLimit - FLowLimit > 0 then Result := (Int64(FPosition - FLowLimit) * 100) div Int64(FHighLimit - FLowLimit) else Result := 0; end; procedure TViewerControl.SetPercent(const AValue: Integer); begin if FHighLimit - FLowLimit > 0 then Position := Int64(AValue) * (Int64(FHighLimit - FLowLimit) div 100) + FLowLimit else Position := 0; end; procedure TViewerControl.SetBlockBegin(const AValue: PtrInt); begin if (AValue >= FLowLimit) and (AValue < FHighLimit) then begin if FBlockEnd < AValue then FBlockEnd := AValue; FBlockBeg := AValue; Invalidate; end; end; procedure TViewerControl.SetBlockEnd(const AValue: PtrInt); begin if (AValue >= FLowLimit) and (AValue < FHighLimit) then begin if FBlockBeg > AValue then FBlockBeg := AValue; FBlockEnd := AValue; Invalidate; end; end; procedure TViewerControl.OutText(x, y: Integer; StartPos: PtrInt; DataLength: Integer); var pBegLine, pEndLine: PtrInt; iBegDrawIndex, iEndDrawIndex: PtrInt; xOffset: Integer; sText: string; begin pBegLine := StartPos; pEndLine := pBegLine + DataLength; if ((FBlockEnd - FBlockBeg) = 0) or ((FBlockBeg < pBegLine) and (FBlockEnd < pBegLine)) or // before ((FBlockBeg > pEndLine) and (FBlockEnd > pEndLine)) then //after begin // out of selection, draw normal Canvas.Font.Color := Font.Color; Canvas.TextOut(x, y, GetText(StartPos, DataLength, 0)); Exit; end; // Get selection start/end. if (FBlockBeg <= pBegLine) then iBegDrawIndex := pBegLine else iBegDrawIndex := FBlockBeg; if (FBlockEnd < pEndLine) then iEndDrawIndex := FBlockEnd else iEndDrawIndex := pEndLine; xOffset := 0; // Text before selection. if iBegDrawIndex - pBegLine > 0 then begin sText := GetText(StartPos, iBegDrawIndex - pBegLine, xOffset); Canvas.Font.Color := Font.Color; Canvas.TextOut(x, y, sText); x := x + Canvas.TextWidth(sText); xOffset := xOffset + UTF8Length(sText); end; // Selected text. sText := GetText(StartPos + iBegDrawIndex - pBegLine, iEndDrawIndex - iBegDrawIndex, xOffset); Canvas.Brush.Color := clHighlight; Canvas.Font.Color := clHighlightText; // Cannot simply draw text with brush with TextOut // because it differs between widgetsets. Canvas.Brush.Style := bsSolid; Canvas.FillRect(Bounds(x, y, Canvas.TextWidth(sText), FTextHeight)); Canvas.Brush.Style := bsClear; // Or use TextRect instead of TextOut with Opaque = True. //ts := Canvas.TextStyle; //ts.Opaque := True; //ts.Clipping := True; //Canvas.TextRect(Bounds(X, Y, Canvas.TextWidth(sText), FTextHeight), X, Y, sText, ts); Canvas.TextOut(x, y, sText); x := x + Canvas.TextWidth(sText); xOffset := xOffset + UTF8Length(sText); // restore previous canvas settings Canvas.Brush.Color := Color; Canvas.Font.Color := Font.Color; // Text after selection. if pEndLine - iEndDrawIndex > 0 then begin sText := GetText(StartPos + iEndDrawIndex - pBegLine, pEndLine - iEndDrawIndex, xOffset); Canvas.TextOut(x, y, sText); end; end; procedure TViewerControl.OutCustom(x, y: Integer; sText: string; StartPos: PtrInt; DataLength: Integer); var pBegLine, pEndLine: PtrInt; iBegDrawIndex, iEndDrawIndex: PtrInt; sNextText: String = ''; sTmpText: String; begin pBegLine := StartPos; pEndLine := pBegLine + DataLength; if ((FBlockEnd - FBlockBeg) = 0) or ((FBlockBeg < pBegLine) and (FBlockEnd <= pBegLine)) or // before ((FBlockBeg > pEndLine) and (FBlockEnd > pEndLine)) then //after begin // out of selection, draw normal Canvas.Font.Color := Font.Color; Canvas.TextOut(x, y, sText); Exit; end; // Get selection start/end. if (FBlockBeg <= pBegLine) then iBegDrawIndex := pBegLine else iBegDrawIndex := FBlockBeg; if (FBlockEnd < pEndLine) then iEndDrawIndex := FBlockEnd else iEndDrawIndex := pEndLine; // Text before selection (offset and hex part). sTmpText := Copy(sText, 1, FCustom.StartOfs + (iBegDrawIndex - pBegLine) * (FCustom.MaxValueDigits+FCustom.SpaceCount)); Canvas.Font.Color := Font.Color; Canvas.TextOut(x, y, sTmpText); x := x + Canvas.TextWidth(sTmpText); // Selected text (hex part). sTmpText := Copy(sText, 1 + FCustom.StartOfs + (iBegDrawIndex - pBegLine) * (FCustom.MaxValueDigits+FCustom.SpaceCount), (iEndDrawIndex - iBegDrawIndex)* (FCustom.MaxValueDigits+FCustom.SpaceCount)); // Move last character from selection to not selected text. sNextText := Copy(sTmpText, Length(sTmpText), 1); Delete(sTmpText, Length(sTmpText), 1); Canvas.Brush.Color := clHighlight; Canvas.Font.Color := clHighlightText; Canvas.Brush.Style := bsSolid; Canvas.FillRect(Bounds(x, y, Canvas.TextWidth(sTmpText), FTextHeight)); Canvas.Brush.Style := bsClear; Canvas.TextOut(x, y, sTmpText); x := x + Canvas.TextWidth(sTmpText); // restore previous canvas settings Canvas.Brush.Color := Color; Canvas.Font.Color := Font.Color; // Text after selection (hex part). if pEndLine - iEndDrawIndex > 0 then begin sTmpText := sNextText + Copy(sText, 1 + FCustom.StartOfs + (iEndDrawIndex - pBegLine) * (FCustom.MaxValueDigits+FCustom.SpaceCount), (pEndLine - iEndDrawIndex) * (FCustom.MaxValueDigits+FCustom.SpaceCount)); sNextText := ''; Canvas.TextOut(x, y, sTmpText); x := x + Canvas.TextWidth(sTmpText); end; // Space after hex if data doesn't span full line. if DataLength < FHex.ValuesPerLine then sNextText := sNextText + Copy(sText, 1 + FCustom.StartOfs + DataLength * (FCustom.MaxValueDigits+FCustom.SpaceCount), (FCustom.ValuesPerLine - DataLength) * (FCustom.MaxValueDigits+FCustom.SpaceCount)); // Space between hex and ascii. sTmpText := sNextText + ' '; Canvas.TextOut(x, y, sTmpText); x := x + Canvas.TextWidth(sTmpText); // Text before selection (ascii part). if iBegDrawIndex - pBegLine > 0 then begin sTmpText := Copy(sText, 1 + FCustom.StartAscii, iBegDrawIndex - pBegLine); Canvas.TextOut(x, y, sTmpText); x := x + Canvas.TextWidth(sTmpText); end; // Selected text (ascii part). sTmpText := Copy(sText, 1 + FCustom.StartAscii + iBegDrawIndex - pBegLine, iEndDrawIndex - iBegDrawIndex); Canvas.Brush.Color := clHighlight; Canvas.Font.Color := clHighlightText; Canvas.Brush.Style := bsSolid; Canvas.FillRect(Bounds(x, y, Canvas.TextWidth(sTmpText), FTextHeight)); Canvas.Brush.Style := bsClear; Canvas.TextOut(x, y, sTmpText); x := x + Canvas.TextWidth(sTmpText); // restore background color Canvas.Brush.Color := Color; Canvas.Font.Color := Font.Color; // Text after selection. if pEndLine - iEndDrawIndex > 0 then begin sTmpText := Copy(sText, 1 + FCustom.StartAscii + iEndDrawIndex - pBegLine, pEndLine - iEndDrawIndex); Canvas.TextOut(x, y, sTmpText); end; end; procedure TViewerControl.OutBin(x, y: Integer; sText: string; StartPos: PtrInt; DataLength: Integer); var pBegLine, pEndLine: PtrInt; iBegDrawIndex, iEndDrawIndex: PtrInt; sTmpText: String; begin pBegLine := StartPos; pEndLine := pBegLine + DataLength; if ((FBlockEnd - FBlockBeg) = 0) or ((FBlockBeg < pBegLine) and (FBlockEnd < pBegLine)) or // before ((FBlockBeg > pEndLine) and (FBlockEnd > pEndLine)) then //after begin // out of selection, draw normal Canvas.Font.Color := Font.Color; Canvas.TextOut(x, y, sText); Exit; end; // Get selection start/end. if (FBlockBeg <= pBegLine) then iBegDrawIndex := pBegLine else iBegDrawIndex := FBlockBeg; if (FBlockEnd < pEndLine) then iEndDrawIndex := FBlockEnd else iEndDrawIndex := pEndLine; // Text before selection. if iBegDrawIndex - pBegLine > 0 then begin sTmpText := Copy(sText, 1, iBegDrawIndex - pBegLine); Canvas.Font.Color := Font.Color; Canvas.TextOut(x, y, sTmpText); x := x + Canvas.TextWidth(sTmpText); end; // Selected text. sTmpText := Copy(sText, 1 + iBegDrawIndex - pBegLine, iEndDrawIndex - iBegDrawIndex); Canvas.Brush.Color := clHighlight; Canvas.Font.Color := clHighlightText; Canvas.Brush.Style := bsSolid; Canvas.FillRect(Bounds(x, y, Canvas.TextWidth(sTmpText), FTextHeight)); Canvas.Brush.Style := bsClear; Canvas.TextOut(x, y, sTmpText); x := x + Canvas.TextWidth(sTmpText); // restore previous canvas settings Canvas.Brush.Color := Color; Canvas.Font.Color := Font.Color; // Text after selection. if pEndLine - iEndDrawIndex > 0 then begin sTmpText := Copy(sText, 1 + iEndDrawIndex - pBegLine, pEndLine - iEndDrawIndex); Canvas.TextOut(x, y, sTmpText); end; end; procedure TViewerControl.AddLineOffset(const iOffset: PtrInt); begin FLineList.Add(iOffset); end; procedure TViewerControl.KeyDown(var Key: word; Shift: TShiftState); begin if Shift = [] then begin case Key of VK_DOWN: begin Key := 0; Scroll(1); end; VK_UP: begin Key := 0; Scroll(-1); end; VK_HOME: begin Key := 0; GoHome; end; VK_END: begin Key := 0; GoEnd; end; VK_PRIOR: begin Key := 0; PageUp; end; VK_NEXT: begin Key := 0; PageDown; end; else inherited KeyDown(Key, Shift); end; end else if Shift = [ssCtrl] then begin case Key of VK_HOME: begin Key := 0; GoHome; end; VK_END: begin Key := 0; GoEnd; end; else inherited KeyDown(Key, Shift); end; end else inherited KeyDown(Key, Shift); end; function TViewerControl.FindAsciiSetForward(aPosition, aMaxBytes: PtrInt; const AsciiChars: String; bFindNotIn: Boolean): PtrInt; var i: Integer; found: Boolean; u: Cardinal; CharLenInBytes: Integer; begin Result := -1; while aMaxBytes > 0 do begin u := GetNextCharAsAscii(aPosition, CharLenInBytes); if CharLenInBytes = 0 then Exit; if not bFindNotIn then begin for i := 1 to Length(AsciiChars) do if u = ord(AsciiChars[i]) then Exit(aPosition); end else begin found := False; for i := 1 to Length(AsciiChars) do if u = ord(AsciiChars[i]) then begin found := True; break; end; if not found then Exit(aPosition); end; Inc(aPosition, CharLenInBytes); Dec(aMaxBytes, CharLenInBytes); end; end; function TViewerControl.FindAsciiSetBackward(aPosition, aMaxBytes: PtrInt; const AsciiChars: String; bFindNotIn: Boolean): PtrInt; var i: Integer; found: Boolean; u: Cardinal; CharLenInBytes: Integer; begin Result := -1; while aMaxBytes > 0 do begin u := GetPrevCharAsAscii(aPosition, CharLenInBytes); if CharLenInBytes = 0 then Exit; if not bFindNotIn then begin for i := 1 to Length(AsciiChars) do if u = ord(AsciiChars[i]) then Exit(aPosition); end else begin found := False; for i := 1 to Length(AsciiChars) do if u = ord(AsciiChars[i]) then begin found := True; break; end; if not found then Exit(aPosition); end; Dec(aPosition, CharLenInBytes); Dec(aMaxBytes, CharLenInBytes); end; end; procedure TViewerControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var LineBegin, LineEnd: PtrInt; ClickPos: PtrInt; CharSide: TCharSide; begin inherited; SetFocus; if not IsFileOpen then Exit; case Button of mbLeft: begin if Shift * [ssDouble, ssTriple] = [] then begin // Single click. ClickPos := XYPos2Adr(x, y, CharSide); if ClickPos <> -1 then begin FBlockBeg := ClickPos; FBlockEnd := ClickPos; FMouseBlockBeg := ClickPos; FMouseBlockSide := CharSide; FSelecting := True; Invalidate; end else FSelecting := False; end else // if double click or triple click begin FSelecting := False; LineBegin := GetStartOfLine(FMouseBlockBeg); LineEnd := GetEndOfLine(FMouseBlockBeg); if ssDouble in Shift then begin // Select word with double-click. FBlockBeg := FindAsciiSetBackward(FMouseBlockBeg, FMouseBlockBeg - LineBegin, sNonCharacter, False); FBlockEnd := FindAsciiSetForward(FMouseBlockBeg, LineEnd - FMouseBlockBeg, sNonCharacter, False); end else if ssTriple in Shift then begin // Select line with triple-click. FBlockBeg := FindAsciiSetForward(LineBegin, LineEnd - LineBegin, sWhiteSpace, True); FBlockEnd := FindAsciiSetBackward(LineEnd, LineEnd - LineBegin, sWhiteSpace, True); end; if FBlockBeg = -1 then FBlockBeg := LineBegin; if FBlockEnd = -1 then FBlockEnd := LineEnd; if FBlockBeg > FBlockEnd then FBlockEnd := FBlockBeg; CopyToClipboard; Invalidate; end; end; // mbLeft end; // case end; procedure TViewerControl.MouseMove(Shift: TShiftState; X, Y: Integer); procedure MoveOneChar(var aPosition: PtrInt); var CharLenInBytes: Integer; begin GetNextCharAsAscii(aPosition, CharLenInBytes); aPosition := aPosition + CharLenInBytes; end; procedure MoveOneCharByMouseSide(var aPosition: PtrInt); begin if FMouseBlockSide in [csRight, csAfter] then MoveOneChar(aPosition); end; var ClickPos: PtrInt; CharSide: TCharSide; begin inherited; if FSelecting then begin if y < FTextHeight then Scroll(-3) else if y > ClientHeight - FTextHeight then Scroll(3); ClickPos := XYPos2Adr(x, y, CharSide); if ClickPos <> -1 then begin if ClickPos < FMouseBlockBeg then begin // Got a new beginning. FBlockBeg := ClickPos; FBlockEnd := FMouseBlockBeg; // Move end beyond last character. MoveOneCharByMouseSide(FBlockEnd); // When selecting from right to left, the current selected side must be // either csLeft or csBefore, otherwise current position is not included. if not (CharSide in [csLeft, csBefore]) then begin // Current position should not be included in selection. // Move beginning after first character. MoveOneChar(FBlockBeg); end; end else if ClickPos > FMouseBlockBeg then begin // Got a new end. FBlockBeg := FMouseBlockBeg; FBlockEnd := ClickPos; // Move beginning after first character. MoveOneCharByMouseSide(FBlockBeg); // When selecting from left to right, the current selected side must be // either csRight or csAfter, otherwise current position is not included. if CharSide in [csRight, csAfter] then begin // Current position should be included in selection. // Move end beyond last character. MoveOneChar(FBlockEnd); end; end else if FMouseBlockSide <> CharSide then begin // Same position but changed side of the character. FBlockBeg := FMouseBlockBeg; FBlockEnd := FMouseBlockBeg; if ((FMouseBlockSide in [csBefore, csLeft]) and (CharSide in [csRight, csAfter])) or ((FMouseBlockSide in [csRight, csAfter]) and (CharSide in [csBefore, csLeft])) then begin // Move end beyond last character. MoveOneChar(FBlockEnd); end; end else begin FBlockBeg := FMouseBlockBeg; FBlockEnd := FMouseBlockBeg; end; Invalidate; end; end; end; procedure TViewerControl.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin inherited; if FSelecting and (Button = mbLeft) and (Shift * [ssDouble, ssTriple] = []) then begin CopyToClipboard; FSelecting := False; end; end; function TViewerControl.DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; begin Result := inherited; if not Result then Result := Scroll(Mouse.WheelScrollLines); end; function TViewerControl.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; begin Result := inherited; if not Result then Result := Scroll(-Mouse.WheelScrollLines); end; function TViewerControl.XYPos2Adr(x, y: Integer; out CharSide: TCharSide): PtrInt; var yIndex: Integer; StartLine, EndLine: PtrInt; function XYPos2AdrBin: PtrInt; var i: Integer; px: Integer = 0; charWidth: Integer; sText: String; tmpPosition: PtrInt; begin tmpPosition := StartLine; sText := TransformBin(tmpPosition, EndLine); for i := 1 to Length(sText) do begin charWidth := Canvas.TextWidth(string(sText[i])); if px + charWidth > x then begin if px + charWidth div 2 > x then CharSide := csLeft else CharSide := csRight; Exit(StartLine + i - 1); // -1 because we count from 1 end; px := px + charWidth; end; CharSide := csBefore; Result := EndLine; end; function XYPos2AdrCustom: PtrInt; // | offset part | custom part | native part | // | 0000AAAA: | FF AA CC AE | djfjks | var i: Integer; px: Integer = 0; charWidth: Integer; sText, sPartialText: String; tmpPosition: PtrInt; begin tmpPosition := StartLine; sText := TransformCustom(tmpPosition, EndLine); if sText='' then exit; // Clicked on offset part sPartialText := Copy(sText, 1, FCustom.StartOfs); charWidth := Canvas.TextWidth(sPartialText); px := px + charWidth; if px > x then begin CharSide := csBefore; Exit(StartLine); end; // Clicked on custom part for i := 0 to FCustom.ValuesPerLine - 1 do begin sPartialText := Copy(sText, 1 + FCustom.StartOfs + i * (FCustom.MaxValueDigits+FCustom.SpaceCount), FCustom.MaxValueDigits); charWidth := Canvas.TextWidth(sPartialText); if px + charWidth > x then begin // Check if we're not after end of data. if StartLine + i >= EndLine then begin CharSide := csBefore; Exit(EndLine); end; if px + charWidth div 2 > x then CharSide := csLeft else CharSide := csRight; Exit(StartLine + i); end; // Space after hex number. charWidth := charWidth + Canvas.TextWidth(string(sText[1 + FCustom.StartOfs + i * (FCustom.MaxValueDigits+1) + FCustom.MaxValueDigits])); if px + charWidth > x then begin CharSide := csAfter; Exit(StartLine + i); end; px := px + charWidth; end; // Clicked between hex and ascii. sPartialText := Copy(sText, 1 + FCustom.StartOfs, FCustom.StartAscii - FCustom.EndOfs); charWidth := Canvas.TextWidth(sPartialText); if px + charWidth > x then begin Exit(-1); // No position. end; px := px + charWidth; // Clicked on ascii part. for i := 0 to FCustom.ValuesPerLine - 1 do begin charWidth := Canvas.TextWidth(string(sText[1 + FCustom.StartAscii + i])); if px + charWidth > x then begin // Check if we're not after end of data. if StartLine + i >= EndLine then begin CharSide := csBefore; Exit(EndLine); end; if px + charWidth div 2 > x then CharSide := csLeft else CharSide := csRight; Exit(StartLine + i); end; px := px + charWidth; end; CharSide := csBefore; Result := EndLine; end; function XYPos2AdrText: PtrInt; var i: Integer; px: Integer = 0; charWidth: Integer; len: Integer = 0; CharLenInBytes: Integer; s: String; begin i := StartLine; while i < EndLine do begin s := GetNextCharAsUtf8(i, CharLenInBytes); if CharLenInBytes = 0 then Break; // Check if the conversion to UTF-8 was successful. if Length(s) > 0 then begin if s = #9 then begin s := StringOfChar(' ', cTabSpaces - len mod cTabSpaces); len := len + (cTabSpaces - len mod cTabSpaces); end else Inc(len); // Assume there is one character after conversion // (otherwise use Inc(len, UTF8Length(s))). if len <= FHPosition then begin i := i + CharLenInBytes; Continue; end; charWidth := Canvas.TextWidth(s); if px + charWidth > x then begin if px + charWidth div 2 > x then CharSide := csLeft else CharSide := csRight; Exit(i); end; px := px + charWidth; end; i := i + CharLenInBytes; end; CharSide := csBefore; Result := EndLine; end; begin if FLineList.Count = 0 then Exit(-1); yIndex := y div FTextHeight; if yIndex >= FLineList.Count then yIndex := FLineList.Count - 1; if yIndex < 0 then yIndex := 0; // Get position of first character of the line. StartLine := FLineList.Items[yIndex]; // Get position of last character of the line. EndLine := GetEndOfLine(StartLine); if x = 0 then begin CharSide := csBefore; Exit(StartLine); end; case Mode of vcmBin: Result := XYPos2AdrBin; vcmHex,vcmDec: Result := XYPos2AdrCustom; // XYPos2AdrHex; vcmText, vcmWrap, vcmBook: Result := XYPos2AdrText; else raise Exception.Create('Invalid viewer mode'); end; end; procedure TViewerControl.SelectAll; begin SelectText(FLowLimit, FHighLimit); end; procedure TViewerControl.SelectText(AStart, AEnd: PtrInt); begin if AStart < FLowLimit then AStart := FLowLimit; if AEnd > FHighLimit then AEnd := FHighLimit; if AStart <= AEnd then begin FBlockBeg := AStart; FBlockEnd := AEnd; Invalidate; end; end; procedure TViewerControl.CopyToClipboard; var sText, utf8Text: string; begin if (FBlockEnd - FBlockBeg) <= 0 then Exit; if (FBlockEnd - FBlockBeg) > 1024 * 1024 then // Max 1 MB to clipboard Exit; SetString(sText, GetDataAdr + FBlockBeg, FBlockEnd - FBlockBeg); utf8Text := ConvertToUTF8(sText); {$IFDEF LCLGTK2} // Workaround for Lazarus bug #0021453. LCL adds trailing zero to clipboard in Clipboard.AsText. Clipboard.Clear; Clipboard.AddFormat(PredefinedClipboardFormat(pcfText), utf8Text[1], Length(utf8Text)); {$ELSE} Clipboard.AsText := utf8Text; {$ENDIF} end; procedure TViewerControl.CopyToClipboardF; var s,sText, utf8Text: string; len: Integer; begin len:=FBlockEnd-FBlockBeg; if len=0 then exit; sText:=TransformCustomBlock(FBlockBeg,len,False,False,s); utf8Text := ConvertToUTF8(sText); {$IFDEF LCLGTK2} // Workaround for Lazarus bug #0021453. LCL adds trailing zero to clipboard in Clipboard.AsText. Clipboard.Clear; Clipboard.AddFormat(PredefinedClipboardFormat(pcfText), utf8Text[1], Length(utf8Text)); {$ELSE} Clipboard.AsText := utf8Text; {$ENDIF} end; function TViewerControl.Selection: String; const MAX_LEN = 512; var sText: String; AIndex: PtrInt; ALength: PtrInt; CharLenInBytes: Integer; begin if (FBlockEnd - FBlockBeg) <= 0 then Exit(EmptyStr); ALength:= FBlockEnd - FBlockBeg; if ALength <= MAX_LEN then begin SetString(sText, GetDataAdr + FBlockBeg, ALength); Result := ConvertToUTF8(sText); end else begin Result:= EmptyStr; AIndex:= FBlockBeg; ALength:= AIndex + MAX_LEN; while AIndex < ALength do begin sText := GetNextCharAsUtf8(AIndex, CharLenInBytes); if CharLenInBytes = 0 then Break; Result:= Result + sText; AIndex:= AIndex + CharLenInBytes; end; end; end; function TViewerControl.GetNextCharAsAscii(const iPosition: PtrInt; out CharLenInBytes: Integer): Cardinal; var u1, u2: Word; InvalidCharLen: Integer; begin Result := 0; case FEncoding of veUtf8, veUtf8bom: begin if iPosition < FHighLimit then begin CharLenInBytes := SafeUTF8NextCharLen(GetDataAdr + iPosition, FHighLimit - iPosition, InvalidCharLen); // It's enough to only return Ascii. if CharLenInBytes = 1 then Result := PByte(GetDataAdr)[iPosition]; // Full conversion: // Result := UTF8CharacterToUnicode(PAnsiChar(GetDataAdr + iPosition), CharLenInBytes); end else CharLenInBytes := 0; end; veAnsi, veOem, veCp1250..veCp950, veIso88591, veIso88592, veKoi8: if iPosition < FHighLimit then begin Result := PByte(GetDataAdr)[iPosition]; CharLenInBytes := 1; end else CharLenInBytes := 0; veUcs2be: if iPosition + SizeOf(Word) - 1 < FHighLimit then begin Result := BEtoN(PWord(GetDataAdr + iPosition)[0]); CharLenInBytes := SizeOf(Word); end else CharLenInBytes := 0; veUcs2le: if iPosition + SizeOf(Word) - 1 < FHighLimit then begin Result := LEtoN(PWord(GetDataAdr + iPosition)[0]); CharLenInBytes := SizeOf(Word); end else CharLenInBytes := 0; veUtf16be: if iPosition + SizeOf(Word) - 1 < FHighLimit then begin u1 := BEtoN(PWord(GetDataAdr + iPosition)[0]); CharLenInBytes := UTF16CharacterLength(@u1); if CharLenInBytes = 1 then begin Result := u1; end else if iPosition + SizeOf(Word) * CharLenInBytes - 1 < FHighLimit then begin u2 := BEtoN(PWord(GetDataAdr + iPosition)[1]); Result := utf16PairToUnicode(u1, u2); end; CharLenInBytes := CharLenInBytes * SizeOf(Word); end else CharLenInBytes := 0; veUtf16le: if iPosition + SizeOf(Word) - 1 < FHighLimit then begin u1 := LEtoN(PWord(GetDataAdr + iPosition)[0]); CharLenInBytes := UTF16CharacterLength(@u1); if CharLenInBytes = 1 then begin Result := u1; end else if iPosition + SizeOf(Word) * CharLenInBytes - 1 < FHighLimit then begin u2 := LEtoN(PWord(GetDataAdr + iPosition)[1]); Result := utf16PairToUnicode(u1, u2); end else CharLenInBytes := 0; CharLenInBytes := CharLenInBytes * SizeOf(Word); end else CharLenInBytes := 0; veUtf32be: if iPosition + SizeOf(LongWord) - 1 < FHighLimit then begin Result := BEtoN(PLongWord(GetDataAdr + iPosition)[0]); CharLenInBytes := SizeOf(LongWord); end else CharLenInBytes := 0; veUtf32le: if iPosition + SizeOf(LongWord) - 1 < FHighLimit then begin Result := LEtoN(PLongWord(GetDataAdr + iPosition)[0]); CharLenInBytes := SizeOf(LongWord); end else CharLenInBytes := 0; else raise Exception.Create('Unsupported viewer encoding'); end; end; function TViewerControl.GetPrevCharAsAscii(const iPosition: PtrInt; out CharLenInBytes: Integer): Cardinal; var u1, u2: Word; InvalidCharLen: Integer; begin Result := 0; case FEncoding of veUtf8, veUtf8bom: begin if iPosition > FLowLimit then begin CharLenInBytes := SafeUTF8PrevCharLen(GetDataAdr + iPosition, iPosition - FLowLimit, InvalidCharLen); // It's enough to only return Ascii. if CharLenInBytes = 1 then Result := PByte(GetDataAdr)[iPosition - 1]; // Full conversion: // Result := UTF8CharacterToUnicode(PAnsiChar(GetDataAdr + iPosition - CharLenInBytes), CharLenInBytes); end else CharLenInBytes := 0; end; veAnsi, veOem, veCp1250..veCp950, veIso88591, veIso88592, veKoi8: if iPosition > FLowLimit then begin Result := PByte(GetDataAdr + iPosition)[-1]; CharLenInBytes := 1; end else CharLenInBytes := 0; veUcs2be: if iPosition >= FLowLimit + SizeOf(Word) then begin Result := BEtoN(PWord(GetDataAdr + iPosition)[-1]); CharLenInBytes := SizeOf(Word); end else CharLenInBytes := 0; veUcs2le: if iPosition >= FLowLimit + SizeOf(Word) then begin Result := LEtoN(PWord(GetDataAdr + iPosition)[-1]); CharLenInBytes := SizeOf(Word); end else CharLenInBytes := 0; veUtf16be: if iPosition >= FLowLimit + SizeOf(Word) then begin u1 := BEtoN(PWord(GetDataAdr + iPosition)[-1]); CharLenInBytes := UTF16CharacterLength(@u1); if CharLenInBytes = 1 then begin Result := u1; end else if iPosition >= FLowLimit + SizeOf(Word) * CharLenInBytes then begin u2 := BEtoN(PWord(GetDataAdr + iPosition)[-2]); // u2 is the first, u1 is the second value of the pair Result := utf16PairToUnicode(u2, u1); end; CharLenInBytes := CharLenInBytes * SizeOf(Word); end else CharLenInBytes := 0; veUtf16le: if iPosition >= FLowLimit + SizeOf(Word) then begin u1 := LEtoN(PWord(GetDataAdr + iPosition)[-1]); CharLenInBytes := UTF16CharacterLength(@u1); if CharLenInBytes = 1 then begin Result := u1; end else if iPosition >= FLowLimit + SizeOf(Word) * CharLenInBytes then begin u2 := LEtoN(PWord(GetDataAdr + iPosition)[-2]); // u2 is the first, u1 is the second value of the pair Result := utf16PairToUnicode(u2, u1); end; CharLenInBytes := CharLenInBytes * SizeOf(Word); end else CharLenInBytes := 0; veUtf32be: if iPosition >= FLowLimit + SizeOf(LongWord) then begin Result := BEtoN(PLongWord(GetDataAdr + iPosition)[-1]); CharLenInBytes := SizeOf(LongWord); end else CharLenInBytes := 0; veUtf32le: if iPosition >= FLowLimit + SizeOf(LongWord) then begin Result := LEtoN(PLongWord(GetDataAdr + iPosition)[-1]); CharLenInBytes := SizeOf(LongWord); end else CharLenInBytes := 0; else raise Exception.Create('Unsupported viewer encoding'); end; end; function TViewerControl.GetNextCharAsUtf8(const iPosition: PtrInt; out CharLenInBytes: Integer): String; var u1: Word; s: string; InvalidCharLen: Integer; begin Result := ''; case FEncoding of veUtf8, veUtf8bom: CharLenInBytes := SafeUTF8NextCharLen(GetDataAdr + iPosition, FHighLimit - iPosition, InvalidCharLen); veAnsi, veOem, veCp1250..veCp950, veIso88591, veIso88592, veKoi8: CharLenInBytes := 1; veUcs2be, veUcs2le: CharLenInBytes := 2; veUtf16be: if iPosition + SizeOf(Word) - 1 < FHighLimit then begin u1 := BEtoN(PWord(GetDataAdr + iPosition)[0]); CharLenInBytes := UTF16CharacterLength(@u1) * SizeOf(Word); end else CharLenInBytes := 0; veUtf16le: if iPosition + SizeOf(Word) - 1 < FHighLimit then begin u1 := LEtoN(PWord(GetDataAdr + iPosition)[0]); CharLenInBytes := UTF16CharacterLength(@u1) * SizeOf(Word); end else CharLenInBytes := 0; veUtf32be, veUtf32le: CharLenInBytes := 4; else raise Exception.Create('Unsupported viewer encoding'); end; if (CharLenInBytes > 0) and (iPosition + CharLenInBytes - 1 < FHighLimit) then begin SetString(s, GetDataAdr + iPosition, CharLenInBytes); Result := ConvertToUTF8(s); end else Result := ''; end; function TViewerControl.ConvertToUTF8(const sText: AnsiString): String; begin if FEncoding = veAutoDetect then FEncoding := DetectEncoding; // Force detect encoding. case FEncoding of veAutoDetect: ; veAnsi: Result := CeAnsiToUtf8(sText); veOem: Result := CeOemToUtf8(sText); veUtf8, veUtf8bom: Result := Utf8ReplaceBroken(sText); veUtf16be: Result := Utf16BEToUtf8(sText); veUtf16le: Result := Utf16LEToUtf8(sText); veUtf32be: Result := Utf32BEToUtf8(sText); veUtf32le: Result := Utf32LEToUtf8(sText); else Result := LConvEncoding.ConvertEncoding(sText, ViewerEncodingsNames[FEncoding], EncodingUTF8); end; end; function TViewerControl.ConvertFromUTF8(const sText: String): AnsiString; begin if FEncoding = veAutoDetect then FEncoding := DetectEncoding; // Force detect encoding. case FEncoding of veAutoDetect: ; veAnsi: Result := CeUtf8ToAnsi(sText); veOem: Result := CeUtf8ToOem(sText); veUtf8, veUtf8bom: Result := sText; veUtf16be: Result := Utf8ToUtf16BE(sText); veUtf16le: Result := Utf8ToUtf16LE(sText); veUtf32be: Result := '';//Utf8ToUtf32BE(sText); veUtf32le: Result := '';//Utf8ToUtf32LE(sText); else Result := LConvEncoding.ConvertEncoding(sText, EncodingUTF8, ViewerEncodingsNames[FEncoding]); end; end; function TViewerControl.IsVisible(const aPosition: PtrInt): Boolean; var StartPos: PtrInt; CharLenInBytes: Integer; begin if IsFileOpen and (FLineList.Count > 0) then begin FVisibleOffset:= 0; StartPos:= GetStartOfLine(aPosition); // Calculate horizontal offset in symbols while (StartPos < aPosition) do begin GetNextCharAsAscii(StartPos, CharLenInBytes); Inc(StartPos, CharLenInBytes); Inc(FVisibleOffset); end; Result := (aPosition >= FLineList.Items[0]) and (aPosition <= FLineList.Items[FLineList.Count - 1]) and (FVisibleOffset >= FHPosition) and (FVisibleOffset <= FHPosition + FTextWidth); end else Result := False; end; procedure TViewerControl.MakeVisible(const aPosition: PtrInt); var Offset: Integer; LastLine: Boolean; begin if not IsVisible(aPosition) then begin SetPosition(aPosition); Offset:= GetLinesTillEnd(aPosition, LastLine); if (Offset > 4) and (LastLine = False) then Scroll(-4); Update; if (FVisibleOffset < FHPosition) or (FVisibleOffset > FHPosition + FTextWidth) then begin SetHPosition(FVisibleOffset); HScroll(-1); end; end; end; procedure TViewerControl.ScrollBarVertScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); begin FUpdateScrollBarPos := False; case ScrollCode of scLineUp: Scroll(-1); scLineDown: Scroll(1); scPageUp: PageUp; scPageDown: PageDown; scTop: GoHome; scBottom: GoEnd; scTrack, scPosition: begin // This check helps avoiding loops if changing ScrollPos below // triggers another scPosition message. if (ScrollCode = scTrack) or (ScrollPos <> FScrollBarPosition) then begin if ScrollPos = 0 then GoHome else if ScrollPos = 100 then GoEnd else Percent := ScrollPos; end; end; scEndScroll: begin end; end; ScrollPos := FScrollBarPosition; FUpdateScrollBarPos := True; end; procedure TViewerControl.ScrollBarHorzScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); begin FUpdateScrollBarPos := False; case ScrollCode of scLineUp: HScroll(-1); scLineDown: HScroll(1); scPageUp: HPageUp; scPageDown: HPageDown; scTop: HGoHome; scBottom: HGoEnd; scTrack, scPosition: begin // This check helps avoiding loops if changing ScrollPos below // triggers another scPosition message. if (ScrollCode = scTrack) or (ScrollPos <> FHScrollBarPosition) then begin if ScrollPos = 0 then HGoHome else if ScrollPos = 100 then HGoEnd else HScroll((FHLowEnd - FTextWidth) * ScrollPos div 100 - FHPosition); end; end; scEndScroll: begin end; end; ScrollPos := FHScrollBarPosition; FUpdateScrollBarPos := True; end; procedure TViewerControl.UpdateScrollbars; begin FScrollBarVert.LargeChange := GetClientHeightInLines - 1; case Mode of vcmBin, vcmHex: begin //FScrollBarVert.PageSize := // ((FHighLimit div cHexWidth - GetClientHeightInLines) div 100); end else FScrollBarVert.PageSize := 1; end; FScrollBarHorz.Visible:= (FViewerControlMode = vcmText); end; procedure TViewerControl.ViewerResize(Sender: TObject); begin UpdateScrollbars; // Force recalculating position. SetPosition(FPosition); SetHPosition(FHPosition); end; procedure TViewerControl.ReReadFile; begin FBlockBeg := 0; FBlockEnd := 0; FBOMLength := GetBomLength; UpdateLimits; UpdateScrollbars; Invalidate; end; function TViewerControl.IsFileOpen: Boolean; begin Result := Assigned(FMappedFile); end; function TViewerControl.DetectEncoding: TViewerEncoding; var DetectStringLength: Integer = 2048; // take first 2kB of the file to detect encoding DetectString: String; DetectedEncodingName: String; Enc: TViewerEncoding; begin if IsFileOpen then begin // Default to Ansi in case encoding cannot be detected or is unsupported. Result := veAnsi; if FFileSize < DetectStringLength then DetectStringLength := FFileSize; SetString(DetectString, PAnsiChar(FMappedFile), DetectStringLength); if Assigned(FOnGuessEncoding) then DetectedEncodingName := FOnGuessEncoding(DetectString) else DetectedEncodingName := LConvEncoding.GuessEncoding(DetectString); if DetectedEncodingName <> '' then begin DetectedEncodingName := NormalizeEncoding(DetectedEncodingName); // Map UCS-2 to UTF-16. if DetectedEncodingName = 'ucs2le' then DetectedEncodingName := 'utf16le' else if DetectedEncodingName = 'ucs2be' then DetectedEncodingName := 'utf16be'; for Enc := Low(TViewerEncoding) to High(TViewerEncoding) do begin if NormalizeEncoding(ViewerEncodingsNames[Enc]) = DetectedEncodingName then begin Result := Enc; break; end; end; end; end else Result := veAutoDetect; end; procedure TViewerControl.GetSupportedEncodings(List: TStrings); var Enc: TViewerEncoding; begin for Enc := Low(TViewerEncoding) to High(TViewerEncoding) do List.Add(ViewerEncodingsNames[Enc]); end; function TViewerControl.GetBomLength: Integer; begin Result := 0; case FEncoding of veUtf8, veUtf8bom: if (FFileSize >= 3) and (PByte(FMappedFile)[0] = $EF) and (PByte(FMappedFile)[1] = $BB) and (PByte(FMappedFile)[2] = $BF) then begin Result := 3; end; veUcs2be, veUtf16be: if (FFileSize >= 2) and (PByte(FMappedFile)[0] = $FE) and (PByte(FMappedFile)[1] = $FF) then begin Result := 2; end; veUcs2le, veUtf16le: if (FFileSize >= 2) and (PByte(FMappedFile)[0] = $FF) and (PByte(FMappedFile)[1] = $FE) then begin Result := 2; end; veUtf32be: if (FFileSize >= 4) and (PByte(FMappedFile)[0] = $00) and (PByte(FMappedFile)[1] = $00) and (PByte(FMappedFile)[2] = $FE) and (PByte(FMappedFile)[3] = $FF) then begin Result := 4; end; veUtf32le: if (FFileSize >= 4) and (PByte(FMappedFile)[0] = $00) and (PByte(FMappedFile)[1] = $00) and (PByte(FMappedFile)[2] = $FF) and (PByte(FMappedFile)[3] = $FE) then begin Result := 4; end; end; end; procedure TViewerControl.UpdateLimits; begin if FEncoding = veAutoDetect then FEncoding := DetectEncoding; FBOMLength := GetBomLength; case FViewerControlMode of vcmText, vcmWrap, vcmBook: begin FLowLimit := 0; FHighLimit := FFileSize - FBOMLength; end; else begin FLowLimit := 0; FHighLimit := FFileSize; end; end; end; procedure TViewerControl.UpdateSelection; procedure Check(var aPosition: PtrInt; Backwards: Boolean); var CharStart: Pointer; begin case FEncoding of veUtf8, veUtf8bom: begin if not Backwards then begin CharStart := SafeUTF8NextCharStart(GetDataAdr + aPosition, FHighLimit - aPosition); if Assigned(CharStart) then aPosition := CharStart - GetDataAdr else aPosition := 0; end else begin CharStart := SafeUTF8PrevCharEnd(GetDataAdr + aPosition, aPosition - FLowLimit); if Assigned(CharStart) then aPosition := CharStart - GetDataAdr else aPosition := 0; end; end; veAnsi, veOem, veCp1250..veCp950, veIso88591, veIso88592, veKoi8: ; // any position allowed veUcs2be, veUcs2le: aPosition := ((aPosition - FLowLimit) and not 1) + FLowLimit; veUtf16be, veUtf16le: // todo: check if not in the middle of utf-16 character aPosition := ((aPosition - FLowLimit) and not 1) + FLowLimit; veUtf32be, veUtf32le: aPosition := ((aPosition - FLowLimit) and not 3) + FLowLimit; else raise Exception.Create('Unsupported viewer encoding'); end; end; begin if (FBlockBeg < FLowLimit) or (FBlockBeg >= FHighLimit) or (FBlockEnd < FLowLimit) or (FBlockEnd >= FHighLimit) then begin FBlockBeg := FLowLimit; FBlockEnd := FLowLimit; end else begin case FViewerControlMode of vcmText, vcmWrap, vcmBook: begin Check(FBlockBeg, False); Check(FBlockEnd, True); if (FBlockBeg < FLowLimit) or (FBlockBeg >= FHighLimit) or (FBlockEnd < FLowLimit) or (FBlockEnd >= FHighLimit) or (FBlockEnd < FBlockBeg) then begin FBlockBeg := FLowLimit; FBlockEnd := FLowLimit; end; end; // In non-text modes any selection is valid. end; end; end; function TViewerControl.FindUtf8Text(iStartPos: PtrInt; const sSearchText: String; bCaseSensitive: Boolean; bSearchBackwards: Boolean): PtrInt; var SearchTextLength: Integer; sSearchChars: array of String; pCurrentAddr, pEndAddr: PtrInt; i, charLen: Integer; function sPos2(pAdr: PtrInt):Boolean; var curChr:String; i, charLen: Integer; begin Result := False; for i := 0 to SearchTextLength-1 do begin curChr:=GetNextCharAsUtf8(pAdr,charLen); case bCaseSensitive of False: if UTF8UpperCase(curChr) <> UTF8UpperCase(sSearchChars[i]) then Exit; True : if curChr <> sSearchChars[i] then Exit; end; if charLen>0 then pAdr:=pAdr+charLen else Inc(pAdr); end; Result:=True; end; begin Result := PtrInt(-1); SearchTextLength := UTF8Length(sSearchText); if (SearchTextLength <= 0) then Exit; setLength(sSearchChars,SearchTextLength); for i:=1 to SearchTextLength do sSearchChars[i-1]:=UTF8Copy(sSearchText,i,1); pCurrentAddr := iStartPos; pEndAddr := FHighLimit - Length(ConvertFromUTF8(sSearchText)); if bSearchBackwards and (pCurrentAddr > pEndAddr) then // Move to the first possible position for searching backwards. pCurrentAddr := pEndAddr; if (pEndAddr < 0) or (pCurrentAddr < 0) or (pCurrentAddr > pEndAddr) then Exit; while True do begin if (pCurrentAddr > pEndAddr) or (pCurrentAddr < 0) then Exit; if sPos2(pCurrentAddr) then begin Result := pCurrentAddr; Exit; end; case bSearchBackwards of False: begin GetNextCharAsUtf8(pCurrentAddr,charLen); if charLen>0 then pCurrentAddr:=pCurrentAddr+charLen else Inc(pCurrentAddr); end; True : Dec(pCurrentAddr); end; end; end; procedure TViewerControl.ResetEncoding; begin FEncoding:= veAutoDetect; end; procedure Register; begin RegisterComponents('SeksiCmd', [TViewerControl]); end; end. doublecmd-0.8.2/components/viewer/viewerpackage.lpk0000664000175000017500000000274612756114647021546 0ustar alexxalexx doublecmd-0.8.2/components/virtualtreeview/0000775000175000017500000000000013244011205020123 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/virtualtreeview_package_doublecmd.lpk0000664000175000017500000000517111751527542027612 0ustar alexxalexx doublecmd-0.8.2/components/virtualtreeview/include/0000775000175000017500000000000013244011205021546 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/arch/0000775000175000017500000000000013244011205022463 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/arch/i386/0000775000175000017500000000000013244011205023154 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/arch/pascal/0000775000175000017500000000000013244011205023726 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/arch/x86_64/0000775000175000017500000000000013244011205023421 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/intf/0000775000175000017500000000000013244011205022506 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/intf/dummyolemethods.inc0000664000175000017500000003473012014201074026426 0ustar alexxalexxfunction TBaseVirtualTree.GetTreeFromDataObject(const DataObject: IDataObject): TBaseVirtualTree; // Returns the owner/sender of the given data object by means of a special clipboard format // or nil if the sender is in another process or no virtual tree at all. var Medium: TStgMedium; Data: PVTReference; begin Result := nil; { if Assigned(DataObject) then begin StandardOLEFormat.cfFormat := CF_VTREFERENCE; if DataObject.GetData(StandardOLEFormat, Medium) = S_OK then begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin if Data.Process = GetCurrentProcessID then Result := Data.Tree; GlobalUnlock(Medium.hGlobal); end; ReleaseStgMedium(@Medium); end; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; // Returns a memory expression of all currently selected nodes in the Medium structure. // Note: The memory requirement of this method might be very high. This depends however on the requested storage format. // For HGlobal (a global memory block) we need to render first all nodes to local memory and copy this then to // the global memory in Medium. This is necessary because we have first to determine how much // memory is needed before we can allocate it. Hence for a short moment we need twice the space as used by the // nodes alone (plus the amount the nodes need in the tree anyway)! // With IStream this does not happen. We directly stream out the nodes and pass the constructed stream along. //--------------- local function -------------------------------------------- { procedure WriteNodes(Stream: TStream); var Selection: TNodeArray; I: Integer; begin if ForClipboard then Selection := GetSortedCutCopySet(True) else Selection := GetSortedSelection(True); for I := 0 to High(Selection) do WriteNode(Stream, Selection[I]); end; //--------------- end local function ---------------------------------------- var Data: PCardinal; ResPointer: Pointer; ResSize: Integer; OLEStream: IStream; VCLStream: TStream; } begin { FillChar(Medium, SizeOf(Medium), 0); // We can render the native clipboard format in two different storage media. if (FormatEtcIn.cfFormat = CF_VIRTUALTREE) and (FormatEtcIn.tymed and (TYMED_HGLOBAL or TYMED_ISTREAM) <> 0) then begin VCLStream := nil; try Medium.PunkForRelease := nil; // Return data in one of the supported storage formats, prefer IStream. if FormatEtcIn.tymed and TYMED_ISTREAM <> 0 then begin // Create an IStream on a memory handle (here it is 0 which indicates to implicitely allocated a handle). // Do not use TStreamAdapter as it is not compatible with OLE (when flushing the clipboard OLE wants the HGlobal // back which is not supported by TStreamAdapater). CreateStreamOnHGlobal(0, True, OLEStream); VCLStream := TOLEStream.Create(OLEStream); WriteNodes(VCLStream); // Rewind stream. VCLStream.Position := 0; Medium.tymed := TYMED_ISTREAM; IUnknown(Medium.Pstm) := OLEStream; Result := S_OK; end else begin VCLStream := TMemoryStream.Create; WriteNodes(VCLStream); ResPointer := TMemoryStream(VCLStream).Memory; ResSize := VCLStream.Position; // Allocate memory to hold the string. if ResSize > 0 then begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, ResSize + SizeOf(Cardinal)); Data := GlobalLock(Medium.hGlobal); // Store the size of the data too, for easy retrival. Data^ := ResSize; Inc(Data); Move(ResPointer^, Data^, ResSize); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Result := S_OK; end else Result := E_FAIL; end; finally // We can free the VCL stream here since it was either a pure memory stream or only a wrapper around // the OLEStream which exists independently. VCLStream.Free; end; end else // Ask application descendants to render self defined formats. Result := DoRenderOLEData(FormatEtcIn, Medium, ForClipboard); } end; //---------------------------------------------------------------------------------------------------------------------- type // needed to handle OLE global memory objects TOLEMemoryStream = class(TCustomMemoryStream) public function Write(const Buffer; Count: Integer): Longint; override; end; //---------------------------------------------------------------------------------------------------------------------- function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer; begin //raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError)); raise EStreamError.Create(SCantWriteResourceStreamError); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ProcessOLEData(Source: TBaseVirtualTree; DataObject: IDataObject; TargetNode: PVirtualNode; Mode: TVTNodeAttachMode; Optimized: Boolean): Boolean; // Recreates the (sub) tree structure serialized into memory and provided by DataObject. The new nodes are attached to // the passed node or FRoot if TargetNode is nil according to Mode. Optimized can be set to True if the entire operation // happens within the same process (i.e. sender and receiver of the OLE operation are located in the same process). // Optimize = True makes only sense if the operation to carry out is a move hence it is also the indication of the // operation to be done here. Source is the source of the OLE data and only of use (and usually assigned) when // an OLE operation takes place in the same application. // Returns True on success, i.e. the CF_VIRTUALTREE format is supported by the data object and the structure could be // recreated, otherwise False. var Medium: TStgMedium; Stream: TStream; Data: Pointer; Node: PVirtualNode; Nodes: TNodeArray; I: Integer; Res: HRESULT; ChangeReason: TChangeReason; begin { Nodes := nil; // Check the data format available by the data object. with StandardOLEFormat do begin // Read best format. cfFormat := CF_VIRTUALTREE; end; Result := DataObject.QueryGetData(StandardOLEFormat) = S_OK; if Result and not (toReadOnly in FOptions.FMiscOptions) then begin BeginUpdate; Result := False; try if TargetNode = nil then TargetNode := FRoot; if TargetNode = FRoot then begin case Mode of amInsertBefore: Mode := amAddChildFirst; amInsertAfter: Mode := amAddChildLast; end; end; // Optimized means source is known and in the same process so we can access its pointers, which avoids duplicating // the data while doing a serialization. Can only be used with cut'n paste and drag'n drop with move effect. if Optimized then begin if tsOLEDragging in Source.FStates then Nodes := Source.FDragSelection else Nodes := Source.GetSortedCutCopySet(True); if Mode in [amInsertBefore,amAddChildLast] then begin for I := 0 to High(Nodes) do if not HasAsParent(TargetNode, Nodes[I]) then Source.MoveTo(Nodes[I], TargetNode, Mode, False); end else begin for I := High(Nodes) downto 0 do if not HasAsParent(TargetNode, Nodes[I]) then Source.MoveTo(Nodes[I], TargetNode, Mode, False); end; Result := True; end else begin if Source = Self then ChangeReason := crNodeCopied else ChangeReason := crNodeAdded; Res := DataObject.GetData(StandardOLEFormat, Medium); if Res = S_OK then begin case Medium.tymed of TYMED_ISTREAM, // IStream interface TYMED_HGLOBAL: // global memory block begin Stream := nil; if Medium.tymed = TYMED_ISTREAM then Stream := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream) else begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin // Get the total size of data to retrieve. I := PCardinal(Data)^; Inc(PCardinal(Data)); Stream := TOLEMemoryStream.Create; TOLEMemoryStream(Stream).SetPointer(Data, I); end; end; if Assigned(Stream) then try while Stream.Position < Stream.Size do begin Node := MakeNewNode; InternalConnectNode(Node, TargetNode, Self, Mode); InternalAddFromStream(Stream, VTTreeStreamVersion, Node); // This seems a bit strange because of the callback for granting to add the node // which actually comes after the node has been added. The reason is that the node must // contain valid data otherwise I don't see how the application can make a funded decision. if not DoNodeCopying(Node, TargetNode) then DeleteNode(Node) else DoNodeCopied(Node); StructureChange(Node, ChangeReason); // In order to maintain the same node order when restoring nodes in the case of amInsertAfter // we have to move the reference node continously. Othwise we would end up with reversed node order. if Mode = amInsertAfter then TargetNode := Node; end; Result := True; finally Stream.Free; if Medium.tymed = TYMED_HGLOBAL then GlobalUnlock(Medium.hGlobal); end; end; end; ReleaseStgMedium(@Medium); end; end; finally EndUpdate; end; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.ContentToClipboard(Format: Word; Source: TVSTTextSourceType): HGLOBAL; // This method constructs a shareable memory object filled with string data in the required format. Supported are: // CF_TEXT - plain ANSI text (Unicode text is converted using the user's current locale) // CF_UNICODETEXT - plain Unicode text // CF_CSV - comma separated plain ANSI text // CF_VRTF + CF_RTFNOOBS - rich text (plain ANSI) // CF_HTML - HTML text encoded using UTF-8 // // Result is the handle to a globally allocated memory block which can directly be used for clipboard and drag'n drop // transfers. The caller is responsible for freeing the memory. If for some reason the content could not be rendered // the Result is 0. //--------------- local function -------------------------------------------- { procedure MakeFragment(var HTML: string); // Helper routine to build a properly-formatted HTML fragment. const Version = 'Version:1.0'#13#10; StartHTML = 'StartHTML:'; EndHTML = 'EndHTML:'; StartFragment = 'StartFragment:'; EndFragment = 'EndFragment:'; DocType = ''; HTMLIntro = '' + ''; HTMLExtro = ''; NumberLengthAndCR = 10; // Let the compiler determine the description length. DescriptionLength = Length(Version) + Length(StartHTML) + Length(EndHTML) + Length(StartFragment) + Length(EndFragment) + 4 * NumberLengthAndCR; var Description: string; StartHTMLIndex, EndHTMLIndex, StartFragmentIndex, EndFragmentIndex: Integer; begin // The HTML clipboard format is defined by using byte positions in the entire block where HTML text and // fragments start and end. These positions are written in a description. Unfortunately the positions depend on the // length of the description but the description may change with varying positions. // To solve this dilemma the offsets are converted into fixed length strings which makes it possible to know // the description length in advance. StartHTMLIndex := DescriptionLength; // position 0 after the description StartFragmentIndex := StartHTMLIndex + Length(DocType) + Length(HTMLIntro); EndFragmentIndex := StartFragmentIndex + Length(HTML); EndHTMLIndex := EndFragmentIndex + Length(HTMLExtro); Description := Version + SysUtils.Format('%s%.8d', [StartHTML, StartHTMLIndex]) + #13#10 + SysUtils.Format('%s%.8d', [EndHTML, EndHTMLIndex]) + #13#10 + SysUtils.Format('%s%.8d', [StartFragment, StartFragmentIndex]) + #13#10 + SysUtils.Format('%s%.8d', [EndFragment, EndFragmentIndex]) + #13#10; HTML := Description + DocType + HTMLIntro + HTML + HTMLExtro; end; } //--------------- end local function ---------------------------------------- var Data: Pointer; DataSize: Cardinal; S: string; WS: WideString; P: Pointer; begin Result := 0; { case Format of CF_TEXT: begin S := ContentToText(Source, #9) + #0; Data := PChar(S); DataSize := Length(S); end; CF_UNICODETEXT: begin WS := ContentToUnicode(Source, #9) + #0; Data := PWideChar(WS); DataSize := 2 * Length(WS); end; else if Format = CF_CSV then S := ContentToText(Source, ListSeparator) + #0 else if (Format = CF_VRTF) or (Format = CF_VRTFNOOBJS) then S := ContentToRTF(Source) + #0 else if Format = CF_HTML then begin S := ContentToHTML(Source); // Build a valid HTML clipboard fragment. MakeFragment(S); S := S + #0; end; Data := PChar(S); DataSize := Length(S); end; if DataSize > 0 then begin Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize); P := GlobalLock(Result); Move(Data^, P^, DataSize); GlobalUnlock(Result); end; } end; doublecmd-0.8.2/components/virtualtreeview/include/intf/gtk/0000775000175000017500000000000013244011205023273 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/intf/gtk/vtvdragmanager.inc0000664000175000017500000000003612014201074026774 0ustar alexxalexx {$i ../dummydragmanager.inc} doublecmd-0.8.2/components/virtualtreeview/include/intf/gtk/olemethods.inc0000664000175000017500000000003512014201074026126 0ustar alexxalexx {$i ../dummyolemethods.inc} doublecmd-0.8.2/components/virtualtreeview/include/intf/gtk/vtgraphicsi.inc0000664000175000017500000000376612014201074026324 0ustar alexxalexxuses gtkdef, gtkint, CairoXlib, gdk, Cairo, glib; //procedure gdk_drawable_get_size(drawable: PGdkDrawable; width, height: Pgint); cdecl; external gdkdll; procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer); function CreateSurface(GtkDC: TGtkDeviceContext): Pcairo_surface_t; var Width, Height: gint; Visual: PGdkVisual; begin Result := nil; if (GtkDC <> nil) and (GtkDC.Drawable <> nil) then begin gdk_window_get_size(GtkDC.Drawable, @Width, @Height); Visual := gdk_visual_get_system; Result := cairo_xlib_surface_create( GDK_WINDOW_XDISPLAY(PGdkWindowPrivate(GtkDC.Drawable)), GDK_WINDOW_XWINDOW(PGdkWindowPrivate(GtkDC.Drawable)), GDK_VISUAL_XVISUAL(PGdkVisualPrivate(Visual)), Width, Height); end; end; var SrcDC: TGtkDeviceContext absolute Source; DestDC: TGtkDeviceContext absolute Destination; SrcSurface, DestSurface: Pcairo_surface_t; SrcContext, DestContext: Pcairo_t; begin case Mode of bmConstantAlpha:; bmPerPixelAlpha:; bmMasterAlpha:; bmConstantAlphaAndColor: begin DestSurface := CreateSurface(DestDC); if DestSurface <> nil then begin DestContext := cairo_create(DestSurface); cairo_set_source_rgba(DestContext, (Bias and $000000FF) / 255, ((Bias shr 8) and $000000FF) / 255, ((Bias shr 16) and $000000FF) / 255, ConstantAlpha / 255 ); cairo_rectangle(DestContext, R.Left + Target.x, R.Top + Target.y, R.Right - R.Left, R.Bottom - R.Top); cairo_fill(DestContext); cairo_destroy(DestContext); cairo_surface_destroy(DestSurface); end; end; end; end; function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer; begin Result := nil; end; function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer; begin Result := nil; end; doublecmd-0.8.2/components/virtualtreeview/include/intf/dummydragmanager.inc0000664000175000017500000006030412014201074026527 0ustar alexxalexx //---------------------------------------------------------------------------------------------------------------------- // OLE drag and drop support classes // This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs // of DD'ing various kinds of virtual data and works also between applications. //----------------- TEnumFormatEtc ------------------------------------------------------------------------------------- constructor TEnumFormatEtc.Create(Tree: TBaseVirtualTree; AFormatEtcArray: TFormatEtcArray); var I: Integer; begin inherited Create; { FTree := Tree; // Make a local copy of the format data. SetLength(FFormatEtcArray, Length(AFormatEtcArray)); for I := 0 to High(AFormatEtcArray) do FFormatEtcArray[I] := AFormatEtcArray[I]; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult; { var AClone: TEnumFormatEtc; } begin { Result := S_OK; try AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray); AClone.FCurrentIndex := FCurrentIndex; Enum := AClone as IEnumFormatEtc; except Result := E_FAIL; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc;pceltFetched:pULong=nil): HResult; { var CopyCount: LongWord; } begin { Result := S_FALSE; CopyCount := Length(FFormatEtcArray) - FCurrentIndex; if celt < CopyCount then CopyCount := celt; if CopyCount > 0 then begin Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc)); Inc(FCurrentIndex, CopyCount); Result := S_OK; end; //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with // a C Program call with a NULL in pCeltFetcjed?? //Answer: Yes. Is necessary a check here if @pceltFetched <> nil then pceltFetched := CopyCount; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Reset: HResult; begin { FCurrentIndex := 0; Result := S_OK; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Skip(celt: LongWord): HResult; begin { if FCurrentIndex + celt < High(FFormatEtcArray) then begin Inc(FCurrentIndex, celt); Result := S_Ok; end else Result := S_FALSE; } end; //----------------- TVTDataObject -------------------------------------------------------------------------------------- constructor TVTDataObject.Create(AOwner: TBaseVirtualTree; ForClipboard: Boolean); begin inherited Create; { FOwner := AOwner; FForClipboard := ForClipboard; FOwner.GetNativeClipboardFormats(FFormatEtcArray); } end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDataObject.Destroy; var I: Integer; StgMedium: PStgMedium; begin { // Cancel a pending clipboard operation if this data object was created for the clipboard and // is freed because something else is placed there. if FForClipboard and not (tsClipboardFlushing in FOwner.FStates) then FOwner.CancelCutOrCopy; // Release any internal clipboard formats for I := 0 to High(FormatEtcArray) do begin StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat); if Assigned(StgMedium) then ReleaseStgMedium(StgMedium); end; FormatEtcArray := nil; inherited; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; // Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown // interface, will always return the same pointer. begin { if Assigned(TestUnknown) then begin if TestUnknown.QueryInterface(IUnknown, Result) = 0 then Result._Release // Don't actually need it just need the pointer value else Result := TestUnknown end else Result := TestUnknown } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; begin { Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and (FormatEtc1.tymed and FormatEtc2.tymed <> 0); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; var I: integer; begin { Result := -1; for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then begin Result := I; Break; end end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium; { var I: integer; } begin { Result := nil; for I := 0 to High(InternalStgMediumArray) do begin if Format = InternalStgMediumArray[I].Format then begin Result := @InternalStgMediumArray[I].Medium; Break; end end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle; // Returns a global memory block that is a copy of the passed memory block. { var Size: Cardinal; Data, NewData: PChar; } begin { Size := GlobalSize(HGlobal); Result := GlobalAlloc(GPTR, Size); Data := GlobalLock(hGlobal); try NewData := GlobalLock(Result); try Move(Data^, NewData^, Size); finally GlobalUnLock(Result); end finally GlobalUnLock(hGlobal); end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; // Tries to render one of the formats which have been stored via the SetData method. // Since this data is already there it is just copied or its reference count is increased (depending on storage medium). { var InternalMedium: PStgMedium; } begin { Result := True; InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat); if Assigned(InternalMedium) then OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject) else Result := False; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; // InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or // increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually // the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData. // If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during // that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make // copy of the data for the caller only to have them destroy it then need us to copy it again if necessary. // This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData. // This way when the caller frees the structure it sees the unkForRelease is not nil and calls Release on the object // instead of destroying the actual data. var Len: Integer; begin { Result := S_OK; // Simply copy all fields to start with. OutStgMedium := InStgMedium; // The data handled here always results from a call of SetData we got. This ensures only one storage format // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several // storage formats). case InStgMedium.tymed of TYMED_HGLOBAL: begin if CopyInMedium then begin // Generate a unique copy of the data passed OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal); if OutStgMedium.hGlobal = 0 then Result := E_OUTOFMEMORY end else // Don't generate a copy just use ourselves and the copy previously saved. OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount. end; TYMED_FILE: begin //todo_lcl_check Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character. OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len); Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len); end; TYMED_ISTREAM: IUnknown(OutStgMedium.Pstm)._AddRef; TYMED_ISTORAGE: IUnknown(OutStgMedium.Pstg)._AddRef; TYMED_GDI: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy GDI objects right now. TYMED_MFPICT: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now. TYMED_ENHMF: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now. else Result := DV_E_TYMED; end; if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then IUnknown(OutStgMedium.PunkForRelease)._AddRef; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; // Advise sink management is greatly simplified by the IDataAdviseHolder interface. // We use this interface and forward all concerning calls to it. begin { Result := S_OK; if FAdviseHolder = nil then Result := CreateDataAdviseHolder(FAdviseHolder); if Result = S_OK then Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DUnadvise(dwConnection: DWord): HResult; begin { if FAdviseHolder = nil then Result := E_NOTIMPL else Result := FAdviseHolder.Unadvise(dwConnection); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumDAdvise(Out enumAdvise : IEnumStatData):HResult; begin { if FAdviseHolder = nil then Result := OLE_E_ADVISENOTSUPPORTED else Result := FAdviseHolder.EnumAdvise(enumAdvise); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; { var NewList: TEnumFormatEtc; } begin { Result := E_FAIL; if Direction = DATADIR_GET then begin NewList := TEnumFormatEtc.Create(FOwner, FormatEtcArray); EnumFormatEtc := NewList as IEnumFormatEtc; Result := S_OK; end else EnumFormatEtc := nil; if EnumFormatEtc = nil then Result := OLE_S_USEREG; } end; //---------------------------------------------------------------------------------------------------------------------- Function TVTDataObject.GetCanonicalFormatEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; begin //Result := DATA_S_SAMEFORMATETC; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; // Data is requested by clipboard or drop target. This method dispatchs the call // depending on the data being requested. { var I: Integer; Data: PVTReference; } begin { // The tree reference format is always supported and returned from here. if FormatEtcIn.cfFormat = CF_VTREFERENCE then begin // Note: this format is not used while flushing the clipboard to avoid a dangling reference // when the owner tree is destroyed before the clipboard data is replaced with something else. if tsClipboardFlushing in FOwner.FStates then Result := E_FAIL else begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference)); Data := GlobalLock(Medium.hGlobal); Data.Process := GetCurrentProcessID; Data.Tree := FOwner; GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Medium.PunkForRelease := nil; Result := S_OK; end; end else begin try // See if we accept this type and if not get the correct return value. Result := QueryGetData(FormatEtcIn); if Result = S_OK then begin for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then begin if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then Result := FOwner.RenderOLEData(FormatEtcIn, Medium, FForClipboard); Break; end; end end except FillChar(Medium, SizeOf(Medium), #0); Result := E_FAIL; end; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; begin //Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult; { var I: Integer; } begin { Result := DV_E_CLIPFORMAT; for I := 0 to High(FFormatEtcArray) do begin if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then begin if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then begin if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then begin if FormatEtc.lindex = FFormatEtcArray[I].lindex then begin Result := S_OK; Break; end else Result := DV_E_LINDEX; end else Result := DV_E_DVASPECT; end else Result := DV_E_TYMED; end; end } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.SetData(const FormatEtc: TFormatEtc; {$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; // Allows dynamic adding to the IDataObject during its existance. Most noteably it is used to implement // IDropSourceHelper and allows to set a special format for optimized moves during a shell transfer. { var Index: Integer; LocalStgMedium: PStgMedium; } begin { // See if we already have a format of that type available. Index := FindFormatEtc(FormatEtc, FormatEtcArray); if Index > - 1 then begin // Just use the TFormatEct in the array after releasing the data. LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat); if Assigned(LocalStgMedium) then begin ReleaseStgMedium(LocalStgMedium); FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; end else begin // It is a new format so create a new TFormatCollectionItem, copy the // FormatEtc parameter into the new object and and put it in the list. SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1); FormatEtcArray[High(FormatEtcArray)] := FormatEtc; // Create a new InternalStgMedium and initialize it and associate it with the format. SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1); InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat; LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium; FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; if DoRelease then begin // We are simply being given the data and we take control of it. LocalStgMedium^ := Medium; Result := S_OK end else begin // We need to reference count or copy the data and keep our own references to it. Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject); // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium. // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN. if Assigned(LocalStgMedium.PunkForRelease) then begin if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface end; end; // Tell all registered advice sinks about the data change. if Assigned(FAdviseHolder) then FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0); } end; //----------------- TVTDragManager ------------------------------------------------------------------------------------- constructor TVTDragManager.Create(AOwner: TBaseVirtualTree); begin inherited Create; FOwner := AOwner; { // Create an instance of the drop target helper interface. This will fail but not harm on systems which do // not support this interface (everything below Windows 2000); CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper); } end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDragManager.Destroy; begin // Set the owner's reference to us to nil otherwise it will access an invalid pointer // after our desctruction is complete. Pointer(FOwner.FDragManager) := nil; inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDataObject: IDataObject; begin // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem. // In this case there is no local reference to a data object and one is created (but not stored). // If there is a local reference then the owner tree is currently the drop target and the stored interface is // that of the drag initiator. { if Assigned(FDataObject) then Result := FDataObject else begin Result := FOwner.DoCreateDataObject; if Result = nil then Result := TVTDataObject.Create(FOwner, False) as IDataObject; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDragSource: TBaseVirtualTree; begin //Result := FDragSource; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDropTargetHelperSupported: Boolean; begin //Result := Assigned(FDropTargetHelper); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetIsDropTarget: Boolean; begin //Result := FIsDropTarget; Result := True; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin { FDataObject := DataObject; FIsDropTarget := True; SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0); // If full dragging of window contents is disabled in the system then our tree windows will be locked // and cannot be updated during a drag operation. With the following call painting is again enabled. if not FFullDragging then LockWindowUpdate(0); if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragEnter(FOwner.Handle, DataObject, Pt, Effect); FDragSource := FOwner.GetTreeFromDataObject(DataObject); Result := FOwner.DragEnter(KeyState, Pt, Effect); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragLeave: HResult; begin { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; FOwner.DragLeave; FIsDropTarget := False; FDragSource := nil; FDataObject := nil; Result := NOERROR; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragOver(Pt, Effect); Result := FOwner.DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.Drop(DataObject, Pt, Effect); Result := FOwner.DragDrop(DataObject, KeyState, Pt, Effect); FIsDropTarget := False; FDataObject := nil; } end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragManager.ForceDragLeave; // Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive // a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from // screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE). begin { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GiveFeedback(Effect: LongWord): HResult; begin //Result := DRAGDROP_S_USEDEFAULTCURSORS; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; var RButton, LButton: Boolean; begin { LButton := (KeyState and MK_LBUTTON) <> 0; RButton := (KeyState and MK_RBUTTON) <> 0; // Drag'n drop canceled by pressing both mouse buttons or Esc? if (LButton and RButton) or EscapePressed then Result := DRAGDROP_S_CANCEL else // Drag'n drop finished? if not (LButton or RButton) then Result := DRAGDROP_S_DROP else Result := S_OK; } end; doublecmd-0.8.2/components/virtualtreeview/include/intf/qt/0000775000175000017500000000000013244011205023132 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/intf/qt/vtvdragmanager.inc0000664000175000017500000000003612014201074026633 0ustar alexxalexx {$i ../dummydragmanager.inc} doublecmd-0.8.2/components/virtualtreeview/include/intf/qt/olemethods.inc0000664000175000017500000000003512014201074025765 0ustar alexxalexx {$i ../dummyolemethods.inc} doublecmd-0.8.2/components/virtualtreeview/include/intf/qt/vtgraphicsi.inc0000664000175000017500000010521312203745772026173 0ustar alexxalexxuses qt4, qtobjects; {$ASMMODE INTEL} procedure AlphaBlendLineConstant(Source, Destination: Pointer; Count: Integer; ConstantAlpha, Bias: Integer); // Blends a line of Count pixels from Source to Destination using a constant alpha value. // The layout of a pixel must be BGRA where A is ignored (but is calculated as the other components). // ConstantAlpha must be in the range 0..255 where 0 means totally transparent (destination pixel only) // and 255 totally opaque (source pixel only). // Bias is an additional value which gets added to every component and must be in the range -128..127 asm {$ifdef CPU64} //windows // RCX contains Source // RDX contains Destination // R8D contains Count // R9D contains ConstantAlpha // Bias is on the stack //non windows // RDI contains Source // RSI contains Destination // EDX contains Count // ECX contains ConstantAlpha // R8D contains Bias //.NOFRAME // Load XMM3 with the constant alpha value (replicate it for every component). // Expand it to word size. {$ifdef windows} MOVD XMM3, R9D // ConstantAlpha {$else} MOVD XMM3, ECX // ConstantAlpha {$endif} PUNPCKLWD XMM3, XMM3 PUNPCKLDQ XMM3, XMM3 // Load XMM5 with the bias value. {$ifdef windows} MOVD XMM5, [Bias] {$else} MOVD XMM5, R8D //Bias {$endif} PUNPCKLWD XMM5, XMM5 PUNPCKLDQ XMM5, XMM5 // Load XMM4 with 128 to allow for saturated biasing. MOV R10D, 128 MOVD XMM4, R10D PUNPCKLWD XMM4, XMM4 PUNPCKLDQ XMM4, XMM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. {$ifdef windows} MOVD XMM1, DWORD PTR [RCX] // data is unaligned MOVD XMM2, DWORD PTR [RDX] // data is unaligned {$else} MOVD XMM1, DWORD PTR [RDI] // data is unaligned MOVD XMM2, DWORD PTR [RSI] // data is unaligned {$endif} PXOR XMM0, XMM0 // clear source pixel register for unpacking PUNPCKLBW XMM0, XMM1{[RCX]} // unpack source pixel byte values into words PSRLW XMM0, 8 // move higher bytes to lower bytes PXOR XMM1, XMM1 // clear target pixel register for unpacking PUNPCKLBW XMM1, XMM2{[RDX]} // unpack target pixel byte values into words MOVQ XMM2, XMM1 // make a copy of the shifted values, we need them again PSRLW XMM1, 8 // move higher bytes to lower bytes // calculation is: target = (alpha * (source - target) + 256 * target) / 256 PSUBW XMM0, XMM1 // source - target PMULLW XMM0, XMM3 // alpha * (source - target) PADDW XMM0, XMM2 // add target (in shifted form) PSRLW XMM0, 8 // divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. PSUBW XMM0, XMM4 PADDSW XMM0, XMM5 PADDW XMM0, XMM4 PACKUSWB XMM0, XMM0 // convert words to bytes with saturation {$ifdef windows} MOVD DWORD PTR [RDX], XMM0 // store the result {$else} MOVD DWORD PTR [RSI], XMM0 // store the result {$endif} @3: {$ifdef windows} ADD RCX, 4 ADD RDX, 4 DEC R8D {$else} ADD RDI, 4 ADD RSI, 4 DEC EDX {$endif} JNZ @1 {$else} // EAX contains Source // EDX contains Destination // ECX contains Count // ConstantAlpha and Bias are on the stack PUSH ESI // save used registers PUSH EDI MOV ESI, EAX // ESI becomes the actual source pointer MOV EDI, EDX // EDI becomes the actual target pointer // Load MM6 with the constant alpha value (replicate it for every component). // Expand it to word size. MOV EAX, [ConstantAlpha] DB $0F, $6E, $F0 /// MOVD MM6, EAX DB $0F, $61, $F6 /// PUNPCKLWD MM6, MM6 DB $0F, $62, $F6 /// PUNPCKLDQ MM6, MM6 // Load MM5 with the bias value. MOV EAX, [Bias] DB $0F, $6E, $E8 /// MOVD MM5, EAX DB $0F, $61, $ED /// PUNPCKLWD MM5, MM5 DB $0F, $62, $ED /// PUNPCKLDQ MM5, MM5 // Load MM4 with 128 to allow for saturated biasing. MOV EAX, 128 DB $0F, $6E, $E0 /// MOVD MM4, EAX DB $0F, $61, $E4 /// PUNPCKLWD MM4, MM4 DB $0F, $62, $E4 /// PUNPCKLDQ MM4, MM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. DB $0F, $EF, $C0 /// PXOR MM0, MM0, clear source pixel register for unpacking DB $0F, $60, $06 /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, move higher bytes to lower bytes DB $0F, $EF, $C9 /// PXOR MM1, MM1, clear target pixel register for unpacking DB $0F, $60, $0F /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words DB $0F, $6F, $D1 /// MOVQ MM2, MM1, make a copy of the shifted values, we need them again DB $0F, $71, $D1, $08 /// PSRLW MM1, 8, move higher bytes to lower bytes // calculation is: target = (alpha * (source - target) + 256 * target) / 256 DB $0F, $F9, $C1 /// PSUBW MM0, MM1, source - target DB $0F, $D5, $C6 /// PMULLW MM0, MM6, alpha * (source - target) DB $0F, $FD, $C2 /// PADDW MM0, MM2, add target (in shifted form) DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. DB $0F, $F9, $C4 /// PSUBW MM0, MM4 DB $0F, $ED, $C5 /// PADDSW MM0, MM5 DB $0F, $FD, $C4 /// PADDW MM0, MM4 DB $0F, $67, $C0 /// PACKUSWB MM0, MM0, convert words to bytes with saturation DB $0F, $7E, $07 /// MOVD [EDI], MM0, store the result @3: ADD ESI, 4 ADD EDI, 4 DEC ECX JNZ @1 POP EDI POP ESI {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure AlphaBlendLinePerPixel(Source, Destination: Pointer; Count, Bias: Integer); // Blends a line of Count pixels from Source to Destination using the alpha value of the source pixels. // The layout of a pixel must be BGRA. // Bias is an additional value which gets added to every component and must be in the range -128..127 asm {$ifdef CPU64} //windows // RCX contains Source // RDX contains Destination // R8D contains Count // R9D contains Bias //non windows // RDI contains Source // RSI contains Destination // EDX contains Count // ECX contains Bias //.NOFRAME // Load XMM5 with the bias value. {$ifdef windows} MOVD XMM5, R9D // Bias {$else} MOVD XMM5, ECX // Bias {$endif} PUNPCKLWD XMM5, XMM5 PUNPCKLDQ XMM5, XMM5 // Load XMM4 with 128 to allow for saturated biasing. MOV R10D, 128 MOVD XMM4, R10D PUNPCKLWD XMM4, XMM4 PUNPCKLDQ XMM4, XMM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. {$ifdef windows} MOVD XMM1, DWORD PTR [RCX] // data is unaligned MOVD XMM2, DWORD PTR [RDX] // data is unaligned {$else} MOVD XMM1, DWORD PTR [RDI] // data is unaligned MOVD XMM2, DWORD PTR [RSI] // data is unaligned {$endif} PXOR XMM0, XMM0 // clear source pixel register for unpacking PUNPCKLBW XMM0, XMM1{[RCX]} // unpack source pixel byte values into words PSRLW XMM0, 8 // move higher bytes to lower bytes PXOR XMM1, XMM1 // clear target pixel register for unpacking PUNPCKLBW XMM1, XMM2{[RDX]} // unpack target pixel byte values into words MOVQ XMM2, XMM1 // make a copy of the shifted values, we need them again PSRLW XMM1, 8 // move higher bytes to lower bytes // Load XMM3 with the source alpha value (replicate it for every component). // Expand it to word size. MOVQ XMM3, XMM0 PUNPCKHWD XMM3, XMM3 PUNPCKHDQ XMM3, XMM3 // calculation is: target = (alpha * (source - target) + 256 * target) / 256 PSUBW XMM0, XMM1 // source - target PMULLW XMM0, XMM3 // alpha * (source - target) PADDW XMM0, XMM2 // add target (in shifted form) PSRLW XMM0, 8 // divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. PSUBW XMM0, XMM4 PADDSW XMM0, XMM5 PADDW XMM0, XMM4 PACKUSWB XMM0, XMM0 // convert words to bytes with saturation {$ifdef windows} MOVD DWORD PTR [RDX], XMM0 // store the result {$else} MOVD DWORD PTR [RSI], XMM0 // store the result {$endif} @3: {$ifdef windows} ADD RCX, 4 ADD RDX, 4 DEC R8D {$else} ADD RDI, 4 ADD RSI, 4 DEC EDX {$endif} JNZ @1 {$else} // EAX contains Source // EDX contains Destination // ECX contains Count // Bias is on the stack PUSH ESI // save used registers PUSH EDI MOV ESI, EAX // ESI becomes the actual source pointer MOV EDI, EDX // EDI becomes the actual target pointer // Load MM5 with the bias value. MOV EAX, [Bias] DB $0F, $6E, $E8 /// MOVD MM5, EAX DB $0F, $61, $ED /// PUNPCKLWD MM5, MM5 DB $0F, $62, $ED /// PUNPCKLDQ MM5, MM5 // Load MM4 with 128 to allow for saturated biasing. MOV EAX, 128 DB $0F, $6E, $E0 /// MOVD MM4, EAX DB $0F, $61, $E4 /// PUNPCKLWD MM4, MM4 DB $0F, $62, $E4 /// PUNPCKLDQ MM4, MM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. DB $0F, $EF, $C0 /// PXOR MM0, MM0, clear source pixel register for unpacking DB $0F, $60, $06 /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, move higher bytes to lower bytes DB $0F, $EF, $C9 /// PXOR MM1, MM1, clear target pixel register for unpacking DB $0F, $60, $0F /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words DB $0F, $6F, $D1 /// MOVQ MM2, MM1, make a copy of the shifted values, we need them again DB $0F, $71, $D1, $08 /// PSRLW MM1, 8, move higher bytes to lower bytes // Load MM6 with the source alpha value (replicate it for every component). // Expand it to word size. DB $0F, $6F, $F0 /// MOVQ MM6, MM0 DB $0F, $69, $F6 /// PUNPCKHWD MM6, MM6 DB $0F, $6A, $F6 /// PUNPCKHDQ MM6, MM6 // calculation is: target = (alpha * (source - target) + 256 * target) / 256 DB $0F, $F9, $C1 /// PSUBW MM0, MM1, source - target DB $0F, $D5, $C6 /// PMULLW MM0, MM6, alpha * (source - target) DB $0F, $FD, $C2 /// PADDW MM0, MM2, add target (in shifted form) DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. DB $0F, $F9, $C4 /// PSUBW MM0, MM4 DB $0F, $ED, $C5 /// PADDSW MM0, MM5 DB $0F, $FD, $C4 /// PADDW MM0, MM4 DB $0F, $67, $C0 /// PACKUSWB MM0, MM0, convert words to bytes with saturation DB $0F, $7E, $07 /// MOVD [EDI], MM0, store the result @3: ADD ESI, 4 ADD EDI, 4 DEC ECX JNZ @1 POP EDI POP ESI {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure AlphaBlendLineMaster(Source, Destination: Pointer; Count: Integer; ConstantAlpha, Bias: Integer); // Blends a line of Count pixels from Source to Destination using the source pixel and a constant alpha value. // The layout of a pixel must be BGRA. // ConstantAlpha must be in the range 0..255. // Bias is an additional value which gets added to every component and must be in the range -128..127 asm {$ifdef CPU64} //windows // RCX contains Source // RDX contains Destination // R8D contains Count // R9D contains ConstantAlpha // Bias is on the stack //non windows // RDI contains Source // RSI contains Destination // EDX contains Count // ECX contains ConstantAlpha // R8D contains Bias //.SAVENV XMM6 //todo see how implement in fpc // Load XMM3 with the constant alpha value (replicate it for every component). // Expand it to word size. {$ifdef windows} MOVD XMM3, R9D // ConstantAlpha {$else} MOVD XMM3, ECX // ConstantAlpha {$endif} PUNPCKLWD XMM3, XMM3 PUNPCKLDQ XMM3, XMM3 // Load XMM5 with the bias value. {$ifdef windows} MOV R10D, [Bias] MOVD XMM5, R10D {$else} MOVD XMM5, R8D {$endif} PUNPCKLWD XMM5, XMM5 PUNPCKLDQ XMM5, XMM5 // Load XMM4 with 128 to allow for saturated biasing. MOV R10D, 128 MOVD XMM4, R10D PUNPCKLWD XMM4, XMM4 PUNPCKLDQ XMM4, XMM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. {$ifdef windows} MOVD XMM1, DWORD PTR [RCX] // data is unaligned MOVD XMM2, DWORD PTR [RDX] // data is unaligned {$else} MOVD XMM1, DWORD PTR [RDI] // data is unaligned MOVD XMM2, DWORD PTR [RSI] // data is unaligned {$endif} PXOR XMM0, XMM0 // clear source pixel register for unpacking PUNPCKLBW XMM0, XMM1{[RCX]} // unpack source pixel byte values into words PSRLW XMM0, 8 // move higher bytes to lower bytes PXOR XMM1, XMM1 // clear target pixel register for unpacking PUNPCKLBW XMM1, XMM2{[RCX]} // unpack target pixel byte values into words MOVQ XMM2, XMM1 // make a copy of the shifted values, we need them again PSRLW XMM1, 8 // move higher bytes to lower bytes // Load XMM6 with the source alpha value (replicate it for every component). // Expand it to word size. MOVQ XMM6, XMM0 PUNPCKHWD XMM6, XMM6 PUNPCKHDQ XMM6, XMM6 PMULLW XMM6, XMM3 // source alpha * master alpha PSRLW XMM6, 8 // divide by 256 // calculation is: target = (alpha * master alpha * (source - target) + 256 * target) / 256 PSUBW XMM0, XMM1 // source - target PMULLW XMM0, XMM6 // alpha * (source - target) PADDW XMM0, XMM2 // add target (in shifted form) PSRLW XMM0, 8 // divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. PSUBW XMM0, XMM4 PADDSW XMM0, XMM5 PADDW XMM0, XMM4 PACKUSWB XMM0, XMM0 // convert words to bytes with saturation {$ifdef windows} MOVD DWORD PTR [RDX], XMM0 // store the result {$else} MOVD DWORD PTR [RSI], XMM0 // store the result {$endif} @3: {$ifdef windows} ADD RCX, 4 ADD RDX, 4 DEC R8D {$else} ADD RDI, 4 ADD RSI, 4 DEC EDX {$endif} JNZ @1 {$else} // EAX contains Source // EDX contains Destination // ECX contains Count // ConstantAlpha and Bias are on the stack PUSH ESI // save used registers PUSH EDI MOV ESI, EAX // ESI becomes the actual source pointer MOV EDI, EDX // EDI becomes the actual target pointer // Load MM6 with the constant alpha value (replicate it for every component). // Expand it to word size. MOV EAX, [ConstantAlpha] DB $0F, $6E, $F0 /// MOVD MM6, EAX DB $0F, $61, $F6 /// PUNPCKLWD MM6, MM6 DB $0F, $62, $F6 /// PUNPCKLDQ MM6, MM6 // Load MM5 with the bias value. MOV EAX, [Bias] DB $0F, $6E, $E8 /// MOVD MM5, EAX DB $0F, $61, $ED /// PUNPCKLWD MM5, MM5 DB $0F, $62, $ED /// PUNPCKLDQ MM5, MM5 // Load MM4 with 128 to allow for saturated biasing. MOV EAX, 128 DB $0F, $6E, $E0 /// MOVD MM4, EAX DB $0F, $61, $E4 /// PUNPCKLWD MM4, MM4 DB $0F, $62, $E4 /// PUNPCKLDQ MM4, MM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. DB $0F, $EF, $C0 /// PXOR MM0, MM0, clear source pixel register for unpacking DB $0F, $60, $06 /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, move higher bytes to lower bytes DB $0F, $EF, $C9 /// PXOR MM1, MM1, clear target pixel register for unpacking DB $0F, $60, $0F /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words DB $0F, $6F, $D1 /// MOVQ MM2, MM1, make a copy of the shifted values, we need them again DB $0F, $71, $D1, $08 /// PSRLW MM1, 8, move higher bytes to lower bytes // Load MM7 with the source alpha value (replicate it for every component). // Expand it to word size. DB $0F, $6F, $F8 /// MOVQ MM7, MM0 DB $0F, $69, $FF /// PUNPCKHWD MM7, MM7 DB $0F, $6A, $FF /// PUNPCKHDQ MM7, MM7 DB $0F, $D5, $FE /// PMULLW MM7, MM6, source alpha * master alpha DB $0F, $71, $D7, $08 /// PSRLW MM7, 8, divide by 256 // calculation is: target = (alpha * master alpha * (source - target) + 256 * target) / 256 DB $0F, $F9, $C1 /// PSUBW MM0, MM1, source - target DB $0F, $D5, $C7 /// PMULLW MM0, MM7, alpha * (source - target) DB $0F, $FD, $C2 /// PADDW MM0, MM2, add target (in shifted form) DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. DB $0F, $F9, $C4 /// PSUBW MM0, MM4 DB $0F, $ED, $C5 /// PADDSW MM0, MM5 DB $0F, $FD, $C4 /// PADDW MM0, MM4 DB $0F, $67, $C0 /// PACKUSWB MM0, MM0, convert words to bytes with saturation DB $0F, $7E, $07 /// MOVD [EDI], MM0, store the result @3: ADD ESI, 4 ADD EDI, 4 DEC ECX JNZ @1 POP EDI POP ESI {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure AlphaBlendLineMasterAndColor(Destination: Pointer; Count: Integer; ConstantAlpha, Color: Integer); // Blends a line of Count pixels in Destination against the given color using a constant alpha value. // The layout of a pixel must be BGRA and Color must be rrggbb00 (as stored by a COLORREF). // ConstantAlpha must be in the range 0..255. asm {$ifdef CPU64} //windows // RCX contains Destination // EDX contains Count // R8D contains ConstantAlpha // R9D contains Color //non windows // RDI contains Destination // ESI contains Count // EDX contains ConstantAlpha // ECX contains Color //.NOFRAME // The used formula is: target = (alpha * color + (256 - alpha) * target) / 256. // alpha * color (factor 1) and 256 - alpha (factor 2) are constant values which can be calculated in advance. // The remaining calculation is therefore: target = (F1 + F2 * target) / 256 // Load XMM3 with the constant alpha value (replicate it for every component). // Expand it to word size. (Every calculation here works on word sized operands.) {$ifdef windows} MOVD XMM3, R8D // ConstantAlpha {$else} MOVD XMM3, EDX // ConstantAlpha {$endif} PUNPCKLWD XMM3, XMM3 PUNPCKLDQ XMM3, XMM3 // Calculate factor 2. MOV R10D, $100 MOVD XMM2, R10D PUNPCKLWD XMM2, XMM2 PUNPCKLDQ XMM2, XMM2 PSUBW XMM2, XMM3 // XMM2 contains now: 255 - alpha = F2 // Now calculate factor 1. Alpha is still in XMM3, but the r and b components of Color must be swapped. {$ifdef windows} BSWAP R9D // Color ROR R9D, 8 MOVD XMM1, R9D // Load the color and convert to word sized values. {$else} BSWAP ECX // Color ROR ECX, 8 MOVD XMM1, ECX // Load the color and convert to word sized values. {$endif} PXOR XMM4, XMM4 PUNPCKLBW XMM1, XMM4 PMULLW XMM1, XMM3 // XMM1 contains now: color * alpha = F1 @1: // The pixel loop calculates an entire pixel in one run. {$ifdef windows} MOVD XMM0, DWORD PTR [RCX] {$else} MOVD XMM0, DWORD PTR [RDI] {$endif} PUNPCKLBW XMM0, XMM4 PMULLW XMM0, XMM2 // calculate F1 + F2 * target PADDW XMM0, XMM1 PSRLW XMM0, 8 // divide by 256 PACKUSWB XMM0, XMM0 // convert words to bytes with saturation {$ifdef windows} MOVD DWORD PTR [RCX], XMM0 // store the result ADD RCX, 4 DEC EDX {$else} MOVD DWORD PTR [RDI], XMM0 // store the result ADD RDI, 4 DEC ESI {$endif} JNZ @1 {$else} // EAX contains Destination // EDX contains Count // ECX contains ConstantAlpha // Color is passed on the stack // The used formula is: target = (alpha * color + (256 - alpha) * target) / 256. // alpha * color (factor 1) and 256 - alpha (factor 2) are constant values which can be calculated in advance. // The remaining calculation is therefore: target = (F1 + F2 * target) / 256 // Load MM3 with the constant alpha value (replicate it for every component). // Expand it to word size. (Every calculation here works on word sized operands.) DB $0F, $6E, $D9 /// MOVD MM3, ECX DB $0F, $61, $DB /// PUNPCKLWD MM3, MM3 DB $0F, $62, $DB /// PUNPCKLDQ MM3, MM3 // Calculate factor 2. MOV ECX, $100 DB $0F, $6E, $D1 /// MOVD MM2, ECX DB $0F, $61, $D2 /// PUNPCKLWD MM2, MM2 DB $0F, $62, $D2 /// PUNPCKLDQ MM2, MM2 DB $0F, $F9, $D3 /// PSUBW MM2, MM3 // MM2 contains now: 255 - alpha = F2 // Now calculate factor 1. Alpha is still in MM3, but the r and b components of Color must be swapped. MOV ECX, [Color] BSWAP ECX ROR ECX, 8 DB $0F, $6E, $C9 /// MOVD MM1, ECX // Load the color and convert to word sized values. DB $0F, $EF, $E4 /// PXOR MM4, MM4 DB $0F, $60, $CC /// PUNPCKLBW MM1, MM4 DB $0F, $D5, $CB /// PMULLW MM1, MM3 // MM1 contains now: color * alpha = F1 @1: // The pixel loop calculates an entire pixel in one run. DB $0F, $6E, $00 /// MOVD MM0, [EAX] DB $0F, $60, $C4 /// PUNPCKLBW MM0, MM4 DB $0F, $D5, $C2 /// PMULLW MM0, MM2 // calculate F1 + F2 * target DB $0F, $FD, $C1 /// PADDW MM0, MM1 DB $0F, $71, $D0, $08 /// PSRLW MM0, 8 // divide by 256 DB $0F, $67, $C0 /// PACKUSWB MM0, MM0 // convert words to bytes with saturation DB $0F, $7E, $00 /// MOVD [EAX], MM0 // store the result ADD EAX, 4 DEC EDX JNZ @1 {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure EMMS; // Reset MMX state to use the FPU for other tasks again. {$ifdef CPU64} inline; begin end; {$else} asm DB $0F, $77 /// EMMS end; {$endif} //---------------------------------------------------------------------------------------------------------------------- function GetBitmapBitsFromDeviceContext(DC: HDC; out Width, Height: Integer): Pointer; // Helper function used to retrieve the bitmap selected into the given device context. If there is a bitmap then // the function will return a pointer to its bits otherwise nil is returned. // Additionally the dimensions of the bitmap are returned. var Bitmap: HBITMAP; DIB: TDIBSection; begin Result := nil; Width := 0; Height := 0; Bitmap := GetCurrentObject(DC, OBJ_BITMAP); if Bitmap <> 0 then begin if GetObject(Bitmap, SizeOf(DIB), @DIB) = SizeOf(DIB) then begin Assert(DIB.dsBm.bmPlanes * DIB.dsBm.bmBitsPixel = 32, 'Alpha blending error: bitmap must use 32 bpp.'); Result := DIB.dsBm.bmBits; Width := DIB.dsBmih.biWidth; Height := DIB.dsBmih.biHeight; end; end; Assert(Result <> nil, 'Alpha blending DC error: no bitmap available.'); end; //---------------------------------------------------------------------------------------------------------------------- function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer; var DIB: TDIBSection; begin Result := nil; if Bitmap <> 0 then begin if GetObject(Bitmap, SizeOf(DIB), @DIB) = SizeOf(DIB) then begin Assert(DIB.dsBm.bmPlanes * DIB.dsBm.bmBitsPixel = 32, 'Alpha blending error: bitmap must use 32 bpp.'); Result := DIB.dsBm.bmBits; end; end; end; function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer; // Helper function to calculate the start address for the given row. begin //todo: Height is always > 0 in LCL { if Height > 0 then // bottom-up DIB Row := Height - Row - 1; } // Return DWORD aligned address of the requested scanline. Result := Bits + Row * ((Width * 32 + 31) and not 31) div 8; end; //---------------------------------------------------------------------------------------------------------------------- procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer); // Optimized alpha blend procedure using MMX instructions to perform as quick as possible. // For this procedure to work properly it is important that both source and target bitmap use the 32 bit color format. // R describes the source rectangle to work on. // Target is the place (upper left corner) in the target bitmap where to blend to. Note that source width + X offset // must be less or equal to the target width. Similar for the height. // If Mode is bmConstantAlpha then the blend operation uses the given ConstantAlpha value for all pixels. // If Mode is bmPerPixelAlpha then each pixel is blended using its individual alpha value (the alpha value of the source). // If Mode is bmMasterAlpha then each pixel is blended using its individual alpha value multiplied by ConstantAlpha. // If Mode is bmConstantAlphaAndColor then each destination pixel is blended using ConstantAlpha but also a constant // color which will be obtained from Bias. In this case no offset value is added, otherwise Bias is used as offset. // Blending of a color into target only (bmConstantAlphaAndColor) ignores Source (the DC) and Target (the position). // CAUTION: This procedure does not check whether MMX instructions are actually available! Call it only if MMX is really // usable. var Y: Integer; SourceRun, TargetRun: PByte; SourceBits, DestBits: Pointer; SourceWidth, SourceHeight, DestWidth, DestHeight: Integer; //BlendColor: TQColor; begin if not IsRectEmpty(R) then begin {$ifdef CPU64} //avoid MasterAlpha due to incomplete AlphaBlendLineMaster. See comment in procedure if Mode = bmMasterAlpha then Mode := bmConstantAlpha; {$endif} // Note: it is tempting to optimize the special cases for constant alpha 0 and 255 by just ignoring soure // (alpha = 0) or simply do a blit (alpha = 255). But this does not take the bias into account. case Mode of bmConstantAlpha: begin // Get a pointer to the bitmap bits for the source and target device contexts. // Note: this supposes that both contexts do actually have bitmaps assigned! SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight); DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight); if Assigned(SourceBits) and Assigned(DestBits) then begin for Y := 0 to R.Bottom - R.Top - 1 do begin SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top); Inc(SourceRun, 4 * R.Left); TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y); Inc(TargetRun, 4 * Target.X); AlphaBlendLineConstant(SourceRun, TargetRun, R.Right - R.Left, ConstantAlpha, Bias); end; end; EMMS; end; bmPerPixelAlpha: begin SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight); DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight); if Assigned(SourceBits) and Assigned(DestBits) then begin for Y := 0 to R.Bottom - R.Top - 1 do begin SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top); Inc(SourceRun, 4 * R.Left); TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y); Inc(TargetRun, 4 * Target.X); AlphaBlendLinePerPixel(SourceRun, TargetRun, R.Right - R.Left, Bias); end; end; EMMS; end; bmMasterAlpha: begin SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight); DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight); if Assigned(SourceBits) and Assigned(DestBits) then begin for Y := 0 to R.Bottom - R.Top - 1 do begin SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top); Inc(SourceRun, 4 * Target.X); TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y); AlphaBlendLineMaster(SourceRun, TargetRun, R.Right - R.Left, ConstantAlpha, Bias); end; end; EMMS; end; bmConstantAlphaAndColor: begin //todo: see why is not working { QColor_fromRgb(@BlendColor, Bias and $000000FF, (Bias shr 8) and $000000FF, (Bias shr 16) and $000000FF, ConstantAlpha); QPainter_fillRect(TQTDeviceContext(Destination).Widget, R.Left + Target.x, R.Top + Target.y, R.Right - R.Left, R.Bottom - R.Top, @BlendColor); } // Source is ignored since there is a constant color value. DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight); if Assigned(DestBits) then begin for Y := 0 to R.Bottom - R.Top - 1 do begin TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + R.Top); Inc(TargetRun, 4 * R.Left); AlphaBlendLineMasterAndColor(TargetRun, R.Right - R.Left, ConstantAlpha, Bias); end; end; EMMS; end; end; end; end; doublecmd-0.8.2/components/virtualtreeview/include/intf/gtk2/0000775000175000017500000000000013244011205023355 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/intf/gtk2/vtvdragmanager.inc0000664000175000017500000000003612014201074027056 0ustar alexxalexx {$i ../dummydragmanager.inc} doublecmd-0.8.2/components/virtualtreeview/include/intf/gtk2/olemethods.inc0000664000175000017500000000003512014201074026210 0ustar alexxalexx {$i ../dummyolemethods.inc} doublecmd-0.8.2/components/virtualtreeview/include/intf/gtk2/vtgraphicsi.inc0000664000175000017500000000307212140233030026371 0ustar alexxalexxuses gtk2def, gdk2, GTK2Proc, Cairo, LCLVersion; {$MACRO ON} {$if lcl_fullversion > 1000000} {$define TGtk2DeviceContext:=TGtkDeviceContext} {$endif} function gdk_cairo_create(drawable: PGdkDrawable): Pcairo_t cdecl external gdklib; procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer); function GetContext(GtkDC: TGtk2DeviceContext): Pcairo_t; begin Result := nil; if (GtkDC <> nil) and (GtkDC.Drawable <> nil) then Result := gdk_cairo_create(GtkDC.Drawable); end; var SrcDC: TGtk2DeviceContext absolute Source; DestDC: TGtk2DeviceContext absolute Destination; SrcContext, DestContext: Pcairo_t; begin case Mode of bmConstantAlpha:; bmPerPixelAlpha:; bmMasterAlpha:; bmConstantAlphaAndColor: begin DestContext := GetContext(DestDC); if DestContext <> nil then begin cairo_set_source_rgba(DestContext, (Bias and $000000FF) / 255, ((Bias shr 8) and $000000FF) / 255, ((Bias shr 16) and $000000FF) / 255, ConstantAlpha / 255 ); cairo_rectangle(DestContext, R.Left + Target.x, R.Top + Target.y, R.Right - R.Left, R.Bottom - R.Top); cairo_fill(DestContext); cairo_destroy(DestContext); end; end; end; end; function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer; begin Result := nil; end; function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer; begin Result := nil; end; doublecmd-0.8.2/components/virtualtreeview/include/intf/win32/0000775000175000017500000000000013244011205023450 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/intf/win32/vtvdragmanager.inc0000664000175000017500000005765712140233030027173 0ustar alexxalexx //---------------------------------------------------------------------------------------------------------------------- // OLE drag and drop support classes // This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs // of DD'ing various kinds of virtual data and works also between applications. //----------------- TEnumFormatEtc ------------------------------------------------------------------------------------- constructor TEnumFormatEtc.Create(Tree: TBaseVirtualTree; AFormatEtcArray: TFormatEtcArray); var I: Integer; begin inherited Create; FTree := Tree; // Make a local copy of the format data. SetLength(FFormatEtcArray, Length(AFormatEtcArray)); for I := 0 to High(AFormatEtcArray) do FFormatEtcArray[I] := AFormatEtcArray[I]; end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult; var AClone: TEnumFormatEtc; begin Result := S_OK; try AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray); AClone.FCurrentIndex := FCurrentIndex; Enum := AClone as IEnumFormatEtc; except Result := E_FAIL; end; end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; pceltFetched:pULong=nil): HResult; var CopyCount: LongWord; begin Result := S_FALSE; CopyCount := Length(FFormatEtcArray) - FCurrentIndex; if celt < CopyCount then CopyCount := celt; if CopyCount > 0 then begin Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc)); Inc(FCurrentIndex, CopyCount); Result := S_OK; end; if pceltFetched <> nil then pceltFetched^ := CopyCount; end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Reset: HResult; begin FCurrentIndex := 0; Result := S_OK; end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Skip(celt: LongWord): HResult; begin if FCurrentIndex + celt < High(FFormatEtcArray) then begin Inc(FCurrentIndex, celt); Result := S_Ok; end else Result := S_FALSE; end; //----------------- TVTDataObject -------------------------------------------------------------------------------------- constructor TVTDataObject.Create(AOwner: TBaseVirtualTree; ForClipboard: Boolean); begin inherited Create; FOwner := AOwner; FForClipboard := ForClipboard; FOwner.GetNativeClipboardFormats(FFormatEtcArray); end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDataObject.Destroy; var I: Integer; StgMedium: PStgMedium; begin // Cancel a pending clipboard operation if this data object was created for the clipboard and // is freed because something else is placed there. if FForClipboard and not (tsClipboardFlushing in FOwner.FStates) then FOwner.CancelCutOrCopy; // Release any internal clipboard formats for I := 0 to High(FormatEtcArray) do begin StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat); if Assigned(StgMedium) then ReleaseStgMedium(StgMedium); end; FormatEtcArray := nil; inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; // Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown // interface, will always return the same pointer. begin if Assigned(TestUnknown) then begin if TestUnknown.QueryInterface(IUnknown, Result) = 0 then Result._Release // Don't actually need it just need the pointer value else Result := TestUnknown end else Result := TestUnknown end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; begin Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and (FormatEtc1.tymed and FormatEtc2.tymed <> 0); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; var I: integer; begin Result := -1; for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then begin Result := I; Break; end end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium; var I: integer; begin Result := nil; for I := 0 to High(InternalStgMediumArray) do begin if Format = InternalStgMediumArray[I].Format then begin Result := @InternalStgMediumArray[I].Medium; Break; end end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle; // Returns a global memory block that is a copy of the passed memory block. var Size: Cardinal; Data, NewData: PByte; begin Size := GlobalSize(HGlobal); Result := GlobalAlloc(GPTR, Size); Data := GlobalLock(hGlobal); try NewData := GlobalLock(Result); try Move(Data^, NewData^, Size); finally GlobalUnLock(Result); end finally GlobalUnLock(hGlobal); end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; // Tries to render one of the formats which have been stored via the SetData method. // Since this data is already there it is just copied or its reference count is increased (depending on storage medium). var InternalMedium: PStgMedium; begin Result := True; InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat); if Assigned(InternalMedium) then OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject) else Result := False; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; // InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or // increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually // the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData. // If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during // that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make // copy of the data for the caller only to have them destroy it then need us to copy it again if necessary. // This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData. // This way when the caller frees the structure it sees the unkForRelease is not nil and calls Release on the object // instead of destroying the actual data. var Len: Integer; begin Result := S_OK; // Simply copy all fields to start with. OutStgMedium := InStgMedium; // The data handled here always results from a call of SetData we got. This ensures only one storage format // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several // storage formats). case InStgMedium.tymed of TYMED_HGLOBAL: begin if CopyInMedium then begin // Generate a unique copy of the data passed OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal); if OutStgMedium.hGlobal = 0 then Result := E_OUTOFMEMORY end else // Don't generate a copy just use ourselves and the copy previously saved. OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount. end; TYMED_FILE: begin //todo_lcl_check Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character. OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len); Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len); end; TYMED_ISTREAM: IUnknown(OutStgMedium.Pstm)._AddRef; TYMED_ISTORAGE: IUnknown(OutStgMedium.Pstg)._AddRef; TYMED_GDI: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy GDI objects right now. TYMED_MFPICT: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now. TYMED_ENHMF: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now. else Result := DV_E_TYMED; end; if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then IUnknown(OutStgMedium.PunkForRelease)._AddRef; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; // Advise sink management is greatly simplified by the IDataAdviseHolder interface. // We use this interface and forward all concerning calls to it. begin Result := S_OK; if FAdviseHolder = nil then Result := CreateDataAdviseHolder(FAdviseHolder); if Result = S_OK then Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DUnadvise(dwConnection: DWord): HResult; begin if FAdviseHolder = nil then Result := E_NOTIMPL else Result := FAdviseHolder.Unadvise(dwConnection); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumDAdvise(Out enumAdvise : IEnumStatData):HResult; begin if FAdviseHolder = nil then Result := OLE_E_ADVISENOTSUPPORTED else Result := FAdviseHolder.EnumAdvise(enumAdvise); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; var NewList: TEnumFormatEtc; begin Result := E_FAIL; if Direction = DATADIR_GET then begin NewList := TEnumFormatEtc.Create(FOwner, FormatEtcArray); EnumFormatEtc := NewList as IEnumFormatEtc; Result := S_OK; end else EnumFormatEtc := nil; if EnumFormatEtc = nil then Result := OLE_S_USEREG; end; //---------------------------------------------------------------------------------------------------------------------- Function TVTDataObject.GetCanonicalFormatEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; begin Result := DATA_S_SAMEFORMATETC; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; // Data is requested by clipboard or drop target. This method dispatchs the call // depending on the data being requested. var I: Integer; Data: PVTReference; begin // The tree reference format is always supported and returned from here. if FormatEtcIn.cfFormat = CF_VTREFERENCE then begin // Note: this format is not used while flushing the clipboard to avoid a dangling reference // when the owner tree is destroyed before the clipboard data is replaced with something else. if tsClipboardFlushing in FOwner.FStates then Result := E_FAIL else begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference)); Data := GlobalLock(Medium.hGlobal); Data.Process := GetCurrentProcessID; Data.Tree := FOwner; GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Medium.PunkForRelease := nil; Result := S_OK; end; end else begin try // See if we accept this type and if not get the correct return value. Result := QueryGetData(FormatEtcIn); if Result = S_OK then begin for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then begin if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then Result := FOwner.RenderOLEData(FormatEtcIn, Medium, FForClipboard); Break; end; end end except FillChar(Medium, SizeOf(Medium), #0); Result := E_FAIL; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; begin Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult; var I: Integer; begin Result := DV_E_CLIPFORMAT; for I := 0 to High(FFormatEtcArray) do begin if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then begin if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then begin if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then begin if FormatEtc.lindex = FFormatEtcArray[I].lindex then begin Result := S_OK; Break; end else Result := DV_E_LINDEX; end else Result := DV_E_DVASPECT; end else Result := DV_E_TYMED; end; end end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.SetData(const FormatEtc: TFormatEtc; const Medium: TStgMedium; DoRelease: BOOL): HResult; // Allows dynamic adding to the IDataObject during its existance. Most noteably it is used to implement // IDropSourceHelper and allows to set a special format for optimized moves during a shell transfer. var Index: Integer; LocalStgMedium: PStgMedium; begin // See if we already have a format of that type available. Index := FindFormatEtc(FormatEtc, FormatEtcArray); if Index > - 1 then begin // Just use the TFormatEct in the array after releasing the data. LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat); if Assigned(LocalStgMedium) then begin ReleaseStgMedium(LocalStgMedium); FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; end else begin // It is a new format so create a new TFormatCollectionItem, copy the // FormatEtc parameter into the new object and and put it in the list. SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1); FormatEtcArray[High(FormatEtcArray)] := FormatEtc; // Create a new InternalStgMedium and initialize it and associate it with the format. SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1); InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat; LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium; FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; if DoRelease then begin // We are simply being given the data and we take control of it. LocalStgMedium^ := Medium; Result := S_OK end else begin // We need to reference count or copy the data and keep our own references to it. Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject); // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium. // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN. if Assigned(LocalStgMedium.PunkForRelease) then begin if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface end; end; // Tell all registered advice sinks about the data change. if Assigned(FAdviseHolder) then FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0); end; //----------------- TVTDragManager ------------------------------------------------------------------------------------- constructor TVTDragManager.Create(AOwner: TBaseVirtualTree); begin inherited Create; FOwner := AOwner; // Create an instance of the drop target helper interface. This will fail but not harm on systems which do // not support this interface (everything below Windows 2000); CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper); end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDragManager.Destroy; begin // Set the owner's reference to us to nil otherwise it will access an invalid pointer // after our desctruction is complete. Pointer(FOwner.FDragManager) := nil; inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDataObject: IDataObject; begin // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem. // In this case there is no local reference to a data object and one is created (but not stored). // If there is a local reference then the owner tree is currently the drop target and the stored interface is // that of the drag initiator. if Assigned(FDataObject) then Result := FDataObject else begin Result := FOwner.DoCreateDataObject; if Result = nil then Result := TVTDataObject.Create(FOwner, False) as IDataObject; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDragSource: TBaseVirtualTree; begin Result := FDragSource; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDropTargetHelperSupported: Boolean; begin Result := Assigned(FDropTargetHelper); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetIsDropTarget: Boolean; begin Result := FIsDropTarget; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin FDataObject := DataObject; FIsDropTarget := True; SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0); // If full dragging of window contents is disabled in the system then our tree windows will be locked // and cannot be updated during a drag operation. With the following call painting is again enabled. if not FFullDragging then LockWindowUpdate(0); if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragEnter(FOwner.Handle, DataObject, Pt, Effect); FDragSource := FOwner.GetTreeFromDataObject(DataObject); Result := FOwner.DragEnter(KeyState, Pt, Effect); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragLeave: HResult; begin if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; FOwner.DragLeave; FIsDropTarget := False; FDragSource := nil; FDataObject := nil; Result := NOERROR; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragOver(Pt, Effect); Result := FOwner.DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.Drop(DataObject, Pt, Effect); Result := FOwner.DragDrop(DataObject, KeyState, Pt, Effect); FIsDropTarget := False; FDataObject := nil; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragManager.ForceDragLeave; // Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive // a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from // screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE). begin if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; end; //---------------------------------------------------------------------------------------------------------------------- {$IF FPC_FULLVERSION < 020601} function TVTDragManager.GiveFeedback(Effect: Longint): HResult; {$ELSE} function TVTDragManager.GiveFeedback(Effect: LongWord): HResult; {$ENDIF} begin Result := DRAGDROP_S_USEDEFAULTCURSORS; end; //---------------------------------------------------------------------------------------------------------------------- {$IF FPC_FULLVERSION < 020601} function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: Longint): HResult; {$ELSE} function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; {$ENDIF} var RButton, LButton: Boolean; begin LButton := (KeyState and MK_LBUTTON) <> 0; RButton := (KeyState and MK_RBUTTON) <> 0; // Drag'n drop canceled by pressing both mouse buttons or Esc? if (LButton and RButton) or EscapePressed then Result := DRAGDROP_S_CANCEL else // Drag'n drop finished? if not (LButton or RButton) then Result := DRAGDROP_S_DROP else Result := S_OK; end; doublecmd-0.8.2/components/virtualtreeview/include/intf/win32/olemethods.inc0000664000175000017500000003466612014201074026324 0ustar alexxalexxfunction TBaseVirtualTree.GetTreeFromDataObject(const DataObject: IDataObject): TBaseVirtualTree; // Returns the owner/sender of the given data object by means of a special clipboard format // or nil if the sender is in another process or no virtual tree at all. var Medium: TStgMedium; Data: PVTReference; begin Result := nil; if Assigned(DataObject) then begin StandardOLEFormat.cfFormat := CF_VTREFERENCE; if DataObject.GetData(StandardOLEFormat, Medium) = S_OK then begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin if Data.Process = GetCurrentProcessID then Result := Data.Tree; GlobalUnlock(Medium.hGlobal); end; ReleaseStgMedium(@Medium); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; // Returns a memory expression of all currently selected nodes in the Medium structure. // Note: The memory requirement of this method might be very high. This depends however on the requested storage format. // For HGlobal (a global memory block) we need to render first all nodes to local memory and copy this then to // the global memory in Medium. This is necessary because we have first to determine how much // memory is needed before we can allocate it. Hence for a short moment we need twice the space as used by the // nodes alone (plus the amount the nodes need in the tree anyway)! // With IStream this does not happen. We directly stream out the nodes and pass the constructed stream along. //--------------- local function -------------------------------------------- procedure WriteNodes(Stream: TStream); var Selection: TNodeArray; I: Integer; begin if ForClipboard then Selection := GetSortedCutCopySet(True) else Selection := GetSortedSelection(True); for I := 0 to High(Selection) do WriteNode(Stream, Selection[I]); end; //--------------- end local function ---------------------------------------- var Data: PCardinal; ResPointer: Pointer; ResSize: Integer; OLEStream: IStream; VCLStream: TStream; begin FillChar(Medium, SizeOf(Medium), 0); // We can render the native clipboard format in two different storage media. if (FormatEtcIn.cfFormat = CF_VIRTUALTREE) and (FormatEtcIn.tymed and (TYMED_HGLOBAL or TYMED_ISTREAM) <> 0) then begin VCLStream := nil; try Medium.PunkForRelease := nil; // Return data in one of the supported storage formats, prefer IStream. if FormatEtcIn.tymed and TYMED_ISTREAM <> 0 then begin // Create an IStream on a memory handle (here it is 0 which indicates to implicitely allocated a handle). // Do not use TStreamAdapter as it is not compatible with OLE (when flushing the clipboard OLE wants the HGlobal // back which is not supported by TStreamAdapater). CreateStreamOnHGlobal(0, True, OLEStream); VCLStream := TOLEStream.Create(OLEStream); WriteNodes(VCLStream); // Rewind stream. VCLStream.Position := 0; Medium.tymed := TYMED_ISTREAM; IUnknown(Medium.Pstm) := OLEStream; Result := S_OK; end else begin VCLStream := TMemoryStream.Create; WriteNodes(VCLStream); ResPointer := TMemoryStream(VCLStream).Memory; ResSize := VCLStream.Position; // Allocate memory to hold the string. if ResSize > 0 then begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, ResSize + SizeOf(Cardinal)); Data := GlobalLock(Medium.hGlobal); // Store the size of the data too, for easy retrival. Data^ := ResSize; Inc(Data); Move(ResPointer^, Data^, ResSize); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Result := S_OK; end else Result := E_FAIL; end; finally // We can free the VCL stream here since it was either a pure memory stream or only a wrapper around // the OLEStream which exists independently. VCLStream.Free; end; end else // Ask application descendants to render self defined formats. Result := DoRenderOLEData(FormatEtcIn, Medium, ForClipboard); end; //---------------------------------------------------------------------------------------------------------------------- type // needed to handle OLE global memory objects TOLEMemoryStream = class(TCustomMemoryStream) public function Write(const Buffer; Count: Integer): Longint; override; end; //---------------------------------------------------------------------------------------------------------------------- function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer; begin //raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError)); raise EStreamError.Create(SCantWriteResourceStreamError); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ProcessOLEData(Source: TBaseVirtualTree; DataObject: IDataObject; TargetNode: PVirtualNode; Mode: TVTNodeAttachMode; Optimized: Boolean): Boolean; // Recreates the (sub) tree structure serialized into memory and provided by DataObject. The new nodes are attached to // the passed node or FRoot if TargetNode is nil according to Mode. Optimized can be set to True if the entire operation // happens within the same process (i.e. sender and receiver of the OLE operation are located in the same process). // Optimize = True makes only sense if the operation to carry out is a move hence it is also the indication of the // operation to be done here. Source is the source of the OLE data and only of use (and usually assigned) when // an OLE operation takes place in the same application. // Returns True on success, i.e. the CF_VIRTUALTREE format is supported by the data object and the structure could be // recreated, otherwise False. var Medium: TStgMedium; Stream: TStream; Data: Pointer; Node: PVirtualNode; Nodes: TNodeArray; I: Integer; Res: HRESULT; ChangeReason: TChangeReason; begin Nodes := nil; // Check the data format available by the data object. with StandardOLEFormat do begin // Read best format. cfFormat := CF_VIRTUALTREE; end; Result := DataObject.QueryGetData(StandardOLEFormat) = S_OK; if Result and not (toReadOnly in FOptions.FMiscOptions) then begin BeginUpdate; Result := False; try if TargetNode = nil then TargetNode := FRoot; if TargetNode = FRoot then begin case Mode of amInsertBefore: Mode := amAddChildFirst; amInsertAfter: Mode := amAddChildLast; end; end; // Optimized means source is known and in the same process so we can access its pointers, which avoids duplicating // the data while doing a serialization. Can only be used with cut'n paste and drag'n drop with move effect. if Optimized then begin if tsOLEDragging in Source.FStates then Nodes := Source.FDragSelection else Nodes := Source.GetSortedCutCopySet(True); if Mode in [amInsertBefore,amAddChildLast] then begin for I := 0 to High(Nodes) do if not HasAsParent(TargetNode, Nodes[I]) then Source.MoveTo(Nodes[I], TargetNode, Mode, False); end else begin for I := High(Nodes) downto 0 do if not HasAsParent(TargetNode, Nodes[I]) then Source.MoveTo(Nodes[I], TargetNode, Mode, False); end; Result := True; end else begin if Source = Self then ChangeReason := crNodeCopied else ChangeReason := crNodeAdded; Res := DataObject.GetData(StandardOLEFormat, Medium); if Res = S_OK then begin case Medium.tymed of TYMED_ISTREAM, // IStream interface TYMED_HGLOBAL: // global memory block begin Stream := nil; if Medium.tymed = TYMED_ISTREAM then Stream := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream) else begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin // Get the total size of data to retrieve. I := PCardinal(Data)^; Inc(PCardinal(Data)); Stream := TOLEMemoryStream.Create; TOLEMemoryStream(Stream).SetPointer(Data, I); end; end; if Assigned(Stream) then try while Stream.Position < Stream.Size do begin Node := MakeNewNode; InternalConnectNode(Node, TargetNode, Self, Mode); InternalAddFromStream(Stream, VTTreeStreamVersion, Node); // This seems a bit strange because of the callback for granting to add the node // which actually comes after the node has been added. The reason is that the node must // contain valid data otherwise I don't see how the application can make a funded decision. if not DoNodeCopying(Node, TargetNode) then DeleteNode(Node) else DoNodeCopied(Node); StructureChange(Node, ChangeReason); // In order to maintain the same node order when restoring nodes in the case of amInsertAfter // we have to move the reference node continously. Othwise we would end up with reversed node order. if Mode = amInsertAfter then TargetNode := Node; end; Result := True; finally Stream.Free; if Medium.tymed = TYMED_HGLOBAL then GlobalUnlock(Medium.hGlobal); end; end; end; ReleaseStgMedium(@Medium); end; end; finally EndUpdate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.ContentToClipboard(Format: Word; Source: TVSTTextSourceType): HGLOBAL; // This method constructs a shareable memory object filled with string data in the required format. Supported are: // CF_TEXT - plain ANSI text (Unicode text is converted using the user's current locale) // CF_UNICODETEXT - plain Unicode text // CF_CSV - comma separated plain ANSI text // CF_VRTF + CF_RTFNOOBS - rich text (plain ANSI) // CF_HTML - HTML text encoded using UTF-8 // // Result is the handle to a globally allocated memory block which can directly be used for clipboard and drag'n drop // transfers. The caller is responsible for freeing the memory. If for some reason the content could not be rendered // the Result is 0. //--------------- local function -------------------------------------------- procedure MakeFragment(var HTML: string); // Helper routine to build a properly-formatted HTML fragment. const Version = 'Version:1.0'#13#10; StartHTML = 'StartHTML:'; EndHTML = 'EndHTML:'; StartFragment = 'StartFragment:'; EndFragment = 'EndFragment:'; DocType = ''; HTMLIntro = '' + ''; HTMLExtro = ''; NumberLengthAndCR = 10; // Let the compiler determine the description length. DescriptionLength = Length(Version) + Length(StartHTML) + Length(EndHTML) + Length(StartFragment) + Length(EndFragment) + 4 * NumberLengthAndCR; var Description: string; StartHTMLIndex, EndHTMLIndex, StartFragmentIndex, EndFragmentIndex: Integer; begin // The HTML clipboard format is defined by using byte positions in the entire block where HTML text and // fragments start and end. These positions are written in a description. Unfortunately the positions depend on the // length of the description but the description may change with varying positions. // To solve this dilemma the offsets are converted into fixed length strings which makes it possible to know // the description length in advance. StartHTMLIndex := DescriptionLength; // position 0 after the description StartFragmentIndex := StartHTMLIndex + Length(DocType) + Length(HTMLIntro); EndFragmentIndex := StartFragmentIndex + Length(HTML); EndHTMLIndex := EndFragmentIndex + Length(HTMLExtro); Description := Version + SysUtils.Format('%s%.8d', [StartHTML, StartHTMLIndex]) + #13#10 + SysUtils.Format('%s%.8d', [EndHTML, EndHTMLIndex]) + #13#10 + SysUtils.Format('%s%.8d', [StartFragment, StartFragmentIndex]) + #13#10 + SysUtils.Format('%s%.8d', [EndFragment, EndFragmentIndex]) + #13#10; HTML := Description + DocType + HTMLIntro + HTML + HTMLExtro; end; //--------------- end local function ---------------------------------------- var Data: Pointer; DataSize: Cardinal; S: string; WS: UnicodeString; P: Pointer; begin Result := 0; case Format of CF_TEXT: begin S := ContentToAnsi(Source, #9) + #0; Data := PChar(S); DataSize := Length(S); end; CF_UNICODETEXT: begin WS := ContentToUTF16(Source, #9) + #0; Data := PWideChar(WS); DataSize := 2 * Length(WS); end; else if Format = CF_CSV then S := ContentToAnsi(Source, ListSeparator) + #0 else if (Format = CF_VRTF) or (Format = CF_VRTFNOOBJS) then S := ContentToRTF(Source) + #0 else if Format = CF_HTML then begin S := ContentToHTML(Source); // Build a valid HTML clipboard fragment. MakeFragment(S); S := S + #0; end; Data := PChar(S); DataSize := Length(S); end; if DataSize > 0 then begin Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize); P := GlobalLock(Result); Move(Data^, P^, DataSize); GlobalUnlock(Result); end; end; doublecmd-0.8.2/components/virtualtreeview/include/intf/win32/vtgraphicsi.inc0000664000175000017500000007645512140233030026503 0ustar alexxalexx {$ASMMODE INTEL} procedure AlphaBlendLineConstant(Source, Destination: Pointer; Count: Integer; ConstantAlpha, Bias: Integer); // Blends a line of Count pixels from Source to Destination using a constant alpha value. // The layout of a pixel must be BGRA where A is ignored (but is calculated as the other components). // ConstantAlpha must be in the range 0..255 where 0 means totally transparent (destination pixel only) // and 255 totally opaque (source pixel only). // Bias is an additional value which gets added to every component and must be in the range -128..127 asm {$ifdef CPU64} // RCX contains Source // RDX contains Destination // R8D contains Count // R9D contains ConstantAlpha // Bias is on the stack //.NOFRAME // Load XMM3 with the constant alpha value (replicate it for every component). // Expand it to word size. MOVD XMM3, R9D // ConstantAlpha PUNPCKLWD XMM3, XMM3 PUNPCKLDQ XMM3, XMM3 // Load XMM5 with the bias value. MOVD XMM5, [Bias] PUNPCKLWD XMM5, XMM5 PUNPCKLDQ XMM5, XMM5 // Load XMM4 with 128 to allow for saturated biasing. MOV R10D, 128 MOVD XMM4, R10D PUNPCKLWD XMM4, XMM4 PUNPCKLDQ XMM4, XMM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. MOVD XMM1, DWORD PTR [RCX] // data is unaligned MOVD XMM2, DWORD PTR [RDX] // data is unaligned PXOR XMM0, XMM0 // clear source pixel register for unpacking PUNPCKLBW XMM0, XMM1{[RCX]} // unpack source pixel byte values into words PSRLW XMM0, 8 // move higher bytes to lower bytes PXOR XMM1, XMM1 // clear target pixel register for unpacking PUNPCKLBW XMM1, XMM2{[RDX]} // unpack target pixel byte values into words MOVQ XMM2, XMM1 // make a copy of the shifted values, we need them again PSRLW XMM1, 8 // move higher bytes to lower bytes // calculation is: target = (alpha * (source - target) + 256 * target) / 256 PSUBW XMM0, XMM1 // source - target PMULLW XMM0, XMM3 // alpha * (source - target) PADDW XMM0, XMM2 // add target (in shifted form) PSRLW XMM0, 8 // divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. PSUBW XMM0, XMM4 PADDSW XMM0, XMM5 PADDW XMM0, XMM4 PACKUSWB XMM0, XMM0 // convert words to bytes with saturation MOVD DWORD PTR [RDX], XMM0 // store the result @3: ADD RCX, 4 ADD RDX, 4 DEC R8D JNZ @1 {$else} // EAX contains Source // EDX contains Destination // ECX contains Count // ConstantAlpha and Bias are on the stack PUSH ESI // save used registers PUSH EDI MOV ESI, EAX // ESI becomes the actual source pointer MOV EDI, EDX // EDI becomes the actual target pointer // Load MM6 with the constant alpha value (replicate it for every component). // Expand it to word size. MOV EAX, [ConstantAlpha] DB $0F, $6E, $F0 /// MOVD MM6, EAX DB $0F, $61, $F6 /// PUNPCKLWD MM6, MM6 DB $0F, $62, $F6 /// PUNPCKLDQ MM6, MM6 // Load MM5 with the bias value. MOV EAX, [Bias] DB $0F, $6E, $E8 /// MOVD MM5, EAX DB $0F, $61, $ED /// PUNPCKLWD MM5, MM5 DB $0F, $62, $ED /// PUNPCKLDQ MM5, MM5 // Load MM4 with 128 to allow for saturated biasing. MOV EAX, 128 DB $0F, $6E, $E0 /// MOVD MM4, EAX DB $0F, $61, $E4 /// PUNPCKLWD MM4, MM4 DB $0F, $62, $E4 /// PUNPCKLDQ MM4, MM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. DB $0F, $EF, $C0 /// PXOR MM0, MM0, clear source pixel register for unpacking DB $0F, $60, $06 /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, move higher bytes to lower bytes DB $0F, $EF, $C9 /// PXOR MM1, MM1, clear target pixel register for unpacking DB $0F, $60, $0F /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words DB $0F, $6F, $D1 /// MOVQ MM2, MM1, make a copy of the shifted values, we need them again DB $0F, $71, $D1, $08 /// PSRLW MM1, 8, move higher bytes to lower bytes // calculation is: target = (alpha * (source - target) + 256 * target) / 256 DB $0F, $F9, $C1 /// PSUBW MM0, MM1, source - target DB $0F, $D5, $C6 /// PMULLW MM0, MM6, alpha * (source - target) DB $0F, $FD, $C2 /// PADDW MM0, MM2, add target (in shifted form) DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. DB $0F, $F9, $C4 /// PSUBW MM0, MM4 DB $0F, $ED, $C5 /// PADDSW MM0, MM5 DB $0F, $FD, $C4 /// PADDW MM0, MM4 DB $0F, $67, $C0 /// PACKUSWB MM0, MM0, convert words to bytes with saturation DB $0F, $7E, $07 /// MOVD [EDI], MM0, store the result @3: ADD ESI, 4 ADD EDI, 4 DEC ECX JNZ @1 POP EDI POP ESI {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure AlphaBlendLinePerPixel(Source, Destination: Pointer; Count, Bias: Integer); // Blends a line of Count pixels from Source to Destination using the alpha value of the source pixels. // The layout of a pixel must be BGRA. // Bias is an additional value which gets added to every component and must be in the range -128..127 asm {$ifdef CPU64} // RCX contains Source // RDX contains Destination // R8D contains Count // R9D contains Bias //.NOFRAME // Load XMM5 with the bias value. MOVD XMM5, R9D // Bias PUNPCKLWD XMM5, XMM5 PUNPCKLDQ XMM5, XMM5 // Load XMM4 with 128 to allow for saturated biasing. MOV R10D, 128 MOVD XMM4, R10D PUNPCKLWD XMM4, XMM4 PUNPCKLDQ XMM4, XMM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. MOVD XMM1, DWORD PTR [RCX] // data is unaligned MOVD XMM2, DWORD PTR [RDX] // data is unaligned PXOR XMM0, XMM0 // clear source pixel register for unpacking PUNPCKLBW XMM0, XMM1{[RCX]} // unpack source pixel byte values into words PSRLW XMM0, 8 // move higher bytes to lower bytes PXOR XMM1, XMM1 // clear target pixel register for unpacking PUNPCKLBW XMM1, XMM2{[RDX]} // unpack target pixel byte values into words MOVQ XMM2, XMM1 // make a copy of the shifted values, we need them again PSRLW XMM1, 8 // move higher bytes to lower bytes // Load XMM3 with the source alpha value (replicate it for every component). // Expand it to word size. MOVQ XMM3, XMM0 PUNPCKHWD XMM3, XMM3 PUNPCKHDQ XMM3, XMM3 // calculation is: target = (alpha * (source - target) + 256 * target) / 256 PSUBW XMM0, XMM1 // source - target PMULLW XMM0, XMM3 // alpha * (source - target) PADDW XMM0, XMM2 // add target (in shifted form) PSRLW XMM0, 8 // divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. PSUBW XMM0, XMM4 PADDSW XMM0, XMM5 PADDW XMM0, XMM4 PACKUSWB XMM0, XMM0 // convert words to bytes with saturation MOVD DWORD PTR [RDX], XMM0 // store the result @3: ADD RCX, 4 ADD RDX, 4 DEC R8D JNZ @1 {$else} // EAX contains Source // EDX contains Destination // ECX contains Count // Bias is on the stack PUSH ESI // save used registers PUSH EDI MOV ESI, EAX // ESI becomes the actual source pointer MOV EDI, EDX // EDI becomes the actual target pointer // Load MM5 with the bias value. MOV EAX, [Bias] DB $0F, $6E, $E8 /// MOVD MM5, EAX DB $0F, $61, $ED /// PUNPCKLWD MM5, MM5 DB $0F, $62, $ED /// PUNPCKLDQ MM5, MM5 // Load MM4 with 128 to allow for saturated biasing. MOV EAX, 128 DB $0F, $6E, $E0 /// MOVD MM4, EAX DB $0F, $61, $E4 /// PUNPCKLWD MM4, MM4 DB $0F, $62, $E4 /// PUNPCKLDQ MM4, MM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. DB $0F, $EF, $C0 /// PXOR MM0, MM0, clear source pixel register for unpacking DB $0F, $60, $06 /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, move higher bytes to lower bytes DB $0F, $EF, $C9 /// PXOR MM1, MM1, clear target pixel register for unpacking DB $0F, $60, $0F /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words DB $0F, $6F, $D1 /// MOVQ MM2, MM1, make a copy of the shifted values, we need them again DB $0F, $71, $D1, $08 /// PSRLW MM1, 8, move higher bytes to lower bytes // Load MM6 with the source alpha value (replicate it for every component). // Expand it to word size. DB $0F, $6F, $F0 /// MOVQ MM6, MM0 DB $0F, $69, $F6 /// PUNPCKHWD MM6, MM6 DB $0F, $6A, $F6 /// PUNPCKHDQ MM6, MM6 // calculation is: target = (alpha * (source - target) + 256 * target) / 256 DB $0F, $F9, $C1 /// PSUBW MM0, MM1, source - target DB $0F, $D5, $C6 /// PMULLW MM0, MM6, alpha * (source - target) DB $0F, $FD, $C2 /// PADDW MM0, MM2, add target (in shifted form) DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. DB $0F, $F9, $C4 /// PSUBW MM0, MM4 DB $0F, $ED, $C5 /// PADDSW MM0, MM5 DB $0F, $FD, $C4 /// PADDW MM0, MM4 DB $0F, $67, $C0 /// PACKUSWB MM0, MM0, convert words to bytes with saturation DB $0F, $7E, $07 /// MOVD [EDI], MM0, store the result @3: ADD ESI, 4 ADD EDI, 4 DEC ECX JNZ @1 POP EDI POP ESI {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure AlphaBlendLineMaster(Source, Destination: Pointer; Count: Integer; ConstantAlpha, Bias: Integer); // Blends a line of Count pixels from Source to Destination using the source pixel and a constant alpha value. // The layout of a pixel must be BGRA. // ConstantAlpha must be in the range 0..255. // Bias is an additional value which gets added to every component and must be in the range -128..127 asm {$ifdef CPU64} // RCX contains Source // RDX contains Destination // R8D contains Count // R9D contains ConstantAlpha // Bias is on the stack //.SAVENV XMM6 //todo see how implement in fpc AlphaBlendLineMaster // Load XMM3 with the constant alpha value (replicate it for every component). // Expand it to word size. MOVD XMM3, R9D // ConstantAlpha PUNPCKLWD XMM3, XMM3 PUNPCKLDQ XMM3, XMM3 // Load XMM5 with the bias value. MOV R10D, [Bias] MOVD XMM5, R10D PUNPCKLWD XMM5, XMM5 PUNPCKLDQ XMM5, XMM5 // Load XMM4 with 128 to allow for saturated biasing. MOV R10D, 128 MOVD XMM4, R10D PUNPCKLWD XMM4, XMM4 PUNPCKLDQ XMM4, XMM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. MOVD XMM1, DWORD PTR [RCX] // data is unaligned MOVD XMM2, DWORD PTR [RDX] // data is unaligned PXOR XMM0, XMM0 // clear source pixel register for unpacking PUNPCKLBW XMM0, XMM1{[RCX]} // unpack source pixel byte values into words PSRLW XMM0, 8 // move higher bytes to lower bytes PXOR XMM1, XMM1 // clear target pixel register for unpacking PUNPCKLBW XMM1, XMM2{[RCX]} // unpack target pixel byte values into words MOVQ XMM2, XMM1 // make a copy of the shifted values, we need them again PSRLW XMM1, 8 // move higher bytes to lower bytes // Load XMM6 with the source alpha value (replicate it for every component). // Expand it to word size. MOVQ XMM6, XMM0 PUNPCKHWD XMM6, XMM6 PUNPCKHDQ XMM6, XMM6 PMULLW XMM6, XMM3 // source alpha * master alpha PSRLW XMM6, 8 // divide by 256 // calculation is: target = (alpha * master alpha * (source - target) + 256 * target) / 256 PSUBW XMM0, XMM1 // source - target PMULLW XMM0, XMM6 // alpha * (source - target) PADDW XMM0, XMM2 // add target (in shifted form) PSRLW XMM0, 8 // divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. PSUBW XMM0, XMM4 PADDSW XMM0, XMM5 PADDW XMM0, XMM4 PACKUSWB XMM0, XMM0 // convert words to bytes with saturation MOVD DWORD PTR [RDX], XMM0 // store the result @3: ADD RCX, 4 ADD RDX, 4 DEC R8D JNZ @1 {$else} // EAX contains Source // EDX contains Destination // ECX contains Count // ConstantAlpha and Bias are on the stack PUSH ESI // save used registers PUSH EDI MOV ESI, EAX // ESI becomes the actual source pointer MOV EDI, EDX // EDI becomes the actual target pointer // Load MM6 with the constant alpha value (replicate it for every component). // Expand it to word size. MOV EAX, [ConstantAlpha] DB $0F, $6E, $F0 /// MOVD MM6, EAX DB $0F, $61, $F6 /// PUNPCKLWD MM6, MM6 DB $0F, $62, $F6 /// PUNPCKLDQ MM6, MM6 // Load MM5 with the bias value. MOV EAX, [Bias] DB $0F, $6E, $E8 /// MOVD MM5, EAX DB $0F, $61, $ED /// PUNPCKLWD MM5, MM5 DB $0F, $62, $ED /// PUNPCKLDQ MM5, MM5 // Load MM4 with 128 to allow for saturated biasing. MOV EAX, 128 DB $0F, $6E, $E0 /// MOVD MM4, EAX DB $0F, $61, $E4 /// PUNPCKLWD MM4, MM4 DB $0F, $62, $E4 /// PUNPCKLDQ MM4, MM4 @1: // The pixel loop calculates an entire pixel in one run. // Note: The pixel byte values are expanded into the higher bytes of a word due // to the way unpacking works. We compensate for this with an extra shift. DB $0F, $EF, $C0 /// PXOR MM0, MM0, clear source pixel register for unpacking DB $0F, $60, $06 /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, move higher bytes to lower bytes DB $0F, $EF, $C9 /// PXOR MM1, MM1, clear target pixel register for unpacking DB $0F, $60, $0F /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words DB $0F, $6F, $D1 /// MOVQ MM2, MM1, make a copy of the shifted values, we need them again DB $0F, $71, $D1, $08 /// PSRLW MM1, 8, move higher bytes to lower bytes // Load MM7 with the source alpha value (replicate it for every component). // Expand it to word size. DB $0F, $6F, $F8 /// MOVQ MM7, MM0 DB $0F, $69, $FF /// PUNPCKHWD MM7, MM7 DB $0F, $6A, $FF /// PUNPCKHDQ MM7, MM7 DB $0F, $D5, $FE /// PMULLW MM7, MM6, source alpha * master alpha DB $0F, $71, $D7, $08 /// PSRLW MM7, 8, divide by 256 // calculation is: target = (alpha * master alpha * (source - target) + 256 * target) / 256 DB $0F, $F9, $C1 /// PSUBW MM0, MM1, source - target DB $0F, $D5, $C7 /// PMULLW MM0, MM7, alpha * (source - target) DB $0F, $FD, $C2 /// PADDW MM0, MM2, add target (in shifted form) DB $0F, $71, $D0, $08 /// PSRLW MM0, 8, divide by 256 // Bias is accounted for by conversion of range 0..255 to -128..127, // doing a saturated add and convert back to 0..255. DB $0F, $F9, $C4 /// PSUBW MM0, MM4 DB $0F, $ED, $C5 /// PADDSW MM0, MM5 DB $0F, $FD, $C4 /// PADDW MM0, MM4 DB $0F, $67, $C0 /// PACKUSWB MM0, MM0, convert words to bytes with saturation DB $0F, $7E, $07 /// MOVD [EDI], MM0, store the result @3: ADD ESI, 4 ADD EDI, 4 DEC ECX JNZ @1 POP EDI POP ESI {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure AlphaBlendLineMasterAndColor(Destination: Pointer; Count: Integer; ConstantAlpha, Color: Integer); // Blends a line of Count pixels in Destination against the given color using a constant alpha value. // The layout of a pixel must be BGRA and Color must be rrggbb00 (as stored by a COLORREF). // ConstantAlpha must be in the range 0..255. asm {$ifdef CPU64} // RCX contains Destination // EDX contains Count // R8D contains ConstantAlpha // R9D contains Color //.NOFRAME // The used formula is: target = (alpha * color + (256 - alpha) * target) / 256. // alpha * color (factor 1) and 256 - alpha (factor 2) are constant values which can be calculated in advance. // The remaining calculation is therefore: target = (F1 + F2 * target) / 256 // Load XMM3 with the constant alpha value (replicate it for every component). // Expand it to word size. (Every calculation here works on word sized operands.) MOVD XMM3, R8D // ConstantAlpha PUNPCKLWD XMM3, XMM3 PUNPCKLDQ XMM3, XMM3 // Calculate factor 2. MOV R10D, $100 MOVD XMM2, R10D PUNPCKLWD XMM2, XMM2 PUNPCKLDQ XMM2, XMM2 PSUBW XMM2, XMM3 // XMM2 contains now: 255 - alpha = F2 // Now calculate factor 1. Alpha is still in XMM3, but the r and b components of Color must be swapped. BSWAP R9D // Color ROR R9D, 8 MOVD XMM1, R9D // Load the color and convert to word sized values. PXOR XMM4, XMM4 PUNPCKLBW XMM1, XMM4 PMULLW XMM1, XMM3 // XMM1 contains now: color * alpha = F1 @1: // The pixel loop calculates an entire pixel in one run. MOVD XMM0, DWORD PTR [RCX] PUNPCKLBW XMM0, XMM4 PMULLW XMM0, XMM2 // calculate F1 + F2 * target PADDW XMM0, XMM1 PSRLW XMM0, 8 // divide by 256 PACKUSWB XMM0, XMM0 // convert words to bytes with saturation MOVD DWORD PTR [RCX], XMM0 // store the result ADD RCX, 4 DEC EDX JNZ @1 {$else} // EAX contains Destination // EDX contains Count // ECX contains ConstantAlpha // Color is passed on the stack // The used formula is: target = (alpha * color + (256 - alpha) * target) / 256. // alpha * color (factor 1) and 256 - alpha (factor 2) are constant values which can be calculated in advance. // The remaining calculation is therefore: target = (F1 + F2 * target) / 256 // Load MM3 with the constant alpha value (replicate it for every component). // Expand it to word size. (Every calculation here works on word sized operands.) DB $0F, $6E, $D9 /// MOVD MM3, ECX DB $0F, $61, $DB /// PUNPCKLWD MM3, MM3 DB $0F, $62, $DB /// PUNPCKLDQ MM3, MM3 // Calculate factor 2. MOV ECX, $100 DB $0F, $6E, $D1 /// MOVD MM2, ECX DB $0F, $61, $D2 /// PUNPCKLWD MM2, MM2 DB $0F, $62, $D2 /// PUNPCKLDQ MM2, MM2 DB $0F, $F9, $D3 /// PSUBW MM2, MM3 // MM2 contains now: 255 - alpha = F2 // Now calculate factor 1. Alpha is still in MM3, but the r and b components of Color must be swapped. MOV ECX, [Color] BSWAP ECX ROR ECX, 8 DB $0F, $6E, $C9 /// MOVD MM1, ECX // Load the color and convert to word sized values. DB $0F, $EF, $E4 /// PXOR MM4, MM4 DB $0F, $60, $CC /// PUNPCKLBW MM1, MM4 DB $0F, $D5, $CB /// PMULLW MM1, MM3 // MM1 contains now: color * alpha = F1 @1: // The pixel loop calculates an entire pixel in one run. DB $0F, $6E, $00 /// MOVD MM0, [EAX] DB $0F, $60, $C4 /// PUNPCKLBW MM0, MM4 DB $0F, $D5, $C2 /// PMULLW MM0, MM2 // calculate F1 + F2 * target DB $0F, $FD, $C1 /// PADDW MM0, MM1 DB $0F, $71, $D0, $08 /// PSRLW MM0, 8 // divide by 256 DB $0F, $67, $C0 /// PACKUSWB MM0, MM0 // convert words to bytes with saturation DB $0F, $7E, $00 /// MOVD [EAX], MM0 // store the result ADD EAX, 4 DEC EDX JNZ @1 {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure EMMS; // Reset MMX state to use the FPU for other tasks again. {$ifdef CPU64} inline; begin end; {$else} asm DB $0F, $77 /// EMMS end; {$endif} //---------------------------------------------------------------------------------------------------------------------- function GetBitmapBitsFromDeviceContext(DC: HDC; out Width, Height: Integer): Pointer; // Helper function used to retrieve the bitmap selected into the given device context. If there is a bitmap then // the function will return a pointer to its bits otherwise nil is returned. // Additionally the dimensions of the bitmap are returned. var Bitmap: HBITMAP; DIB: TDIBSection; begin Result := nil; Width := 0; Height := 0; Bitmap := GetCurrentObject(DC, OBJ_BITMAP); if Bitmap <> 0 then begin if GetObject(Bitmap, SizeOf(DIB), @DIB) = SizeOf(DIB) then begin Assert(DIB.dsBm.bmPlanes * DIB.dsBm.bmBitsPixel = 32, 'Alpha blending error: bitmap must use 32 bpp.'); Result := DIB.dsBm.bmBits; Width := DIB.dsBmih.biWidth; Height := DIB.dsBmih.biHeight; end; end; Assert(Result <> nil, 'Alpha blending DC error: no bitmap available.'); end; //---------------------------------------------------------------------------------------------------------------------- function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer; var DIB: TDIBSection; begin Result := nil; if Bitmap <> 0 then begin if GetObject(Bitmap, SizeOf(DIB), @DIB) = SizeOf(DIB) then begin Assert(DIB.dsBm.bmPlanes * DIB.dsBm.bmBitsPixel = 32, 'Alpha blending error: bitmap must use 32 bpp.'); Result := DIB.dsBm.bmBits; end; end; end; function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer; // Helper function to calculate the start address for the given row. begin //todo: Height is always > 0 in LCL { if Height > 0 then // bottom-up DIB Row := Height - Row - 1; } // Return DWORD aligned address of the requested scanline. Result := Bits + Row * ((Width * 32 + 31) and not 31) div 8; end; //---------------------------------------------------------------------------------------------------------------------- procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer); // Optimized alpha blend procedure using MMX instructions to perform as quick as possible. // For this procedure to work properly it is important that both source and target bitmap use the 32 bit color format. // R describes the source rectangle to work on. // Target is the place (upper left corner) in the target bitmap where to blend to. Note that source width + X offset // must be less or equal to the target width. Similar for the height. // If Mode is bmConstantAlpha then the blend operation uses the given ConstantAlpha value for all pixels. // If Mode is bmPerPixelAlpha then each pixel is blended using its individual alpha value (the alpha value of the source). // If Mode is bmMasterAlpha then each pixel is blended using its individual alpha value multiplied by ConstantAlpha. // If Mode is bmConstantAlphaAndColor then each destination pixel is blended using ConstantAlpha but also a constant // color which will be obtained from Bias. In this case no offset value is added, otherwise Bias is used as offset. // Blending of a color into target only (bmConstantAlphaAndColor) ignores Source (the DC) and Target (the position). // CAUTION: This procedure does not check whether MMX instructions are actually available! Call it only if MMX is really // usable. var Y: Integer; SourceRun, TargetRun: PByte; SourceBits, DestBits: Pointer; SourceWidth, SourceHeight, DestWidth, DestHeight: Integer; begin if not IsRectEmpty(R) then begin {$ifdef CPU64} //avoid MasterAlpha due to incomplete AlphaBlendLineMaster. See comment in procedure if Mode = bmMasterAlpha then Mode := bmConstantAlpha; {$endif} // Note: it is tempting to optimize the special cases for constant alpha 0 and 255 by just ignoring soure // (alpha = 0) or simply do a blit (alpha = 255). But this does not take the bias into account. case Mode of bmConstantAlpha: begin // Get a pointer to the bitmap bits for the source and target device contexts. // Note: this supposes that both contexts do actually have bitmaps assigned! SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight); DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight); if Assigned(SourceBits) and Assigned(DestBits) then begin for Y := 0 to R.Bottom - R.Top - 1 do begin SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top); Inc(SourceRun, 4 * R.Left); TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y); Inc(TargetRun, 4 * Target.X); AlphaBlendLineConstant(SourceRun, TargetRun, R.Right - R.Left, ConstantAlpha, Bias); end; end; EMMS; end; bmPerPixelAlpha: begin SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight); DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight); if Assigned(SourceBits) and Assigned(DestBits) then begin for Y := 0 to R.Bottom - R.Top - 1 do begin SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top); Inc(SourceRun, 4 * R.Left); TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y); Inc(TargetRun, 4 * Target.X); AlphaBlendLinePerPixel(SourceRun, TargetRun, R.Right - R.Left, Bias); end; end; EMMS; end; bmMasterAlpha: begin SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight); DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight); if Assigned(SourceBits) and Assigned(DestBits) then begin for Y := 0 to R.Bottom - R.Top - 1 do begin SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top); Inc(SourceRun, 4 * Target.X); TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y); AlphaBlendLineMaster(SourceRun, TargetRun, R.Right - R.Left, ConstantAlpha, Bias); end; end; EMMS; end; bmConstantAlphaAndColor: begin // Source is ignored since there is a constant color value. DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight); if Assigned(DestBits) then begin for Y := 0 to R.Bottom - R.Top - 1 do begin TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + R.Top); Inc(TargetRun, 4 * R.Left); AlphaBlendLineMasterAndColor(TargetRun, R.Right - R.Left, ConstantAlpha, Bias); end; end; EMMS; end; end; end; end; doublecmd-0.8.2/components/virtualtreeview/include/intf/carbon/0000775000175000017500000000000013244011205023752 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/include/intf/carbon/vtvdragmanager.inc0000664000175000017500000000003612014201074027453 0ustar alexxalexx {$i ../dummydragmanager.inc} doublecmd-0.8.2/components/virtualtreeview/include/intf/carbon/olemethods.inc0000664000175000017500000000003512014201074026605 0ustar alexxalexx {$i ../dummyolemethods.inc} doublecmd-0.8.2/components/virtualtreeview/include/intf/carbon/vtgraphicsi.inc0000664000175000017500000000115612014201074026772 0ustar alexxalexx//todo: properly implement procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer); begin case Mode of bmConstantAlpha, bmPerPixelAlpha, bmMasterAlpha, bmConstantAlphaAndColor: begin BitBlt(Destination, Target.X, Target.Y, R.Right - R.Left, R.Bottom - R.Top, Source, R.Left, R.Right, SRCCOPY); end; end; end; function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer; begin Result := nil; end; function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer; begin Result := nil; end;doublecmd-0.8.2/components/virtualtreeview/ideicons.lrs0000664000175000017500000000661711727533326022475 0ustar alexxalexxLazarusResources.Add('tvirtualdrawtree','XPM',[ '/* XPM */'#10'static char * tvirtualdrawtree_xpm[] = {'#10'"24 24 8 1",'#10 +'".'#9'c #000000",'#10'"+'#9'c None",'#10'"@'#9'c #808000",'#10'"#'#9'c #20A' +'080",'#10'"$'#9'c #808080",'#10'"%'#9'c #C0A000",'#10'"&'#9'c #C0C0C0",'#10 +'"*'#9'c #FFFFFF",'#10'"++++++..++++++++++++++++",'#10'"+++++.&&............' +'.+++",'#10'"++++.***&&&&&&&&&&$$@.++",'#10'"++++.************@$$$.++",'#10 +'"+++.************@$$$$.++",'#10'"++++...@********.$$$$.++",'#10'"+++++++...' +'......$$$$@+++",'#10'"+++++++.$$$$$$$$***$.+++",'#10'"+++++++.*******%***&.' +'+++",'#10'"+++++++.*.****%%%**$.+++",'#10'"+++++++.*...*%%%%%*.++++",'#10'"' +'+++++++.*.**%%%%%%%.++++",'#10'"++++++.**.***####**.++++",'#10'"+++++.$**.*' +'*######*.++++",'#10'"+++++.&**..*######*.++++",'#10'"+++++.******######*.++' +'++",'#10'"+++++.*******####**&.+++",'#10'"+...+.***.....******.+++",'#10'"+' +'.&&@....&&&&&.****$.+++",'#10'"+.&&&&&&&&&&&&&.**&.++++",'#10'"++.$&&&&&&&&' +'&&&.&&&.++++",'#10'"++.$$$$$$$$$$$$$.&.+++++",'#10'"+++...............+++++' +'+",'#10'"++++++++++++++++++++++++"};'#10 ]); LazarusResources.Add('tvirtualstringtree','XPM',[ '/* XPM */'#10'static char * tvirtualstringtree_xpm[] = {'#10'"24 24 8 1",'#10 +'".'#9'c #000000",'#10'"+'#9'c None",'#10'"@'#9'c #808000",'#10'"#'#9'c #20A' +'080",'#10'"$'#9'c #808080",'#10'"%'#9'c #C0A000",'#10'"&'#9'c #C0C0C0",'#10 +'"*'#9'c #FFFFFF",'#10'"++++++..++++++++++++++++",'#10'"+++++.&&............' +'.+++",'#10'"++++.***&&&&&&&&&&$$@.++",'#10'"++++.************@$$$.++",'#10 +'"+++.************@$$$$.++",'#10'"++++...@********.$$$$.++",'#10'"+++++++...' +'......$$$$@+++",'#10'"+++++++.$$$$$$$$***$.+++",'#10'"+++++++.***********&.' +'+++",'#10'"+++++++.*.**......*$.+++",'#10'"+++++++.*....%%%%.*.++++",'#10'"' +'+++++++.*.**......*.++++",'#10'"++++++.**.*********.++++",'#10'"+++++.$**.*' +'*......*.++++",'#10'"+++++.&**....####.*.++++",'#10'"+++++.******......*.++' +'++",'#10'"+++++.*************&.+++",'#10'"+...+.***.....******.+++",'#10'"+' +'.&&@....&&&&&.****$.+++",'#10'"+.&&&&&&&&&&&&&.**&.++++",'#10'"++.$&&&&&&&&' +'&&&.&&&.++++",'#10'"++.$$$$$$$$$$$$$.&.+++++",'#10'"+++...............+++++' +'+",'#10'"++++++++++++++++++++++++"};'#10 ]); LazarusResources.Add('tvtheaderpopupmenu','XPM',[ '/* XPM */'#10'static char * tvtheaderpopupmenu_xpm[] = {'#10'"24 24 7 1",'#10 +'".'#9'c #000000",'#10'"+'#9'c #000080",'#10'"@'#9'c None",'#10'"#'#9'c #808' +'000",'#10'"$'#9'c #808080",'#10'"%'#9'c #C0C0C0",'#10'"&'#9'c #FFFFFF",'#10 +'"@@@@@@..@@@@@@@@@@@@@@@@",'#10'"@@@@@.%%.............@@@",'#10'"@@@@.&&&%%' +'%%%%%%%%$$#.@@",'#10'"@@@@.&&&&&&&&&&&&#$$$.@@",'#10'"@@@.&&&&&&&&&&&&#$$$$' +'.@@",'#10'"@@@@...#&&&&&&&&.$$$$.@@",'#10'"@@@@@@@.........$$$$#@@@",'#10'"' +'@@@@@@@.$$$$$$$$&&&$.@@@",'#10'"@@@@@@@.$&&&&&&.&&&%.@@@",'#10'"@@@@@@@.$&+' +'++&&.&&&$.@@@",'#10'"@@@@@@@.$&&&&&&.&&&.@@@@",'#10'"@@@@@@@.$&+++++.&&&.@@' +'@@",'#10'"@@@@@@.&$+&&&+&+&&&.@@@@",'#10'"@@@@@.$&$&++++&&+&&.@@@@",'#10'"@' +'@@@@.%&$&&&&+&&&+&.@@@@",'#10'"@@@@@.&&$....+&&&&+.@@@@",'#10'"@@@@@.&&&&&&' +'&+&&&++++@@@",'#10'"@...@.&&&....+&&&&+&.@@@",'#10'"@.%%#....%%%%+&++&&+.@@' +'@",'#10'"@.%%%%%%%%%%%++$+&&+@@@@",'#10'"@@.$%%%%%%%%%+%.%+&&+@@@",'#10'"@@' +'.$$$$$$$$$$$$$.+&&+@@@",'#10'"@@@...............++@@@@",'#10'"@@@@@@@@@@@@@' +'@@@@@@@@@@@"};'#10 ]); doublecmd-0.8.2/components/virtualtreeview/lclconstants.inc0000664000175000017500000000750112014201074023327 0ustar alexxalexx// Message constants that are not defined in LCL WM_APP = $8000; // ExtTextOut Options ETO_RTLREADING = 128; //DrawText options DT_RTLREADING = 131072; // Clipboard constants CF_BITMAP = 2; CF_DIB = 8; CF_PALETTE = 9; CF_ENHMETAFILE = 14; CF_METAFILEPICT = 3; CF_OEMTEXT = 7; CF_TEXT = 1; CF_UNICODETEXT = 13; CF_DIF = 5; CF_DSPBITMAP = 130; CF_DSPENHMETAFILE = 142; CF_DSPMETAFILEPICT = 131; CF_DSPTEXT = 129; CF_GDIOBJFIRST = 768; CF_GDIOBJLAST = 1023; CF_HDROP = 15; CF_LOCALE = 16; CF_OWNERDISPLAY = 128; CF_PENDATA = 10; CF_PRIVATEFIRST = 512; CF_PRIVATELAST = 767; CF_RIFF = 11; CF_SYLK = 4; CF_WAVE = 12; CF_TIFF = 6; CF_MAX = 17; // Win32 colors CLR_NONE = $ffffffff; CLR_DEFAULT = $ff000000; //DrawFrameControl constants DFCS_HOT = $1000; //Thread support //This values is for win32, how about others?? INFINITE = $FFFFFFFF; //OLE Support E_OUTOFMEMORY = HRESULT($8007000E); E_INVALIDARG = HRESULT($80070057); E_NOINTERFACE = HRESULT($80004002); E_POINTER = HRESULT($80004003); E_HANDLE = HRESULT($80070006); E_ABORT = HRESULT($80004004); E_FAIL = HRESULT($80004005); E_ACCESSDENIED = HRESULT($80070005); DV_E_TYMED = HRESULT($80040069); DV_E_CLIPFORMAT = HRESULT($8004006A); DV_E_LINDEX = HRESULT($80040068); DV_E_DVASPECT = HRESULT($8004006B); OLE_E_ADVISENOTSUPPORTED = HRESULT($80040003); OLE_S_USEREG = HRESULT($00040000); DATA_S_SAMEFORMATETC = HRESULT($00040130); DRAGDROP_S_DROP = HRESULT($00040100); DRAGDROP_S_CANCEL = HRESULT($00040101); DRAGDROP_S_USEDEFAULTCURSORS = HRESULT($00040102); NOERROR = 0; SPI_GETDRAGFULLWINDOWS = 38; // windows management SWP_HIDEWINDOW = 128; SWP_SHOWWINDOW = 64; //Imagelists ILD_NORMAL = 0; // Set WindowPos SWP_FRAMECHANGED = 32; SWP_NOOWNERZORDER = 512; SWP_NOSENDCHANGING = 1024; { RedrawWindow } RDW_ERASE = 4; RDW_FRAME = 1024; RDW_INTERNALPAINT = 2; RDW_INVALIDATE = 1; RDW_NOERASE = 32; RDW_NOFRAME = 2048; RDW_NOINTERNALPAINT = 16; RDW_VALIDATE = 8; RDW_ERASENOW = 512; RDW_UPDATENOW = 256; RDW_ALLCHILDREN = 128; RDW_NOCHILDREN = 64; //SetRedraw WM_SETREDRAW = 11; //Dummy CM_PARENTFONTCHANGED = 1999; //Wheel WHEEL_DELTA = 120; WHEEL_PAGESCROLL = High(DWord); SPI_GETWHEELSCROLLLINES = 104; //MultiByte MB_USEGLYPHCHARS = 4; LOCALE_IDEFAULTANSICODEPAGE = 4100; //Image list ILD_TRANSPARENT = $00000001; ILD_MASK = $00000010; ILD_IMAGE = $00000020; ILD_ROP = $00000040; ILD_BLEND25 = $00000002; ILD_BLEND50 = $00000004; ILD_OVERLAYMASK = $00000F00; { GetDCEx } DCX_WINDOW = $1; DCX_CACHE = $2; DCX_PARENTCLIP = $20; DCX_CLIPSIBLINGS = $10; DCX_CLIPCHILDREN = $8; DCX_NORESETATTRS = $4; DCX_LOCKWINDOWUPDATE = $400; DCX_EXCLUDERGN = $40; DCX_INTERSECTRGN = $80; DCX_VALIDATE = $200000; SCantWriteResourceStreamError = 'CantWriteResourceStreamError'; //command EN_UPDATE = 1024; ES_AUTOHSCROLL = $80; ES_AUTOVSCROLL = $40; ES_CENTER = $1; ES_LEFT = 0; ES_LOWERCASE = $10; ES_MULTILINE = $4; ES_NOHIDESEL = $100; EM_SETRECTNP = 180; DT_END_ELLIPSIS = 32768; doublecmd-0.8.2/components/virtualtreeview/doublecmd.diff0000664000175000017500000003265312203745772022745 0ustar alexxalexxIndex: VTConfig.inc =================================================================== --- VTConfig.inc (revision 2731) +++ VTConfig.inc (working copy) @@ -22,7 +22,7 @@ //Lazarus port options -{$define EnableOLE} +{.$define EnableOLE} {.$define EnableNativeTVM} {.$define EnablePrint} {.$define EnableNCFunctions} @@ -42,7 +42,7 @@ //under linux the performance is poor with threading enabled {$ifdef Windows} - {$define EnableThreadSupport} + {.$define EnableThreadSupport} {$endif} {$ifdef CPU64} {$define PACKARRAYPASCAL} Index: VirtualTrees.pas =================================================================== --- VirtualTrees.pas (revision 2731) +++ VirtualTrees.pas (working copy) @@ -745,6 +745,7 @@ toAutoHideButtons, // Node buttons are hidden when there are child nodes, but all are invisible. toAutoDeleteMovedNodes, // Delete nodes which where moved in a drag operation (if not directed otherwise). toDisableAutoscrollOnFocus, // Disable scrolling a node or column into view if it gets focused. + toDisableAutoscrollHorizontal, // Only autoscroll on focus vertically never horizontally toAutoChangeScale, // Change default node height automatically if the system's font scale is set to big fonts. toAutoFreeOnCollapse, // Frees any child node after a node has been collapsed (HasChildren flag stays there). toDisableAutoscrollOnEdit, // Do not center a node horizontally when it is edited. @@ -2018,7 +2019,7 @@ var Allowed: Boolean) of object; TVTDragOverEvent = procedure(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState; const Pt: TPoint; Mode: TDropMode; var Effect: LongWord; var Accept: Boolean) of object; - TVTDragDropEvent = procedure(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject; + TVTDragDropEvent = procedure(Sender: TBaseVirtualTree; Source: TObject; {DataObject: IDataObject;} Formats: TFormatArray; Shift: TShiftState; const Pt: TPoint; var Effect: LongWord; Mode: TDropMode) of object; TVTRenderOLEDataEvent = procedure(Sender: TBaseVirtualTree; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean; var Result: HRESULT) of object; @@ -2543,6 +2544,7 @@ procedure BeginOperation; function CalculateSelectionRect(X, Y: Integer): Boolean; virtual; function CanAutoScroll: Boolean; virtual; + function CanScroll(const ClientMousePos: TPoint): Boolean; virtual; function CanShowDragImage: Boolean; virtual; procedure Change(Node: PVirtualNode); virtual; procedure ChangeScale(M, D: Integer); override; @@ -3015,6 +3017,7 @@ function GetNextNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextSibling(Node: PVirtualNode): PVirtualNode; + function GetNextSiblingNoInit(Node: PVirtualNode): PVirtualNode; function GetNextVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetNextVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetNextVisibleSibling(Node: PVirtualNode): PVirtualNode; @@ -3033,6 +3036,7 @@ function GetPreviousNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetPreviousSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetPreviousSibling(Node: PVirtualNode): PVirtualNode; + function GetPreviousSiblingNoInit(Node: PVirtualNode): PVirtualNode; function GetPreviousVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetPreviousVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetPreviousVisibleSibling(Node: PVirtualNode): PVirtualNode; @@ -13858,7 +13862,7 @@ FFocusedColumn := Value; if Assigned(FFocusedNode) and not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) then begin - if ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, True) then + if ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions)) then InvalidateNode(FFocusedNode); end; @@ -15036,7 +15040,8 @@ LeaveStates := [tsHint]; if [tsWheelPanning, tsWheelScrolling] * FStates = [] then begin - KillTimer(Handle, ScrollTimer); + if HandleAllocated then + KillTimer(Handle, ScrollTimer); LeaveStates := LeaveStates + [tsScrollPending, tsScrolling]; end; DoStateChange([], LeaveStates); @@ -15660,7 +15665,7 @@ if (Shift = [ssCtrlOS]) and not ActAsGrid then begin ScrollIntoView(Node, toCenterScrollIntoView in FOptions.SelectionOptions, - not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions)); + not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions)); if (CharCode = VK_HOME) and not UseRightToLeftAlignment then SetOffsetX(0) else @@ -17879,7 +17884,7 @@ if hoVisible in FHeader.FOptions then Dec(Y, FHeader.Height); - if (Y > 0) and (Y < Integer(FDefaultNodeHeight)) and (FOffsetY <> 0) then + if (Y < Integer(FDefaultNodeHeight)) and (FOffsetY <> 0) then Include(Result, sdUp); //todo: probably the code below is bug due to poor timeGetTime implementation @@ -18424,7 +18429,7 @@ begin if Assigned(FOnDragDrop) then - FOnDragDrop(Self, Source, DataObject, Formats, Shift, Pt, Effect, Mode); + FOnDragDrop(Self, Source, {DataObject, }Formats, Shift, Pt, Effect, Mode); end; //---------------------------------------------------------------------------------------------------------------------- @@ -18576,7 +18581,7 @@ InvalidateNode(FFocusedNode); if (FUpdateCount = 0) and not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) then ScrollIntoView(FFocusedNode, (toCenterScrollIntoView in FOptions.SelectionOptions) and - (MouseButtonDown * FStates = []), True); + (MouseButtonDown * FStates = []), not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions)); end; // Reset range anchor if necessary. @@ -19392,7 +19397,7 @@ ClientP := ScreenToClient(P); Panning := [tsWheelPanning, tsWheelScrolling] * FStates <> []; - if IsMouseSelecting or InRect or Panning then + if IsMouseSelecting or InRect or Panning or CanScroll(ClientP) then begin DeltaX := 0; DeltaY := 0; @@ -21111,7 +21116,7 @@ if NewNode or NewColumn then begin ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, - not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions)); + not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions)); DoFocusChange(FFocusedNode, FFocusedColumn); end; end; @@ -21809,7 +21814,7 @@ begin if Y < 0 then - Y := 0; + Exit(nil); AbsolutePos := Y; if Relative then @@ -24335,6 +24340,12 @@ DoCanEdit(Node, Column, Result); end; +function TBaseVirtualTree.CanScroll(const ClientMousePos: TPoint): Boolean; +// Determines whether auto scrolling can occur based on current mouse cursor position. +begin + Result := False; +end; + //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.Clear; @@ -26446,6 +26457,22 @@ //---------------------------------------------------------------------------------------------------------------------- +function TBaseVirtualTree.GetNextSiblingNoInit(Node: PVirtualNode): PVirtualNode; + +// Returns the next sibling of Node performing no initialization. + +begin + Result := Node; + if Assigned(Result) then + begin + Assert(Result <> FRoot, 'Node must not be the hidden root node.'); + + Result := Result.NextSibling; + end; +end; + +//---------------------------------------------------------------------------------------------------------------------- + function TBaseVirtualTree.GetNextVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; // Returns next node in tree, with regard to Node, which is visible. @@ -27064,6 +27091,22 @@ //---------------------------------------------------------------------------------------------------------------------- +function TBaseVirtualTree.GetPreviousSiblingNoInit(Node: PVirtualNode): PVirtualNode; + +// Get next sibling of Node, performes no initialization. + +begin + Result := Node; + if Assigned(Result) then + begin + Assert(Result <> FRoot, 'Node must not be the hidden root node.'); + + Result := Result.PrevSibling; + end; +end; + +//---------------------------------------------------------------------------------------------------------------------- + function TBaseVirtualTree.GetPreviousVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; // Returns the previous node in tree, with regard to Node, which is visible. @@ -29252,6 +29295,7 @@ HScrollBarVisible: Boolean; ScrolledVertically, ScrolledHorizontally: Boolean; + OffY, OffYM: Integer; begin //todo: minimize calls to ClientHeight and ClientWidth @@ -29296,7 +29340,14 @@ if Center then SetOffsetY(FOffsetY - R.Bottom + ClientHeight div 2) else - SetOffsetY(FOffsetY - R.Bottom + ClientHeight); + begin + // Leave additional space at the bottom to have scrollrect start with full row. + OffY := FOffsetY - R.Bottom + ClientHeight; + OffYM := OffY mod DefaultNodeHeight; + if OffYM <> 0 then + OffY := OffY - (DefaultNodeHeight + OffYM); + SetOffsetY(OffY); + end; // When scrolling up and the horizontal scroll appears because of the operation // then we have to move up the node the horizontal scrollbar's height too // in order to avoid that the scroll bar hides the node which we wanted to have in view. @@ -29350,10 +29401,13 @@ end else begin - if ColumnRight > ClientWidth then - NewOffset := FEffectiveOffsetX + (ColumnRight - ClientWidth) - else if ColumnLeft < Header.Columns.GetVisibleFixedWidth then - NewOffset := FEffectiveOffsetX - (Header.Columns.GetVisibleFixedWidth - ColumnLeft); + if FHeader.Columns.Count > 1 then + begin + if ColumnRight > ClientWidth then + NewOffset := FEffectiveOffsetX + (ColumnRight - ClientWidth) + else if ColumnLeft < Header.Columns.GetVisibleFixedWidth then + NewOffset := FEffectiveOffsetX - (Header.Columns.GetVisibleFixedWidth - ColumnLeft); + end; if NewOffset <> FEffectiveOffsetX then begin if UseRightToLeftAlignment then Index: include/intf/qt/vtgraphicsi.inc =================================================================== --- include/intf/qt/vtgraphicsi.inc (revision 2731) +++ include/intf/qt/vtgraphicsi.inc (working copy) @@ -284,7 +284,7 @@ // Load MM4 with 128 to allow for saturated biasing. MOV EAX, 128 - DB $0F, $6E, AlphaBlendLineConstant$E0 /// MOVD MM4, EAX + DB $0F, $6E, $E0 /// MOVD MM4, EAX DB $0F, $61, $E4 /// PUNPCKLWD MM4, MM4 DB $0F, $62, $E4 /// PUNPCKLDQ MM4, MM4 Index: units/carbon/fakemmsystem.pas =================================================================== --- units/carbon/fakemmsystem.pas (revision 2731) +++ units/carbon/fakemmsystem.pas (working copy) @@ -15,6 +15,9 @@ implementation +uses + LCLIntf; + function timeBeginPeriod(x1: DWord): DWord; begin @@ -26,12 +29,8 @@ end; function timeGetTime: DWORD; -var - ATime: TSystemTime; begin - //todo: properly implement - GetLocalTime(ATime); - Result := ATime.MilliSecond; + Result := GetTickCount; end; end. Index: units/qt/fakemmsystem.pas =================================================================== --- units/qt/fakemmsystem.pas (revision 2731) +++ units/qt/fakemmsystem.pas (working copy) @@ -15,6 +15,9 @@ implementation +uses + LCLIntf; + function timeBeginPeriod(x1: DWord): DWord; begin @@ -26,12 +29,8 @@ end; function timeGetTime: DWORD; -var - ATime: TSystemTime; begin - //todo: properly implement - GetLocalTime(ATime); - Result := ATime.MilliSecond; + Result := GetTickCount; end; end. Index: units/win32/virtualpanningwindow.pas =================================================================== --- units/win32/virtualpanningwindow.pas (revision 2731) +++ units/win32/virtualpanningwindow.pas (working copy) @@ -41,9 +41,10 @@ PanningObject:=TVirtualPanningWindow(GetWindowLongPtrW(Window,GWL_USERDATA)); if Assigned(PanningObject) then PanningObject.HandlePaintMessage; + Result := 0; end else - DefWindowProc(Window,Msg,WPara,LPara); + Result := DefWindowProc(Window,Msg,WPara,LPara); end; var @@ -87,8 +88,7 @@ with Position do FHandle := CreateWindowEx(WS_EX_TOOLWINDOW, PanningWindowClass.lpszClassName, nil, WS_POPUP, X - 16, Y - 16, 32, 32, OwnerHandle, 0, HInstance, nil); - //todo use SetWindowLongPtr later - SetWindowLong(FHandle,GWL_USERDATA,PtrInt(Self)); + SetWindowLongPtr(FHandle,GWL_USERDATA,LONG_PTR(Self)); FImage := TBitmap.Create; end; doublecmd-0.8.2/components/virtualtreeview/virtualtreeview_package.lpk0000664000175000017500000000455512140233030025554 0ustar alexxalexx doublecmd-0.8.2/components/virtualtreeview/VTConfig.inc0000664000175000017500000000334612140233030022277 0ustar alexxalexx// Configuration file for VirtualTrees.pas (see www.soft-gems.net). // // The content of this file is public domain. You may do with it whatever you like, provided the header stays fully intact // in all version and derivative work. // // The original code is VTConfig.inc, released October 5, 2004. // // The initial developer of the original code is Mike Lischke (public@soft-gems.net, www.soft-gems.net). //---------------------------------------------------------------------------------------------------------------------- {.$define UseFlatScrollbars} {.$define ReverseFullExpandHotKey} // Used to define Ctrl+'+' instead of Ctrl+Shift+'+' for full expand (and similar for collapsing). // Enable this switch for Windows XP theme support. If you compile with Delphi 6 or lower you must download and install // the Soft Gems Theme Manager package. {.$define ThemeSupport} // Virtual Treeview can use a tiny but very effective local memory manager for node allocation. // The local memory manager was implemented by David Clark from Caelo Software Inc. // See below for more info about it. {.$define UseLocalMemoryManager} //Lazarus port options {.$define EnableOLE} {.$define EnableNativeTVM} {.$define EnablePrint} {.$define EnableNCFunctions} {$define EnableAdvancedGraphics} {$define EnableAlphaBlend} {.$define EnableAccessible} {$define ThemeSupport} {$if defined(LCLWin32) or defined(LCLWinCE)} {$define LCLWin} {$endif} {.$define DEBUG_VTV} {$define USE_DELPHICOMPAT} //since {$if not defined(USE_DELPHICOMPAT) and not defined(LCLWin)} {$define INCOMPLETE_WINAPI} {$endif} //under linux the performance is poor with threading enabled {$ifdef Windows} {.$define EnableThreadSupport} {$endif} {$ifdef CPU64} {$define PACKARRAYPASCAL} {$endif} doublecmd-0.8.2/components/virtualtreeview/VTAccessibility.pas0000664000175000017500000006344012014201074023677 0ustar alexxalexxunit VTAccessibility; // This unit implements iAccessible interfaces for the VirtualTree visual components // and the currently focused node. // // Written by Marco Zehe. (c) 2007 interface uses Windows, Classes, ActiveX, oleacc, VirtualTrees, VTAccessibilityFactory, Controls; type TVirtualTreeAccessibility = class(TInterfacedObject, IDispatch, IAccessible) private FVirtualTree: TVirtualStringTree; public { IAccessibility } function Get_accParent(out ppdispParent: IDispatch): HResult; stdcall; function Get_accChildCount(out pcountChildren: Integer): HResult; stdcall; function Get_accChild(varChild: OleVariant; out ppdispChild: IDispatch): HResult; stdcall; function Get_accName(varChild: OleVariant; out pszName: WideString): HResult; stdcall; function Get_accValue(varChild: OleVariant; out pszValue: WideString): HResult; stdcall; function Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult; stdcall; function Get_accRole(varChild: OleVariant; out pvarRole: OleVariant): HResult; stdcall; function Get_accState(varChild: OleVariant; out pvarState: OleVariant): HResult; stdcall; function Get_accHelp(varChild: OleVariant; out pszHelp: WideString): HResult; stdcall; function Get_accHelpTopic(out pszHelpFile: WideString; varChild: OleVariant; out pidTopic: Integer): HResult; stdcall; function Get_accKeyboardShortcut(varChild: OleVariant; out pszKeyboardShortcut: WideString): HResult; stdcall; function Get_accFocus(out pvarChild: OleVariant): HResult; stdcall; function Get_accSelection(out pvarChildren: OleVariant): HResult; stdcall; function Get_accDefaultAction(varChild: OleVariant; out pszDefaultAction: WideString): HResult; stdcall; function accSelect(flagsSelect: Integer; varChild: OleVariant): HResult; stdcall; function accLocation(out pxLeft: Integer; out pyTop: Integer; out pcxWidth: Integer; out pcyHeight: Integer; varChild: OleVariant): HResult; stdcall; function accNavigate(navDir: Integer; varStart: OleVariant; out pvarEndUpAt: OleVariant): HResult; stdcall; function accHitTest(xLeft: Integer; yTop: Integer; out pvarChild: OleVariant): HResult; stdcall; function accDoDefaultAction(varChild: OleVariant): HResult; stdcall; function Set_accName(varChild: OleVariant; const pszName: WideString): HResult; stdcall; function Set_accValue(varChild: OleVariant; const pszValue: WideString): HResult; stdcall; {IDispatch} function GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount: Integer; LocaleID: Integer; DispIDs: Pointer): HRESULT; stdcall; function GetTypeInfo(Index: Integer; LocaleID: Integer; out TypeInfo): HRESULT; stdcall; function GetTypeInfoCount(out Count: Integer): HRESULT; stdcall; function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult: Pointer; ExcepInfo: Pointer; ArgErr: Pointer): HRESULT; stdcall; constructor Create(VirtualTree: TVirtualStringTree); end; TVirtualTreeItemAccessibility = class(TVirtualTreeAccessibility, IAccessible) public { IAccessibility } function Get_accParent(out ppdispParent: IDispatch): HResult; stdcall; function Get_accChildCount(out pcountChildren: Integer): HResult; stdcall; function Get_accChild(varChild: OleVariant; out ppdispChild: IDispatch): HResult; stdcall; function Get_accName(varChild: OleVariant; out pszName: WideString): HResult; stdcall; function Get_accValue(varChild: OleVariant; out pszValue: WideString): HResult; stdcall; function Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult; stdcall; function Get_accRole(varChild: OleVariant; out pvarRole: OleVariant): HResult; stdcall; function Get_accState(varChild: OleVariant; out pvarState: OleVariant): HResult; stdcall; function accLocation(out pxLeft: Integer; out pyTop: Integer; out pcxWidth: Integer; out pcyHeight: Integer; varChild: OleVariant): HResult; stdcall; constructor Create(VirtualTree: TVirtualStringTree); end; TVTMultiColumnItemAccessibility = class(TVirtualTreeItemAccessibility, IAccessible) private function GetItemDescription(varChild: OleVariant; out pszDescription: WideString; IncludeMainColumn: boolean): HResult; stdcall; public { IAccessibility } function Get_accName(varChild: OleVariant; out pszName: WideString): HResult; stdcall; function Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult; stdcall; end; TVTDefaultAccessibleProvider = class(TInterfacedObject, IVTAccessibleProvider) function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible; end; TVTDefaultAccessibleItemProvider = class(TInterfacedObject, IVTAccessibleProvider) function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible; end; TVTMultiColumnAccessibleItemProvider = class(TInterfacedObject, IVTAccessibleProvider) function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible; end; implementation uses Variants, SysUtils, Types, Forms; { TVirtualTreeAccessibility } //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.accDoDefaultAction(varChild: OleVariant): HResult; // a default action is not supported. begin Result := DISP_E_MEMBERNOTFOUND; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.accHitTest(xLeft: Integer; yTop: Integer; out pvarChild: OleVariant): HResult; // returns the iAccessible object at the given point, if applicable. var Pt: TPoint; HitInfo: THitInfo; begin Result := S_FALSE; if FVirtualTree <> nil then begin // VariantInit(pvarChild); // TVarData(pvarChild).VType := VT_I4; Pt := fVirtualTree.ScreenToClient(Point(xLeft, yTop)); if fVirtualTree.FocusedNode <> nil then begin fVirtualTree.GetHitTestInfoAt(xLeft, yTop, false, HitInfo); if FVirtualTree.FocusedNode = HitInfo.HitNode then begin pvarChild := FVirtualTree.AccessibleItem; Result := S_OK; exit; end; end; if PtInRect(FVirtualTree.BoundsRect, Pt) then begin pvarChild := CHILDID_SELF; Result := S_OK; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.accLocation(out pxLeft: Integer; out pyTop: Integer; out pcxWidth: Integer; out pcyHeight: Integer; varChild: OleVariant): HResult; // returns the location of the VirtualStringTree object. var P: TPoint; begin Result := S_FALSE; if varChild = CHILDID_SELF then begin if FVirtualTree <> nil then begin P := FVirtualTree.ClientToScreen(FVirtualTree.ClientRect.TopLeft); pxLeft := P.X; pyTop := P.Y; pcxWidth := FVirtualTree.Width; pcyHeight := FVirtualTree.Height; Result := S_OK; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.accNavigate(navDir: Integer; varStart: OleVariant; out pvarEndUpAt: OleVariant): HResult; // This is not supported. begin Result := DISP_E_MEMBERNOTFOUND; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accSelection(out pvarChildren: OleVariant): HResult; // returns the selected child ID, if any. begin Result := s_false; if FVirtualTree <> nil then if fVirtualTree.FocusedNode <> nil then begin pvarChildren := 1; result := s_OK; end; end; //---------------------------------------------------------------------------------------------------------------------- constructor TVirtualTreeAccessibility.Create(VirtualTree: TVirtualStringTree); // assigns the parent and current fields, and lets the control's iAccessible object know its address. begin fVirtualTree := VirtualTree; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HRESULT; // Not supported. begin Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HRESULT; // not supported. begin Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.GetTypeInfoCount( out Count: Integer): HRESULT; // not supported. begin Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accChild(varChild: OleVariant; out ppdispChild: IDispatch): HResult; // returns the iAccessible child, whicfh represents the focused item. begin if varChild = CHILDID_SELF then begin ppdispChild := FVirtualTree.AccessibleItem; Result := S_OK; end else Result := E_INVALIDARG end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accChildCount(out pcountChildren: Integer): HResult; // Returns the number 1 for the one child: The focused item. begin pcountChildren := 1; Result := S_OK; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accDefaultAction(varChild: OleVariant; out pszDefaultAction: WideString): HResult; // Not supported. begin Result := DISP_E_MEMBERNOTFOUND; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult; // returns the hint of the control, if assigned. begin pszDescription := ''; Result := S_FALSE; if varChild = CHILDID_SELF then begin if FVirtualTree <> nil then pszDescription := GetLongHint(fVirtualTree.Hint); end; if Length(pszDescription) > 0 then Result := S_OK; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accFocus(out pvarChild: OleVariant): HResult; // returns the child ID of 1, if assigned. begin Result := s_false; if fVirtualTree <> nil then begin if FVirtualTree.FocusedNode <> nil then begin pvarChild := fVirtualTree.AccessibleItem; result := s_OK; end else begin pvarChild := childid_self; result := S_OK; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accHelp(varChild: OleVariant; out pszHelp: WideString): HResult; // Not supported. begin Result := DISP_E_MEMBERNOTFOUND; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accHelpTopic(out pszHelpFile: WideString; varChild: OleVariant; out pidTopic: Integer): HResult; // Returns the HelpContext ID, if present. begin pszHelpFile := ''; pidTopic := 0; Result := S_OK; if varChild = CHILDID_SELF then if FVirtualTree <> nil then begin pszHelpFile := Application.HelpFile; pidTopic := FVirtualTree.HelpContext; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accKeyboardShortcut(varChild: OleVariant; out pszKeyboardShortcut: WideString): HResult; // Not supported. begin pszKeyboardShortcut := ''; Result := S_FALSE; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accName(varChild: OleVariant; out pszName: WideString): HResult; // if set, returns the new published AccessibleName property. // otherwise, returns the default text. begin pszName := ''; Result := S_FALSE; if varChild = CHILDID_SELF then begin if FVirtualTree <> nil then begin if FVirtualTree.AccessibleName <> '' then pszName := FVirtualTree.AccessibleName else PSZName := FVirtualTree.DefaultText; result := S_OK; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accParent(out ppdispParent: IDispatch): HResult; // Returns false, the tree itself does not have a parent. begin ppdispParent := nil; Result := S_FALSE; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accRole(varChild: OleVariant; out pvarRole: OleVariant): HResult; // tells MSAA that it is a TreeView. begin Result := S_OK; // VariantInit(pvarRole); // TVarData(pvarRole).VType := VT_I4; if varChild = CHILDID_SELF then begin if FVirtualTree <> nil then pvarRole := ROLE_SYSTEM_OUTLINE end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.accSelect(flagsSelect: Integer; varChild: OleVariant): HResult; // since we're not supporting more than one item, this is not supported currently. begin Result := DISP_E_MEMBERNOTFOUND; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accState(varChild: OleVariant; out pvarState: OleVariant): HResult; // returns the state of the control. const IsEnabled: array[Boolean] of Integer = (STATE_SYSTEM_UNAVAILABLE, 0); HasPopup: array[Boolean] of Integer = (0, STATE_SYSTEM_HASPOPUP); IsVisible: array[Boolean] of Integer = (STATE_SYSTEM_INVISIBLE, 0); begin Result := S_OK; // VariantInit(pvarState); // TVarData(pvarState).VType := VT_I4; if varChild = CHILDID_SELF then begin if FVirtualTree <> nil then begin pvarState := STATE_SYSTEM_FOCUSED or STATE_SYSTEM_FOCUSABLE or STATE_SYSTEM_HOTTRACKED; pvarState := pvarState or IsVisible[FVirtualTree.Visible]; pvarState := pvarState or IsEnabled[FVirtualTree.Enabled]; end else Result := E_INVALIDARG; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Get_accValue(varChild: OleVariant; out pszValue: WideString): HResult; // the TreeView control itself does not have a value, returning false here. begin pszValue := ''; Result := S_FALSE;//DISP_E_MEMBERNOTFOUND; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HRESULT; // not supported. begin Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Set_accName(varChild: OleVariant; const pszName: WideString): HResult; stdcall; // not supported. begin Result := DISP_E_MEMBERNOTFOUND end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeAccessibility.Set_accValue(varChild: OleVariant; const pszValue: WideString): HResult; // not supported. begin Result := DISP_E_MEMBERNOTFOUND end; { TVirtualTreeItemAccessibility } //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeItemAccessibility.accLocation(out pxLeft, pyTop, pcxWidth, pcyHeight: Integer; varChild: OleVariant): HResult; // returns the location of the current accessible item. var P: TPoint; DisplayRect: TRect; begin Result := S_FALSE; if varChild = CHILDID_SELF then begin if FVirtualTree.FocusedNode <> nil then begin DisplayRect := FVirtualTree.GetDisplayRect(FVirtualTree.FocusedNode, -1, TRUE, FALSE); P := FVirtualTree.ClientToScreen(DisplayRect.TopLeft); pxLeft := P.X; pyTop := P.Y; pcxWidth := DisplayRect.Right - DisplayRect.Left; pcyHeight := DisplayRect.Bottom - DisplayRect.Top; Result := S_OK; end; end; end; //---------------------------------------------------------------------------------------------------------------------- constructor TVirtualTreeItemAccessibility.Create(VirtualTree: TVirtualStringTree); // sets up the parent/child relationship. begin fVirtualTree := VirtualTree; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeItemAccessibility.Get_accChild(varChild: OleVariant; out ppdispChild: IDispatch): HResult; // the item does not have children. Returning false. begin ppdispChild := nil; Result := S_FALSE; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeItemAccessibility.Get_accChildCount(out pcountChildren: Integer): HResult; // the item itself does not have children, returning 0. begin pcountChildren := 0; Result := S_OK; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeItemAccessibility.Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult; // not supported for an item. begin Result := DISP_E_MEMBERNOTFOUND; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeItemAccessibility.Get_accName(varChild: OleVariant; out pszName: WideString): HResult; // the name is the node's caption. begin pszName := ''; Result := S_FALSE; if varChild = childid_self then begin if FVirtualTree <> nil then if FVirtualTree.FocusedNode <> nil then begin pszName := FVirtualTree.Text[FVirtualTree.FocusedNode, FVirtualTree.Header.MainColumn]; result := S_OK; end else begin PSZName := FVirtualTree.DefaultText; result := S_OK; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeItemAccessibility.Get_accParent(out ppdispParent: IDispatch): HResult; // tells MSAA that the VritualStringTree is its parent. begin result := S_FALSE; if FVirtualTree <> nil then begin ppdispParent := FVirtualTree.Accessible; Result := S_OK; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeItemAccessibility.Get_accRole(varChild: OleVariant; out pvarRole: OleVariant): HResult; // tells MSAA that it is a TreeView item as opposed to the TreeView itself. begin Result := S_OK; // VariantInit(pvarRole); // TVarData(pvarRole).VType := VT_I4; if varChild = childid_self then begin if FVirtualTree <> nil then pvarRole := ROLE_SYSTEM_OUTLINEITEM end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeItemAccessibility.Get_accState(varChild: OleVariant; out pvarState: OleVariant): HResult; // Tells MSAA the state the item is in. const IsEnabled: array[Boolean] of Integer = (STATE_SYSTEM_UNAVAILABLE, 0); HasPopup: array[Boolean] of Integer = (0, STATE_SYSTEM_HASPOPUP); IsVisible: array[Boolean] of Integer = (STATE_SYSTEM_INVISIBLE, 0); IsChecked: array[Boolean] of Integer = (0, STATE_SYSTEM_CHECKED); IsExpanded: array[Boolean] of Integer = (0, STATE_SYSTEM_EXPANDED); IsCollapsed: array[Boolean] of Integer = (0, STATE_SYSTEM_COLLAPSED); begin Result := S_OK; // VariantInit(pvarState); // TVarData(pvarState).VType := VT_I4; if varChild = childid_self then begin if FVirtualTree <> nil then begin pvarState := STATE_SYSTEM_FOCUSED or STATE_SYSTEM_FOCUSABLE or STATE_SYSTEM_HOTTRACKED; pvarState := pvarState or IsVisible[FVirtualTree.Visible]; pvarState := pvarState or IsEnabled[FVirtualTree.Enabled]; if fVirtualTree.FocusedNode <> nil then begin pvarState := pvarState or IsChecked[csCheckedNormal = FVirtualTree.FocusedNode.CheckState]; pvarState := pvarState or IsExpanded[VSExpanded in FVirtualTree.FocusedNode.States]; if not (vsExpanded in FVirtualTree.FocusedNode.States) then pvarState:= PvarState or IsCollapsed[vsHasChildren in FVirtualTree.FocusedNode.States]; end; end else Result := E_INVALIDARG; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeItemAccessibility.Get_accValue(varChild: OleVariant; out pszValue: WideString): HResult; // for a TreeView item, the value is the nesting level number, 0-based. begin pszValue := ''; Result := S_FALSE;//DISP_E_MEMBERNOTFOUND; if varChild = childid_self then if FVirtualTree <> nil then if FVirtualTree.FocusedNode <> nil then begin PSZValue := IntToStr(FVirtualTree.GetNodeLevel(FVirtualTree.FocusedNode)); result := S_OK; end; end; { TVTMultiColumnItemAccessibility } function TVTMultiColumnItemAccessibility.GetItemDescription( varChild: OleVariant; out pszDescription: WideString; IncludeMainColumn: boolean): HResult; var I: Integer; sTemp: WideString; begin pszDescription := ''; Result := S_FALSE; if varChild = childid_self then begin if FVirtualTree <> nil then if FVirtualTree.FocusedNode <> nil then begin if IncludeMainColumn then pszDescription := FVirtualTree.Text[FVirtualTree.FocusedNode, FVirtualTree.Header.MainColumn] +'; '; for I := 0 to FVirtualTree.Header.Columns.Count - 1 do if FVirtualTree.Header.MainColumn <> I then begin sTemp := FVirtualTree.Text[FVirtualTree.FocusedNode, I]; if sTemp <> '' then pszDescription := pszDescription +FVirtualTree.Header.Columns[I].Text +': ' +sTemp +'; '; end; if pszDescription <> '' then if pszDescription[Length(pszDescription)-1] = ';' then Delete(pszDescription, length(pszDescription)-1, 2); result := S_OK; end else begin PSZDescription := FVirtualTree.DefaultText; result := S_OK; end; end; end; function TVTMultiColumnItemAccessibility.Get_accDescription( varChild: OleVariant; out pszDescription: WideString): HResult; begin result := GetItemDescription(varChild, pszDescription, false) end; function TVTMultiColumnItemAccessibility.Get_accName(varChild: OleVariant; out pszName: WideString): HResult; begin result := GetItemDescription(varChild, pszName, true) end; { TVTDefaultAccessibleProvider } function TVTDefaultAccessibleProvider.CreateIAccessible( ATree: TBaseVirtualTree): IAccessible; begin result := TVirtualTreeAccessibility.Create(TVirtualStringTree(ATree)); end; { TVTDefaultAccessibleItemProvider } function TVTDefaultAccessibleItemProvider.CreateIAccessible( ATree: TBaseVirtualTree): IAccessible; begin result := TVirtualTreeItemAccessibility.Create(TVirtualStringTree(ATree)); end; { TVTMultiColumnAccessibleItemProvider } function TVTMultiColumnAccessibleItemProvider.CreateIAccessible( ATree: TBaseVirtualTree): IAccessible; begin result := nil; if TVirtualStringTree(ATree).Header.UseColumns then result := TVTMultiColumnItemAccessibility.Create(TVirtualStringTree(ATree)); end; var IDefaultAccessibleProvider: TVTDefaultAccessibleProvider; IDefaultAccessibleItemProvider: TVTDefaultAccessibleItemProvider; IMultiColumnAccessibleProvider: TVTMultiColumnAccessibleItemProvider; initialization if VTAccessibleFactory = nil then VTAccessibleFactory := TVTAccessibilityFactory.Create; if IDefaultAccessibleProvider = nil then begin IDefaultAccessibleProvider := TVTDefaultAccessibleProvider.Create; VTAccessibleFactory.RegisterAccessibleProvider(IDefaultAccessibleProvider); end; if IDefaultAccessibleItemProvider = nil then begin IDefaultAccessibleItemProvider := TVTDefaultAccessibleItemProvider.Create; VTAccessibleFactory.RegisterAccessibleProvider(IDefaultAccessibleItemProvider); end; if IMultiColumnAccessibleProvider = nil then begin IMultiColumnAccessibleProvider := TVTMultiColumnAccessibleItemProvider.Create; VTAccessibleFactory.RegisterAccessibleProvider(IMultiColumnAccessibleProvider); end; finalization if VTAccessibleFactory <> nil then begin VTAccessibleFactory.UnRegisterAccessibleProvider(IMultiColumnAccessibleProvider); IMultiColumnAccessibleProvider := nil; VTAccessibleFactory.UnRegisterAccessibleProvider(IDefaultAccessibleItemProvider); IDefaultAccessibleItemProvider := nil; VTAccessibleFactory.UnRegisterAccessibleProvider(IDefaultAccessibleProvider); IDefaultAccessibleProvider := nil; end; end. doublecmd-0.8.2/components/virtualtreeview/readme.txt0000664000175000017500000000033112014201074022115 0ustar alexxalexxVirtual Tree View from Lazarus CCR https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/components/virtualtreeview-new/branches/4.8 Rev. 2200 Some modifications done for Double Commander (see doublecmd.diff). doublecmd-0.8.2/components/virtualtreeview/VTHeaderPopup.pas0000664000175000017500000002131212014201074023314 0ustar alexxalexxunit VTHeaderPopup; //---------------------------------------------------------------------------------------------------------------------- // The contents of this file are subject to the Mozilla Public License // Version 1.1 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.mozilla.org/MPL/ // // Alternatively, you may redistribute this library, use and/or modify it under the terms of the // GNU Lesser General Public License as published by the Free Software Foundation; // either version 2.1 of the License, or (at your option) any later version. // You may obtain a copy of the LGPL at http://www.gnu.org/copyleft/. // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations // under the License. // // The Original Code is VTHeaderPopup.pas. // // The Initial Developer of the Original Code is Ralf Junker . All Rights Reserved. // // September 2004: // - Bug fix: TVTHeaderPopupMenu.OnMenuItemClick used the wrong Tag member for the event. // // Modified 12 Dec 2003 by Ralf Junker . // - Added missing default storage specifier for Options property. // - To avoid mixing up image lists of different trees sharing the same header // popup, set the popup's image list to nil if hoShowImages is not in the // tree's header options. // - Added an additional check for the PopupComponent property before casting // it hardly to a Virtual Treeview in OnMenuItemClick. See entry 31 Mar 2003. // // Modified 14 Sep 2003 by Mike Lischke . // - Renamed event type name to be consistent with other event types (e.g. used in VT). // - Added event for hiding/showing columns. // - DoXXX method are now virtual. // - Conditional code rearrangement to get back Ctrl+Shift+Up/Down navigation. // // Modified 31 Mar 2003 by Mike Lischke . // - Added a check for the PopupComponent property before casting it hardly to // a Virtual Treeview. People might (accidentally) misuse the header popup. // // Modified 20 Oct 2002 by Borut Maricic . // - Added the possibility to use Troy Wolbrink's Unicode aware popup menu. // Define the compiler symbol TNT to enable it. You can get Troy's Unicode // controls collection from http://home.ccci.org/wolbrink/tnt/delphi_unicode_controls.htm. // // Modified 24 Feb 2002 by Ralf Junker . // - Fixed a bug where the OnAddHeaderPopupItem would interfere with // poAllowHideAll options. // - All column indexes now consistently use TColumnIndex (instead of Integer). // // Modified 23 Feb 2002 by Ralf Junker . // - Added option to show menu items in the same order as the columns or in // original order. // - Added option to prevent the user to hide all columns. // // Modified 17 Feb 2002 by Jim Kueneman . // - Added the event to filter the items as they are added to the menu. //---------------------------------------------------------------------------------------------------------------------- {$mode delphi} interface uses {$ifdef TNT} TntMenus, {$else} Menus, {$endif TNT} VirtualTrees; type TVTHeaderPopupOption = ( poOriginalOrder, // Show menu items in original column order as they were added to the tree. poAllowHideAll // Allows to hide all columns, including the last one. ); TVTHeaderPopupOptions = set of TVTHeaderPopupOption; TAddPopupItemType = ( apNormal, apDisabled, apHidden ); TAddHeaderPopupItemEvent = procedure(const Sender: TBaseVirtualTree; const Column: TColumnIndex; var Cmd: TAddPopupItemType) of object; TColumnChangeEvent = procedure(const Sender: TBaseVirtualTree; const Column: TColumnIndex; Visible: Boolean) of object; {$ifdef TNT} TVTMenuItem = TTntMenuItem; {$else} TVTMenuItem = TMenuItem; {$endif} {$ifdef TNT} TVTHeaderPopupMenu = class(TTntPopupMenu) {$else} TVTHeaderPopupMenu = class(TPopupMenu) {$endif} private FOptions: TVTHeaderPopupOptions; FOnAddHeaderPopupItem: TAddHeaderPopupItemEvent; FOnColumnChange: TColumnChangeEvent; protected procedure DoAddHeaderPopupItem(const Column: TColumnIndex; out Cmd: TAddPopupItemType); virtual; procedure DoColumnChange(Column: TColumnIndex; Visible: Boolean); virtual; procedure OnMenuItemClick(Sender: TObject); public procedure Popup(x, y: Integer); override; published property Options: TVTHeaderPopupOptions read FOptions write FOptions default []; property OnAddHeaderPopupItem: TAddHeaderPopupItemEvent read FOnAddHeaderPopupItem write FOnAddHeaderPopupItem; property OnColumnChange: TColumnChangeEvent read FOnColumnChange write FOnColumnChange; end; //---------------------------------------------------------------------------------------------------------------------- implementation uses {$ifdef TNT} TnTClasses {$else} Classes {$endif TNT}; type TVirtualTreeCast = class(TBaseVirtualTree); // Necessary to make the header accessible. //----------------- TVTHeaderPopupMenu --------------------------------------------------------------------------------- procedure TVTHeaderPopupMenu.DoAddHeaderPopupItem(const Column: TColumnIndex; out Cmd: TAddPopupItemType); begin Cmd := apNormal; if Assigned(FOnAddHeaderPopupItem) then FOnAddHeaderPopupItem(TVirtualTreeCast(PopupComponent), Column, Cmd); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeaderPopupMenu.DoColumnChange(Column: TColumnIndex; Visible: Boolean); begin if Assigned(FOnColumnChange) then FOnColumnChange(TVirtualTreeCast(PopupComponent), Column, Visible); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeaderPopupMenu.OnMenuItemClick(Sender: TObject); begin if Assigned(PopupComponent) and (PopupComponent is TBaseVirtualTree) then with TVTMenuItem(Sender), TVirtualTreeCast(PopupComponent).Header.Columns.Items[Tag] do begin if Checked then Options := Options - [coVisible] else Options := Options + [coVisible]; DoColumnChange(TVTMenuItem(Sender).Tag, not Checked); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeaderPopupMenu.Popup(x, y: Integer); var I: Integer; ColPos: TColumnPosition; ColIdx: TColumnIndex; NewMenuItem: TVTMenuItem; Cmd: TAddPopupItemType; VisibleCounter: Cardinal; VisibleItem: TVTMenuItem; begin if Assigned(PopupComponent) and (PopupComponent is TBaseVirtualTree) then begin // Delete existing menu items. I := Items.Count; while I > 0 do begin Dec(I); Items[I].Free; end; // Add column menu items. with TVirtualTreeCast(PopupComponent).Header do begin if hoShowImages in Options then Self.Images := Images else // Remove a possible reference to image list of another tree previously assigned. Self.Images := nil; VisibleItem := nil; VisibleCounter := 0; for ColPos := 0 to Columns.Count - 1 do begin if poOriginalOrder in FOptions then ColIdx := ColPos else ColIdx := Columns.ColumnFromPosition(ColPos); with Columns[ColIdx] do begin if coVisible in Options then Inc(VisibleCounter); DoAddHeaderPopupItem(ColIdx, Cmd); if Cmd <> apHidden then begin NewMenuItem := TVTMenuItem.Create(Self); NewMenuItem.Tag := ColIdx; NewMenuItem.Caption := Text; NewMenuItem.Hint := Hint; NewMenuItem.ImageIndex := ImageIndex; NewMenuItem.Checked := coVisible in Options; NewMenuItem.OnClick := OnMenuItemClick; if Cmd = apDisabled then NewMenuItem.Enabled := False else if coVisible in Options then VisibleItem := NewMenuItem; Items.Add(NewMenuItem); end; end; end; // Conditionally disable menu item of last enabled column. if (VisibleCounter = 1) and (VisibleItem <> nil) and not (poAllowHideAll in FOptions) then VisibleItem.Enabled := False; end; end; inherited; end; //---------------------------------------------------------------------------------------------------------------------- end. doublecmd-0.8.2/components/virtualtreeview/virtualtrees.lrs0000664000175000017500000050502111727533326023422 0ustar alexxalexxLazarusResources.Add('VT_VERTSPLIT','CUR',[ #0#0#2#0#1#0' '#2#0#14#0#15#0'0'#1#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#1#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#0#0#2#0#0#0#2#0#0#0#0#0#0#0#255#255#255#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#6#0#0#0#9#0#0#0#16#128#0#0 +' @'#0#0#25#128#0#0#9#0#0#0#9#0#0#7#249#254#0#4#0#2#0#4#0#2#0#7#249#254#0#0#9 +#0#0#0#9#0#0#0#25#128#0#0' @'#0#0#16#128#0#0#9#0#0#0#6#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#249 +#255#255#255#240#255#255#255#224#127#255#255#192'?'#255#255#224#127#255#255 +#240#255#255#255#240#255#255#248#0#1#255#248#0#1#255#248#0#1#255#248#0#1#255 +#255#240#255#255#255#240#255#255#255#224#127#255#255#192'?'#255#255#224#127 +#255#255#240#255#255#255#249#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255 ]); LazarusResources.Add('VT_HEADERSPLIT','CUR',[ #0#0#2#0#1#0' '#0#0#15#0#14#0'0'#1#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#1#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#7 +#128#0#0#4#128#0#0#4#128#0#0#4#128#0#0#4#128#0#0'D'#136#0#0#164#148#0#1'<' +#242#0#2#0#1#0#2#0#1#0#1'<'#242#0#0#164#148#0#0'D'#136#0#0#4#128#0#0#4#128#0 +#0#4#128#0#0#4#128#0#0#7#128#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#248#127 +#255#255#248#127#255#255#248#127#255#255#248#127#255#255#248#127#255#255#184 +'w'#255#255#24'c'#255#254#0#1#255#252#0#0#255#252#0#0#255#254#0#1#255#255#24 +'c'#255#255#184'w'#255#255#248#127#255#255#248#127#255#255#248#127#255#255 +#248#127#255#255#248#127#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255 ]); LazarusResources.Add('VT_MOVEALL','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0'0'#1#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#1#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#128#0#0#2'@'#0#0#4' '#0#0#8#16#0#0#16#8 +#0#0' '#4#0#0#127#254#0#0#160#5#0#1' '#4#128#2'!'#132'@'#4'"D '#8'$$'#16#8'$' +'$'#16#4'"D '#2'!'#132'@'#1' '#4#128#0#160#5#0#0#127#254#0#0' '#4#0#0#16#8#0 +#0#8#16#0#0#4' '#0#0#2'@'#0#0#1#128#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#254#127#255#255 +#252'?'#255#255#248#31#255#255#240#15#255#255#224#7#255#255#192#3#255#255#128 +#1#255#255#31#248#255#254#31#248#127#252#30'x?'#248#28'8'#31#240#24#24#15#240 +#24#24#15#248#28'8'#31#252#30'x?'#254#31#248#127#255#31#248#255#255#128#1#255 +#255#192#3#255#255#224#7#255#255#240#15#255#255#248#31#255#255#252'?'#255#255 +#254#127#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 ]); LazarusResources.Add('VT_MOVEE','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0 +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#15#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0#240#0#0#0#0#0#0#0#0#0#0#15#240 +#0#15#0#15#0#0#0#0#0#0#0#0#0#0#240#15#0#15#0#0#240#0#0#0#0#0#0#0#0#15#0#0#240 +#15#0#0#15#0#0#0#0#0#0#0#0#15#0#0#240#15#0#0#15#0#0#0#0#0#0#0#0#0#240#15#0#15 +#0#0#240#0#0#0#0#0#0#0#0#0#15#240#0#15#0#15#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0 +#240#0#0#0#0#0#0#0#0#0#0#0#0#0#15#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#251#255#255#255#249#255#255#255#248#255#255#255#248#127 +#255#254'x?'#255#252'8'#31#255#248#24#15#255#248#24#15#255#252'8'#31#255#254 +'x?'#255#255#248#127#255#255#248#255#255#255#249#255#255#255#251#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 ]); LazarusResources.Add('VT_MOVEEW','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0 +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#240#0#0#0#0#15#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#15#240#0#0#0#0#0#0#0#0 +#240#240#0#0#0#0#15#15#0#0#0#0#0#0#0#15#0#240#0#0#0#0#15#0#240#0#0#0#0#0#0 +#240#0#240#0#15#240#0#15#0#15#0#0#0#0#0#15#0#0#240#0#240#15#0#15#0#0#240#0#0 +#0#0#240#0#0#240#15#0#0#240#15#0#0#15#0#0#0#0#240#0#0#240#15#0#0#240#15#0#0 +#15#0#0#0#0#15#0#0#240#0#240#15#0#15#0#0#240#0#0#0#0#0#240#0#240#0#15#240#0 +#15#0#15#0#0#0#0#0#0#15#0#240#0#0#0#0#15#0#240#0#0#0#0#0#0#0#240#240#0#0#0#0 +#15#15#0#0#0#0#0#0#0#0#15#240#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#240#0#0#0#0#15 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#223#251 +#255#255#159#249#255#255#31#248#255#254#31#248#127#252#30'x?'#248#28'8'#31 +#240#24#24#15#240#24#24#15#248#28'8'#31#252#30'x?'#254#31#248#127#255#31#248 +#255#255#159#249#255#255#223#251#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255 ]); LazarusResources.Add('VT_MOVEN','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0 +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0 +#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255 +#255#255#255#255#255#255#0#0#0#0#0#0#0#0#15#0#0#0#0#0#0#240#0#0#0#0#0#0#0#0#0 +#240#0#0#0#0#15#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240#0#0#0#0#0#0#0#0#0#0#0#240 +#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#254#127#255#255#252'?'#255#255#248#31#255#255#248#31#255#255#252'?' +#255#255#254#127#255#255#255#255#255#255#0#0#255#255#128#1#255#255#192#3#255 +#255#224#7#255#255#240#15#255#255#248#31#255#255#252'?'#255#255#254#127#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 ]); LazarusResources.Add('VT_MOVENE','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0 +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#240#15#0#0#0#240#0#0#0#0#0#0#0#0#0#15#0#0#240#0#15#240#0#0 +#0#0#0#0#0#0#0#15#0#0#240#0#240#240#0#0#0#0#0#0#0#0#0#0#240#15#0#15#0#240#0#0 +#0#0#0#0#0#0#0#0#15#240#0#240#0#240#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0 +#0#0#0#0#0#0#0#0#0#240#0#0#240#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#240#0#0#0#0#0#0 +#0#0#0#0#0#240#0#0#0#240#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240#0#0#0#0#0#0#0#0#0 +#0#255#255#255#255#255#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#254#127#255#255#252'?'#127#255#248#30#127#255#248#28#127#255#252 +'8'#127#255#254'p'#127#255#255#224#127#255#255#192#127#255#255#128#127#255 +#255#0#127#255#254#0#127#255#252#0#127#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 ]); LazarusResources.Add('VT_MOVENS','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0 +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0 +#240#0#0#0#0#0#0#0#0#0#0#0#0#240#0#0#15#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240 +#0#0#0#0#0#0#0#0#0#0#240#0#0#0#0#15#0#0#0#0#0#0#0#0#0#15#255#255#255#255#255 +#255#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0 +#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0 +#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#255#255#255#255 +#255#255#240#0#0#0#0#0#0#0#0#0#240#0#0#0#0#15#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0 +#240#0#0#0#0#0#0#0#0#0#0#0#240#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0 +#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#254#127#255#255#252'?'#255 +#255#248#31#255#255#240#15#255#255#224#7#255#255#192#3#255#255#128#1#255#255 +#255#255#255#255#255#255#255#255#254#127#255#255#252'?'#255#255#248#31#255 +#255#248#31#255#255#252'?'#255#255#254#127#255#255#255#255#255#255#255#255 +#255#255#128#1#255#255#192#3#255#255#224#7#255#255#240#15#255#255#248#31#255 +#255#252'?'#255#255#254#127#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255 ]); LazarusResources.Add('VT_MOVENW','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0 +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0 +#0#0#0#0#0#15#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#15#240#0#15#0#0#240#0#0#0#0#0 +#0#0#0#0#15#15#0#15#0#0#240#0#0#0#0#0#0#0#0#0#15#0#240#0#240#15#0#0#0#0#0#0#0 +#0#0#0#15#0#15#0#15#240#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0 +#0#15#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#240#0#0#0#0#0#0#0#0#0#0#0#15#0 +#0#0#15#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240#0#0#0#0#0#0#0#0#0#0#15#255#255 +#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#254#127#255#254#252'?'#255#254'x'#31#255#254'8'#31#255#254#28'?'#255 +#254#14#127#255#254#7#255#255#254#3#255#255#254#1#255#255#254#0#255#255#254#0 +#127#255#254#0'?'#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255 ]); LazarusResources.Add('VT_MOVES','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0 +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0 +#240#0#0#0#0#0#0#0#0#0#0#0#0#240#0#0#15#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240 +#0#0#0#0#0#0#0#0#0#0#240#0#0#0#0#15#0#0#0#0#0#0#0#0#0#15#0#0#0#0#0#0#240#0#0 +#0#0#0#0#0#0#255#255#255#255#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0 +#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0 +#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#254#127#255#255#252'?'#255#255#248#31#255#255#240#15#255 +#255#224#7#255#255#192#3#255#255#128#1#255#255#0#0#255#255#255#255#255#255 +#254#127#255#255#252'?'#255#255#248#31#255#255#248#31#255#255#252'?'#255#255 +#254#127#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 ]); LazarusResources.Add('VT_MOVESE','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0 +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#240#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0 +#240#0#0#0#0#0#0#0#0#0#0#0#240#0#0#0#240#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#240#0 +#0#0#0#0#0#0#0#0#0#0#0#240#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0 +#0#0#0#0#0#0#15#240#0#240#0#240#0#0#0#0#0#0#0#0#0#0#240#15#0#15#0#240#0#0#0#0 +#0#0#0#0#0#15#0#0#240#0#240#240#0#0#0#0#0#0#0#0#0#15#0#0#240#0#15#240#0#0#0#0 +#0#0#0#0#0#0#240#15#0#0#0#240#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#252 +#0#127#255#254#0#127#255#255#0#127#255#255#128#127#255#255#192#127#255#255 +#224#127#255#254'p'#127#255#252'8'#127#255#248#28#127#255#248#30#127#255#252 +'?'#127#255#254#127#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('VT_MOVESW','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0 +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#15#255#255#255#255#255#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240#0#0#0 +#0#0#0#0#0#0#0#15#0#0#0#15#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#240#0#0#0#0#0#0#0#0 +#0#0#0#15#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0 +#15#0#15#0#15#240#0#0#0#0#0#0#0#0#0#0#15#0#240#0#240#15#0#0#0#0#0#0#0#0#0#0 +#15#15#0#15#0#0#240#0#0#0#0#0#0#0#0#0#15#240#0#15#0#0#240#0#0#0#0#0#0#0#0#0 +#15#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#254#0'?'#255#254 +#0#127#255#254#0#255#255#254#1#255#255#254#3#255#255#254#7#255#255#254#14#127 +#255#254#28'?'#255#254'8'#31#255#254'x'#31#255#254#252'?'#255#255#254#127#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255 ]); LazarusResources.Add('VT_MOVEW','CUR',[ #0#0#2#0#1#0' '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1 +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0 +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240 +#240#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0#240#0#0#0#0#0#0#0#0#0#0#0#0#0#240#0#240#0 +#15#240#0#0#0#0#0#0#0#0#0#15#0#0#240#0#240#15#0#0#0#0#0#0#0#0#0#240#0#0#240 +#15#0#0#240#0#0#0#0#0#0#0#0#240#0#0#240#15#0#0#240#0#0#0#0#0#0#0#0#15#0#0#240 +#0#240#15#0#0#0#0#0#0#0#0#0#0#240#0#240#0#15#240#0#0#0#0#0#0#0#0#0#0#15#0#240 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#223#255#255#255#159#255#255#255#31#255#255#254 +#31#255#255#252#30#127#255#248#28'?'#255#240#24#31#255#240#24#31#255#248#28 +'?'#255#252#30#127#255#254#31#255#255#255#31#255#255#255#159#255#255#255#223 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 ]); LazarusResources.Add('VT_XPBUTTONPLUS','BMP',[ 'BM4'#1#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#9#0#0#0#9#0#0#0#1#0#24#0#0#0#0#0#0#0#0#0 +#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#211#194#176#181#152'x'#181#152'x'#181 +#152'x'#181#152'x'#181#152'x'#181#152'x'#181#152'x'#211#194#176#0#181#152'x' +#191#204#210#174#190#198#168#184#194#167#184#193#167#184#193#166#183#192#170 +#186#195#181#152'x'#0#181#152'x'#217#225#228#207#216#220#201#211#216#0#0#0 +#198#209#214#192#204#210#187#200#207#181#152'x'#0#181#152'x'#238#242#242#236 +#240#240#231#237#237#0#0#0#227#233#234#217#224#227#204#214#219#181#152'x'#0 +#181#152'x'#241#245#245#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#210#219#223#181#152'x' +#0#181#152'x'#245#247#247#245#247#247#244#247#247#0#0#0#244#246#246#235#240 +#241#218#225#229#181#152'x'#0#181#152'x'#251#252#252#251#253#253#251#253#253 +#0#0#0#251#252#252#250#252#252#243#246#247#181#152'x'#0#181#152'x'#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#181#152'x'#0#211#194#176#181#152'x'#181#152'x'#181#152'x'#181#152'x'#181#152 +'x'#181#152'x'#181#152'x'#211#194#176#0#0#0 ]); LazarusResources.Add('VT_XPBUTTONMINUS','BMP',[ 'BM4'#1#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#9#0#0#0#9#0#0#0#1#0#24#0#0#0#0#0#0#0#0#0 +#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#211#194#176#181#152'x'#181#152'x'#181 +#152'x'#181#152'x'#181#152'x'#181#152'x'#181#152'x'#211#194#176#0#181#152'x' +#191#204#210#174#190#198#168#184#194#167#184#193#167#184#193#166#183#192#170 +#186#195#181#152'x'#0#181#152'x'#217#225#228#207#216#220#201#211#216#199#210 +#215#198#209#214#192#204#210#187#200#207#181#152'x'#0#181#152'x'#238#242#242 +#236#240#240#231#237#237#230#235#236#227#233#234#217#224#227#204#214#219#181 +#152'x'#0#181#152'x'#241#245#245#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#210#219#223 +#181#152'x'#0#181#152'x'#245#247#247#245#247#247#244#247#247#244#247#247#244 +#246#246#235#240#241#218#225#229#181#152'x'#0#181#152'x'#251#252#252#251#253 +#253#251#253#253#251#253#253#251#252#252#250#252#252#243#246#247#181#152'x'#0 +#181#152'x'#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#181#152'x'#0#211#194#176#181#152'x'#181#152'x'#181#152 +'x'#181#152'x'#181#152'x'#181#152'x'#181#152'x'#211#194#176#0#0#0 ]); LazarusResources.Add('VT_CHECK_LIGHT','BMP',[ 'BM'#246#12#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#4#0#0#0#0#0 +#128#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255#0#255#0 +#192#192#192#0#128#128#128#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'""""""""""""""""""""""""""""""""""""""""""""""332"""""332"""""332"""""332""' +'"""332"""""332"""""332"""""332"""#33332""#33332""#33332""#33332""#33332""#3' +'3332""#33332""#33332""#33332""#33332""#33332""#33332"!DDDDDDB!DDDDDDB$'#17 +#17#17#17#17#17#18'!DDDDDDB""""""""""3'#17#17#19'""""3'#17#17#19'""""3333"""' +'"3333""""3'#17#17#19'""""3'#17#17#19'""""3333""""3333"""4'#17#17#17#17#19'"' +'"4'#17#17#17#17#19'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19 +'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333"!3' +'33333B!333333B$333333'#18'!333333B"""""""""#A'#17#17#17'2""#A'#17#17#17'2""' +'#C3332""#C3332""#A'#19'3'#17'2""#A'#19'3'#17'2""#C3332""#C3332""4'#17#17#17 +#17#19'""4'#17#17#17#17#19'""433333""433333""4'#20'A'#17'D'#19'""4'#20'A'#17 +'D'#19'""44C3D3""44C3D3""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!333' +'333B!333333B$333333'#18'!333333B"""""""""$'#17#17#17#17#19'""$'#17#17#17#17 +#19'""$33333""$33333""$'#17'DDA'#19'""$'#17'DDA'#19'""$3DDC3""$3DDC3""4'#17 +#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#20'D'#20'D'#19'""4'#20 +'D'#20'D'#19'""44D4D3""44D4D3""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD' +'3"!333333B!333333B$333'#3'33'#18'!333333B"""""""""4'#17#17#17#17#19'""4'#17 +#17#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'#19'""43DDC3""43DDC' +'3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17'DDA'#19'""' +'4'#17'DDA'#19'""43DDC3""43DDC3""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44D' +'DD3"!330333B!330333B$330'#0'33'#18'!334333B"""""""""4'#17#17#17#17#19'""4' +#17#17#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'#19'""43DDC3""43' +'DDC3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17#20'D'#17 +#19'""4'#17#20'D'#17#19'""434D33""434D33""4'#20'DDD'#19'""4'#20'DDD'#19'""44' +'DDD3""44DDD3"!33'#0#3'33B!33'#0#3'33B$33'#0#0#3'3'#18'!33DC33B"""""""""4'#17 +#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC' +#19'""43DDC3""43DDC3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333' +'""4'#17'DDA'#19'""4'#17'DDA'#19'""43DDC3""43DDC3""4'#20'DDD'#19'""4'#20'DDD' +#19'""44DDD3""44DDD3"!30'#0#0'33B!30'#0#0'33B$30'#0#0#0'3'#18'!34DD33B""""""' +'"""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17'DDA'#19'""' +'4'#17'DDA'#19'""43DDC3""43DDC3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433' +'333""433333""4'#20'D'#20'D'#19'""4'#20'D'#20'D'#19'""44D4D3""44D4D3""4'#20 +'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!3'#0#0#0#3'3B!3'#0#0#0#3'3B$33333' +'3'#18'!3DDDC3B"""""""""$1'#17#17#17'2""$1'#17#17#17'2""$33332""$33332""$1' +#19'3'#17'2""$1'#19'3'#17'2""$33332""$33332""4'#17#17#17#17#19'""4'#17#17#17 +#17#19'""433333""433333""4'#20'A'#17'D'#19'""4'#20'A'#17'D'#19'""44C3D3""44C' +'3D3""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!333333B!333333B$333333' +#18'!333333B"""""""""#C'#17#17#20'2""#C'#17#17#20'2""#C3342""#C3342""#C'#17 +#17#20'2""#C'#17#17#20'2""#C3342""#C3342""4'#17#17#17#17#19'""4'#17#17#17#17 +#19'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333' +'""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333"!333333B!333333B$3' +'33333'#18'!333333B""""""""""4DDC""""4DDC""""4DDC""""4DDC""""4DDC""""4DDC"""' +'"4DDC""""4DDC"""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DD' +'DDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC"!333333B!333333B$333333'#18'!333333B"""' +'""""""""33""""""33""""""33""""""33""""""33""""""33""""""33""""""33""""#3333' +'2""#33332""#33332""#33332""#33332""#33332""#33332""#33332""#33332""#33332""' +'#33332""#33332"!'#17#17#17#17#17#17#18'!'#17#17#17#17#17#17#18'$DDDDDDB!'#17 +#17#17#17#17#17#18'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""' ]); LazarusResources.Add('VT_CHECK_DARK','BMP',[ 'BM'#246#12#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#4#0#0#0#0#0 +#128#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255#0#255#0 +#192#192#192#0#128#128#128#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'""""""""""""""""""""""""""""""""""""""""""""""DDB"""""DDB"""""DDB"""""DDB""' +'"""DDB"""""DDB"""""DDB"""""DDB"""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$D' +'DDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB"!DDDDDDB!DDDDDDB$'#17 +#17#17#17#17#17#18'!DDDDDDB""""""""""D'#17#17#20'""""D'#17#17#20'""""D334"""' +'"D334""""D'#17#17#20'""""D'#17#17#20'""""D334""""D334"""@'#17#17#17#17#20'"' +'"@'#17#17#17#17#20'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20 +'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334"!3' +'33333B!333333B$333333'#18'!333333B"""""""""$'#1#17#17#17'B""$'#1#17#17#17'B' +'""$'#3'333B""$'#3'333B""$'#1#20'D'#17'B""$'#1#20'D'#17'B""$'#3'4D3B""$'#3'4' +'D3B""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#16#1#17#0#20 +'""@'#16#1#17#0#20'""@0'#3'3'#0'4""@0'#3'3'#0'4""@'#16#0#0#0#20'""@'#16#0#0#0 +#20'""@0'#0#0#0'4""@4DDD4"!333333B!333333B$333333'#18'!333333B""""""""" '#17 +#17#17#17#20'"" '#17#17#17#17#20'"" 33334"" 33334"" '#17#0#0#1#20'"" '#17#0#0 +#1#20'"" 3'#0#0#3'4"" 3'#0#0#3'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@3' +'3334""@33334""@'#16#0#16#0#20'""@'#16#0#16#0#20'""@0'#0'0'#0'4""@0'#0'0'#0 +'4""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!333333B!333333B$3' +'33'#3'33'#18'!333333B"""""""""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@3333' +'4""@33334""@'#20#0#0#4#20'""@'#20#0#0#4#20'""@4'#0#0#4'4""@4'#0#0#4'4""@'#17 +#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#0#0#1#20'""@'#17#0#0 +#1#20'""@3'#0#0#3'4""@3'#0#0#3'4""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0 +'4""@4DDD4"!330333B!330333B$330'#0'33'#18'!334333B"""""""""@'#17#17#17#17#20 +'""@'#17#17#17#17#20'""@33334""@33334""@'#20#0#0#4#20'""@'#20#0#0#4#20'""@4' +#0#0#4'4""@4'#0#0#4'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@3333' +'4""@'#17#16#0#17#20'""@'#17#16#0#17#20'""@30'#0'34""@30'#0'34""@'#16#0#0#0 +#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!33'#0#3'33B!33'#0#3'33B$33'#0#0#3 +'3'#18'!33DC33B"""""""""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@333' +'34""@'#20#0#0#4#20'""@'#20#0#0#4#20'""@4'#0#0#4'4""@4'#0#0#4'4""@'#17#17#17 +#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#0#0#1#20'""@'#17#0#0#1#20 +'""@3'#0#0#3'4""@3'#0#0#3'4""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""' +'@4DDD4"!30'#0#0'33B!30'#0#0'33B$30'#0#0#0'3'#18'!34DD33B"""""""""@'#17#17#17 +#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#0#0#1#20'""@'#17#0#0#1#20 +'""@3'#0#0#3'4""@3'#0#0#3'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334"' +'"@33334""@'#16#0#16#0#20'""@'#16#0#16#0#20'""@0'#0'0'#0'4""@0'#0'0'#0'4""@' +#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!3'#0#0#0#3'3B!3'#0#0#0#3 +'3B$333333'#18'!3DDDC3B""""""""" A'#17#17#17'B"" A'#17#17#17'B"" C333B"" C33' +'3B"" A'#20'D'#17'B"" A'#20'D'#17'B"" C4D3B"" C4D3B""@'#17#17#17#17#20'""@' +#17#17#17#17#20'""@33334""@33334""@'#16#1#17#0#20'""@'#16#1#17#0#20'""@0'#3 +'3'#0'4""@0'#3'3'#0'4""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4' +'"!333333B!333333B$333333'#18'!333333B"""""""""$'#4#17#17#16'B""$'#4#17#17#16 +'B""$'#4'330B""$'#4'330B""$'#4#17#17#16'B""$'#4#17#17#16'B""$'#4'330B""$'#4 +'330B""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#17#17#17 +#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17 +#20'""@33334""@33334"!333333B!333333B$333333'#18'!333333B""""""""""@'#0#0#4 +'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0 +#4'""""@'#0#0#4'"""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4 +'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4 +'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'"!333333B!333333B$333333'#18'!' +'333333B"""""""""""DD""""""DD""""""DD""""""DD""""""DD""""""DD""""""DD""""""D' +'D""""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB' +'""$DDDDB""$DDDDB""$DDDDB"!'#17#17#17#17#17#17#18'!'#17#17#17#17#17#17#18'$D' +'DDDDDB!'#17#17#17#17#17#17#18'"""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' ,'"""""""""""""""""""""""""""""""""""""""""""""""""""""""' ]); LazarusResources.Add('VT_FLAT','BMP',[ 'BM'#246#12#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#4#0#0#0#0#0 +#128#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255#0#255#0 +#192#192#192#0#128#128#128#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'""""""""""""""""""""""""""""""""""""""""""""""'#0#0'""""""'#0#0'""""""'#0#0 +'""""""'#0#0'""""""'#0#0'""""""'#0#0'""""""'#0#0'""""""'#0#0'""" '#0#0#0#0#0 +#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0 +#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0 +#0#0#0#0#0'" '#0#0#0#0#0#0'""'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0 +#2'"'#0#0#0#0#0#0#2'""""""""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0 +#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'"" '#0#0#0#0#0#0 +'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0 +#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0 +#0#0#0#0'" '#0#0#0#0#0#0'""'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'"'#0'33333'#2'"' +#0#0#0#0#0#0#2'""""""""" '#0#17#17#0#2'"" '#0#17#17#0#2'"" '#0'33'#0#2'"" '#0 +'33'#0#2'"" '#0#17#17#0#2'"" '#0#17#17#0#2'"" '#0'33'#0#2'"" '#0'33'#0#2'" ' +#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1#17#17 +#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1#17#17#17#17#0 +'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'""'#0#17#17#17#17#16#2'"'#0 +#17#17#17#17#16#2'"'#0#17#17#17#17#19#2'"'#0'33330'#2'""""""""" '#1#17#17#16 +#2'"" '#1#17#17#16#2'"" '#3'330'#2'"" '#3'330'#2'"" '#1#17#17#16#2'"" '#1#17 +#17#16#2'"" '#3'330'#2'"" '#3'330'#2'" '#1#17#17#17#17#0'" '#1#17#17#17#17#0 +'" '#3'3333'#0'" '#3'3333'#0'" '#1#17#1#17#17#0'" '#1#17#1#17#17#0'" '#3'3'#3 +'33'#0'" '#3'3'#3'33'#0'" '#1#0#0#0#1#0'" '#1#0#0#0#1#0'" '#3#0#0#0#3#0'" '#3 +'DDDC'#0'""'#0#17#17#17#17#16#2'"'#0#17#17#17#17#16#2'"'#0#17#17#17#17#19#2 +'"'#0'33330'#2'"""""""""'#0#17#17#17#17#0'""'#0#17#17#17#17#0'""'#0'3333'#0 +'""'#0'3333'#0'""'#0#17#16#1#17#0'""'#0#17#16#1#17#0'""'#0'30'#3'3'#0'""'#0 +'30'#3'3'#0'" '#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333' +#0'" '#1#16#0#17#17#0'" '#1#16#0#17#17#0'" '#3'0'#0'33'#0'" '#3'0'#0'33'#0'"' +' '#1#0#0#0#1#0'" '#1#0#0#0#1#0'" '#3#0#0#0#3#0'" '#3'DDDC'#0'""'#0#17#17#1 +#17#16#2'"'#0#17#17#1#17#16#2'"'#0#17#17#1#17#19#2'"'#0'33'#3'30'#2'""""""""' +'"'#0#17#17#17#17#0'""'#0#17#17#17#17#0'""'#0'3333'#0'""'#0'3333'#0'""'#0#17 +#0#0#17#0'""'#0#17#0#0#17#0'""'#0'3'#0#0'3'#0'""'#0'3'#0#0'3'#0'" '#1#17#17 +#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1#0#0#1#17#0'" ' +#1#0#0#1#17#0'" '#3#0#0#3'3'#0'" '#3#0#0#3'3'#0'" '#1#0#0#0#1#0'" '#1#0#0#0#1 +#0'" '#3#0#0#0#3#0'" '#3'DDDC'#0'""'#0#17#16#0#17#16#2'"'#0#17#16#0#17#16#2 +'"'#0#17#16#0#17#19#2'"'#0'30'#0'30'#2'"""""""""'#0#17#17#17#17#0'""'#0#17#17 +#17#17#0'""'#0'3333'#0'""'#0'3333'#0'""'#0#17#0#0#17#0'""'#0#17#0#0#17#0'""' +#0'3'#0#0'3'#0'""'#0'3'#0#0'3'#0'" '#1#17#17#17#17#0'" '#1#17#17#17#17#0'" ' +#3'3333'#0'" '#3'3333'#0'" '#1#0#16#0#17#0'" '#1#0#16#0#17#0'" '#3#0'0'#0'3' +#0'" '#3#0'0'#0'3'#0'" '#1#0#0#0#1#0'" '#1#0#0#0#1#0'" '#3#0#0#0#3#0'" '#3'D' +'DDC'#0'""'#0#17#0#0#1#16#2'"'#0#17#0#0#1#16#2'"'#0#17#0#0#1#19#2'"'#0'3'#0#0 +#3'0'#2'"""""""""'#0#17#17#17#17#0'""'#0#17#17#17#17#0'""'#0'3333'#0'""'#0'3' +'333'#0'""'#0#17#16#1#17#0'""'#0#17#16#1#17#0'""'#0'30'#3'3'#0'""'#0'30'#3'3' +#0'" '#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1 +#1#17#0#1#0'" '#1#1#17#0#1#0'" '#3#3'3'#0#3#0'" '#3#3'3'#0#3#0'" '#1#0#0#0#1 +#0'" '#1#0#0#0#1#0'" '#3#0#0#0#3#0'" '#3'DDDC'#0'""'#0#16#0#0#0#16#2'"'#0#16 +#0#0#0#16#2'"'#0#16#0#0#0#19#2'"'#0'0'#0#0#0'0'#2'""""""""" '#1#17#17#16#2'"' +'" '#1#17#17#16#2'"" '#3'330'#2'"" '#3'330'#2'"" '#1#17#17#16#2'"" '#1#17#17 +#16#2'"" '#3'330'#2'"" '#3'330'#2'" '#1#17#17#17#17#0'" '#1#17#17#17#17#0'" ' +#3'3333'#0'" '#3'3333'#0'" '#1#17#17#16#1#0'" '#1#17#17#16#1#0'" '#3'330'#3#0 +'" '#3'330'#3#0'" '#1#0#0#0#1#0'" '#1#0#0#0#1#0'" '#3#0#0#0#3#0'" '#3'DDDC'#0 +'""'#0#17#17#17#17#16#2'"'#0#17#17#17#17#16#2'"'#0#17#17#17#17#19#2'"'#0'333' +'30'#2'""""""""" '#0#17#17#0#2'"" '#0#17#17#0#2'"" '#0'33'#0#2'"" '#0'33'#0#2 +'"" '#0#17#17#0#2'"" '#0#17#17#0#2'"" '#0'33'#0#2'"" '#0'33'#0#2'" '#1#17#17 +#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1#17#17#17#1#0 +'" '#1#17#17#17#1#0'" '#3'333'#3#0'" '#3'333'#3#0'" '#1#0#0#0#1#0'" '#1#0#0#0 +#1#0'" '#3#0#0#0#3#0'" '#3'DDDC'#0'""'#0#17#17#17#17#16#2'"'#0#17#17#17#17#16 +#2'"'#0#17#17#17#17#19#2'"'#0'33330'#2'""""""""""'#0#0#0#0'""""'#0#0#0#0'"""' ,'"'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0 +#0#0'"" '#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" ' +#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1#17#17 +#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'""'#0#17#17#17#17#16 +#2'"'#0#17#17#17#17#16#2'"'#0#17#17#17#17#19#2'"'#0'33330'#2'"""""""""""'#0#0 +'""""""'#0#0'""""""'#0#0'""""""'#0#0'""""""'#0#0'""""""'#0#0'""""""'#0#0'"""' +'"""'#0#0'""" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0 +'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0 +#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'""'#0#0#0#0#0#0#2'"'#0#0 +#0#0#0#0#2'"'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'"""""""""""""""""""""""""""""""' +'""""""""""""""""""""""""""""""""""""""""" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" ' +#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0 +'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0 +#0#0'""'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'""""""""""""""""""""""""""""""""""""""""""""""""' ]); LazarusResources.Add('VT_TICK_DARK','BMP',[ 'BM'#246#12#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#4#0#0#0#0#0 +#128#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255#0#255#0 +#192#192#192#0#128#128#128#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'""""""""""""""""""""""""""""""""""""""""""""""DDB"""""DDB"""""DDB"""""DDB""' +'"""DDB"""""DDB"""""DDB"""""DDB"""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$D' +'DDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB"!DDDDDDB!DDDDDDB$'#17 +#17#17#17#17#17#18'!DDDDDDB""""""""""D'#17#17#20'""""D'#17#17#20'""""D334"""' +'"D334""""D'#17#17#20'""""D'#17#17#20'""""D334""""D334"""@'#17#17#17#17#20'"' +'"@'#17#17#17#17#20'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20 +'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334"!3' +'33333B!333333B$333333'#18'!333333B"""""""""$'#1#17#17#17'B""$'#1#17#17#17'B' +'""$'#3'333B""$'#3'333B""$'#1#20'D'#17'B""$'#1#20'D'#17'B""$'#3'4D3B""$'#3'4' +'D3B""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#16#17#17 +#20'""@'#17#16#17#17#20'""@30334""@30334""@'#16#0#0#0#20'""@'#16#0#0#0#20'""' +'@0'#0#0#0'4""@4DDD4"!333333B!333333B$333333'#18'!333333B""""""""" '#17#17#17 +#17#20'"" '#17#17#17#17#20'"" 33334"" 33334"" '#17#0#0#1#20'"" '#17#0#0#1#20 +'"" 3'#0#0#3'4"" 3'#0#0#3'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334"' +'"@33334""@'#17#0#1#17#20'""@'#17#0#1#17#20'""@3'#0#3'34""@3'#0#3'34""@'#16#0 +#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!333333B!333333B$333'#3'33'#18 +'!333333B"""""""""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@' +#20#0#0#4#20'""@'#20#0#0#4#20'""@4'#0#0#4'4""@4'#0#0#4'4""@'#17#17#17#17#20 +'""@'#17#17#17#17#20'""@33334""@33334""@'#16#0#0#17#20'""@'#16#0#0#17#20'""@' +'0'#0#0'34""@0'#0#0'34""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD' +'4"!330333B!330333B$330'#0'33'#18'!334333B"""""""""@'#17#17#17#17#20'""@'#17 +#17#17#17#20'""@33334""@33334""@'#20#0#0#4#20'""@'#20#0#0#4#20'""@4'#0#0#4'4' +'""@4'#0#0#4'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#16 +#1#0#1#20'""@'#16#1#0#1#20'""@0'#3#0#3'4""@0'#3#0#3'4""@'#16#0#0#0#20'""@'#16 +#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!33'#0#3'33B!33'#0#3'33B$33'#0#0#3'3'#18'!33' +'DC33B"""""""""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#20 +#0#0#4#20'""@'#20#0#0#4#20'""@4'#0#0#4'4""@4'#0#0#4'4""@'#17#17#17#17#20'""@' +#17#17#17#17#20'""@33334""@33334""@'#17#17#16#0#20'""@'#17#17#16#0#20'""@330' +#0'4""@330'#0'4""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!30'#0 +#0'33B!30'#0#0'33B$30'#0#0#0'3'#18'!34DD33B"""""""""@'#17#17#17#17#20'""@'#17 +#17#17#17#20'""@33334""@33334""@'#17#0#0#1#20'""@'#17#0#0#1#20'""@3'#0#0#3'4' +'""@3'#0#0#3'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17 +#17#17#0#20'""@'#17#17#17#0#20'""@333'#0'4""@333'#0'4""@'#16#0#0#0#20'""@'#16 +#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!3'#0#0#0#3'3B!3'#0#0#0#3'3B$333333'#18'!3DD' +'DC3B""""""""" A'#17#17#17'B"" A'#17#17#17'B"" C333B"" C333B"" A'#20'D'#17'B' +'"" A'#20'D'#17'B"" C4D3B"" C4D3B""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@' +'33334""@33334""@'#17#17#17#16#20'""@'#17#17#17#16#20'""@33304""@33304""@'#16 +#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!333333B!333333B$333333'#18 +'!333333B"""""""""$'#4#17#17#16'B""$'#4#17#17#16'B""$'#4'330B""$'#4'330B""$' +#4#17#17#16'B""$'#4#17#17#16'B""$'#4'330B""$'#4'330B""@'#17#17#17#17#20'""@' +#17#17#17#17#20'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@3' +'3334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334"!33333' +'3B!333333B$333333'#18'!333333B""""""""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4 +'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'"""@'#0#0#0 +#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0 +#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4 +'""@'#0#0#0#0#4'"!333333B!333333B$333333'#18'!333333B"""""""""""DD""""""DD""' +'""""DD""""""DD""""""DD""""""DD""""""DD""""""DD""""$DDDDB""$DDDDB""$DDDDB""$' +'DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB"!'#17 +#17#17#17#17#17#18'!'#17#17#17#17#17#17#18'$DDDDDDB!'#17#17#17#17#17#17#18'"' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' ,'""""""""""""""""""""""""' ]); LazarusResources.Add('VT_TICK_LIGHT','BMP',[ 'BM'#246#12#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#4#0#0#0#0#0 +#128#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255#0#255#0 +#192#192#192#0#128#128#128#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128 +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255 +#255#255#0'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'""""""""""""""""""""""""""""""""""""""""""""""332"""""332"""""332"""""332""' +'"""332"""""332"""""332"""""332"""#33332""#33332""#33332""#33332""#33332""#3' +'3332""#33332""#33332""#33332""#33332""#33332""#33332"!DDDDDDB!DDDDDDB$'#17 +#17#17#17#17#17#18'!DDDDDDB""""""""""3'#17#17#19'""""3'#17#17#19'""""3333"""' +'"3333""""3'#17#17#19'""""3'#17#17#19'""""3333""""3333"""4'#17#17#17#17#19'"' +'"4'#17#17#17#17#19'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19 +'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333"!3' +'33333B!333333B$333333'#18'!333333B"""""""""#A'#17#17#17'2""#A'#17#17#17'2""' +'#C3332""#C3332""#A'#19'3'#17'2""#A'#19'3'#17'2""#C3332""#C3332""4'#17#17#17 +#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17#20#17#17#19'""4'#17#20#17 +#17#19'""434333""434333""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!333' +'333B!333333B$333333'#18'!333333B"""""""""$'#17#17#17#17#19'""$'#17#17#17#17 +#19'""$33333""$33333""$'#17'DDA'#19'""$'#17'DDA'#19'""$3DDC3""$3DDC3""4'#17 +#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17'DA'#17#19'""4'#17'D' +'A'#17#19'""43DC33""43DC33""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!' +'333333B!333333B$333'#3'33'#18'!333333B"""""""""4'#17#17#17#17#19'""4'#17#17 +#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'#19'""43DDC3""43DDC3""' +'4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#20'DD'#17#19'""4' +#20'DD'#17#19'""44DD33""44DD33""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DD' +'D3"!330333B!330333B$330'#0'33'#18'!334333B"""""""""4'#17#17#17#17#19'""4'#17 +#17#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'#19'""43DDC3""43DDC' +'3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#20'ADA'#19'""' +'4'#20'ADA'#19'""44CDC3""44CDC3""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44D' +'DD3"!33'#0#3'33B!33'#0#3'33B$33'#0#0#3'3'#18'!33DC33B"""""""""4'#17#17#17#17 +#19'""4'#17#17#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'#19'""43' +'DDC3""43DDC3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17 +#17#20'D'#19'""4'#17#17#20'D'#19'""4334D3""4334D3""4'#20'DDD'#19'""4'#20'DDD' +#19'""44DDD3""44DDD3"!30'#0#0'33B!30'#0#0'33B$30'#0#0#0'3'#18'!34DD33B""""""' +'"""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17'DDA'#19'""' +'4'#17'DDA'#19'""43DDC3""43DDC3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433' +'333""433333""4'#17#17#17'D'#19'""4'#17#17#17'D'#19'""4333D3""4333D3""4'#20 +'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!3'#0#0#0#3'3B!3'#0#0#0#3'3B$33333' +'3'#18'!3DDDC3B"""""""""$1'#17#17#17'2""$1'#17#17#17'2""$33332""$33332""$1' +#19'3'#17'2""$1'#19'3'#17'2""$33332""$33332""4'#17#17#17#17#19'""4'#17#17#17 +#17#19'""433333""433333""4'#17#17#17#20#19'""4'#17#17#17#20#19'""433343""433' +'343""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!333333B!333333B$333333' +#18'!333333B"""""""""#C'#17#17#20'2""#C'#17#17#20'2""#C3342""#C3342""#C'#17 +#17#20'2""#C'#17#17#20'2""#C3342""#C3342""4'#17#17#17#17#19'""4'#17#17#17#17 +#19'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333' +'""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333"!333333B!333333B$3' +'33333'#18'!333333B""""""""""4DDC""""4DDC""""4DDC""""4DDC""""4DDC""""4DDC"""' +'"4DDC""""4DDC"""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DD' +'DDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC"!333333B!333333B$333333'#18'!333333B"""' +'""""""""33""""""33""""""33""""""33""""""33""""""33""""""33""""""33""""#3333' +'2""#33332""#33332""#33332""#33332""#33332""#33332""#33332""#33332""#33332""' +'#33332""#33332"!'#17#17#17#17#17#17#18'!'#17#17#17#17#17#17#18'$DDDDDDB!'#17 +#17#17#17#17#17#18'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' +'"""""""""""""""""""""""""""""""""""""""""""' ]); LazarusResources.Add('VT_UTILITIES','BMP',[ 'BM6'#13#0#0#0#0#0#0'6'#4#0#0'('#0#0#0#144#0#0#0#16#0#0#0#1#0#8#0#0#0#0#0#0#0 +#0#0#19#11#0#0#19#11#0#0#0#1#0#0#0#1#0#0'www'#255'%r'#207#255'*u'#208#255#255 +#0#255#255#246#24#248#255#225'V'#232#255'O'#145#227#255'X'#150#227#255#134 +#134#134#255#140#140#140#255#147#147#147#255#154#154#154#255#190#190#190#255 +#184#199#203#255#197#197#197#255#204#204#204#255#195#210#213#255#221#221#221 +#255#240#251#255#255#255#255#255#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#17#15#14#14#14#15#17#3#3#3#3#3 +#3#3#3#3#17#15#14#14#14#15#17#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#17#12#11#9#9#9#11#12#17#3#3#3#3#3#3 +#3#17#12#11#9#9#9#11#12#17#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#17#12#18#18#18#18#18#0#10#12#17#3#3#3#3#3 +#17#12#18#18#18#18#18#0#10#12#17#3#3#3#3#3#3#3#3#3#3#19#3#3#3#3#3#3#3#3#3#3#3 +#19#19#19#19#19#19#19#19#19#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#15#18#18#18#18#8#18#18#0#11#15 +#3#3#3#3#3#15#18#18#8#18#18#18#18#0#11#15#3#3#3#3#3#3#3#3#3#8#14#19#3#3#3#3#3 +#3#3#3#3#3#3#8#14#14#14#14#14#19#3#3#3#3#3#3#3#3#3#3#3#3#11#3#3#3#3#3#3#3#3#3 +#3#3#11#11#11#11#11#11#11#11#11#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#18#18#18#18#8 +#8#18#18#18#9#14#3#3#3#3#3#18#18#18#8#8#18#18#18#18#9#14#3#3#3#3#3#3#3#3#3#8 +#14#19#3#3#3#3#3#3#3#3#3#3#3#8#14#14#14#14#14#19#3#3#3#3#3#3#3#3#3#3#3#11#11 +#11#3#3#3#3#3#3#3#3#3#3#3#11#11#11#11#11#11#11#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 ,#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#18#18#18#8#8#8#18#18#18#9#14#3#3#3#3#3#18#18#18#8#8#8#18#18#18#9#14#3#3 +#3#3#3#3#3#3#8#14#14#14#19#3#3#3#3#3#3#3#3#3#3#3#8#14#14#14#19#3#3#3#3#3#3#3 +#3#3#3#3#11#11#11#11#11#3#3#3#3#3#3#3#3#3#3#3#11#11#11#11#11#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#18#18#8#8#8#8#18#18#18#9#14#3#3#3#3#3#18#18#18#8#8#8#8 +#18#18#9#14#3#3#3#3#3#3#3#3#8#14#14#14#19#3#3#3#3#3#3#3#3#3#3#3#8#14#14#14#19 +#3#3#3#3#3#3#3#3#3#3#11#11#11#11#11#11#11#3#3#3#3#3#3#3#3#3#3#3#11#11#11#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#18#18#18#8#8#8#18#18#18#11#15#3#3#3#3#3#18 +#18#18#8#8#8#18#18#18#11#15#3#3#3#3#3#3#3#8#14#14#14#14#14#19#3#3#3#3#3#3#3#3 +#3#3#3#8#14#19#3#3#3#3#3#3#3#3#3#3#11#11#11#11#11#11#11#11#11#3#3#3#3#3#3#3#3 +#3#3#3#11#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#18#18#18#18#8#8#18#18#18#12 +#17#3#3#3#3#3#18#18#18#8#8#18#18#18#18#12#17#3#3#3#3#3#3#3#8#14#14#14#14#14 +#19#3#3#3#3#3#3#3#3#3#3#3#8#14#19#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#18#18#18#18#8#18 +#18#12#17#3#3#3#3#3#3#3#18#18#8#18#18#18#18#12#17#3#3#3#3#3#3#3#8#8#8#8#8#8#8 +#8#19#3#3#3#3#3#3#3#3#3#3#3#19#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#18#18#18#18#18 +#15#17#3#3#3#3#3#3#3#3#3#18#18#18#18#18#15#17#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#4#5#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#13#13#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1 +#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#13#13#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#16#1#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6 +#6#6#6#6#6#6#6#6#2#16#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3 +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#1#6#7#7#7#7#7#7 +#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7 +#6#1 ]); LazarusResources.Add('VT_XP','BMP',[ 'BM8K'#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#24#0#0#0#0#0#0#0#0 +#0#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#238#231#223#233#224#214#231#221#211 +#233#224#214#238#231#223#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#238#231#223#233 +#224#214#231#221#211#233#224#214#238#231#223#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#238#231#223#233#224#214#231#221#211#233#224#214#238#231#223#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 ,#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#238#231#223#233#224#214#231#221#211#233 +#224#214#238#231#223#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#238#231#223#233#224 +#214#231#221#211#233#224#214#238#231#223#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#238#231#223#233#224#214#231#221#211#233#224#214#238#231#223#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#225#217#237'_'#140'y#oL'#6'b7'#6 +'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#24'iDX'#138't'#238#244#250#255 +#0#255#236#216#223'_'#140'y#oL'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6 +'b7'#6'b7'#24'iDX'#138't'#248#241#243#255#0#255#225#217#237'_'#140'y#oL'#6'b' +'7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#24'iDX'#138't'#238#244 +#250#255#0#255#255#255#255#184#196#202#184#196#202#184#196#202#184#196#202 +#184#196#202#184#196#202#184#196#202#184#196#202#184#196#202#184#196#202#184 +#196#202#184#196#202#184#196#202#255#255#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#226#214#201#220#206#191#217#202#186#216#201#184#217#202#186#220 +#206#191#226#214#201#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#224#212#198#217#201#185#213#196#178#211 +#194#175#213#196#178#217#201#185#224#212#198#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#226#214#201#220 +#206#191#217#202#186#216#201#184#217#202#186#220#206#191#226#214#201#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#226#214#201#220#206#191#217#202#186#216#201#184#217#202 +#186#220#206#191#226#214#201#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#226#214#201#220#206#191#217#202 +#186#216#201#184#217#202#186#220#206#191#226#214#201#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#226#214 +#201#220#206#191#217#202#186#216#201#184#217#202#186#220#206#191#226#214#201 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 ,#255'V'#17#0'V'#17#0'U'#19#0'U'#16#0'V'#17#0'R'#14#1'W'#16#2'T'#18#0'U'#15#2 +'U'#16#0'W'#18#0'T'#18#0'V'#17#0#255#0#255#255#0#255#255#0#255'W'#19#0'W'#18 +#1'Y'#19#2'^'#18#0'W'#20#0'V'#18#0'W'#18#1'V'#17#0'W'#19#0'X'#17#3'U'#21#0'Z' +#21#2'X'#18#1#255#0#255#255#0#255#255#0#255'V'#19#0'T'#19#4'W'#18#1'W'#18#1 +'Z'#18#0'X'#19#0'W'#17#0'W'#18#0'Z'#18#1'X'#19#0'V'#22#0'W'#18#0'X'#20#1#255 +#0#255#255#0#255#255#0#255#168#183#185#170#183#185#171#184#186#169#184#186 +#168#183#185#170#183#185#169#182#184#168#183#185#169#184#187#170#183#185#171 +#184#186#168#183#185#168#183#185#255#0#255#255#0#255#255#0#255'W'#18#0'U'#18 +#3'R'#19#0'V'#18#0'U'#19#0'U'#15#0'U'#19#0'T'#18#0'S'#17#0'Y'#17#0'T'#18#0'U' +#16#1'V'#19#0#255#0#255#255#0#255#255#0#255'U'#17#4'Y'#20#0'W'#20#0'Y'#16#2 +'U'#17#0'Z'#17#3'V'#15#1'Z'#19#0'U'#19#1'U'#17#0'X'#18#1'X'#20#1'Y'#17#0#255 +#0#255#255#0#255#255#0#255'X'#19#0'U'#19#0'X'#18#1'W'#20#0'U'#16#1'X'#19#0'X' +#18#1'U'#19#0'Y'#17#0'X'#21#0'V'#18#0'U'#19#0'Y'#20#1#255#0#255#255#0#255#255 +#0#255#168#183#185#170#183#185#171#183#183#170#183#185#171#184#186#169#182 +#184#170#183#185#169#185#184#169#182#184#170#183#185#168#183#185#167#182#184 +#170#183#185#255#0#255#255#0#255#255#0#255'W'#18#0'U'#18#3'R'#19#0'V'#18#0'U' +#19#0'U'#15#0'U'#19#0'T'#18#0'S'#17#0'Y'#17#0'T'#18#0'U'#16#1'V'#19#0#255#0 +#255#255#0#255#255#0#255'U'#17#4'Y'#20#0'W'#20#0'Y'#16#2'U'#17#0'Z'#17#3'V' +#15#1'Z'#19#0'U'#19#1'U'#17#0'X'#18#1'X'#20#1'Y'#17#0#255#0#255#255#0#255#255 +#0#255'X'#19#0'U'#19#0'X'#18#1'W'#20#0'U'#16#1'X'#19#0'X'#18#1'U'#19#0'Y'#17 +#0'X'#21#0'V'#18#0'U'#19#0'Y'#20#1#255#0#255#255#0#255#255#0#255#168#183#185 +#170#183#185#171#183#183#170#183#185#171#184#186#169#182#184#170#183#185#169 +#185#184#169#182#184#170#183#185#168#183#185#167#182#184#170#183#185#255#0 +#255#255#0#255#255#0#255'N'#131'lD}c'#152#178#199#184#209#227#184#209#227#184 +#209#227#184#209#227#184#209#227#184#209#227#184#209#227#183#209#226#182#208 +#226#164#177#201'B|aU'#136'r'#255#0#255'N'#131'ludu%r'#207'%r'#207'%r'#207'%' +'r'#207'%r'#207'%r'#207'%r'#207'%r'#207'%r'#207'%r'#207'%r'#207'rbsU'#136'r' +#255#0#255'N'#131'lG'#130'f'#166#203#216#226#243#246#228#244#248#228#244#248 +#228#244#248#228#244#248#228#244#248#228#244#248#228#245#248#229#245#248#190 +#218#228'H'#132'iU'#136'r'#255#0#255#184#196#202#201#211#217#221#231#235#233 +#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242 +#246#233#242#246#233#242#246#225#235#239#201#211#217#184#196#202#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#223#210#196#185#153#131#154'jN'#129'D#q,'#8#129'D#'#154 +'jN'#185#153#131#223#210#196#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#220#205#190#181#147'{'#151'eH'#127'A'#31'q,'#7#127 +'A'#31#151'eH'#181#147'{'#220#205#190#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#223#210#196#185#153#131#154'jN'#129'D#q,'#8 +#129'D#'#154'jN'#185#153#131#223#210#196#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#213#221#222#197#208 +#210#188#200#203#197#208#210#213#221#222#233#237#238#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#223#210#196#185#153 +#131#154'jN'#129'D#q,'#8#129'D#'#154'jN'#185#153#131#223#210#196#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#223#210#196#185 +#153#131#154'jN'#129'D#q,'#8#129'D#'#154'jN'#185#153#131#223#210#196#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#223#210#196 +#185#153#131#154'jN'#129'D#q,'#8#129'D#'#154'jN'#185#153#131#223#210#196#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#208#216#215#190#201#199#180#192#190#190#201#199#208#216#215#230 +#234#234#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255'V'#17#0#244#249#247#248#247#251#248#248#248#248#248#248#251#249#249#247 +#248#246#248#248#248#247#249#249#248#248#248#245#247#248#248#247#249'V'#17#0 +#255#0#255#255#0#255#255#0#255'U'#20#0#136#195#251#132#193#249#130#194#248 +#135#195#249#135#195#249#132#199#244#138#195#250#132#196#244#136#191#252#130 +#195#246#132#197#248'X'#20#0#255#0#255#255#0#255#255#0#255'Z'#18#0#201#210 +#213#197#211#210#198#210#210#198#210#214#196#208#208#198#212#211#198#209#213 +#199#211#213#198#209#213#197#211#210#200#213#211'V'#20#2#255#0#255#255#0#255 +#255#0#255#167#182#184#226#239#241#227#239#241#225#238#240#225#238#240#225 +#237#239#226#239#241#225#238#240#225#238#240#226#238#240#226#238#240#227#240 +#242#169#182#184#255#0#255#255#0#255#255#0#255'V'#17#0#251#249#248#250#248 +#247#245#247#247#244#250#245#248#249#247#250#248#248#248#247#249#247#249#250 +#247#246#248#250#248#247#249#247#246'V'#17#2#255#0#255#255#0#255#255#0#255'X' +#18#1#133#196#246#130#194#249#132#195#245#137#196#246#138#196#248#135#198#248 ,#132#197#248#136#196#250#133#192#248#136#196#250#132#195#246'Z'#20#0#255#0 +#255#255#0#255#255#0#255'W'#18#1#197#213#212#198#210#216#197#210#208#199#210 +#214#199#211#213#196#208#212#200#210#210#192#210#209#197#209#211#200#211#215 +#199#211#213'X'#18#1#255#0#255#255#0#255#255#0#255#170#183#185#227#239#239 +#227#237#237#226#238#238#226#238#240#227#239#241#225#237#239#226#240#239#227 +#239#241#227#239#241#225#238#240#226#239#241#171#184#186#255#0#255#255#0#255 +#255#0#255'V'#17#0#251#249#248#250#248#247#245#247#247#244#250#245#248#249 +#247#250#248#248#248#247#249#247#249#250#247#246#248#250#248#247#249#247#246 +'V'#17#2#255#0#255#255#0#255#255#0#255'X'#18#1#133#196#246#130#194#249#132 +#195#245#137#196#246#138#196#248#135#198#248#132#197#248#136#196#250#133#192 +#248#136#196#250#132#195#246'Z'#20#0#255#0#255#255#0#255#255#0#255'W'#18#1 +#197#213#212#198#210#216#197#210#208#199#210#214#199#211#213#196#208#212#200 +#210#210#192#210#209#197#209#211#200#211#215#199#211#213'X'#18#1#255#0#255 +#255#0#255#255#0#255#170#183#185#227#239#239#227#237#237#226#238#238#226#238 +#240#227#239#241#225#237#239#226#240#239#227#239#241#227#239#241#225#238#240 +#226#239#241#171#184#186#255#0#255#255#0#255#255#0#255#24'iD'#179#200#215#201 +#225#236#200#224#234#200#224#235#201#225#236#201#225#236#201#225#236#201#225 +#236#201#225#236#200#224#235#198#221#234#193#216#230#170#185#205#24'iD'#255#0 +#255#24'iDc'#153#221'O'#145#227'O'#145#227'N'#144#227'O'#145#227'O'#145#227 +'O'#145#227'O'#145#227'O'#145#227'O'#145#227'O'#145#227'O'#145#227'a'#152#219 +#24'iD'#255#0#255#24'iD'#176#196#212#211#233#238#216#236#242#217#237#242#217 +#237#242#216#236#242#216#236#242#216#236#242#217#237#242#217#237#242#219#238 +#243#221#238#244#183#208#222#24'iD'#255#0#255#184#196#202#225#235#239#233#242 +#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246 +#233#242#246#233#242#246#233#242#246#233#242#246#225#235#239#184#196#202#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#213#195#179#162'v['#150'dH'#192#162#143#228#215#207#249#247 +#245#228#215#207#192#162#143#150'dH'#162'v['#213#195#179#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#210#190#173#158'pT'#129'g`~'#147#176'q'#167 +#223'c'#171#243'q'#167#223'~'#147#176#129'g`'#158'pT'#210#190#173#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#213#195#179#162'v['#150'kR'#180#161 +#147#196#192#187#200#203#203#196#192#187#180#161#147#150'kR'#162'v['#213#195 +#179#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#217#224#226 +#208#217#219#228#233#234#244#246#247#254#254#254#244#246#247#228#233#234#208 +#217#219#217#224#226#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#213#195#179#162'v['#150'dH'#192#162#143#228#215#207#249#247#245#228#215 +#207#192#162#143#150'dH'#162'v['#213#195#179#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#213#195#179#162'v['#150'dH'#192#162#143#228#215#207#249 +#247#245#228#215#207#192#162#143#150'dH'#162'v['#213#195#179#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#213#195#179#162'v['#150'dH'#192#162#143 +#228#215#207#249#247#245#228#215#207#192#162#143#150'dH'#162'v['#213#195#179 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#213#220#219#203 +#212#210#225#230#229#243#245#245#253#254#254#243#245#245#225#230#229#203#212 +#210#213#220#219#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +'V'#17#0#246#248#249#248#248#248#246#249#247#248#248#248#249#247#247#249#248 +#250#246#248#249#250#248#248#246#248#248#248#249#247#249#249#249'V'#17#0#255 +#0#255#255#0#255#255#0#255'Y'#20#1#129#195#246#248#248#248#244#249#247#245 +#247#247#249#248#252#249#246#248#250#249#245#244#249#248#248#247#249#250#248 +#248#133#196#246'W'#18#3#255#0#255#255#0#255#255#0#255'W'#18#1#197#209#213 +#195#208#210#196#205#209#194#204#211#194#205#209#196#205#209#193#207#206#194 +#206#208#195#208#210#195#207#209#199#210#214'W'#18#1#255#0#255#255#0#255#255 +#0#255#170#183#185#224#237#239#225#237#239#225#237#239#224#236#238#225#237 +#239#224#236#238#223#236#238#225#237#239#224#236#238#224#236#236#226#238#238 +#170#183#185#255#0#255#255#0#255#255#0#255'T'#18#0#245#247#247#248#248#248 +#248#248#248#245#248#252#251#247#252#248#247#249#250#248#247#246#248#248#248 +#249#245#246#248#248#243#248#246'V'#17#0#255#0#255#255#0#255#255#0#255'X'#19 +#0#134#197#248#250#249#245#245#247#247#244#249#248#244#249#247#251#247#252 +#246#248#248#246#250#245#246#248#248#249#247#247#132#196#250'W'#19#0#255#0 +#255#255#0#255#255#0#255'X'#21#0#199#210#214#195#205#212#197#209#211#202#208 +#207#196#209#211#203#208#211#196#205#209#194#207#209#202#205#213#194#206#210 +#200#213#215'Z'#18#0#255#0#255#255#0#255#255#0#255#168#183#186#224#237#239 +#225#237#237#225#237#237#225#237#239#227#239#241#227#239#241#225#238#240#224 +#236#238#224#236#238#227#239#241#226#239#241#169#182#184#255#0#255#255#0#255 ,#255#0#255'T'#18#0#245#247#247#248#248#248#248#248#248#245#248#252#251#247 +#252#248#247#249#250#248#247#246#248#248#248#249#245#246#248#248#243#248#246 +'V'#17#0#255#0#255#255#0#255#255#0#255'X'#19#0#134#197#248#250#249#245#245 +#247#247#244#249#248#244#249#247#251#247#252#246#248#248#246#250#245#246#248 +#248#249#247#247#132#196#250'W'#19#0#255#0#255#255#0#255#255#0#255'X'#21#0 +#199#210#214#195#205#212#197#209#211#202#208#207#196#209#211#203#208#211#196 +#205#209#194#207#209#202#205#213#194#206#210#200#213#215'Z'#18#0#255#0#255 +#255#0#255#255#0#255#168#183#186#224#237#239#225#237#237#225#237#237#225#237 +#239#227#239#241#227#239#241#225#238#240#224#236#238#224#236#238#227#239#241 +#226#239#241#169#182#184#255#0#255#255#0#255#255#0#255#6'b7'#225#243#246#224 +#243#246#224#243#246#224#243#246#224#243#246#224#243#246#224#243#246#224#243 +#246#224#243#246#224#243#246#222#241#246#214#235#242#204#228#238#6'b7'#255#0 +#255#6'b7X'#150#227'X'#150#227#224#242#245#224#242#245#224#242#245#224#242 +#245#224#242#245#224#242#245#224#242#245#224#242#245#222#240#245'X'#150#227 +'V'#149#227#6'b7'#255#0#255#6'b7'#190#213#227#197#220#231#201#225#234#202#226 +#234#202#226#234#202#226#234#202#226#234#202#226#234#202#226#234#202#226#234 +#203#227#235#206#228#236#207#229#237#6'b7'#255#0#255#184#196#202#233#242#246 +#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233 +#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#184#196 +#202#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#226#214#201#161'tY'#178#141'v'#249#248#245#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#249#248#245#178#141'v'#161'tY'#226 +#214#201#255#0#255#255#0#255#255#0#255#224#212#198#158'pT'#136#135#143'~'#180 +#234#179#210#240#223#235#247#250#250#251#223#235#247#179#210#240'~'#180#234 +#136#135#143#158'pT'#224#212#198#255#0#255#255#0#255#255#0#255#226#214#201 +#161'tY'#173#144'}'#207#210#209#202#206#207#202#206#207#202#206#207#202#206 +#207#202#206#207#207#210#209#173#144'}'#161'tY'#226#214#201#255#0#255#255#0 +#255#255#0#255#255#0#255#217#224#226#224#229#231#254#254#254#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#254#254#254#224#229#231#217#224 +#226#255#0#255#255#0#255#255#0#255#255#0#255#226#214#201#161'tY'#178#141'v' +#248#245#242#247#243#240#237#230#223#233#225#215#237#230#223#247#243#240#248 +#245#242#178#141'v'#161'tY'#226#214#201#255#0#255#255#0#255#255#0#255#226#214 +#201#161'tY'#178#141'v'#248#245#242#247#243#240#237#230#223#233#225#215#237 +#230#223#247#243#240#248#245#242#178#141'v'#161'tY'#226#214#201#255#0#255#255 +#0#255#255#0#255#226#214#201#161'tY'#178#141'v'#248#245#242#247#243#240#237 +#230#223#233#225#215#237#230#223#247#243#240#248#245#242#178#141'v'#161'tY' +#226#214#201#255#0#255#255#0#255#255#0#255#255#0#255#213#220#219#220#226#225 +#254#254#254#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#254 +#254#254#220#226#225#213#220#219#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255'V'#17#0#246#248#249#248#249#247#250#247#249#249#248#250#250#246#245 +#246#248#249#250#248#247#246#248#248#250#247#249#249#249#249#249#248#250'V' +#17#0#255#0#255#255#0#255#255#0#255'X'#19#2#133#193#247#249#249#249#252#247 +#248#250#248#247#247#248#246#252#247#249#243#248#247#248#249#247#248#248#248 +#249#250#246#130#194#249'['#19#1#255#0#255#255#0#255#255#0#255'V'#17#0#195 +#210#213#195#207#207#194#204#204#193#206#204#195#206#203#197#205#204#193#204 +#208#194#205#209#192#204#208#196#208#208#198#209#213'Z'#19#0#255#0#255#255#0 +#255#255#0#255#168#183#185#224#237#239#226#238#240#224#236#238#224#236#238 +#224#236#238#225#237#239#223#236#238#224#236#238#225#237#239#225#237#237#225 +#237#239#171#184#186#255#0#255#255#0#255#255#0#255'U'#15#2#245#251#246#250 +#246#251#249#249#249#247#247#247#2#134#0#248#247#249#244#249#247#247#249#250 +#246#245#247#252#248#247#250#246#251'V'#18#0#255#0#255#255#0#255#255#0#255'X' +#20#1#135#191#250#248#247#249#250#246#251#246#248#248#0#135#0#247#247#247#249 +#246#248#247#250#248#248#247#249#247#248#246#129#195#248'X'#19#0#255#0#255 +#255#0#255#255#0#255'W'#18#3#196#210#209#200#208#208#203#210#207#200#208#215 +#0'e'#3#205#208#216#198#207#211#198#204#209#193#206#204#194#207#215#197#211 +#210'Y'#20#0#255#0#255#255#0#255#255#0#255#169#184#187#227#239#241#225#237 +#237#226#238#238#228#240#242#161#173#175#226#238#240#227#239#241#225#238#240 +#225#237#239#224#237#239#224#237#239#171#184#186#255#0#255#255#0#255#255#0 +#255'U'#15#2#245#251#246#250#246#251#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0 +#0#139#0#0#139#0#252#248#247#250#246#251'V'#18#0#255#0#255#255#0#255#255#0 +#255'X'#20#1#135#191#250#248#247#249#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0 +#0#139#0#0#139#0#247#248#246#129#195#248'X'#19#0#255#0#255#255#0#255#255#0 +#255'W'#18#3#196#210#209#200#208#208#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0 ,#0#139#0#0#139#0#194#207#215#197#211#210'Y'#20#0#255#0#255#255#0#255#255#0 +#255#169#184#187#227#239#241#225#237#237#163#176#178#163#176#178#163#176#178 +#163#176#178#163#176#178#163#176#178#163#176#178#224#237#239#224#237#239#171 +#184#186#255#0#255#255#0#255#255#0#255#6'b7'#226#244#247#226#244#247#225#243 +#246#225#243#246#225#243#246#225#243#246#154#154#154#225#243#246#225#243#246 +#225#243#246#223#242#246#216#237#242#207#228#238#6'b7'#255#0#255#6'b7\'#153 +#228']'#154#229#225#242#245#225#242#245#225#242#245#225#242#245#154#154#154 +#225#242#245#225#242#245#225#242#245#223#241#245'\'#153#228'\'#153#228#6'b7' +#255#0#255#6'b7'#189#212#226#196#219#230#201#225#234#202#226#234#202#226#234 +#202#226#234#154#154#154#202#226#234#202#226#234#202#226#234#203#226#234#204 +#228#236#206#228#236#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#233 +#242#246#233#242#246#233#242#246#233#242#246#154#154#154#233#242#246#233#242 +#246#233#242#246#233#242#246#233#242#246#233#242#246#184#196#202#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#185#153#131#147'_A'#241#236#229#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#241#236#229#147'_A'#185#153#131#255 +#0#255#255#0#255#255#0#255#183#150#127#128'f^{'#176#228#220#228#236#254#254 +#253#255#255#255#255#255#255#255#255#255#254#254#253#220#228#236'{'#176#228 +#128'f^'#183#150#127#255#0#255#255#0#255#255#0#255#185#153#131#147'fL'#202 +#203#199#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206 +#207#202#206#207#202#203#199#147'fL'#185#153#131#255#0#255#255#0#255#255#0 +#255#233#237#238#208#217#219#254#254#254#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#254#254#254#208#217#219#255 +#0#255#255#0#255#255#0#255#255#0#255#185#153#131#147'_A'#241#236#229#247#243 +#240#227#216#204#214#198#181#211#194#175#214#198#181#227#216#204#247#243#240 +#241#236#229#147'_A'#185#153#131#255#0#255#255#0#255#255#0#255#185#153#131 +#147'_A'#241#236#229#247#243#240#227#216#204#214#198#181#211#194#175#214#198 +#181#227#216#204#247#243#240#241#236#229#147'_A'#185#153#131#255#0#255#255#0 +#255#255#0#255#185#153#131#147'_A'#241#236#229#247#243#240#227#216#204#214 +#198#181#211#194#175#214#198#181#227#216#204#247#243#240#241#236#229#147'_A' +#185#153#131#255#0#255#255#0#255#255#0#255#230#234#234#203#212#210#254#254 +#254#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#254#254#254#203#212#210#230#234#234#255#0#255#255#0#255#255#0 +#255#255#0#255'V'#17#0#246#248#248#248#249#247#246#248#248#250#248#247#249 +#250#246#246#248#249#250#248#248#245#248#246#248#249#247#248#249#247#249#247 +#247'V'#17#0#255#0#255#255#0#255#255#0#255'S'#16#1#130#196#245#244#246#246 +#252#249#245#248#248#248#244#249#247#250#248#248#248#247#249#248#248#248#250 +#248#247#246#248#248#131#197#246'X'#19#0#255#0#255#255#0#255#255#0#255'W'#18 +#0#198#209#213#195#208#210#201#206#207#199#204#205#195#204#207#197#205#204 +#193#205#205#196#204#204#197#204#207#197#206#209#197#209#213'X'#20#1#255#0 +#255#255#0#255#255#0#255#167#182#184#224#237#239#224#236#238#224#236#238#224 +#237#239#223#235#237#226#238#240#223#236#238#225#237#239#224#236#238#224#237 +#239#228#240#242#170#183#185#255#0#255#255#0#255#255#0#255'V'#15#1#245#250 +#248#248#248#248#249#247#246#1#137#1#0#141#2#0#135#0#246#248#249#251#248#243 +#249#249#249#250#247#249#246#247#251'W'#17#0#255#0#255#255#0#255#255#0#255'Y' +#17#0#130#194#248#252#247#248#251#250#246#0#135#0#1#135#0#3#134#0#248#249#247 +#245#247#247#245#247#248#247#249#249#134#193#249'Z'#18#0#255#0#255#255#0#255 +#255#0#255'Z'#19#0#198#211#213#198#208#215#202#209#212#2'e'#1#1'j'#3#2'f'#0 +#204#209#212#196#209#211#195#204#208#195#207#209#196#210#208'X'#18#1#255#0 +#255#255#0#255#255#0#255#169#184#186#224#237#239#226#238#238#227#239#239#163 +#175#177#165#177#179#164#176#178#227#239#241#225#238#240#226#238#240#224#236 +#238#227#239#241#170#183#185#255#0#255#255#0#255#255#0#255'V'#15#1#245#250 +#248#248#248#248#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#250 +#247#249#246#247#251'W'#17#0#255#0#255#255#0#255#255#0#255'Y'#17#0#130#194 +#248#252#247#248#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#247 +#249#249#134#193#249'Z'#18#0#255#0#255#255#0#255#255#0#255'Z'#19#0#198#211 +#213#198#208#215#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#195 +#207#209#196#210#208'X'#18#1#255#0#255#255#0#255#255#0#255#169#184#186#224 +#237#239#226#238#238#163#176#178#163#176#178#163#176#178#163#176#178#163#176 +#178#163#176#178#163#176#178#224#236#238#227#239#241#170#183#185#255#0#255 +#255#0#255#255#0#255#6'b7'#227#245#248#227#245#248#226#244#247#226#244#247 +#226#244#247#154#154#154#154#154#154#154#154#154#226#244#247#226#244#247#225 +#243#246#217#238#243#208#229#238#6'b7'#255#0#255#6'b7c'#158#229'c'#158#229 ,#226#243#246#226#243#246#226#243#246#154#154#154#154#154#154#154#154#154#226 +#243#246#226#243#246#225#242#245'c'#158#229'b'#157#229#6'b7'#255#0#255#6'b7' +#189#211#227#197#219#231#202#225#234#203#226#235#203#226#235#154#154#154#154 +#154#154#154#154#154#203#226#235#203#226#235#204#226#235#206#227#236#206#228 +#237#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#233#242#246#233#242 +#246#233#242#246#154#154#154#154#154#154#154#154#154#233#242#246#233#242#246 +#233#242#246#233#242#246#233#242#246#184#196#202#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#152'hK'#181#147 +'}'#250#247#245#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#250#247#245#181#147'}'#152'hK'#255#0#255#255#0#255 +#255#0#255#151'eHz'#143#170#170#196#223#250#248#246#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#250#248#246#170#196#223'z'#143#170#151 +'eH'#255#0#255#255#0#255#255#0#255#152'hK'#172#150#134#199#202#202#202#206 +#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207 +#199#202#202#172#150#134#152'hK'#255#0#255#255#0#255#255#0#255#213#221#222 +#228#233#234#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#228#233#234#213#221#222#255#0 +#255#255#0#255#255#0#255#152'hK'#181#147'}'#250#247#245#237#230#223#170#187 +#145'V'#162'K'#24#148#28'V'#162'K'#170#187#145#237#230#223#250#247#245#181 +#147'}'#152'hK'#255#0#255#255#0#255#255#0#255#152'hK'#181#147'}'#250#247#245 +#237#230#223#170#187#145'V'#162'K'#24#148#28'V'#162'K'#170#187#145#237#230 +#223#250#247#245#181#147'}'#152'hK'#255#0#255#255#0#255#255#0#255#152'hK'#181 +#147'}'#250#247#245#237#230#223#170#187#145'V'#162'K'#24#148#28'V'#162'K'#170 +#187#145#237#230#223#250#247#245#181#147'}'#152'hK'#255#0#255#255#0#255#255#0 +#255#208#216#215#225#230#229#255#255#255#255#255#255#238#241#241#207#215#214 +#183#195#193#207#215#214#238#241#241#255#255#255#255#255#255#225#230#229#208 +#216#215#255#0#255#255#0#255#255#0#255#255#0#255'V'#17#0#245#244#246#244#243 +#245#246#244#244#241#245#246#251#246#247#248#248#248#248#247#249#248#248#248 +#247#246#248#250#248#248#246#249#247'V'#17#0#255#0#255#255#0#255#255#0#255'Z' +#18#0#129#193#248#247#246#248#244#246#246#246#245#249#249#249#249#243#248#247 +#253#248#250#246#248#249#252#247#248#247#249#249#133#194#250'V'#19#0#255#0 +#255#255#0#255#255#0#255'X'#18#1#195#209#208#193#205#205#194#203#206#193#205 +#205#194#204#204#193#206#204#196#203#206#193#206#204#195#204#208#195#206#210 +#198#210#212'X'#19#0#255#0#255#255#0#255#255#0#255#168#183#185#225#238#240 +#225#237#239#224#237#239#222#235#237#224#236#238#224#236#238#224#236#238#224 +#236#238#224#236#238#223#236#238#226#238#240#171#184#186#255#0#255#255#0#255 +#255#0#255'T'#17#2#246#248#249#254#246#246#3#136#2#0#139#0#0#137#0#0#140#0#4 +#136#0#247#248#246#249#248#250#251#249#249#245#249#244'W'#18#0#255#0#255#255 +#0#255#255#0#255'W'#18#1#132#194#248#246#250#245#0#136#1#3#138#0#0#137#0#0 +#141#0#0#135#0#249#247#247#251#251#245#249#246#248#134#197#248'['#20#0#255#0 +#255#255#0#255#255#0#255'W'#17#0#195#208#216#200#206#211#0'g'#0#0'i'#2#0'j'#0 +#3'k'#0#1'g'#2#203#208#217#200#206#211#197#207#207#198#207#216'X'#19#0#255#0 +#255#255#0#255#255#0#255#168#183#185#226#239#241#225#237#237#161#173#173#163 +#176#178#163#176#178#163#176#178#163#177#176#227#240#242#226#238#240#226#238 +#240#226#238#240#170#183#185#255#0#255#255#0#255#255#0#255'T'#17#2#246#248 +#249#254#246#246#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#251 +#249#249#245#249#244'W'#18#0#255#0#255#255#0#255#255#0#255'W'#18#1#132#194 +#248#246#250#245#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#249 +#246#248#134#197#248'['#20#0#255#0#255#255#0#255#255#0#255'W'#17#0#195#208 +#216#200#206#211#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#197 +#207#207#198#207#216'X'#19#0#255#0#255#255#0#255#255#0#255#168#183#185#226 +#239#241#225#237#237#163#176#178#163#176#178#163#176#178#163#176#178#163#176 +#178#163#176#178#163#176#178#226#238#240#226#238#240#170#183#185#255#0#255 +#255#0#255#255#0#255#6'b7'#228#245#248#228#245#248#227#244#247#227#244#247 +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#227#244#247#226 +#243#246#218#238#243#210#229#238#6'b7'#255#0#255#6'b7j'#162#230'j'#162#230 +#227#243#246#227#243#246#154#154#154#154#154#154#154#154#154#154#154#154#154 +#154#154#227#243#246#226#242#245'j'#162#230'j'#162#230#6'b7'#255#0#255#6'b7' +#190#211#227#198#219#231#203#225#234#204#226#235#154#154#154#154#154#154#154 +#154#154#154#154#154#154#154#154#204#226#235#207#226#235#208#227#236#207#228 +#237#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#233#242#246#233#242 +#246#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#233#242#246 +#233#242#246#233#242#246#233#242#246#184#196#202#255#0#255#255#0#255#255#0 ,#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#127'B '#210#189 +#173#252#251#250#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#252#251#250#210#189#173#127'B '#255#0#255#255#0#255 +#255#0#255#127'A'#31'k'#159#213#207#213#218#253#252#251#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#253#252#251#207#213#218'k'#159#213 +#127'A'#31#255#0#255#255#0#255#255#0#255#127'B '#185#176#167#200#204#204#202 +#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206 +#207#200#204#204#185#176#167#127'B '#255#0#255#255#0#255#255#0#255#197#208 +#210#244#246#247#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#244#246#247#197#208#210#255 +#0#255#255#0#255#255#0#255#127'B '#210#189#173#252#251#250#233#225#215'W'#164 +'M'#13#146#19#13#146#19#13#146#19'W'#164'M'#233#225#215#252#251#250#210#189 +#173#127'B '#255#0#255#255#0#255#255#0#255#127'B '#210#189#173#252#251#250 +#233#225#215'W'#164'M'#13#146#19#13#146#19#13#146#19'W'#164'M'#233#225#215 +#252#251#250#210#189#173#127'B '#255#0#255#255#0#255#255#0#255#127'B '#210 +#189#173#252#251#250#233#225#215'W'#164'M'#13#146#19#13#146#19#13#146#19'W' +#164'M'#233#225#215#252#251#250#210#189#173#127'B '#255#0#255#255#0#255#255#0 +#255#190#201#199#243#245#245#255#255#255#255#255#255#207#215#214#178#191#189 +#178#191#189#178#191#189#207#215#214#255#255#255#255#255#255#243#245#245#190 +#201#199#255#0#255#255#0#255#255#0#255#255#0#255'V'#17#0#242#242#242#239#241 +#241#241#240#244#238#244#243#244#244#244#245#246#244#245#244#246#247#246#248 +#248#247#249#245#248#246#248#247#249'V'#17#0#255#0#255#255#0#255#255#0#255'Z' +#18#1#132#189#250#236#240#241#239#241#241#244#242#242#244#244#244#245#244#246 +#239#246#243#251#248#250#252#247#246#242#249#244#135#197#251'W'#19#0#255#0 +#255#255#0#255#255#0#255'W'#19#0#191#206#209#191#204#206#193#204#202#194#205 +#203#196#203#206#191#205#203#197#204#207#193#205#207#193#205#207#196#206#206 +#202#208#213'W'#18#0#255#0#255#255#0#255#255#0#255#169#182#184#225#239#238 +#225#237#239#224#236#238#225#237#239#226#237#241#225#237#239#224#236#238#225 +#237#239#226#238#238#224#236#238#227#239#241#167#183#182#255#0#255#255#0#255 +#255#0#255'W'#18#0#240#243#247#240#243#248#1#135#0#2#135#1#254#249#248#0#137 +#0#0#137#0#0#137#0#247#248#246#246#247#251#247#249#249'V'#16#0#255#0#255#255 +#0#255#255#0#255'W'#18#0#129#188#250#246#245#249#0#137#0#2#136#0#248#249#247 +#1#133#3#1#137#1#0#137#0#244#247#251#246#249#247#137#199#247'U'#19#0#255#0 +#255#255#0#255#255#0#255'W'#18#1#192#205#213#203#208#209#2'e'#1#0'g'#0#208 +#210#218#4'g'#0#0'i'#2#2'e'#1#204#211#214#196#209#207#200#209#212'W'#20#0#255 +#0#255#255#0#255#255#0#255#171#183#187#226#238#240#229#239#239#161#173#175 +#163#175#177#229#241#243#163#175#177#163#175#177#162#175#177#227#239#241#226 +#238#240#225#238#240#170#183#185#255#0#255#255#0#255#255#0#255'W'#18#0#240 +#243#247#240#243#248#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0 +#246#247#251#247#249#249'V'#16#0#255#0#255#255#0#255#255#0#255'W'#18#0#129 +#188#250#246#245#249#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0 +#246#249#247#137#199#247'U'#19#0#255#0#255#255#0#255#255#0#255'W'#18#1#192 +#205#213#203#208#209#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0 +#196#209#207#200#209#212'W'#20#0#255#0#255#255#0#255#255#0#255#171#183#187 +#226#238#240#229#239#239#163#176#178#163#176#178#163#176#178#163#176#178#163 +#176#178#163#176#178#163#176#178#226#238#240#225#238#240#170#183#185#255#0 +#255#255#0#255#255#0#255#6'b7'#233#249#250#233#249#250#232#250#251#154#154 +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154 +#231#249#251#224#243#247#214#235#242#6'b7'#255#0#255#6'b7'#146#187#236#139 +#184#235#232#249#250#154#154#154#154#154#154#154#154#154#154#154#154#154#154 +#154#154#154#154#154#154#154#231#248#250#139#184#235#145#186#235#6'b7'#255#0 +#255#6'b7'#193#215#228#200#222#234#207#228#237#154#154#154#154#154#154#154 +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#210#229#238#211#230 +#238#211#231#238#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#233#242 +#246#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154 +#154#154#154#233#242#246#233#242#246#233#242#246#184#196#202#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255'q,'#8 +#224#211#197#250#247#245#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#250#247#245#224#211#197'q,'#8#255#0#255#255 +#0#255#255#0#255'q,'#7'^'#164#234#226#217#208#250#248#246#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#250#248#246#226#217#208'^'#164#234 +'q,'#7#255#0#255#255#0#255#255#0#255'q,'#8#187#185#178#199#202#202#202#206 ,#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207 +#199#202#202#187#185#178'q,'#8#255#0#255#255#0#255#255#0#255#188#200#203#254 +#254#254#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#254#254#254#188#200#203#255#0#255 +#255#0#255#255#0#255'q,'#8#224#211#197#250#247#245#237#230#223#25#149#29#13 +#146#19#13#146#19#13#146#19#25#149#29#237#230#223#250#247#245#224#211#197'q,' +#8#255#0#255#255#0#255#255#0#255'q,'#8#224#211#197#250#247#245#237#230#223#25 +#149#29#13#146#19#13#146#19#13#146#19#25#149#29#237#230#223#250#247#245#224 +#211#197'q,'#8#255#0#255#255#0#255#255#0#255'q,'#8#224#211#197#250#247#245 +#237#230#223#25#149#29#13#146#19#13#146#19#13#146#19#25#149#29#237#230#223 +#250#247#245#224#211#197'q,'#8#255#0#255#255#0#255#255#0#255#180#192#190#253 +#254#254#255#255#255#255#255#255#183#195#193#178#191#189#178#191#189#178#191 +#189#183#195#193#255#255#255#255#255#255#253#254#254#180#192#190#255#0#255 +#255#0#255#255#0#255#255#0#255'V'#17#0#233#235#236#230#235#234#231#236#235 +#235#238#236#237#239#240#237#239#240#242#242#242#246#244#243#240#246#245#247 +#247#247#250#248#248'V'#17#0#255#0#255#255#0#255#255#0#255'U'#19#1'w'#190#240 +#234#233#235#235#233#233#231#236#235#233#239#238#239#238#240#237#241#242#238 +#245#242#243#246#244#250#246#251#134#193#249'W'#20#0#255#0#255#255#0#255#255 +#0#255'X'#18#1#192#204#206#192#201#204#194#202#202#189#202#200#190#202#202 +#193#203#203#195#202#205#196#204#203#196#203#206#192#204#208#197#208#212'Y' +#20#1#255#0#255#255#0#255#255#0#255#170#183#185#224#238#237#225#237#239#224 +#236#238#225#237#239#223#235#237#227#239#239#224#236#238#224#236#238#224#235 +#239#225#237#239#225#237#237#170#183#185#255#0#255#255#0#255#255#0#255'P'#19 +#0#229#235#242#238#237#239#3#135#0#241#240#244#246#240#245#250#243#250#1#137 +#1#0#137#0#0#136#0#244#249#247#251#249#249'V'#16#0#255#0#255#255#0#255#255#0 +#255'W'#19#0#129#188#244#234#237#241#0#133#0#243#239#244#240#243#248#245#245 +#245#4#134#3#0#140#1#2#136#0#247#247#247#136#196#248'X'#19#0#255#0#255#255#0 +#255#255#0#255'Y'#20#0#192#205#207#193#205#205#0'f'#1#195#205#212#200#205#208 +#197#203#214#0'g'#0#1'h'#0#2'f'#0#201#208#211#197#208#212'Z'#19#0#255#0#255 +#255#0#255#255#0#255#168#183#185#225#238#240#226#238#240#161#173#175#227#239 +#241#226#239#241#227#238#242#163#174#178#163#175#177#160#173#175#225#238#240 +#227#239#241#170#183#185#255#0#255#255#0#255#255#0#255'P'#19#0#229#235#242 +#238#237#239#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#244#249 +#247#251#249#249'V'#16#0#255#0#255#255#0#255#255#0#255'W'#19#0#129#188#244 +#234#237#241#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#247#247 +#247#136#196#248'X'#19#0#255#0#255#255#0#255#255#0#255'Y'#20#0#192#205#207 +#193#205#205#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#201#208 +#211#197#208#212'Z'#19#0#255#0#255#255#0#255#255#0#255#168#183#185#225#238 +#240#226#238#240#163#176#178#163#176#178#163#176#178#163#176#178#163#176#178 +#163#176#178#163#176#178#225#238#240#227#239#241#170#183#185#255#0#255#255#0 +#255#255#0#255#6'b7'#235#249#250#235#249#250#154#154#154#154#154#154#154#154 +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154 +#225#243#247#215#235#242#6'b7'#255#0#255#6'b7'#150#190#237#139#184#235#154 +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154 +#154#154#154#154#154#154#154#139#184#235#150#190#237#6'b7'#255#0#255#6'b7' +#193#215#228#200#222#234#154#154#154#154#154#154#154#154#154#154#154#154#154 +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#211#230#238#211#231 +#238#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#154#154#154#154#154 +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154 +#154#154#154#233#242#246#233#242#246#184#196#202#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#128'C!'#205#183 +#165#243#238#232#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#243#238#232#205#183#165#128'C!'#255#0#255#255#0#255 +#255#0#255#128'B l'#160#214#199#201#203#243#238#233#254#254#253#255#255#255 +#255#255#255#255#255#255#254#254#253#243#238#233#199#201#203'l'#160#214#128 +'B '#255#0#255#255#0#255#255#0#255#128'C!'#182#173#163#196#198#195#202#206 +#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207 +#196#198#195#182#173#163#128'C!'#255#0#255#255#0#255#255#0#255#197#208#210 +#244#246#247#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#244#246#247#197#208#210#255#0 +#255#255#0#255#255#0#255#128'C!'#205#183#165#243#238#232#247#243#240']'#172 +'X'#13#146#19#13#146#19#13#146#19']'#172'X'#247#243#240#243#238#232#205#183 +#165#128'C!'#255#0#255#255#0#255#255#0#255#128'C!'#205#183#165#243#238#232 ,#247#243#240']'#172'X'#13#146#19#13#146#19#13#146#19']'#172'X'#247#243#240 +#243#238#232#205#183#165#128'C!'#255#0#255#255#0#255#255#0#255#128'C!'#205 +#183#165#243#238#232#247#243#240']'#172'X'#13#146#19#13#146#19#13#146#19']' +#172'X'#247#243#240#243#238#232#205#183#165#128'C!'#255#0#255#255#0#255#255#0 +#255#190#201#199#243#245#245#255#255#255#255#255#255#207#215#214#178#191#189 +#178#191#189#178#191#189#207#215#214#255#255#255#255#255#255#243#245#245#190 +#201#199#255#0#255#255#0#255#255#0#255#255#0#255'V'#17#0#227#230#234#226#230 +#231#225#229#230#229#234#233#234#235#233#231#236#235#235#237#237#235#240#239 +#241#242#240#243#242#244#247#249#249'V'#17#0#255#0#255#255#0#255#255#0#255'W' +#18#0'|'#181#243#225#227#228#227#226#228#222#230#230#230#232#232#229#231#231 +#233#235#236#233#237#238#242#237#238#241#243#243#131#194#245'W'#18#1#255#0 +#255#255#0#255#255#0#255'W'#18#0#189#203#202#188#200#200#185#199#198#188#202 +#201#188#200#202#192#201#204#191#204#202#191#204#202#190#202#204#192#204#206 +#196#210#209'W'#19#0#255#0#255#255#0#255#255#0#255#170#183#185#225#238#240 +#224#236#238#223#235#237#223#235#237#225#237#239#225#237#237#224#236#238#223 +#236#238#223#235#239#224#236#238#225#237#237#171#184#186#255#0#255#255#0#255 +#255#0#255'Z'#18#1#224#227#231#224#228#229#226#229#233#228#233#232#233#233 +#233#238#236#236#245#239#244#5#137#0#0#137#2#250#247#249#246#246#246'V'#17#2 +#255#0#255#255#0#255#255#0#255'Y'#20#1'y'#181#241#229#230#228#231#229#229#231 +#230#232#229#234#232#234#235#239#245#239#244#1#134#0#0#138#0#246#248#248#133 +#192#248'['#20#0#255#0#255#255#0#255#255#0#255'V'#17#2#188#200#206#190#202 +#204#195#198#206#191#203#205#192#201#204#196#203#206#201#203#213#0'f'#1#0'f' +#1#195#206#210#196#209#211'W'#19#0#255#0#255#255#0#255#255#0#255#168#183#185 +#225#239#238#225#237#237#226#238#238#227#239#239#223#237#236#226#238#240#227 +#239#241#163#175#177#162#174#176#228#240#242#228#237#240#171#183#185#255#0 +#255#255#0#255#255#0#255'Z'#18#1#224#227#231#224#228#229#0#139#0#0#139#0#0 +#139#0#0#139#0#0#139#0#0#139#0#0#139#0#250#247#249#246#246#246'V'#17#2#255#0 +#255#255#0#255#255#0#255'Y'#20#1'y'#181#241#229#230#228#0#139#0#0#139#0#0#139 +#0#0#139#0#0#139#0#0#139#0#0#139#0#246#248#248#133#192#248'['#20#0#255#0#255 +#255#0#255#255#0#255'V'#17#2#188#200#206#190#202#204#0#139#0#0#139#0#0#139#0 +#0#139#0#0#139#0#0#139#0#0#139#0#195#206#210#196#209#211'W'#19#0#255#0#255 +#255#0#255#255#0#255#168#183#185#225#239#238#225#237#237#163#176#178#163#176 +#178#163#176#178#163#176#178#163#176#178#163#176#178#163#176#178#228#240#242 +#228#237#240#171#183#185#255#0#255#255#0#255#255#0#255#6'b7'#237#251#252#236 +#251#252#236#251#252#236#251#252#236#251#252#236#251#252#236#251#252#236#251 +#252#236#251#252#236#251#252#236#250#251#228#244#249#219#237#244#6'b7'#255#0 +#255#6'b7'#156#196#238#139#184#235#237#251#252#237#251#252#237#251#252#237 +#251#252#237#251#252#237#251#252#237#251#252#237#251#252#236#250#251#139#184 +#235#156#196#238#6'b7'#255#0#255#6'b7'#195#216#229#202#224#234#208#229#238 +#211#230#238#211#230#238#211#230#238#211#230#238#211#230#238#211#230#238#211 +#230#238#211#230#238#212#231#238#213#231#238#6'b7'#255#0#255#184#196#202#233 +#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242 +#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246 +#184#196#202#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#156'lP'#178#142'v'#233#224#214#251#250#248#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#251#250#248#233#224#214#178 +#142'v'#156'lP'#255#0#255#255#0#255#255#0#255#155'kO{'#143#171#161#185#208 +#229#218#207#243#238#233#250#248#246#253#252#251#250#248#246#243#238#233#229 +#218#207#161#185#208'{'#143#171#155'kO'#255#0#255#255#0#255#255#0#255#156'lP' +#170#146#129#191#191#186#200#204#203#202#206#207#202#206#207#202#206#207#202 +#206#207#202#206#207#200#204#203#191#191#186#170#146#129#156'lP'#255#0#255 +#255#0#255#255#0#255#213#221#222#228#233#234#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#228#233#234#213#221#222#255#0#255#255#0#255#255#0#255#156'lP'#178#142'v'#233 +#224#214#250#247#245#196#222#191'`'#177'_'#26#151#31'`'#177'_'#196#222#191 +#250#247#245#233#224#214#178#142'v'#156'lP'#255#0#255#255#0#255#255#0#255#156 +'lP'#178#142'v'#233#224#214#250#247#245#196#222#191'`'#177'_'#26#151#31'`' +#177'_'#196#222#191#250#247#245#233#224#214#178#142'v'#156'lP'#255#0#255#255 +#0#255#255#0#255#156'lP'#178#142'v'#233#224#214#250#247#245#196#222#191'`' +#177'_'#26#151#31'`'#177'_'#196#222#191#250#247#245#233#224#214#178#142'v' +#156'lP'#255#0#255#255#0#255#255#0#255#208#216#215#225#230#229#255#255#255 +#255#255#255#238#241#241#207#215#214#183#195#193#207#215#214#238#241#241#255 +#255#255#255#255#255#225#230#229#208#216#215#255#0#255#255#0#255#255#0#255 ,#255#0#255'V'#17#0#217#226#230#221#225#226#221#227#226#225#227#227#226#232 +#227#230#232#232#228#231#235#236#233#235#234#236#236#234#239#242#238#241#245 +'V'#17#0#255#0#255#255#0#255#255#0#255'['#19#1't'#177#241#217#225#218#216#222 +#221#220#223#221#217#225#224#226#228#228#224#229#227#233#233#227#235#234#236 +#234#240#239'}'#189#247'X'#18#1#255#0#255#255#0#255#255#0#255'V'#16#3#183#201 +#200#189#200#198#186#198#198#186#200#199#186#200#196#188#201#199#189#201#201 +#191#201#201#191#200#203#191#204#202#194#206#208'W'#18#0#255#0#255#255#0#255 +#255#0#255#170#182#186#224#237#239#226#237#241#225#237#239#224#236#238#224 +#235#239#224#236#238#225#237#239#224#236#238#223#237#236#225#238#240#225#238 +#240#168#184#183#255#0#255#255#0#255#255#0#255'Y'#17#0#212#221#224#216#220 +#221#215#220#221#219#224#223#218#226#225#224#229#228#227#230#234#233#234#238 +#1#133#2#236#240#241#240#242#242'W'#17#0#255#0#255#255#0#255#255#0#255'V'#21 +#0't'#178#242#217#222#221#216#221#222#217#222#223#220#225#223#224#231#228#227 +#231#232#236#235#239#0#133#3#237#238#242'~'#189#249'Z'#19#0#255#0#255#255#0 +#255#255#0#255'T'#18#0#184#203#200#189#198#201#189#198#202#186#199#201#190 +#198#197#189#201#201#189#201#203#200#205#208#2'f'#0#190#205#207#194#206#210 +'W'#18#0#255#0#255#255#0#255#255#0#255#168#181#183#225#238#240#225#237#239 +#223#235#237#225#237#239#225#237#239#224#236#238#226#238#240#228#240#242#159 +#172#174#226#238#238#225#237#239#171#184#186#255#0#255#255#0#255#255#0#255'Y' +#17#0#212#221#224#216#220#221#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0 +#0#139#0#236#240#241#240#242#242'W'#17#0#255#0#255#255#0#255#255#0#255'V'#21 +#0't'#178#242#217#222#221#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0 +#139#0#237#238#242'~'#189#249'Z'#19#0#255#0#255#255#0#255#255#0#255'T'#18#0 +#184#203#200#189#198#201#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0 +#139#0#190#205#207#194#206#210'W'#18#0#255#0#255#255#0#255#255#0#255#168#181 +#183#225#238#240#225#237#239#163#176#178#163#176#178#163#176#178#163#176#178 +#163#176#178#163#176#178#163#176#178#226#238#238#225#237#239#171#184#186#255 +#0#255#255#0#255#255#0#255#6'b7'#240#253#254#239#253#254#239#253#254#239#253 +#254#239#253#254#239#253#254#239#253#254#239#253#254#239#253#254#239#253#254 +#238#253#254#232#247#251#224#241#246#6'b7'#255#0#255#6'b7'#161#198#238#139 +#184#235#240#253#254#240#253#254#240#253#254#240#253#254#240#253#254#240#253 +#254#240#253#254#240#253#254#239#253#254#139#184#235#161#198#238#6'b7'#255#0 +#255#6'b7'#195#217#229#202#224#234#210#230#238#212#233#238#213#233#238#213 +#233#238#213#233#238#213#233#238#213#233#238#213#233#238#213#233#238#213#233 +#238#214#233#238#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#233#242 +#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246 +#233#242#246#233#242#246#233#242#246#233#242#246#184#196#202#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#196 +#169#152#147'_B'#222#208#194#233#224#214#243#238#232#250#247#245#252#251#250 +#250#247#245#243#238#232#233#224#214#222#208#194#147'_B'#196#169#152#255#0 +#255#255#0#255#255#0#255#196#169#151#130'ibx'#171#222#197#195#192#222#209#195 +#229#218#207#232#222#212#229#218#207#222#209#195#197#195#192'x'#171#222#130 +'ib'#196#169#151#255#0#255#255#0#255#255#0#255#196#169#152#147'fM'#191#187 +#179#191#191#186#196#198#195#199#202#202#200#204#204#199#202#202#196#198#195 +#191#191#186#191#187#179#147'fM'#196#169#152#255#0#255#255#0#255#255#0#255 +#255#0#255#208#217#219#254#254#254#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#254#254#254#208#217#219#255#0 +#255#255#0#255#255#0#255#255#0#255#196#169#152#147'_B'#222#208#194#233#224 +#214#243#238#232#250#247#245#252#251#250#250#247#245#243#238#232#233#224#214 +#222#208#194#147'_B'#196#169#152#255#0#255#255#0#255#255#0#255#196#169#152 +#147'_B'#222#208#194#233#224#214#243#238#232#250#247#245#252#251#250#250#247 +#245#243#238#232#233#224#214#222#208#194#147'_B'#196#169#152#255#0#255#255#0 +#255#255#0#255#196#169#152#147'_B'#222#208#194#233#224#214#243#238#232#250 +#247#245#252#251#250#250#247#245#243#238#232#233#224#214#222#208#194#147'_B' +#196#169#152#255#0#255#255#0#255#255#0#255#255#0#255#203#212#210#254#254#254 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#254#254#254#203#212#210#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255'V'#17#0#219#223#224#214#225#223#222#224#224#221#224#228#222#225#229 +#223#227#228#225#230#228#229#231#232#227#231#232#236#236#236#236#241#242'V' +#17#0#255#0#255#255#0#255#255#0#255'Y'#20#1'p'#173#235#214#217#215#213#218 +#217#217#219#220#219#221#221#218#223#222#223#226#224#221#224#228#224#229#227 +#234#232#231'}'#185#244'['#20#0#255#0#255#255#0#255#255#0#255'Y'#20#0#187#199 +#199#185#198#200#185#197#197#185#197#201#184#199#202#189#198#202#188#200#200 ,#188#200#202#183#200#203#192#204#206#189#204#207'Y'#19#2#255#0#255#255#0#255 +#255#0#255#173#185#187#226#238#240#226#237#241#225#237#239#224#236#238#225 +#237#239#225#237#237#224#236#238#225#237#239#224#236#236#225#237#239#226#238 +#240#170#184#183#255#0#255#255#0#255#255#0#255'Y'#19#2#211#216#219#204#218 +#217#214#216#216#213#218#221#215#221#220#215#221#226#219#224#222#225#227#228 +#226#229#234#228#233#231#231#236#237'V'#14#2#255#0#255#255#0#255#255#0#255'W' +#19#0'p'#175#235#207#218#216#213#218#217#220#220#220#221#221#221#224#221#223 +#221#226#225#226#228#229#230#230#230#235#236#234#128#185#246'['#19#2#255#0 +#255#255#0#255#255#0#255'Y'#20#1#188#200#200#185#199#198#185#198#200#186#199 +#201#187#197#197#184#196#200#188#200#204#193#201#201#190#199#208#194#203#206 +#195#204#207'T'#20#2#255#0#255#255#0#255#255#0#255#173#185#189#225#237#239 +#227#239#241#226#238#240#225#237#239#224#236#238#224#236#238#225#237#239#226 +#238#238#226#240#239#225#237#237#226#238#238#170#184#183#255#0#255#255#0#255 +#255#0#255'Y'#19#2#211#216#219#204#218#217#214#216#216#213#218#221#215#221 +#220#215#221#226#219#224#222#225#227#228#226#229#234#228#233#231#231#236#237 +'V'#14#2#255#0#255#255#0#255#255#0#255'W'#19#0'p'#175#235#207#218#216#213#218 +#217#220#220#220#221#221#221#224#221#223#221#226#225#226#228#229#230#230#230 +#235#236#234#128#185#246'['#19#2#255#0#255#255#0#255#255#0#255'Y'#20#1#188 +#200#200#185#199#198#185#198#200#186#199#201#187#197#197#184#196#200#188#200 +#204#193#201#201#190#199#208#194#203#206#195#204#207'T'#20#2#255#0#255#255#0 +#255#255#0#255#173#185#189#225#237#239#227#239#241#226#238#240#225#237#239 +#224#236#238#224#236#238#225#237#239#226#238#238#226#240#239#225#237#237#226 +#238#238#170#184#183#255#0#255#255#0#255#255#0#255'#oL'#180#221#228#245#255 +#255#245#255#255#245#255#255#245#255#255#245#255#255#245#255#255#245#255#255 +#245#255#255#245#255#255#245#255#255#244#255#255#180#221#228'#oL'#255#0#255 +'#oL'#149#197#252#139#184#235#150#190#237#150#190#237#150#190#237#150#190#237 +#150#190#237#150#190#237#150#190#237#150#190#237#150#190#237#139#184#235#149 +#197#252'#oL'#255#0#255'#oL'#149#175#196#185#208#227#191#212#228#194#216#230 +#195#217#231#195#217#231#195#217#231#195#217#231#195#217#231#195#217#231#194 +#216#230#196#218#231#158#189#206'#oL'#255#0#255#184#196#202#221#231#235#233 +#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242 +#246#233#242#246#233#242#246#233#242#246#233#242#246#221#231#235#184#196#202 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#167'}e'#172#133'm'#219#204#189#222#209#195#226#214#201 +#228#217#205#226#214#201#222#209#195#219#204#189#172#133'm'#167'}e'#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#166'}d'#138#136#145'x'#171#222#159 +#182#204#191#190#189#209#194#178#191#190#189#159#182#204'x'#171#222#138#136 +#145#166'}d'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#167'}e'#168 +#138'v'#189#185#176#185#183#177#187#186#180#188#187#182#187#186#180#185#183 +#177#189#185#176#168#138'v'#167'}e'#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#217#224#226#224#229#231#254#254#254#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#254#254#254#224#229#231#217#224#226#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#167'}e'#172#133'm'#219#204#189 +#222#209#195#226#214#201#228#217#205#226#214#201#222#209#195#219#204#189#172 +#133'm'#167'}e'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#167'}e'#172 +#133'm'#219#204#189#222#209#195#226#214#201#228#217#205#226#214#201#222#209 +#195#219#204#189#172#133'm'#167'}e'#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#167'}e'#172#133'm'#219#204#189#222#209#195#226#214#201#228#217#205 +#226#214#201#222#209#195#219#204#189#172#133'm'#167'}e'#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#213#220#219#220#226#225#254#254#254#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#254#254#254#220#226#225 +#213#220#219#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255'V'#17#0#214 +#226#226#218#222#227#220#223#227#221#226#229#221#227#226#223#229#228#224#230 +#229#222#231#228#229#232#237#230#233#237#232#238#237'V'#17#0#255#0#255#255#0 +#255#255#0#255'X'#19#0'l'#177#240'o'#172#236'm'#174#235'q'#176#236'r'#177#237 +'t'#177#239's'#182#239't'#181#236'u'#178#240'v'#181#241'y'#184#245'T'#18#0 +#255#0#255#255#0#255#255#0#255'V'#18#0#187#201#199#185#199#205#184#197#199 +#184#199#201#187#199#201#186#199#201#188#200#202#188#199#203#188#202#201#193 +#202#206#193#205#205'W'#19#0#255#0#255#255#0#255#255#0#255#170#182#184#227 +#239#239#225#237#239#227#239#239#226#238#238#225#237#239#226#238#238#226#238 +#240#226#238#238#225#237#239#225#237#239#227#239#239#170#182#186#255#0#255 +#255#0#255#255#0#255'T'#18#0#206#215#219#209#214#217#209#214#215#210#215#218 +#212#215#219#209#218#221#216#223#220#217#222#221#220#226#225#214#228#227#224 ,#230#235'T'#18#0#255#0#255#255#0#255#255#0#255'X'#19#0'n'#176#241'n'#171#235 +'p'#173#235'm'#179#232's'#179#237'r'#180#239'r'#180#239's'#181#240'v'#179#243 +'t'#183#240'u'#184#247'Y'#20#1#255#0#255#255#0#255#255#0#255'W'#19#0#188#201 +#203#187#199#205#183#198#200#184#198#197#186#199#201#188#201#203#189#199#199 +#189#200#204#189#198#208#183#201#202#192#203#211'X'#20#1#255#0#255#255#0#255 +#255#0#255#169#182#184#227#239#239#226#238#238#225#237#237#226#238#238#226 +#238#238#226#238#238#224#236#236#229#238#241#225#237#239#225#237#237#227#239 +#239#169#182#184#255#0#255#255#0#255#255#0#255'T'#18#0#206#215#219#209#214 +#217#209#214#215#210#215#218#212#215#219#209#218#221#216#223#220#217#222#221 +#220#226#225#214#228#227#224#230#235'T'#18#0#255#0#255#255#0#255#255#0#255'X' +#19#0'n'#176#241'n'#171#235'p'#173#235'm'#179#232's'#179#237'r'#180#239'r' +#180#239's'#181#240'v'#179#243't'#183#240'u'#184#247'Y'#20#1#255#0#255#255#0 +#255#255#0#255'W'#19#0#188#201#203#187#199#205#183#198#200#184#198#197#186 +#199#201#188#201#203#189#199#199#189#200#204#189#198#208#183#201#202#192#203 +#211'X'#20#1#255#0#255#255#0#255#255#0#255#169#182#184#227#239#239#226#238 +#238#225#237#237#226#238#238#226#238#238#226#238#238#224#236#236#229#238#241 +#225#237#239#225#237#237#227#239#239#169#182#184#255#0#255#255#0#255#255#0 +#255'['#137'uM'#138'm'#180#222#229#246#255#255#246#255#255#246#255#255#246 +#255#255#246#255#255#246#255#255#246#255#255#246#255#255#246#255#255#201#235 +#238'M'#138'm['#138'v'#255#0#255'['#137'u|'#140#137#149#197#252#149#197#252 +#149#197#252#149#197#252#149#197#252#149#197#252#149#197#252#149#197#252#149 +#197#252#149#197#252#149#197#252'|'#140#137'['#138'v'#255#0#255'['#137'u@z`' +#145#167#192#178#204#222#179#205#223#180#205#223#180#205#223#180#205#223#180 +#205#223#180#205#223#180#205#223#180#205#223#164#178#201'C|b['#138'v'#255#0 +#255#184#196#202#201#211#217#221#231#235#233#242#246#233#242#246#233#242#246 +#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#225 +#235#239#201#211#217#184#196#202#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#168#127'g'#148 +'aC'#178#142'v'#200#177#157#214#198#180#200#177#157#178#142'v'#148'aC'#168 +#127'g'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#168#127'g'#131'jd|'#144#173'l'#160#214']'#164#233'l'#160#214'|'#144#173#131 +'jd'#168#127'g'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#168#127'g'#148'hN'#170#146#129#179#169#158#182#178#170#179#169#158 +#170#146#129#148'hN'#168#127'g'#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#217#224#226#208#217#219#228#233#234#244#246#247#254 +#254#254#244#246#247#228#233#234#208#217#219#217#224#226#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#168#127'g'#148'aC'#178#142 +'v'#200#177#157#214#198#180#200#177#157#178#142'v'#148'aC'#168#127'g'#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#168#127'g' +#148'aC'#178#142'v'#200#177#157#214#198#180#200#177#157#178#142'v'#148'aC' +#168#127'g'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#168#127'g'#148'aC'#178#142'v'#200#177#157#214#198#180#200#177#157#178 +#142'v'#148'aC'#168#127'g'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#213#220#219#203#212#210#225#230#229#243#245#245#253#254 +#254#243#245#245#225#230#229#203#212#210#213#220#219#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255'V'#17#0'V'#17#0'V'#17#0'V'#17#0'V'#17#0 +'V'#17#0'V'#17#0'V'#17#0'V'#17#0'V'#17#0'V'#17#0'V'#17#0'V'#17#0#255#0#255 +#255#0#255#255#0#255'^'#17#1'W'#19#0'X'#20#1'Z'#19#0'X'#19#0'['#19#1'Y'#18#0 +'['#20#0'V'#21#0'X'#19#0'X'#21#0'V'#17#0'X'#21#0#255#0#255#255#0#255#255#0 +#255'W'#18#1'X'#20#1'V'#19#0'Y'#21#2'Z'#18#1'W'#19#0'X'#19#0'X'#19#0'Y'#17#0 +'V'#17#0'W'#16#2'W'#19#0'U'#19#0#255#0#255#255#0#255#255#0#255#168#183#185 +#170#184#183#170#183#185#170#183#185#168#183#185#169#184#186#169#185#184#170 +#183#185#171#184#186#168#183#186#169#184#186#169#182#184#171#183#187#255#0 +#255#255#0#255#255#0#255'T'#18#0'X'#19#2'S'#17#0'U'#19#1'W'#19#0'X'#19#0'Q' +#19#1'T'#15#0'W'#19#0'V'#18#0'S'#17#0'W'#18#0'W'#18#1#255#0#255#255#0#255#255 +#0#255'_'#19#1'X'#19#0'Z'#21#2'Z'#20#0'X'#19#0'X'#17#3'U'#19#0'Z'#18#1'X'#19 +#0'['#20#0'Q'#20#0'Y'#20#1'W'#18#0#255#0#255#255#0#255#255#0#255'X'#19#2'W' +#19#0'X'#20#1'Z'#18#0']'#18#4'X'#18#1'T'#21#0'Z'#18#0'S'#19#1'X'#19#0'U'#23#0 +'X'#18#1'W'#18#0#255#0#255#255#0#255#255#0#255#171#184#186#171#184#186#170 +#183#185#171#184#186#168#181#183#170#183#185#169#182#184#172#185#187#169#181 +#185#171#184#186#171#184#186#170#183#185#170#185#188#255#0#255#255#0#255#255 +#0#255'T'#18#0'X'#19#2'S'#17#0'U'#19#1'W'#19#0'X'#19#0'Q'#19#1'T'#15#0'W'#19 +#0'V'#18#0'S'#17#0'W'#18#0'W'#18#1#255#0#255#255#0#255#255#0#255'_'#19#1'X' ,#19#0'Z'#21#2'Z'#20#0'X'#19#0'X'#17#3'U'#19#0'Z'#18#1'X'#19#0'['#20#0'Q'#20#0 +'Y'#20#1'W'#18#0#255#0#255#255#0#255#255#0#255'X'#19#2'W'#19#0'X'#20#1'Z'#18 +#0']'#18#4'X'#18#1'T'#21#0'Z'#18#0'S'#19#1'X'#19#0'U'#23#0'X'#18#1'W'#18#0 +#255#0#255#255#0#255#255#0#255#171#184#186#171#184#186#170#183#185#171#184 +#186#168#181#183#170#183#185#169#182#184#172#185#187#169#181#185#171#184#186 +#171#184#186#170#183#185#170#185#188#255#0#255#255#0#255#255#0#255#209#196 +#219'['#137'u#oL'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#24'i' +'DO'#131'm'#213#201#223#255#0#255#222#196#200'['#137'u#oL'#6'b7'#6'b7'#6'b7' +#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#24'iDO'#131'm'#226#201#205#255#0#255#209 +#196#219'['#137'u#oL'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7' +#24'iDO'#131'm'#213#201#223#255#0#255#255#255#255#184#196#202#184#196#202#184 +#196#202#184#196#202#184#196#202#184#196#202#184#196#202#184#196#202#184#196 +#202#184#196#202#184#196#202#184#196#202#184#196#202#255#255#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#202#177#162#160'sY'#130'F%q-'#8#130'F%'#160's' +'Y'#202#177#162#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#202#177#162#160'sY'#130'F%q-'#8#130'F%'#160's' +'Y'#202#177#162#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#202#177#162#160'sY'#130'F%q-'#8#130'F%'#160's' +'Y'#202#177#162#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#233#237#238#213#221#222#197#208#210#188#200 +#203#197#208#210#213#221#222#233#237#238#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#202#177#162#160'sY' +#130'F%q-'#8#130'F%'#160'sY'#202#177#162#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#202#177#162#160'sY' +#130'F%q-'#8#130'F%'#160'sY'#202#177#162#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#202#177#162#160'sY' +#130'F%q-'#8#130'F%'#160'sY'#202#177#162#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#208#216#215 +#190#201#199#180#192#190#190#201#199#208#216#215#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 ,#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0 ]); LazarusResources.Add('VT_MOVENS_BMP','BMP',[ 'BM6'#12#0#0#0#0#0#0'6'#0#0#0'('#0#0#0' '#0#0#0' '#0#0#0#1#0#24#0#0#0#0#0#0#12 +#0#0#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0 +#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255 +#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 ,#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0 +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255 +#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 ,#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 ]); LazarusResources.Add('VT_MOVEEW_BMP','BMP',[ 'BM6'#12#0#0#0#0#0#0'6'#0#0#0'('#0#0#0' '#0#0#0' '#0#0#0#1#0#24#0#0#0#0#0#0#12 +#0#0#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#255 +#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255 +#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0 +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255 +#255#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255 +#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255 +#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#255 +#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0 ,#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0 +#0#255#255#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0 +#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255 +#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0 +#255#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255 +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#255#255#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#255#255#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255 +#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#255#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255 +#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 ,#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 ]); LazarusResources.Add('VT_MOVEALL_BMP','BMP',[ 'BM6'#12#0#0#0#0#0#0'6'#0#0#0'('#0#0#0' '#0#0#0' '#0#0#0#1#0#24#0#0#0#0#0#0#12 +#0#0#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0 +#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255 +#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0 +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#255#255#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0 +#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0 +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0 +#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#255 +#255#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0 +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255 ,#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255 +#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255 +#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255 +#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#255 +#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0 +#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#255#255#0 +#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0 +#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0 +#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255 +#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0 +#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0 +#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#255#255#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255 +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255 +#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255 +#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0 +#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 ,#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255 +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0 +#255#255#0#255#255#0#255#255#0#255 ]); doublecmd-0.8.2/components/virtualtreeview/VTAccessibilityFactory.pas0000664000175000017500000000755712014201074025236 0ustar alexxalexxunit VTAccessibilityFactory; // class to create IAccessibles for the tree passed into it. // If not already assigned, creates IAccessibles for the tree itself // and the focused item // the tree accessible is returned when the tree receives an WM_GETOBJECT message // the AccessibleItem is returned when the Accessible is being asked for the first child // To create your own IAccessibles, use the VTStandardAccessible unit as a reference, // and assign your Accessibles to the variables in tthe unit's initialization. // You only need to add the unit to your project, and voil, you have an accessible string tree! // // Written by Marco Zehe. (c) 2007 interface uses Classes, oleacc, VirtualTrees; type IVTAccessibleProvider = interface function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible; end; TVTAccessibilityFactory = class(TObject) private FAccessibleProviders: TInterfaceList; public constructor Create; destructor Destroy; override; function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible; procedure RegisterAccessibleProvider(AProvider: IVTAccessibleProvider); procedure UnRegisterAccessibleProvider(AProvider: IVTAccessibleProvider); end; var VTAccessibleFactory: TVTAccessibilityFactory; implementation { TVTAccessibilityFactory } constructor TVTAccessibilityFactory.Create; begin inherited; FAccessibleProviders := TInterfaceList.Create; FAccessibleProviders.Clear; end; function TVTAccessibilityFactory.CreateIAccessible( ATree: TBaseVirtualTree): IAccessible; var I: Integer; TmpIAccessible: IAccessible; // returns an IAccessible. // 1. If the Accessible property of the passed-in tree is nil, // the first registered element will be returned. // Usually, this is the IAccessible that provides information about the tree itself. // If it is not nil, we'll check whether the AccessibleItem is nil. // If it is, we'll look in the registered IAccessibles for the appropriate one. // Each IAccessibleProvider will check the tree for properties to determine whether it is responsible. // We'll work top to bottom, from the most complicated to the most simple. // The index for these should all be greater than 0, e g the IAccessible for the tree itself should always be registered first, then any IAccessible items. begin result := nil; if ATree <> nil then begin if ATree.Accessible = nil then begin if FAccessibleProviders.Count > 0 then begin result := IVTAccessibleProvider(FAccessibleProviders.Items[0]).CreateIAccessible(ATree); exit; end; end; if ATree.AccessibleItem = nil then begin if FAccessibleProviders.Count > 0 then begin for I := FAccessibleProviders.Count - 1 downto 1 do begin TmpIAccessible := IVTAccessibleProvider(FAccessibleProviders.Items[I]).CreateIAccessible(ATree); if TmpIAccessible <> nil then begin result := TmpIAccessible; break; end; end; if TmpIAccessible = nil then begin result := IVTAccessibleProvider(FAccessibleProviders.Items[0]).CreateIAccessible(ATree); end; end; end else begin result := ATree.AccessibleItem; end; end; end; destructor TVTAccessibilityFactory.Destroy; begin FAccessibleProviders.Free; FAccessibleProviders := nil; inherited; end; procedure TVTAccessibilityFactory.RegisterAccessibleProvider( AProvider: IVTAccessibleProvider); // Ads a provider if it is not already registered begin if FAccessibleProviders.IndexOf(AProvider) < 0 then FAccessibleProviders.Add(AProvider) end; procedure TVTAccessibilityFactory.UnRegisterAccessibleProvider( AProvider: IVTAccessibleProvider); // Unregisters/removes an IAccessible provider if it is present begin if FAccessibleProviders.IndexOf(AProvider) >= 0 then FAccessibleProviders.Remove(AProvider); end; end. doublecmd-0.8.2/components/virtualtreeview/units/0000775000175000017500000000000013244011205021265 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/units/gtk/0000775000175000017500000000000013244011205022052 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/units/gtk/virtualpanningwindow.pas0000664000175000017500000000201212014201074027042 0ustar alexxalexxunit virtualpanningwindow; {$mode objfpc}{$H+} interface uses LCLType, Graphics, Classes, SysUtils; type { TVirtualPanningWindow } TVirtualPanningWindow = class private FHandle: THandle; FOwnerHandle: THandle; FImage: TBitmap; procedure HandlePaintMessage; public procedure Start(OwnerHandle: THandle; const Position: TPoint); procedure Stop; procedure Show(ClipRegion: HRGN); property Image: TBitmap read FImage; property Handle: THandle read FHandle; end; implementation {$ifdef DEBUG_VTV} uses vtlogger; {$endif} { TVirtualPanningWindow } procedure TVirtualPanningWindow.HandlePaintMessage; begin end; procedure TVirtualPanningWindow.Start(OwnerHandle: THandle; const Position: TPoint); begin FImage := TBitmap.Create; end; procedure TVirtualPanningWindow.Stop; begin FImage.Free; FImage := nil; end; procedure TVirtualPanningWindow.Show(ClipRegion: HRGN); begin {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPanning],'Panning Image',FImage);{$endif} end; end. doublecmd-0.8.2/components/virtualtreeview/units/gtk/virtualdragmanager.pas0000664000175000017500000017010612014201074026442 0ustar alexxalexxunit virtualdragmanager; {fake unit just to compile - not used under non windows} {$mode delphi} interface uses Classes, SysUtils, Types; const // Drag image helpers for Windows 2000 and up. IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0)); IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46)); CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}'; SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}'; SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}'; //Bridge to ActiveX constants TYMED_HGLOBAL = 1; TYMED_ISTREAM = 4; DVASPECT_CONTENT = 1; CLSCTX_INPROC_SERVER = $0010; DROPEFFECT_COPY = 1; DROPEFFECT_LINK = 4; DROPEFFECT_MOVE = 2; DROPEFFECT_NONE = 0; DROPEFFECT_SCROLL = dword($80000000); DATADIR_GET = 1; type //types from win unit Long = LongInt; WinBool= LongBool; Bool= WinBool; ULONG = cardinal; LONGLONG = int64; LPDWORD = ^DWORD; LPVOID = pointer; TCOLORREF = cardinal; TIID = TGUID; LARGE_INTEGER = record case byte of 0: (LowPart : DWORD; HighPart : LONG); 1: (QuadPart : LONGLONG); end; PLARGE_INTEGER = ^LARGE_INTEGER; _LARGE_INTEGER = LARGE_INTEGER; TLargeInteger = Int64; PLargeInteger = ^TLargeInteger; ULARGE_INTEGER = record case byte of 0: (LowPart : DWORD; HighPart : DWORD); 1: (QuadPart : LONGLONG); end; PULARGE_INTEGER = ^ULARGE_INTEGER; _ULARGE_INTEGER = ULARGE_INTEGER; HANDLE = System.THandle; HWND = HANDLE; //HRESULT = System.HResult; HBITMAP = HANDLE; HENHMETAFILE = HANDLE; //activex types IMoniker = Interface; WINOLEAPI = HResult; TLCID = DWORD; OleChar = WChar; LPOLESTR = ^OLECHAR; HMetaFilePict = Pointer; tagBIND_OPTS = Record cvStruct, // sizeof(BIND_OPTS) grfFlags, grfMode, dwTickCountDeadline : DWord; End; TBind_Opts = tagBIND_OPTS; TCLIPFORMAT = Word; tagDVTARGETDEVICE = Record tdSize : DWord; tdDriverNameOffset, tdDeviceNameOffset, tdPortNameOffset, tdExtDevmodeOffset : Word; Data : Record End; End; DVTARGETDEVICE = TagDVTARGETDEVICE; PDVTARGETDEVICE = ^tagDVTARGETDEVICE; tagFORMATETC = Record CfFormat : Word {TCLIPFORMAT}; Ptd : PDVTARGETDEVICE; dwAspect : DWORD; lindex : Long; tymed : DWORD; End; FORMATETC = TagFORMATETC; TFORMATETC = FORMATETC; LPFORMATETC = ^FORMATETC; PFormatEtc = LPFORMATETC; tagSTATDATA = Record // field used by: FORMATETC : Tformatetc; // EnumAdvise, EnumData (cache), EnumFormats advf : DWord; // EnumAdvise, EnumData (cache) padvSink : Pointer {IAdviseSink}; // EnumAdvise dwConnection: DWord; // EnumAdvise End; STATDATA = TagStatData; TagSTGMEDIUM = Record Tymed : DWord; Case Integer Of 0 : (HBITMAP : hBitmap; PUnkForRelease : Pointer {IUnknown}); 1 : (HMETAFILEPICT : hMetaFilePict ); 2 : (HENHMETAFILE : hEnhMetaFile ); 3 : (HGLOBAL : hGlobal ); 4 : (lpszFileName : LPOLESTR ); 5 : (pstm : Pointer{IStream} ); 6 : (pstg : Pointer{IStorage} ); End; USTGMEDIUM = TagSTGMEDIUM; STGMEDIUM = USTGMEDIUM; TStgMedium = TagSTGMEDIUM; PStgMedium = ^TStgMedium; LPSTGMEDIUM = ^STGMEDIUM; IEnumString = Interface (IUnknown) ['{00000101-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out xcelt;Out Celtfetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong; Out celt;Out Celtfetched:ULong):HResult; StdCall; Function Skip (Celt:ULong):Hresult;StdCall; Function Reset:HResult;StdCall; Function Clone(Out penum:IEnumString):HResult;StdCall; End; IEnumMoniker = Interface (IUnknown) ['{00000102-0000-0000-C000-000000000046}'] Function Next(celt:ULong; out Elt;out celftfetched: ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong; Out rgelt;out celtfetched :ULong):Hresult; StdCall; Function Skip(celt:Ulong):HResult; StdCall; Function Reset:HResult; StdCall; Function Close(out penum:IEnumMoniker):HResult;StdCall; End; IEnumSTATDATA = Interface (IUnknown) ['{00000105-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall; Function Skip(Celt:ULong):HResult;StdCall; Function Reset:HResult;StdCall; Function Clone(out penum:IEnumstatdata):HResult;StdCall; End; IEnumFORMATETC = Interface (IUnknown) ['{00000103-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall; Function Skip(Celt:ULong):HResult;StdCall; Function Reset:HResult;StdCall; Function Clone(out penum:IEnumFORMATETC):HResult;StdCall; End; IPersist = Interface (IUnknown) ['{0000010c-0000-0000-C000-000000000046}'] Function GetClassId(clsid:TClsId):HResult; StdCall; End; IPersistStream = Interface(IPersist) ['{00000109-0000-0000-C000-000000000046}'] Function IsDirty:HResult; StdCall; Function Load(Const stm: IStream):HResult; StdCall; Function Save(Const stm: IStream;fClearDirty:Bool):HResult;StdCall; Function GetSizeMax(Out cbSize:ULarge_Integer):HResult; StdCall; End; IRunningObjectTable = Interface (IUnknown) ['{00000010-0000-0000-C000-000000000046}'] Function Register (grfFlags :DWord;const unkobject:IUnknown;Const mkObjectName:IMoniker;Out dwregister:DWord):HResult;StdCall; Function Revoke (dwRegister:DWord):HResult; StdCall; Function IsRunning (Const mkObjectName: IMoniker):HResult;StdCall; Function GetObject (Const mkObjectName: IMoniker; Out punkObject:IUnknown):HResult; StdCall; Function NoteChangeTime(dwRegister :DWord;Const FileTime: TFileTime):HResult;StdCall; Function GetTimeOfLastChange(Const mkObjectName:IMoniker;Out filetime:TFileTime):HResult; StdCall; Function EnumRunning (Out enumMoniker: IEnumMoniker):HResult; StdCall; End; IBindCtx = Interface (IUnknown) ['{0000000e-0000-0000-C000-000000000046}'] Function RegisterObjectBound(Const punk:IUnknown):HResult; stdCall; Function RevokeObjectBound (Const Punk:IUnknown):HResult; stdCall; Function ReleaseBoundObjects :HResult; StdCall; Function SetBindOptions(Const bindOpts:TBind_Opts):HResult; stdCall; // Function RemoteSetBindOptions(Const bind_opts: TBind_Opts2):HResult;StdCall; Function GetBindOptions(var BindOpts:TBind_Opts):HResult; stdCall; // Function RemoteGetBindOptions(Var bind_opts: TBind_Opts2):HResult;StdCall; Function GetRunningObjectTable(Out rot : IRunningObjectTable):Hresult; StdCall; Function RegisterObjectParam(Const pszkey:LPOleStr;const punk:IUnknown):HResult; Function GetObjectParam(Const pszkey:LPOleStr; out punk: IUnknown):HResult; StdCall; Function EnumObjectParam (out enum:IEnumString):Hresult;StdCall; Function RevokeObjectParam(pszKey:LPOleStr):HResult;StdCall; End; PIMoniker = ^IMoniker; IMoniker = Interface (IPersistStream) ['{0000000f-0000-0000-C000-000000000046}'] Function BindToObject (const pbc:IBindCtx;const mktoleft:IMoniker; RiidResult:TIID;Out vresult):HResult;StdCall; // Function RemoteBindToObject (const pbc:IBindCtx;const mktoleft:IMoniker;RiidResult:TIID;Out vresult):HResult;StdCall; Function BindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall; // Function RemoteBindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall; Function Reduce (const pbc:IBindCtx; dwReduceHowFar:DWord; mktoLeft: PIMoniker; Out mkReduced:IMoniker):HResult; StdCall; Function ComposeWith(Const MkRight:IMoniker;fOnlyIfNotGeneric:BOOL; OUT mkComposite:IMoniker):HResult; StdCall; Function Enum(fForward:Bool;Out enumMoniker:IEnumMoniker):HResult;StdCall; Function IsEqual(Const mkOtherMoniker:IMoniker):HResult;StdCall; Function Hash (Out dwHash:Dword):HResult;StdCall; Function IsRunning(Const bc:IBindCtx;Const MkToLeft:IMoniker;Const mknewlyRunning:IMoniker):HResult;StdCall; Function GetTimeOfLastChange(Const bc:IBindCtx;Const mkToLeft:IMoniker; out ft : FileTime):HResult; StdCall; Function Inverse(out mk : IMoniker):HResult; StdCall; Function CommonPrefixWith (Const mkOther:IMoniker):HResult; StdCall; Function RelativePathTo(Const mkother:IMoniker; Out mkRelPath : IMoniker):HResult;StdCall; Function GetDisplayName(Const bc:IMoniker;const mktoleft:IMoniker;Out szDisplayName: pOleStr):HResult; StdCall; Function ParseDisplayName(Const bc:IBindCtx;Const mkToLeft:IMoniker;szDisplayName:POleStr;out cheaten:ULong;out mkOut:IMoniker):HResult; StdCall; Function IsSystemMonitor(Out dwMkSys:DWord):HResult;StdCall; End; IAdviseSink = Interface (IUnknown) ['{0000010f-0000-0000-C000-000000000046}'] {$ifdef midl500} ['{00000150-0000-0000-C000-000000000046}'] {$endif} Procedure OnDataChange (Const pformatetc : Formatetc;const pstgmed : STGMEDIUM); StdCall; Procedure OnViewChange (dwAspect : DWord; lindex : Long); StdCall; Procedure OnRename (Const pmk : IMoniker); StdCall; Procedure OnSave; StdCall; Procedure OnClose; StdCall; End; //Fake interfaces IDataObject = Interface (IUnknown) ['{0000010e-0000-0000-C000-000000000046}'] Function GetData(Const formatetcIn : FORMATETC;Out medium : STGMEDIUM):HRESULT; STDCALL; Function GetDataHere(CONST pformatetc : FormatETC; Out medium : STGMEDIUM):HRESULT; STDCALL; Function QueryGetData(const pformatetc : FORMATETC):HRESULT; STDCALL; Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; STDCALl; Function SetData (Const pformatetc : FORMATETC;const medium:STGMEDIUM;FRelease : BOOL):HRESULT; StdCall; Function EnumFormatEtc(dwDirection : DWord; OUT enumformatetcpara : IENUMFORMATETC):HRESULT; StdCall; Function DAdvise(const formatetc : FORMATETC;advf :DWORD; CONST AdvSink : IAdviseSink;OUT dwConnection:DWORD):HRESULT;StdCall; Function DUnadvise(dwconnection :DWord) :HRESULT;StdCall; Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;StdCall; End; IDropTarget = interface(IUnknown) ['{00000122-0000-0000-C000-000000000046}'] function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; function DragLeave: HResult;StdCall; function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD):HResult;StdCall; end; IDropSource = interface(IUnknown) ['{00000121-0000-0000-C000-000000000046}'] function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: LongWord):HResult;StdCall; function GiveFeedback(dwEffect: LongWord): HResult;StdCall; end; IDataAdviseHolder = Interface (IUnknown) ['{00000110-0000-0000-C000-000000000046}'] Function Advise (CONST pdataObject : IDataObject;CONST fetc:FORMATETC;advf : DWORD;Const pAdvise:IAdviseSink;Out DwConnection:DWord):HResult; StdCall; Function Unadvise (dwConnection:Dword):HResult; StdCall; Function EnumAdvise(out penumAdvise : IEnumStatData):HResult;StdCall; Function SendOnDataChange(const pDataObject :IDataObject;DwReserved,advf : DWord):HResult; StdCall; End; // OLE drag'n drop support TFormatEtcArray = array of TFormatEtc; TFormatArray = array of Word; // IDataObject.SetData support TInternalStgMedium = packed record Format: TClipFormat; Medium: TStgMedium; end; TInternalStgMediumArray = array of TInternalStgMedium; TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc) private FTree: TObject; FFormatEtcArray: TFormatEtcArray; FCurrentIndex: Integer; public constructor Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray); function Clone(out Enum: IEnumFormatEtc): HResult; stdcall; function Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; stdcall; function Reset: HResult; stdcall; function Skip(celt: LongWord): HResult; stdcall; end; IDropTargetHelper = interface(IUnknown) [SID_IDropTargetHelper] function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function DragLeave: HRESULT; stdcall; function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Show(fShow: Boolean): HRESULT; stdcall; end; PSHDragImage = ^TSHDragImage; TSHDragImage = packed record sizeDragImage: TSize; ptOffset: TPoint; hbmpDragImage: HBITMAP; ColorRef: TColorRef; end; IDragSourceHelper = interface(IUnknown) [SID_IDragSourceHelper] function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall; function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall; end; IVTDragManager = interface(IUnknown) ['{C4B25559-14DA-446B-8901-0C879000EB16}'] procedure ForceDragLeave; stdcall; function GetDataObject: IDataObject; stdcall; function GetDragSource: TObject; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; property DataObject: IDataObject read GetDataObject; property DragSource: TObject read GetDragSource; property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported; property IsDropTarget: Boolean read GetIsDropTarget; end; // This data object is used in two different places. One is for clipboard operations and the other while dragging. TVTDataObject = class(TInterfacedObject, IDataObject) private //FOwner: TBaseVirtualTree; // The tree which provides clipboard or drag data. FOwner: TObject; // The tree which provides clipboard or drag data. FForClipboard: Boolean; // Determines which data to render with GetData. FFormatEtcArray: TFormatEtcArray; FInternalStgMediumArray: TInternalStgMediumArray; // The available formats in the DataObject FAdviseHolder: IDataAdviseHolder; // Reference to an OLE supplied implementation for advising. protected function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; function FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; function FindInternalStgMedium(Format: TClipFormat): PStgMedium; function HGlobalClone(HGlobal: THandle): THandle; function RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; property ForClipboard: Boolean read FForClipboard; property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray; property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray; property Owner: TObject read FOwner; public constructor Create(AOwner: TObject; ForClipboard: Boolean); virtual; destructor Destroy; override; function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; virtual; stdcall; function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall; Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;virtual;StdCall; function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall; Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; virtual; STDCALl; function GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall; function SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall; end; // TVTDragManager is a class to manage drag and drop in a Virtual Treeview. TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget) private FOwner, // The tree which is responsible for drag management. FDragSource: TObject; // Reference to the source tree if the source was a VT, might be different than // the owner tree. FIsDropTarget: Boolean; // True if the owner is currently the drop target. FDataObject: IDataObject; // A reference to the data object passed in by DragEnter (only used when the owner // tree is the current drop target). FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support FFullDragging: BOOL; // True, if full dragging is currently enabled in the system. function GetDataObject: IDataObject; stdcall; function GetDragSource: TObject; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; public constructor Create(AOwner: TObject); virtual; destructor Destroy; override; function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function DragLeave: HResult; stdcall; function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; procedure ForceDragLeave; stdcall; function GiveFeedback(Effect: LongWord): HResult; stdcall; function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall; end; //Ole helper functions function Succeeded(Status : HRESULT) : BOOLEAN; function Failed(Status : HRESULT) : BOOLEAN; //ActiveX functions that have wrong calling convention in fpc function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall; function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall; function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI; function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall; procedure OleUninitialize;stdcall; procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall; function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall; function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall; function OleFlushClipboard:WINOLEAPI;stdcall; function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall; function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall; function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall; //helper functions to isolate windows/OLE specific code function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; function GetStreamFromMedium(Medium:TStgMedium):TStream; procedure UnlockMediumData(Medium:TStgMedium); function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject; function AllocateGlobal(Data: Pointer; DataSize:Cardinal): HGLOBAL; implementation uses VirtualTrees, Controls {$ifdef DEBUG_VTV}, vtlogger{$endif}; type TVirtualTreeAccess = class (TBaseVirtualTree) end; function Succeeded(Status : HRESULT) : BOOLEAN; begin Succeeded:=Status and HRESULT($80000000)=0; end; function Failed(Status : HRESULT) : BOOLEAN; begin Failed:=Status and HRESULT($80000000)<>0; end; function RegisterDragDrop(hwnd: HWND; pDropTarget: IDropTarget): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function RevokeDragDrop(hwnd: HWND): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource; dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleInitialize(pvReserved: LPVOID): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; procedure OleUninitialize; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; procedure ReleaseStgMedium(_para1: LPSTGMEDIUM); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleSetClipboard(pDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleGetClipboard(out ppDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleFlushClipboard: WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleIsCurrentClipboard(pDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function CreateStreamOnHGlobal(hGlobal: HGLOBAL; fDeleteOnRelease: BOOL; out stm: IStream): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function CoCreateInstance(const _para1: TCLSID; _para2: IUnknown; _para3: DWORD; const _para4: TIID; out _para5): HRESULT; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; { //--------------- local function -------------------------------------------- procedure WriteNodes(Stream: TStream); var Selection: TNodeArray; I: Integer; begin with TVirtualTreeAccess(Tree) do begin if ForClipboard then Selection := GetSortedCutCopySet(True) else Selection := GetSortedSelection(True); for I := 0 to High(Selection) do WriteNode(Stream, Selection[I]); end; end; //--------------- end local function ---------------------------------------- } var Data: PCardinal; ResPointer: Pointer; ResSize: Integer; OLEStream: IStream; VCLStream: TStream; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { VCLStream := nil; try Medium.PunkForRelease := nil; // Return data in one of the supported storage formats, prefer IStream. if FormatEtcIn.tymed and TYMED_ISTREAM <> 0 then begin // Create an IStream on a memory handle (here it is 0 which indicates to implicitely allocated a handle). // Do not use TStreamAdapter as it is not compatible with OLE (when flushing the clipboard OLE wants the HGlobal // back which is not supported by TStreamAdapater). CreateStreamOnHGlobal(0, True, OLEStream); VCLStream := TOLEStream.Create(OLEStream); WriteNodes(VCLStream); // Rewind stream. VCLStream.Position := 0; Medium.tymed := TYMED_ISTREAM; IUnknown(Medium.Pstm) := OLEStream; Result := S_OK; end else begin VCLStream := TMemoryStream.Create; WriteNodes(VCLStream); ResPointer := TMemoryStream(VCLStream).Memory; ResSize := VCLStream.Position; // Allocate memory to hold the string. if ResSize > 0 then begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, ResSize + SizeOf(Cardinal)); Data := GlobalLock(Medium.hGlobal); // Store the size of the data too, for easy retrival. Data^ := ResSize; Inc(Data); Move(ResPointer^, Data^, ResSize); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Result := S_OK; end else Result := E_FAIL; end; finally // We can free the VCL stream here since it was either a pure memory stream or only a wrapper around // the OLEStream which exists independently. VCLStream.Free; end; } end; type // needed to handle OLE global memory objects TOLEMemoryStream = class(TCustomMemoryStream) public function Write(const Buffer; Count: Integer): Longint; override; end; //---------------------------------------------------------------------------------------------------------------------- function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} // raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError)); end; function GetStreamFromMedium(Medium: TStgMedium): TStream; var Data: Pointer; I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; if Medium.tymed = TYMED_ISTREAM then Result := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream) else begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin // Get the total size of data to retrieve. I := PCardinal(Data)^; Inc(PCardinal(Data)); Result := TOLEMemoryStream.Create; TOLEMemoryStream(Result).SetPointer(Data, I); end; end; } end; procedure UnlockMediumData(Medium: TStgMedium); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Medium.tymed = TYMED_HGLOBAL then GlobalUnlock(Medium.hGlobal); } end; function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject; var Medium: TStgMedium; Data: PVTReference; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; if Assigned(DataObject) then begin Format.cfFormat := CF_VTREFERENCE; if DataObject.GetData(Format, Medium) = S_OK then begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin if Data.Process = GetCurrentProcessID then Result := Data.Tree; GlobalUnlock(Medium.hGlobal); end; ReleaseStgMedium(@Medium); end; end; } end; function AllocateGlobal(Data: Pointer; DataSize: Cardinal): HGLOBAL; var P:Pointer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize); P := GlobalLock(Result); Move(Data^, P^, DataSize); GlobalUnlock(Result); } end; //---------------------------------------------------------------------------------------------------------------------- // OLE drag and drop support classes // This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs // of DD'ing various kinds of virtual data and works also between applications. //----------------- TEnumFormatEtc ------------------------------------------------------------------------------------- constructor TEnumFormatEtc.Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray); var I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FTree := Tree; // Make a local copy of the format data. SetLength(FFormatEtcArray, Length(AFormatEtcArray)); for I := 0 to High(AFormatEtcArray) do FFormatEtcArray[I] := AFormatEtcArray[I]; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult; var AClone: TEnumFormatEtc; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; try AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray); AClone.FCurrentIndex := FCurrentIndex; Enum := AClone as IEnumFormatEtc; except Result := E_FAIL; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; var CopyCount: LongWord; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_FALSE; CopyCount := Length(FFormatEtcArray) - FCurrentIndex; if celt < CopyCount then CopyCount := celt; if CopyCount > 0 then begin Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc)); Inc(FCurrentIndex, CopyCount); Result := S_OK; end; //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with // a C Program call with a NULL in pCeltFetcjed?? //Answer: Yes. Is necessary a check here if @pceltFetched <> nil then pceltFetched := CopyCount; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Reset: HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { FCurrentIndex := 0; Result := S_OK; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Skip(celt: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FCurrentIndex + celt < High(FFormatEtcArray) then begin Inc(FCurrentIndex, celt); Result := S_Ok; end else Result := S_FALSE; } end; //----------------- TVTDataObject -------------------------------------------------------------------------------------- constructor TVTDataObject.Create(AOwner: TObject; ForClipboard: Boolean); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FOwner := AOwner; FForClipboard := ForClipboard; TVirtualTreeAccess(FOwner).GetNativeClipboardFormats(FFormatEtcArray); } end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDataObject.Destroy; var I: Integer; StgMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // Cancel a pending clipboard operation if this data object was created for the clipboard and // is freed because something else is placed there. if FForClipboard and not (tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates) then TVirtualTreeAccess(FOwner).CancelCutOrCopy; // Release any internal clipboard formats for I := 0 to High(FormatEtcArray) do begin StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat); if Assigned(StgMedium) then ReleaseStgMedium(StgMedium); end; FormatEtcArray := nil; inherited; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; // Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown // interface, will always return the same pointer. begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(TestUnknown) then begin if TestUnknown.QueryInterface(IUnknown, Result) = 0 then Result._Release // Don't actually need it just need the pointer value else Result := TestUnknown end else Result := TestUnknown } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and (FormatEtc1.tymed and FormatEtc2.tymed <> 0); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; var I: integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := -1; for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then begin Result := I; Break; end end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium; var I: integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; for I := 0 to High(InternalStgMediumArray) do begin if Format = InternalStgMediumArray[I].Format then begin Result := @InternalStgMediumArray[I].Medium; Break; end end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle; // Returns a global memory block that is a copy of the passed memory block. var Size: Cardinal; Data, NewData: PChar; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Size := GlobalSize(HGlobal); Result := GlobalAlloc(GPTR, Size); Data := GlobalLock(hGlobal); try NewData := GlobalLock(Result); try Move(Data^, NewData^, Size); finally GlobalUnLock(Result); end finally GlobalUnLock(hGlobal); end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; // Tries to render one of the formats which have been stored via the SetData method. // Since this data is already there it is just copied or its reference count is increased (depending on storage medium). var InternalMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := True; InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat); if Assigned(InternalMedium) then OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject) else Result := False; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; // InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or // increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually // the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData. // If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during // that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make // copy of the data for the caller only to have them destroy it then need us to copy it again if necessary. // This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData. // This way when the caller frees the structure it sees the unkForRelease is not nil and calls Release on the object // instead of destroying the actual data. var Len: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; // Simply copy all fields to start with. OutStgMedium := InStgMedium; // The data handled here always results from a call of SetData we got. This ensures only one storage format // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several // storage formats). case InStgMedium.tymed of TYMED_HGLOBAL: begin if CopyInMedium then begin // Generate a unique copy of the data passed OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal); if OutStgMedium.hGlobal = 0 then Result := E_OUTOFMEMORY end else // Don't generate a copy just use ourselves and the copy previously saved. OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount. end; TYMED_FILE: begin //todo_lcl_check Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character. OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len); Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len); end; TYMED_ISTREAM: IUnknown(OutStgMedium.Pstm)._AddRef; TYMED_ISTORAGE: IUnknown(OutStgMedium.Pstg)._AddRef; TYMED_GDI: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy GDI objects right now. TYMED_MFPICT: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now. TYMED_ENHMF: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now. else Result := DV_E_TYMED; end; if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then IUnknown(OutStgMedium.PunkForRelease)._AddRef; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; // Advise sink management is greatly simplified by the IDataAdviseHolder interface. // We use this interface and forward all concerning calls to it. begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; if FAdviseHolder = nil then Result := CreateDataAdviseHolder(FAdviseHolder); if Result = S_OK then Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DUnadvise(dwConnection: DWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FAdviseHolder = nil then Result := E_NOTIMPL else Result := FAdviseHolder.Unadvise(dwConnection); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumDAvise(Out enumAdvise : IEnumStatData):HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FAdviseHolder = nil then Result := OLE_E_ADVISENOTSUPPORTED else Result := FAdviseHolder.EnumAdvise(enumAdvise); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; var NewList: TEnumFormatEtc; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := E_FAIL; if Direction = DATADIR_GET then begin NewList := TEnumFormatEtc.Create(TVirtualTreeAccess(FOwner), FormatEtcArray); EnumFormatEtc := NewList as IEnumFormatEtc; Result := S_OK; end else EnumFormatEtc := nil; if EnumFormatEtc = nil then Result := OLE_S_USEREG; } end; //---------------------------------------------------------------------------------------------------------------------- Function TVTDataObject.GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := DATA_S_SAMEFORMATETC; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; // Data is requested by clipboard or drop target. This method dispatchs the call // depending on the data being requested. var I: Integer; Data: PVTReference; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} // The tree reference format is always supported and returned from here. { if FormatEtcIn.cfFormat = CF_VTREFERENCE then begin // Note: this format is not used while flushing the clipboard to avoid a dangling reference // when the owner tree is destroyed before the clipboard data is replaced with something else. if tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates then Result := E_FAIL else begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference)); Data := GlobalLock(Medium.hGlobal); Data.Process := GetCurrentProcessID; Data.Tree := TBaseVirtualTree(FOwner); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Medium.PunkForRelease := nil; Result := S_OK; end; end else begin try // See if we accept this type and if not get the correct return value. Result := QueryGetData(FormatEtcIn); if Result = S_OK then begin for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then begin if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then Result := TVirtualTreeAccess(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard); Break; end; end end except FillChar(Medium, SizeOf(Medium), #0); Result := E_FAIL; end; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult; var I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := DV_E_CLIPFORMAT; for I := 0 to High(FFormatEtcArray) do begin if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then begin if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then begin if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then begin if FormatEtc.lindex = FFormatEtcArray[I].lindex then begin Result := S_OK; Break; end else Result := DV_E_LINDEX; end else Result := DV_E_DVASPECT; end else Result := DV_E_TYMED; end; end } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; // Allows dynamic adding to the IDataObject during its existance. Most noteably it is used to implement // IDropSourceHelper and allows to set a special format for optimized moves during a shell transfer. var Index: Integer; LocalStgMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // See if we already have a format of that type available. Index := FindFormatEtc(FormatEtc, FormatEtcArray); if Index > - 1 then begin // Just use the TFormatEct in the array after releasing the data. LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat); if Assigned(LocalStgMedium) then begin ReleaseStgMedium(LocalStgMedium); FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; end else begin // It is a new format so create a new TFormatCollectionItem, copy the // FormatEtc parameter into the new object and and put it in the list. SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1); FormatEtcArray[High(FormatEtcArray)] := FormatEtc; // Create a new InternalStgMedium and initialize it and associate it with the format. SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1); InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat; LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium; FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; if DoRelease then begin // We are simply being given the data and we take control of it. LocalStgMedium^ := Medium; Result := S_OK end else begin // We need to reference count or copy the data and keep our own references to it. Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject); // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium. // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN. if Assigned(LocalStgMedium.PunkForRelease) then begin if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface end; end; // Tell all registered advice sinks about the data change. if Assigned(FAdviseHolder) then FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0); } end; //----------------- TVTDragManager ------------------------------------------------------------------------------------- constructor TVTDragManager.Create(AOwner: TObject); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FOwner := AOwner; // Create an instance of the drop target helper interface. This will fail but not harm on systems which do // not support this interface (everything below Windows 2000); CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper); } end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDragManager.Destroy; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // Set the owner's reference to us to nil otherwise it will access an invalid pointer // after our desctruction is complete. TVirtualTreeAccess(FOwner).FreeDragManager; inherited; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDataObject: IDataObject; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem. // In this case there is no local reference to a data object and one is created (but not stored). // If there is a local reference then the owner tree is currently the drop target and the stored interface is // that of the drag initiator. if Assigned(FDataObject) then Result := FDataObject else begin Result := TVirtualTreeAccess(FOwner).DoCreateDataObject; if Result = nil then Result := TVTDataObject.Create(FOwner, False) as IDataObject; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDragSource: TObject; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := FDragSource; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDropTargetHelperSupported: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := Assigned(FDropTargetHelper); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetIsDropTarget: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := FIsDropTarget; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { FDataObject := DataObject; FIsDropTarget := True; SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0); // If full dragging of window contents is disabled in the system then our tree windows will be locked // and cannot be updated during a drag operation. With the following call painting is again enabled. if not FFullDragging then LockWindowUpdate(0); if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragEnter(TBaseVirtualTree(FOwner).Handle, DataObject, Pt, Effect); FDragSource := TVirtualTreeAccess(FOwner).GetTreeFromDataObject(DataObject); Result := TVirtualTreeAccess(FOwner).DragEnter(KeyState, Pt, Effect); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragLeave: HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; TVirtualTreeAccess(FOwner).DragLeave; FIsDropTarget := False; FDragSource := nil; FDataObject := nil; Result := NOERROR; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragOver(Pt, Effect); Result := TVirtualTreeAccess(FOwner).DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.Drop(DataObject, Pt, Effect); Result := TVirtualTreeAccess(FOwner).DragDrop(DataObject, KeyState, Pt, Effect); FIsDropTarget := False; FDataObject := nil; } end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragManager.ForceDragLeave; // Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive // a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from // screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE). begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GiveFeedback(Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := DRAGDROP_S_USEDEFAULTCURSORS; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; var RButton, LButton: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { LButton := (KeyState and MK_LBUTTON) <> 0; RButton := (KeyState and MK_RBUTTON) <> 0; // Drag'n drop canceled by pressing both mouse buttons or Esc? if (LButton and RButton) or EscapePressed then Result := DRAGDROP_S_CANCEL else // Drag'n drop finished? if not (LButton or RButton) then Result := DRAGDROP_S_DROP else Result := S_OK; } end; end. doublecmd-0.8.2/components/virtualtreeview/units/gtk/fakeactivex.pas0000664000175000017500000000005412014201074025047 0ustar alexxalexxunit FakeActiveX; {$i ../dummyactivex.inc} doublecmd-0.8.2/components/virtualtreeview/units/gtk/fakemmsystem.pas0000664000175000017500000000075212014201074025267 0ustar alexxalexxunit fakemmsystem; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Types; function timeBeginPeriod(x1: DWord): DWord; function timeEndPeriod(x1: DWord): DWord; function timeGetTime: DWORD; implementation function timeBeginPeriod(x1: DWord): DWord; begin end; function timeEndPeriod(x1: DWord): DWord; begin end; function timeGetTime: DWORD; var ATime: TSystemTime; begin //todo: properly implement GetLocalTime(ATime); Result := ATime.MilliSecond; end; end. doublecmd-0.8.2/components/virtualtreeview/units/qt/0000775000175000017500000000000013244011205021711 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/units/qt/virtualpanningwindow.pas0000664000175000017500000000201212014201074026701 0ustar alexxalexxunit virtualpanningwindow; {$mode objfpc}{$H+} interface uses LCLType, Graphics, Classes, SysUtils; type { TVirtualPanningWindow } TVirtualPanningWindow = class private FHandle: THandle; FOwnerHandle: THandle; FImage: TBitmap; procedure HandlePaintMessage; public procedure Start(OwnerHandle: THandle; const Position: TPoint); procedure Stop; procedure Show(ClipRegion: HRGN); property Image: TBitmap read FImage; property Handle: THandle read FHandle; end; implementation {$ifdef DEBUG_VTV} uses vtlogger; {$endif} { TVirtualPanningWindow } procedure TVirtualPanningWindow.HandlePaintMessage; begin end; procedure TVirtualPanningWindow.Start(OwnerHandle: THandle; const Position: TPoint); begin FImage := TBitmap.Create; end; procedure TVirtualPanningWindow.Stop; begin FImage.Free; FImage := nil; end; procedure TVirtualPanningWindow.Show(ClipRegion: HRGN); begin {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPanning],'Panning Image',FImage);{$endif} end; end. doublecmd-0.8.2/components/virtualtreeview/units/qt/virtualdragmanager.pas0000664000175000017500000017010712014201074026302 0ustar alexxalexxunit virtualdragmanager; {fake unit just to compile - not used under non windows} {$mode delphi} interface uses Classes, SysUtils, Types; const // Drag image helpers for Windows 2000 and up. IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0)); IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46)); CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}'; SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}'; SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}'; //Bridge to ActiveX constants TYMED_HGLOBAL = 1; TYMED_ISTREAM = 4; DVASPECT_CONTENT = 1; CLSCTX_INPROC_SERVER = $0010; DROPEFFECT_COPY = 1; DROPEFFECT_LINK = 4; DROPEFFECT_MOVE = 2; DROPEFFECT_NONE = 0; DROPEFFECT_SCROLL = dword($80000000); DATADIR_GET = 1; type //types from win unit Long = LongInt; WinBool= LongBool; Bool= WinBool; ULONG = cardinal; LONGLONG = int64; LPDWORD = ^DWORD; LPVOID = pointer; TCOLORREF = cardinal; TIID = TGUID; LARGE_INTEGER = record case byte of 0: (LowPart : DWORD; HighPart : LONG); 1: (QuadPart : LONGLONG); end; PLARGE_INTEGER = ^LARGE_INTEGER; _LARGE_INTEGER = LARGE_INTEGER; TLargeInteger = Int64; PLargeInteger = ^TLargeInteger; ULARGE_INTEGER = record case byte of 0: (LowPart : DWORD; HighPart : DWORD); 1: (QuadPart : LONGLONG); end; PULARGE_INTEGER = ^ULARGE_INTEGER; _ULARGE_INTEGER = ULARGE_INTEGER; HANDLE = System.THandle; HWND = HANDLE; //HRESULT = System.HResult; HBITMAP = HANDLE; HENHMETAFILE = HANDLE; //activex types IMoniker = Interface; WINOLEAPI = HResult; TLCID = DWORD; OleChar = WChar; LPOLESTR = ^OLECHAR; HMetaFilePict = Pointer; tagBIND_OPTS = Record cvStruct, // sizeof(BIND_OPTS) grfFlags, grfMode, dwTickCountDeadline : DWord; End; TBind_Opts = tagBIND_OPTS; TCLIPFORMAT = Word; tagDVTARGETDEVICE = Record tdSize : DWord; tdDriverNameOffset, tdDeviceNameOffset, tdPortNameOffset, tdExtDevmodeOffset : Word; Data : Record End; End; DVTARGETDEVICE = TagDVTARGETDEVICE; PDVTARGETDEVICE = ^tagDVTARGETDEVICE; tagFORMATETC = Record CfFormat : Word {TCLIPFORMAT}; Ptd : PDVTARGETDEVICE; dwAspect : DWORD; lindex : Long; tymed : DWORD; End; FORMATETC = TagFORMATETC; TFORMATETC = FORMATETC; LPFORMATETC = ^FORMATETC; PFormatEtc = LPFORMATETC; tagSTATDATA = Record // field used by: FORMATETC : Tformatetc; // EnumAdvise, EnumData (cache), EnumFormats advf : DWord; // EnumAdvise, EnumData (cache) padvSink : Pointer {IAdviseSink}; // EnumAdvise dwConnection: DWord; // EnumAdvise End; STATDATA = TagStatData; TagSTGMEDIUM = Record Tymed : DWord; Case Integer Of 0 : (HBITMAP : hBitmap; PUnkForRelease : Pointer {IUnknown}); 1 : (HMETAFILEPICT : hMetaFilePict ); 2 : (HENHMETAFILE : hEnhMetaFile ); 3 : (HGLOBAL : hGlobal ); 4 : (lpszFileName : LPOLESTR ); 5 : (pstm : Pointer{IStream} ); 6 : (pstg : Pointer{IStorage} ); End; USTGMEDIUM = TagSTGMEDIUM; STGMEDIUM = USTGMEDIUM; TStgMedium = TagSTGMEDIUM; PStgMedium = ^TStgMedium; LPSTGMEDIUM = ^STGMEDIUM; IEnumString = Interface (IUnknown) ['{00000101-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out xcelt;Out Celtfetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong; Out celt;Out Celtfetched:ULong):HResult; StdCall; Function Skip (Celt:ULong):Hresult;StdCall; Function Reset:HResult;StdCall; Function Clone(Out penum:IEnumString):HResult;StdCall; End; IEnumMoniker = Interface (IUnknown) ['{00000102-0000-0000-C000-000000000046}'] Function Next(celt:ULong; out Elt;out celftfetched: ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong; Out rgelt;out celtfetched :ULong):Hresult; StdCall; Function Skip(celt:Ulong):HResult; StdCall; Function Reset:HResult; StdCall; Function Close(out penum:IEnumMoniker):HResult;StdCall; End; IEnumSTATDATA = Interface (IUnknown) ['{00000105-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall; Function Skip(Celt:ULong):HResult;StdCall; Function Reset:HResult;StdCall; Function Clone(out penum:IEnumstatdata):HResult;StdCall; End; IEnumFORMATETC = Interface (IUnknown) ['{00000103-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall; Function Skip(Celt:ULong):HResult;StdCall; Function Reset:HResult;StdCall; Function Clone(out penum:IEnumFORMATETC):HResult;StdCall; End; IPersist = Interface (IUnknown) ['{0000010c-0000-0000-C000-000000000046}'] Function GetClassId(clsid:TClsId):HResult; StdCall; End; IPersistStream = Interface(IPersist) ['{00000109-0000-0000-C000-000000000046}'] Function IsDirty:HResult; StdCall; Function Load(Const stm: IStream):HResult; StdCall; Function Save(Const stm: IStream;fClearDirty:Bool):HResult;StdCall; Function GetSizeMax(Out cbSize:ULarge_Integer):HResult; StdCall; End; IRunningObjectTable = Interface (IUnknown) ['{00000010-0000-0000-C000-000000000046}'] Function Register (grfFlags :DWord;const unkobject:IUnknown;Const mkObjectName:IMoniker;Out dwregister:DWord):HResult;StdCall; Function Revoke (dwRegister:DWord):HResult; StdCall; Function IsRunning (Const mkObjectName: IMoniker):HResult;StdCall; Function GetObject (Const mkObjectName: IMoniker; Out punkObject:IUnknown):HResult; StdCall; Function NoteChangeTime(dwRegister :DWord;Const FileTime: TFileTime):HResult;StdCall; Function GetTimeOfLastChange(Const mkObjectName:IMoniker;Out filetime:TFileTime):HResult; StdCall; Function EnumRunning (Out enumMoniker: IEnumMoniker):HResult; StdCall; End; IBindCtx = Interface (IUnknown) ['{0000000e-0000-0000-C000-000000000046}'] Function RegisterObjectBound(Const punk:IUnknown):HResult; stdCall; Function RevokeObjectBound (Const Punk:IUnknown):HResult; stdCall; Function ReleaseBoundObjects :HResult; StdCall; Function SetBindOptions(Const bindOpts:TBind_Opts):HResult; stdCall; // Function RemoteSetBindOptions(Const bind_opts: TBind_Opts2):HResult;StdCall; Function GetBindOptions(var BindOpts:TBind_Opts):HResult; stdCall; // Function RemoteGetBindOptions(Var bind_opts: TBind_Opts2):HResult;StdCall; Function GetRunningObjectTable(Out rot : IRunningObjectTable):Hresult; StdCall; Function RegisterObjectParam(Const pszkey:LPOleStr;const punk:IUnknown):HResult; Function GetObjectParam(Const pszkey:LPOleStr; out punk: IUnknown):HResult; StdCall; Function EnumObjectParam (out enum:IEnumString):Hresult;StdCall; Function RevokeObjectParam(pszKey:LPOleStr):HResult;StdCall; End; PIMoniker = ^IMoniker; IMoniker = Interface (IPersistStream) ['{0000000f-0000-0000-C000-000000000046}'] Function BindToObject (const pbc:IBindCtx;const mktoleft:IMoniker; RiidResult:TIID;Out vresult):HResult;StdCall; // Function RemoteBindToObject (const pbc:IBindCtx;const mktoleft:IMoniker;RiidResult:TIID;Out vresult):HResult;StdCall; Function BindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall; // Function RemoteBindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall; Function Reduce (const pbc:IBindCtx; dwReduceHowFar:DWord; mktoLeft: PIMoniker; Out mkReduced:IMoniker):HResult; StdCall; Function ComposeWith(Const MkRight:IMoniker;fOnlyIfNotGeneric:BOOL; OUT mkComposite:IMoniker):HResult; StdCall; Function Enum(fForward:Bool;Out enumMoniker:IEnumMoniker):HResult;StdCall; Function IsEqual(Const mkOtherMoniker:IMoniker):HResult;StdCall; Function Hash (Out dwHash:Dword):HResult;StdCall; Function IsRunning(Const bc:IBindCtx;Const MkToLeft:IMoniker;Const mknewlyRunning:IMoniker):HResult;StdCall; Function GetTimeOfLastChange(Const bc:IBindCtx;Const mkToLeft:IMoniker; out ft : FileTime):HResult; StdCall; Function Inverse(out mk : IMoniker):HResult; StdCall; Function CommonPrefixWith (Const mkOther:IMoniker):HResult; StdCall; Function RelativePathTo(Const mkother:IMoniker; Out mkRelPath : IMoniker):HResult;StdCall; Function GetDisplayName(Const bc:IMoniker;const mktoleft:IMoniker;Out szDisplayName: pOleStr):HResult; StdCall; Function ParseDisplayName(Const bc:IBindCtx;Const mkToLeft:IMoniker;szDisplayName:POleStr;out cheaten:ULong;out mkOut:IMoniker):HResult; StdCall; Function IsSystemMonitor(Out dwMkSys:DWord):HResult;StdCall; End; IAdviseSink = Interface (IUnknown) ['{0000010f-0000-0000-C000-000000000046}'] {$ifdef midl500} ['{00000150-0000-0000-C000-000000000046}'] {$endif} Procedure OnDataChange (Const pformatetc : Formatetc;const pstgmed : STGMEDIUM); StdCall; Procedure OnViewChange (dwAspect : DWord; lindex : Long); StdCall; Procedure OnRename (Const pmk : IMoniker); StdCall; Procedure OnSave; StdCall; Procedure OnClose; StdCall; End; //Fake interfaces IDataObject = Interface (IUnknown) ['{0000010e-0000-0000-C000-000000000046}'] Function GetData(Const formatetcIn : FORMATETC;Out medium : STGMEDIUM):HRESULT; STDCALL; Function GetDataHere(CONST pformatetc : FormatETC; Out medium : STGMEDIUM):HRESULT; STDCALL; Function QueryGetData(const pformatetc : FORMATETC):HRESULT; STDCALL; Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; STDCALl; Function SetData (Const pformatetc : FORMATETC;const medium:STGMEDIUM;FRelease : BOOL):HRESULT; StdCall; Function EnumFormatEtc(dwDirection : DWord; OUT enumformatetcpara : IENUMFORMATETC):HRESULT; StdCall; Function DAdvise(const formatetc : FORMATETC;advf :DWORD; CONST AdvSink : IAdviseSink;OUT dwConnection:DWORD):HRESULT;StdCall; Function DUnadvise(dwconnection :DWord) :HRESULT;StdCall; Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;StdCall; End; IDropTarget = interface(IUnknown) ['{00000122-0000-0000-C000-000000000046}'] function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; function DragLeave: HResult;StdCall; function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD):HResult;StdCall; end; IDropSource = interface(IUnknown) ['{00000121-0000-0000-C000-000000000046}'] function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: LongWord):HResult;StdCall; function GiveFeedback(dwEffect: LongWord): HResult;StdCall; end; IDataAdviseHolder = Interface (IUnknown) ['{00000110-0000-0000-C000-000000000046}'] Function Advise (CONST pdataObject : IDataObject;CONST fetc:FORMATETC;advf : DWORD;Const pAdvise:IAdviseSink;Out DwConnection:DWord):HResult; StdCall; Function Unadvise (dwConnection:Dword):HResult; StdCall; Function EnumAdvise(out penumAdvise : IEnumStatData):HResult;StdCall; Function SendOnDataChange(const pDataObject :IDataObject;DwReserved,advf : DWord):HResult; StdCall; End; // OLE drag'n drop support TFormatEtcArray = array of TFormatEtc; TFormatArray = array of Word; // IDataObject.SetData support TInternalStgMedium = packed record Format: TClipFormat; Medium: TStgMedium; end; TInternalStgMediumArray = array of TInternalStgMedium; TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc) private FTree: TObject; FFormatEtcArray: TFormatEtcArray; FCurrentIndex: Integer; public constructor Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray); function Clone(out Enum: IEnumFormatEtc): HResult; stdcall; function Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; stdcall; function Reset: HResult; stdcall; function Skip(celt: LongWord): HResult; stdcall; end; IDropTargetHelper = interface(IUnknown) [SID_IDropTargetHelper] function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function DragLeave: HRESULT; stdcall; function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Show(fShow: Boolean): HRESULT; stdcall; end; PSHDragImage = ^TSHDragImage; TSHDragImage = packed record sizeDragImage: TSize; ptOffset: TPoint; hbmpDragImage: HBITMAP; ColorRef: TColorRef; end; IDragSourceHelper = interface(IUnknown) [SID_IDragSourceHelper] function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall; function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall; end; IVTDragManager = interface(IUnknown) ['{C4B25559-14DA-446B-8901-0C879000EB16}'] procedure ForceDragLeave; stdcall; function GetDataObject: IDataObject; stdcall; function GetDragSource: TObject; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; property DataObject: IDataObject read GetDataObject; property DragSource: TObject read GetDragSource; property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported; property IsDropTarget: Boolean read GetIsDropTarget; end; // This data object is used in two different places. One is for clipboard operations and the other while dragging. TVTDataObject = class(TInterfacedObject, IDataObject) private //FOwner: TBaseVirtualTree; // The tree which provides clipboard or drag data. FOwner: TObject; // The tree which provides clipboard or drag data. FForClipboard: Boolean; // Determines which data to render with GetData. FFormatEtcArray: TFormatEtcArray; FInternalStgMediumArray: TInternalStgMediumArray; // The available formats in the DataObject FAdviseHolder: IDataAdviseHolder; // Reference to an OLE supplied implementation for advising. protected function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; function FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; function FindInternalStgMedium(Format: TClipFormat): PStgMedium; function HGlobalClone(HGlobal: THandle): THandle; function RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; property ForClipboard: Boolean read FForClipboard; property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray; property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray; property Owner: TObject read FOwner; public constructor Create(AOwner: TObject; ForClipboard: Boolean); virtual; destructor Destroy; override; function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; virtual; stdcall; function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall; Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;virtual;StdCall; function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall; Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; virtual; STDCALl; function GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall; function SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall; end; // TVTDragManager is a class to manage drag and drop in a Virtual Treeview. TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget) private FOwner, // The tree which is responsible for drag management. FDragSource: TObject; // Reference to the source tree if the source was a VT, might be different than // the owner tree. FIsDropTarget: Boolean; // True if the owner is currently the drop target. FDataObject: IDataObject; // A reference to the data object passed in by DragEnter (only used when the owner // tree is the current drop target). FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support FFullDragging: BOOL; // True, if full dragging is currently enabled in the system. function GetDataObject: IDataObject; stdcall; function GetDragSource: TObject; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; public constructor Create(AOwner: TObject); virtual; destructor Destroy; override; function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function DragLeave: HResult; stdcall; function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; procedure ForceDragLeave; stdcall; function GiveFeedback(Effect: LongWord): HResult; stdcall; function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall; end; //Ole helper functions function Succeeded(Status : HRESULT) : BOOLEAN; function Failed(Status : HRESULT) : BOOLEAN; //ActiveX functions that have wrong calling convention in fpc function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall; function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall; function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI; function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall; procedure OleUninitialize;stdcall; procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall; function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall; function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall; function OleFlushClipboard:WINOLEAPI;stdcall; function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall; function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall; function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall; //helper functions to isolate windows/OLE specific code function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; function GetStreamFromMedium(Medium:TStgMedium):TStream; procedure UnlockMediumData(Medium:TStgMedium); function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject; function AllocateGlobal(Data: Pointer; DataSize:Cardinal): HGLOBAL; implementation uses VirtualTrees, Controls {$ifdef DEBUG_VTV}, vtlogger {$endif}; type TVirtualTreeAccess = class (TBaseVirtualTree) end; function Succeeded(Status : HRESULT) : BOOLEAN; begin Succeeded:=Status and HRESULT($80000000)=0; end; function Failed(Status : HRESULT) : BOOLEAN; begin Failed:=Status and HRESULT($80000000)<>0; end; function RegisterDragDrop(hwnd: HWND; pDropTarget: IDropTarget): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function RevokeDragDrop(hwnd: HWND): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource; dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleInitialize(pvReserved: LPVOID): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; procedure OleUninitialize; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; procedure ReleaseStgMedium(_para1: LPSTGMEDIUM); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleSetClipboard(pDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleGetClipboard(out ppDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleFlushClipboard: WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleIsCurrentClipboard(pDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function CreateStreamOnHGlobal(hGlobal: HGLOBAL; fDeleteOnRelease: BOOL; out stm: IStream): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function CoCreateInstance(const _para1: TCLSID; _para2: IUnknown; _para3: DWORD; const _para4: TIID; out _para5): HRESULT; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; { //--------------- local function -------------------------------------------- procedure WriteNodes(Stream: TStream); var Selection: TNodeArray; I: Integer; begin with TVirtualTreeAccess(Tree) do begin if ForClipboard then Selection := GetSortedCutCopySet(True) else Selection := GetSortedSelection(True); for I := 0 to High(Selection) do WriteNode(Stream, Selection[I]); end; end; //--------------- end local function ---------------------------------------- } var Data: PCardinal; ResPointer: Pointer; ResSize: Integer; OLEStream: IStream; VCLStream: TStream; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { VCLStream := nil; try Medium.PunkForRelease := nil; // Return data in one of the supported storage formats, prefer IStream. if FormatEtcIn.tymed and TYMED_ISTREAM <> 0 then begin // Create an IStream on a memory handle (here it is 0 which indicates to implicitely allocated a handle). // Do not use TStreamAdapter as it is not compatible with OLE (when flushing the clipboard OLE wants the HGlobal // back which is not supported by TStreamAdapater). CreateStreamOnHGlobal(0, True, OLEStream); VCLStream := TOLEStream.Create(OLEStream); WriteNodes(VCLStream); // Rewind stream. VCLStream.Position := 0; Medium.tymed := TYMED_ISTREAM; IUnknown(Medium.Pstm) := OLEStream; Result := S_OK; end else begin VCLStream := TMemoryStream.Create; WriteNodes(VCLStream); ResPointer := TMemoryStream(VCLStream).Memory; ResSize := VCLStream.Position; // Allocate memory to hold the string. if ResSize > 0 then begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, ResSize + SizeOf(Cardinal)); Data := GlobalLock(Medium.hGlobal); // Store the size of the data too, for easy retrival. Data^ := ResSize; Inc(Data); Move(ResPointer^, Data^, ResSize); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Result := S_OK; end else Result := E_FAIL; end; finally // We can free the VCL stream here since it was either a pure memory stream or only a wrapper around // the OLEStream which exists independently. VCLStream.Free; end; } end; type // needed to handle OLE global memory objects TOLEMemoryStream = class(TCustomMemoryStream) public function Write(const Buffer; Count: Integer): Longint; override; end; //---------------------------------------------------------------------------------------------------------------------- function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} // raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError)); end; function GetStreamFromMedium(Medium: TStgMedium): TStream; var Data: Pointer; I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; if Medium.tymed = TYMED_ISTREAM then Result := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream) else begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin // Get the total size of data to retrieve. I := PCardinal(Data)^; Inc(PCardinal(Data)); Result := TOLEMemoryStream.Create; TOLEMemoryStream(Result).SetPointer(Data, I); end; end; } end; procedure UnlockMediumData(Medium: TStgMedium); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Medium.tymed = TYMED_HGLOBAL then GlobalUnlock(Medium.hGlobal); } end; function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject; var Medium: TStgMedium; Data: PVTReference; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; if Assigned(DataObject) then begin Format.cfFormat := CF_VTREFERENCE; if DataObject.GetData(Format, Medium) = S_OK then begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin if Data.Process = GetCurrentProcessID then Result := Data.Tree; GlobalUnlock(Medium.hGlobal); end; ReleaseStgMedium(@Medium); end; end; } end; function AllocateGlobal(Data: Pointer; DataSize: Cardinal): HGLOBAL; var P:Pointer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize); P := GlobalLock(Result); Move(Data^, P^, DataSize); GlobalUnlock(Result); } end; //---------------------------------------------------------------------------------------------------------------------- // OLE drag and drop support classes // This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs // of DD'ing various kinds of virtual data and works also between applications. //----------------- TEnumFormatEtc ------------------------------------------------------------------------------------- constructor TEnumFormatEtc.Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray); var I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FTree := Tree; // Make a local copy of the format data. SetLength(FFormatEtcArray, Length(AFormatEtcArray)); for I := 0 to High(AFormatEtcArray) do FFormatEtcArray[I] := AFormatEtcArray[I]; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult; var AClone: TEnumFormatEtc; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; try AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray); AClone.FCurrentIndex := FCurrentIndex; Enum := AClone as IEnumFormatEtc; except Result := E_FAIL; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; var CopyCount: LongWord; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_FALSE; CopyCount := Length(FFormatEtcArray) - FCurrentIndex; if celt < CopyCount then CopyCount := celt; if CopyCount > 0 then begin Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc)); Inc(FCurrentIndex, CopyCount); Result := S_OK; end; //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with // a C Program call with a NULL in pCeltFetcjed?? //Answer: Yes. Is necessary a check here if @pceltFetched <> nil then pceltFetched := CopyCount; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Reset: HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { FCurrentIndex := 0; Result := S_OK; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Skip(celt: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FCurrentIndex + celt < High(FFormatEtcArray) then begin Inc(FCurrentIndex, celt); Result := S_Ok; end else Result := S_FALSE; } end; //----------------- TVTDataObject -------------------------------------------------------------------------------------- constructor TVTDataObject.Create(AOwner: TObject; ForClipboard: Boolean); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FOwner := AOwner; FForClipboard := ForClipboard; TVirtualTreeAccess(FOwner).GetNativeClipboardFormats(FFormatEtcArray); } end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDataObject.Destroy; var I: Integer; StgMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // Cancel a pending clipboard operation if this data object was created for the clipboard and // is freed because something else is placed there. if FForClipboard and not (tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates) then TVirtualTreeAccess(FOwner).CancelCutOrCopy; // Release any internal clipboard formats for I := 0 to High(FormatEtcArray) do begin StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat); if Assigned(StgMedium) then ReleaseStgMedium(StgMedium); end; FormatEtcArray := nil; inherited; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; // Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown // interface, will always return the same pointer. begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(TestUnknown) then begin if TestUnknown.QueryInterface(IUnknown, Result) = 0 then Result._Release // Don't actually need it just need the pointer value else Result := TestUnknown end else Result := TestUnknown } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and (FormatEtc1.tymed and FormatEtc2.tymed <> 0); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; var I: integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := -1; for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then begin Result := I; Break; end end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium; var I: integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; for I := 0 to High(InternalStgMediumArray) do begin if Format = InternalStgMediumArray[I].Format then begin Result := @InternalStgMediumArray[I].Medium; Break; end end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle; // Returns a global memory block that is a copy of the passed memory block. var Size: Cardinal; Data, NewData: PChar; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Size := GlobalSize(HGlobal); Result := GlobalAlloc(GPTR, Size); Data := GlobalLock(hGlobal); try NewData := GlobalLock(Result); try Move(Data^, NewData^, Size); finally GlobalUnLock(Result); end finally GlobalUnLock(hGlobal); end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; // Tries to render one of the formats which have been stored via the SetData method. // Since this data is already there it is just copied or its reference count is increased (depending on storage medium). var InternalMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := True; InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat); if Assigned(InternalMedium) then OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject) else Result := False; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; // InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or // increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually // the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData. // If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during // that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make // copy of the data for the caller only to have them destroy it then need us to copy it again if necessary. // This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData. // This way when the caller frees the structure it sees the unkForRelease is not nil and calls Release on the object // instead of destroying the actual data. var Len: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; // Simply copy all fields to start with. OutStgMedium := InStgMedium; // The data handled here always results from a call of SetData we got. This ensures only one storage format // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several // storage formats). case InStgMedium.tymed of TYMED_HGLOBAL: begin if CopyInMedium then begin // Generate a unique copy of the data passed OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal); if OutStgMedium.hGlobal = 0 then Result := E_OUTOFMEMORY end else // Don't generate a copy just use ourselves and the copy previously saved. OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount. end; TYMED_FILE: begin //todo_lcl_check Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character. OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len); Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len); end; TYMED_ISTREAM: IUnknown(OutStgMedium.Pstm)._AddRef; TYMED_ISTORAGE: IUnknown(OutStgMedium.Pstg)._AddRef; TYMED_GDI: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy GDI objects right now. TYMED_MFPICT: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now. TYMED_ENHMF: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now. else Result := DV_E_TYMED; end; if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then IUnknown(OutStgMedium.PunkForRelease)._AddRef; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; // Advise sink management is greatly simplified by the IDataAdviseHolder interface. // We use this interface and forward all concerning calls to it. begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; if FAdviseHolder = nil then Result := CreateDataAdviseHolder(FAdviseHolder); if Result = S_OK then Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DUnadvise(dwConnection: DWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FAdviseHolder = nil then Result := E_NOTIMPL else Result := FAdviseHolder.Unadvise(dwConnection); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumDAvise(Out enumAdvise : IEnumStatData):HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FAdviseHolder = nil then Result := OLE_E_ADVISENOTSUPPORTED else Result := FAdviseHolder.EnumAdvise(enumAdvise); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; var NewList: TEnumFormatEtc; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := E_FAIL; if Direction = DATADIR_GET then begin NewList := TEnumFormatEtc.Create(TVirtualTreeAccess(FOwner), FormatEtcArray); EnumFormatEtc := NewList as IEnumFormatEtc; Result := S_OK; end else EnumFormatEtc := nil; if EnumFormatEtc = nil then Result := OLE_S_USEREG; } end; //---------------------------------------------------------------------------------------------------------------------- Function TVTDataObject.GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := DATA_S_SAMEFORMATETC; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; // Data is requested by clipboard or drop target. This method dispatchs the call // depending on the data being requested. var I: Integer; Data: PVTReference; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} // The tree reference format is always supported and returned from here. { if FormatEtcIn.cfFormat = CF_VTREFERENCE then begin // Note: this format is not used while flushing the clipboard to avoid a dangling reference // when the owner tree is destroyed before the clipboard data is replaced with something else. if tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates then Result := E_FAIL else begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference)); Data := GlobalLock(Medium.hGlobal); Data.Process := GetCurrentProcessID; Data.Tree := TBaseVirtualTree(FOwner); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Medium.PunkForRelease := nil; Result := S_OK; end; end else begin try // See if we accept this type and if not get the correct return value. Result := QueryGetData(FormatEtcIn); if Result = S_OK then begin for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then begin if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then Result := TVirtualTreeAccess(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard); Break; end; end end except FillChar(Medium, SizeOf(Medium), #0); Result := E_FAIL; end; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult; var I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := DV_E_CLIPFORMAT; for I := 0 to High(FFormatEtcArray) do begin if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then begin if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then begin if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then begin if FormatEtc.lindex = FFormatEtcArray[I].lindex then begin Result := S_OK; Break; end else Result := DV_E_LINDEX; end else Result := DV_E_DVASPECT; end else Result := DV_E_TYMED; end; end } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; // Allows dynamic adding to the IDataObject during its existance. Most noteably it is used to implement // IDropSourceHelper and allows to set a special format for optimized moves during a shell transfer. var Index: Integer; LocalStgMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // See if we already have a format of that type available. Index := FindFormatEtc(FormatEtc, FormatEtcArray); if Index > - 1 then begin // Just use the TFormatEct in the array after releasing the data. LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat); if Assigned(LocalStgMedium) then begin ReleaseStgMedium(LocalStgMedium); FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; end else begin // It is a new format so create a new TFormatCollectionItem, copy the // FormatEtc parameter into the new object and and put it in the list. SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1); FormatEtcArray[High(FormatEtcArray)] := FormatEtc; // Create a new InternalStgMedium and initialize it and associate it with the format. SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1); InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat; LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium; FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; if DoRelease then begin // We are simply being given the data and we take control of it. LocalStgMedium^ := Medium; Result := S_OK end else begin // We need to reference count or copy the data and keep our own references to it. Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject); // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium. // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN. if Assigned(LocalStgMedium.PunkForRelease) then begin if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface end; end; // Tell all registered advice sinks about the data change. if Assigned(FAdviseHolder) then FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0); } end; //----------------- TVTDragManager ------------------------------------------------------------------------------------- constructor TVTDragManager.Create(AOwner: TObject); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FOwner := AOwner; // Create an instance of the drop target helper interface. This will fail but not harm on systems which do // not support this interface (everything below Windows 2000); CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper); } end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDragManager.Destroy; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // Set the owner's reference to us to nil otherwise it will access an invalid pointer // after our desctruction is complete. TVirtualTreeAccess(FOwner).FreeDragManager; inherited; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDataObject: IDataObject; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem. // In this case there is no local reference to a data object and one is created (but not stored). // If there is a local reference then the owner tree is currently the drop target and the stored interface is // that of the drag initiator. if Assigned(FDataObject) then Result := FDataObject else begin Result := TVirtualTreeAccess(FOwner).DoCreateDataObject; if Result = nil then Result := TVTDataObject.Create(FOwner, False) as IDataObject; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDragSource: TObject; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := FDragSource; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDropTargetHelperSupported: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := Assigned(FDropTargetHelper); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetIsDropTarget: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := FIsDropTarget; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { FDataObject := DataObject; FIsDropTarget := True; SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0); // If full dragging of window contents is disabled in the system then our tree windows will be locked // and cannot be updated during a drag operation. With the following call painting is again enabled. if not FFullDragging then LockWindowUpdate(0); if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragEnter(TBaseVirtualTree(FOwner).Handle, DataObject, Pt, Effect); FDragSource := TVirtualTreeAccess(FOwner).GetTreeFromDataObject(DataObject); Result := TVirtualTreeAccess(FOwner).DragEnter(KeyState, Pt, Effect); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragLeave: HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; TVirtualTreeAccess(FOwner).DragLeave; FIsDropTarget := False; FDragSource := nil; FDataObject := nil; Result := NOERROR; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragOver(Pt, Effect); Result := TVirtualTreeAccess(FOwner).DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.Drop(DataObject, Pt, Effect); Result := TVirtualTreeAccess(FOwner).DragDrop(DataObject, KeyState, Pt, Effect); FIsDropTarget := False; FDataObject := nil; } end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragManager.ForceDragLeave; // Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive // a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from // screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE). begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GiveFeedback(Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := DRAGDROP_S_USEDEFAULTCURSORS; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; var RButton, LButton: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { LButton := (KeyState and MK_LBUTTON) <> 0; RButton := (KeyState and MK_RBUTTON) <> 0; // Drag'n drop canceled by pressing both mouse buttons or Esc? if (LButton and RButton) or EscapePressed then Result := DRAGDROP_S_CANCEL else // Drag'n drop finished? if not (LButton or RButton) then Result := DRAGDROP_S_DROP else Result := S_OK; } end; end. doublecmd-0.8.2/components/virtualtreeview/units/qt/fakeactivex.pas0000664000175000017500000000005412014201074024706 0ustar alexxalexxunit FakeActiveX; {$i ../dummyactivex.inc} doublecmd-0.8.2/components/virtualtreeview/units/qt/fakemmsystem.pas0000664000175000017500000000065012014201074025123 0ustar alexxalexxunit fakemmsystem; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Types; function timeBeginPeriod(x1: DWord): DWord; function timeEndPeriod(x1: DWord): DWord; function timeGetTime: DWORD; implementation uses LCLIntf; function timeBeginPeriod(x1: DWord): DWord; begin end; function timeEndPeriod(x1: DWord): DWord; begin end; function timeGetTime: DWORD; begin Result := GetTickCount; end; end. doublecmd-0.8.2/components/virtualtreeview/units/dummyactivex.inc0000664000175000017500000004056012014201074024503 0ustar alexxalexx {fake unit just to compile - not used under non windows} {$mode delphi} interface uses {$ifdef Windows} Windows, {$endif} Classes, SysUtils, Types; const TYMED_HGLOBAL = 1; TYMED_ISTREAM = 4; DVASPECT_CONTENT = 1; CLSCTX_INPROC_SERVER = $0010; DROPEFFECT_COPY = 1; DROPEFFECT_LINK = 4; DROPEFFECT_MOVE = 2; DROPEFFECT_NONE = 0; DROPEFFECT_SCROLL = dword($80000000); DATADIR_GET = 1; type //types from win unit Long = LongInt; WinBool = LongBool; Bool = WinBool; ULONG = cardinal; PULONG = ^ULONG; LONGLONG = int64; LPDWORD = ^DWORD; LPVOID = pointer; TCOLORREF = cardinal; TIID = TGUID; LARGE_INTEGER = record case byte of 0: (LowPart : DWORD; HighPart : LONG); 1: (QuadPart : LONGLONG); end; PLARGE_INTEGER = ^LARGE_INTEGER; _LARGE_INTEGER = LARGE_INTEGER; TLargeInteger = Int64; PLargeInteger = ^TLargeInteger; ULARGE_INTEGER = record case byte of 0: (LowPart : DWORD; HighPart : DWORD); 1: (QuadPart : LONGLONG); end; PULARGE_INTEGER = ^ULARGE_INTEGER; _ULARGE_INTEGER = ULARGE_INTEGER; HANDLE = System.THandle; HWND = HANDLE; //HRESULT = System.HResult; HBITMAP = HANDLE; HENHMETAFILE = HANDLE; //activex types IMoniker = Interface; WINOLEAPI = HResult; TLCID = DWORD; OleChar = WChar; LPOLESTR = ^OLECHAR; HMetaFilePict = Pointer; tagBIND_OPTS = Record cvStruct, // sizeof(BIND_OPTS) grfFlags, grfMode, dwTickCountDeadline : DWord; End; TBind_Opts = tagBIND_OPTS; TCLIPFORMAT = Word; tagDVTARGETDEVICE = Record tdSize : DWord; tdDriverNameOffset, tdDeviceNameOffset, tdPortNameOffset, tdExtDevmodeOffset : Word; Data : Record End; End; DVTARGETDEVICE = TagDVTARGETDEVICE; PDVTARGETDEVICE = ^tagDVTARGETDEVICE; tagFORMATETC = Record CfFormat : Word {TCLIPFORMAT}; Ptd : PDVTARGETDEVICE; dwAspect : DWORD; lindex : Long; tymed : DWORD; End; FORMATETC = TagFORMATETC; TFORMATETC = FORMATETC; LPFORMATETC = ^FORMATETC; PFormatEtc = LPFORMATETC; tagSTATDATA = Record // field used by: FORMATETC : Tformatetc; // EnumAdvise, EnumData (cache), EnumFormats advf : DWord; // EnumAdvise, EnumData (cache) padvSink : Pointer {IAdviseSink}; // EnumAdvise dwConnection: DWord; // EnumAdvise End; STATDATA = TagStatData; TagSTGMEDIUM = Record Tymed : DWord; Case Integer Of 0 : (HBITMAP : hBitmap; PUnkForRelease : Pointer {IUnknown}); 1 : (HMETAFILEPICT : hMetaFilePict ); 2 : (HENHMETAFILE : hEnhMetaFile ); 3 : (HGLOBAL : hGlobal ); 4 : (lpszFileName : LPOLESTR ); 5 : (pstm : Pointer{IStream} ); 6 : (pstg : Pointer{IStorage} ); End; USTGMEDIUM = TagSTGMEDIUM; STGMEDIUM = USTGMEDIUM; TStgMedium = TagSTGMEDIUM; PStgMedium = ^TStgMedium; LPSTGMEDIUM = ^STGMEDIUM; IEnumString = Interface (IUnknown) ['{00000101-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out xcelt;Out Celtfetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong; Out celt;Out Celtfetched:ULong):HResult; StdCall; Function Skip (Celt:ULong):Hresult;StdCall; Function Reset:HResult;StdCall; Function Clone(Out penum:IEnumString):HResult;StdCall; End; IEnumMoniker = Interface (IUnknown) ['{00000102-0000-0000-C000-000000000046}'] Function Next(celt:ULong; out Elt;out celftfetched: ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong; Out rgelt;out celtfetched :ULong):Hresult; StdCall; Function Skip(celt:Ulong):HResult; StdCall; Function Reset:HResult; StdCall; Function Close(out penum:IEnumMoniker):HResult;StdCall; End; IEnumSTATDATA = Interface (IUnknown) ['{00000105-0000-0000-C000-000000000046}'] Function Next (Celt:ULong;Out xcelt;pceltfetched : PUlong):HResult; StdCall; // Function RemoteNext(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall; Function Skip(Celt:ULong):HResult;StdCall; Function Reset:HResult;StdCall; Function Clone(out penum:IEnumstatdata):HResult;StdCall; End; IEnumFORMATETC = Interface (IUnknown) ['{00000103-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out Rgelt:FormatEtc;pceltFetched:pULong=nil):HResult; StdCall; // Function RemoteNext(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall; Function Skip(Celt:ULong):HResult;StdCall; Function Reset:HResult;StdCall; Function Clone(out penum:IEnumFORMATETC):HResult;StdCall; End; IPersist = Interface (IUnknown) ['{0000010c-0000-0000-C000-000000000046}'] Function GetClassId(clsid:TClsId):HResult; StdCall; End; IPersistStream = Interface(IPersist) ['{00000109-0000-0000-C000-000000000046}'] Function IsDirty:HResult; StdCall; Function Load(Const stm: IStream):HResult; StdCall; Function Save(Const stm: IStream;fClearDirty:Bool):HResult;StdCall; Function GetSizeMax(Out cbSize:ULarge_Integer):HResult; StdCall; End; IRunningObjectTable = Interface (IUnknown) ['{00000010-0000-0000-C000-000000000046}'] Function Register (grfFlags :DWord;const unkobject:IUnknown;Const mkObjectName:IMoniker;Out dwregister:DWord):HResult;StdCall; Function Revoke (dwRegister:DWord):HResult; StdCall; Function IsRunning (Const mkObjectName: IMoniker):HResult;StdCall; Function GetObject (Const mkObjectName: IMoniker; Out punkObject:IUnknown):HResult; StdCall; Function NoteChangeTime(dwRegister :DWord;Const FileTime: TFileTime):HResult;StdCall; Function GetTimeOfLastChange(Const mkObjectName:IMoniker;Out filetime:TFileTime):HResult; StdCall; Function EnumRunning (Out enumMoniker: IEnumMoniker):HResult; StdCall; End; IBindCtx = Interface (IUnknown) ['{0000000e-0000-0000-C000-000000000046}'] Function RegisterObjectBound(Const punk:IUnknown):HResult; stdCall; Function RevokeObjectBound (Const Punk:IUnknown):HResult; stdCall; Function ReleaseBoundObjects :HResult; StdCall; Function SetBindOptions(Const bindOpts:TBind_Opts):HResult; stdCall; // Function RemoteSetBindOptions(Const bind_opts: TBind_Opts2):HResult;StdCall; Function GetBindOptions(var BindOpts:TBind_Opts):HResult; stdCall; // Function RemoteGetBindOptions(Var bind_opts: TBind_Opts2):HResult;StdCall; Function GetRunningObjectTable(Out rot : IRunningObjectTable):Hresult; StdCall; Function RegisterObjectParam(Const pszkey:LPOleStr;const punk:IUnknown):HResult; Function GetObjectParam(Const pszkey:LPOleStr; out punk: IUnknown):HResult; StdCall; Function EnumObjectParam (out enum:IEnumString):Hresult;StdCall; Function RevokeObjectParam(pszKey:LPOleStr):HResult;StdCall; End; PIMoniker = ^IMoniker; IMoniker = Interface (IPersistStream) ['{0000000f-0000-0000-C000-000000000046}'] Function BindToObject (const pbc:IBindCtx;const mktoleft:IMoniker; RiidResult:TIID;Out vresult):HResult;StdCall; // Function RemoteBindToObject (const pbc:IBindCtx;const mktoleft:IMoniker;RiidResult:TIID;Out vresult):HResult;StdCall; Function BindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall; // Function RemoteBindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall; Function Reduce (const pbc:IBindCtx; dwReduceHowFar:DWord; mktoLeft: PIMoniker; Out mkReduced:IMoniker):HResult; StdCall; Function ComposeWith(Const MkRight:IMoniker;fOnlyIfNotGeneric:BOOL; OUT mkComposite:IMoniker):HResult; StdCall; Function Enum(fForward:Bool;Out enumMoniker:IEnumMoniker):HResult;StdCall; Function IsEqual(Const mkOtherMoniker:IMoniker):HResult;StdCall; Function Hash (Out dwHash:Dword):HResult;StdCall; Function IsRunning(Const bc:IBindCtx;Const MkToLeft:IMoniker;Const mknewlyRunning:IMoniker):HResult;StdCall; Function GetTimeOfLastChange(Const bc:IBindCtx;Const mkToLeft:IMoniker; out ft : FileTime):HResult; StdCall; Function Inverse(out mk : IMoniker):HResult; StdCall; Function CommonPrefixWith (Const mkOther:IMoniker):HResult; StdCall; Function RelativePathTo(Const mkother:IMoniker; Out mkRelPath : IMoniker):HResult;StdCall; Function GetDisplayName(Const bc:IMoniker;const mktoleft:IMoniker;Out szDisplayName: pOleStr):HResult; StdCall; Function ParseDisplayName(Const bc:IBindCtx;Const mkToLeft:IMoniker;szDisplayName:POleStr;out cheaten:ULong;out mkOut:IMoniker):HResult; StdCall; Function IsSystemMonitor(Out dwMkSys:DWord):HResult;StdCall; End; IAdviseSink = Interface (IUnknown) ['{0000010f-0000-0000-C000-000000000046}'] {$ifdef midl500} ['{00000150-0000-0000-C000-000000000046}'] {$endif} Procedure OnDataChange (Const pformatetc : Formatetc;const pstgmed : STGMEDIUM); StdCall; Procedure OnViewChange (dwAspect : DWord; lindex : Long); StdCall; Procedure OnRename (Const pmk : IMoniker); StdCall; Procedure OnSave; StdCall; Procedure OnClose; StdCall; End; //Fake interfaces IDataObject = Interface (IUnknown) ['{0000010e-0000-0000-C000-000000000046}'] Function GetData(Const formatetcIn : FORMATETC;Out medium : STGMEDIUM):HRESULT; STDCALL; Function GetDataHere(CONST pformatetc : FormatETC; Out medium : STGMEDIUM):HRESULT; STDCALL; Function QueryGetData(const pformatetc : FORMATETC):HRESULT; STDCALL; Function GetCanonicalFormatEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; STDCALl; Function SetData (Const pformatetc : FORMATETC;const medium:STGMEDIUM;FRelease : BOOL):HRESULT; StdCall; Function EnumFormatEtc(dwDirection : DWord; OUT enumformatetcpara : IENUMFORMATETC):HRESULT; StdCall; Function DAdvise(const formatetc : FORMATETC;advf :DWORD; CONST AdvSink : IAdviseSink;OUT dwConnection:DWORD):HRESULT;StdCall; Function DUnadvise(dwconnection :DWord) :HRESULT;StdCall; Function EnumDAdvise(Out enumAdvise : IEnumStatData):HResult;StdCall; End; IDropTarget = interface(IUnknown) ['{00000122-0000-0000-C000-000000000046}'] function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; function DragLeave: HResult;StdCall; function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD):HResult;StdCall; end; IDropSource = interface(IUnknown) ['{00000121-0000-0000-C000-000000000046}'] function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: DWORD):HResult;StdCall; function GiveFeedback(dwEffect: DWORD): HResult;StdCall; end; IDataAdviseHolder = Interface (IUnknown) ['{00000110-0000-0000-C000-000000000046}'] Function Advise (CONST pdataObject : IDataObject;CONST fetc:FORMATETC;advf : DWORD;Const pAdvise:IAdviseSink;Out DwConnection:DWord):HResult; StdCall; Function Unadvise (dwConnection:Dword):HResult; StdCall; Function EnumAdvise(out penumAdvise : IEnumStatData):HResult;StdCall; Function SendOnDataChange(const pDataObject :IDataObject;DwReserved,advf : DWord):HResult; StdCall; End; //Ole helper functions function Succeeded(Status : HRESULT) : BOOLEAN; function Failed(Status : HRESULT) : BOOLEAN; //ActiveX functions that have wrong calling convention in fpc function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall; function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall; function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI; function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall; procedure OleUninitialize;stdcall; procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall; function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall; function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall; function OleFlushClipboard:WINOLEAPI;stdcall; function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall; function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall; function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall; implementation function Succeeded(Status : HRESULT) : BOOLEAN; begin Succeeded:=Status and HRESULT($80000000)=0; end; function Failed(Status : HRESULT) : BOOLEAN; begin Failed:=Status and HRESULT($80000000)<>0; end; function RegisterDragDrop(hwnd: HWND; pDropTarget: IDropTarget): WINOLEAPI; begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; function RevokeDragDrop(hwnd: HWND): WINOLEAPI; begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource; dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI; begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; function OleInitialize(pvReserved: LPVOID): WINOLEAPI; begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; procedure OleUninitialize; begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; procedure ReleaseStgMedium(_para1: LPSTGMEDIUM); begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; function OleSetClipboard(pDataObj: IDataObject): WINOLEAPI; begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; function OleGetClipboard(out ppDataObj: IDataObject): WINOLEAPI; begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; function OleFlushClipboard: WINOLEAPI; begin // Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; function OleIsCurrentClipboard(pDataObj: IDataObject): WINOLEAPI; begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; function CreateStreamOnHGlobal(hGlobal: HGLOBAL; fDeleteOnRelease: BOOL; out stm: IStream): WINOLEAPI; begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; function CoCreateInstance(const _para1: TCLSID; _para2: IUnknown; _para3: DWORD; const _para4: TIID; out _para5): HRESULT; begin //Logger.SendError([lcOle],'Ole function called in Linux'); //Logger.SendCallStack([lcOle],'Stack'); end; end. doublecmd-0.8.2/components/virtualtreeview/units/gtk2/0000775000175000017500000000000013244011205022134 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/units/gtk2/virtualpanningwindow.pas0000664000175000017500000000201212014201074027124 0ustar alexxalexxunit virtualpanningwindow; {$mode objfpc}{$H+} interface uses LCLType, Graphics, Classes, SysUtils; type { TVirtualPanningWindow } TVirtualPanningWindow = class private FHandle: THandle; FOwnerHandle: THandle; FImage: TBitmap; procedure HandlePaintMessage; public procedure Start(OwnerHandle: THandle; const Position: TPoint); procedure Stop; procedure Show(ClipRegion: HRGN); property Image: TBitmap read FImage; property Handle: THandle read FHandle; end; implementation {$ifdef DEBUG_VTV} uses vtlogger; {$endif} { TVirtualPanningWindow } procedure TVirtualPanningWindow.HandlePaintMessage; begin end; procedure TVirtualPanningWindow.Start(OwnerHandle: THandle; const Position: TPoint); begin FImage := TBitmap.Create; end; procedure TVirtualPanningWindow.Stop; begin FImage.Free; FImage := nil; end; procedure TVirtualPanningWindow.Show(ClipRegion: HRGN); begin {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPanning],'Panning Image',FImage);{$endif} end; end. doublecmd-0.8.2/components/virtualtreeview/units/gtk2/virtualdragmanager.pas0000664000175000017500000017010612014201074026524 0ustar alexxalexxunit virtualdragmanager; {fake unit just to compile - not used under non windows} {$mode delphi} interface uses Classes, SysUtils, Types; const // Drag image helpers for Windows 2000 and up. IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0)); IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46)); CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}'; SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}'; SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}'; //Bridge to ActiveX constants TYMED_HGLOBAL = 1; TYMED_ISTREAM = 4; DVASPECT_CONTENT = 1; CLSCTX_INPROC_SERVER = $0010; DROPEFFECT_COPY = 1; DROPEFFECT_LINK = 4; DROPEFFECT_MOVE = 2; DROPEFFECT_NONE = 0; DROPEFFECT_SCROLL = dword($80000000); DATADIR_GET = 1; type //types from win unit Long = LongInt; WinBool= LongBool; Bool= WinBool; ULONG = cardinal; LONGLONG = int64; LPDWORD = ^DWORD; LPVOID = pointer; TCOLORREF = cardinal; TIID = TGUID; LARGE_INTEGER = record case byte of 0: (LowPart : DWORD; HighPart : LONG); 1: (QuadPart : LONGLONG); end; PLARGE_INTEGER = ^LARGE_INTEGER; _LARGE_INTEGER = LARGE_INTEGER; TLargeInteger = Int64; PLargeInteger = ^TLargeInteger; ULARGE_INTEGER = record case byte of 0: (LowPart : DWORD; HighPart : DWORD); 1: (QuadPart : LONGLONG); end; PULARGE_INTEGER = ^ULARGE_INTEGER; _ULARGE_INTEGER = ULARGE_INTEGER; HANDLE = System.THandle; HWND = HANDLE; //HRESULT = System.HResult; HBITMAP = HANDLE; HENHMETAFILE = HANDLE; //activex types IMoniker = Interface; WINOLEAPI = HResult; TLCID = DWORD; OleChar = WChar; LPOLESTR = ^OLECHAR; HMetaFilePict = Pointer; tagBIND_OPTS = Record cvStruct, // sizeof(BIND_OPTS) grfFlags, grfMode, dwTickCountDeadline : DWord; End; TBind_Opts = tagBIND_OPTS; TCLIPFORMAT = Word; tagDVTARGETDEVICE = Record tdSize : DWord; tdDriverNameOffset, tdDeviceNameOffset, tdPortNameOffset, tdExtDevmodeOffset : Word; Data : Record End; End; DVTARGETDEVICE = TagDVTARGETDEVICE; PDVTARGETDEVICE = ^tagDVTARGETDEVICE; tagFORMATETC = Record CfFormat : Word {TCLIPFORMAT}; Ptd : PDVTARGETDEVICE; dwAspect : DWORD; lindex : Long; tymed : DWORD; End; FORMATETC = TagFORMATETC; TFORMATETC = FORMATETC; LPFORMATETC = ^FORMATETC; PFormatEtc = LPFORMATETC; tagSTATDATA = Record // field used by: FORMATETC : Tformatetc; // EnumAdvise, EnumData (cache), EnumFormats advf : DWord; // EnumAdvise, EnumData (cache) padvSink : Pointer {IAdviseSink}; // EnumAdvise dwConnection: DWord; // EnumAdvise End; STATDATA = TagStatData; TagSTGMEDIUM = Record Tymed : DWord; Case Integer Of 0 : (HBITMAP : hBitmap; PUnkForRelease : Pointer {IUnknown}); 1 : (HMETAFILEPICT : hMetaFilePict ); 2 : (HENHMETAFILE : hEnhMetaFile ); 3 : (HGLOBAL : hGlobal ); 4 : (lpszFileName : LPOLESTR ); 5 : (pstm : Pointer{IStream} ); 6 : (pstg : Pointer{IStorage} ); End; USTGMEDIUM = TagSTGMEDIUM; STGMEDIUM = USTGMEDIUM; TStgMedium = TagSTGMEDIUM; PStgMedium = ^TStgMedium; LPSTGMEDIUM = ^STGMEDIUM; IEnumString = Interface (IUnknown) ['{00000101-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out xcelt;Out Celtfetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong; Out celt;Out Celtfetched:ULong):HResult; StdCall; Function Skip (Celt:ULong):Hresult;StdCall; Function Reset:HResult;StdCall; Function Clone(Out penum:IEnumString):HResult;StdCall; End; IEnumMoniker = Interface (IUnknown) ['{00000102-0000-0000-C000-000000000046}'] Function Next(celt:ULong; out Elt;out celftfetched: ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong; Out rgelt;out celtfetched :ULong):Hresult; StdCall; Function Skip(celt:Ulong):HResult; StdCall; Function Reset:HResult; StdCall; Function Close(out penum:IEnumMoniker):HResult;StdCall; End; IEnumSTATDATA = Interface (IUnknown) ['{00000105-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall; Function Skip(Celt:ULong):HResult;StdCall; Function Reset:HResult;StdCall; Function Clone(out penum:IEnumstatdata):HResult;StdCall; End; IEnumFORMATETC = Interface (IUnknown) ['{00000103-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall; Function Skip(Celt:ULong):HResult;StdCall; Function Reset:HResult;StdCall; Function Clone(out penum:IEnumFORMATETC):HResult;StdCall; End; IPersist = Interface (IUnknown) ['{0000010c-0000-0000-C000-000000000046}'] Function GetClassId(clsid:TClsId):HResult; StdCall; End; IPersistStream = Interface(IPersist) ['{00000109-0000-0000-C000-000000000046}'] Function IsDirty:HResult; StdCall; Function Load(Const stm: IStream):HResult; StdCall; Function Save(Const stm: IStream;fClearDirty:Bool):HResult;StdCall; Function GetSizeMax(Out cbSize:ULarge_Integer):HResult; StdCall; End; IRunningObjectTable = Interface (IUnknown) ['{00000010-0000-0000-C000-000000000046}'] Function Register (grfFlags :DWord;const unkobject:IUnknown;Const mkObjectName:IMoniker;Out dwregister:DWord):HResult;StdCall; Function Revoke (dwRegister:DWord):HResult; StdCall; Function IsRunning (Const mkObjectName: IMoniker):HResult;StdCall; Function GetObject (Const mkObjectName: IMoniker; Out punkObject:IUnknown):HResult; StdCall; Function NoteChangeTime(dwRegister :DWord;Const FileTime: TFileTime):HResult;StdCall; Function GetTimeOfLastChange(Const mkObjectName:IMoniker;Out filetime:TFileTime):HResult; StdCall; Function EnumRunning (Out enumMoniker: IEnumMoniker):HResult; StdCall; End; IBindCtx = Interface (IUnknown) ['{0000000e-0000-0000-C000-000000000046}'] Function RegisterObjectBound(Const punk:IUnknown):HResult; stdCall; Function RevokeObjectBound (Const Punk:IUnknown):HResult; stdCall; Function ReleaseBoundObjects :HResult; StdCall; Function SetBindOptions(Const bindOpts:TBind_Opts):HResult; stdCall; // Function RemoteSetBindOptions(Const bind_opts: TBind_Opts2):HResult;StdCall; Function GetBindOptions(var BindOpts:TBind_Opts):HResult; stdCall; // Function RemoteGetBindOptions(Var bind_opts: TBind_Opts2):HResult;StdCall; Function GetRunningObjectTable(Out rot : IRunningObjectTable):Hresult; StdCall; Function RegisterObjectParam(Const pszkey:LPOleStr;const punk:IUnknown):HResult; Function GetObjectParam(Const pszkey:LPOleStr; out punk: IUnknown):HResult; StdCall; Function EnumObjectParam (out enum:IEnumString):Hresult;StdCall; Function RevokeObjectParam(pszKey:LPOleStr):HResult;StdCall; End; PIMoniker = ^IMoniker; IMoniker = Interface (IPersistStream) ['{0000000f-0000-0000-C000-000000000046}'] Function BindToObject (const pbc:IBindCtx;const mktoleft:IMoniker; RiidResult:TIID;Out vresult):HResult;StdCall; // Function RemoteBindToObject (const pbc:IBindCtx;const mktoleft:IMoniker;RiidResult:TIID;Out vresult):HResult;StdCall; Function BindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall; // Function RemoteBindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall; Function Reduce (const pbc:IBindCtx; dwReduceHowFar:DWord; mktoLeft: PIMoniker; Out mkReduced:IMoniker):HResult; StdCall; Function ComposeWith(Const MkRight:IMoniker;fOnlyIfNotGeneric:BOOL; OUT mkComposite:IMoniker):HResult; StdCall; Function Enum(fForward:Bool;Out enumMoniker:IEnumMoniker):HResult;StdCall; Function IsEqual(Const mkOtherMoniker:IMoniker):HResult;StdCall; Function Hash (Out dwHash:Dword):HResult;StdCall; Function IsRunning(Const bc:IBindCtx;Const MkToLeft:IMoniker;Const mknewlyRunning:IMoniker):HResult;StdCall; Function GetTimeOfLastChange(Const bc:IBindCtx;Const mkToLeft:IMoniker; out ft : FileTime):HResult; StdCall; Function Inverse(out mk : IMoniker):HResult; StdCall; Function CommonPrefixWith (Const mkOther:IMoniker):HResult; StdCall; Function RelativePathTo(Const mkother:IMoniker; Out mkRelPath : IMoniker):HResult;StdCall; Function GetDisplayName(Const bc:IMoniker;const mktoleft:IMoniker;Out szDisplayName: pOleStr):HResult; StdCall; Function ParseDisplayName(Const bc:IBindCtx;Const mkToLeft:IMoniker;szDisplayName:POleStr;out cheaten:ULong;out mkOut:IMoniker):HResult; StdCall; Function IsSystemMonitor(Out dwMkSys:DWord):HResult;StdCall; End; IAdviseSink = Interface (IUnknown) ['{0000010f-0000-0000-C000-000000000046}'] {$ifdef midl500} ['{00000150-0000-0000-C000-000000000046}'] {$endif} Procedure OnDataChange (Const pformatetc : Formatetc;const pstgmed : STGMEDIUM); StdCall; Procedure OnViewChange (dwAspect : DWord; lindex : Long); StdCall; Procedure OnRename (Const pmk : IMoniker); StdCall; Procedure OnSave; StdCall; Procedure OnClose; StdCall; End; //Fake interfaces IDataObject = Interface (IUnknown) ['{0000010e-0000-0000-C000-000000000046}'] Function GetData(Const formatetcIn : FORMATETC;Out medium : STGMEDIUM):HRESULT; STDCALL; Function GetDataHere(CONST pformatetc : FormatETC; Out medium : STGMEDIUM):HRESULT; STDCALL; Function QueryGetData(const pformatetc : FORMATETC):HRESULT; STDCALL; Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; STDCALl; Function SetData (Const pformatetc : FORMATETC;const medium:STGMEDIUM;FRelease : BOOL):HRESULT; StdCall; Function EnumFormatEtc(dwDirection : DWord; OUT enumformatetcpara : IENUMFORMATETC):HRESULT; StdCall; Function DAdvise(const formatetc : FORMATETC;advf :DWORD; CONST AdvSink : IAdviseSink;OUT dwConnection:DWORD):HRESULT;StdCall; Function DUnadvise(dwconnection :DWord) :HRESULT;StdCall; Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;StdCall; End; IDropTarget = interface(IUnknown) ['{00000122-0000-0000-C000-000000000046}'] function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; function DragLeave: HResult;StdCall; function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD):HResult;StdCall; end; IDropSource = interface(IUnknown) ['{00000121-0000-0000-C000-000000000046}'] function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: LongWord):HResult;StdCall; function GiveFeedback(dwEffect: LongWord): HResult;StdCall; end; IDataAdviseHolder = Interface (IUnknown) ['{00000110-0000-0000-C000-000000000046}'] Function Advise (CONST pdataObject : IDataObject;CONST fetc:FORMATETC;advf : DWORD;Const pAdvise:IAdviseSink;Out DwConnection:DWord):HResult; StdCall; Function Unadvise (dwConnection:Dword):HResult; StdCall; Function EnumAdvise(out penumAdvise : IEnumStatData):HResult;StdCall; Function SendOnDataChange(const pDataObject :IDataObject;DwReserved,advf : DWord):HResult; StdCall; End; // OLE drag'n drop support TFormatEtcArray = array of TFormatEtc; TFormatArray = array of Word; // IDataObject.SetData support TInternalStgMedium = packed record Format: TClipFormat; Medium: TStgMedium; end; TInternalStgMediumArray = array of TInternalStgMedium; TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc) private FTree: TObject; FFormatEtcArray: TFormatEtcArray; FCurrentIndex: Integer; public constructor Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray); function Clone(out Enum: IEnumFormatEtc): HResult; stdcall; function Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; stdcall; function Reset: HResult; stdcall; function Skip(celt: LongWord): HResult; stdcall; end; IDropTargetHelper = interface(IUnknown) [SID_IDropTargetHelper] function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function DragLeave: HRESULT; stdcall; function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Show(fShow: Boolean): HRESULT; stdcall; end; PSHDragImage = ^TSHDragImage; TSHDragImage = packed record sizeDragImage: TSize; ptOffset: TPoint; hbmpDragImage: HBITMAP; ColorRef: TColorRef; end; IDragSourceHelper = interface(IUnknown) [SID_IDragSourceHelper] function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall; function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall; end; IVTDragManager = interface(IUnknown) ['{C4B25559-14DA-446B-8901-0C879000EB16}'] procedure ForceDragLeave; stdcall; function GetDataObject: IDataObject; stdcall; function GetDragSource: TObject; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; property DataObject: IDataObject read GetDataObject; property DragSource: TObject read GetDragSource; property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported; property IsDropTarget: Boolean read GetIsDropTarget; end; // This data object is used in two different places. One is for clipboard operations and the other while dragging. TVTDataObject = class(TInterfacedObject, IDataObject) private //FOwner: TBaseVirtualTree; // The tree which provides clipboard or drag data. FOwner: TObject; // The tree which provides clipboard or drag data. FForClipboard: Boolean; // Determines which data to render with GetData. FFormatEtcArray: TFormatEtcArray; FInternalStgMediumArray: TInternalStgMediumArray; // The available formats in the DataObject FAdviseHolder: IDataAdviseHolder; // Reference to an OLE supplied implementation for advising. protected function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; function FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; function FindInternalStgMedium(Format: TClipFormat): PStgMedium; function HGlobalClone(HGlobal: THandle): THandle; function RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; property ForClipboard: Boolean read FForClipboard; property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray; property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray; property Owner: TObject read FOwner; public constructor Create(AOwner: TObject; ForClipboard: Boolean); virtual; destructor Destroy; override; function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; virtual; stdcall; function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall; Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;virtual;StdCall; function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall; Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; virtual; STDCALl; function GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall; function SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall; end; // TVTDragManager is a class to manage drag and drop in a Virtual Treeview. TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget) private FOwner, // The tree which is responsible for drag management. FDragSource: TObject; // Reference to the source tree if the source was a VT, might be different than // the owner tree. FIsDropTarget: Boolean; // True if the owner is currently the drop target. FDataObject: IDataObject; // A reference to the data object passed in by DragEnter (only used when the owner // tree is the current drop target). FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support FFullDragging: BOOL; // True, if full dragging is currently enabled in the system. function GetDataObject: IDataObject; stdcall; function GetDragSource: TObject; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; public constructor Create(AOwner: TObject); virtual; destructor Destroy; override; function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function DragLeave: HResult; stdcall; function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; procedure ForceDragLeave; stdcall; function GiveFeedback(Effect: LongWord): HResult; stdcall; function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall; end; //Ole helper functions function Succeeded(Status : HRESULT) : BOOLEAN; function Failed(Status : HRESULT) : BOOLEAN; //ActiveX functions that have wrong calling convention in fpc function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall; function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall; function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI; function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall; procedure OleUninitialize;stdcall; procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall; function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall; function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall; function OleFlushClipboard:WINOLEAPI;stdcall; function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall; function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall; function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall; //helper functions to isolate windows/OLE specific code function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; function GetStreamFromMedium(Medium:TStgMedium):TStream; procedure UnlockMediumData(Medium:TStgMedium); function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject; function AllocateGlobal(Data: Pointer; DataSize:Cardinal): HGLOBAL; implementation uses VirtualTrees, Controls {$ifdef DEBUG_VTV}, vtlogger{$endif}; type TVirtualTreeAccess = class (TBaseVirtualTree) end; function Succeeded(Status : HRESULT) : BOOLEAN; begin Succeeded:=Status and HRESULT($80000000)=0; end; function Failed(Status : HRESULT) : BOOLEAN; begin Failed:=Status and HRESULT($80000000)<>0; end; function RegisterDragDrop(hwnd: HWND; pDropTarget: IDropTarget): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function RevokeDragDrop(hwnd: HWND): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource; dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleInitialize(pvReserved: LPVOID): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; procedure OleUninitialize; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; procedure ReleaseStgMedium(_para1: LPSTGMEDIUM); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleSetClipboard(pDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleGetClipboard(out ppDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleFlushClipboard: WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleIsCurrentClipboard(pDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function CreateStreamOnHGlobal(hGlobal: HGLOBAL; fDeleteOnRelease: BOOL; out stm: IStream): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function CoCreateInstance(const _para1: TCLSID; _para2: IUnknown; _para3: DWORD; const _para4: TIID; out _para5): HRESULT; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; { //--------------- local function -------------------------------------------- procedure WriteNodes(Stream: TStream); var Selection: TNodeArray; I: Integer; begin with TVirtualTreeAccess(Tree) do begin if ForClipboard then Selection := GetSortedCutCopySet(True) else Selection := GetSortedSelection(True); for I := 0 to High(Selection) do WriteNode(Stream, Selection[I]); end; end; //--------------- end local function ---------------------------------------- } var Data: PCardinal; ResPointer: Pointer; ResSize: Integer; OLEStream: IStream; VCLStream: TStream; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { VCLStream := nil; try Medium.PunkForRelease := nil; // Return data in one of the supported storage formats, prefer IStream. if FormatEtcIn.tymed and TYMED_ISTREAM <> 0 then begin // Create an IStream on a memory handle (here it is 0 which indicates to implicitely allocated a handle). // Do not use TStreamAdapter as it is not compatible with OLE (when flushing the clipboard OLE wants the HGlobal // back which is not supported by TStreamAdapater). CreateStreamOnHGlobal(0, True, OLEStream); VCLStream := TOLEStream.Create(OLEStream); WriteNodes(VCLStream); // Rewind stream. VCLStream.Position := 0; Medium.tymed := TYMED_ISTREAM; IUnknown(Medium.Pstm) := OLEStream; Result := S_OK; end else begin VCLStream := TMemoryStream.Create; WriteNodes(VCLStream); ResPointer := TMemoryStream(VCLStream).Memory; ResSize := VCLStream.Position; // Allocate memory to hold the string. if ResSize > 0 then begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, ResSize + SizeOf(Cardinal)); Data := GlobalLock(Medium.hGlobal); // Store the size of the data too, for easy retrival. Data^ := ResSize; Inc(Data); Move(ResPointer^, Data^, ResSize); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Result := S_OK; end else Result := E_FAIL; end; finally // We can free the VCL stream here since it was either a pure memory stream or only a wrapper around // the OLEStream which exists independently. VCLStream.Free; end; } end; type // needed to handle OLE global memory objects TOLEMemoryStream = class(TCustomMemoryStream) public function Write(const Buffer; Count: Integer): Longint; override; end; //---------------------------------------------------------------------------------------------------------------------- function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} // raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError)); end; function GetStreamFromMedium(Medium: TStgMedium): TStream; var Data: Pointer; I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; if Medium.tymed = TYMED_ISTREAM then Result := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream) else begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin // Get the total size of data to retrieve. I := PCardinal(Data)^; Inc(PCardinal(Data)); Result := TOLEMemoryStream.Create; TOLEMemoryStream(Result).SetPointer(Data, I); end; end; } end; procedure UnlockMediumData(Medium: TStgMedium); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Medium.tymed = TYMED_HGLOBAL then GlobalUnlock(Medium.hGlobal); } end; function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject; var Medium: TStgMedium; Data: PVTReference; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; if Assigned(DataObject) then begin Format.cfFormat := CF_VTREFERENCE; if DataObject.GetData(Format, Medium) = S_OK then begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin if Data.Process = GetCurrentProcessID then Result := Data.Tree; GlobalUnlock(Medium.hGlobal); end; ReleaseStgMedium(@Medium); end; end; } end; function AllocateGlobal(Data: Pointer; DataSize: Cardinal): HGLOBAL; var P:Pointer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize); P := GlobalLock(Result); Move(Data^, P^, DataSize); GlobalUnlock(Result); } end; //---------------------------------------------------------------------------------------------------------------------- // OLE drag and drop support classes // This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs // of DD'ing various kinds of virtual data and works also between applications. //----------------- TEnumFormatEtc ------------------------------------------------------------------------------------- constructor TEnumFormatEtc.Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray); var I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FTree := Tree; // Make a local copy of the format data. SetLength(FFormatEtcArray, Length(AFormatEtcArray)); for I := 0 to High(AFormatEtcArray) do FFormatEtcArray[I] := AFormatEtcArray[I]; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult; var AClone: TEnumFormatEtc; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; try AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray); AClone.FCurrentIndex := FCurrentIndex; Enum := AClone as IEnumFormatEtc; except Result := E_FAIL; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; var CopyCount: LongWord; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_FALSE; CopyCount := Length(FFormatEtcArray) - FCurrentIndex; if celt < CopyCount then CopyCount := celt; if CopyCount > 0 then begin Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc)); Inc(FCurrentIndex, CopyCount); Result := S_OK; end; //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with // a C Program call with a NULL in pCeltFetcjed?? //Answer: Yes. Is necessary a check here if @pceltFetched <> nil then pceltFetched := CopyCount; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Reset: HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { FCurrentIndex := 0; Result := S_OK; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Skip(celt: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FCurrentIndex + celt < High(FFormatEtcArray) then begin Inc(FCurrentIndex, celt); Result := S_Ok; end else Result := S_FALSE; } end; //----------------- TVTDataObject -------------------------------------------------------------------------------------- constructor TVTDataObject.Create(AOwner: TObject; ForClipboard: Boolean); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FOwner := AOwner; FForClipboard := ForClipboard; TVirtualTreeAccess(FOwner).GetNativeClipboardFormats(FFormatEtcArray); } end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDataObject.Destroy; var I: Integer; StgMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // Cancel a pending clipboard operation if this data object was created for the clipboard and // is freed because something else is placed there. if FForClipboard and not (tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates) then TVirtualTreeAccess(FOwner).CancelCutOrCopy; // Release any internal clipboard formats for I := 0 to High(FormatEtcArray) do begin StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat); if Assigned(StgMedium) then ReleaseStgMedium(StgMedium); end; FormatEtcArray := nil; inherited; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; // Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown // interface, will always return the same pointer. begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(TestUnknown) then begin if TestUnknown.QueryInterface(IUnknown, Result) = 0 then Result._Release // Don't actually need it just need the pointer value else Result := TestUnknown end else Result := TestUnknown } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and (FormatEtc1.tymed and FormatEtc2.tymed <> 0); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; var I: integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := -1; for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then begin Result := I; Break; end end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium; var I: integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; for I := 0 to High(InternalStgMediumArray) do begin if Format = InternalStgMediumArray[I].Format then begin Result := @InternalStgMediumArray[I].Medium; Break; end end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle; // Returns a global memory block that is a copy of the passed memory block. var Size: Cardinal; Data, NewData: PChar; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Size := GlobalSize(HGlobal); Result := GlobalAlloc(GPTR, Size); Data := GlobalLock(hGlobal); try NewData := GlobalLock(Result); try Move(Data^, NewData^, Size); finally GlobalUnLock(Result); end finally GlobalUnLock(hGlobal); end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; // Tries to render one of the formats which have been stored via the SetData method. // Since this data is already there it is just copied or its reference count is increased (depending on storage medium). var InternalMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := True; InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat); if Assigned(InternalMedium) then OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject) else Result := False; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; // InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or // increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually // the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData. // If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during // that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make // copy of the data for the caller only to have them destroy it then need us to copy it again if necessary. // This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData. // This way when the caller frees the structure it sees the unkForRelease is not nil and calls Release on the object // instead of destroying the actual data. var Len: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; // Simply copy all fields to start with. OutStgMedium := InStgMedium; // The data handled here always results from a call of SetData we got. This ensures only one storage format // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several // storage formats). case InStgMedium.tymed of TYMED_HGLOBAL: begin if CopyInMedium then begin // Generate a unique copy of the data passed OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal); if OutStgMedium.hGlobal = 0 then Result := E_OUTOFMEMORY end else // Don't generate a copy just use ourselves and the copy previously saved. OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount. end; TYMED_FILE: begin //todo_lcl_check Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character. OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len); Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len); end; TYMED_ISTREAM: IUnknown(OutStgMedium.Pstm)._AddRef; TYMED_ISTORAGE: IUnknown(OutStgMedium.Pstg)._AddRef; TYMED_GDI: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy GDI objects right now. TYMED_MFPICT: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now. TYMED_ENHMF: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now. else Result := DV_E_TYMED; end; if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then IUnknown(OutStgMedium.PunkForRelease)._AddRef; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; // Advise sink management is greatly simplified by the IDataAdviseHolder interface. // We use this interface and forward all concerning calls to it. begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; if FAdviseHolder = nil then Result := CreateDataAdviseHolder(FAdviseHolder); if Result = S_OK then Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DUnadvise(dwConnection: DWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FAdviseHolder = nil then Result := E_NOTIMPL else Result := FAdviseHolder.Unadvise(dwConnection); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumDAvise(Out enumAdvise : IEnumStatData):HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FAdviseHolder = nil then Result := OLE_E_ADVISENOTSUPPORTED else Result := FAdviseHolder.EnumAdvise(enumAdvise); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; var NewList: TEnumFormatEtc; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := E_FAIL; if Direction = DATADIR_GET then begin NewList := TEnumFormatEtc.Create(TVirtualTreeAccess(FOwner), FormatEtcArray); EnumFormatEtc := NewList as IEnumFormatEtc; Result := S_OK; end else EnumFormatEtc := nil; if EnumFormatEtc = nil then Result := OLE_S_USEREG; } end; //---------------------------------------------------------------------------------------------------------------------- Function TVTDataObject.GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := DATA_S_SAMEFORMATETC; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; // Data is requested by clipboard or drop target. This method dispatchs the call // depending on the data being requested. var I: Integer; Data: PVTReference; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} // The tree reference format is always supported and returned from here. { if FormatEtcIn.cfFormat = CF_VTREFERENCE then begin // Note: this format is not used while flushing the clipboard to avoid a dangling reference // when the owner tree is destroyed before the clipboard data is replaced with something else. if tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates then Result := E_FAIL else begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference)); Data := GlobalLock(Medium.hGlobal); Data.Process := GetCurrentProcessID; Data.Tree := TBaseVirtualTree(FOwner); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Medium.PunkForRelease := nil; Result := S_OK; end; end else begin try // See if we accept this type and if not get the correct return value. Result := QueryGetData(FormatEtcIn); if Result = S_OK then begin for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then begin if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then Result := TVirtualTreeAccess(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard); Break; end; end end except FillChar(Medium, SizeOf(Medium), #0); Result := E_FAIL; end; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult; var I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := DV_E_CLIPFORMAT; for I := 0 to High(FFormatEtcArray) do begin if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then begin if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then begin if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then begin if FormatEtc.lindex = FFormatEtcArray[I].lindex then begin Result := S_OK; Break; end else Result := DV_E_LINDEX; end else Result := DV_E_DVASPECT; end else Result := DV_E_TYMED; end; end } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; // Allows dynamic adding to the IDataObject during its existance. Most noteably it is used to implement // IDropSourceHelper and allows to set a special format for optimized moves during a shell transfer. var Index: Integer; LocalStgMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // See if we already have a format of that type available. Index := FindFormatEtc(FormatEtc, FormatEtcArray); if Index > - 1 then begin // Just use the TFormatEct in the array after releasing the data. LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat); if Assigned(LocalStgMedium) then begin ReleaseStgMedium(LocalStgMedium); FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; end else begin // It is a new format so create a new TFormatCollectionItem, copy the // FormatEtc parameter into the new object and and put it in the list. SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1); FormatEtcArray[High(FormatEtcArray)] := FormatEtc; // Create a new InternalStgMedium and initialize it and associate it with the format. SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1); InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat; LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium; FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; if DoRelease then begin // We are simply being given the data and we take control of it. LocalStgMedium^ := Medium; Result := S_OK end else begin // We need to reference count or copy the data and keep our own references to it. Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject); // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium. // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN. if Assigned(LocalStgMedium.PunkForRelease) then begin if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface end; end; // Tell all registered advice sinks about the data change. if Assigned(FAdviseHolder) then FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0); } end; //----------------- TVTDragManager ------------------------------------------------------------------------------------- constructor TVTDragManager.Create(AOwner: TObject); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FOwner := AOwner; // Create an instance of the drop target helper interface. This will fail but not harm on systems which do // not support this interface (everything below Windows 2000); CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper); } end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDragManager.Destroy; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // Set the owner's reference to us to nil otherwise it will access an invalid pointer // after our desctruction is complete. TVirtualTreeAccess(FOwner).FreeDragManager; inherited; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDataObject: IDataObject; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem. // In this case there is no local reference to a data object and one is created (but not stored). // If there is a local reference then the owner tree is currently the drop target and the stored interface is // that of the drag initiator. if Assigned(FDataObject) then Result := FDataObject else begin Result := TVirtualTreeAccess(FOwner).DoCreateDataObject; if Result = nil then Result := TVTDataObject.Create(FOwner, False) as IDataObject; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDragSource: TObject; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := FDragSource; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDropTargetHelperSupported: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := Assigned(FDropTargetHelper); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetIsDropTarget: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := FIsDropTarget; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { FDataObject := DataObject; FIsDropTarget := True; SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0); // If full dragging of window contents is disabled in the system then our tree windows will be locked // and cannot be updated during a drag operation. With the following call painting is again enabled. if not FFullDragging then LockWindowUpdate(0); if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragEnter(TBaseVirtualTree(FOwner).Handle, DataObject, Pt, Effect); FDragSource := TVirtualTreeAccess(FOwner).GetTreeFromDataObject(DataObject); Result := TVirtualTreeAccess(FOwner).DragEnter(KeyState, Pt, Effect); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragLeave: HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; TVirtualTreeAccess(FOwner).DragLeave; FIsDropTarget := False; FDragSource := nil; FDataObject := nil; Result := NOERROR; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragOver(Pt, Effect); Result := TVirtualTreeAccess(FOwner).DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.Drop(DataObject, Pt, Effect); Result := TVirtualTreeAccess(FOwner).DragDrop(DataObject, KeyState, Pt, Effect); FIsDropTarget := False; FDataObject := nil; } end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragManager.ForceDragLeave; // Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive // a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from // screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE). begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GiveFeedback(Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := DRAGDROP_S_USEDEFAULTCURSORS; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; var RButton, LButton: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { LButton := (KeyState and MK_LBUTTON) <> 0; RButton := (KeyState and MK_RBUTTON) <> 0; // Drag'n drop canceled by pressing both mouse buttons or Esc? if (LButton and RButton) or EscapePressed then Result := DRAGDROP_S_CANCEL else // Drag'n drop finished? if not (LButton or RButton) then Result := DRAGDROP_S_DROP else Result := S_OK; } end; end. doublecmd-0.8.2/components/virtualtreeview/units/gtk2/fakeactivex.pas0000664000175000017500000000005412014201074025131 0ustar alexxalexxunit FakeActiveX; {$i ../dummyactivex.inc} doublecmd-0.8.2/components/virtualtreeview/units/gtk2/fakemmsystem.pas0000664000175000017500000000065012014201074025346 0ustar alexxalexxunit fakemmsystem; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Types, LCLIntf; function timeBeginPeriod(x1: DWord): DWord; function timeEndPeriod(x1: DWord): DWord; function timeGetTime: DWORD; implementation function timeBeginPeriod(x1: DWord): DWord; begin // end; function timeEndPeriod(x1: DWord): DWord; begin // end; function timeGetTime: DWORD; begin Result := GetTickCount; end; end. doublecmd-0.8.2/components/virtualtreeview/units/win32/0000775000175000017500000000000013244011205022227 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/units/win32/virtualpanningwindow.pas0000664000175000017500000000521212140233030027221 0ustar alexxalexxunit virtualpanningwindow; {Adapted from VirtualTrees by Luiz Amrico to work in LCL/Lazarus} {$mode objfpc}{$H+} interface uses Windows, Graphics, Classes, SysUtils; type { TVirtualPanningWindow } TVirtualPanningWindow = class private FHandle: THandle; FImage: TBitmap; procedure HandlePaintMessage; public procedure Start(OwnerHandle: THandle; const Position: TPoint); procedure Stop; procedure Show(ClipRegion: HRGN); property Image: TBitmap read FImage; property Handle: THandle read FHandle; end; implementation {$ifdef DEBUG_VTV} uses vtlogger; {$endif} function PanningWindowProc(Window: HWnd; Msg: UInt;WPara: WParam; LPara: LParam): LResult; stdcall; var PanningObject: TVirtualPanningWindow; begin if Msg = WM_PAINT then begin PanningObject:=TVirtualPanningWindow(GetWindowLongPtrW(Window,GWL_USERDATA)); if Assigned(PanningObject) then PanningObject.HandlePaintMessage; Result := 0; end else Result := DefWindowProc(Window,Msg,WPara,LPara); end; var PanningWindowClass: TWndClass = ( style: 0; lpfnWndProc: @PanningWindowProc; cbClsExtra: 0; cbWndExtra: 0; hInstance: 0; hIcon: 0; hCursor: 0; hbrBackground: 0; lpszMenuName: nil; lpszClassName: 'VTPanningWindow' ); { TVirtualPanningWindow } procedure TVirtualPanningWindow.HandlePaintMessage; var PS: PaintStruct; begin BeginPaint(FHandle, PS); BitBlt(PS.hdc,0,0,FImage.Width,FImage.Height,FImage.Canvas.Handle,0,0,SRCCOPY); EndPaint(FHandle, PS); end; procedure TVirtualPanningWindow.Start(OwnerHandle: THandle; const Position: TPoint); var TempClass: TWndClass; begin // Register the helper window class. if not GetClassInfo(HInstance, PanningWindowClass.lpszClassName, TempClass) then begin PanningWindowClass.hInstance := HInstance; Windows.RegisterClass(PanningWindowClass); end; // Create the helper window and show it at the given position without activating it. with Position do FHandle := CreateWindowEx(WS_EX_TOOLWINDOW, PanningWindowClass.lpszClassName, nil, WS_POPUP, X - 16, Y - 16, 32, 32, OwnerHandle, 0, HInstance, nil); SetWindowLongPtr(FHandle,GWL_USERDATA,LONG_PTR(Self)); FImage := TBitmap.Create; end; procedure TVirtualPanningWindow.Stop; begin // Destroy the helper window. DestroyWindow(FHandle); FImage.Free; FImage := nil; end; procedure TVirtualPanningWindow.Show(ClipRegion: HRGN); begin {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPanning],'Panning Image',FImage);{$endif} //todo: move SetWindowRgn to DelphiCompat SetWindowRgn(FHandle, ClipRegion, False); ShowWindow(FHandle, SW_SHOWNOACTIVATE); end; end. doublecmd-0.8.2/components/virtualtreeview/units/win32/virtualdragmanager.pas0000664000175000017500000011656712014201074026632 0ustar alexxalexxunit virtualdragmanager; {$mode delphi} interface uses Windows, ActiveX, Classes, SysUtils; const // Drag image helpers for Windows 2000 and up. IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0)); IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46)); CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}'; SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}'; SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}'; //Bridge to ActiveX constants TYMED_HGLOBAL = ActiveX.TYMED_HGLOBAL; TYMED_ISTREAM = ActiveX.TYMED_ISTREAM; DVASPECT_CONTENT = ActiveX.DVASPECT_CONTENT; CLSCTX_INPROC_SERVER = ActiveX.CLSCTX_INPROC_SERVER; DROPEFFECT_COPY = ActiveX.DROPEFFECT_COPY; DROPEFFECT_LINK = ActiveX.DROPEFFECT_LINK; DROPEFFECT_MOVE = ActiveX.DROPEFFECT_MOVE; DROPEFFECT_NONE = ActiveX.DROPEFFECT_NONE; DROPEFFECT_SCROLL = ActiveX.DROPEFFECT_SCROLL; DATADIR_GET = ActiveX.DATADIR_GET; type //Bridge to ActiveX Types IDataObject = ActiveX.IDataObject; IDropTarget = ActiveX.IDropTarget; IDropSource = ActiveX.IDropSource; IEnumFormatEtc = ActiveX.IEnumFORMATETC; //WINOLEAPI = ActiveX.WINOLEAPI; TFormatEtc = ActiveX.TFORMATETC; TStgMedium = ActiveX.TStgMedium; PDVTargetDevice = ActiveX.PDVTARGETDEVICE; // OLE drag'n drop support TFormatEtcArray = array of TFormatEtc; TFormatArray = array of Word; // IDataObject.SetData support TInternalStgMedium = packed record Format: TClipFormat; Medium: TStgMedium; end; TInternalStgMediumArray = array of TInternalStgMedium; TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc) private FTree: TObject; FFormatEtcArray: TFormatEtcArray; FCurrentIndex: Integer; public constructor Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray); function Clone(out Enum: IEnumFormatEtc): HResult; stdcall; function Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; stdcall; function Reset: HResult; stdcall; function Skip(celt: LongWord): HResult; stdcall; end; IDropTargetHelper = interface(IUnknown) [SID_IDropTargetHelper] function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function DragLeave: HRESULT; stdcall; function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Show(fShow: Boolean): HRESULT; stdcall; end; PSHDragImage = ^TSHDragImage; TSHDragImage = packed record sizeDragImage: TSize; ptOffset: TPoint; hbmpDragImage: HBITMAP; ColorRef: TColorRef; end; IDragSourceHelper = interface(IUnknown) [SID_IDragSourceHelper] function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall; function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall; end; IVTDragManager = interface(IUnknown) ['{C4B25559-14DA-446B-8901-0C879000EB16}'] procedure ForceDragLeave; stdcall; function GetDataObject: IDataObject; stdcall; function GetDragSource: TObject; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; property DataObject: IDataObject read GetDataObject; property DragSource: TObject read GetDragSource; property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported; property IsDropTarget: Boolean read GetIsDropTarget; end; // This data object is used in two different places. One is for clipboard operations and the other while dragging. TVTDataObject = class(TInterfacedObject, IDataObject) private //FOwner: TBaseVirtualTree; // The tree which provides clipboard or drag data. FOwner: TObject; // The tree which provides clipboard or drag data. FForClipboard: Boolean; // Determines which data to render with GetData. FFormatEtcArray: TFormatEtcArray; FInternalStgMediumArray: TInternalStgMediumArray; // The available formats in the DataObject FAdviseHolder: IDataAdviseHolder; // Reference to an OLE supplied implementation for advising. protected function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; function FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; function FindInternalStgMedium(Format: TClipFormat): PStgMedium; function HGlobalClone(HGlobal: THandle): THandle; function RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; property ForClipboard: Boolean read FForClipboard; property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray; property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray; property Owner: TObject read FOwner; public constructor Create(AOwner: TObject; ForClipboard: Boolean); virtual; destructor Destroy; override; function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; virtual; stdcall; function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall; Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;virtual;StdCall; function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall; Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; virtual; STDCALl; function GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall; function SetData(const FormatEtc: TFormatEtc; {$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall; end; // TVTDragManager is a class to manage drag and drop in a Virtual Treeview. TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget) private FOwner, // The tree which is responsible for drag management. FDragSource: TObject; // Reference to the source tree if the source was a VT, might be different than // the owner tree. FIsDropTarget: Boolean; // True if the owner is currently the drop target. FDataObject: IDataObject; // A reference to the data object passed in by DragEnter (only used when the owner // tree is the current drop target). FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support FFullDragging: BOOL; // True, if full dragging is currently enabled in the system. function GetDataObject: IDataObject; stdcall; function GetDragSource: TObject; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; public constructor Create(AOwner: TComponent); virtual; destructor Destroy; override; function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function DragLeave: HResult; stdcall; function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; procedure ForceDragLeave; stdcall; function GiveFeedback(Effect: LongWord): HResult; stdcall; function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall; end; //Ole helper functions function Succeeded(Status : HRESULT) : BOOLEAN; function Failed(Status : HRESULT) : BOOLEAN; //ActiveX functions that have wrong calling convention in fpc function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall;external 'ole32.dll' name 'RegisterDragDrop'; function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall;external 'ole32.dll' name 'RevokeDragDrop'; function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI;stdcall;external 'ole32.dll' name 'DoDragDrop'; function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleInitialize'; procedure OleUninitialize;stdcall;external 'ole32.dll' name 'OleUninitialize'; procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall;external 'ole32.dll' name 'ReleaseStgMedium'; function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleSetClipboard'; function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleGetClipboard'; function OleFlushClipboard:WINOLEAPI;stdcall;external 'ole32.dll' name 'OleFlushClipboard'; function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleIsCurrentClipboard'; function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall;external 'ole32.dll' name 'CreateStreamOnHGlobal'; function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall; external 'ole32.dll' name 'CoCreateInstance'; //helper functions to isolate windows/OLE specific code function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; function GetStreamFromMedium(Medium:TStgMedium):TStream; procedure UnlockMediumData(Medium:TStgMedium); function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject; function AllocateGlobal(Data: Pointer; DataSize:Cardinal): HGLOBAL; implementation uses VirtualTrees, Controls, oleutils; type TVirtualTreeAccess = class (TBaseVirtualTree) end; function Succeeded(Status : HRESULT) : BOOLEAN; begin Succeeded:=Status and HRESULT($80000000)=0; end; function Failed(Status : HRESULT) : BOOLEAN; begin Failed:=Status and HRESULT($80000000)<>0; end; function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; //--------------- local function -------------------------------------------- procedure WriteNodes(Stream: TStream); var Selection: TNodeArray; I: Integer; begin with TVirtualTreeAccess(Tree) do begin if ForClipboard then Selection := GetSortedCutCopySet(True) else Selection := GetSortedSelection(True); for I := 0 to High(Selection) do WriteNode(Stream, Selection[I]); end; end; //--------------- end local function ---------------------------------------- var Data: PCardinal; ResPointer: Pointer; ResSize: Integer; OLEStream: IStream; VCLStream: TStream; begin VCLStream := nil; try Medium.PunkForRelease := nil; // Return data in one of the supported storage formats, prefer IStream. if FormatEtcIn.tymed and TYMED_ISTREAM <> 0 then begin // Create an IStream on a memory handle (here it is 0 which indicates to implicitely allocated a handle). // Do not use TStreamAdapter as it is not compatible with OLE (when flushing the clipboard OLE wants the HGlobal // back which is not supported by TStreamAdapater). CreateStreamOnHGlobal(0, True, OLEStream); VCLStream := TOLEStream.Create(OLEStream); WriteNodes(VCLStream); // Rewind stream. VCLStream.Position := 0; Medium.tymed := TYMED_ISTREAM; IUnknown(Medium.Pstm) := OLEStream; Result := S_OK; end else begin VCLStream := TMemoryStream.Create; WriteNodes(VCLStream); ResPointer := TMemoryStream(VCLStream).Memory; ResSize := VCLStream.Position; // Allocate memory to hold the string. if ResSize > 0 then begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, ResSize + SizeOf(Cardinal)); Data := GlobalLock(Medium.hGlobal); // Store the size of the data too, for easy retrival. Data^ := ResSize; Inc(Data); Move(ResPointer^, Data^, ResSize); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Result := S_OK; end else Result := E_FAIL; end; finally // We can free the VCL stream here since it was either a pure memory stream or only a wrapper around // the OLEStream which exists independently. VCLStream.Free; end; end; type // needed to handle OLE global memory objects TOLEMemoryStream = class(TCustomMemoryStream) public function Write(const Buffer; Count: Integer): Longint; override; end; //---------------------------------------------------------------------------------------------------------------------- function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer; begin {$ifdef COMPILER_5_UP} raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError)); {$else} raise EStreamError.Create(SCantWriteResourceStreamError); {$endif COMPILER_5_UP} end; function GetStreamFromMedium(Medium: TStgMedium): TStream; var Data: Pointer; I: Integer; begin Result := nil; if Medium.tymed = TYMED_ISTREAM then Result := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream) else begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin // Get the total size of data to retrieve. I := PCardinal(Data)^; Inc(PCardinal(Data)); Result := TOLEMemoryStream.Create; TOLEMemoryStream(Result).SetPointer(Data, I); end; end; end; procedure UnlockMediumData(Medium: TStgMedium); begin if Medium.tymed = TYMED_HGLOBAL then GlobalUnlock(Medium.hGlobal); end; function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject; var Medium: TStgMedium; Data: PVTReference; begin Result := nil; if Assigned(DataObject) then begin Format.cfFormat := CF_VTREFERENCE; if DataObject.GetData(Format, Medium) = S_OK then begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin if Data.Process = GetCurrentProcessID then Result := Data.Tree; GlobalUnlock(Medium.hGlobal); end; ReleaseStgMedium(@Medium); end; end; end; function AllocateGlobal(Data: Pointer; DataSize: Cardinal): HGLOBAL; var P:Pointer; begin Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize); P := GlobalLock(Result); Move(Data^, P^, DataSize); GlobalUnlock(Result); end; //---------------------------------------------------------------------------------------------------------------------- // OLE drag and drop support classes // This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs // of DD'ing various kinds of virtual data and works also between applications. //----------------- TEnumFormatEtc ------------------------------------------------------------------------------------- constructor TEnumFormatEtc.Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray); var I: Integer; begin inherited Create; FTree := Tree; // Make a local copy of the format data. SetLength(FFormatEtcArray, Length(AFormatEtcArray)); for I := 0 to High(AFormatEtcArray) do FFormatEtcArray[I] := AFormatEtcArray[I]; end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult; var AClone: TEnumFormatEtc; begin Result := S_OK; try AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray); AClone.FCurrentIndex := FCurrentIndex; Enum := AClone as IEnumFormatEtc; except Result := E_FAIL; end; end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; var CopyCount: LongWord; begin Result := S_FALSE; CopyCount := Length(FFormatEtcArray) - FCurrentIndex; if celt < CopyCount then CopyCount := celt; if CopyCount > 0 then begin Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc)); Inc(FCurrentIndex, CopyCount); Result := S_OK; end; //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with // a C Program call with a NULL in pCeltFetcjed?? //Answer: Yes. Is necessary a check here if @pceltFetched <> nil then pceltFetched := CopyCount; end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Reset: HResult; begin FCurrentIndex := 0; Result := S_OK; end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Skip(celt: LongWord): HResult; begin if FCurrentIndex + celt < High(FFormatEtcArray) then begin Inc(FCurrentIndex, celt); Result := S_Ok; end else Result := S_FALSE; end; //----------------- TVTDataObject -------------------------------------------------------------------------------------- constructor TVTDataObject.Create(AOwner: TObject; ForClipboard: Boolean); begin inherited Create; FOwner := AOwner; FForClipboard := ForClipboard; TVirtualTreeAccess(FOwner).GetNativeClipboardFormats(FFormatEtcArray); end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDataObject.Destroy; var I: Integer; StgMedium: PStgMedium; begin // Cancel a pending clipboard operation if this data object was created for the clipboard and // is freed because something else is placed there. if FForClipboard and not (tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates) then TVirtualTreeAccess(FOwner).CancelCutOrCopy; // Release any internal clipboard formats for I := 0 to High(FormatEtcArray) do begin StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat); if Assigned(StgMedium) then ReleaseStgMedium(StgMedium); end; FormatEtcArray := nil; inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; // Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown // interface, will always return the same pointer. begin if Assigned(TestUnknown) then begin if TestUnknown.QueryInterface(IUnknown, Result) = 0 then Result._Release // Don't actually need it just need the pointer value else Result := TestUnknown end else Result := TestUnknown end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; begin Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and (FormatEtc1.tymed and FormatEtc2.tymed <> 0); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; var I: integer; begin Result := -1; for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then begin Result := I; Break; end end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium; var I: integer; begin Result := nil; for I := 0 to High(InternalStgMediumArray) do begin if Format = InternalStgMediumArray[I].Format then begin Result := @InternalStgMediumArray[I].Medium; Break; end end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle; // Returns a global memory block that is a copy of the passed memory block. var Size: Cardinal; Data, NewData: PChar; begin Size := GlobalSize(HGlobal); Result := GlobalAlloc(GPTR, Size); Data := GlobalLock(hGlobal); try NewData := GlobalLock(Result); try Move(Data^, NewData^, Size); finally GlobalUnLock(Result); end finally GlobalUnLock(hGlobal); end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; // Tries to render one of the formats which have been stored via the SetData method. // Since this data is already there it is just copied or its reference count is increased (depending on storage medium). var InternalMedium: PStgMedium; begin Result := True; InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat); if Assigned(InternalMedium) then OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject) else Result := False; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; // InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or // increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually // the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData. // If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during // that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make // copy of the data for the caller only to have them destroy it then need us to copy it again if necessary. // This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData. // This way when the caller frees the structure it sees the unkForRelease is not nil and calls Release on the object // instead of destroying the actual data. var Len: Integer; begin Result := S_OK; // Simply copy all fields to start with. OutStgMedium := InStgMedium; // The data handled here always results from a call of SetData we got. This ensures only one storage format // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several // storage formats). case InStgMedium.tymed of TYMED_HGLOBAL: begin if CopyInMedium then begin // Generate a unique copy of the data passed OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal); if OutStgMedium.hGlobal = 0 then Result := E_OUTOFMEMORY end else // Don't generate a copy just use ourselves and the copy previously saved. OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount. end; TYMED_FILE: begin //todo_lcl_check Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character. OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len); Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len); end; TYMED_ISTREAM: IUnknown(OutStgMedium.Pstm)._AddRef; TYMED_ISTORAGE: IUnknown(OutStgMedium.Pstg)._AddRef; TYMED_GDI: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy GDI objects right now. TYMED_MFPICT: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now. TYMED_ENHMF: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now. else Result := DV_E_TYMED; end; if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then IUnknown(OutStgMedium.PunkForRelease)._AddRef; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; // Advise sink management is greatly simplified by the IDataAdviseHolder interface. // We use this interface and forward all concerning calls to it. begin Result := S_OK; if FAdviseHolder = nil then Result := CreateDataAdviseHolder(FAdviseHolder); if Result = S_OK then Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DUnadvise(dwConnection: DWord): HResult; begin if FAdviseHolder = nil then Result := E_NOTIMPL else Result := FAdviseHolder.Unadvise(dwConnection); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumDAvise(Out enumAdvise : IEnumStatData):HResult; begin if FAdviseHolder = nil then Result := OLE_E_ADVISENOTSUPPORTED else Result := FAdviseHolder.EnumAdvise(enumAdvise); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; var NewList: TEnumFormatEtc; begin Result := E_FAIL; if Direction = DATADIR_GET then begin NewList := TEnumFormatEtc.Create(TVirtualTreeAccess(FOwner), FormatEtcArray); EnumFormatEtc := NewList as IEnumFormatEtc; Result := S_OK; end else EnumFormatEtc := nil; if EnumFormatEtc = nil then Result := OLE_S_USEREG; end; //---------------------------------------------------------------------------------------------------------------------- Function TVTDataObject.GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; begin Result := DATA_S_SAMEFORMATETC; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; // Data is requested by clipboard or drop target. This method dispatchs the call // depending on the data being requested. var I: Integer; Data: PVTReference; begin // The tree reference format is always supported and returned from here. if FormatEtcIn.cfFormat = CF_VTREFERENCE then begin // Note: this format is not used while flushing the clipboard to avoid a dangling reference // when the owner tree is destroyed before the clipboard data is replaced with something else. if tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates then Result := E_FAIL else begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference)); Data := GlobalLock(Medium.hGlobal); Data.Process := GetCurrentProcessID; Data.Tree := TBaseVirtualTree(FOwner); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Medium.PunkForRelease := nil; Result := S_OK; end; end else begin try // See if we accept this type and if not get the correct return value. Result := QueryGetData(FormatEtcIn); if Result = S_OK then begin for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then begin if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then Result := TVirtualTreeAccess(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard); Break; end; end end except FillChar(Medium, SizeOf(Medium), #0); Result := E_FAIL; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; begin Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult; var I: Integer; begin Result := DV_E_CLIPFORMAT; for I := 0 to High(FFormatEtcArray) do begin if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then begin if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then begin if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then begin if FormatEtc.lindex = FFormatEtcArray[I].lindex then begin Result := S_OK; Break; end else Result := DV_E_LINDEX; end else Result := DV_E_DVASPECT; end else Result := DV_E_TYMED; end; end end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; // Allows dynamic adding to the IDataObject during its existance. Most noteably it is used to implement // IDropSourceHelper and allows to set a special format for optimized moves during a shell transfer. var Index: Integer; LocalStgMedium: PStgMedium; begin // See if we already have a format of that type available. Index := FindFormatEtc(FormatEtc, FormatEtcArray); if Index > - 1 then begin // Just use the TFormatEct in the array after releasing the data. LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat); if Assigned(LocalStgMedium) then begin ReleaseStgMedium(LocalStgMedium); FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; end else begin // It is a new format so create a new TFormatCollectionItem, copy the // FormatEtc parameter into the new object and and put it in the list. SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1); FormatEtcArray[High(FormatEtcArray)] := FormatEtc; // Create a new InternalStgMedium and initialize it and associate it with the format. SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1); InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat; LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium; FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; if DoRelease then begin // We are simply being given the data and we take control of it. LocalStgMedium^ := Medium; Result := S_OK end else begin // We need to reference count or copy the data and keep our own references to it. Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject); // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium. // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN. if Assigned(LocalStgMedium.PunkForRelease) then begin if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface end; end; // Tell all registered advice sinks about the data change. if Assigned(FAdviseHolder) then FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0); end; //----------------- TVTDragManager ------------------------------------------------------------------------------------- constructor TVTDragManager.Create(AOwner: TComponent); begin inherited Create; FOwner := AOwner; // Create an instance of the drop target helper interface. This will fail but not harm on systems which do // not support this interface (everything below Windows 2000); CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper); end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDragManager.Destroy; begin // Set the owner's reference to us to nil otherwise it will access an invalid pointer // after our desctruction is complete. TVirtualTreeAccess(FOwner).FreeDragManager; inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDataObject: IDataObject; begin // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem. // In this case there is no local reference to a data object and one is created (but not stored). // If there is a local reference then the owner tree is currently the drop target and the stored interface is // that of the drag initiator. if Assigned(FDataObject) then Result := FDataObject else begin Result := TVirtualTreeAccess(FOwner).DoCreateDataObject; if Result = nil then Result := TVTDataObject.Create(FOwner, False) as IDataObject; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDragSource: TObject; begin Result := FDragSource; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDropTargetHelperSupported: Boolean; begin Result := Assigned(FDropTargetHelper); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetIsDropTarget: Boolean; begin Result := FIsDropTarget; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin FDataObject := DataObject; FIsDropTarget := True; SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0); // If full dragging of window contents is disabled in the system then our tree windows will be locked // and cannot be updated during a drag operation. With the following call painting is again enabled. if not FFullDragging then LockWindowUpdate(0); if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragEnter(TBaseVirtualTree(FOwner).Handle, DataObject, Pt, Effect); FDragSource := TVirtualTreeAccess(FOwner).GetTreeFromDataObject(DataObject); Result := TVirtualTreeAccess(FOwner).DragEnter(KeyState, Pt, Effect); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragLeave: HResult; begin if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; TVirtualTreeAccess(FOwner).DragLeave; FIsDropTarget := False; FDragSource := nil; FDataObject := nil; Result := NOERROR; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragOver(Pt, Effect); Result := TVirtualTreeAccess(FOwner).DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.Drop(DataObject, Pt, Effect); Result := TVirtualTreeAccess(FOwner).DragDrop(DataObject, KeyState, Pt, Effect); FIsDropTarget := False; FDataObject := nil; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragManager.ForceDragLeave; // Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive // a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from // screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE). begin if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GiveFeedback(Effect: LongWord): HResult; begin Result := DRAGDROP_S_USEDEFAULTCURSORS; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; var RButton, LButton: Boolean; begin LButton := (KeyState and MK_LBUTTON) <> 0; RButton := (KeyState and MK_RBUTTON) <> 0; // Drag'n drop canceled by pressing both mouse buttons or Esc? if (LButton and RButton) or EscapePressed then Result := DRAGDROP_S_CANCEL else // Drag'n drop finished? if not (LButton or RButton) then Result := DRAGDROP_S_DROP else Result := S_OK; end; end. doublecmd-0.8.2/components/virtualtreeview/units/carbon/0000775000175000017500000000000013244011205022531 5ustar alexxalexxdoublecmd-0.8.2/components/virtualtreeview/units/carbon/virtualpanningwindow.pas0000664000175000017500000000201212014201074027521 0ustar alexxalexxunit virtualpanningwindow; {$mode objfpc}{$H+} interface uses LCLType, Graphics, Classes, SysUtils; type { TVirtualPanningWindow } TVirtualPanningWindow = class private FHandle: THandle; FOwnerHandle: THandle; FImage: TBitmap; procedure HandlePaintMessage; public procedure Start(OwnerHandle: THandle; const Position: TPoint); procedure Stop; procedure Show(ClipRegion: HRGN); property Image: TBitmap read FImage; property Handle: THandle read FHandle; end; implementation {$ifdef DEBUG_VTV} uses vtlogger; {$endif} { TVirtualPanningWindow } procedure TVirtualPanningWindow.HandlePaintMessage; begin end; procedure TVirtualPanningWindow.Start(OwnerHandle: THandle; const Position: TPoint); begin FImage := TBitmap.Create; end; procedure TVirtualPanningWindow.Stop; begin FImage.Free; FImage := nil; end; procedure TVirtualPanningWindow.Show(ClipRegion: HRGN); begin {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPanning],'Panning Image',FImage);{$endif} end; end. doublecmd-0.8.2/components/virtualtreeview/units/carbon/virtualdragmanager.pas0000664000175000017500000017010612014201074027121 0ustar alexxalexxunit virtualdragmanager; {fake unit just to compile - not used under non windows} {$mode delphi} interface uses Classes, SysUtils, Types; const // Drag image helpers for Windows 2000 and up. IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0)); IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46)); CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}'; SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}'; SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}'; //Bridge to ActiveX constants TYMED_HGLOBAL = 1; TYMED_ISTREAM = 4; DVASPECT_CONTENT = 1; CLSCTX_INPROC_SERVER = $0010; DROPEFFECT_COPY = 1; DROPEFFECT_LINK = 4; DROPEFFECT_MOVE = 2; DROPEFFECT_NONE = 0; DROPEFFECT_SCROLL = dword($80000000); DATADIR_GET = 1; type //types from win unit Long = LongInt; WinBool= LongBool; Bool= WinBool; ULONG = cardinal; LONGLONG = int64; LPDWORD = ^DWORD; LPVOID = pointer; TCOLORREF = cardinal; TIID = TGUID; LARGE_INTEGER = record case byte of 0: (LowPart : DWORD; HighPart : LONG); 1: (QuadPart : LONGLONG); end; PLARGE_INTEGER = ^LARGE_INTEGER; _LARGE_INTEGER = LARGE_INTEGER; TLargeInteger = Int64; PLargeInteger = ^TLargeInteger; ULARGE_INTEGER = record case byte of 0: (LowPart : DWORD; HighPart : DWORD); 1: (QuadPart : LONGLONG); end; PULARGE_INTEGER = ^ULARGE_INTEGER; _ULARGE_INTEGER = ULARGE_INTEGER; HANDLE = System.THandle; HWND = HANDLE; //HRESULT = System.HResult; HBITMAP = HANDLE; HENHMETAFILE = HANDLE; //activex types IMoniker = Interface; WINOLEAPI = HResult; TLCID = DWORD; OleChar = WChar; LPOLESTR = ^OLECHAR; HMetaFilePict = Pointer; tagBIND_OPTS = Record cvStruct, // sizeof(BIND_OPTS) grfFlags, grfMode, dwTickCountDeadline : DWord; End; TBind_Opts = tagBIND_OPTS; TCLIPFORMAT = Word; tagDVTARGETDEVICE = Record tdSize : DWord; tdDriverNameOffset, tdDeviceNameOffset, tdPortNameOffset, tdExtDevmodeOffset : Word; Data : Record End; End; DVTARGETDEVICE = TagDVTARGETDEVICE; PDVTARGETDEVICE = ^tagDVTARGETDEVICE; tagFORMATETC = Record CfFormat : Word {TCLIPFORMAT}; Ptd : PDVTARGETDEVICE; dwAspect : DWORD; lindex : Long; tymed : DWORD; End; FORMATETC = TagFORMATETC; TFORMATETC = FORMATETC; LPFORMATETC = ^FORMATETC; PFormatEtc = LPFORMATETC; tagSTATDATA = Record // field used by: FORMATETC : Tformatetc; // EnumAdvise, EnumData (cache), EnumFormats advf : DWord; // EnumAdvise, EnumData (cache) padvSink : Pointer {IAdviseSink}; // EnumAdvise dwConnection: DWord; // EnumAdvise End; STATDATA = TagStatData; TagSTGMEDIUM = Record Tymed : DWord; Case Integer Of 0 : (HBITMAP : hBitmap; PUnkForRelease : Pointer {IUnknown}); 1 : (HMETAFILEPICT : hMetaFilePict ); 2 : (HENHMETAFILE : hEnhMetaFile ); 3 : (HGLOBAL : hGlobal ); 4 : (lpszFileName : LPOLESTR ); 5 : (pstm : Pointer{IStream} ); 6 : (pstg : Pointer{IStorage} ); End; USTGMEDIUM = TagSTGMEDIUM; STGMEDIUM = USTGMEDIUM; TStgMedium = TagSTGMEDIUM; PStgMedium = ^TStgMedium; LPSTGMEDIUM = ^STGMEDIUM; IEnumString = Interface (IUnknown) ['{00000101-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out xcelt;Out Celtfetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong; Out celt;Out Celtfetched:ULong):HResult; StdCall; Function Skip (Celt:ULong):Hresult;StdCall; Function Reset:HResult;StdCall; Function Clone(Out penum:IEnumString):HResult;StdCall; End; IEnumMoniker = Interface (IUnknown) ['{00000102-0000-0000-C000-000000000046}'] Function Next(celt:ULong; out Elt;out celftfetched: ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong; Out rgelt;out celtfetched :ULong):Hresult; StdCall; Function Skip(celt:Ulong):HResult; StdCall; Function Reset:HResult; StdCall; Function Close(out penum:IEnumMoniker):HResult;StdCall; End; IEnumSTATDATA = Interface (IUnknown) ['{00000105-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall; Function Skip(Celt:ULong):HResult;StdCall; Function Reset:HResult;StdCall; Function Clone(out penum:IEnumstatdata):HResult;StdCall; End; IEnumFORMATETC = Interface (IUnknown) ['{00000103-0000-0000-C000-000000000046}'] Function Next(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall; // Function RemoteNext(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall; Function Skip(Celt:ULong):HResult;StdCall; Function Reset:HResult;StdCall; Function Clone(out penum:IEnumFORMATETC):HResult;StdCall; End; IPersist = Interface (IUnknown) ['{0000010c-0000-0000-C000-000000000046}'] Function GetClassId(clsid:TClsId):HResult; StdCall; End; IPersistStream = Interface(IPersist) ['{00000109-0000-0000-C000-000000000046}'] Function IsDirty:HResult; StdCall; Function Load(Const stm: IStream):HResult; StdCall; Function Save(Const stm: IStream;fClearDirty:Bool):HResult;StdCall; Function GetSizeMax(Out cbSize:ULarge_Integer):HResult; StdCall; End; IRunningObjectTable = Interface (IUnknown) ['{00000010-0000-0000-C000-000000000046}'] Function Register (grfFlags :DWord;const unkobject:IUnknown;Const mkObjectName:IMoniker;Out dwregister:DWord):HResult;StdCall; Function Revoke (dwRegister:DWord):HResult; StdCall; Function IsRunning (Const mkObjectName: IMoniker):HResult;StdCall; Function GetObject (Const mkObjectName: IMoniker; Out punkObject:IUnknown):HResult; StdCall; Function NoteChangeTime(dwRegister :DWord;Const FileTime: TFileTime):HResult;StdCall; Function GetTimeOfLastChange(Const mkObjectName:IMoniker;Out filetime:TFileTime):HResult; StdCall; Function EnumRunning (Out enumMoniker: IEnumMoniker):HResult; StdCall; End; IBindCtx = Interface (IUnknown) ['{0000000e-0000-0000-C000-000000000046}'] Function RegisterObjectBound(Const punk:IUnknown):HResult; stdCall; Function RevokeObjectBound (Const Punk:IUnknown):HResult; stdCall; Function ReleaseBoundObjects :HResult; StdCall; Function SetBindOptions(Const bindOpts:TBind_Opts):HResult; stdCall; // Function RemoteSetBindOptions(Const bind_opts: TBind_Opts2):HResult;StdCall; Function GetBindOptions(var BindOpts:TBind_Opts):HResult; stdCall; // Function RemoteGetBindOptions(Var bind_opts: TBind_Opts2):HResult;StdCall; Function GetRunningObjectTable(Out rot : IRunningObjectTable):Hresult; StdCall; Function RegisterObjectParam(Const pszkey:LPOleStr;const punk:IUnknown):HResult; Function GetObjectParam(Const pszkey:LPOleStr; out punk: IUnknown):HResult; StdCall; Function EnumObjectParam (out enum:IEnumString):Hresult;StdCall; Function RevokeObjectParam(pszKey:LPOleStr):HResult;StdCall; End; PIMoniker = ^IMoniker; IMoniker = Interface (IPersistStream) ['{0000000f-0000-0000-C000-000000000046}'] Function BindToObject (const pbc:IBindCtx;const mktoleft:IMoniker; RiidResult:TIID;Out vresult):HResult;StdCall; // Function RemoteBindToObject (const pbc:IBindCtx;const mktoleft:IMoniker;RiidResult:TIID;Out vresult):HResult;StdCall; Function BindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall; // Function RemoteBindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall; Function Reduce (const pbc:IBindCtx; dwReduceHowFar:DWord; mktoLeft: PIMoniker; Out mkReduced:IMoniker):HResult; StdCall; Function ComposeWith(Const MkRight:IMoniker;fOnlyIfNotGeneric:BOOL; OUT mkComposite:IMoniker):HResult; StdCall; Function Enum(fForward:Bool;Out enumMoniker:IEnumMoniker):HResult;StdCall; Function IsEqual(Const mkOtherMoniker:IMoniker):HResult;StdCall; Function Hash (Out dwHash:Dword):HResult;StdCall; Function IsRunning(Const bc:IBindCtx;Const MkToLeft:IMoniker;Const mknewlyRunning:IMoniker):HResult;StdCall; Function GetTimeOfLastChange(Const bc:IBindCtx;Const mkToLeft:IMoniker; out ft : FileTime):HResult; StdCall; Function Inverse(out mk : IMoniker):HResult; StdCall; Function CommonPrefixWith (Const mkOther:IMoniker):HResult; StdCall; Function RelativePathTo(Const mkother:IMoniker; Out mkRelPath : IMoniker):HResult;StdCall; Function GetDisplayName(Const bc:IMoniker;const mktoleft:IMoniker;Out szDisplayName: pOleStr):HResult; StdCall; Function ParseDisplayName(Const bc:IBindCtx;Const mkToLeft:IMoniker;szDisplayName:POleStr;out cheaten:ULong;out mkOut:IMoniker):HResult; StdCall; Function IsSystemMonitor(Out dwMkSys:DWord):HResult;StdCall; End; IAdviseSink = Interface (IUnknown) ['{0000010f-0000-0000-C000-000000000046}'] {$ifdef midl500} ['{00000150-0000-0000-C000-000000000046}'] {$endif} Procedure OnDataChange (Const pformatetc : Formatetc;const pstgmed : STGMEDIUM); StdCall; Procedure OnViewChange (dwAspect : DWord; lindex : Long); StdCall; Procedure OnRename (Const pmk : IMoniker); StdCall; Procedure OnSave; StdCall; Procedure OnClose; StdCall; End; //Fake interfaces IDataObject = Interface (IUnknown) ['{0000010e-0000-0000-C000-000000000046}'] Function GetData(Const formatetcIn : FORMATETC;Out medium : STGMEDIUM):HRESULT; STDCALL; Function GetDataHere(CONST pformatetc : FormatETC; Out medium : STGMEDIUM):HRESULT; STDCALL; Function QueryGetData(const pformatetc : FORMATETC):HRESULT; STDCALL; Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; STDCALl; Function SetData (Const pformatetc : FORMATETC;const medium:STGMEDIUM;FRelease : BOOL):HRESULT; StdCall; Function EnumFormatEtc(dwDirection : DWord; OUT enumformatetcpara : IENUMFORMATETC):HRESULT; StdCall; Function DAdvise(const formatetc : FORMATETC;advf :DWORD; CONST AdvSink : IAdviseSink;OUT dwConnection:DWORD):HRESULT;StdCall; Function DUnadvise(dwconnection :DWord) :HRESULT;StdCall; Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;StdCall; End; IDropTarget = interface(IUnknown) ['{00000122-0000-0000-C000-000000000046}'] function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; function DragLeave: HResult;StdCall; function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD):HResult;StdCall; end; IDropSource = interface(IUnknown) ['{00000121-0000-0000-C000-000000000046}'] function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: LongWord):HResult;StdCall; function GiveFeedback(dwEffect: LongWord): HResult;StdCall; end; IDataAdviseHolder = Interface (IUnknown) ['{00000110-0000-0000-C000-000000000046}'] Function Advise (CONST pdataObject : IDataObject;CONST fetc:FORMATETC;advf : DWORD;Const pAdvise:IAdviseSink;Out DwConnection:DWord):HResult; StdCall; Function Unadvise (dwConnection:Dword):HResult; StdCall; Function EnumAdvise(out penumAdvise : IEnumStatData):HResult;StdCall; Function SendOnDataChange(const pDataObject :IDataObject;DwReserved,advf : DWord):HResult; StdCall; End; // OLE drag'n drop support TFormatEtcArray = array of TFormatEtc; TFormatArray = array of Word; // IDataObject.SetData support TInternalStgMedium = packed record Format: TClipFormat; Medium: TStgMedium; end; TInternalStgMediumArray = array of TInternalStgMedium; TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc) private FTree: TObject; FFormatEtcArray: TFormatEtcArray; FCurrentIndex: Integer; public constructor Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray); function Clone(out Enum: IEnumFormatEtc): HResult; stdcall; function Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; stdcall; function Reset: HResult; stdcall; function Skip(celt: LongWord): HResult; stdcall; end; IDropTargetHelper = interface(IUnknown) [SID_IDropTargetHelper] function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function DragLeave: HRESULT; stdcall; function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Show(fShow: Boolean): HRESULT; stdcall; end; PSHDragImage = ^TSHDragImage; TSHDragImage = packed record sizeDragImage: TSize; ptOffset: TPoint; hbmpDragImage: HBITMAP; ColorRef: TColorRef; end; IDragSourceHelper = interface(IUnknown) [SID_IDragSourceHelper] function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall; function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall; end; IVTDragManager = interface(IUnknown) ['{C4B25559-14DA-446B-8901-0C879000EB16}'] procedure ForceDragLeave; stdcall; function GetDataObject: IDataObject; stdcall; function GetDragSource: TObject; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; property DataObject: IDataObject read GetDataObject; property DragSource: TObject read GetDragSource; property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported; property IsDropTarget: Boolean read GetIsDropTarget; end; // This data object is used in two different places. One is for clipboard operations and the other while dragging. TVTDataObject = class(TInterfacedObject, IDataObject) private //FOwner: TBaseVirtualTree; // The tree which provides clipboard or drag data. FOwner: TObject; // The tree which provides clipboard or drag data. FForClipboard: Boolean; // Determines which data to render with GetData. FFormatEtcArray: TFormatEtcArray; FInternalStgMediumArray: TInternalStgMediumArray; // The available formats in the DataObject FAdviseHolder: IDataAdviseHolder; // Reference to an OLE supplied implementation for advising. protected function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; function FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; function FindInternalStgMedium(Format: TClipFormat): PStgMedium; function HGlobalClone(HGlobal: THandle): THandle; function RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; property ForClipboard: Boolean read FForClipboard; property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray; property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray; property Owner: TObject read FOwner; public constructor Create(AOwner: TObject; ForClipboard: Boolean); virtual; destructor Destroy; override; function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; virtual; stdcall; function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall; Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;virtual;StdCall; function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall; Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; virtual; STDCALl; function GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall; function SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall; end; // TVTDragManager is a class to manage drag and drop in a Virtual Treeview. TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget) private FOwner, // The tree which is responsible for drag management. FDragSource: TObject; // Reference to the source tree if the source was a VT, might be different than // the owner tree. FIsDropTarget: Boolean; // True if the owner is currently the drop target. FDataObject: IDataObject; // A reference to the data object passed in by DragEnter (only used when the owner // tree is the current drop target). FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support FFullDragging: BOOL; // True, if full dragging is currently enabled in the system. function GetDataObject: IDataObject; stdcall; function GetDragSource: TObject; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; public constructor Create(AOwner: TObject); virtual; destructor Destroy; override; function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function DragLeave: HResult; stdcall; function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; procedure ForceDragLeave; stdcall; function GiveFeedback(Effect: LongWord): HResult; stdcall; function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall; end; //Ole helper functions function Succeeded(Status : HRESULT) : BOOLEAN; function Failed(Status : HRESULT) : BOOLEAN; //ActiveX functions that have wrong calling convention in fpc function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall; function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall; function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI; function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall; procedure OleUninitialize;stdcall; procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall; function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall; function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall; function OleFlushClipboard:WINOLEAPI;stdcall; function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall; function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall; function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall; //helper functions to isolate windows/OLE specific code function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; function GetStreamFromMedium(Medium:TStgMedium):TStream; procedure UnlockMediumData(Medium:TStgMedium); function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject; function AllocateGlobal(Data: Pointer; DataSize:Cardinal): HGLOBAL; implementation uses VirtualTrees, Controls {$ifdef DEBUG_VTV}, vtlogger{$endif}; type TVirtualTreeAccess = class (TBaseVirtualTree) end; function Succeeded(Status : HRESULT) : BOOLEAN; begin Succeeded:=Status and HRESULT($80000000)=0; end; function Failed(Status : HRESULT) : BOOLEAN; begin Failed:=Status and HRESULT($80000000)<>0; end; function RegisterDragDrop(hwnd: HWND; pDropTarget: IDropTarget): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function RevokeDragDrop(hwnd: HWND): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource; dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleInitialize(pvReserved: LPVOID): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; procedure OleUninitialize; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; procedure ReleaseStgMedium(_para1: LPSTGMEDIUM); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleSetClipboard(pDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleGetClipboard(out ppDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleFlushClipboard: WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function OleIsCurrentClipboard(pDataObj: IDataObject): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function CreateStreamOnHGlobal(hGlobal: HGLOBAL; fDeleteOnRelease: BOOL; out stm: IStream): WINOLEAPI; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function CoCreateInstance(const _para1: TCLSID; _para2: IUnknown; _para3: DWORD; const _para4: TIID; out _para5): HRESULT; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} end; function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; { //--------------- local function -------------------------------------------- procedure WriteNodes(Stream: TStream); var Selection: TNodeArray; I: Integer; begin with TVirtualTreeAccess(Tree) do begin if ForClipboard then Selection := GetSortedCutCopySet(True) else Selection := GetSortedSelection(True); for I := 0 to High(Selection) do WriteNode(Stream, Selection[I]); end; end; //--------------- end local function ---------------------------------------- } var Data: PCardinal; ResPointer: Pointer; ResSize: Integer; OLEStream: IStream; VCLStream: TStream; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { VCLStream := nil; try Medium.PunkForRelease := nil; // Return data in one of the supported storage formats, prefer IStream. if FormatEtcIn.tymed and TYMED_ISTREAM <> 0 then begin // Create an IStream on a memory handle (here it is 0 which indicates to implicitely allocated a handle). // Do not use TStreamAdapter as it is not compatible with OLE (when flushing the clipboard OLE wants the HGlobal // back which is not supported by TStreamAdapater). CreateStreamOnHGlobal(0, True, OLEStream); VCLStream := TOLEStream.Create(OLEStream); WriteNodes(VCLStream); // Rewind stream. VCLStream.Position := 0; Medium.tymed := TYMED_ISTREAM; IUnknown(Medium.Pstm) := OLEStream; Result := S_OK; end else begin VCLStream := TMemoryStream.Create; WriteNodes(VCLStream); ResPointer := TMemoryStream(VCLStream).Memory; ResSize := VCLStream.Position; // Allocate memory to hold the string. if ResSize > 0 then begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, ResSize + SizeOf(Cardinal)); Data := GlobalLock(Medium.hGlobal); // Store the size of the data too, for easy retrival. Data^ := ResSize; Inc(Data); Move(ResPointer^, Data^, ResSize); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Result := S_OK; end else Result := E_FAIL; end; finally // We can free the VCL stream here since it was either a pure memory stream or only a wrapper around // the OLEStream which exists independently. VCLStream.Free; end; } end; type // needed to handle OLE global memory objects TOLEMemoryStream = class(TCustomMemoryStream) public function Write(const Buffer; Count: Integer): Longint; override; end; //---------------------------------------------------------------------------------------------------------------------- function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} // raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError)); end; function GetStreamFromMedium(Medium: TStgMedium): TStream; var Data: Pointer; I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; if Medium.tymed = TYMED_ISTREAM then Result := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream) else begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin // Get the total size of data to retrieve. I := PCardinal(Data)^; Inc(PCardinal(Data)); Result := TOLEMemoryStream.Create; TOLEMemoryStream(Result).SetPointer(Data, I); end; end; } end; procedure UnlockMediumData(Medium: TStgMedium); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Medium.tymed = TYMED_HGLOBAL then GlobalUnlock(Medium.hGlobal); } end; function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject; var Medium: TStgMedium; Data: PVTReference; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; if Assigned(DataObject) then begin Format.cfFormat := CF_VTREFERENCE; if DataObject.GetData(Format, Medium) = S_OK then begin Data := GlobalLock(Medium.hGlobal); if Assigned(Data) then begin if Data.Process = GetCurrentProcessID then Result := Data.Tree; GlobalUnlock(Medium.hGlobal); end; ReleaseStgMedium(@Medium); end; end; } end; function AllocateGlobal(Data: Pointer; DataSize: Cardinal): HGLOBAL; var P:Pointer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize); P := GlobalLock(Result); Move(Data^, P^, DataSize); GlobalUnlock(Result); } end; //---------------------------------------------------------------------------------------------------------------------- // OLE drag and drop support classes // This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs // of DD'ing various kinds of virtual data and works also between applications. //----------------- TEnumFormatEtc ------------------------------------------------------------------------------------- constructor TEnumFormatEtc.Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray); var I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FTree := Tree; // Make a local copy of the format data. SetLength(FFormatEtcArray, Length(AFormatEtcArray)); for I := 0 to High(AFormatEtcArray) do FFormatEtcArray[I] := AFormatEtcArray[I]; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult; var AClone: TEnumFormatEtc; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; try AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray); AClone.FCurrentIndex := FCurrentIndex; Enum := AClone as IEnumFormatEtc; except Result := E_FAIL; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; var CopyCount: LongWord; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_FALSE; CopyCount := Length(FFormatEtcArray) - FCurrentIndex; if celt < CopyCount then CopyCount := celt; if CopyCount > 0 then begin Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc)); Inc(FCurrentIndex, CopyCount); Result := S_OK; end; //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with // a C Program call with a NULL in pCeltFetcjed?? //Answer: Yes. Is necessary a check here if @pceltFetched <> nil then pceltFetched := CopyCount; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Reset: HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { FCurrentIndex := 0; Result := S_OK; } end; //---------------------------------------------------------------------------------------------------------------------- function TEnumFormatEtc.Skip(celt: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FCurrentIndex + celt < High(FFormatEtcArray) then begin Inc(FCurrentIndex, celt); Result := S_Ok; end else Result := S_FALSE; } end; //----------------- TVTDataObject -------------------------------------------------------------------------------------- constructor TVTDataObject.Create(AOwner: TObject; ForClipboard: Boolean); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FOwner := AOwner; FForClipboard := ForClipboard; TVirtualTreeAccess(FOwner).GetNativeClipboardFormats(FFormatEtcArray); } end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDataObject.Destroy; var I: Integer; StgMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // Cancel a pending clipboard operation if this data object was created for the clipboard and // is freed because something else is placed there. if FForClipboard and not (tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates) then TVirtualTreeAccess(FOwner).CancelCutOrCopy; // Release any internal clipboard formats for I := 0 to High(FormatEtcArray) do begin StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat); if Assigned(StgMedium) then ReleaseStgMedium(StgMedium); end; FormatEtcArray := nil; inherited; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; // Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown // interface, will always return the same pointer. begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(TestUnknown) then begin if TestUnknown.QueryInterface(IUnknown, Result) = 0 then Result._Release // Don't actually need it just need the pointer value else Result := TestUnknown end else Result := TestUnknown } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and (FormatEtc1.tymed and FormatEtc2.tymed <> 0); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; var I: integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := -1; for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then begin Result := I; Break; end end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium; var I: integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := nil; for I := 0 to High(InternalStgMediumArray) do begin if Format = InternalStgMediumArray[I].Format then begin Result := @InternalStgMediumArray[I].Medium; Break; end end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle; // Returns a global memory block that is a copy of the passed memory block. var Size: Cardinal; Data, NewData: PChar; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Size := GlobalSize(HGlobal); Result := GlobalAlloc(GPTR, Size); Data := GlobalLock(hGlobal); try NewData := GlobalLock(Result); try Move(Data^, NewData^, Size); finally GlobalUnLock(Result); end finally GlobalUnLock(hGlobal); end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; // Tries to render one of the formats which have been stored via the SetData method. // Since this data is already there it is just copied or its reference count is increased (depending on storage medium). var InternalMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := True; InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat); if Assigned(InternalMedium) then OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject) else Result := False; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; // InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or // increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually // the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData. // If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during // that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make // copy of the data for the caller only to have them destroy it then need us to copy it again if necessary. // This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData. // This way when the caller frees the structure it sees the unkForRelease is not nil and calls Release on the object // instead of destroying the actual data. var Len: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; // Simply copy all fields to start with. OutStgMedium := InStgMedium; // The data handled here always results from a call of SetData we got. This ensures only one storage format // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several // storage formats). case InStgMedium.tymed of TYMED_HGLOBAL: begin if CopyInMedium then begin // Generate a unique copy of the data passed OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal); if OutStgMedium.hGlobal = 0 then Result := E_OUTOFMEMORY end else // Don't generate a copy just use ourselves and the copy previously saved. OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount. end; TYMED_FILE: begin //todo_lcl_check Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character. OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len); Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len); end; TYMED_ISTREAM: IUnknown(OutStgMedium.Pstm)._AddRef; TYMED_ISTORAGE: IUnknown(OutStgMedium.Pstg)._AddRef; TYMED_GDI: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy GDI objects right now. TYMED_MFPICT: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now. TYMED_ENHMF: if not CopyInMedium then // Don't generate a copy just use ourselves and the previously saved data. OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount. else Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now. else Result := DV_E_TYMED; end; if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then IUnknown(OutStgMedium.PunkForRelease)._AddRef; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; // Advise sink management is greatly simplified by the IDataAdviseHolder interface. // We use this interface and forward all concerning calls to it. begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := S_OK; if FAdviseHolder = nil then Result := CreateDataAdviseHolder(FAdviseHolder); if Result = S_OK then Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.DUnadvise(dwConnection: DWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FAdviseHolder = nil then Result := E_NOTIMPL else Result := FAdviseHolder.Unadvise(dwConnection); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumDAvise(Out enumAdvise : IEnumStatData):HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if FAdviseHolder = nil then Result := OLE_E_ADVISENOTSUPPORTED else Result := FAdviseHolder.EnumAdvise(enumAdvise); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; var NewList: TEnumFormatEtc; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := E_FAIL; if Direction = DATADIR_GET then begin NewList := TEnumFormatEtc.Create(TVirtualTreeAccess(FOwner), FormatEtcArray); EnumFormatEtc := NewList as IEnumFormatEtc; Result := S_OK; end else EnumFormatEtc := nil; if EnumFormatEtc = nil then Result := OLE_S_USEREG; } end; //---------------------------------------------------------------------------------------------------------------------- Function TVTDataObject.GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := DATA_S_SAMEFORMATETC; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; // Data is requested by clipboard or drop target. This method dispatchs the call // depending on the data being requested. var I: Integer; Data: PVTReference; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} // The tree reference format is always supported and returned from here. { if FormatEtcIn.cfFormat = CF_VTREFERENCE then begin // Note: this format is not used while flushing the clipboard to avoid a dangling reference // when the owner tree is destroyed before the clipboard data is replaced with something else. if tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates then Result := E_FAIL else begin Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference)); Data := GlobalLock(Medium.hGlobal); Data.Process := GetCurrentProcessID; Data.Tree := TBaseVirtualTree(FOwner); GlobalUnlock(Medium.hGlobal); Medium.tymed := TYMED_HGLOBAL; Medium.PunkForRelease := nil; Result := S_OK; end; end else begin try // See if we accept this type and if not get the correct return value. Result := QueryGetData(FormatEtcIn); if Result = S_OK then begin for I := 0 to High(FormatEtcArray) do begin if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then begin if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then Result := TVirtualTreeAccess(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard); Break; end; end end except FillChar(Medium, SizeOf(Medium), #0); Result := E_FAIL; end; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := E_NOTIMPL; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult; var I: Integer; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { Result := DV_E_CLIPFORMAT; for I := 0 to High(FFormatEtcArray) do begin if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then begin if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then begin if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then begin if FormatEtc.lindex = FFormatEtcArray[I].lindex then begin Result := S_OK; Break; end else Result := DV_E_LINDEX; end else Result := DV_E_DVASPECT; end else Result := DV_E_TYMED; end; end } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDataObject.SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; // Allows dynamic adding to the IDataObject during its existance. Most noteably it is used to implement // IDropSourceHelper and allows to set a special format for optimized moves during a shell transfer. var Index: Integer; LocalStgMedium: PStgMedium; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // See if we already have a format of that type available. Index := FindFormatEtc(FormatEtc, FormatEtcArray); if Index > - 1 then begin // Just use the TFormatEct in the array after releasing the data. LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat); if Assigned(LocalStgMedium) then begin ReleaseStgMedium(LocalStgMedium); FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; end else begin // It is a new format so create a new TFormatCollectionItem, copy the // FormatEtc parameter into the new object and and put it in the list. SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1); FormatEtcArray[High(FormatEtcArray)] := FormatEtc; // Create a new InternalStgMedium and initialize it and associate it with the format. SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1); InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat; LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium; FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0); end; if DoRelease then begin // We are simply being given the data and we take control of it. LocalStgMedium^ := Medium; Result := S_OK end else begin // We need to reference count or copy the data and keep our own references to it. Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject); // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium. // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN. if Assigned(LocalStgMedium.PunkForRelease) then begin if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface end; end; // Tell all registered advice sinks about the data change. if Assigned(FAdviseHolder) then FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0); } end; //----------------- TVTDragManager ------------------------------------------------------------------------------------- constructor TVTDragManager.Create(AOwner: TObject); begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { inherited Create; FOwner := AOwner; // Create an instance of the drop target helper interface. This will fail but not harm on systems which do // not support this interface (everything below Windows 2000); CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper); } end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDragManager.Destroy; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // Set the owner's reference to us to nil otherwise it will access an invalid pointer // after our desctruction is complete. TVirtualTreeAccess(FOwner).FreeDragManager; inherited; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDataObject: IDataObject; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem. // In this case there is no local reference to a data object and one is created (but not stored). // If there is a local reference then the owner tree is currently the drop target and the stored interface is // that of the drag initiator. if Assigned(FDataObject) then Result := FDataObject else begin Result := TVirtualTreeAccess(FOwner).DoCreateDataObject; if Result = nil then Result := TVTDataObject.Create(FOwner, False) as IDataObject; end; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDragSource: TObject; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := FDragSource; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetDropTargetHelperSupported: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := Assigned(FDropTargetHelper); end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GetIsDropTarget: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := FIsDropTarget; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { FDataObject := DataObject; FIsDropTarget := True; SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0); // If full dragging of window contents is disabled in the system then our tree windows will be locked // and cannot be updated during a drag operation. With the following call painting is again enabled. if not FFullDragging then LockWindowUpdate(0); if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragEnter(TBaseVirtualTree(FOwner).Handle, DataObject, Pt, Effect); FDragSource := TVirtualTreeAccess(FOwner).GetTreeFromDataObject(DataObject); Result := TVirtualTreeAccess(FOwner).DragEnter(KeyState, Pt, Effect); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragLeave: HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; TVirtualTreeAccess(FOwner).DragLeave; FIsDropTarget := False; FDragSource := nil; FDataObject := nil; Result := NOERROR; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragOver(Pt, Effect); Result := TVirtualTreeAccess(FOwner).DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect); } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.Drop(DataObject, Pt, Effect); Result := TVirtualTreeAccess(FOwner).DragDrop(DataObject, KeyState, Pt, Effect); FIsDropTarget := False; FDataObject := nil; } end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragManager.ForceDragLeave; // Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive // a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from // screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE). begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { if Assigned(FDropTargetHelper) and FFullDragging then FDropTargetHelper.DragLeave; } end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.GiveFeedback(Effect: LongWord): HResult; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} //Result := DRAGDROP_S_USEDEFAULTCURSORS; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; var RButton, LButton: Boolean; begin {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif} { LButton := (KeyState and MK_LBUTTON) <> 0; RButton := (KeyState and MK_RBUTTON) <> 0; // Drag'n drop canceled by pressing both mouse buttons or Esc? if (LButton and RButton) or EscapePressed then Result := DRAGDROP_S_CANCEL else // Drag'n drop finished? if not (LButton or RButton) then Result := DRAGDROP_S_DROP else Result := S_OK; } end; end. doublecmd-0.8.2/components/virtualtreeview/units/carbon/fakeactivex.pas0000664000175000017500000000005412014201074025526 0ustar alexxalexxunit FakeActiveX; {$i ../dummyactivex.inc} doublecmd-0.8.2/components/virtualtreeview/units/carbon/fakemmsystem.pas0000664000175000017500000000065012014201074025743 0ustar alexxalexxunit fakemmsystem; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Types; function timeBeginPeriod(x1: DWord): DWord; function timeEndPeriod(x1: DWord): DWord; function timeGetTime: DWORD; implementation uses LCLIntf; function timeBeginPeriod(x1: DWord): DWord; begin end; function timeEndPeriod(x1: DWord): DWord; begin end; function timeGetTime: DWORD; begin Result := GetTickCount; end; end. doublecmd-0.8.2/components/virtualtreeview/vtlogger.pas0000664000175000017500000000335612014201074022467 0ustar alexxalexxunit vtlogger; {$mode objfpc}{$H+} interface uses multiloglcl, multilog; const //lc stands for LogClass //it's possible to define the constants to suit any need lcAll = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]; lcDebug = 0; lcError = 1; lcInfo = 2; lcWarning = 3; lcEvents = 4; lcPaint = 5; lcPaintHeader = 6; lcDummyFunctions = 7; lcMessages = 8; lcPaintSelection = 9; lcSetCursor = 10;//it generates a lot of messages. so it will be debugged alone lcPaintBitmap = 11; lcScroll = 12; lcPaintDetails = 13; lcCheck = 14; lcEditLink = 15; lcEraseBkgnd = 16; lcColumnPosition = 17; lcTimer = 18; lcDrag = 19; lcOle = 20; lcPanning = 21; lcHeaderOffset = 22; lcSelection = 23; lcAlphaBlend = 24; lcHint = 25; lcMouseEvent = 26; var Logger: TLCLLogger; function GetSelectedNodes(Sender: TLogger; Data: Pointer; var DoSend: Boolean): String; implementation uses VirtualTrees, sysutils; type TNodeData = record Title: String; end; PNodeData = ^TNodeData; function GetSelectedNodes(Sender: TLogger; Data: Pointer; var DoSend: Boolean): String; var i: Integer; TempNode: PVirtualNode; begin with TBaseVirtualTree(Data) do begin Result:='SelectedCount: '+IntToStr(SelectedCount)+LineEnding; TempNode:=GetFirstSelected; if TempNode = nil then exit; Result:=Result+PNodeData(GetNodeData(TempNode))^.Title+LineEnding; for i:= 1 to SelectedCount -1 do begin TempNode:=GetNextSelected(TempNode); Result:=Result+PNodeData(GetNodeData(TempNode))^.Title+LineEnding; end; end; end; initialization Logger:=TLCLLogger.Create; finalization Logger.Free; end. doublecmd-0.8.2/components/virtualtreeview/virtualtreeview_package_doublecmd.pas0000664000175000017500000000075412014201074027567 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit virtualtreeview_package_doublecmd; interface uses VirtualTrees, VTHeaderPopup, registervirtualtreeview, VTGraphics, LazarusPackageIntf; implementation procedure Register; begin RegisterUnit('registervirtualtreeview', @registervirtualtreeview.Register); end; initialization RegisterPackage('virtualtreeview_package_doublecmd', @Register); end. doublecmd-0.8.2/components/virtualtreeview/VTGraphics.pas0000664000175000017500000000151612140233030022641 0ustar alexxalexxunit VTGraphics; {$mode delphi} interface uses DelphiCompat, Types, LCLIntf, LCLType; type // Describes the mode how to blend pixels. TBlendMode = ( bmConstantAlpha, // apply given constant alpha bmPerPixelAlpha, // use alpha value of the source pixel bmMasterAlpha, // use alpha value of source pixel and multiply it with the constant alpha value bmConstantAlphaAndColor // blend the destination color with the given constant color und the constant alpha value ); procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer); function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer; function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer; implementation {$i vtgraphicsi.inc} end. doublecmd-0.8.2/components/virtualtreeview/registervirtualtreeview.pas0000664000175000017500000000117212014201074025636 0ustar alexxalexxunit registervirtualtreeview; {$Mode ObjFpc} {$H+} interface uses Classes, SysUtils, LResources, LazarusPackageIntf, VirtualTrees, VTHeaderPopup; procedure Register; implementation procedure RegisterUnitVirtualTrees; begin RegisterComponents('Virtual Controls', [TVirtualDrawTree, TVirtualStringTree]); end; procedure RegisterUnitVTHeaderPopup; begin RegisterComponents('Virtual Controls', [TVTHeaderPopupMenu]); end; procedure Register; begin RegisterUnit('VirtualTrees', @RegisterUnitVirtualTrees); RegisterUnit('VTHeaderPopup', @RegisterUnitVTHeaderPopup); end; initialization {$i ideicons.lrs} end. doublecmd-0.8.2/components/virtualtreeview/virtualtreeview_package.pas0000664000175000017500000000073512014201074025550 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit virtualtreeview_package; interface uses VirtualTrees, VTHeaderPopup, registervirtualtreeview, VTGraphics, LazarusPackageIntf; implementation procedure Register; begin RegisterUnit('registervirtualtreeview', @registervirtualtreeview.Register); end; initialization RegisterPackage('virtualtreeview_package', @Register); end. doublecmd-0.8.2/components/virtualtreeview/lclfunctions.inc0000664000175000017500000000671312014201074023327 0ustar alexxalexx//Used in DrawTextW { function GetTextAlign(DC: HDC): UINT; begin Logger.AddCheckPoint(lcDummyFunctions,'GetTextAlign'); Result:=TA_TOP or TA_LEFT; end; } //Used in DrawTextW, ShortenString, TVirtualTreeColumn.ComputeHeaderLayout, TVirtualTreeColumns.DrawButtonText, // TVTEdit.AutoAdjustSize, TCustomVirtualStringTree.PaintNormalText, TCustomVirtualStringTree.WMSetFont // TCustomVirtualStringTree.DoTextMeasuring { function GetTextExtentPoint32W(DC: HDC; Str: PWideChar; Count: Integer; var Size: TSize): Boolean; var TempStr: String; begin Logger.AddCheckPoint(lcDummyFunctions,'GetTextExtentPoint32W'); TempStr:=WideCharToString(Str); Result:=GetTextExtentPoint(DC, PChar(TempStr), Length(TempStr), Size); end; } //Used in DrawTextW { function ExtTextOutW(DC: HDC; X, Y: Integer; Options: LongInt; Rect: PRect; Str: PWideChar; Count: LongInt; Dx: PInteger): Boolean; var TempStr: String; begin Logger.AddCheckPoint(lcDummyFunctions,'ExtTextOutW'); TempStr:=WideCharToString(Str); Result:= ExtTextOut(DC, X, Y, Options, Rect, PChar(TempStr), Length(TempStr), Dx); end; } //Used in TVirtualTreeHintWindow.CalcHintRect, TVirtualTreeColumn.ComputeHeaderLayout // TBaseVirtualTree.CollectSelectedNodesRTL, TBaseVirtualTree.DetermineHitPositionRTL // TBaseVirtualTree.UpdateEditBounds, TBaseVirtualTree.GetDisplayRect, PaintTree, // TStringEditLink.PrepareEdit, TCustomVirtualStringTree.ComputeNodeHeight etc function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints; cPoints: UINT): Integer; var I:Integer; XOffset, YOffset: SmallInt; FromRect,ToRect: TRect; begin GetWindowRect(hWndFrom,FromRect); GetWindowRect(hWndTo,ToRect); XOffset:=(FromRect.Left - ToRect.Left); YOffset:=(FromRect.Top - ToRect.Top); for i:=0 to cPoints - 1 do begin { Mode Delphi does not support treating a pointer as a array if ObjFpc is used than this syntax is preferred PPoint(@lpPoints)[i].x:= XOffset + PPoint(@lpPoints)[i].x; PPoint(@lpPoints)[i].y:= YOffset + PPoint(@lpPoints)[i].y; } PPoint(@lpPoints+i)^.x:= XOffset + PPoint(@lpPoints+i)^.x; PPoint(@lpPoints+i)^.y:= YOffset + PPoint(@lpPoints+i)^.y; end; Result:=MakeLong(XOffset,YOffset); end; {$ifndef UseExternalDragManager} function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall;external 'ole32.dll' name 'RegisterDragDrop'; function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall;external 'ole32.dll' name 'RevokeDragDrop'; function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI;stdcall;external 'ole32.dll' name 'DoDragDrop'; function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleInitialize'; procedure OleUninitialize;stdcall;external 'ole32.dll' name 'OleUninitialize'; procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall;external 'ole32.dll' name 'ReleaseStgMedium'; function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleSetClipboard'; function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleGetClipboard'; function OleFlushClipboard:WINOLEAPI;stdcall;external 'ole32.dll' name 'OleFlushClipboard'; function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleIsCurrentClipboard'; function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall;external 'ole32.dll' name 'CreateStreamOnHGlobal'; {$endif} doublecmd-0.8.2/components/virtualtreeview/VirtualTrees.pas0000664000175000017500000445764313161144471023322 0ustar alexxalexxunit VirtualTrees; {$mode delphi}{$H+} {$packset 1} // Version 4.8.7 // // The contents of this file are subject to the Mozilla Public License // Version 1.1 (the "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ // // Alternatively, you may redistribute this library, use and/or modify it under the terms of the // GNU Lesser General Public License as published by the Free Software Foundation; // either version 2.1 of the License, or (at your option) any later version. // You may obtain a copy of the LGPL at http://www.gnu.org/copyleft/. // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the // specific language governing rights and limitations under the License. // // The original code is VirtualTrees.pas, released September 30, 2000. // // The initial developer of the original code is digital publishing AG (Munich, Germany, www.digitalpublishing.de), // written by Mike Lischke (public@soft-gems.net, www.soft-gems.net). // // Portions created by digital publishing AG are Copyright // (C) 1999-2001 digital publishing AG. All Rights Reserved. //---------------------------------------------------------------------------------------------------------------------- // // April 2010 // - Bug fix: Removed active column changing from TBaseVirtualTree.WMKeyDown to re-gain standard conforming // behaviour for VK_NEXT and VK_PRIOR // - Bug fix: Paint option toUseExplorerTheme works properly without defining columns // - Bug fix: TBaseVirtualTree.PrepareBitmaps now correctly closes the theme handle // January 2010 // - Bug fix: TBaseVirtualTree.AdjustTotalHeight now longer calculates wrong total heights if nodes have been // made invisible // - Bug fix: TCustomVirtualStringTree.OnMeasureTextWidth now works as intended // - Bug fix: Added missing $IFDEFs concerning theming support // - Bug fix: Removed default from properties TVirtualTreeColumn.Color and TVirtualTreeColumn.BiDiMode // July 2009 // - Bug fix: TWorkerThread will no longer reference the tree after it has been destroyed (Mantis issue #384) // - Bug fix: TBaseVirtualTree.InternalConnectNode checked the expanded state of the wrong node if Mode was // amAddChildFirst or amAddChildLast // June 2009 // - Bug fix: fixed some issues concerning the vista theme handling // - Improvement: removed hidden node handling in this branch // - Improvement: reverted header click handling to old version to keep compatibility in this branch // - Improvement: removed TVTPaintOption toHideTreeLinesIfThemed // May 2009 // - Improvement: new TVTMiscOption toEditOnClick, toEditOnDblClick to control if editing can be started with a single // click or a double click // - Bug fix: the internal pointers of TBufferedAnsiString are now PAnsiChar to work correctly with Delphi 2009 // April 2009 // - Bug fix: TBaseVirtualTree.GetVisibleParent no longer returns the given node in case it is fully visible // - Improvement: fixed a potential issue in TVirtualTreeColumns.TotalWidth in case it is called before // FPositionToIndex is initialized // - Bug fix: TBaseVirtualTree.CollectSelectedNodesLTR and TBaseVirtualTree.CollectSelectedNodesRTL handle straight // vertical selection rectangles no longer as empty // - Bug fix: TCheckImageKind.ckSystemDefault now works as intended // - Improvement: made the following methods of TBaseVirtualTree virtual: PrepareCell, AddChild, BeginUpdate, // EndUpdate and SortTree // - Improvement: made TBaseVirtualTree.PrepareCell protected // - Improvement: moved some members of TVTEdit and TStringEditLink from private to protected // - Improvement: re-designed header click handling // - Improvement: new TVTPaintOption toShowHiddenNodes to globally ignore the hidden state of nodes // - Improvement: individual nodes can now be hidden without affecting their children // - Improvement: re-designed Explorer theme drawing // - Bug fix: corrected allocation problems in TBufferedAnsiString and TWideBufferedString // March 2009 // - Bug fix: fixed an issue in TVirtualTreeColumns.HandleClick that could lead to a case where no header click event // is triggered // - Bug fix: fixed an issue in TBaseVirtualTree.HandleHotTrack that could lead to an endless loop under certain // conditions // - Improvement: removed unused variables in TVirtualTreeColumn.ComputeHeaderLayout // - Bug fix: corrected TBaseVirtualTree.GetVisibleParent // - Improvement: extended hot node tracking to track the hot column too // - Improvement: new THitPosition hiOnItemButtonExact used to draw hot buttons when using Windows Vista's Explorer // theme // - Improvement: new TVTPaintOption toHideTreeLinesIfThemed to consider toShowTreeLines only if running unthemed // - Improvement: new TVTPaintOption toUseExplorerTheme to draw the tree like Windows Vista's Explorer treeview // February 2009 // - Bug fix: reverted the implementation of DrawTextW back to the one prior to 4.8.1 as the line end detection // lead to a compiler warning under Delphi 2009 // - Bug fix: corrected implementation of GetStringDrawRect to match its declaration (UnicodeString vs WideString) // - Bug fix: the node focus will no longer change if a TVTMiscOption.toGridExtensions is set and one clicks right of // (or left of, if right-to-left reading) the last column // - Bug fix: fixed an issue with TVTHeader.Assign that could lead to an access violation if the header is created at // runtime // - Bug fix: one can no longer change a node's height with the right mouse button even if toNodeHeightResize and // toRightClickSelect are set // - Improvement: TVTAutoOption.toDisableAutoScrollOnFocus now works for nodes too // - Improvement: new property TBaseVirtualTree.SelectionLocked to disable changing the selection // - Improvement: made the dual-scroll effect in TBaseVirtualTree.ToggleNode much smoother // - Bug fix: removed off-by-1 errors in TBaseVirtualTree.ToggleNode // - Bug fix: added a check for FUpdateCount to TBaseVirtualTree.SetUpdateState as otherwise every call to // TBaseVirtualTree.DoBeforeCellPaint to get the cell content margin within an Begin/EndUpdate-block would // re-enable painting // - Bug fix: TVTHeader.HandleMessage could provide a wrong column index to OnBeforeColumnWidthTracking in some cases // - Improvement: new properties TBaseVirtualTree.OnBeforeAutoFitColumn, TBaseVirtualTree.OnAfterAutoFitColumn // - Improvement: new procedures TBaseVirtualTree.CancelOperation, TBaseVirtualTree.BeginOperation, // TBaseVirtualTree.EndOperation and new property TBaseVirtualTree.OperationCanceled to enable the // application to stop (possibly) long-running operations // - Improvement: integrated changes from Andreas Hausladen // - Improvement: integrated changes from Dmitry Zegebart where applicable // - Bug fix: removed off-by-1 error in TBaseVirtualTree.GetDisplayRect // - Bug fix: changed the size of the buffer used in TBaseVirtualTree.PaintTree to paint the area below the last node // as the bitmap was not completely erased using previous size under certain conditions // - Bug fix: fixed TBaseVirtualTree.GetPreviousLevel // January 2009 // - Bug fix: removed off-by-1 error in TBaseVirtualTree.GetBottomNode // - Improvement: improved speed of TBaseVirtualTree.GetMaxColumnWidth when using UseSmartColumnWidth // - Version is now 4.8.0 // December 2008 // - Bug fix: modified TBaseVirtualTree.UpdateHorizontalScrollbar and TBaseVirtualTree.UpdateVerticalScrollbar to // recalculate the tree's dimensions even if an update is in progress // - Improvement: renamed TVTHeaderState hsTracking and hsTrackPending to hsColumnWidthTracking and // hsColumnWidthTrackPending // - Improvement: modified TBaseVirtualTree.GetFirstVisible and TBaseVirtualTree.GetFirstVisibleNoInit to optionally // take a node to specify where to start // - Improvement: modified TVTAfterGetMaxColumnWidthEvent to make the result of TBaseVirtualTree.GetMaxColumnWidth // changable // - Bug fix: corrected TBaseVirtualTree.GetMaxColumnWidth to consider toFixedIndent and no longer take nodes into // account that are just above or below the visible area // - Improvement: new property TVirtualTreeColumns.DefaultWidth // - Improvement: new property TVTHeader.FixedAreaConstraints (new class TVTFixedAreaConstraints) to limit the // fixed area (header, fixed columns) to a percentage of the client area // November 2008 // - Improvement: new cursor added: crVertSplit used for height tracking // - Improvement: changed type of TVTHeader.Height from Cardinal to Integer to make boundary checks easier // - Improvement: new properties TVTHeader.MinHeight and TVTHeader.MaxHeight // - Improvement: new VirtualTreeStates tsNodeHeightTracking and tsNodeHeightTrackPending // - Improvement: new HeaderStates hsHeightTracking and hsHeightTrackPending // - Improvement: new TVTMiscOption toNodeHeightResize to allow changing node heights via mouse // - Improvement: new TVTHeaderOption hoHeightResize to allow changing header height via mouse // - Improvement: new properties TBaseVirtualTree.OnHeaderHeightTracking, TBaseVirtualTree.OnHeaderDblClickResize, // TBaseVirtualTree.OnColumnWidthTracking, TBaseVirtualTree.OnColumnWidthDblClickResize, // TBaseVirtualTree.OnNodeHeightTracking, TBaseVirtualTree.OnNodeHeightDblClickResize // - Improvement: new function TVTHeader.ResizeColumns to resize multiple columns at once // - Improvement: TVTHeader.DetermineSplitterIndex is no longer influenced by non-resizable columns // - Bug fix: TBaseVirtualTree.ToggleNode now uses DoStateChange to modify FStates // - Bug fix: TBaseVirtualTree.DoBeforeCellPaint now saves the update rect if CellPaintMode is cpmGetContentMargin // and restores it afterwards // - Improvement: modified TBaseVirtualTree.CmMouseWheel to handle mice with wheel delta < 120 correctly // - Improvement: modified TVTHeader.LoadFromStream and WriteToStream to save ParentFont // - Improvement: TVTHeader.Font is now only stored by Delphi if ParentFont is False (Mantis issue #217) // - Bug fix: corrected TVTHeader.Create to set TVTHeader.FOptions correctly to the default value (Mantis issue #333) // - Improvement: new TVTAnimationOption toAdvancedAnimatedToggle to scroll the node to be toggled animatedly instead // of just scroll its child nodes animatedly // - Improvement: added VirtualTreeState tsToggling to eliminate artefacts caused by TBaseVirtualTree.DoSetOffsetXY // while toggling // - Bug fix: corrected button handling when toFixedIndent is set // - Improvement: redesigned TBaseVirtualTree.ToggleNode to harmonize the visual toggle behaviour independent of // toChildrenAbove // - Improvement: made TBaseVirtualTree.CanEdit public // - Improvement: added parameter ConsiderChildrenAbove to TGetNextNodeProc // - Improvement: modified all variants of TBaseVirtualTree.GetFirst and TBaseVirtualTree.GetLast to optionally // consider toChildrenAbove // October 2008 // - Bugfix: removed 'FVisibleCount := 0' from TBaseVirtualTree.Clear as this would lead to incorrect VisibleCount in // read-only mode // - Bugfix: fixed a condition in TBaseVirtualTree.ToggleCallback that could lead to artefacts // - Improvement: changed the implementation of TBaseVirtualTree.GetNext/GetPrevious so that no penalties occur if // toChildrenAbove is not set // - Improvement: TBaseVirtualTree.ToggleNode will no longer leave nodes with state vsToggeling if an exception // occurs // - Improvement: improved behaviour of TBaseVirtualTree.ToggleNode in case toChildrenAbove is set // - Bug fix: corrected TBaseVirtualTree.ScrollIntoView to behave as expected when no fixed columns exist // - Bug fix: extended TBaseVirtualTree.InitializeLineImageAndSelectLevel to eliminate artifacts while scrolling with // toChildrenAbove set // - Bug fix: corrected CompareNodePositions to consider toChildrenAbove // - Bug fix: corrected ToggleNode to scroll correctly if toChildrenAbove and toAnimatedToggle are set // - Improvement: new TVTPaintOption toFixedIndent to draw the tree with a fixed ident (instead of node level // dependent indents) // - Improvement: new TVTPaintOption toChildrenAbove to draw children nodes above their parent // August 2008 // - Improvement: redesigned and overloaded TBaseVirtualTree.ScrollIntoView in order to use vertical scrolling // separately // - Improvement: optimized TBaseVirtualTree.ScrollIntoView for horizontal scrolling // - Improvement: in TBaseVirtualTree.WMKeyDown column navigation for VK_PRIOR and VK_NEXT is now handled in same way // as row navigation // - Improvement: new TVTHeaderOption hoDisableAnimatedResize to disable animated resize for all columns // - Improvement: new TVTColumnOption coDisableAnimatedResize to disable animated resize for a specific column // - Improvement: in TBaseVirtualTree.UpdateHorizontalScrollBar and TBaseVirtualTree.UpdateVerticalScrollBar scrollbar // updates now avoided for tsUpdating in FStates // July 2008 // - Improvement: in TBaseVirtualTree.WMHScroll the horizontal page scrolling now considers fixed columns // - Improvement: in TBaseVirtualTree.ScrollIntoView the case of FFocusedColumn being invalid is considered // - Improvement: in TBaseVirtualTree.HandleMouseDown DoFocusNode is not called if node focus did not change // - Improvement: in TBaseVirtualTree.SetFocusedColumn the focused node will only be invalidate if it was actually // scrolled into view // - Improvement: new TVTColumnOption coAllowFocus to affect column focus behaviour // - Improvement: new function TVTHeader.AllowFocus to check wether a column can be focused // - Improvement: in TBaseVirtualTree.SetFocusedColumn the old colunm and the new column are both invalidated // - Improvement: merged latest changes from Jim into current code base. // June 2008 // - Improvement: new property TVirtualTreeColumns.Count // - Bug fix: in TVirtualTreeColumns.AnimatedResize the column is validated (to avoid "List index out of bounds") // - Improvement: the content retangle of the cell can be modified via the OnBeforeCellPaint event, the cell paint // mode indicates wether OnBeforeCellPaint is called for painting the cell or just for getting the // cell content margin // - Improvement: new functions added: TBaseVirtualTree.DoGetCellContentMargins, // TCustomVirtualDrawTree.DoGetCellContentMargin // - Improvement: new property: TCustomVirtualDrawTree.OnGetCellContentMargin // - Improvement: in TBaseVirtualTree.GetMaxColumnWidth the cell content margin is considered // - Improvement: in TBaseVirtualTree.CMHintShow the cell content margin is considered for singleline tooltips // - Improvement: new function added: TVTHeader.DoGetPopupMenu (to query the application via TreeView.FOnGetPopupMenu // for a column specific header popup menu) // - Improvement: new property added: TBaseVirtualTree.OnCanSplitterResizeColumn, // new function added: TVirtualTreeColumns.GetScrollWidth // - Improvement: horizontal page scrolling now uses the average column width (of all visible, non-fixed columns) as // scroll amount // - Improvement: procedure TBaseVirtualTree.CMMouseWheel redesigned // - Bug fix: TVTHeader.DetermineSplitterIndex works correctly even when using fixed columns // - Bug fix: on right-to-left BiDiMode TVirtualTreeColumns.PaintHeader respects (left) scroll bar correctly // - Bug fix: for multiline tooltips also the column width is checked to determine the tooltip is needed or // unnecessary // - Improvement: the result value of GetUseSmartColumnWidth is initialized correctly // - Improvement: added hoFullRepaintOnResize to TVTHeaderOption to enable full header repainting (instead of // repainting all subsequent columns only) on resizing a column // - Bug fix: horizontal page scrolling via mouse wheel now works correctly, i.e. in TBaseVirtualTree.CMMouseWheel // ScrollCount includes GetVisibleFixedWidth and FIndent // - Improvement: new TVTColumnOption coSmartResize to avoid contradicting the virtual paradigm // - Improvement: horizontal scrolling via mouse wheel can be forced by holding the shift key // - Improvement: new parameter for function TBaseVirtualTree.GetMaxColumnWidth added: UseSmartColumnWidth (to // avoid contradicting the virtual paradigm, i.e. leave nodes out of consideration which are not in // view) // - Improvement: new parameters for TVTHeader.AutoFitColumns added: SmartAutoFitType, RangeStartCol and // RangeEndCol // - Improvement: new parameters for events FOUnknownnAfterAutoFitColumns, FOnBeforeAutoFitColumns, FOnAfterGetMaxColumnWidth // and FOnBeforeGetMaxColumnWidth added // - Version is now 4.6.0 // May 2008 // - Improvement: new properties: FOnAfterAutoFitColumns, FOnBeforeAutoFitColumns, FOnAfterGetMaxColumnWidth and // FOnBeforeGetMaxColumnWidth // - Bug fix: FDropTargetNode is considered in TBaseVirtualTree.DoFreeNode // August 2007 // - for accessibility, added an OnGetImageText event that can be used to give accessible text to images used in nodes. // - Implemented an ImageText property used by the VTAccessibility unit to retrieve text for a given node and its column. // - Switched loading of accessibility libraries to dynamic from static to avoid problems in Win95 // June 2007 // - Bug fix: Fixed a problem with potentially large amount of nodes (larger than 2 billion) in // TBaseVirtualTree.SetChildCount. // - Bug fix: remove hint if any in case the tree loses the focus. // - Improvement: TVirtualTreeColumns.HandleClick is now virtual, introduced TVTHeader.DoSetSortColumn. // - Bug fix: compiler error due to old variable reference when enabling flat scrollbars. // May 2007 // - Improvement: new functions: GetPreviousSelected, GetPreviousChecked, GetCheckedCount, // GetPreviousCutCopy, GetCutCopyCount, GetFirstLeaf, GetNextLeaf, // GetPreviousLeaf, GetFirstLevel, GetNextLevel, GetPreviousLevel // - Improvement: new properties: CheckedCount, CutCopyCount // - Improvement: DoFocusChanging for finding a valid column (TBaseVirtualTree.WMKeyDown) // March 2007 // - Improvement: adjusted accessibility implementation to compile with pre-BDS IDEs. // - If a column is not visible, MultiColumnAccessibility now will not include it. // January 2007 // - Improvement: added code donation from Marco Zehe (with help from Sebastian Modersohn) which implements the // MS accessibility interface for Virtual Treeview. // December 2006 // - Improvement: bidi mode implementation finished (toAutoBidiColumnOrdering introduced) // - Change: right-to-left flag removed from shorten string methods/events (not necessary) // - Version is now 4.5.0 // November 2006 // - Bug fix: Total height is wrong on reading from stream // September 2006 // - Bug fix: Mantis issue #326 // July 2006 // - Change: value for crHeaderSplit cursor conflicts with other resource IDs, so I changed it. // - Published OnStartDrag in VirtualDrawTree. // April 2006 // - Bug fix: check for MMX availabiltiy is missing in some places before calling MMX code // - Bug fix: flag for VCL dragging was removed too late causing all kind of problems with mouse up code in VCL drag mode. // - Bug fix: If the past mode in ProcessOLEData is amInsertAfter then nodes where inserted in the wrong order. // March 2006 // - Bug fix: total count and total height is wrong after loading from stream // - Bug fix: variable node height computation // - Bug fix: FLastChangedNode was not reset in DoFreeNode // February 2006 // - Improvement: GetFirstChecked now also has a default value for its state parameter. // - Improvement: avoid potential reentrancy problems in paint code by checking for the paint state there. // January 2006 // - Bug fix: disabled images are now drawn like enabled ones (with respect to position, indices etc.). // - Improvement: New property BottomSpace, allows to specify an additional area below the last node in the tree. // - Bug fix: VT.EndUpdate did not invalidate the cache so the cache was never used again after that. // - Improvement: tree states for double clicks (left, middle, right). // December 2005 // - Bug fix: check for column index for auto setting main column if the current one is deleted. // // For full document history see help file. // // Credits for their valuable assistance and code donations go to: // Freddy Ertl, Marian Aldenh?vel, Thomas Bogenrieder, Jim Kuenemann, Werner Lehmann, Jens Treichler, // Paul Gallagher (IBO tree), Ondrej Kelle, Ronaldo Melo Ferraz, Heri Bender, Roland Bed?rftig (BCB) // Anthony Mills, Alexander Egorushkin (BCB), Mathias Torell (BCB), Frank van den Bergh, Vadim Sedulin, Peter Evans, // Milan Vandrovec (BCB), Steve Moss, Joe White, David Clark, Anders Thomsen, Igor Afanasyev, Eugene Programmer, // Corbin Dunn, Richard Pringle, Uli Gerhardt, Azza, Igor Savkic, Daniel Bauten, Timo Tegtmeier, Dmitry Zegebart, // Andreas Hausladen // Beta testers: // Freddy Ertl, Hans-J?rgen Schnorrenberg, Werner Lehmann, Jim Kueneman, Vadim Sedulin, Moritz Franckenstein, // Wim van der Vegt, Franc v/d Westelaken // Indirect contribution (via publicly accessible work of those persons): // Alex Denissov, Hiroyuki Hori (MMXAsm expert) // Documentation: // Markus Spoettl and toolsfactory GbR (http://www.doc-o-matic.com/, sponsoring Soft Gems development // with a free copy of the Doc-O-Matic help authoring system), Sven H. (Step by step tutorial) // CLX: // Dmitri Dmitrienko (initial developer) // Source repository: // Subversion (server), TortoiseSVN (client tools), Fisheye (Web interface) // Accessability implementation: // Marco Zehe (with help from Sebastian Modersohn) // LCL Port: // Luiz Am?rico Pereira C?mara //---------------------------------------------------------------------------------------------------------------------- interface {$I VTConfig.inc} uses {$ifdef Windows} Windows, ActiveX, CommCtrl, {$else} FakeActiveX, {$endif} OleUtils, LCLIntf, {$ifdef USE_DELPHICOMPAT} DelphiCompat, LclExt, {$endif} virtualpanningwindow, VTGraphics, //alpha blend functions {$ifdef DEBUG_VTV} vtlogger, {$endif} LCLType, LResources, LMessages, Types, SysUtils, Classes, Graphics, Controls, Forms, ImgList, StdCtrls, Menus, Printers, SyncObjs, // Thread support Clipbrd // Clipboard support {$ifdef ThemeSupport} , Themes , TmSchema {$endif ThemeSupport} {$ifdef EnableAccessible} , oleacc // for MSAA IAccessible support {$endif}; const {$I lclconstants.inc} {$if defined(LCLGtk) or defined(LCLGtk2)} {$define Gtk} {$endif} {$if defined(Gtk)} {$define ManualClipNeeded} {$endif} {$if defined(LCLGtk2) or defined(LCLCarbon) or defined(LCLQt)} {$define ContextMenuBeforeMouseUp} {$endif} VTMajorVersion = 4; VTMinorVersion = 8; VTReleaseVersion = 7; VTTreeStreamVersion = 2; VTHeaderStreamVersion = 6; // The header needs an own stream version to indicate changes only relevant to the header. CacheThreshold = 2000; // Number of nodes a tree must at least have to start caching and at the same // time the maximum number of nodes between two cache entries. FadeAnimationStepCount = 255; // Number of animation steps for hint fading (0..255). ShadowSize = 5; // Size in pixels of the hint shadow. This value has no influence on Win2K and XP systems // as those OSes have native shadow support. // Special identifiers for columns. NoColumn = -1; InvalidColumn = -2; // Indices for check state images used for checking. ckEmpty = 0; // an empty image used as place holder // radio buttons ckRadioUncheckedNormal = 1; ckRadioUncheckedHot = 2; ckRadioUncheckedPressed = 3; ckRadioUncheckedDisabled = 4; ckRadioCheckedNormal = 5; ckRadioCheckedHot = 6; ckRadioCheckedPressed = 7; ckRadioCheckedDisabled = 8; // check boxes ckCheckUncheckedNormal = 9; ckCheckUncheckedHot = 10; ckCheckUncheckedPressed = 11; ckCheckUncheckedDisabled = 12; ckCheckCheckedNormal = 13; ckCheckCheckedHot = 14; ckCheckCheckedPressed = 15; ckCheckCheckedDisabled = 16; ckCheckMixedNormal = 17; ckCheckMixedHot = 18; ckCheckMixedPressed = 19; ckCheckMixedDisabled = 20; // simple button ckButtonNormal = 21; ckButtonHot = 22; ckButtonPressed = 23; ckButtonDisabled = 24; // Instead using a TTimer class for each of the various events I use Windows timers with messages // as this is more economical. ExpandTimer = 1; EditTimer = 2; ScrollTimer = 4; ChangeTimer = 5; StructureChangeTimer = 6; SearchTimer = 7; // Need to use this message to release the edit link interface asynchronously. WM_CHANGESTATE = WM_APP + 32; // Virtual Treeview does not need to be subclassed by an eventual Theme Manager instance as it handles // Windows XP theme painting itself. Hence the special message is used to prevent subclassing. CM_DENYSUBCLASSING = CM_BASE + 2000; // Decoupling message for auto-adjusting the internal edit window. CM_AUTOADJUST = CM_BASE + 2005; // VT's own clipboard formats, // Note: The reference format is used internally to allow to link to a tree reference // to implement optimized moves and other back references. CFSTR_VIRTUALTREE = 'Virtual Tree Data'; CFSTR_VTREFERENCE = 'Virtual Tree Reference'; CFSTR_HTML = 'HTML Format'; CFSTR_RTF = 'Rich Text Format'; CFSTR_RTFNOOBJS = 'Rich Text Format Without Objects'; CFSTR_CSV = 'CSV'; // Drag image helpers for Windows 2000 and up. IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0)); IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46)); CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0)); SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}'; SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}'; SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}'; // Help identifiers for exceptions. Application developers are responsible to link them with actual help topics. hcTFEditLinkIsNil = 2000; hcTFWrongMoveError = 2001; hcTFWrongStreamFormat = 2002; hcTFWrongStreamVersion = 2003; hcTFStreamTooSmall = 2004; hcTFCorruptStream1 = 2005; hcTFCorruptStream2 = 2006; hcTFClipboardFailed = 2007; hcTFCannotSetUserData = 2008; // Header standard split cursor. crHeaderSplit = TCursor(63); // Height changing cursor. crVertSplit = TCursor(62); //Panning Cursors crVT_MOVEALL = TCursor(64); crVT_MOVEEW = TCursor(65); crVT_MOVENS = TCursor(66); crVT_MOVENW = TCursor(67); crVT_MOVESW = TCursor(68); crVT_MOVENE = TCursor(69); crVT_MOVESE = TCursor(70); crVT_MOVEW = TCursor(71); crVT_MOVEE = TCursor(72); crVT_MOVEN = TCursor(73); crVT_MOVES = TCursor(74); UtilityImageSize = 16; // Needed by descendants for hittests. {$if defined(LCLCarbon) or defined(LCLCocoa)} ssCtrlOS = ssMeta; // Mac OS X fix {$else} ssCtrlOS = ssCtrl; {$endif} var // Clipboard format IDs used in OLE drag'n drop and clipboard transfers. CF_VIRTUALTREE, CF_VTREFERENCE, CF_VRTF, CF_VRTFNOOBJS, // Unfortunately CF_RTF* is already defined as being // registration strings so I have to use different identifiers. CF_HTML, CF_CSV: Word; MMXAvailable: Boolean; // necessary to know because the blend code uses MMX instructions IsWinNT: Boolean; // Necessary to fix bugs in Win95/WinME (non-client area region intersection, edit resize) // and to allow for check of system dependent hint animation. IsWinVistaOrAbove: Boolean; type // The exception used by the trees. EVirtualTreeError = class(Exception); // Limits the speed interval which can be used for auto scrolling (milliseconds). TAutoScrollInterval = 1..1000; // Need to declare the correct WMNCPaint record as the VCL (D5-) doesn't. TRealWMNCPaint = packed record Msg: Cardinal; Rgn: HRGN; lParam: Integer; Result: Integer; end; // Be careful when adding new states as this might change the size of the type which in turn // changes the alignment in the node record as well as the stream chunks. // Do not reorder the states and always add new states at the end of this enumeration in order to avoid // breaking existing code. TVirtualNodeState = ( vsInitialized, // Set after the node has been initialized. vsChecking, // Node's check state is changing, avoid propagation. vsCutOrCopy, // Node is selected as cut or copy and paste source. vsDisabled, // Set if node is disabled. vsDeleting, // Set when the node is about to be freed. vsExpanded, // Set if the node is expanded. vsHasChildren, // Indicates the presence of child nodes without actually setting them. vsVisible, // Indicate whether the node is visible or not (independent of the expand states of its parents). vsSelected, // Set if the node is in the current selection. vsInitialUserData, // Set if (via AddChild or InsertNode) initial user data has been set which requires OnFreeNode. vsAllChildrenHidden, // Set if vsHasChildren is set and no child node has the vsVisible flag set. vsClearing, // A node's children are being deleted. Don't register structure change event. vsMultiline, // Node text is wrapped at the cell boundaries instead of being shorted. vsHeightMeasured, // Node height has been determined and does not need a recalculation. vsToggling // Set when a node is expanded/collapsed to prevent recursive calls. ); TVirtualNodeStates = set of TVirtualNodeState; // States used in InitNode to indicate states a node shall initially have. TVirtualNodeInitState = ( ivsDisabled, ivsExpanded, ivsHasChildren, ivsMultiline, ivsSelected ); TVirtualNodeInitStates = set of TVirtualNodeInitState; TVTScrollBarStyle = ( sbmRegular, sbmFlat, sbm3D ); // Options per column. TVTColumnOption = ( coAllowClick, // Column can be clicked (must be enabled too). coDraggable, // Column can be dragged. coEnabled, // Column is enabled. coParentBidiMode, // Column uses the parent's bidi mode. coParentColor, // Column uses the parent's background color. coResizable, // Column can be resized. coShowDropMark, // Column shows the drop mark if it is currently the drop target. coVisible, // Column is shown. coAutoSpring, // Column takes part in the auto spring feature of the header (must be resizable too). coFixed, // Column is fixed and can not be selected or scrolled etc. coSmartResize, // Column is resized to its largest entry which is in view (instead of its largest // visible entry). coAllowFocus, // Column can be focused. coDisableAnimatedResize, // Column resizing is not animated. coWrapCaption, // Caption could be wrapped across several header lines to fit columns width. coUseCaptionAlignment // Column's caption has its own aligment. ); TVTColumnOptions = set of TVTColumnOption; // These flags are used to indicate where a click in the header happened. TVTHeaderHitPosition = ( hhiNoWhere, // No column is involved (possible only if the tree is smaller than the client area). hhiOnColumn, // On a column. hhiOnIcon, // On the bitmap associated with a column. hhiOnCheckbox // On the checkbox if enabled. ); TVTHeaderHitPositions = set of TVTHeaderHitPosition; // These flags are returned by the hit test method. THitPosition = ( hiAbove, // above the client area (if relative) or the absolute tree area hiBelow, // below the client area (if relative) or the absolute tree area hiNowhere, // no node is involved (possible only if the tree is not as tall as the client area) hiOnItem, // on the bitmaps/buttons or label associated with an item hiOnItemButton, // on the button associated with an item hiOnItemButtonExact, // exactly on the button associated with an item hiOnItemCheckbox, // on the checkbox if enabled hiOnItemIndent, // in the indentation area in front of a node hiOnItemLabel, // on the normal text area associated with an item hiOnItemLeft, // in the area to the left of a node's text area (e.g. when right aligned or centered) hiOnItemRight, // in the area to the right of a node's text area (e.g. if left aligned or centered) hiOnNormalIcon, // on the "normal" image hiOnStateIcon, // on the state image hiToLeft, // to the left of the client area (if relative) or the absolute tree area hiToRight, // to the right of the client area (if relative) or the absolute tree area hiUpperSplitter, // in the upper splitter area of a node hiLowerSplitter // in the lower splitter area of a node ); THitPositions = set of THitPosition; TCheckType = ( ctNone, ctTriStateCheckBox, ctCheckBox, ctRadioButton, ctButton ); // The check states include both, transient and fluent (temporary) states. The only temporary state defined so // far is the pressed state. TCheckState = ( csUncheckedNormal, // unchecked and not pressed csUncheckedPressed, // unchecked and pressed csCheckedNormal, // checked and not pressed csCheckedPressed, // checked and pressed csMixedNormal, // 3-state check box and not pressed csMixedPressed // 3-state check box and pressed ); TCheckImageKind = ( ckLightCheck, // gray cross ckDarkCheck, // black cross ckLightTick, // gray tick mark ckDarkTick, // black tick mark ckFlat, // flat images (no 3D border) ckXP, // Windows XP style ckCustom, // application defined check images ckSystemFlat, // Flat system defined check images. ckSystemDefault // Uses the system check images, theme aware. ); // mode to describe a move action TVTNodeAttachMode = ( amNoWhere, // just for simplified tests, means to ignore the Add/Insert command amInsertBefore, // insert node just before destination (as sibling of destination) amInsertAfter, // insert node just after destionation (as sibling of destination) amAddChildFirst, // add node as first child of destination amAddChildLast // add node as last child of destination ); // modes to determine drop position further TDropMode = ( dmNowhere, dmAbove, dmOnNode, dmBelow ); // operations basically allowed during drag'n drop TDragOperation = ( doCopy, doMove, doLink ); TDragOperations = set of TDragOperation; TVTImageKind = ( ikNormal, ikSelected, ikState, ikOverlay ); TVTHintMode = ( hmDefault, // show the hint of the control hmHint, // show node specific hint string returned by the application hmHintAndDefault, // same as hmHint but show the control's hint if no node is concerned hmTooltip // show the text of the node if it isn't already fully shown ); // Indicates how to format a tooltip. TVTTooltipLineBreakStyle = ( hlbDefault, // Use multi-line style of the node. hlbForceSingleLine, // Use single line hint. hlbForceMultiLine // Use multi line hint. ); TMouseButtons = set of TMouseButton; // Used to describe the action to do when using the OnBeforeItemErase event. TItemEraseAction = ( eaColor, // Use the provided color to erase the background instead the one of the tree. eaDefault, // The tree should erase the item's background (bitmap or solid). eaNone // Do nothing. Let the application paint the background. ); // There is a heap of switchable behavior in the tree. Since published properties may never exceed 4 bytes, // which limits sets to at most 32 members, and because for better overview tree options are splitted // in various sub-options and are held in a commom options class. // // Options to customize tree appearance: TVTPaintOption = ( toHideFocusRect, // Avoid drawing the dotted rectangle around the currently focused node. toHideSelection, // Selected nodes are drawn as unselected nodes if the tree is unfocused. toHotTrack, // Track which node is under the mouse cursor. toPopupMode, // Paint tree as would it always have the focus (useful for tree combo boxes etc.) toShowBackground, // Use the background image if there's one. toShowButtons, // Display collapse/expand buttons left to a node. toShowDropmark, // Show the dropmark during drag'n drop operations. toShowHorzGridLines, // Display horizontal lines to simulate a grid. toShowRoot, // Show lines also at top level (does not show the hidden/internal root node). toShowTreeLines, // Display tree lines to show hierarchy of nodes. toShowVertGridLines, // Display vertical lines (depending on columns) to simulate a grid. toThemeAware, // Draw UI elements (header, tree buttons etc.) according to the current theme if // enabled (Windows XP+ only, application must be themed). toUseBlendedImages, // Enable alpha blending for ghosted nodes or those which are being cut/copied. toGhostedIfUnfocused, // Ghosted images are still shown as ghosted if unfocused (otherwise the become non-ghosted // images). toFullVertGridLines, // Display vertical lines over the full client area, not only the space occupied by nodes. // This option only has an effect if toShowVertGridLines is enabled too. toAlwaysHideSelection, // Do not draw node selection, regardless of focused state. toUseBlendedSelection, // Enable alpha blending for node selections. toStaticBackground, // Show simple static background instead of a tiled one. toChildrenAbove, // Display child nodes above their parent. toFixedIndent, // Draw the tree with a fixed indent. toUseExplorerTheme // Use the explorer theme if run under Windows Vista (or above). ); TVTPaintOptions = set of TVTPaintOption; // Options to toggle animation support: TVTAnimationOption = ( toAnimatedToggle, // Expanding and collapsing a node is animated (quick window scroll). toAdvancedAnimatedToggle // Do some advanced animation effects when toggling a node. ); TVTAnimationOptions = set of TVTAnimationOption; // Options which toggle automatic handling of certain situations: TVTAutoOption = ( toAutoDropExpand, // Expand node if it is the drop target for more than a certain time. toAutoExpand, // Nodes are expanded (collapsed) when getting (losing) the focus. toAutoScroll, // Scroll if mouse is near the border while dragging or selecting. toAutoScrollOnExpand, // Scroll as many child nodes in view as possible after expanding a node. toAutoSort, // Sort tree when Header.SortColumn or Header.SortDirection change or sort node if // child nodes are added. toAutoSpanColumns, // Large entries continue into next column(s) if there's no text in them (no clipping). toAutoTristateTracking, // Checkstates are automatically propagated for tri state check boxes. toAutoHideButtons, // Node buttons are hidden when there are child nodes, but all are invisible. toAutoDeleteMovedNodes, // Delete nodes which where moved in a drag operation (if not directed otherwise). toDisableAutoscrollOnFocus, // Disable scrolling a node or column into view if it gets focused. toDisableAutoscrollHorizontal, // Only autoscroll on focus vertically never horizontally toAutoChangeScale, // Change default node height automatically if the system's font scale is set to big fonts. toAutoFreeOnCollapse, // Frees any child node after a node has been collapsed (HasChildren flag stays there). toDisableAutoscrollOnEdit, // Do not center a node horizontally when it is edited. toAutoBidiColumnOrdering // When set then columns (if any exist) will be reordered from lowest index to highest index // and vice versa when the tree's bidi mode is changed. ); TVTAutoOptions = set of TVTAutoOption; // Options which determine the tree's behavior when selecting nodes: TVTSelectionOption = ( toDisableDrawSelection, // Prevent user from selecting with the selection rectangle in multiselect mode. toExtendedFocus, // Entries other than in the main column can be selected, edited etc. toFullRowSelect, // Hit test as well as selection highlight are not constrained to the text of a node. toLevelSelectConstraint, // Constrain selection to the same level as the selection anchor. toMiddleClickSelect, // Allow selection, dragging etc. with the middle mouse button. This and toWheelPanning // are mutual exclusive. toMultiSelect, // Allow more than one node to be selected. toRightClickSelect, // Allow selection, dragging etc. with the right mouse button. toSiblingSelectConstraint, // Constrain selection to nodes with same parent. toCenterScrollIntoView, // Center nodes vertically in the client area when scrolling into view. toSimpleDrawSelection // Simplifies draw selection, so a node's caption does not need to intersect with the // selection rectangle. ); TVTSelectionOptions = set of TVTSelectionOption; // Options which do not fit into any of the other groups: TVTMiscOption = ( toAcceptOLEDrop, // Register tree as OLE accepting drop target toCheckSupport, // Show checkboxes/radio buttons. toEditable, // Node captions can be edited. toFullRepaintOnResize, // Fully invalidate the tree when its window is resized (CS_HREDRAW/CS_VREDRAW). toGridExtensions, // Use some special enhancements to simulate and support grid behavior. toInitOnSave, // Initialize nodes when saving a tree to a stream. toReportMode, // Tree behaves like TListView in report mode. toToggleOnDblClick, // Toggle node expansion state when it is double clicked. toWheelPanning, // Support for mouse panning (wheel mice only). This option and toMiddleClickSelect are // mutal exclusive, where panning has precedence. toReadOnly, // The tree does not allow to be modified in any way. No action is executed and // node editing is not possible. toVariableNodeHeight, // When set then GetNodeHeight will trigger OnMeasureItem to allow variable node heights. toFullRowDrag, // Start node dragging by clicking anywhere in it instead only on the caption or image. // Must be used together with toDisableDrawSelection. toNodeHeightResize, // Allows changing a node's height via mouse. toNodeHeightDblClickResize, // Allows to reset a node's height to FDefaultNodeHeight via a double click. toEditOnClick, // Editing mode can be entered with a single click toEditOnDblClick // Editing mode can be entered with a double click ); TVTMiscOptions = set of TVTMiscOption; // Options to control data export TVTExportMode = ( emAll, // export all records (regardless checked state) emChecked, // export checked records only emUnchecked // export unchecked records only ); const DefaultPaintOptions = [toShowButtons, toShowDropmark, toShowTreeLines, toShowRoot, toThemeAware, toUseBlendedImages]; DefaultAnimationOptions = []; DefaultAutoOptions = [toAutoDropExpand, toAutoTristateTracking, toAutoScrollOnExpand, toAutoDeleteMovedNodes]; DefaultSelectionOptions = []; DefaultMiscOptions = [toAcceptOLEDrop, toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning, toEditOnClick]; DefaultColumnOptions = [coAllowClick, coDraggable, coEnabled, coParentColor, coParentBidiMode, coResizable, coShowDropmark, coVisible, coAllowFocus]; type TBaseVirtualTree = class; TVirtualTreeClass = class of TBaseVirtualTree; PVirtualNode = ^TVirtualNode; TColumnIndex = type Integer; TColumnPosition = type Cardinal; // This record must already be defined here and not later because otherwise BCB users will not be able // to compile (conversion done by BCB is wrong). TCacheEntry = record Node: PVirtualNode; AbsoluteTop: Cardinal; end; TCache = array of TCacheEntry; TNodeArray = array of PVirtualNode; TCustomVirtualTreeOptions = class(TPersistent) private FOwner: TBaseVirtualTree; FPaintOptions: TVTPaintOptions; FAnimationOptions: TVTAnimationOptions; FAutoOptions: TVTAutoOptions; FSelectionOptions: TVTSelectionOptions; FMiscOptions: TVTMiscOptions; FExportMode: TVTExportMode; procedure SetAnimationOptions(const Value: TVTAnimationOptions); procedure SetAutoOptions(const Value: TVTAutoOptions); procedure SetMiscOptions(const Value: TVTMiscOptions); procedure SetPaintOptions(const Value: TVTPaintOptions); procedure SetSelectionOptions(const Value: TVTSelectionOptions); protected property AnimationOptions: TVTAnimationOptions read FAnimationOptions write SetAnimationOptions default DefaultAnimationOptions; property AutoOptions: TVTAutoOptions read FAutoOptions write SetAutoOptions default DefaultAutoOptions; property ExportMode: TVTExportMode read FExportMode write FExportMode default emAll; property MiscOptions: TVTMiscOptions read FMiscOptions write SetMiscOptions default DefaultMiscOptions; property PaintOptions: TVTPaintOptions read FPaintOptions write SetPaintOptions default DefaultPaintOptions; property SelectionOptions: TVTSelectionOptions read FSelectionOptions write SetSelectionOptions default DefaultSelectionOptions; public constructor Create(AOwner: TBaseVirtualTree); virtual; procedure AssignTo(Dest: TPersistent); override; property Owner: TBaseVirtualTree read FOwner; end; TTreeOptionsClass = class of TCustomVirtualTreeOptions; TVirtualTreeOptions = class(TCustomVirtualTreeOptions) published property AnimationOptions; property AutoOptions; property ExportMode; property MiscOptions; property PaintOptions; property SelectionOptions; end; // Used in the CF_VTREFERENCE clipboard format. PVTReference = ^TVTReference; TVTReference = record Process: Cardinal; Tree: TBaseVirtualTree; end; TVirtualNode = record Index, // index of node with regard to its parent ChildCount: Cardinal; // number of child nodes NodeHeight: Word; // height in pixels States: TVirtualNodeStates; // states describing various properties of the node (expanded, initialized etc.) Align: Byte; // line/button alignment CheckState: TCheckState; // indicates the current check state (e.g. checked, pressed etc.) CheckType: TCheckType; // indicates which check type shall be used for this node Dummy: Byte; // dummy value to fill DWORD boundary TotalCount, // sum of this node, all of its child nodes and their child nodes etc. TotalHeight: Cardinal; // height in pixels this node covers on screen including the height of all of its // children // Note: Some copy routines require that all pointers (as well as the data area) in a node are // located at the end of the node! Hence if you want to add new member fields (except pointers to internal // data) then put them before field Parent. Parent, // reference to the node's parent (for the root this contains the treeview) PrevSibling, // link to the node's previous sibling or nil if it is the first node NextSibling, // link to the node's next sibling or nil if it is the last node FirstChild, // link to the node's first child... LastChild: PVirtualNode; // link to the node's last child... Data: record end; // this is a placeholder, each node gets extra data determined by NodeDataSize end; // Structure used when info about a certain position in the tree is needed. THitInfo = record HitNode: PVirtualNode; HitPositions: THitPositions; HitColumn: TColumnIndex; end; // auto scroll directions TScrollDirections = set of ( sdLeft, sdUp, sdRight, sdDown ); // OLE drag'n drop support TFormatEtcArray = array of TFormatEtc; TFormatArray = array of Word; // IDataObject.SetData support TInternalStgMedium = packed record Format: TClipFormat; Medium: TStgMedium; end; TInternalStgMediumArray = array of TInternalStgMedium; TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc) private FTree: TBaseVirtualTree; FFormatEtcArray: TFormatEtcArray; FCurrentIndex: Integer; public constructor Create(Tree: TBaseVirtualTree; AFormatEtcArray: TFormatEtcArray); function Clone(out Enum: IEnumFormatEtc): HResult; stdcall; function Next(celt: LongWord; out elt: FormatEtc;pceltFetched:pULong=nil): HResult; stdcall; function Reset: HResult; stdcall; function Skip(celt: LongWord): HResult; stdcall; end; // ----- OLE drag'n drop handling IDropTargetHelper = interface(IUnknown) [SID_IDropTargetHelper] function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function DragLeave: HRESULT; stdcall; function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall; function Show(fShow: Boolean): HRESULT; stdcall; end; PSHDragImage = ^TSHDragImage; TSHDragImage = packed record sizeDragImage: TSize; ptOffset: TPoint; hbmpDragImage: HBITMAP; ColorRef: TColorRef; end; IDragSourceHelper = interface(IUnknown) [SID_IDragSourceHelper] function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall; function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall; end; IVTDragManager = interface(IUnknown) ['{C4B25559-14DA-446B-8901-0C879000EB16}'] procedure ForceDragLeave; stdcall; function GetDataObject: IDataObject; stdcall; function GetDragSource: TBaseVirtualTree; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; property DataObject: IDataObject read GetDataObject; property DragSource: TBaseVirtualTree read GetDragSource; property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported; property IsDropTarget: Boolean read GetIsDropTarget; end; // This data object is used in two different places. One is for clipboard operations and the other while dragging. TVTDataObject = class(TInterfacedObject, IDataObject) private FOwner: TBaseVirtualTree; // The tree which provides clipboard or drag data. FForClipboard: Boolean; // Determines which data to render with GetData. FFormatEtcArray: TFormatEtcArray; FInternalStgMediumArray: TInternalStgMediumArray; // The available formats in the DataObject FAdviseHolder: IDataAdviseHolder; // Reference to an OLE supplied implementation for advising. protected function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown; function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean; function FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer; function FindInternalStgMedium(Format: TClipFormat): PStgMedium; function HGlobalClone(HGlobal: THandle): THandle; function RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var OLEResult: HResult): Boolean; function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium; CopyInMedium: Boolean; DataObject: IDataObject): HRESULT; property ForClipboard: Boolean read FForClipboard; property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray; property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray; property Owner: TBaseVirtualTree read FOwner; public constructor Create(AOwner: TBaseVirtualTree; ForClipboard: Boolean); virtual; destructor Destroy; override; function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord): HResult; virtual; stdcall; function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall; Function EnumDAdvise(out enumAdvise : IEnumStatData):HResult;virtual;StdCall; function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall; function GetCanonicalFormatEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; virtual; STDCALl; function GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult; virtual; stdcall; function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall; function SetData(const FormatEtc: TFormatEtc; const Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall; end; // TVTDragManager is a class to manage drag and drop in a Virtual Treeview. TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget) private FOwner, // The tree which is responsible for drag management. FDragSource: TBaseVirtualTree; // Reference to the source tree if the source was a VT, might be different than // the owner tree. FIsDropTarget: Boolean; // True if the owner is currently the drop target. FDataObject: IDataObject; // A reference to the data object passed in by DragEnter (only used when the owner // tree is the current drop target). FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support FFullDragging: BOOL; // True, if full dragging is currently enabled in the system. function GetDataObject: IDataObject; stdcall; function GetDragSource: TBaseVirtualTree; stdcall; function GetDropTargetHelperSupported: Boolean; stdcall; function GetIsDropTarget: Boolean; stdcall; public constructor Create(AOwner: TBaseVirtualTree); virtual; destructor Destroy; override; function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function DragLeave: HResult; stdcall; function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall; procedure ForceDragLeave; stdcall; {$IF (FPC_FULLVERSION < 020601) and DEFINED(LCLWin32)} function GiveFeedback(Effect: Longint): HResult; stdcall; function QueryContinueDrag(EscapePressed: BOOL; KeyState: Longint): HResult; stdcall; {$ELSE} function GiveFeedback(Effect: LongWord): HResult; stdcall; function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall; {$ENDIF} end; PVTHintData = ^TVTHintData; TVTHintData = record Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; HintRect: TRect; // used for draw trees only, string trees get the size from the hint string DefaultHint: String; // used only if there is no node specific hint string available // or a header hint is about to appear HintText: String; // set when size of the hint window is calculated HintInfo: PHintInfo; end; // The trees need an own hint window class because of Unicode output and adjusted font. { TVirtualTreeHintWindow } TVirtualTreeHintWindow = class(THintWindow) private FHintData: TVTHintData; procedure WMShowWindow(var Message: TLMShowWindow); message LM_SHOWWINDOW; public function CalcHintRect(MaxWidth: Integer; const AHint: string; AData: Pointer): TRect; override; procedure Paint; override; end; // Drag image support for the tree. TVTTransparency = 0..255; TVTBias = -128..127; // Simple move limitation for the drag image. TVTDragMoveRestriction = ( dmrNone, dmrHorizontalOnly, dmrVerticalOnly ); TVTDragImageStates = set of ( disHidden, // Internal drag image is currently hidden (always hidden if drag image helper interfaces are used). disInDrag, // Drag image class is currently being used. disPrepared, // Drag image class is prepared. disSystemSupport // Running on Windows 2000 or higher. System supports drag images natively. ); // Class to manage header and tree drag image during a drag'n drop operation. TVTDragImage = class private FOwner: TBaseVirtualTree; FBackImage, // backup of overwritten screen area FAlphaImage, // target for alpha blending FDragImage: TBitmap; // the actual drag image to blend to screen FImagePosition, // position of image (upper left corner) in screen coordinates FLastPosition: TPoint; // last mouse position in screen coordinates FTransparency: TVTTransparency; // alpha value of the drag image (0 - fully transparent, 255 - fully opaque) FPreBlendBias, // value to darken or lighten the drag image before it is blended FPostBlendBias: TVTBias; // value to darken or lighten the alpha blend result FFade: Boolean; // determines whether to fade the drag image from center to borders or not FRestriction: TVTDragMoveRestriction; // determines in which directions the drag image can be moved FColorKey: TColor; // color to make fully transparent regardless of any other setting FStates: TVTDragImageStates; // Determines the states of the drag image class. function GetVisible: Boolean; // True if the drag image is currently hidden (used only when dragging) protected procedure InternalShowDragImage(ScreenDC: HDC); procedure MakeAlphaChannel(Source, Target: TBitmap); public constructor Create(AOwner: TBaseVirtualTree); destructor Destroy; override; function DragTo(const P: TPoint; ForceRepaint: Boolean): Boolean; procedure EndDrag; function GetDragImageRect: TRect; procedure HideDragImage; procedure PrepareDrag(DragImage: TBitmap; const ImagePosition, HotSpot: TPoint; const DataObject: IDataObject); procedure RecaptureBackground(Tree: TBaseVirtualTree; R: TRect; VisibleRegion: HRGN; CaptureNCArea, ReshowDragImage: Boolean); procedure ShowDragImage; function WillMove(const P: TPoint): Boolean; property ColorKey: TColor read FColorKey write FColorKey default clWindow; property Fade: Boolean read FFade write FFade default False; property MoveRestriction: TVTDragMoveRestriction read FRestriction write FRestriction default dmrNone; property PostBlendBias: TVTBias read FPostBlendBias write FPostBlendBias default 0; property PreBlendBias: TVTBias read FPreBlendBias write FPreBlendBias default 0; property Transparency: TVTTransparency read FTransparency write FTransparency default 128; property Visible: Boolean read GetVisible; end; // tree columns implementation TVirtualTreeColumns = class; TVTHeader = class; TVirtualTreeColumnStyle = ( vsText, vsOwnerDraw ); TVTHeaderColumnLayout = ( blGlyphLeft, blGlyphRight, blGlyphTop, blGlyphBottom ); TVirtualTreeColumn = class(TCollectionItem) private FText, FHint: String; FLeft, FWidth: Integer; FPosition: TColumnPosition; FMinWidth: Integer; FMaxWidth: Integer; FStyle: TVirtualTreeColumnStyle; FImageIndex: TImageIndex; FBiDiMode: TBiDiMode; FLayout: TVTHeaderColumnLayout; FMargin, FSpacing: Integer; FOptions: TVTColumnOptions; FTag: Integer; FAlignment: TAlignment; FCaptionAlignment: TAlignment; // Alignment of the caption. FLastWidth: Integer; FColor: TColor; FBonusPixel: Boolean; FSpringRest: Single; // Accumulator for width adjustment when auto spring option is enabled. FCaptionText: String; FCheckBox: Boolean; FCheckType: TCheckType; FCheckState: TCheckState; FImageRect: TRect; FHasImage: Boolean; function GetCaptionAlignment: TAlignment; function GetLeft: Integer; function IsBiDiModeStored: Boolean; function IsCaptionAlignmentStored: Boolean; function IsColorStored: Boolean; procedure SetAlignment(const Value: TAlignment); procedure SetBiDiMode(Value: TBiDiMode); procedure SetCaptionAlignment(const Value: TAlignment); procedure SetCheckBox(Value: Boolean); procedure SetCheckState(Value: TCheckState); procedure SetCheckType(Value: TCheckType); procedure SetColor(const Value: TColor); procedure SetImageIndex(Value: TImageIndex); procedure SetLayout(Value: TVTHeaderColumnLayout); procedure SetMargin(Value: Integer); procedure SetMaxWidth(Value: Integer); procedure SetMinWidth(Value: Integer); procedure SetOptions(Value: TVTColumnOptions); procedure SetPosition(Value: TColumnPosition); procedure SetSpacing(Value: Integer); procedure SetStyle(Value: TVirtualTreeColumnStyle); procedure SetText(const Value: String); procedure SetWidth(Value: Integer); protected procedure ComputeHeaderLayout(DC: HDC; const Client: TRect; UseHeaderGlyph, UseSortGlyph: Boolean; var HeaderGlyphPos, SortGlyphPos: TPoint; var TextBounds: TRect; DrawFormat: Cardinal; CalculateTextRect: Boolean = False); procedure GetAbsoluteBounds(var Left, Right: Integer); function GetDisplayName: string; override; function GetOwner: TVirtualTreeColumns; reintroduce; public constructor Create(Collection: TCollection); override; destructor Destroy; override; procedure Assign(Source: TPersistent); override; function Equals(OtherColumnObj: TObject): Boolean; virtual; function GetRect: TRect; virtual; procedure LoadFromStream(const Stream: TStream; Version: Integer); procedure ParentBiDiModeChanged; procedure ParentColorChanged; procedure RestoreLastWidth; procedure SaveToStream(const Stream: TStream); function UseRightToLeftReading: Boolean; property Left: Integer read GetLeft; property Owner: TVirtualTreeColumns read GetOwner; published property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify; property BiDiMode: TBiDiMode read FBiDiMode write SetBiDiMode stored IsBiDiModeStored default bdLeftToRight; property CaptionAlignment: TAlignment read GetCaptionAlignment write SetCaptionAlignment stored IsCaptionAlignmentStored default taLeftJustify; property CaptionText: String read FCaptionText stored False; property CheckType: TCheckType read FCheckType write SetCheckType default ctCheckBox; property CheckState: TCheckState read FCheckState write SetCheckState default csUncheckedNormal; property CheckBox: Boolean read FCheckBox write SetCheckBox default False; property Color: TColor read FColor write SetColor stored IsColorStored; property Hint: String read FHint write FHint; property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1; property Layout: TVTHeaderColumnLayout read FLayout write SetLayout default blGlyphLeft; property Margin: Integer read FMargin write SetMargin default 4; property MaxWidth: Integer read FMaxWidth write SetMaxWidth default 10000; property MinWidth: Integer read FMinWidth write SetMinWidth default 10; property Options: TVTColumnOptions read FOptions write SetOptions default DefaultColumnOptions; property Position: TColumnPosition read FPosition write SetPosition; property Spacing: Integer read FSpacing write SetSpacing default 4; property Style: TVirtualTreeColumnStyle read FStyle write SetStyle default vsText; property Tag: Integer read FTag write FTag default 0; property Text: String read FText write SetText; property Width: Integer read FWidth write SetWidth default 50; end; TVirtualTreeColumnClass = class of TVirtualTreeColumn; TColumnsArray = array of TVirtualTreeColumn; TCardinalArray = array of Cardinal; TIndexArray = array of TColumnIndex; TVirtualTreeColumns = class(TCollection) private FHeader: TVTHeader; FHeaderBitmap: TBitmap; // backbuffer for drawing FHoverIndex, // currently "hot" column FDownIndex, // Column on which a mouse button is held down. FTrackIndex: TColumnIndex; // Index of column which is currently being resized FClickIndex: TColumnIndex; // last clicked column FPositionToIndex: TIndexArray; FDefaultWidth: Integer; // the width columns are created with FNeedPositionsFix: Boolean; // True if FixPositions must still be called after DFM loading or Bidi mode change. FClearing: Boolean; // True if columns are being deleted entirely. // drag support FDragIndex: TColumnIndex; // index of column currently being dragged FDropTarget: TColumnIndex; // current target column (index) while dragging FDropBefore: Boolean; // True if drop position is in the left half of a column, False for the right // side to drop the dragged column to function GetCount: Integer; function GetItem(Index: TColumnIndex): TVirtualTreeColumn; function GetNewIndex(P: TPoint; var OldIndex: TColumnIndex): Boolean; procedure SetDefaultWidth(Value: Integer); procedure SetItem(Index: TColumnIndex; Value: TVirtualTreeColumn); protected procedure AdjustAutoSize(CurrentIndex: TColumnIndex; Force: Boolean = False); function AdjustDownColumn(P: TPoint): TColumnIndex; function AdjustHoverColumn(const P: TPoint): Boolean; procedure AdjustPosition(Column: TVirtualTreeColumn; Position: Cardinal); function CanSplitterResize(P: TPoint; Column: TColumnIndex): Boolean; procedure DoCanSplitterResize(P: TPoint; Column: TColumnIndex; var Allowed: Boolean); procedure DrawButtonText(DC: HDC; Caption: String; Bounds: TRect; Enabled, Hot: Boolean; DrawFormat: Cardinal; WrapCaption: Boolean); procedure DrawXPButton(DC: HDC; const ButtonR: TRect; DrawSplitter, Down, Hover: Boolean); procedure FixPositions; function GetColumnAndBounds(const P: TPoint; var ColumnLeft, ColumnRight: Integer; Relative: Boolean = True): Integer; function GetOwner: TPersistent; override; procedure HandleClick(P: TPoint; Button: TMouseButton; Force, DblClick: Boolean); virtual; procedure IndexChanged(OldIndex, NewIndex: Integer); procedure InitializePositionArray; procedure ReorderColumns(RTL: Boolean); procedure Update(Item: TCollectionItem); override; procedure UpdatePositions(Force: Boolean = False); property HeaderBitmap: TBitmap read FHeaderBitmap; property PositionToIndex: TIndexArray read FPositionToIndex; public constructor Create(AOwner: TVTHeader); destructor Destroy; override; function Add: TVirtualTreeColumn; virtual; procedure AnimatedResize(Column: TColumnIndex; NewWidth: Integer); procedure Assign(Source: TPersistent); override; procedure Clear; virtual; function ColumnFromPosition(const P: TPoint; Relative: Boolean = True): TColumnIndex; overload; virtual; function ColumnFromPosition(PositionIndex: TColumnPosition): TColumnIndex; overload; virtual; function Equals(OtherColumnsObj: TObject): Boolean; procedure GetColumnBounds(Column: TColumnIndex; out Left, Right: Integer); function GetFirstVisibleColumn(ConsiderAllowFocus: Boolean = False): TColumnIndex; function GetLastVisibleColumn(ConsiderAllowFocus: Boolean = False): TColumnIndex; function GetNextColumn(Column: TColumnIndex): TColumnIndex; function GetNextVisibleColumn(Column: TColumnIndex; ConsiderAllowFocus: Boolean = False): TColumnIndex; function GetPreviousColumn(Column: TColumnIndex): TColumnIndex; function GetPreviousVisibleColumn(Column: TColumnIndex; ConsiderAllowFocus: Boolean = False): TColumnIndex; function GetScrollWidth: Integer; function GetVisibleColumns: TColumnsArray; function GetVisibleFixedWidth: Integer; function IsValidColumn(Column: TColumnIndex): Boolean; procedure LoadFromStream(const Stream: TStream; Version: Integer); procedure PaintHeader(DC: HDC; const R: TRect; HOffset: Integer); virtual; procedure SaveToStream(const Stream: TStream); function TotalWidth: Integer; property Count: Integer read GetCount; property ClickIndex: TColumnIndex read FClickIndex; property DefaultWidth: Integer read FDefaultWidth write SetDefaultWidth default 50; property Items[Index: TColumnIndex]: TVirtualTreeColumn read GetItem write SetItem; default; property Header: TVTHeader read FHeader; property TrackIndex: TColumnIndex read FTrackIndex; end; TVirtualTreeColumnsClass = class of TVirtualTreeColumns; TVTConstraintPercent = 0..100; TVTFixedAreaConstraints = class(TPersistent) private FHeader: TVTHeader; FMaxHeightPercent, FMaxWidthPercent, FMinHeightPercent, FMinWidthPercent: TVTConstraintPercent; FOnChange: TNotifyEvent; procedure SetConstraints(Index: Integer; Value: TVTConstraintPercent); protected procedure Change; property Header: TVTHeader read FHeader; public constructor Create(AOwner: TVTHeader); procedure Assign(Source: TPersistent); override; property OnChange: TNotifyEvent read FOnChange write FOnChange; published property MaxHeightPercent: TVTConstraintPercent index 0 read FMaxHeightPercent write SetConstraints default 0; property MaxWidthPercent: TVTConstraintPercent index 1 read FMaxWidthPercent write SetConstraints default 0; property MinHeightPercent: TVTConstraintPercent index 2 read FMinHeightPercent write SetConstraints default 0; property MinWidthPercent: TVTConstraintPercent index 3 read FMinWidthPercent write SetConstraints default 0; end; TVTHeaderStyle = ( hsThickButtons, // TButton look and feel hsFlatButtons, // flatter look than hsThickButton, like an always raised flat TToolButton hsPlates, // flat TToolButton look and feel (raise on hover etc.) hsXPStyle // Windows XP style ); TVTHeaderOption = ( hoAutoResize, // Adjust a column so that the header never exceeds the client width of the owner control. hoColumnResize, // Resizing columns with the mouse is allowed. hoDblClickResize, // Allows a column to resize itself to its largest entry. hoDrag, // Dragging columns is allowed. hoHotTrack, // Header captions are highlighted when mouse is over a particular column. hoOwnerDraw, // Header items with the owner draw style can be drawn by the application via event. hoRestrictDrag, // Header can only be dragged horizontally. hoShowHint, // Show application defined header hint. hoShowImages, // Show header images. hoShowSortGlyphs, // Allow visible sort glyphs. hoVisible, // Header is visible. hoAutoSpring, // Distribute size changes of the header to all columns, which are sizable and have the // coAutoSpring option enabled. hoAutoResize must be enabled too. hoFullRepaintOnResize, // Fully invalidate the header (instead of subsequent columns only) when a column is resized. hoDisableAnimatedResize, // Disable animated resize for all columns. hoHeightResize, // Allow resizing header height via mouse. hoHeightDblClickResize // Allow the header to resize itself to its default height. ); TVTHeaderOptions = set of TVTHeaderOption; THeaderState = ( hsAutoSizing, // auto size chain is in progess, do not trigger again on WM_SIZE hsDragging, // header dragging is in progress (only if enabled) hsDragPending, // left button is down, user might want to start dragging a column hsLoading, // The header currently loads from stream, so updates are not necessary. hsColumnWidthTracking, // column resizing is in progress hsColumnWidthTrackPending, // left button is down, user might want to start resize a column hsHeightTracking, // height resizing is in progress hsHeightTrackPending, // left button is down, user might want to start changing height hsResizing, // multi column resizing in progress hsScaling, // the header is scaled after a change of FixedAreaConstraints or client size hsNeedScaling // the header needs to be scaled ); THeaderStates = set of THeaderState; TSortDirection = ( sdAscending, sdDescending ); // describes the used column resize behaviour for AutoFitColumns TSmartAutoFitType = ( smaAllColumns, // consider nodes in view only for all columns smaNoColumn, // consider nodes in view only for no column smaUseColumnOption // use coSmartResize of the corresponding column ); // desribes what made a structure change event happen TChangeReason = ( crIgnore, // used as placeholder crAccumulated, // used for delayed changes crChildAdded, // one or more child nodes have been added crChildDeleted, // one or more child nodes have been deleted crNodeAdded, // a node has been added crNodeCopied, // a node has been duplicated crNodeMoved // a node has been moved to a new place ); TVTHeader = class(TPersistent) private FOwner: TBaseVirtualTree; FColumns: TVirtualTreeColumns; FHeight: Integer; FFont: TFont; FParentFont: Boolean; FOptions: TVTHeaderOptions; FStates: THeaderStates; // Used to keep track of internal states the header can enter. FTrackPoint: TPoint; // Client coordinate where the tracking started. FStyle: TVTHeaderStyle; // button style FBackground: TColor; FAutoSizeIndex: TColumnIndex; FPopupMenu: TPopupMenu; FMainColumn: TColumnIndex; // the column which holds the tree FMaxHeight: Integer; FMinHeight: Integer; FDefaultHeight: Integer; FFixedAreaConstraints: TVTFixedAreaConstraints; // Percentages for the fixed area (header, fixed columns). FImages: TCustomImageList; FImageChangeLink: TChangeLink; // connections to the image list to get notified about changes FSortColumn: TColumnIndex; FSortDirection: TSortDirection; FTrackStart: TPoint; // client coordinates of the tracking start point FDragStart: TPoint; // initial mouse drag position FDragImage: TVTDragImage; // drag image management during header drag FLastWidth: Integer; // Used to adjust spring columns. This is the width of all visible columns, // not the header rectangle. procedure FontChanged(Sender: TObject); function GetMainColumn: TColumnIndex; function GetUseColumns: Boolean; function IsFontStored: Boolean; procedure SetAutoSizeIndex(Value: TColumnIndex); procedure SetBackground(Value: TColor); procedure SetColumns(Value: TVirtualTreeColumns); procedure SetDefaultHeight(Value: Integer); procedure SetFont(const Value: TFont); procedure SetHeight(Value: Integer); procedure SetImages(const Value: TCustomImageList); procedure SetMainColumn(Value: TColumnIndex); procedure SetMaxHeight(Value: Integer); procedure SetMinHeight(Value: Integer); procedure SetOptions(Value: TVTHeaderOptions); procedure SetParentFont(Value: Boolean); procedure SetSortColumn(Value: TColumnIndex); procedure SetSortDirection(const Value: TSortDirection); procedure SetStyle(Value: TVTHeaderStyle); protected procedure ChangeScale(M, D: Integer); virtual; function DetermineSplitterIndex(const P: TPoint): Boolean; virtual; procedure DoAfterAutoFitColumn(Column: TColumnIndex); virtual; procedure DoAfterColumnWidthTracking(Column: TColumnIndex); virtual; procedure DoAfterHeightTracking; virtual; function DoBeforeAutoFitColumn(Column: TColumnIndex; SmartAutoFitType: TSmartAutoFitType): Boolean; virtual; procedure DoBeforeColumnWidthTracking(Column: TColumnIndex; Shift: TShiftState); virtual; procedure DoBeforeHeightTracking(Shift: TShiftState); virtual; function DoColumnWidthDblClickResize(Column: TColumnIndex; P: TPoint; Shift: TShiftState): Boolean; virtual; function DoColumnWidthTracking(Column: TColumnIndex; Shift: TShiftState; var TrackPoint: TPoint; P: TPoint): Boolean; virtual; function DoGetPopupMenu(Column: TColumnIndex; Position: TPoint): TPopupMenu; virtual; function DoHeightTracking(var P: TPoint; Shift: TShiftState): Boolean; virtual; function DoHeightDblClickResize(var P: TPoint; Shift: TShiftState): Boolean; virtual; procedure DoSetSortColumn(Value: TColumnIndex); virtual; procedure DragTo(const P: TPoint); procedure FixedAreaConstraintsChanged(Sender: TObject); function GetColumnsClass: TVirtualTreeColumnsClass; virtual; function GetOwner: TPersistent; override; function GetShiftState: TShiftState; function HandleHeaderMouseMove(var Message: TLMMouseMove): Boolean; function HandleMessage(var Message: TLMessage): Boolean; virtual; procedure ImageListChange(Sender: TObject); procedure PrepareDrag(P, Start: TPoint); procedure RecalculateHeader; virtual; procedure RescaleHeader; procedure UpdateMainColumn; procedure UpdateSpringColumns; public constructor Create(AOwner: TBaseVirtualTree); virtual; destructor Destroy; override; function AllowFocus(ColumnIndex: TColumnIndex): Boolean; procedure Assign(Source: TPersistent); override; procedure AutoFitColumns(Animated: Boolean = True; SmartAutoFitType: TSmartAutoFitType = smaUseColumnOption; RangeStartCol: Integer = NoColumn; RangeEndCol: Integer = NoColumn); function InHeader(const P: TPoint): Boolean; virtual; function InHeaderSplitterArea(P: TPoint): Boolean; virtual; procedure Invalidate(Column: TVirtualTreeColumn; ExpandToBorder: Boolean = False); procedure LoadFromStream(const Stream: TStream); virtual; function ResizeColumns(ChangeBy: Integer; RangeStartCol: TColumnIndex; RangeEndCol: TColumnIndex; Options: TVTColumnOptions = [coVisible]): Integer; procedure RestoreColumns; procedure SaveToStream(const Stream: TStream); virtual; property DragImage: TVTDragImage read FDragImage; property States: THeaderStates read FStates; property Treeview: TBaseVirtualTree read FOwner; property UseColumns: Boolean read GetUseColumns; published property AutoSizeIndex: TColumnIndex read FAutoSizeIndex write SetAutoSizeIndex; property Background: TColor read FBackground write SetBackground default clBtnFace; property Columns: TVirtualTreeColumns read FColumns write SetColumns; property DefaultHeight: Integer read FDefaultHeight write SetDefaultHeight; property Font: TFont read FFont write SetFont stored IsFontStored; property FixedAreaConstraints: TVTFixedAreaConstraints read FFixedAreaConstraints write FFixedAreaConstraints; property Height: Integer read FHeight write SetHeight default 17; property Images: TCustomImageList read FImages write SetImages; property MainColumn: TColumnIndex read GetMainColumn write SetMainColumn default 0; property MaxHeight: Integer read FMaxHeight write SetMaxHeight default 10000; property MinHeight: Integer read FMinHeight write SetMinHeight default 10; property Options: TVTHeaderOptions read FOptions write SetOptions default [hoColumnResize, hoDrag, hoShowSortGlyphs]; property ParentFont: Boolean read FParentFont write SetParentFont default False; property PopupMenu: TPopupMenu read FPopupMenu write FPopUpMenu; property SortColumn: TColumnIndex read FSortColumn write SetSortColumn default NoColumn; property SortDirection: TSortDirection read FSortDirection write SetSortDirection default sdAscending; property Style: TVTHeaderStyle read FStyle write SetStyle default hsThickButtons; end; TVTHeaderClass = class of TVTHeader; // Communication interface between a tree editor and the tree itself (declared as using stdcall in case it // is implemented in a (C/C++) DLL). The GUID is not nessecary in Delphi but important for BCB users // to allow QueryInterface and _uuidof calls. IVTEditLink = interface ['{2BE3EAFA-5ACB-45B4-9D9A-B58BCC496E17}'] function BeginEdit: Boolean; stdcall; // Called when editing actually starts. function CancelEdit: Boolean; stdcall; // Called when editing has been cancelled by the tree. function EndEdit: Boolean; stdcall; // Called when editing has been finished by the tree. function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall; // Called after creation to allow a setup. function GetBounds: TRect; stdcall; // Called to get the current size of the edit window // (only important if the edit resizes itself). procedure ProcessMessage(var Message: TLMessage); stdcall; // Used to forward messages to the edit window(s)- procedure SetBounds(R: TRect); stdcall; // Called to place the editor. end; // Indicates in the OnUpdating event what state the tree is currently in. TVTUpdateState = ( usBegin, // The tree just entered the update state (BeginUpdate call for the first time). usBeginSynch, // The tree just entered the synch update state (BeginSynch call for the first time). usSynch, // Begin/EndSynch has been called but the tree did not change the update state. usUpdate, // Begin/EndUpdate has been called but the tree did not change the update state. usEnd, // The tree just left the update state (EndUpdate called for the last level). usEndSynch // The tree just left the synch update state (EndSynch called for the last level). ); // Used during owner draw of the header to indicate which drop mark for the column must be drawn. TVTDropMarkMode = ( dmmNone, dmmLeft, dmmRight ); // This structure carries all important information about header painting and is used in the advanced header painting. THeaderPaintInfo = record TargetCanvas: TCanvas; Column: TVirtualTreeColumn; PaintRectangle: TRect; TextRectangle: TRect; IsHoverIndex, IsDownIndex, IsEnabled, ShowHeaderGlyph, ShowSortGlyph, ShowRightBorder: Boolean; DropMark: TVTDropMarkMode; GlyphPos, SortGlyphPos: TPoint; end; // These elements are used both to query the application, which of them it wants to draw itself and to tell it during // painting, which elements must be drawn during the advanced custom draw events. THeaderPaintElements = set of ( hpeBackground, hpeDropMark, hpeHeaderGlyph, hpeSortGlyph, hpeText ); // Various events must be handled at different places than they were initiated or need // a persistent storage until they are reset. TVirtualTreeStates = set of ( tsCancelHintAnimation, // Set when a new hint is about to show but an old hint is still being animated. tsChangePending, // A selection change is pending. tsCheckPropagation, // Set during automatic check state propagation. tsCollapsing, // A full collapse operation is in progress. tsToggleFocusedSelection, // Node selection was modifed using Ctrl-click. Change selection state on next mouse up. tsClearPending, // Need to clear the current selection on next mouse move. tsClipboardFlushing, // Set during flushing the clipboard to avoid freeing the content. tsCopyPending, // Indicates a pending copy operation which needs to be finished. tsCutPending, // Indicates a pending cut operation which needs to be finished. tsDrawSelPending, // Multiselection only. User held down the left mouse button on a free // area and might want to start draw selection. tsDrawSelecting, // Multiselection only. Draw selection has actually started. tsEditing, // Indicates that an edit operation is currently in progress. tsEditPending, // An mouse up start edit if dragging has not started. tsExpanding, // A full expand operation is in progress. tsNodeHeightTracking, // A node height changing operation is in progress. tsNodeHeightTrackPending, // left button is down, user might want to start changing a node's height. tsHint, // Set when our hint is visible or soon will be. tsInAnimation, // Set if the tree is currently in an animation loop. tsIncrementalSearching, // Set when the user starts incremental search. tsIncrementalSearchPending, // Set in WM_KEYDOWN to tell to use the char in WM_CHAR for incremental search. tsIterating, // Set when IterateSubtree is currently in progress. tsKeyCheckPending, // A check operation is under way, initiated by a key press (space key). Ignore mouse. tsLeftButtonDown, // Set when the left mouse button is down. tsLeftDblClick, // Set when the left mouse button was doubly clicked. tsMouseCheckPending, // A check operation is under way, initiated by a mouse click. Ignore space key. tsMiddleButtonDown, // Set when the middle mouse button is down. tsMiddleDblClick, // Set when the middle mouse button was doubly clicked. tsNeedScale, // On next ChangeScale scale the default node height. tsNeedRootCountUpdate, // Set if while loading a root node count is set. tsOLEDragging, // OLE dragging in progress. tsOLEDragPending, // User has requested to start delayed dragging. tsPainting, // The tree is currently painting itself. tsRightButtonDown, // Set when the right mouse button is down. tsRightDblClick, // Set when the right mouse button was doubly clicked. tsPopupMenuShown, // The user clicked the right mouse button, which might cause a popup menu to appear. tsScrolling, // Set when autoscrolling is active. tsScrollPending, // Set when waiting for the scroll delay time to elapse. tsSizing, // Set when the tree window is being resized. This is used to prevent recursive calls // due to setting the scrollbars when sizing. tsStopValidation, // Cache validation can be stopped (usually because a change has occured meanwhile). tsStructureChangePending, // The structure of the tree has been changed while the update was locked. tsSynchMode, // Set when the tree is in synch mode, where no timer events are triggered. tsThumbTracking, // Stop updating the horizontal scroll bar while dragging the vertical thumb and vice versa. tsToggling, // A toggle operation (for some node) is in progress. tsUpdateHiddenChildrenNeeded, // Pending update for the hidden children flag after massive visibility changes. tsUpdating, // The tree does currently not update its window because a BeginUpdate has not yet ended. tsUseCache, // The tree's node caches are validated and non-empty. tsUserDragObject, // Signals that the application created an own drag object in OnStartDrag. tsUseThemes, // The tree runs under WinXP+, is theme aware and themes are enabled. tsValidating, // The tree's node caches are currently validated. tsValidationNeeded, // Something in the structure of the tree has changed. The cache needs validation. tsVCLDragging, // VCL drag'n drop in progress. tsVCLDragPending, // One-shot flag to avoid clearing the current selection on implicit mouse up for VCL drag. tsWheelPanning, // Wheel mouse panning is active or soon will be. tsWheelScrolling, // Wheel mouse scrolling is active or soon will be. tsWindowCreating // Set during window handle creation to avoid frequent unnecessary updates. ); TChangeStates = set of ( csStopValidation, // Cache validation can be stopped (usually because a change has occured meanwhile). csUseCache, // The tree's node caches are validated and non-empty. csValidating, // The tree's node caches are currently validated. csValidationNeeded // Something in the structure of the tree has changed. The cache needs validation. ); // determines whether and how the drag image is to show TVTDragImageKind = ( diComplete, // show a complete drag image with all columns, only visible columns are shown diMainColumnOnly, // show only the main column (the tree column) diNoImage // don't show a drag image at all ); // Switch for OLE and VCL drag'n drop. Because it is not possible to have both simultanously. TVTDragType = ( dtOLE, dtVCL ); // options which determine what to draw in PaintTree TVTInternalPaintOption = ( poBackground, // draw background image if there is any and it is enabled poColumnColor, // erase node's background with the column's color poDrawFocusRect, // draw focus rectangle around the focused node poDrawSelection, // draw selected nodes with the normal selection color poDrawDropMark, // draw drop mark if a node is currently the drop target poGridLines, // draw grid lines if enabled poMainOnly, // draw only the main column poSelectedOnly // draw only selected nodes ); TVTInternalPaintOptions = set of TVTInternalPaintOption; // Determines the look of a tree's lines. TVTLineStyle = ( lsCustomStyle, // application provides a line pattern lsDotted, // usual dotted lines (default) lsSolid // simple solid lines ); // TVTLineType is used during painting a tree TVTLineType = ( ltNone, // no line at all ltBottomRight, // a line from bottom to the center and from there to the right ltTopDown, // a line from top to bottom ltTopDownRight, // a line from top to bottom and from center to the right ltRight, // a line from center to the right ltTopRight, // a line from bottom to center and from there to the right // special styles for alternative drawings of tree lines ltLeft, // a line from top to bottom at the left ltLeftBottom // a combination of ltLeft and a line at the bottom from left to right ); // Determines how to draw tree lines. TVTLineMode = ( lmNormal, // usual tree lines (as in TTreeview) lmBands // looks similar to a Nassi-Schneidermann diagram ); // A collection of line type IDs which is used while painting a node. TLineImage = array of TVTLineType; TVTScrollIncrement = 1..10000; // Export type TVTExportType = ( etRTF, // contentToRTF etHTML, // contentToHTML etText, // contentToText etExcel, // supported by external tools etWord, // supported by external tools etCustom // supported by external tools ); TVTNodeExportEvent = function (Sender: TBaseVirtualTree; aExportType: TVTExportType; Node: PVirtualNode): Boolean of object; TVTColumnExportEvent = procedure (Sender: TBaseVirtualTree; aExportType: TVTExportType; Column: TVirtualTreeColumn) of object; TVTTreeExportEvent = procedure(Sender: TBaseVirtualTree; aExportType: TVTExportType) of object; // A class to manage scroll bar aspects. TScrollBarOptions = class(TPersistent) private FAlwaysVisible: Boolean; FOwner: TBaseVirtualTree; FScrollBars: TScrollStyle; // used to hide or show vertical and/or horizontal scrollbar FScrollBarStyle: TVTScrollBarStyle; // kind of scrollbars to use FIncrementX, FIncrementY: TVTScrollIncrement; // number of pixels to scroll in one step (when auto scrolling) procedure SetAlwaysVisible(Value: Boolean); procedure SetScrollBars(Value: TScrollStyle); procedure SetScrollBarStyle(Value: TVTScrollBarStyle); protected function GetOwner: TPersistent; override; public constructor Create(AOwner: TBaseVirtualTree); procedure Assign(Source: TPersistent); override; published property AlwaysVisible: Boolean read FAlwaysVisible write SetAlwaysVisible default False; property HorizontalIncrement: TVTScrollIncrement read FIncrementX write FIncrementX default 20; property ScrollBars: TScrollStyle read FScrollbars write SetScrollBars default ssBoth; property ScrollBarStyle: TVTScrollBarStyle read FScrollBarStyle write SetScrollBarStyle default sbmRegular; property VerticalIncrement: TVTScrollIncrement read FIncrementY write FIncrementY default 20; end; // class to collect all switchable colors into one place TVTColors = class(TPersistent) private FOwner: TBaseVirtualTree; FColors: array[0..14] of TColor; function GetColor(const Index: Integer): TColor; procedure SetColor(const Index: Integer; const Value: TColor); public constructor Create(AOwner: TBaseVirtualTree); procedure Assign(Source: TPersistent); override; published property BorderColor: TColor index 7 read GetColor write SetColor default clBtnFace; property DisabledColor: TColor index 0 read GetColor write SetColor default clBtnShadow; property DropMarkColor: TColor index 1 read GetColor write SetColor default clHighlight; property DropTargetColor: TColor index 2 read GetColor write SetColor default clHighLight; property DropTargetBorderColor: TColor index 11 read GetColor write SetColor default clHighLight; property FocusedSelectionColor: TColor index 3 read GetColor write SetColor default clHighLight; property FocusedSelectionBorderColor: TColor index 9 read GetColor write SetColor default clHighLight; property GridLineColor: TColor index 4 read GetColor write SetColor default clBtnFace; property HeaderHotColor: TColor index 14 read GetColor write SetColor default clBtnShadow; property HotColor: TColor index 8 read GetColor write SetColor default clWindowText; property SelectionRectangleBlendColor: TColor index 12 read GetColor write SetColor default clHighlight; property SelectionRectangleBorderColor: TColor index 13 read GetColor write SetColor default clHighlight; property TreeLineColor: TColor index 5 read GetColor write SetColor default clBtnShadow; property UnfocusedSelectionColor: TColor index 6 read GetColor write SetColor default clBtnFace; property UnfocusedSelectionBorderColor: TColor index 10 read GetColor write SetColor default clBtnFace; end; // For painting a node and its columns/cells a lot of information must be passed frequently around. TVTImageInfo = record Index: Integer; // Index in the associated image list. XPos, // Horizontal position in the current target canvas. YPos: Integer; // Vertical position in the current target canvas. Ghosted: Boolean; // Flag to indicate that the image must be drawn slightly lighter. Images: TCustomImageList; // The image list to be used for painting. end; TVTImageInfoIndex = ( iiNormal, iiState, iiCheck, iiOverlay ); // Options which are used when modifying the scroll offsets. TScrollUpdateOptions = set of ( suoRepaintHeader, // if suoUpdateNCArea is also set then invalidate the header suoRepaintScrollbars, // if suoUpdateNCArea is also set then repaint both scrollbars after updating them suoScrollClientArea, // scroll and invalidate the proper part of the client area suoUpdateNCArea // update non-client area (scrollbars, header) ); // Determines the look of a tree's buttons. TVTButtonStyle = ( bsRectangle, // traditional Windows look (plus/minus buttons) bsTriangle // traditional Macintosh look ); // TButtonFillMode is only used when the button style is bsRectangle and determines how to fill the interior. TVTButtonFillMode = ( fmTreeColor, // solid color, uses the tree's background color fmWindowColor, // solid color, uses clWindow fmShaded, // color gradient, Windows XP style (legacy code, use toThemeAware on Windows XP instead) fmTransparent // transparent color, use the item's background color ); TVTPaintInfo = record Canvas: TCanvas; // the canvas to paint on PaintOptions: TVTInternalPaintOptions; // a copy of the paint options passed to PaintTree Node: PVirtualNode; // the node to paint Column: TColumnIndex; // the node's column index to paint Position: TColumnPosition; // the column position of the node CellRect, // the node cell ContentRect: TRect; // the area of the cell used for the node's content NodeWidth: Integer; // the actual node width Alignment: TAlignment; // how to align within the node rectangle CaptionAlignment: TAlignment; // how to align text within the caption rectangle BidiMode: TBidiMode; // directionality to be used for painting BrushOrigin: TPoint; // the alignment for the brush used to draw dotted lines ImageInfo: array[TVTImageInfoIndex] of TVTImageInfo; // info about each possible node image end; // Method called by the Animate routine for each animation step. TVTAnimationCallback = function(Step, StepSize: Integer; Data: Pointer): Boolean of object; TVTIncrementalSearch = ( isAll, // search every node in tree, initialize if necessary isNone, // disable incremental search isInitializedOnly, // search only initialized nodes, skip others isVisibleOnly // search only visible nodes, initialize if necessary ); // Determines which direction to use when advancing nodes during an incremental search. TVTSearchDirection = ( sdForward, sdBackward ); // Determines where to start incremental searching for each key press. TVTSearchStart = ( ssAlwaysStartOver, // always use the first/last node (depending on direction) to search from ssLastHit, // use the last found node ssFocusedNode // use the currently focused node ); // Determines how to use the align member of a node. TVTNodeAlignment = ( naFromBottom, // the align member specifies amount of units (usually pixels) from top border of the node naFromTop, // align is to be measured from bottom naProportional // align is to be measure in percent of the entire node height and relative to top ); // Determines how to draw the selection rectangle used for draw selection. TVTDrawSelectionMode = ( smDottedRectangle, // same as DrawFocusRect smBlendedRectangle // alpha blending, uses special colors (see TVTColors) ); // Determines for which purpose the cell paint event is called. TVTCellPaintMode = ( cpmPaint, // painting the cell cpmGetContentMargin // getting cell content margin ); // Determines which sides of the cell content margin should be considered. TVTCellContentMarginType = ( ccmtAllSides, // consider all sides ccmtTopLeftOnly, // consider top margin and left margin only ccmtBottomRightOnly // consider bottom margin and right margin only ); TClipboardFormats = class(TStringList) private FOwner: TBaseVirtualTree; public constructor Create(AOwner: TBaseVirtualTree); virtual; function Add(const S: string): Integer; override; procedure Insert(Index: Integer; const S: string); override; property Owner: TBaseVirtualTree read FOwner; end; // ----- Event prototypes: // node enumeration TVTGetNodeProc = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean) of object; // node events TVTChangingEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; var Allowed: Boolean) of object; TVTCheckChangingEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; var NewState: TCheckState; var Allowed: Boolean) of object; TVTChangeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode) of object; TVTStructureChangeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Reason: TChangeReason) of object; TVTEditCancelEvent = procedure(Sender: TBaseVirtualTree; Column: TColumnIndex) of object; TVTEditChangingEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean) of object; TVTEditChangeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex) of object; TVTFreeNodeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode) of object; TVTFocusChangingEvent = procedure(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex; var Allowed: Boolean) of object; TVTFocusChangeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex) of object; TVTGetImageEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer) of object; TVTGetImageExEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer; var ImageList: TCustomImageList) of object; TVTGetImageTextEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var ImageText: String) of object; TVTHotNodeChangeEvent = procedure(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode) of object; TVTInitChildrenEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal) of object; TVTInitNodeEvent = procedure(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates) of object; TVTPopupEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; const P: TPoint; var AskParent: Boolean; var PopupMenu: TPopupMenu) of object; TVTHelpContextEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var HelpContext: Integer) of object; TVTCreateEditorEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink) of object; TVTSaveNodeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream) of object; // header/column events TVTHeaderClickEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) of object; TVTHeaderMouseEvent = procedure(Sender: TVTHeader; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) of object; TVTHeaderMouseMoveEvent = procedure(Sender: TVTHeader; Shift: TShiftState; X, Y: Integer) of object; TVTBeforeHeaderHeightTrackingEvent = procedure(Sender: TVTHeader; Shift: TShiftState) of object; TVTAfterHeaderHeightTrackingEvent = procedure(Sender: TVTHeader) of object; TVTHeaderHeightTrackingEvent = procedure(Sender: TVTHeader; var P: TPoint; Shift: TShiftState; var Allowed: Boolean) of object; TVTHeaderHeightDblClickResizeEvent = procedure(Sender: TVTHeader; var P: TPoint; Shift: TShiftState; var Allowed: Boolean) of object; TVTHeaderNotifyEvent = procedure(Sender: TVTHeader; Column: TColumnIndex) of object; TVTHeaderDraggingEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; var Allowed: Boolean) of object; TVTHeaderDraggedEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; OldPosition: Integer) of object; TVTHeaderDraggedOutEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; const DropPosition: TPoint) of object; TVTHeaderPaintEvent = procedure(Sender: TVTHeader; HeaderCanvas: TCanvas; Column: TVirtualTreeColumn; const R: TRect; Hover, Pressed: Boolean; DropMark: TVTDropMarkMode) of object; TVTHeaderPaintQueryElementsEvent = procedure(Sender: TVTHeader; var PaintInfo: THeaderPaintInfo; var Elements: THeaderPaintElements) of object; TVTAdvancedHeaderPaintEvent = procedure(Sender: TVTHeader; var PaintInfo: THeaderPaintInfo; const Elements: THeaderPaintElements) of object; TVTBeforeAutoFitColumnsEvent = procedure(Sender: TVTHeader; var SmartAutoFitType: TSmartAutoFitType) of object; TVTBeforeAutoFitColumnEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; var SmartAutoFitType: TSmartAutoFitType; var Allowed: Boolean) of object; TVTAfterAutoFitColumnEvent = procedure(Sender: TVTHeader; Column: TColumnIndex) of object; TVTAfterAutoFitColumnsEvent = procedure(Sender: TVTHeader) of object; TVTColumnClickEvent = procedure (Sender: TBaseVirtualTree; Column: TColumnIndex; Shift: TShiftState) of object; TVTColumnDblClickEvent = procedure (Sender: TBaseVirtualTree; Column: TColumnIndex; Shift: TShiftState) of object; TVTColumnWidthDblClickResizeEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; Shift: TShiftState; P: TPoint; var Allowed: Boolean) of object; TVTBeforeColumnWidthTrackingEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; Shift: TShiftState) of object; TVTAfterColumnWidthTrackingEvent = procedure(Sender: TVTHeader; Column: TColumnIndex) of object; TVTColumnWidthTrackingEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; Shift: TShiftState; var TrackPoint: TPoint; P: TPoint; var Allowed: Boolean) of object; TVTGetHeaderCursorEvent = procedure(Sender: TVTHeader; var Cursor: HCURSOR) of object; TVTBeforeGetMaxColumnWidthEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; var UseSmartColumnWidth: Boolean) of object; TVTAfterGetMaxColumnWidthEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; var MaxWidth: Integer) of object; TVTCanSplitterResizeColumnEvent = procedure(Sender: TVTHeader; P: TPoint; Column: TColumnIndex; var Allowed: Boolean) of object; // move, copy and node tracking events TVTNodeMovedEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode) of object; TVTNodeMovingEvent = procedure(Sender: TBaseVirtualTree; Node, Target: PVirtualNode; var Allowed: Boolean) of object; TVTNodeCopiedEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode) of object; TVTNodeCopyingEvent = procedure(Sender: TBaseVirtualTree; Node, Target: PVirtualNode; var Allowed: Boolean) of object; TVTNodeHeightTrackingEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; Shift: TShiftState; var TrackPoint: TPoint; P: TPoint; var Allowed: Boolean) of object; TVTNodeHeightDblClickResizeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; Shift: TShiftState; P: TPoint; var Allowed: Boolean) of object; // drag'n drop/OLE events TVTCreateDragManagerEvent = procedure(Sender: TBaseVirtualTree; out DragManager: IVTDragManager) of object; TVTCreateDataObjectEvent = procedure(Sender: TBaseVirtualTree; out IDataObject: IDataObject) of object; TVTDragAllowedEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean) of object; TVTDragOverEvent = procedure(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState; const Pt: TPoint; Mode: TDropMode; var Effect: LongWord; var Accept: Boolean) of object; TVTDragDropEvent = procedure(Sender: TBaseVirtualTree; Source: TObject; {DataObject: IDataObject;} Formats: TFormatArray; Shift: TShiftState; const Pt: TPoint; var Effect: LongWord; Mode: TDropMode) of object; TVTRenderOLEDataEvent = procedure(Sender: TBaseVirtualTree; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean; var Result: HRESULT) of object; TVTGetUserClipboardFormatsEvent = procedure(Sender: TBaseVirtualTree; var Formats: TFormatEtcArray) of object; // paint events TVTBeforeItemEraseEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect; var ItemColor: TColor; var EraseAction: TItemEraseAction) of object; TVTAfterItemEraseEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect) of object; TVTBeforeItemPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect; var CustomDraw: Boolean) of object; TVTAfterItemPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect) of object; TVTBeforeCellPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect) of object; TVTAfterCellPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const CellRect: TRect) of object; TVTPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas) of object; TVTBackgroundPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; const R: TRect; var Handled: Boolean) of object; TVTGetLineStyleEvent = procedure(Sender: TBaseVirtualTree; var Bits: Pointer) of object; TVTMeasureItemEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer) of object; // search, sort TVTCompareEvent = procedure(Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer) of object; TVTIncrementalSearchEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; const SearchText: String; var Result: Integer) of object; // miscellaneous TVTGetNodeDataSizeEvent = procedure(Sender: TBaseVirtualTree; var NodeDataSize: Integer) of object; TVTKeyActionEvent = procedure(Sender: TBaseVirtualTree; var CharCode: Word; var Shift: TShiftState; var DoDefault: Boolean) of object; TVTScrollEvent = procedure(Sender: TBaseVirtualTree; DeltaX, DeltaY: Integer) of object; TVTUpdatingEvent = procedure(Sender: TBaseVirtualTree; State: TVTUpdateState) of object; TVTGetCursorEvent = procedure(Sender: TBaseVirtualTree; var Cursor: TCursor) of object; TVTStateChangeEvent = procedure(Sender: TBaseVirtualTree; Enter, Leave: TVirtualTreeStates) of object; TVTGetCellIsEmptyEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var IsEmpty: Boolean) of object; TVTScrollbarShowEvent = procedure(Sender: TBaseVirtualTree; Bar: Integer; Show: Boolean) of object; // Helper types for node iterations. TGetFirstNodeProc = function: PVirtualNode of object; TGetNextNodeProc = function(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode of object; // ----- TBaseVirtualTree TBaseVirtualTree = class(TCustomControl) private //FBorderStyle: TBorderStyle; FHeader: TVTHeader; FRoot: PVirtualNode; FDefaultNodeHeight, FIndent: Cardinal; FOptions: TCustomVirtualTreeOptions; FUpdateCount: Cardinal; // update stopper, updates of the tree control are only done if = 0 FSynchUpdateCount: Cardinal; // synchronizer, causes all events which are usually done via timers // to happen immediately, regardless of the normal update state FNodeDataSize: Integer; // number of bytes to allocate with each node (in addition to its base // structure and the internal data), if -1 then do callback FStates: TVirtualTreeStates; // various active/pending states the tree needs to consider FLastSelected, FFocusedNode: PVirtualNode; FEditColumn, // column to be edited (focused node) FFocusedColumn: TColumnIndex; // NoColumn if no columns are active otherwise the last hit column of // the currently focused node FHeightTrackPoint: TPoint; // Starting point of a node's height changing operation. FHeightTrackNode: PVirtualNode; // Node which height is being changed. FHeightTrackColumn: TColumnIndex; // Initial column where the height changing operation takes place. FScrollDirections: TScrollDirections; // directions to scroll client area into depending on mouse position FLastStructureChangeReason: TChangeReason; // Used for delayed structure change event. FLastStructureChangeNode, // dito FLastChangedNode, // used for delayed change event FCurrentHotNode: PVirtualNode; // Node over which the mouse is hovering. FCurrentHotColumn: TColumnIndex; // Column over which the mouse is hovering. FHotNodeButtonHit: Boolean; // Indicates wether the mouse is hovering over the hot node's button. FLastSelRect, FNewSelRect: TRect; // used while doing draw selection FHotCursor: TCursor; // can be set to additionally indicate the current hot node FHintMode: TVTHintMode; // determines the kind of the hint window FHintData: TVTHintData; // used while preparing the hint window FChangeDelay: Cardinal; // used to delay OnChange event FEditDelay: Cardinal; // determines time to elapse before a node goes into edit mode FPositionCache: TCache; // array which stores node references ordered by vertical positions // (see also DoValidateCache for more information) FVisibleCount: Cardinal; // number of currently visible nodes FStartIndex: Cardinal; // index to start validating cache from FSelection: TNodeArray; // list of currently selected nodes FSelectionCount: Integer; // number of currently selected nodes (size of FSelection might differ) FSelectionLocked: Boolean; // prevents the tree from changing the selection FRangeAnchor: PVirtualNode; // anchor node for selection with the keyboard, determines start of a // selection range FCheckNode: PVirtualNode; // node which "captures" a check event FPendingCheckState: TCheckState; // the new state the check node will get if all went fine FCheckPropagationCount: Cardinal; // nesting level of check propagation (WL, 05.02.2004) FLastSelectionLevel: Integer; // keeps the last node level for constrained multiselection FDrawSelShiftState: TShiftState; // keeps the initial shift state when the user starts selection with // the mouse FEditLink: IVTEditLink; // used to comunicate with an application defined editor FTempNodeCache: TNodeArray; // used at various places to hold temporarily a bunch of node refs. FTempNodeCount: Cardinal; // number of nodes in FTempNodeCache FBackground: TPicture; // A background image loadable at design and runtime. FMargin: Integer; // horizontal border distance FTextMargin: Integer; // space between the node's text and its horizontal bounds FBackgroundOffsetX, FBackgroundOffsetY: Integer; // used to fine tune the position of the background image FAnimationDuration: Cardinal; // specifies how long an animation shall take (expanding, hint) FWantTabs: Boolean; // If True then the tree also consumes the tab key. FNodeAlignment: TVTNodeAlignment; // determines how to interpret the align member of a node FHeaderRect: TRect; // Space which the header currently uses in the control (window coords). FLastHintRect: TRect; // Area which the mouse must leave to reshow a hint. FUpdateRect: TRect; // paint support and images FPlusBM, FMinusBM, // small bitmaps used for tree buttons FHotPlusBM, FHotMinusBM: TBitmap; // small bitmaps used for hot tree buttons FImages, // normal images in the tree FStateImages: TCustomImageList; // state images in the tree FCustomCheckImages: TBitmap; // application defined check images FCheckImageKind: TCheckImageKind; // light or dark, cross marks or tick marks FCheckImages: TBitmap; // Reference to global image list to be used for the check images. FImageChangeLink, FStateChangeLink, FCustomCheckChangeLink: TChangeLink; // connections to the image lists FOldFontChange: TNotifyEvent; // helper method pointer for tracking font changes in the off screen buffer FFontChanged: Boolean; // flag for keeping informed about font changes in the off screen buffer FColors: TVTColors; // class comprising all customizable colors in the tree FButtonStyle: TVTButtonStyle; // style of the tree buttons FButtonFillMode: TVTButtonFillMode; // for rectangular tree buttons only: how to fill them FLineStyle: TVTLineStyle; // style of the tree lines FLineMode: TVTLineMode; // tree lines or bands etc. FDottedBrush: HBRUSH; // used to paint dotted lines without special pens FSelectionCurveRadius: Cardinal; // radius for rounded selection rectangles FSelectionBlendFactor: Byte; // Determines the factor by which the selection rectangle is to be // faded if enabled. FDrawSelectionMode: TVTDrawSelectionMode; // determines the paint mode for draw selection // alignment and directionality support FAlignment: TAlignment; // default alignment of the tree if no columns are shown // drag'n drop and clipboard support FDragImageKind: TVTDragImageKind; // determines whether or not and what to show in the drag image FDragOperations: TDragOperations; // determines which operations are allowed during drag'n drop FDragThreshold: Integer; // used to determine when to actually start a drag'n drop operation FDragManager: IVTDragManager; // drag'n drop, cut'n paste FDropTargetNode: PVirtualNode; // node currently selected as drop target FLastDropMode: TDropMode; // set while dragging and used to track changes FDragSelection: TNodeArray; // temporary copy of FSelection used during drag'n drop FDragType: TVTDragType; // used to switch between OLE and VCL drag'n drop FDragImage: TVTDragImage; // drag image management FDragWidth, FDragHeight: Integer; // size of the drag image, the larger the more CPU power is needed FClipboardFormats: TClipboardFormats; // a list of clipboard format descriptions enabled for this tree FLastVCLDragTarget: PVirtualNode; // A node cache for VCL drag'n drop (keywords: DragLeave on DragDrop). FVCLDragEffect: LongWord; // A cache for VCL drag'n drop to keep the current drop effect. // scroll support FScrollBarOptions: TScrollBarOptions; // common properties of horizontal and vertical scrollbar FAutoScrollInterval: TAutoScrollInterval; // determines speed of auto scrolling FAutoScrollDelay: Cardinal; // amount of milliseconds to wait until autoscrolling becomes active FAutoExpandDelay: Cardinal; // amount of milliseconds to wait until a node is expanded if it is the // drop target FOffsetX: Integer; FOffsetY: Integer; // Determines left and top scroll offset. FEffectiveOffsetX: Integer; // Actual position of the horizontal scroll bar (varies depending on bidi mode). FRangeX, FRangeY: Cardinal; // current virtual width and height of the tree FBottomSpace: Cardinal; // Extra space below the last node. FDefaultPasteMode: TVTNodeAttachMode; // Used to determine where to add pasted nodes to. FSingletonNodeArray: TNodeArray; // Contains only one element for quick addition of single nodes // to the selection. FDragScrollStart: Cardinal; // Contains the start time when a tree does auto scrolling as drop target. // search FIncrementalSearch: TVTIncrementalSearch; // Used to determine whether and how incremental search is to be used. FSearchTimeout: Cardinal; // Number of milliseconds after which to stop incremental searching. FSearchBuffer: String; // Collects a sequence of keypresses used to do incremental searching. FLastSearchNode: PVirtualNode; // Reference to node which was last found as search fit. FSearchDirection: TVTSearchDirection; // Direction to incrementally search the tree. FSearchStart: TVTSearchStart; // Where to start iteration on each key press. // miscellanous FTotalInternalDataSize: Cardinal; // Cache of the sum of the necessary internal data size for all tree // classes derived from this base class. FPanningWindow: TVirtualPanningWindow; // Helper window for wheel panning FLastClickPos: TPoint; // Used for retained drag start and wheel mouse scrolling. FOperationCount: Cardinal; // Counts how many nested long-running operations are in progress. FOperationCanceled: Boolean; // Used to indicate that a long-running operation should be canceled. {$ifdef EnableAccessible} // MSAA support FAccessible: IAccessible; // The IAccessible interface to the window itself. FAccessibleItem: IAccessible; // The IAccessible to the item that currently has focus. FAccessibleName: string; // The name the window is given for screen readers. {$endif} // export FOnBeforeNodeExport: TVTNodeExportEvent; // called before exporting a node FOnNodeExport: TVTNodeExportEvent; FOnAfterNodeExport: TVTNodeExportEvent; // called after exporting a node FOnBeforeColumnExport: TVTColumnExportEvent; // called before exporting a column FOnColumnExport: TVTColumnExportEvent; FOnAfterColumnExport: TVTColumnExportEvent; // called after exporting a column FOnBeforeTreeExport: TVTTreeExportEvent; // called before starting the export FOnAfterTreeExport: TVTTreeExportEvent; // called after finishing the export FOnBeforeHeaderExport: TVTTreeExportEvent; // called before exporting the header FOnAfterHeaderExport: TVTTreeExportEvent; // called after exporting the header // common events FOnChange: TVTChangeEvent; // selection change FOnStructureChange: TVTStructureChangeEvent; // structural change like adding nodes etc. FOnInitChildren: TVTInitChildrenEvent; // called when a node's children are needed (expanding etc.) FOnInitNode: TVTInitNodeEvent; // called when a node needs to be initialized (child count etc.) FOnFreeNode: TVTFreeNodeEvent; // called when a node is about to be destroyed, user data can and should // be freed in this event FOnGetImage: TVTGetImageEvent; // Used to retrieve the image index of a given node. FOnGetImageEx: TVTGetImageExEvent; // Used to retrieve the image index of a given node along with a custom // image list. FOnGetImageText: TVTGetImageTextEvent; // Used to retrieve the image alternative text of a given node. // Used by the accessibility interface to provide useful text for status images. FOnHotChange: TVTHotNodeChangeEvent; // called when the current "hot" node (that is, the node under the mouse) // changes and hot tracking is enabled FOnExpanding, // called just before a node is expanded FOnCollapsing: TVTChangingEvent; // called just before a node is collapsed FOnChecking: TVTCheckChangingEvent; // called just before a node's check state is changed FOnExpanded, // called after a node has been expanded FOnCollapsed, // called after a node has been collapsed FOnChecked: TVTChangeEvent; // called after a node's check state has been changed FOnResetNode: TVTChangeEvent; // called when a node is set to be uninitialized FOnNodeMoving: TVTNodeMovingEvent; // called just before a node is moved from one parent node to another // (this can be cancelled) FOnNodeMoved: TVTNodeMovedEvent; // called after a node and its children have been moved to another // parent node (probably another tree, but within the same application) FOnNodeCopying: TVTNodeCopyingEvent; // called when an node is copied to another parent node (probably in // another tree, but within the same application, can be cancelled) FOnNodeHeightTracking: TVTNodeHeightTrackingEvent; // called when a node's height is being changed via mouse FOnNodeHeightDblClickResize: TVTNodeHeightDblClickResizeEvent; // called when a node's vertical splitter is double clicked FOnNodeCopied: TVTNodeCopiedEvent; // call after a node has been copied FOnEditing: TVTEditChangingEvent; // called just before a node goes into edit mode FOnEditCancelled: TVTEditCancelEvent; // called when editing has been cancelled FOnEdited: TVTEditChangeEvent; // called when editing has successfully been finished FOnFocusChanging: TVTFocusChangingEvent; // called when the focus is about to go to a new node and/or column // (can be cancelled) FOnFocusChanged: TVTFocusChangeEvent; // called when the focus goes to a new node and/or column FOnGetPopupMenu: TVTPopupEvent; // called when the popup for a node or the header needs to be shown FOnGetHelpContext: TVTHelpContextEvent; // called when a node specific help theme should be called FOnCreateEditor: TVTCreateEditorEvent; // called when a node goes into edit mode, this allows applications // to supply their own editor FOnLoadNode, // called after a node has been loaded from a stream (file, clipboard, // OLE drag'n drop) to allow an application to load their own data // saved in OnSaveNode FOnSaveNode: TVTSaveNodeEvent; // called when a node needs to be serialized into a stream // (see OnLoadNode) to give the application the opportunity to save // their node specific, persistent data (note: never save memory // references) // header/column mouse events FOnAfterAutoFitColumn: TVTAfterAutoFitColumnEvent; FOnAfterAutoFitColumns: TVTAfterAutoFitColumnsEvent; FOnBeforeAutoFitColumns: TVTBeforeAutoFitColumnsEvent; FOnBeforeAutoFitColumn: TVTBeforeAutoFitColumnEvent; FOnHeaderClick, // mouse events for the header, just like those for a control FOnHeaderImageClick, FOnHeaderCheckBoxClick: TVTHeaderClickEvent; FOnHeaderDblClick: TVTHeaderClickEvent; FOnAfterHeaderHeightTracking: TVTAfterHeaderHeightTrackingEvent; FOnBeforeHeaderHeightTracking: TVTBeforeHeaderHeightTrackingEvent; FOnHeaderHeightTracking: TVTHeaderHeightTrackingEvent; FOnHeaderHeightDblClickResize: TVTHeaderHeightDblClickResizeEvent; FOnHeaderMouseDown, FOnHeaderMouseUp: TVTHeaderMouseEvent; FOnHeaderMouseMove: TVTHeaderMouseMoveEvent; FOnAfterGetMaxColumnWidth: TVTAfterGetMaxColumnWidthEvent; FOnBeforeGetMaxColumnWidth: TVTBeforeGetMaxColumnWidthEvent; FOnColumnClick: TVTColumnClickEvent; FOnColumnDblClick: TVTColumnDblClickEvent; FOnColumnResize: TVTHeaderNotifyEvent; FOnColumnWidthDblClickResize: TVTColumnWidthDblClickResizeEvent; FOnAfterColumnWidthTracking: TVTAfterColumnWidthTrackingEvent; FOnBeforeColumnWidthTracking: TVTBeforeColumnWidthTrackingEvent; FOnColumnWidthTracking: TVTColumnWidthTrackingEvent; FOnGetHeaderCursor: TVTGetHeaderCursorEvent; // triggered to allow the app. to use customized cursors for the header FOnCanSplitterResizeColumn: TVTCanSplitterResizeColumnEvent; // paint events FOnAfterPaint, // triggered when the tree has entirely been painted FOnBeforePaint: TVTPaintEvent; // triggered when the tree is about to be painted FOnAfterItemPaint: TVTAfterItemPaintEvent; // triggered after an item has been painted FOnBeforeItemPaint: TVTBeforeItemPaintEvent; // triggered when an item is about to be painted FOnBeforeItemErase: TVTBeforeItemEraseEvent; // triggered when an item's background is about to be erased FOnAfterItemErase: TVTAfterItemEraseEvent; // triggered after an item's background has been erased FOnAfterCellPaint: TVTAfterCellPaintEvent; // triggered after a column of an item has been painted FOnBeforeCellPaint: TVTBeforeCellPaintEvent; // triggered when a column of an item is about to be painted FOnHeaderDraw: TVTHeaderPaintEvent; // Used when owner draw is enabled for the header and a column is set // to owner draw mode. FOnHeaderDrawQueryElements: TVTHeaderPaintQueryElementsEvent; // Used for advanced header painting to query the // application for the elements, which are drawn by it and which should // be drawn by the tree. FOnAdvancedHeaderDraw: TVTAdvancedHeaderPaintEvent; // Used when owner draw is enabled for the header and a column // is set to owner draw mode. But only if OnHeaderDrawQueryElements // returns at least one element to be drawn by the application. // In this case OnHeaderDraw is not used. FOnGetLineStyle: TVTGetLineStyleEvent; // triggered when a custom line style is used and the pattern brush // needs to be build FOnPaintBackground: TVTBackgroundPaintEvent; // triggered if a part of the tree's background must be erased which is // not covered by any node FOnMeasureItem: TVTMeasureItemEvent; // Triggered when a node is about to be drawn and its height was not yet // determined by the application. // drag'n drop events FOnCreateDragManager: TVTCreateDragManagerEvent; // called to allow for app./descendant defined drag managers FOnCreateDataObject: TVTCreateDataObjectEvent; // called to allow for app./descendant defined data objects FOnDragAllowed: TVTDragAllowedEvent; // used to get permission for manual drag in mouse down FOnDragOver: TVTDragOverEvent; // called for every mouse move FOnDragDrop: TVTDragDropEvent; // called on release of mouse button (if drop was allowed) FOnHeaderDragged: TVTHeaderDraggedEvent; // header (column) drag'n drop FOnHeaderDraggedOut: TVTHeaderDraggedOutEvent; // header (column) drag'n drop, which did not result in a valid drop. FOnHeaderDragging: TVTHeaderDraggingEvent; // header (column) drag'n drop FOnRenderOLEData: TVTRenderOLEDataEvent; // application/descendant defined clipboard formats FOnGetUserClipboardFormats: TVTGetUserClipboardFormatsEvent; // gives application/descendants the opportunity to // add own clipboard formats on the fly // miscellanous events FOnGetNodeDataSize: TVTGetNodeDataSizeEvent; // Called if NodeDataSize is -1. FOnKeyAction: TVTKeyActionEvent; // Used to selectively prevent key actions (full expand on Ctrl+'+' etc.). FOnScroll: TVTScrollEvent; // Called when one or both paint offsets changed. FOnUpdating: TVTUpdatingEvent; // Called from BeginUpdate, EndUpdate, BeginSynch and EndSynch. FOnGetCursor: TVTGetCursorEvent; // Called to allow the app. to set individual cursors. FOnStateChange: TVTStateChangeEvent; // Called whenever a state in the tree changes. FOnGetCellIsEmpty: TVTGetCellIsEmptyEvent; // Called when the tree needs to know if a cell is empty. FOnShowScrollbar: TVTScrollbarShowEvent; // Called when a scrollbar is changed in its visibility. // search, sort FOnCompareNodes: TVTCompareEvent; // used during sort FOnIncrementalSearch: TVTIncrementalSearchEvent; // triggered on every key press (not key down) procedure AdjustCoordinatesByIndent(var PaintInfo: TVTPaintInfo; Indent: Integer); procedure AdjustImageBorder(ImageWidth, ImageHeight: Integer; BidiMode: TBidiMode; VAlign: Integer; var R: TRect; var ImageInfo: TVTImageInfo); procedure AdjustTotalCount(Node: PVirtualNode; Value: Integer; Relative: Boolean = False); procedure AdjustTotalHeight(Node: PVirtualNode; Value: Integer; Relative: Boolean = False); function CalculateCacheEntryCount: Integer; procedure CalculateVerticalAlignments(ShowImages, ShowStateImages: Boolean; Node: PVirtualNode; out VAlign, VButtonAlign: Integer); function ChangeCheckState(Node: PVirtualNode; Value: TCheckState): Boolean; function CollectSelectedNodesLTR(MainColumn, NodeLeft, NodeRight: Integer; Alignment: TAlignment; OldRect: TRect; const NewRect: TRect): Boolean; function CollectSelectedNodesRTL(MainColumn, NodeLeft, NodeRight: Integer; Alignment: TAlignment; OldRect: TRect; const NewRect: TRect): Boolean; procedure ClearNodeBackground(const PaintInfo: TVTPaintInfo; UseBackground, Floating: Boolean; R: TRect); function CompareNodePositions(Node1, Node2: PVirtualNode; ConsiderChildrenAbove: Boolean = False): Integer; function DetermineLineImageAndSelectLevel(Node: PVirtualNode; out LineImage: TLineImage): Integer; procedure DrawLineImage(const PaintInfo: TVTPaintInfo; X, Y, H, VAlign: Integer; Style: TVTLineType; Reverse: Boolean); function FindInPositionCache(Node: PVirtualNode; var CurrentPos: Cardinal): PVirtualNode; overload; function FindInPositionCache(Position: Cardinal; var CurrentPos: Cardinal): PVirtualNode; overload; procedure FixupTotalCount(Node: PVirtualNode); procedure FixupTotalHeight(Node: PVirtualNode); function GetBottomNode: PVirtualNode; function GetCheckedCount: Integer; function GetCheckState(Node: PVirtualNode): TCheckState; function GetCheckType(Node: PVirtualNode): TCheckType; function GetChildCount(Node: PVirtualNode): Cardinal; function GetChildrenInitialized(Node: PVirtualNode): Boolean; function GetCutCopyCount: Integer; function GetDisabled(Node: PVirtualNode): Boolean; function GetDragManager: IVTDragManager; function GetExpanded(Node: PVirtualNode): Boolean; function GetFullyVisible(Node: PVirtualNode): Boolean; function GetHasChildren(Node: PVirtualNode): Boolean; function GetMultiline(Node: PVirtualNode): Boolean; function GetNodeHeight(Node: PVirtualNode): Cardinal; function GetNodeParent(Node: PVirtualNode): PVirtualNode; function GetOffsetXY: TPoint; function GetRootNodeCount: Cardinal; function GetSelected(Node: PVirtualNode): Boolean; function GetTopNode: PVirtualNode; function GetTotalCount: Cardinal; function GetVerticalAlignment(Node: PVirtualNode): Byte; function GetVisible(Node: PVirtualNode): Boolean; function GetVisiblePath(Node: PVirtualNode): Boolean; procedure HandleClickSelection(LastFocused, NewNode: PVirtualNode; Shift: TShiftState; DragPending: Boolean); function HandleDrawSelection(X, Y: Integer): Boolean; function HasVisibleNextSibling(Node: PVirtualNode): Boolean; function HasVisiblePreviousSibling(Node: PVirtualNode): Boolean; procedure ImageListChange(Sender: TObject); procedure InitializeFirstColumnValues(var PaintInfo: TVTPaintInfo); procedure InitRootNode(OldSize: Cardinal = 0); procedure InterruptValidation; function IsFirstVisibleChild(Parent, Node: PVirtualNode): Boolean; function IsLastVisibleChild(Parent, Node: PVirtualNode): Boolean; procedure LimitPaintingToArea(Canvas: TCanvas; ClipRect: TRect; VisibleRegion: HRGN = 0); //lcl procedure LoadPanningCursors; function MakeNewNode: PVirtualNode; {$ifdef PACKARRAYPASCAL} function PackArray(const TheArray: TNodeArray; Count: Integer): Integer; {$else} function PackArray(TheArray: TNodeArray; Count: Integer): Integer; {$endif} procedure PrepareBitmaps(NeedButtons, NeedLines: Boolean); procedure SetAlignment(const Value: TAlignment); procedure SetAnimationDuration(const Value: Cardinal); procedure SetBackground(const Value: TPicture); procedure SetBackgroundOffset(const Index, Value: Integer); procedure SetBottomNode(Node: PVirtualNode); procedure SetBottomSpace(const Value: Cardinal); procedure SetButtonFillMode(const Value: TVTButtonFillMode); procedure SetButtonStyle(const Value: TVTButtonStyle); procedure SetCheckImageKind(Value: TCheckImageKind); procedure SetCheckState(Node: PVirtualNode; Value: TCheckState); procedure SetCheckType(Node: PVirtualNode; Value: TCheckType); procedure SetChildCount(Node: PVirtualNode; NewChildCount: Cardinal); procedure SetClipboardFormats(const Value: TClipboardFormats); procedure SetColors(const Value: TVTColors); procedure SetCustomCheckImages(const Value: TBitmap); procedure SetDefaultNodeHeight(Value: Cardinal); procedure SetDisabled(Node: PVirtualNode; Value: Boolean); procedure SetExpanded(Node: PVirtualNode; Value: Boolean); procedure SetFocusedColumn(Value: TColumnIndex); procedure SetFocusedNode(Value: PVirtualNode); procedure SetFullyVisible(Node: PVirtualNode; Value: Boolean); procedure SetHasChildren(Node: PVirtualNode; Value: Boolean); procedure SetHeader(const Value: TVTHeader); procedure SetImages(const Value: TCustomImageList); procedure SetIndent(Value: Cardinal); procedure SetLineMode(const Value: TVTLineMode); procedure SetLineStyle(const Value: TVTLineStyle); procedure SetMargin(Value: Integer); procedure SetMultiline(Node: PVirtualNode; const Value: Boolean); procedure SetNodeAlignment(const Value: TVTNodeAlignment); procedure SetNodeDataSize(Value: Integer); procedure SetNodeHeight(Node: PVirtualNode; Value: Cardinal); procedure SetNodeParent(Node: PVirtualNode; const Value: PVirtualNode); procedure SetOffsetX(const Value: Integer); procedure SetOffsetXY(const Value: TPoint); procedure SetOffsetY(const Value: Integer); procedure SetOptions(const Value: TCustomVirtualTreeOptions); procedure SetRootNodeCount(Value: Cardinal); procedure SetScrollBarOptions(Value: TScrollBarOptions); procedure SetSearchOption(const Value: TVTIncrementalSearch); procedure SetSelected(Node: PVirtualNode; Value: Boolean); procedure SetSelectionCurveRadius(const Value: Cardinal); procedure SetStateImages(const Value: TCustomImageList); procedure SetTextMargin(Value: Integer); procedure SetTopNode(Node: PVirtualNode); procedure SetUpdateState(Updating: Boolean); procedure SetVerticalAlignment(Node: PVirtualNode; Value: Byte); procedure SetVisible(Node: PVirtualNode; Value: Boolean); procedure SetVisiblePath(Node: PVirtualNode; Value: Boolean); procedure StaticBackground(Source: TBitmap; Target: TCanvas; const Offset: TPoint; const R: TRect); procedure TileBackground(Source: TBitmap; Target: TCanvas; const Offset: TPoint; R: TRect); function ToggleCallback(Step, StepSize: Integer; Data: Pointer): Boolean; protected procedure CMColorChange(var Message: TLMessage); message CM_COLORCHANGED; procedure CMBiDiModeChanged(var Message: TLMessage); message CM_BIDIMODECHANGED; procedure CMDenySubclassing(var Message: TLMessage); message CM_DENYSUBCLASSING; //procedure CMDrag(var Message: TCMDrag); message CM_DRAG; procedure CMFontChanged(var Message: TLMessage); message CM_FONTCHANGED; procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW; procedure CMMouseLeave(var Message: TLMessage); message CM_MOUSELEAVE; procedure CMMouseWheel(var Message: TLMMouseEvent); message LM_MOUSEWHEEL; {$ifdef EnableNativeTVM} procedure TVMGetItem(var Message: TLMessage); message TVM_GETITEM; procedure TVMGetItemRect(var Message: TLMessage); message TVM_GETITEMRECT; procedure TVMGetNextItem(var Message: TLMessage); message TVM_GETNEXTITEM; {$endif} procedure WMCancelMode(var Message: TLMNoParams); message LM_CANCELMODE; procedure WMChangeState(var Message: TLMessage); message WM_CHANGESTATE; procedure WMChar(var Message: TLMChar); message LM_CHAR; procedure WMContextMenu(var Message: TLMContextMenu); message LM_CONTEXTMENU; procedure WMCopy(var Message: TLMNoParams); message LM_COPY; procedure WMCut(var Message: TLMNoParams); message LM_CUT; procedure WMEnable(var Message: TLMNoParams); message LM_ENABLE; procedure WMEraseBkgnd(var Message: TLMEraseBkgnd); message LM_ERASEBKGND; procedure WMGetDlgCode(var Message: TLMNoParams); message LM_GETDLGCODE; {$ifdef EnableAccessible} procedure WMGetObject(var Message: TLMessage);{ message WM_GETOBJECT;} {$endif} procedure WMHScroll(var Message: TLMHScroll); message LM_HSCROLL; procedure WMKeyDown(var Message: TLMKeyDown); message LM_KEYDOWN; procedure WMKeyUp(var Message: TLMKeyUp); message LM_KEYUP; procedure WMKillFocus(var Msg: TLMKillFocus); message LM_KILLFOCUS; procedure WMLButtonDblClk(var Message: TLMLButtonDblClk); message LM_LBUTTONDBLCLK; procedure WMLButtonDown(var Message: TLMLButtonDown); message LM_LBUTTONDOWN; procedure WMLButtonUp(var Message: TLMLButtonUp); message LM_LBUTTONUP; procedure WMMButtonDblClk(var Message: TLMMButtonDblClk); message LM_MBUTTONDBLCLK; procedure WMMButtonDown(var Message: TLMMButtonDown); message LM_MBUTTONDOWN; procedure WMMButtonUp(var Message: TLMMButtonUp); message LM_MBUTTONUP; {$ifdef EnableNCFunctions} procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE; procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST; procedure WMNCPaint(var Message: TRealWMNCPaint); message WM_NCPAINT; {$endif} procedure WMPaint(var Message: TLMPaint); message LM_PAINT; procedure WMPaste(var Message: TLMNoParams); message LM_PASTE; {$ifdef EnablePrintFunctions} procedure WMPrint(var Message: TWMPrint); message WM_PRINT; procedure WMPrintClient(var Message: TWMPrintClient); message WM_PRINTCLIENT; {$endif} procedure WMRButtonDblClk(var Message: TLMRButtonDblClk); message LM_RBUTTONDBLCLK; procedure WMRButtonDown(var Message: TLMRButtonDown); message LM_RBUTTONDOWN; procedure WMRButtonUp(var Message: TLMRButtonUp); message LM_RBUTTONUP; procedure WMSetFocus(var Msg: TLMSetFocus); message LM_SETFOCUS; procedure WMSize(var Message: TLMSize); message LM_SIZE; procedure WMTimer(var Message: TLMTimer); message LM_TIMER; {$ifdef ThemeSupport} {$ifdef Windows} procedure WMThemeChanged(var Message: TLMessage); message WM_THEMECHANGED; {$endif} {$endif ThemeSupport} procedure WMVScroll(var Message: TLMVScroll); message LM_VSCROLL; procedure AddToSelection(Node: PVirtualNode); overload; virtual; procedure AddToSelection(const NewItems: TNodeArray; NewLength: Integer; ForceInsert: Boolean = False); overload; virtual; procedure AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; out NextNonEmpty: TColumnIndex); virtual; procedure AdjustPanningCursor(X, Y: Integer); virtual; procedure AdviseChangeEvent(StructureChange: Boolean; Node: PVirtualNode; Reason: TChangeReason); virtual; function AllocateInternalDataArea(Size: Cardinal): Cardinal; virtual; procedure Animate(Steps, Duration: Cardinal; Callback: TVTAnimationCallback; Data: Pointer); virtual; procedure BeginOperation; function CalculateSelectionRect(X, Y: Integer): Boolean; virtual; function CanAutoScroll: Boolean; virtual; function CanScroll(const ClientMousePos: TPoint): Boolean; virtual; function CanShowDragImage: Boolean; virtual; procedure Change(Node: PVirtualNode); virtual; procedure ChangeScale(M, D: Integer); override; //lcl procedure CheckImageListNeeded; function CheckParentCheckState(Node: PVirtualNode; NewCheckState: TCheckState): Boolean; virtual; procedure ClearTempCache; virtual; function ColumnIsEmpty(Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; function ComputeRTLOffset(ExcludeScrollbar: Boolean = False): Integer; virtual; function CountLevelDifference(Node1, Node2: PVirtualNode): Integer; virtual; function CountVisibleChildren(Node: PVirtualNode): Cardinal; virtual; procedure CreateParams(var Params: TCreateParams); override; procedure CreateWnd; override; procedure DestroyHandle; override; procedure DetermineHiddenChildrenFlag(Node: PVirtualNode); virtual; procedure DetermineHiddenChildrenFlagAllNodes; virtual; procedure DetermineHitPositionLTR(var HitInfo: THitInfo; Offset, Right: Integer; Alignment: TAlignment); virtual; procedure DetermineHitPositionRTL(var HitInfo: THitInfo; Offset, Right: Integer; Alignment: TAlignment); virtual; function DetermineNextCheckState(CheckType: TCheckType; CheckState: TCheckState): TCheckState; virtual; function DetermineScrollDirections(X, Y: Integer): TScrollDirections; virtual; procedure DoAdvancedHeaderDraw(var PaintInfo: THeaderPaintInfo; const Elements: THeaderPaintElements); virtual; procedure DoAfterCellPaint(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const CellRect: TRect); virtual; procedure DoAfterItemErase(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect); virtual; procedure DoAfterItemPaint(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect); virtual; procedure DoAfterPaint(Canvas: TCanvas); virtual; procedure DoAutoScroll(X, Y: Integer); virtual; procedure DoAutoSize; override; function DoBeforeDrag(Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; procedure DoBeforeCellPaint(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect); virtual; procedure DoBeforeItemErase(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect; var Color: TColor; var EraseAction: TItemEraseAction); virtual; function DoBeforeItemPaint(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect): Boolean; virtual; procedure DoBeforePaint(Canvas: TCanvas); virtual; function DoCancelEdit: Boolean; virtual; procedure DoCanEdit(Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean); virtual; procedure DoChange(Node: PVirtualNode); virtual; procedure DoCheckClick(Node: PVirtualNode; NewCheckState: TCheckState); virtual; procedure DoChecked(Node: PVirtualNode); virtual; function DoChecking(Node: PVirtualNode; var NewCheckState: TCheckState): Boolean; virtual; procedure DoCollapsed(Node: PVirtualNode); virtual; function DoCollapsing(Node: PVirtualNode): Boolean; virtual; procedure DoColumnClick(Column: TColumnIndex; Shift: TShiftState); virtual; procedure DoColumnDblClick(Column: TColumnIndex; Shift: TShiftState); virtual; procedure DoColumnResize(Column: TColumnIndex); virtual; function DoCompare(Node1, Node2: PVirtualNode; Column: TColumnIndex): Integer; virtual; function DoCreateDataObject: IDataObject; virtual; function DoCreateDragManager: IVTDragManager; virtual; function DoCreateEditor(Node: PVirtualNode; Column: TColumnIndex): IVTEditLink; virtual; procedure DoDragging(P: TPoint); virtual; procedure DoDragExpand; virtual; function DoDragMsg(ADragMessage: TDragMessage; APosition: TPoint; ADragObject: TDragObject; ATarget: TControl; ADocking: Boolean): LRESULT; override; function DoDragOver(Source: TObject; Shift: TShiftState; State: TDragState; const Pt: TPoint; Mode: TDropMode; var Effect: LongWord): Boolean; virtual; procedure DoDragDrop(Source: TObject; DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState; const Pt: TPoint; var Effect: LongWord; Mode: TDropMode); virtual; procedure DoEdit; virtual; procedure DoEndDrag(Target: TObject; X, Y: Integer); override; function DoEndEdit: Boolean; virtual; procedure DoExpanded(Node: PVirtualNode); virtual; function DoExpanding(Node: PVirtualNode): Boolean; virtual; procedure DoFocusChange(Node: PVirtualNode; Column: TColumnIndex); virtual; function DoFocusChanging(OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex): Boolean; virtual; procedure DoFocusNode(Node: PVirtualNode; Ask: Boolean); virtual; procedure DoFreeNode(Node: PVirtualNode); virtual; function DoGetCellContentMargin(Node: PVirtualNode; Column: TColumnIndex; CellContentMarginType: TVTCellContentMarginType = ccmtAllSides; Canvas: TCanvas = nil): TPoint; virtual; procedure DoGetCursor(var Cursor: TCursor); virtual; procedure DoGetHeaderCursor(var Cursor: HCURSOR); virtual; function DoGetImageIndex(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var Index: Integer): TCustomImageList; virtual; procedure DoGetImageText(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var ImageText: String); virtual; procedure DoGetLineStyle(var Bits: Pointer); virtual; function DoGetNodeHint(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; virtual; function DoGetNodeTooltip(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; virtual; function DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer; virtual; function DoGetPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Position: TPoint): TPopupMenu; virtual; procedure DoGetUserClipboardFormats(var Formats: TFormatEtcArray); virtual; procedure DoHeaderClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure DoHeaderDblClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure DoHeaderImageClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure DoHeaderCheckBoxClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure DoHeaderDragged(Column: TColumnIndex; OldPosition: TColumnPosition); virtual; procedure DoHeaderDraggedOut(Column: TColumnIndex; const DropPosition: TPoint); virtual; function DoHeaderDragging(Column: TColumnIndex): Boolean; virtual; procedure DoHeaderDraw(Canvas: TCanvas; Column: TVirtualTreeColumn; const R: TRect; Hover, Pressed: Boolean; DropMark: TVTDropMarkMode); virtual; procedure DoHeaderDrawQueryElements(var PaintInfo: THeaderPaintInfo; var Elements: THeaderPaintElements); virtual; procedure DoHeaderMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure DoHeaderMouseMove(Shift: TShiftState; X, Y: Integer); virtual; procedure DoHeaderMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure DoHotChange(Old, New: PVirtualNode); virtual; function DoIncrementalSearch(Node: PVirtualNode; const Text: String): Integer; virtual; procedure DoInitChildren(Node: PVirtualNode; var ChildCount: Cardinal); virtual; procedure DoInitNode(Parent, Node: PVirtualNode; var InitStates: TVirtualNodeInitStates); virtual; function DoKeyAction(var CharCode: Word; var Shift: TShiftState): Boolean; virtual; procedure DoLoadUserData(Node: PVirtualNode; Stream: TStream); virtual; procedure DoMeasureItem(TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer); virtual; procedure DoNodeCopied(Node: PVirtualNode); virtual; function DoNodeCopying(Node, NewParent: PVirtualNode): Boolean; virtual; function DoNodeHeightDblClickResize(Node: PVirtualNode; Column: TColumnIndex; Shift: TShiftState; P: TPoint): Boolean; virtual; function DoNodeHeightTracking(Node: PVirtualNode; Column: TColumnIndex; Shift: TShiftState; var TrackPoint: TPoint; P: TPoint): Boolean; virtual; procedure DoNodeMoved(Node: PVirtualNode); virtual; function DoNodeMoving(Node, NewParent: PVirtualNode): Boolean; virtual; function DoPaintBackground(Canvas: TCanvas; const R: TRect): Boolean; virtual; procedure DoPaintDropMark(Canvas: TCanvas; Node: PVirtualNode; const R: TRect); virtual; procedure DoPaintNode(var PaintInfo: TVTPaintInfo); virtual; procedure DoPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Position: TPoint); virtual; function DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; virtual; procedure DoReset(Node: PVirtualNode); virtual; procedure DoSaveUserData(Node: PVirtualNode; Stream: TStream); virtual; procedure DoScroll(DeltaX, DeltaY: Integer); virtual; function DoSetOffsetXY(Value: TPoint; Options: TScrollUpdateOptions; ClipRect: PRect = nil): Boolean; virtual; procedure DoShowScrollbar(Bar: Integer; Show: Boolean); virtual; procedure DoStartDrag(var DragObject: TDragObject); override; procedure DoStateChange(Enter: TVirtualTreeStates; Leave: TVirtualTreeStates = []); virtual; procedure DoStructureChange(Node: PVirtualNode; Reason: TChangeReason); virtual; procedure DoTimerScroll; virtual; procedure DoUpdating(State: TVTUpdateState); virtual; function DoValidateCache: Boolean; virtual; procedure DragAndDrop(AllowedEffects: LongWord; DataObject: IDataObject; DragEffect: LongWord); virtual; procedure DragCanceled; override; function DragDrop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; reintroduce; virtual; function DragEnter(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; virtual; procedure DragFinished; virtual; procedure DragLeave; virtual; function DragOver(Source: TObject; KeyState: LongWord; DragState: TDragState; Pt: TPoint; var Effect: LongWord): HResult; reintroduce; virtual; procedure DrawDottedHLine(const PaintInfo: TVTPaintInfo; Left, Right, Top: Integer); virtual; procedure DrawDottedVLine(const PaintInfo: TVTPaintInfo; Top, Bottom, Left: Integer); virtual; procedure EndOperation; function FindNodeInSelection(P: PVirtualNode; out Index: Integer; LowBound, HighBound: Integer): Boolean; virtual; procedure FinishChunkHeader(Stream: TStream; StartPos, EndPos: Integer); virtual; procedure FontChanged(AFont: TObject); virtual; function GetBorderDimensions: TSize; virtual; function GetCheckImage(Node: PVirtualNode; ImgCheckType: TCheckType = ctNone; ImgCheckState: TCheckState = csUncheckedNormal; ImgEnabled: Boolean = False): Integer; virtual; function GetClientRect: TRect; override; function GetColumnClass: TVirtualTreeColumnClass; virtual; function GetHeaderClass: TVTHeaderClass; virtual; function GetHintWindowClass: THintWindowClass; virtual; procedure GetImageIndex(var Info: TVTPaintInfo; Kind: TVTImageKind; InfoIndex: TVTImageInfoIndex; DefaultImages: TCustomImageList); virtual; function GetMaxRightExtend: Cardinal; virtual; procedure GetNativeClipboardFormats(var Formats: TFormatEtcArray); virtual; function GetOperationCanceled: Boolean; function GetOptionsClass: TTreeOptionsClass; virtual; function GetTreeFromDataObject(const DataObject: IDataObject): TBaseVirtualTree; virtual; procedure HandleHotTrack(X, Y: Integer); virtual; procedure HandleIncrementalSearch(CharCode: Word); virtual; procedure HandleMouseDblClick(var Message: TLMMouse; const HitInfo: THitInfo); virtual; procedure HandleMouseDown(var Message: TLMMouse; var HitInfo: THitInfo); virtual; procedure HandleMouseUp(Keys: PtrUInt; const HitInfo: THitInfo); virtual; function HasImage(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex): Boolean; virtual; function HasPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Pos: TPoint): Boolean; virtual; procedure InitChildren(Node: PVirtualNode); virtual; procedure InitNode(Node: PVirtualNode); virtual; procedure InternalAddFromStream(Stream: TStream; Version: Integer; Node: PVirtualNode); virtual; function InternalAddToSelection(Node: PVirtualNode; ForceInsert: Boolean): Boolean; overload; function InternalAddToSelection(const NewItems: TNodeArray; NewLength: Integer; ForceInsert: Boolean): Boolean; overload; procedure InternalCacheNode(Node: PVirtualNode); virtual; procedure InternalClearSelection; virtual; procedure InternalConnectNode(Node, Destination: PVirtualNode; Target: TBaseVirtualTree; Mode: TVTNodeAttachMode); virtual; function InternalData(Node: PVirtualNode): Pointer; procedure InternalDisconnectNode(Node: PVirtualNode; KeepFocus: Boolean; Reindex: Boolean = True); virtual; function InternalGetNodeAt(X, Y: Integer): PVirtualNode; overload; function InternalGetNodeAt(X, Y: Integer; Relative: Boolean; var NodeTop: Integer): PVirtualNode; overload; procedure InternalRemoveFromSelection(Node: PVirtualNode); virtual; procedure InvalidateCache; procedure Loaded; override; procedure MainColumnChanged; virtual; procedure MarkCutCopyNodes; virtual; procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override; {$ifdef EnableNCFunctions} procedure OriginalWMNCPaint(DC: HDC); virtual; {$endif} procedure Paint; override; procedure PaintCheckImage(const PaintInfo: TVTPaintInfo); virtual; procedure PaintImage(var PaintInfo: TVTPaintInfo; ImageInfoIndex: TVTImageInfoIndex; DoOverlay: Boolean); virtual; procedure PaintNodeButton(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const R: TRect; ButtonX, ButtonY: Integer; BidiMode: TBiDiMode); virtual; procedure PaintTreeLines(const PaintInfo: TVTPaintInfo; VAlignment, IndentSize: Integer; LineImage: TLineImage); virtual; procedure PaintSelectionRectangle(Target: TCanvas; WindowOrgX: Integer; const SelectionRect: TRect; TargetRect: TRect); virtual; procedure PrepareCell(var PaintInfo: TVTPaintInfo; WindowOrgX, MaxWidth: Integer); virtual; function ReadChunk(Stream: TStream; Version: Integer; Node: PVirtualNode; ChunkType, ChunkSize: Integer): Boolean; virtual; procedure ReadNode(Stream: TStream; Version: Integer; Node: PVirtualNode); virtual; procedure RedirectFontChangeEvent(Canvas: TCanvas); virtual; procedure RemoveFromSelection(Node: PVirtualNode); virtual; function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; virtual; procedure ResetRangeAnchor; virtual; procedure RestoreFontChangeEvent(Canvas: TCanvas); virtual; procedure SelectNodes(StartNode, EndNode: PVirtualNode; AddOnly: Boolean); virtual; procedure SetFocusedNodeAndColumn(Node: PVirtualNode; Column: TColumnIndex); virtual; procedure SkipNode(Stream: TStream); virtual; procedure StartWheelPanning(const Position: TPoint); virtual; procedure StopWheelPanning; virtual; procedure StructureChange(Node: PVirtualNode; Reason: TChangeReason); virtual; function SuggestDropEffect(Source: TObject; Shift: TShiftState; const Pt: TPoint; AllowedEffects: LongWord): LongWord; virtual; procedure ToggleSelection(StartNode, EndNode: PVirtualNode); virtual; procedure UnselectNodes(StartNode, EndNode: PVirtualNode); virtual; //lcl procedure UpdateCheckImageList; procedure UpdateColumnCheckState(Col: TVirtualTreeColumn); procedure UpdateDesigner; virtual; procedure UpdateEditBounds; virtual; procedure UpdateHeaderRect; virtual; procedure UpdateWindowAndDragImage(const Tree: TBaseVirtualTree; TreeRect: TRect; UpdateNCArea, ReshowDragImage: Boolean); virtual; procedure ValidateCache; virtual; procedure ValidateNodeDataSize(var Size: Integer); virtual; procedure WndProc(var Message: TLMessage); override; procedure WriteChunks(Stream: TStream; Node: PVirtualNode); virtual; procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify; property AnimationDuration: Cardinal read FAnimationDuration write SetAnimationDuration default 200; property AutoExpandDelay: Cardinal read FAutoExpandDelay write FAutoExpandDelay default 1000; property AutoScrollDelay: Cardinal read FAutoScrollDelay write FAutoScrollDelay default 1000; property AutoScrollInterval: TAutoScrollInterval read FAutoScrollInterval write FAutoScrollInterval default 1; property Background: TPicture read FBackground write SetBackground; property BackgroundOffsetX: Integer index 0 read FBackgroundOffsetX write SetBackgroundOffset default 0; property BackgroundOffsetY: Integer index 1 read FBackgroundOffsetY write SetBackgroundOffset default 0; //property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle; property BottomSpace: Cardinal read FBottomSpace write SetBottomSpace default 0; property ButtonFillMode: TVTButtonFillMode read FButtonFillMode write SetButtonFillMode default fmTreeColor; property ButtonStyle: TVTButtonStyle read FButtonStyle write SetButtonStyle default bsRectangle; property ChangeDelay: Cardinal read FChangeDelay write FChangeDelay default 0; property CheckImageKind: TCheckImageKind read FCheckImageKind write SetCheckImageKind default ckSystemDefault; property ClipboardFormats: TClipboardFormats read FClipboardFormats write SetClipboardFormats; property Colors: TVTColors read FColors write SetColors; property CustomCheckImages: TBitmap read FCustomCheckImages write SetCustomCheckImages; property DefaultNodeHeight: Cardinal read FDefaultNodeHeight write SetDefaultNodeHeight default 18; property DefaultPasteMode: TVTNodeAttachMode read FDefaultPasteMode write FDefaultPasteMode default amAddChildLast; property DragHeight: Integer read FDragHeight write FDragHeight default 350; property DragImageKind: TVTDragImageKind read FDragImageKind write FDragImageKind default diComplete; property DragOperations: TDragOperations read FDragOperations write FDragOperations default [doCopy, doMove]; property DragSelection: TNodeArray read FDragSelection; property DragType: TVTDragType read FDragType write FDragType default dtOLE; property DragWidth: Integer read FDragWidth write FDragWidth default 200; property DrawSelectionMode: TVTDrawSelectionMode read FDrawSelectionMode write FDrawSelectionMode default smDottedRectangle; property EditColumn: TColumnIndex read FEditColumn write FEditColumn; property EditDelay: Cardinal read FEditDelay write FEditDelay default 1000; property Header: TVTHeader read FHeader write SetHeader; property HeaderRect: TRect read FHeaderRect; property HintMode: TVTHintMode read FHintMode write FHintMode default hmDefault; property HotCursor: TCursor read FHotCursor write FHotCursor default crDefault; property Images: TCustomImageList read FImages write SetImages; property IncrementalSearch: TVTIncrementalSearch read FIncrementalSearch write SetSearchOption default isNone; property IncrementalSearchDirection: TVTSearchDirection read FSearchDirection write FSearchDirection default sdForward; property IncrementalSearchStart: TVTSearchStart read FSearchStart write FSearchStart default ssFocusedNode; property IncrementalSearchTimeout: Cardinal read FSearchTimeout write FSearchTimeout default 1000; property Indent: Cardinal read FIndent write SetIndent default 18; property LastClickPos: TPoint read FLastClickPos write FLastClickPos; property LastDropMode: TDropMode read FLastDropMode write FlastDropMode; property LineMode: TVTLineMode read FLineMode write SetLineMode default lmNormal; property LineStyle: TVTLineStyle read FLineStyle write SetLineStyle default lsDotted; property Margin: Integer read FMargin write SetMargin default 4; property NodeAlignment: TVTNodeAlignment read FNodeAlignment write SetNodeAlignment default naProportional; property NodeDataSize: Integer read FNodeDataSize write SetNodeDataSize default -1; property OperationCanceled: Boolean read GetOperationCanceled; property RootNodeCount: Cardinal read GetRootNodeCount write SetRootNodeCount default 0; property ScrollBarOptions: TScrollBarOptions read FScrollBarOptions write SetScrollBarOptions; property SelectionBlendFactor: Byte read FSelectionBlendFactor write FSelectionBlendFactor default 128; property SelectionCurveRadius: Cardinal read FSelectionCurveRadius write SetSelectionCurveRadius default 0; property StateImages: TCustomImageList read FStateImages write SetStateImages; property TextMargin: Integer read FTextMargin write SetTextMargin default 4; property TotalInternalDataSize: Cardinal read FTotalInternalDataSize; property TreeOptions: TCustomVirtualTreeOptions read FOptions write SetOptions; property WantTabs: Boolean read FWantTabs write FWantTabs default False; property OnAdvancedHeaderDraw: TVTAdvancedHeaderPaintEvent read FOnAdvancedHeaderDraw write FOnAdvancedHeaderDraw; property OnAfterAutoFitColumn: TVTAfterAutoFitColumnEvent read FOnAfterAutoFitColumn write FOnAfterAutoFitColumn; property OnAfterAutoFitColumns: TVTAfterAutoFitColumnsEvent read FOnAfterAutoFitColumns write FOnAfterAutoFitColumns; property OnAfterCellPaint: TVTAfterCellPaintEvent read FOnAfterCellPaint write FOnAfterCellPaint; property OnAfterColumnExport : TVTColumnExportEvent read FOnAfterColumnExport write FOnAfterColumnExport; property OnAfterColumnWidthTracking: TVTAfterColumnWidthTrackingEvent read FOnAfterColumnWidthTracking write FOnAfterColumnWidthTracking; property OnAfterGetMaxColumnWidth: TVTAfterGetMaxColumnWidthEvent read FOnAfterGetMaxColumnWidth write FOnAfterGetMaxColumnWidth; property OnAfterHeaderExport: TVTTreeExportEvent read FOnBeforeHeaderExport write FOnBeforeHeaderExport; property OnAfterHeaderHeightTracking: TVTAfterHeaderHeightTrackingEvent read FOnAfterHeaderHeightTracking write FOnAfterHeaderHeightTracking; property OnAfterItemErase: TVTAfterItemEraseEvent read FOnAfterItemErase write FOnAfterItemErase; property OnAfterItemPaint: TVTAfterItemPaintEvent read FOnAfterItemPaint write FOnAfterItemPaint; property OnAfterNodeExport: TVTNodeExportEvent read FOnAfterNodeExport write FOnAfterNodeExport; property OnAfterPaint: TVTPaintEvent read FOnAfterPaint write FOnAfterPaint; property OnAfterTreeExport: TVTTreeExportEvent read FOnAfterTreeExport write FOnAfterTreeExport; property OnBeforeAutoFitColumn: TVTBeforeAutoFitColumnEvent read FOnBeforeAutoFitColumn write FOnBeforeAutoFitColumn; property OnBeforeAutoFitColumns: TVTBeforeAutoFitColumnsEvent read FOnBeforeAutoFitColumns write FOnBeforeAutoFitColumns; property OnBeforeCellPaint: TVTBeforeCellPaintEvent read FOnBeforeCellPaint write FOnBeforeCellPaint; property OnBeforeColumnExport: TVTColumnExportEvent read FOnBeforeColumnExport write FOnBeforeColumnExport; property OnBeforeColumnWidthTracking: TVTBeforeColumnWidthTrackingEvent read FOnBeforeColumnWidthTracking write FOnBeforeColumnWidthTracking; property OnBeforeGetMaxColumnWidth: TVTBeforeGetMaxColumnWidthEvent read FOnBeforeGetMaxColumnWidth write FOnBeforeGetMaxColumnWidth; property OnBeforeHeaderExport: TVTTreeExportEvent read FOnBeforeHeaderExport write FOnBeforeHeaderExport; property OnBeforeHeaderHeightTracking: TVTBeforeHeaderHeightTrackingEvent read FOnBeforeHeaderHeightTracking write FOnBeforeHeaderHeightTracking; property OnBeforeItemErase: TVTBeforeItemEraseEvent read FOnBeforeItemErase write FOnBeforeItemErase; property OnBeforeItemPaint: TVTBeforeItemPaintEvent read FOnBeforeItemPaint write FOnBeforeItemPaint; property OnBeforeNodeExport: TVTNodeExportEvent read FOnBeforeNodeExport write FOnBeforeNodeExport; property OnBeforePaint: TVTPaintEvent read FOnBeforePaint write FOnBeforePaint; property OnBeforeTreeExport: TVTTreeExportEvent read FOnBeforeTreeExport write FOnBeforeTreeExport; property OnCanSplitterResizeColumn: TVTCanSplitterResizeColumnEvent read FOnCanSplitterResizeColumn write FOnCanSplitterResizeColumn; property OnChange: TVTChangeEvent read FOnChange write FOnChange; property OnChecked: TVTChangeEvent read FOnChecked write FOnChecked; property OnChecking: TVTCheckChangingEvent read FOnChecking write FOnChecking; property OnCollapsed: TVTChangeEvent read FOnCollapsed write FOnCollapsed; property OnCollapsing: TVTChangingEvent read FOnCollapsing write FOnCollapsing; property OnColumnClick: TVTColumnClickEvent read FOnColumnClick write FOnColumnClick; property OnColumnDblClick: TVTColumnDblClickEvent read FOnColumnDblClick write FOnColumnDblClick; property OnColumnExport : TVTColumnExportEvent read FOnColumnExport write FOnColumnExport; property OnColumnResize: TVTHeaderNotifyEvent read FOnColumnResize write FOnColumnResize; property OnColumnWidthDblClickResize: TVTColumnWidthDblClickResizeEvent read FOnColumnWidthDblClickResize write FOnColumnWidthDblClickResize; property OnColumnWidthTracking: TVTColumnWidthTrackingEvent read FOnColumnWidthTracking write FOnColumnWidthTracking; property OnCompareNodes: TVTCompareEvent read FOnCompareNodes write FOnCompareNodes; property OnCreateDataObject: TVTCreateDataObjectEvent read FOnCreateDataObject write FOnCreateDataObject; property OnCreateDragManager: TVTCreateDragManagerEvent read FOnCreateDragManager write FOnCreateDragManager; property OnCreateEditor: TVTCreateEditorEvent read FOnCreateEditor write FOnCreateEditor; property OnDragAllowed: TVTDragAllowedEvent read FOnDragAllowed write FOnDragAllowed; property OnDragOver: TVTDragOverEvent read FOnDragOver write FOnDragOver; property OnDragDrop: TVTDragDropEvent read FOnDragDrop write FOnDragDrop; property OnEditCancelled: TVTEditCancelEvent read FOnEditCancelled write FOnEditCancelled; property OnEditing: TVTEditChangingEvent read FOnEditing write FOnEditing; property OnEdited: TVTEditChangeEvent read FOnEdited write FOnEdited; property OnExpanded: TVTChangeEvent read FOnExpanded write FOnExpanded; property OnExpanding: TVTChangingEvent read FOnExpanding write FOnExpanding; property OnFocusChanged: TVTFocusChangeEvent read FOnFocusChanged write FOnFocusChanged; property OnFocusChanging: TVTFocusChangingEvent read FOnFocusChanging write FOnFocusChanging; property OnFreeNode: TVTFreeNodeEvent read FOnFreeNode write FOnFreeNode; property OnGetCellIsEmpty: TVTGetCellIsEmptyEvent read FOnGetCellIsEmpty write FOnGetCellIsEmpty; property OnGetCursor: TVTGetCursorEvent read FOnGetCursor write FOnGetCursor; property OnGetHeaderCursor: TVTGetHeaderCursorEvent read FOnGetHeaderCursor write FOnGetHeaderCursor; property OnGetHelpContext: TVTHelpContextEvent read FOnGetHelpContext write FOnGetHelpContext; property OnGetImageIndex: TVTGetImageEvent read FOnGetImage write FOnGetImage; property OnGetImageIndexEx: TVTGetImageExEvent read FOnGetImageEx write FOnGetImageEx; property OnGetImageText: TVTGetImageTextEvent read FOnGetImageText write FOnGetImageText; property OnGetLineStyle: TVTGetLineStyleEvent read FOnGetLineStyle write FOnGetLineStyle; property OnGetNodeDataSize: TVTGetNodeDataSizeEvent read FOnGetNodeDataSize write FOnGetNodeDataSize; property OnGetPopupMenu: TVTPopupEvent read FOnGetPopupMenu write FOnGetPopupMenu; property OnGetUserClipboardFormats: TVTGetUserClipboardFormatsEvent read FOnGetUserClipboardFormats write FOnGetUserClipboardFormats; property OnHeaderCheckBoxClick: TVTHeaderClickEvent read FOnHeaderCheckBoxClick write FOnHeaderCheckBoxClick; property OnHeaderClick: TVTHeaderClickEvent read FOnHeaderClick write FOnHeaderClick; property OnHeaderDblClick: TVTHeaderClickEvent read FOnHeaderDblClick write FOnHeaderDblClick; property OnHeaderDragged: TVTHeaderDraggedEvent read FOnHeaderDragged write FOnHeaderDragged; property OnHeaderDraggedOut: TVTHeaderDraggedOutEvent read FOnHeaderDraggedOut write FOnHeaderDraggedOut; property OnHeaderDragging: TVTHeaderDraggingEvent read FOnHeaderDragging write FOnHeaderDragging; property OnHeaderDraw: TVTHeaderPaintEvent read FOnHeaderDraw write FOnHeaderDraw; property OnHeaderDrawQueryElements: TVTHeaderPaintQueryElementsEvent read FOnHeaderDrawQueryElements write FOnHeaderDrawQueryElements; property OnHeaderHeightTracking: TVTHeaderHeightTrackingEvent read FOnHeaderHeightTracking write FOnHeaderHeightTracking; property OnHeaderHeightDblClickResize: TVTHeaderHeightDblClickResizeEvent read FOnHeaderHeightDblClickResize write FOnHeaderHeightDblClickResize; property OnHeaderImageClick: TVTHeaderClickEvent read FOnHeaderImageClick write FOnHeaderImageClick; property OnHeaderMouseDown: TVTHeaderMouseEvent read FOnHeaderMouseDown write FOnHeaderMouseDown; property OnHeaderMouseMove: TVTHeaderMouseMoveEvent read FOnHeaderMouseMove write FOnHeaderMouseMove; property OnHeaderMouseUp: TVTHeaderMouseEvent read FOnHeaderMouseUp write FOnHeaderMouseUp; property OnHotChange: TVTHotNodeChangeEvent read FOnHotChange write FOnHotChange; property OnIncrementalSearch: TVTIncrementalSearchEvent read FOnIncrementalSearch write FOnIncrementalSearch; property OnInitChildren: TVTInitChildrenEvent read FOnInitChildren write FOnInitChildren; property OnInitNode: TVTInitNodeEvent read FOnInitNode write FOnInitNode; property OnKeyAction: TVTKeyActionEvent read FOnKeyAction write FOnKeyAction; property OnLoadNode: TVTSaveNodeEvent read FOnLoadNode write FOnLoadNode; property OnMeasureItem: TVTMeasureItemEvent read FOnMeasureItem write FOnMeasureItem; property OnNodeCopied: TVTNodeCopiedEvent read FOnNodeCopied write FOnNodeCopied; property OnNodeCopying: TVTNodeCopyingEvent read FOnNodeCopying write FOnNodeCopying; property OnNodeExport: TVTNodeExportEvent read FOnNodeExport write FOnNodeExport; property OnNodeHeightTracking: TVTNodeHeightTrackingEvent read FOnNodeHeightTracking write FOnNodeHeightTracking; property OnNodeHeightDblClickResize: TVTNodeHeightDblClickResizeEvent read FOnNodeHeightDblClickResize write FOnNodeHeightDblClickResize; property OnNodeMoved: TVTNodeMovedEvent read FOnNodeMoved write FOnNodeMoved; property OnNodeMoving: TVTNodeMovingEvent read FOnNodeMoving write FOnNodeMoving; property OnPaintBackground: TVTBackgroundPaintEvent read FOnPaintBackground write FOnPaintBackground; property OnRenderOLEData: TVTRenderOLEDataEvent read FOnRenderOLEData write FOnRenderOLEData; property OnResetNode: TVTChangeEvent read FOnResetNode write FOnResetNode; property OnSaveNode: TVTSaveNodeEvent read FOnSaveNode write FOnSaveNode; property OnScroll: TVTScrollEvent read FOnScroll write FOnScroll; property OnShowScrollbar: TVTScrollbarShowEvent read FOnShowScrollbar write FOnShowScrollbar; property OnStateChange: TVTStateChangeEvent read FOnStateChange write FOnStateChange; property OnStructureChange: TVTStructureChangeEvent read FOnStructureChange write FOnStructureChange; property OnUpdating: TVTUpdatingEvent read FOnUpdating write FOnUpdating; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function AbsoluteIndex(Node: PVirtualNode): Cardinal; function AddChild(Parent: PVirtualNode; UserData: Pointer = nil): PVirtualNode; virtual; procedure AddFromStream(Stream: TStream; TargetNode: PVirtualNode); procedure AfterConstruction; override; procedure Assign(Source: TPersistent); override; procedure BeginDrag(Immediate: Boolean; Threshold: Integer = -1); procedure BeginSynch; procedure BeginUpdate; virtual; procedure CancelCutOrCopy; function CancelEditNode: Boolean; procedure CancelOperation; function CanEdit(Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; procedure Clear; virtual; procedure ClearChecked; procedure ClearSelection; function CopyTo(Source: PVirtualNode; Tree: TBaseVirtualTree; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean): PVirtualNode; overload; function CopyTo(Source, Target: PVirtualNode; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean): PVirtualNode; overload; procedure CopyToClipBoard; virtual; procedure CutToClipBoard; virtual; procedure DefaultHandler(var AMessage); override; procedure DeleteChildren(Node: PVirtualNode; ResetHasChildren: Boolean = False); procedure DeleteNode(Node: PVirtualNode; Reindex: Boolean = True); procedure DeleteSelectedNodes; virtual; function Dragging: Boolean; function EditNode(Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; function EndEditNode: Boolean; procedure EndSynch; procedure EndUpdate; virtual; function ExecuteAction(Action: TBasicAction): Boolean; override; procedure FinishCutOrCopy; procedure FlushClipboard; procedure FullCollapse(Node: PVirtualNode = nil); virtual; procedure FullExpand(Node: PVirtualNode = nil); virtual; {$ifndef fpc} function GetControlsAlignment: TAlignment; override; {$endif} function GetDisplayRect(Node: PVirtualNode; Column: TColumnIndex; TextOnly: Boolean; Unclipped: Boolean = False; ApplyCellContentMargin: Boolean = False): TRect; function GetFirst(ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetFirstChecked(State: TCheckState = csCheckedNormal; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetFirstChild(Node: PVirtualNode): PVirtualNode; function GetFirstCutCopy(ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetFirstInitialized(ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetFirstLeaf: PVirtualNode; function GetFirstLevel(NodeLevel: Cardinal): PVirtualNode; function GetFirstNoInit(ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetFirstSelected(ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetFirstVisible(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetFirstVisibleChild(Node: PVirtualNode): PVirtualNode; function GetFirstVisibleChildNoInit(Node: PVirtualNode): PVirtualNode; function GetFirstVisibleNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode; procedure GetHitTestInfoAt(X, Y: Integer; Relative: Boolean; var HitInfo: THitInfo); virtual; function GetLast(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetLastInitialized(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetLastNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetLastChild(Node: PVirtualNode): PVirtualNode; function GetLastChildNoInit(Node: PVirtualNode): PVirtualNode; function GetLastVisible(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetLastVisibleChild(Node: PVirtualNode): PVirtualNode; function GetLastVisibleChildNoInit(Node: PVirtualNode): PVirtualNode; function GetLastVisibleNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetMaxColumnWidth(Column: TColumnIndex; UseSmartColumnWidth: Boolean = False): Integer; function GetNext(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextCutCopy(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextInitialized(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextLeaf(Node: PVirtualNode): PVirtualNode; function GetNextLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode; function GetNextNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextSibling(Node: PVirtualNode): PVirtualNode; function GetNextSiblingNoInit(Node: PVirtualNode): PVirtualNode; function GetNextVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetNextVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetNextVisibleSibling(Node: PVirtualNode): PVirtualNode; function GetNextVisibleSiblingNoInit(Node: PVirtualNode): PVirtualNode; function GetNodeAt(X, Y: Integer): PVirtualNode; overload; function GetNodeAt(X, Y: Integer; Relative: Boolean; var NodeTop: Integer): PVirtualNode; overload; function GetNodeData(Node: PVirtualNode): Pointer; function GetNodeLevel(Node: PVirtualNode): Cardinal; function GetPrevious(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetPreviousChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetPreviousCutCopy(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetPreviousInitialized(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetPreviousLeaf(Node: PVirtualNode): PVirtualNode; function GetPreviousLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode; function GetPreviousNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetPreviousSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetPreviousSibling(Node: PVirtualNode): PVirtualNode; function GetPreviousSiblingNoInit(Node: PVirtualNode): PVirtualNode; function GetPreviousVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetPreviousVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetPreviousVisibleSibling(Node: PVirtualNode): PVirtualNode; function GetPreviousVisibleSiblingNoInit(Node: PVirtualNode): PVirtualNode; function GetSortedCutCopySet(Resolve: Boolean): TNodeArray; function GetSortedSelection(Resolve: Boolean): TNodeArray; procedure GetTextInfo(Node: PVirtualNode; Column: TColumnIndex; const AFont: TFont; var R: TRect; out Text: String); virtual; function GetTreeRect: TRect; function GetVisibleParent(Node: PVirtualNode): PVirtualNode; function HasAsParent(Node, PotentialParent: PVirtualNode): Boolean; function InsertNode(Node: PVirtualNode; Mode: TVTNodeAttachMode; UserData: Pointer = nil): PVirtualNode; procedure InvalidateChildren(Node: PVirtualNode; Recursive: Boolean); procedure InvalidateColumn(Column: TColumnIndex); function InvalidateNode(Node: PVirtualNode): TRect; virtual; procedure InvalidateToBottom(Node: PVirtualNode); procedure InvertSelection(VisibleOnly: Boolean); function IsEditing: Boolean; function IsMouseSelecting: Boolean; function IterateSubtree(Node: PVirtualNode; Callback: TVTGetNodeProc; Data: Pointer; Filter: TVirtualNodeStates = []; DoInit: Boolean = False; ChildNodesOnly: Boolean = False): PVirtualNode; procedure LoadFromFile(const FileName: TFileName); virtual; procedure LoadFromStream(Stream: TStream); virtual; procedure MeasureItemHeight(const Canvas: TCanvas; Node: PVirtualNode); procedure MoveTo(Source, Target: PVirtualNode; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean); overload; procedure MoveTo(Node: PVirtualNode; Tree: TBaseVirtualTree; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean); overload; procedure PaintTree(TargetCanvas: TCanvas; const Window: TRect; Target: TPoint; PaintOptions: TVTInternalPaintOptions; PixelFormat: TPixelFormat = pfDevice); function PasteFromClipboard: Boolean; virtual; procedure PrepareDragImage(HotSpot: TPoint; const DataObject: IDataObject); {$ifdef EnablePrint} procedure Print(Printer: TPrinter; PrintHeader: Boolean); {$endif} function ProcessDrop(DataObject: IDataObject; TargetNode: PVirtualNode; var Effect: LongWord; Mode: TVTNodeAttachMode): Boolean; function ProcessOLEData(Source: TBaseVirtualTree; DataObject: IDataObject; TargetNode: PVirtualNode; Mode: TVTNodeAttachMode; Optimized: Boolean): Boolean; procedure RepaintNode(Node: PVirtualNode); procedure ReinitChildren(Node: PVirtualNode; Recursive: Boolean); virtual; procedure ReinitNode(Node: PVirtualNode; Recursive: Boolean); virtual; procedure ResetNode(Node: PVirtualNode); virtual; procedure SaveToFile(const FileName: TFileName); procedure SaveToStream(Stream: TStream; Node: PVirtualNode = nil); virtual; function ScrollIntoView(Node: PVirtualNode; Center: Boolean; Horizontally: Boolean = False): Boolean; overload; function ScrollIntoView(Column: TColumnIndex; Center: Boolean): Boolean; overload; procedure SelectAll(VisibleOnly: Boolean); procedure Sort(Node: PVirtualNode; Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual; procedure SortTree(Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual; procedure ToggleNode(Node: PVirtualNode); function UpdateAction(Action: TBasicAction): Boolean; override; procedure UpdateHorizontalScrollBar(DoRepaint: Boolean); procedure UpdateScrollBars(DoRepaint: Boolean); virtual; procedure UpdateVerticalScrollBar(DoRepaint: Boolean); //lcl: reenable in case TControl implementation change to match Delphi // function UseRightToLeftReading: Boolean; procedure ValidateChildren(Node: PVirtualNode; Recursive: Boolean); procedure ValidateNode(Node: PVirtualNode; Recursive: Boolean); {$ifdef EnableAccessible} property Accessible: IAccessible read FAccessible write FAccessible; property AccessibleItem: IAccessible read FAccessibleItem write FAccessibleItem; property AccessibleName: string read FAccessibleName write FAccessibleName; {$endif} property BottomNode: PVirtualNode read GetBottomNode write SetBottomNode; property CheckedCount: Integer read GetCheckedCount; property CheckImages: TBitmap read FCheckImages; property CheckState[Node: PVirtualNode]: TCheckState read GetCheckState write SetCheckState; property CheckType[Node: PVirtualNode]: TCheckType read GetCheckType write SetCheckType; property ChildCount[Node: PVirtualNode]: Cardinal read GetChildCount write SetChildCount; property ChildrenInitialized[Node: PVirtualNode]: Boolean read GetChildrenInitialized; property CutCopyCount: Integer read GetCutCopyCount; property DragImage: TVTDragImage read FDragImage; property VTVDragManager: IVTDragManager read GetDragManager; property DropTargetNode: PVirtualNode read FDropTargetNode; property EditLink: IVTEditLink read FEditLink; property Expanded[Node: PVirtualNode]: Boolean read GetExpanded write SetExpanded; property FocusedColumn: TColumnIndex read FFocusedColumn write SetFocusedColumn default InvalidColumn; property FocusedNode: PVirtualNode read FFocusedNode write SetFocusedNode; property Font; property FullyVisible[Node: PVirtualNode]: Boolean read GetFullyVisible write SetFullyVisible; property HasChildren[Node: PVirtualNode]: Boolean read GetHasChildren write SetHasChildren; property HotNode: PVirtualNode read FCurrentHotNode; property IsDisabled[Node: PVirtualNode]: Boolean read GetDisabled write SetDisabled; property IsVisible[Node: PVirtualNode]: Boolean read GetVisible write SetVisible; property MultiLine[Node: PVirtualNode]: Boolean read GetMultiline write SetMultiline; property NodeHeight[Node: PVirtualNode]: Cardinal read GetNodeHeight write SetNodeHeight; property NodeParent[Node: PVirtualNode]: PVirtualNode read GetNodeParent write SetNodeParent; property OffsetX: Integer read FOffsetX write SetOffsetX; property OffsetXY: TPoint read GetOffsetXY write SetOffsetXY; property OffsetY: Integer read FOffsetY write SetOffsetY; property RootNode: PVirtualNode read FRoot; property SearchBuffer: String read FSearchBuffer; property Selected[Node: PVirtualNode]: Boolean read GetSelected write SetSelected; property SelectionLocked: Boolean read FSelectionLocked write FSelectionLocked; property TotalCount: Cardinal read GetTotalCount; property TreeStates: TVirtualTreeStates read FStates write FStates; property SelectedCount: Integer read FSelectionCount; property TopNode: PVirtualNode read GetTopNode write SetTopNode; property VerticalAlignment[Node: PVirtualNode]: Byte read GetVerticalAlignment write SetVerticalAlignment; property VisibleCount: Cardinal read FVisibleCount; property VisiblePath[Node: PVirtualNode]: Boolean read GetVisiblePath write SetVisiblePath; property UpdateCount: Cardinal read FUpdateCount; end; // --------- TCustomVirtualStringTree // Options regarding strings (useful only for the string tree and descendants): TVTStringOption = ( toSaveCaptions, // If set then the caption is automatically saved with the tree node, regardless of what is // saved in the user data. toShowStaticText, // Show static text in a caption which can be differently formatted than the caption // but cannot be edited. toAutoAcceptEditChange // Automatically accept changes during edit if the user finishes editing other then // VK_RETURN or ESC. If not set then changes are cancelled. ); TVTStringOptions = set of TVTStringOption; const DefaultStringOptions = [toSaveCaptions, toAutoAcceptEditChange]; type TCustomStringTreeOptions = class(TCustomVirtualTreeOptions) private FStringOptions: TVTStringOptions; procedure SetStringOptions(const Value: TVTStringOptions); protected property StringOptions: TVTStringOptions read FStringOptions write SetStringOptions default DefaultStringOptions; public constructor Create(AOwner: TBaseVirtualTree); override; procedure AssignTo(Dest: TPersistent); override; end; TStringTreeOptions = class(TCustomStringTreeOptions) published property AnimationOptions; property AutoOptions; property ExportMode; property MiscOptions; property PaintOptions; property SelectionOptions; property StringOptions; end; TCustomVirtualStringTree = class; // Edit support classes. TStringEditLink = class; { TVTEdit } TVTEdit = class(TCustomEdit) private procedure CMAutoAdjust(var Message: TLMessage); message CM_AUTOADJUST; procedure CMExit(var Message: TLMessage); message CM_EXIT; procedure CNCommand(var Message: TLMCommand); message CN_COMMAND; procedure DoRelease(Data: PtrInt); procedure WMChar(var Message: TLMChar); message LM_CHAR; procedure WMDestroy(var Message: TLMDestroy); message LM_DESTROY; procedure WMGetDlgCode(var Message: TLMNoParams); message LM_GETDLGCODE; procedure WMKeyDown(var Message: TLMKeyDown); message LM_KEYDOWN; protected FRefLink: IVTEditLink; FLink: TStringEditLink; procedure AutoAdjustSize; virtual; procedure CreateParams(var Params: TCreateParams); override; public constructor Create(Link: TStringEditLink); reintroduce; procedure Release; property AutoSelect; property AutoSize; property BorderStyle; property CharCase; //property HideSelection; property MaxLength; //property OEMConvert; property PasswordChar; end; TStringEditLink = class(TInterfacedObject, IVTEditLink) private FEdit: TVTEdit; // A normal custom edit control. procedure SetEdit(const Value: TVTEdit); protected FTree: TCustomVirtualStringTree; // A back reference to the tree calling. FNode: PVirtualNode; // The node to be edited. FColumn: TColumnIndex; // The column of the node. FAlignment: TAlignment; FTextBounds: TRect; // Smallest rectangle around the text. FStopping: Boolean; // Set to True when the edit link requests stopping the edit action. public constructor Create; virtual; destructor Destroy; override; function BeginEdit: Boolean; virtual; stdcall; function CancelEdit: Boolean; virtual; stdcall; property Edit: TVTEdit read FEdit write SetEdit; function EndEdit: Boolean; virtual; stdcall; function GetBounds: TRect; virtual; stdcall; function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; stdcall; procedure ProcessMessage(var Message: TLMessage); virtual; stdcall; procedure SetBounds(R: TRect); virtual; stdcall; end; // Describes the type of text to return in the text and draw info retrival events. TVSTTextType = ( ttNormal, // normal label of the node, this is also the text which can be edited ttStatic // static (non-editable) text after the normal text ); // Describes the source to use when converting a string tree into a string for clipboard etc. TVSTTextSourceType = ( tstAll, // All nodes are rendered. Initialization is done on the fly. tstInitialized, // Only initialized nodes are rendered. tstSelected, // Only selected nodes are rendered. tstCutCopySet, // Only nodes currently marked as being in the cut/copy clipboard set are rendered. tstVisible // Only visible nodes are rendered. ); TVTPaintText = procedure(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType) of object; TVSTGetTextEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: String) of object; TVSTGetHintEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: String) of object; // New text can only be set for variable caption. TVSTNewTextEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; const NewText: String) of object; TVSTShortenStringEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const S: String; TextSpace: Integer; var Result: String; var Done: Boolean) of object; TVTMeasureTextWidthEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: String; var Width: Integer) of object; TVTDrawTextEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: String; const CellRect: TRect; var DefaultDraw: Boolean) of object; // Helper class to speed up rendering text formats for clipboard and drag'n drop transfers. { TBufferedUTF8String } TBufferedUTF8String = class private FStart, FPosition, FEnd: PChar; function GetAsAnsiString: AnsiString; function GetAsUTF16String: UnicodeString; function GetAsUTF8String: String; public destructor Destroy; override; procedure Add(const S: String); procedure AddNewLine; property AsAnsiString: AnsiString read GetAsAnsiString; property AsUTF8String: String read GetAsUTF8String; property AsUTF16String: UnicodeString read GetAsUTF16String; end; { TCustomVirtualStringTree } TCustomVirtualStringTree = class(TBaseVirtualTree) private FDefaultText: String; // text to show if there's no OnGetText event handler (e.g. at design time) FTextHeight: Integer; // true size of the font FEllipsisWidth: Integer; // width of '...' for the current font FInternalDataOffset: Cardinal; // offset to the internal data of the string tree FOnPaintText: TVTPaintText; // triggered before either normal or fixed text is painted to allow // even finer customization (kind of sub cell painting) FOnGetText: TVSTGetTextEvent; // used to retrieve the string to be displayed for a specific node FOnGetHint: TVSTGetHintEvent; // used to retrieve the hint to be displayed for a specific node FOnNewText: TVSTNewTextEvent; // used to notify the application about an edited node caption FOnShortenString: TVSTShortenStringEvent; // used to allow the application a customized string shortage FOnMeasureTextWidth: TVTMeasureTextWidthEvent; // used to adjust the width of the cells FOnDrawText: TVTDrawTextEvent; // used to custom draw the node text procedure AddContentToBuffer(Buffer: TBufferedUTF8String; Source: TVSTTextSourceType; const Separator: String); function GetImageText(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex): String; procedure GetRenderStartValues(Source: TVSTTextSourceType; out Node: PVirtualNode; out NextNodeProc: TGetNextNodeProc); function GetOptions: TCustomStringTreeOptions; function GetText(Node: PVirtualNode; Column: TColumnIndex): String; procedure InitializeTextProperties(var PaintInfo: TVTPaintInfo); procedure PaintNormalText(var PaintInfo: TVTPaintInfo; TextOutFlags: Integer; Text: String); procedure PaintStaticText(const PaintInfo: TVTPaintInfo; TextOutFlags: Integer; const Text: String); procedure SetDefaultText(const Value: String); procedure SetOptions(const Value: TCustomStringTreeOptions); procedure SetText(Node: PVirtualNode; Column: TColumnIndex; const Value: String); procedure CMFontChanged(var Msg: TLMessage); message CM_FONTCHANGED; protected procedure AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; out NextNonEmpty: TColumnIndex); override; function CanExportNode(Node: PVirtualNode): Boolean; function CalculateTextWidth(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: String): Integer; virtual; function ColumnIsEmpty(Node: PVirtualNode; Column: TColumnIndex): Boolean; override; function DoCreateEditor(Node: PVirtualNode; Column: TColumnIndex): IVTEditLink; override; function DoGetNodeHint(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; override; function DoGetNodeTooltip(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; override; function DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer; override; procedure DoGetText(Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var Text: String); virtual; function DoIncrementalSearch(Node: PVirtualNode; const Text: String): Integer; override; procedure DoNewText(Node: PVirtualNode; Column: TColumnIndex; const Text: String); virtual; procedure DoPaintNode(var PaintInfo: TVTPaintInfo); override; procedure DoPaintText(Node: PVirtualNode; const Canvas: TCanvas; Column: TColumnIndex; TextType: TVSTTextType); virtual; function DoShortenString(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const S: String; Width: Integer; EllipsisWidth: Integer = 0): String; virtual; procedure DoTextDrawing(var PaintInfo: TVTPaintInfo; const Text: String; CellRect: TRect; DrawFormat: Cardinal); virtual; function DoTextMeasuring(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: String): Integer; virtual; function GetOptionsClass: TTreeOptionsClass; override; function InternalData(Node: PVirtualNode): Pointer; procedure MainColumnChanged; override; function ReadChunk(Stream: TStream; Version: Integer; Node: PVirtualNode; ChunkType, ChunkSize: Integer): Boolean; override; function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; override; procedure WriteChunks(Stream: TStream; Node: PVirtualNode); override; property DefaultText: String read FDefaultText write SetDefaultText; property EllipsisWidth: Integer read FEllipsisWidth; property TreeOptions: TCustomStringTreeOptions read GetOptions write SetOptions; property OnGetHint: TVSTGetHintEvent read FOnGetHint write FOnGetHint; property OnGetText: TVSTGetTextEvent read FOnGetText write FOnGetText; property OnNewText: TVSTNewTextEvent read FOnNewText write FOnNewText; property OnPaintText: TVTPaintText read FOnPaintText write FOnPaintText; property OnShortenString: TVSTShortenStringEvent read FOnShortenString write FOnShortenString; property OnMeasureTextWidth: TVTMeasureTextWidthEvent read FOnMeasureTextWidth write FOnMeasureTextWidth; property OnDrawText: TVTDrawTextEvent read FOnDrawText write FOnDrawText; public constructor Create(AOwner: TComponent); override; function ComputeNodeHeight(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; S: String = ''): Integer; virtual; function ContentToClipboard(Format: Word; Source: TVSTTextSourceType): HGLOBAL; procedure ContentToCustom(Source: TVSTTextSourceType); function ContentToHTML(Source: TVSTTextSourceType; const Caption: String = ''): String; function ContentToRTF(Source: TVSTTextSourceType): AnsiString; function ContentToAnsi(Source: TVSTTextSourceType; const Separator: String): AnsiString; function ContentToText(Source: TVSTTextSourceType; const Separator: String): AnsiString; inline; function ContentToUnicode(Source: TVSTTextSourceType; const Separator: String): UnicodeString; inline; function ContentToUTF16(Source: TVSTTextSourceType; const Separator: String): UnicodeString; function ContentToUTF8(Source: TVSTTextSourceType; const Separator: String): String; {$ifndef LCLWin32} procedure CopyToClipBoard; override; procedure CutToClipBoard; override; {$endif} procedure GetTextInfo(Node: PVirtualNode; Column: TColumnIndex; const AFont: TFont; var R: TRect; out Text: String); override; function InvalidateNode(Node: PVirtualNode): TRect; override; function Path(Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; Delimiter: Char): String; procedure ReinitNode(Node: PVirtualNode; Recursive: Boolean); override; property ImageText[Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex]: String read GetImageText; property Text[Node: PVirtualNode; Column: TColumnIndex]: String read GetText write SetText; end; TVirtualStringTree = class(TCustomVirtualStringTree) private function GetOptions: TStringTreeOptions; procedure SetOptions(const Value: TStringTreeOptions); protected function GetOptionsClass: TTreeOptionsClass; override; public property Canvas; published {$ifdef EnableAccessible} property AccessibleName; {$endif} property Action; property Align; property Alignment; property Anchors; property AnimationDuration; property AutoExpandDelay; property AutoScrollDelay; property AutoScrollInterval; property Background; property BackgroundOffsetX; property BackgroundOffsetY; property BiDiMode; //property BevelEdges; //property BevelInner; //property BevelOuter; //property BevelKind; //property BevelWidth; property BorderSpacing; property BorderStyle default bsSingle; property BottomSpace; property ButtonFillMode; property ButtonStyle; property BorderWidth; property ChangeDelay; property CheckImageKind; property ClipboardFormats; property Color; property Colors; property Constraints; //todo: see a way to set CustomCheckImages at design time //property CustomCheckImages; property DefaultNodeHeight; property DefaultPasteMode; property DefaultText; property DragCursor; property DragHeight; property DragKind; property DragImageKind; property DragMode; property DragOperations; property DragType; property DragWidth; property DrawSelectionMode; property EditDelay; property Enabled; property Font; property Header; property HintMode; property HotCursor; property Images; property IncrementalSearch; property IncrementalSearchDirection; property IncrementalSearchStart; property IncrementalSearchTimeout; property Indent; property LineMode; property LineStyle; property Margin; property NodeAlignment; property NodeDataSize; property OperationCanceled; property ParentBiDiMode; property ParentColor default False; property ParentFont; property ParentShowHint; property PopupMenu; property RootNodeCount; property ScrollBarOptions; property SelectionBlendFactor; property SelectionCurveRadius; property ShowHint; property StateImages; property TabOrder; property TabStop default True; property TextMargin; property TreeOptions: TStringTreeOptions read GetOptions write SetOptions; property Visible; property WantTabs; property OnAdvancedHeaderDraw; property OnAfterAutoFitColumn; property OnAfterAutoFitColumns; property OnAfterCellPaint; property OnAfterColumnExport; property OnAfterColumnWidthTracking; property OnAfterGetMaxColumnWidth; property OnAfterHeaderExport; property OnAfterHeaderHeightTracking; property OnAfterItemErase; property OnAfterItemPaint; property OnAfterNodeExport; property OnAfterPaint; property OnAfterTreeExport; property OnBeforeAutoFitColumn; property OnBeforeAutoFitColumns; property OnBeforeCellPaint; property OnBeforeColumnExport; property OnBeforeColumnWidthTracking; property OnBeforeGetMaxColumnWidth; property OnBeforeHeaderExport; property OnBeforeHeaderHeightTracking; property OnBeforeItemErase; property OnBeforeItemPaint; property OnBeforeNodeExport; property OnBeforePaint; property OnBeforeTreeExport; property OnCanSplitterResizeColumn; property OnChange; property OnChecked; property OnChecking; property OnClick; property OnCollapsed; property OnCollapsing; property OnColumnClick; property OnColumnDblClick; property OnColumnExport; property OnColumnResize; property OnColumnWidthDblClickResize; property OnColumnWidthTracking; property OnCompareNodes; property OnContextPopup; property OnCreateDataObject; property OnCreateDragManager; property OnCreateEditor; property OnDblClick; property OnDragAllowed; property OnDragOver; property OnDragDrop; property OnDrawText; property OnEditCancelled; property OnEdited; property OnEditing; property OnEndDock; property OnEndDrag; property OnEnter; property OnExit; property OnExpanded; property OnExpanding; property OnFocusChanged; property OnFocusChanging; property OnFreeNode; property OnGetCellIsEmpty; property OnGetCursor; property OnGetHeaderCursor; property OnGetText; property OnPaintText; property OnGetHelpContext; property OnGetImageIndex; property OnGetImageIndexEx; property OnGetImageText; property OnGetHint; property OnGetLineStyle; property OnGetNodeDataSize; property OnGetPopupMenu; property OnGetUserClipboardFormats; property OnHeaderCheckBoxClick; property OnHeaderClick; property OnHeaderDblClick; property OnHeaderDragged; property OnHeaderDraggedOut; property OnHeaderDragging; property OnHeaderDraw; property OnHeaderDrawQueryElements; property OnHeaderHeightDblClickResize; property OnHeaderHeightTracking; property OnHeaderImageClick; property OnHeaderMouseDown; property OnHeaderMouseMove; property OnHeaderMouseUp; property OnHotChange; property OnIncrementalSearch; property OnInitChildren; property OnInitNode; property OnKeyAction; property OnKeyDown; property OnKeyPress; property OnKeyUp; property OnLoadNode; property OnMeasureItem; property OnMeasureTextWidth; property OnMouseDown; property OnMouseMove; property OnMouseUp; property OnMouseWheel; property OnNewText; property OnNodeCopied; property OnNodeCopying; property OnNodeExport; property OnNodeHeightDblClickResize; property OnNodeHeightTracking; property OnNodeMoved; property OnNodeMoving; property OnPaintBackground; property OnRenderOLEData; property OnResetNode; property OnResize; property OnSaveNode; property OnScroll; property OnShortenString; property OnShowScrollbar; property OnStartDock; property OnStartDrag; property OnStateChange; property OnStructureChange; property OnUpdating; property OnUTF8KeyPress; end; TVTDrawHintEvent = procedure(Sender: TBaseVirtualTree; HintCanvas: TCanvas; Node: PVirtualNode; const R: TRect; Column: TColumnIndex) of object; TVTDrawNodeEvent = procedure(Sender: TBaseVirtualTree; const PaintInfo: TVTPaintInfo) of object; TVTGetCellContentMarginEvent = procedure(Sender: TBaseVirtualTree; HintCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; CellContentMarginType: TVTCellContentMarginType; var CellContentMargin: TPoint) of object; TVTGetNodeWidthEvent = procedure(Sender: TBaseVirtualTree; HintCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; var NodeWidth: Integer) of object; TVTGetHintSizeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var R: TRect) of object; // Tree descendant to let an application draw its stuff itself. TCustomVirtualDrawTree = class(TBaseVirtualTree) private FOnDrawNode: TVTDrawNodeEvent; FOnGetCellContentMargin: TVTGetCellContentMarginEvent; FOnGetNodeWidth: TVTGetNodeWidthEvent; FOnGetHintSize: TVTGetHintSizeEvent; FOnDrawHint: TVTDrawHintEvent; protected procedure DoDrawHint(Canvas: TCanvas; Node: PVirtualNode; const R: TRect; Column: TColumnIndex); function DoGetCellContentMargin(Node: PVirtualNode; Column: TColumnIndex; CellContentMarginType: TVTCellContentMarginType = ccmtAllSides; Canvas: TCanvas = nil): TPoint; override; procedure DoGetHintSize(Node: PVirtualNode; Column: TColumnIndex; var R: TRect); virtual; function DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer; override; procedure DoPaintNode(var PaintInfo: TVTPaintInfo); override; property OnDrawHint: TVTDrawHintEvent read FOnDrawHint write FOnDrawHint; property OnDrawNode: TVTDrawNodeEvent read FOnDrawNode write FOnDrawNode; property OnGetCellContentMargin: TVTGetCellContentMarginEvent read FOnGetCellContentMargin write FOnGetCellContentMargin; property OnGetHintSize: TVTGetHintSizeEvent read FOnGetHintSize write FOnGetHintSize; property OnGetNodeWidth: TVTGetNodeWidthEvent read FOnGetNodeWidth write FOnGetNodeWidth; end; TVirtualDrawTree = class(TCustomVirtualDrawTree) private function GetOptions: TVirtualTreeOptions; procedure SetOptions(const Value: TVirtualTreeOptions); protected function GetOptionsClass: TTreeOptionsClass; override; public property Canvas; published property Action; property Align; property Alignment; property Anchors; property AnimationDuration; property AutoExpandDelay; property AutoScrollDelay; property AutoScrollInterval; property Background; property BackgroundOffsetX; property BackgroundOffsetY; property BiDiMode; //property BevelEdges; //property BevelInner; //property BevelOuter; //property BevelKind; // property BevelWidth; property BorderSpacing; property BorderStyle default bsSingle; property BottomSpace; property ButtonFillMode; property ButtonStyle; property BorderWidth; property ChangeDelay; property CheckImageKind; property ClipboardFormats; property Color; property Colors; property Constraints; property CustomCheckImages; property DefaultNodeHeight; property DefaultPasteMode; property DragCursor; property DragHeight; property DragKind; property DragImageKind; property DragMode; property DragOperations; property DragType; property DragWidth; property DrawSelectionMode; property EditDelay; property Enabled; property Font; property Header; property HintMode; property HotCursor; property Images; property IncrementalSearch; property IncrementalSearchDirection; property IncrementalSearchStart; property IncrementalSearchTimeout; property Indent; property LineMode; property LineStyle; property Margin; property NodeAlignment; property NodeDataSize; property OperationCanceled; property ParentBiDiMode; property ParentColor default False; property ParentFont; property ParentShowHint; property PopupMenu; property RootNodeCount; property ScrollBarOptions; property SelectionBlendFactor; property SelectionCurveRadius; property ShowHint; property StateImages; property TabOrder; property TabStop default True; property TextMargin; property TreeOptions: TVirtualTreeOptions read GetOptions write SetOptions; property Visible; property WantTabs; property OnAdvancedHeaderDraw; property OnAfterAutoFitColumn; property OnAfterAutoFitColumns; property OnAfterCellPaint; property OnAfterColumnExport; property OnAfterColumnWidthTracking; property OnAfterGetMaxColumnWidth; property OnAfterHeaderExport; property OnAfterHeaderHeightTracking; property OnAfterItemErase; property OnAfterItemPaint; property OnAfterNodeExport; property OnAfterPaint; property OnAfterTreeExport; property OnBeforeAutoFitColumn; property OnBeforeAutoFitColumns; property OnBeforeCellPaint; property OnBeforeColumnExport; property OnBeforeColumnWidthTracking; property OnBeforeGetMaxColumnWidth; property OnBeforeHeaderExport; property OnBeforeHeaderHeightTracking; property OnBeforeItemErase; property OnBeforeItemPaint; property OnBeforeNodeExport; property OnBeforePaint; property OnBeforeTreeExport; property OnCanSplitterResizeColumn; property OnChange; property OnChecked; property OnChecking; property OnClick; property OnCollapsed; property OnCollapsing; property OnColumnClick; property OnColumnDblClick; property OnColumnExport; property OnColumnResize; property OnColumnWidthDblClickResize; property OnColumnWidthTracking; property OnCompareNodes; property OnContextPopup; property OnCreateDataObject; property OnCreateDragManager; property OnCreateEditor; property OnDblClick; property OnDragAllowed; property OnDragOver; property OnDragDrop; property OnDrawHint; property OnDrawNode; property OnEdited; property OnEditing; property OnEndDock; property OnEndDrag; property OnEnter; property OnExit; property OnExpanded; property OnExpanding; property OnFocusChanged; property OnFocusChanging; property OnFreeNode; property OnGetCellIsEmpty; property OnGetCursor; property OnGetHeaderCursor; property OnGetHelpContext; property OnGetHintSize; property OnGetImageIndex; property OnGetImageIndexEx; property OnGetLineStyle; property OnGetNodeDataSize; property OnGetNodeWidth; property OnGetPopupMenu; property OnGetUserClipboardFormats; property OnHeaderCheckBoxClick; property OnHeaderClick; property OnHeaderDblClick; property OnHeaderDragged; property OnHeaderDraggedOut; property OnHeaderDragging; property OnHeaderDraw; property OnHeaderDrawQueryElements; property OnHeaderHeightTracking; property OnHeaderHeightDblClickResize; property OnHeaderImageClick; property OnHeaderMouseDown; property OnHeaderMouseMove; property OnHeaderMouseUp; property OnHotChange; property OnIncrementalSearch; property OnInitChildren; property OnInitNode; property OnKeyAction; property OnKeyDown; property OnKeyPress; property OnKeyUp; property OnLoadNode; property OnMeasureItem; property OnMouseDown; property OnMouseMove; property OnMouseUp; property OnMouseWheel; property OnNodeCopied; property OnNodeCopying; property OnNodeExport; property OnNodeHeightTracking; property OnNodeHeightDblClickResize; property OnNodeMoved; property OnNodeMoving; property OnPaintBackground; property OnRenderOLEData; property OnResetNode; property OnResize; property OnSaveNode; property OnScroll; property OnShowScrollbar; property OnStartDock; property OnStartDrag; property OnStateChange; property OnStructureChange; property OnUpdating; property OnUTF8KeyPress; end; // OLE Clipboard and drag'n drop helper procedure EnumerateVTClipboardFormats(TreeClass: TVirtualTreeClass; const List: TStrings); overload; procedure EnumerateVTClipboardFormats(TreeClass: TVirtualTreeClass; var Formats: TFormatEtcArray); overload; function GetVTClipboardFormatDescription(AFormat: Word): string; procedure RegisterVTClipboardFormat(AFormat: Word; TreeClass: TVirtualTreeClass; Priority: Cardinal); overload; function RegisterVTClipboardFormat(Description: string; TreeClass: TVirtualTreeClass; Priority: Cardinal; tymed: Integer = TYMED_HGLOBAL; ptd: PDVTargetDevice = nil; dwAspect: Integer = DVASPECT_CONTENT; lindex: Integer = -1): Word; overload; // utility routines {$ifdef EnablePrint} procedure PrtStretchDrawDIB(Canvas: TCanvas; DestRect: TRect; ABitmap: TBitmap); {$endif} function ShortenString(DC: HDC; const S: String; Width: Integer; EllipsisWidth: Integer = 0): String; function TreeFromNode(Node: PVirtualNode): TBaseVirtualTree; procedure GetStringDrawRect(DC: HDC; const S: String; var Bounds: TRect; DrawFormat: Cardinal); function WrapString(DC: HDC; const S: String; const Bounds: TRect; RTL: Boolean; DrawFormat: Cardinal): String; //---------------------------------------------------------------------------------------------------------------------- implementation uses StrUtils, Math, {$ifdef EnableOLE} //AxCtrls, // TOLEStream {$endif} {$ifdef UseFlatScrollbars} FlatSB, // wrapper for systems without flat SB support {$endif UseFlatScrollbars} {$ifdef Windows} MMSystem, // for animation timer (does not include further resources) {$else} FakeMMSystem, {$endif} TypInfo, // for migration stuff ActnList, StdActns, // for standard action support GraphType, LCLProc {$ifdef EnableAccessible} ,VTAccessibilityFactory {$endif}; // accessibility helper class resourcestring // Localizable strings. SEditLinkIsNil = 'Edit link must not be nil.'; SWrongMoveError = 'Target node cannot be a child node of the node to be moved.'; SWrongStreamFormat = 'Unable to load tree structure, the format is wrong.'; SWrongStreamVersion = 'Unable to load tree structure, the version is unknown.'; SStreamTooSmall = 'Unable to load tree structure, not enough data available.'; SCorruptStream1 = 'Stream data corrupt. A node''s anchor chunk is missing.'; SCorruptStream2 = 'Stream data corrupt. Unexpected data after node''s end position.'; SClipboardFailed = 'Clipboard operation failed.'; SCannotSetUserData = 'Cannot set initial user data because there is not enough user data space allocated.'; const ClipboardStates = [tsCopyPending, tsCutPending]; DefaultScrollUpdateFlags = [suoRepaintHeader, suoRepaintScrollbars, suoScrollClientArea, suoUpdateNCArea]; MinimumTimerInterval = 1; // minimum resolution for timeGetTime TreeNodeSize = (SizeOf(TVirtualNode) + 3) and not 3; // used for node allocation and access to internal data // Lookup to quickly convert a specific check state into its pressed counterpart and vice versa. PressedState: array[TCheckState] of TCheckState = ( csUncheckedPressed, csUncheckedPressed, csCheckedPressed, csCheckedPressed, csMixedPressed, csMixedPressed ); UnpressedState: array[TCheckState] of TCheckState = ( csUncheckedNormal, csUncheckedNormal, csCheckedNormal, csCheckedNormal, csMixedNormal, csMixedNormal ); MouseButtonDown = [tsLeftButtonDown, tsMiddleButtonDown, tsRightButtonDown]; // Do not modify the copyright in any way! Usage of this unit is prohibited without the copyright notice // in the compiled binary file. Copyright: string = 'Virtual Treeview ? 1999, 2010 Mike Lischke'; var //Workaround to LCL bug 8553 {$ifndef LCLWin32} pf32bit: TPixelFormat = pfDevice; {$endif} StandardOLEFormat: TFormatEtc = ( // Format must later be set. cfFormat: 0; // No specific target device to render on. ptd: nil; // Normal content to render. dwAspect: DVASPECT_CONTENT; // No specific page of multipage data (we don't use multipage data by default). lindex: -1; // Acceptable storage formats are IStream and global memory. The first is preferred. tymed: TYMED_ISTREAM or TYMED_HGLOBAL; ); type // streaming support TMagicID = array[0..5] of Char; TChunkHeader = record ChunkType, ChunkSize: Integer; // contains the size of the chunk excluding the header end; // base information about a node TBaseChunkBody = packed record ChildCount, NodeHeight: Cardinal; States: TVirtualNodeStates; Align: Byte; CheckState: TCheckState; CheckType: TCheckType; Reserved: Cardinal; end; TBaseChunk = packed record Header: TChunkHeader; Body: TBaseChunkBody; end; // Toggle animation modes. TToggleAnimationMode = ( tamScrollUp, tamScrollDown, tamNoScroll ); // Internally used data for animations. TToggleAnimationData = record Window: HWND; // copy of the tree's window handle DC: HDC; // the DC of the window to erase uncovered parts Brush: HBRUSH; // the brush to be used to erase uncovered parts R1, R2: TRect; // animation rectangles Mode1, Mode2: TToggleAnimationMode; // animation modes ScaleFactor: Double; // the factor between the missing step size when doing two animations MissedSteps: Double; end; const CheckImagesStrings: array [TCheckImageKind] of String = ('VT_CHECK_LIGHT', 'VT_CHECK_DARK', 'VT_TICK_LIGHT', 'VT_TICK_DARK', 'VT_FLAT', 'VT_XP', '',//ckCustom, // Only the button images are used for ckSystem * // The check buttons are draw at fly as requested 'VT_FLAT',//ckSystemFlat 'VT_CHECK_DARK' //ckSystemDefault ); MagicID: TMagicID = (#$45, 'V', 'T', Char(VTTreeStreamVersion), ' ', #$46); // chunk IDs NodeChunk = 1; BaseChunk = 2; // chunk containing node state, check state, child node count etc. // this chunk is immediately followed by all child nodes CaptionChunk = 3; // used by the string tree to store a node's caption UserChunk = 4; // used for data supplied by the application {$ifdef UseFlatScrollbars} ScrollBarProp: array[TScrollBarStyle] of Integer = ( FSB_REGULAR_MODE, FSB_FLAT_MODE, FSB_ENCARTA_MODE ); {$endif} RTLFlag: array[Boolean] of Integer = (0, ETO_RTLREADING); AlignmentToDrawFlag: array[TAlignment] of Cardinal = (DT_LEFT, DT_RIGHT, DT_CENTER); WideCR = WideChar(#13); WideLF = WideChar(#10); type // internal worker thread TWorkerThread = class(TThread) private FCurrentTree: TBaseVirtualTree; FWaiterList: TThreadList; FRefCount: Cardinal; protected procedure CancelValidation(Tree: TBaseVirtualTree); procedure ChangeTreeStates(EnterStates, LeaveStates: TChangeStates); procedure Execute; override; public constructor Create(CreateSuspended: Boolean); destructor Destroy; override; procedure AddTree(Tree: TBaseVirtualTree); procedure RemoveTree(Tree: TBaseVirtualTree); property CurrentTree: TBaseVirtualTree read FCurrentTree; end; var WorkerThread: TWorkerThread; WorkEvent: TEvent; UtilityImages: TBitmap; // some small additional images (e.g for header dragging) Initialized: Boolean; // True if global structures have been initialized. NeedToUnitialize: Boolean; // True if the OLE subsystem could be initialized successfully. //----------------- TClipboardFormats ---------------------------------------------------------------------------------- type PClipboardFormatListEntry = ^TClipboardFormatListEntry; TClipboardFormatListEntry = record Description: string; // The string used to register the format with Windows. TreeClass: TVirtualTreeClass; // The tree class which supports rendering this format. Priority: Cardinal; // Number which determines the order of formats used in IDataObject. FormatEtc: TFormatEtc; // The definition of the format in the IDataObject. end; TClipboardFormatList = class private FList: TFpList; procedure Sort; public constructor Create; destructor Destroy; override; procedure Add(FormatString: string; AClass: TVirtualTreeClass; Priority: Cardinal; AFormatEtc: TFormatEtc); procedure Clear; procedure EnumerateFormats(TreeClass: TVirtualTreeClass; var Formats: TFormatEtcArray; const AllowedFormats: TClipboardFormats = nil); overload; procedure EnumerateFormats(TreeClass: TVirtualTreeClass; const Formats: TStrings); overload; function FindFormat(FormatString: string): PClipboardFormatListEntry; overload; function FindFormat(FormatString: string; var Fmt: Word): TVirtualTreeClass; overload; function FindFormat(Fmt: Word; out Description: string): TVirtualTreeClass; overload; end; var InternalClipboardFormats: TClipboardFormatList; //---------------------------------------------------------------------------------------------------------------------- constructor TClipboardFormatList.Create; begin FList := TFpList.Create; end; //---------------------------------------------------------------------------------------------------------------------- destructor TClipboardFormatList.Destroy; begin Clear; FList.Free; inherited; end; //---------------------------------------------------------------------------------------------------------------------- procedure TClipboardFormatList.Sort; // Sorts all entry for priority (increasing priority value). //--------------- local function -------------------------------------------- procedure QuickSort(L, R: Integer); var I, J: Integer; P, T: PClipboardFormatListEntry; begin repeat I := L; J := R; P := FList[(L + R) shr 1]; repeat while PClipboardFormatListEntry(FList[I]).Priority < P.Priority do Inc(I); while PClipboardFormatListEntry(Flist[J]).Priority > P.Priority do Dec(J); if I <= J then begin T := Flist[I]; FList[I] := FList[J]; FList[J] := T; Inc(I); Dec(J); end; until I > J; if L < J then QuickSort(L, J); L := I; until I >= R; end; //--------------- end local function ---------------------------------------- begin if FList.Count > 1 then QuickSort(0, FList.Count - 1); end; //---------------------------------------------------------------------------------------------------------------------- procedure TClipboardFormatList.Add(FormatString: string; AClass: TVirtualTreeClass; Priority: Cardinal; AFormatEtc: TFormatEtc); // Adds the given data to the internal list. The priority value is used to sort formats for importance. Larger priority // values mean less priority. var Entry: PClipboardFormatListEntry; begin New(Entry); Entry.Description := FormatString; Entry.TreeClass := AClass; Entry.Priority := Priority; Entry.FormatEtc := AFormatEtc; FList.Add(Entry); Sort; end; //---------------------------------------------------------------------------------------------------------------------- procedure TClipboardFormatList.Clear; var I: Integer; begin for I := 0 to FList.Count - 1 do Dispose(PClipboardFormatListEntry(FList[I])); FList.Clear; end; //---------------------------------------------------------------------------------------------------------------------- procedure TClipboardFormatList.EnumerateFormats(TreeClass: TVirtualTreeClass; var Formats: TFormatEtcArray; const AllowedFormats: TClipboardFormats = nil); // Returns a list of format records for the given class. If assigned the AllowedFormats is used to limit the // enumerated formats to those described in the list. var I, Count: Integer; Entry: PClipboardFormatListEntry; begin SetLength(Formats, FList.Count); Count := 0; for I := 0 to FList.Count - 1 do begin Entry := FList[I]; // Does the tree class support this clipboard format? if TreeClass.InheritsFrom(Entry.TreeClass) then begin // Is this format allowed to be included? if (AllowedFormats = nil) or (AllowedFormats.IndexOf(Entry.Description) > -1) then begin // The list could change before we use the FormatEtc so it is best not to pass a pointer to the true FormatEtc // structure. Instead make a copy and send that. Formats[Count] := Entry.FormatEtc; Inc(Count); end; end; end; SetLength(Formats, Count); end; //---------------------------------------------------------------------------------------------------------------------- procedure TClipboardFormatList.EnumerateFormats(TreeClass: TVirtualTreeClass; const Formats: TStrings); // Returns a list of format descriptions for the given class. var I: Integer; Entry: PClipboardFormatListEntry; begin for I := 0 to FList.Count - 1 do begin Entry := FList[I]; if TreeClass.InheritsFrom(Entry.TreeClass) then Formats.Add(Entry.Description); end; end; //---------------------------------------------------------------------------------------------------------------------- function TClipboardFormatList.FindFormat(FormatString: string): PClipboardFormatListEntry; var I: Integer; Entry: PClipboardFormatListEntry; begin Result := nil; for I := FList.Count - 1 downto 0 do begin Entry := FList[I]; if CompareText(Entry.Description, FormatString) = 0 then begin Result := Entry; Break; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TClipboardFormatList.FindFormat(FormatString: string; var Fmt: Word): TVirtualTreeClass; var I: Integer; Entry: PClipboardFormatListEntry; begin Result := nil; for I := FList.Count - 1 downto 0 do begin Entry := FList[I]; if CompareText(Entry.Description, FormatString) = 0 then begin Result := Entry.TreeClass; Fmt := Entry.FormatEtc.cfFormat; Break; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TClipboardFormatList.FindFormat(Fmt: Word; out Description: string): TVirtualTreeClass; var I: Integer; Entry: PClipboardFormatListEntry; begin Result := nil; for I := FList.Count - 1 downto 0 do begin Entry := FList[I]; if Entry.FormatEtc.cfFormat = Fmt then begin Result := Entry.TreeClass; Description := Entry.Description; Break; end; end; end; //---------------------------------------------------------------------------------------------------------------------- type TClipboardFormatEntry = record ID: Word; Description: string; end; var ClipboardDescriptions: array [1..CF_MAX - 1] of TClipboardFormatEntry = ( (ID: CF_TEXT; Description: 'Plain text'), // Do not localize (ID: CF_BITMAP; Description: 'Windows bitmap'), // Do not localize (ID: CF_METAFILEPICT; Description: 'Windows metafile'), // Do not localize (ID: CF_SYLK; Description: 'Symbolic link'), // Do not localize (ID: CF_DIF; Description: 'Data interchange format'), // Do not localize (ID: CF_TIFF; Description: 'Tiff image'), // Do not localize (ID: CF_OEMTEXT; Description: 'OEM text'), // Do not localize (ID: CF_DIB; Description: 'DIB image'), // Do not localize (ID: CF_PALETTE; Description: 'Palette data'), // Do not localize (ID: CF_PENDATA; Description: 'Pen data'), // Do not localize (ID: CF_RIFF; Description: 'Riff audio data'), // Do not localize (ID: CF_WAVE; Description: 'Wav audio data'), // Do not localize (ID: CF_UNICODETEXT; Description: 'Unicode text'), // Do not localize (ID: CF_ENHMETAFILE; Description: 'Enhanced metafile image'), // Do not localize (ID: CF_HDROP; Description: 'File name(s)'), // Do not localize (ID: CF_LOCALE; Description: 'Locale descriptor') // Do not localize ); //---------------------------------------------------------------------------------------------------------------------- procedure EnumerateVTClipboardFormats(TreeClass: TVirtualTreeClass; const List: TStrings); begin if InternalClipboardFormats = nil then InternalClipboardFormats := TClipboardFormatList.Create; InternalClipboardFormats.EnumerateFormats(TreeClass, List); end; //---------------------------------------------------------------------------------------------------------------------- procedure EnumerateVTClipboardFormats(TreeClass: TVirtualTreeClass; var Formats: TFormatEtcArray); begin if InternalClipboardFormats = nil then InternalClipboardFormats := TClipboardFormatList.Create; InternalClipboardFormats.EnumerateFormats(TreeClass, Formats); end; //---------------------------------------------------------------------------------------------------------------------- function GetVTClipboardFormatDescription(AFormat: Word): string; begin if InternalClipboardFormats = nil then InternalClipboardFormats := TClipboardFormatList.Create; if InternalClipboardFormats.FindFormat(AFormat, Result) = nil then Result := ''; end; //---------------------------------------------------------------------------------------------------------------------- procedure RegisterVTClipboardFormat(AFormat: Word; TreeClass: TVirtualTreeClass; Priority: Cardinal); // Registers the given clipboard format for the given TreeClass. var I: Integer; FormatEtc: TFormatEtc; begin if InternalClipboardFormats = nil then InternalClipboardFormats := TClipboardFormatList.Create; // Assumes a HGlobal format. FormatEtc.cfFormat := AFormat; FormatEtc.ptd := nil; FormatEtc.dwAspect := DVASPECT_CONTENT; FormatEtc.lindex := -1; FormatEtc.tymed := TYMED_HGLOBAL; // Determine description string of the given format. For predefined formats we need the lookup table because they // don't have a description string. For registered formats the description string is the string which was used // to register them. if AFormat < CF_MAX then begin for I := 1 to High(ClipboardDescriptions) do if ClipboardDescriptions[I].ID = AFormat then begin InternalClipboardFormats.Add(ClipboardDescriptions[I].Description, TreeClass, Priority, FormatEtc); Break; end; end else begin InternalClipboardFormats.Add(ClipboardFormatToMimeType(AFormat), TreeClass, Priority, FormatEtc); end; end; //---------------------------------------------------------------------------------------------------------------------- function RegisterVTClipboardFormat(Description: string; TreeClass: TVirtualTreeClass; Priority: Cardinal; tymed: Integer = TYMED_HGLOBAL; ptd: PDVTargetDevice = nil; dwAspect: Integer = DVASPECT_CONTENT; lindex: Integer = -1): Word; // Alternative method to register a certain clipboard format for a given tree class. Registration with the // clipboard is done here too and the assigned ID returned by the function. // tymed may contain or'ed TYMED constants which allows to register several storage formats for one clipboard format. var FormatEtc: TFormatEtc; begin if InternalClipboardFormats = nil then InternalClipboardFormats := TClipboardFormatList.Create; Result := ClipboardRegisterFormat(Description); FormatEtc.cfFormat := Result; FormatEtc.ptd := ptd; FormatEtc.dwAspect := dwAspect; FormatEtc.lindex := lindex; FormatEtc.tymed := tymed; InternalClipboardFormats.Add(Description, TreeClass, Priority, FormatEtc); end; //----------------- utility functions ---------------------------------------------------------------------------------- procedure ShowError(Msg: String; HelpContext: Integer); begin raise EVirtualTreeError.CreateHelp(Msg, HelpContext); end; //---------------------------------------------------------------------------------------------------------------------- function TreeFromNode(Node: PVirtualNode): TBaseVirtualTree; // Returns the tree the node currently belongs to or nil if the node is not attached to a tree. begin Assert(Assigned(Node), 'Node must not be nil.'); // The root node is marked by having its NextSibling (and PrevSibling) pointing to itself. while Assigned(Node) and (Node.NextSibling <> Node) do Node := Node.Parent; if Assigned(Node) then Result := TBaseVirtualTree(Node.Parent) else Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- function OrderRect(const R: TRect): TRect; // Converts the incoming rectangle so that left and top are always less than or equal to right and bottom. begin if R.Left < R.Right then begin Result.Left := R.Left; Result.Right := R.Right; end else begin Result.Left := R.Right; Result.Right := R.Left; end; if R.Top < R.Bottom then begin Result.Top := R.Top; Result.Bottom := R.Bottom; end else begin Result.Top := R.Bottom; Result.Bottom := R.Top; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure QuickSort(const TheArray: TNodeArray; L, R: Integer); var I, J: Integer; P, T: Pointer; begin repeat I := L; J := R; P := TheArray[(L + R) shr 1]; repeat while TheArray[I] < P do Inc(I); while TheArray[J] > P do Dec(J); if I <= J then begin T := TheArray[I]; TheArray[I] := TheArray[J]; TheArray[J] := T; Inc(I); Dec(J); end; until I > J; if L < J then QuickSort(TheArray, L, J); L := I; until I >= R; end; //---------------------------------------------------------------------------------------------------------------------- //todo: Unify the procedure or change to widgetset specific // Currently the UTF-8 version is broken. // the unicode version is used when all winapi is available {$ifndef INCOMPLETE_WINAPI} function ShortenString(DC: HDC; const S: String; Width: Integer; EllipsisWidth: Integer = 0): String; // Adjusts the given string S so that it fits into the given width. EllipsisWidth gives the width of // the three points to be added to the shorted string. If this value is 0 then it will be determined implicitely. // For higher speed (and multiple entries to be shorted) specify this value explicitely. // Note: It is assumed that the string really needs shortage. Check this in advance. var Size: TSize; Len: Integer; L, H, N, W: Integer; WideStr: UnicodeString; begin WideStr := UTF8Decode(S); Len := Length(WideStr); if (Len = 0) or (Width <= 0) then Result := '' else begin // Determine width of triple point using the current DC settings (if not already done). if EllipsisWidth = 0 then begin GetTextExtentPoint32W(DC, '...', 3, Size); EllipsisWidth := Size.cx; end; if Width <= EllipsisWidth then Result := '' else begin // Do a binary search for the optimal string length which fits into the given width. L := 0; H := Len - 1; while L < H do begin N := (L + H + 1) shr 1; GetTextExtentPoint32W(DC, PWideChar(WideStr), N, Size); W := Size.cx + EllipsisWidth; if W <= Width then L := N else H := N - 1; end; Result := UTF8Encode(Copy(WideStr, 1, L) + '...'); end; end; end; {$else} function ShortenString(DC: HDC; const S: String; Width: Integer; EllipsisWidth: Integer = 0): String; // Adjusts the given string S so that it fits into the given width. EllipsisWidth gives the width of // the three points to be added to the shorted string. If this value is 0 then it will be determined implicitely. // For higher speed (and multiple entries to be shorted) specify this value explicitely. // Note: It is assumed that the string really needs shortage. Check this in advance. var Size: TSize; Len: Integer; L, H, N, W: Integer; begin Len := Length(S); if (Len = 0) or (Width <= 0) then Result := '' else begin // Determine width of triple point using the current DC settings (if not already done). if EllipsisWidth = 0 then begin GetTextExtentPoint32(DC, '...', 3, Size); EllipsisWidth := Size.cx; end; if Width <= EllipsisWidth then Result := '' else begin // Do a binary search for the optimal string length which fits into the given width. L := 0; H := Len - 1; while L < H do begin N := (L + H + 1) shr 1; GetTextExtentPoint32(DC, PAnsiChar(S), N, Size); W := Size.cx + EllipsisWidth; if W <= Width then L := N else H := N - 1; end; Result := Copy(S, 1, L) + '...'; end; end; end; {$endif} //---------------------------------------------------------------------------------------------------------------------- function WrapString(DC: HDC; const S: String; const Bounds: TRect; RTL: Boolean; DrawFormat: Cardinal): String; // Wrap the given string S so that it fits into a space of given width. // RTL determines if right-to-left reading is active. var Width, Len, WordCounter, WordsInLine, I, W: Integer; Buffer, Line: String; Words: Array of String; R: TRect; begin Result := ''; Width := Bounds.Right - Bounds.Left; R := Rect(0, 0, 0, 0); // Leading and trailing are ignored. Buffer := Trim(S); Len := Length(Buffer); if Len < 1 then Exit; // Count the words in the string. WordCounter := 1; for I := 1 to Len do if Buffer[I] = ' ' then Inc(WordCounter); SetLength(Words, WordCounter); if RTL then begin // At first we split the string into words with the last word being the // first element in Words. W := 0; for I := 1 to Len do if Buffer[I] = ' ' then Inc(W) else Words[W] := Words[W] + Buffer[I]; // Compose Result. while WordCounter > 0 do begin WordsInLine := 0; Line := ''; while WordCounter > 0 do begin GetStringDrawRect(DC, Line + IfThen(WordsInLine > 0, ' ', '') + Words[WordCounter - 1], R, DrawFormat); if R.Right > Width then begin // If at least one word fits into this line then continue with the next line. if WordsInLine > 0 then Break; Buffer := Words[WordCounter - 1]; if Len > 1 then begin for Len := Length(Buffer) - 1 downto 2 do begin GetStringDrawRect(DC, RightStr(Buffer, Len), R, DrawFormat); if R.Right <= Width then Break; end; end else Len := Length(Buffer); Line := Line + RightStr(Buffer, Max(Len, 1)); Words[WordCounter - 1] := LeftStr(Buffer, Length(Buffer) - Max(Len, 1)); if Words[WordCounter - 1] = '' then Dec(WordCounter); Break; end else begin Dec(WordCounter); Line := Words[WordCounter] + IfThen(WordsInLine > 0, ' ', '') + Line; Inc(WordsInLine); end; end; Result := Result + Line + LineEnding; end; end else begin // At first we split the string into words with the last word being the // first element in Words. W := WordCounter - 1; for I := 1 to Len do if Buffer[I] = ' ' then Dec(W) else Words[W] := Words[W] + Buffer[I]; // Compose Result. while WordCounter > 0 do begin WordsInLine := 0; Line := ''; while WordCounter > 0 do begin GetStringDrawRect(DC, Line + IfThen(WordsInLine > 0, ' ', '') + Words[WordCounter - 1], R, DrawFormat); if R.Right > Width then begin // If at least one word fits into this line then continue with the next line. if WordsInLine > 0 then Break; Buffer := Words[WordCounter - 1]; if Len > 1 then begin for Len := Length(Buffer) - 1 downto 2 do begin GetStringDrawRect(DC, LeftStr(Buffer, Len), R, DrawFormat); if R.Right <= Width then Break; end; end else Len := Length(Buffer); Line := Line + LeftStr(Buffer, Max(Len, 1)); Words[WordCounter - 1] := RightStr(Buffer, Length(Buffer) - Max(Len, 1)); if Words[WordCounter - 1] = '' then Dec(WordCounter); Break; end else begin Dec(WordCounter); Line := Line + IfThen(WordsInLine > 0, ' ', '') + Words[WordCounter]; Inc(WordsInLine); end; end; Result := Result + Line + LineEnding; end; end; Len := Length(Result) - Length(LineEnding); if CompareByte(Result[Len + 1], String(LineEnding)[1], Length(LineEnding)) = 0 then SetLength(Result, Len); end; //---------------------------------------------------------------------------------------------------------------------- // Calculates bounds of a drawing rectangle for the given string procedure GetStringDrawRect(DC: HDC; const S: String; var Bounds: TRect; DrawFormat: Cardinal); begin Bounds.Right := Bounds.Left + 1; Bounds.Bottom := Bounds.Top + 1; DrawText(DC, PChar(S), Length(S), Bounds, DrawFormat or DT_CALCRECT); end; //---------------------------------------------------------------------------------------------------------------------- procedure FillDragRectangles(DragWidth, DragHeight, DeltaX, DeltaY: Integer; out RClip, RScroll, RSamp1, RSamp2, RDraw1, RDraw2: TRect); // Fills the given rectangles with values which can be used while dragging around an image // (used in DragMove of the drag manager and DragTo of the header columns). begin // ScrollDC limits RClip := Rect(0, 0, DragWidth, DragHeight); if DeltaX > 0 then begin // move to the left if DeltaY = 0 then begin // move only to the left // background movement RScroll := Rect(0, 0, DragWidth - DeltaX, DragHeight); RSamp1 := Rect(0, 0, DeltaX, DragHeight); RDraw1 := Rect(DragWidth - DeltaX, 0, DeltaX, DragHeight); end else if DeltaY < 0 then begin // move to bottom left RScroll := Rect(0, -DeltaY, DragWidth - DeltaX, DragHeight); RSamp1 := Rect(0, 0, DeltaX, DragHeight); RSamp2 := Rect(DeltaX, DragHeight + DeltaY, DragWidth - DeltaX, -DeltaY); RDraw1 := Rect(0, 0, DragWidth - DeltaX, -DeltaY); RDraw2 := Rect(DragWidth - DeltaX, 0, DeltaX, DragHeight); end else begin // move to upper left RScroll := Rect(0, 0, DragWidth - DeltaX, DragHeight - DeltaY); RSamp1 := Rect(0, 0, DeltaX, DragHeight); RSamp2 := Rect(DeltaX, 0, DragWidth - DeltaX, DeltaY); RDraw1 := Rect(0, DragHeight - DeltaY, DragWidth - DeltaX, DeltaY); RDraw2 := Rect(DragWidth - DeltaX, 0, DeltaX, DragHeight); end; end else if DeltaX = 0 then begin // vertical movement only if DeltaY < 0 then begin // move downwards RScroll := Rect(0, -DeltaY, DragWidth, DragHeight); RSamp2 := Rect(0, DragHeight + DeltaY, DragWidth, -DeltaY); RDraw2 := Rect(0, 0, DragWidth, -DeltaY); end else begin // move upwards RScroll := Rect(0, 0, DragWidth, DragHeight - DeltaY); RSamp2 := Rect(0, 0, DragWidth, DeltaY); RDraw2 := Rect(0, DragHeight - DeltaY, DragWidth, DeltaY); end; end else begin // move to the right if DeltaY > 0 then begin // move up right RScroll := Rect(-DeltaX, 0, DragWidth, DragHeight); RSamp1 := Rect(0, 0, DragWidth + DeltaX, DeltaY); RSamp2 := Rect(DragWidth + DeltaX, 0, -DeltaX, DragHeight); RDraw1 := Rect(0, 0, -DeltaX, DragHeight); RDraw2 := Rect(-DeltaX, DragHeight - DeltaY, DragWidth + DeltaX, DeltaY); end else if DeltaY = 0 then begin // to the right only RScroll := Rect(-DeltaX, 0, DragWidth, DragHeight); RSamp1 := Rect(DragWidth + DeltaX, 0, -DeltaX, DragHeight); RDraw1 := Rect(0, 0, -DeltaX, DragHeight); end else begin // move down right RScroll := Rect(-DeltaX, -DeltaY, DragWidth, DragHeight); RSamp1 := Rect(0, DragHeight + DeltaY, DragWidth + DeltaX, -DeltaY); RSamp2 := Rect(DragWidth + DeltaX, 0, -DeltaX, DragHeight); RDraw1 := Rect(0, 0, -DeltaX, DragHeight); RDraw2 := Rect(-DeltaX, 0, DragWidth + DeltaX, -DeltaY); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function GetRGBColor(Value: TColor): DWORD; // Little helper to convert a Delphi color to an image list color. begin Result := ColorToRGB(Value); case Result of clNone: Result := CLR_NONE; clDefault: Result := CLR_DEFAULT; end; end; //---------------------------------------------------------------------------------------------------------------------- {$ifdef CPU64} function HasMMX: Boolean; begin Result := True; end; {$else} function HasMMX: Boolean; // Helper method to determine whether the current processor supports MMX. asm PUSH EBX XOR EAX, EAX // Result := False PUSHFD // determine if the processor supports the CPUID command POP EDX MOV ECX, EDX XOR EDX, $200000 PUSH EDX POPFD PUSHFD POP EDX XOR ECX, EDX JZ @1 // no CPUID support so we can't even get to the feature information PUSH EDX POPFD MOV EAX, 1 DW $A20F // CPUID, EAX contains now version info and EDX feature information MOV EBX, EAX // free EAX to get the result value XOR EAX, EAX // Result := False CMP EBX, $50 JB @1 // if processor family is < 5 then it is not a Pentium class processor TEST EDX, $800000 JZ @1 // if the MMX bit is not set then we don't have MMX INC EAX // Result := True @1: POP EBX end; {$endif} //---------------------------------------------------------------------------------------------------------------------- {$ifdef EnablePrint} procedure PrtStretchDrawDIB(Canvas: TCanvas; DestRect: TRect; ABitmap: TBitmap); // Stretch draw on to the new canvas. var Header, Bits: Pointer; HeaderSize, BitsSize: Cardinal; begin GetDIBSizes(ABitmap.Handle, HeaderSize, BitsSize); GetMem(Header, HeaderSize); GetMem(Bits, BitsSize); try GetDIB(ABitmap.Handle, ABitmap.Palette, Header^, Bits^); StretchDIBits(Canvas.Handle, DestRect.Left, DestRect.Top, DestRect.Right - DestRect.Left, DestRect.Bottom - DestRect.Top, 0, 0, ABitmap.Width, ABitmap.Height, Bits, TBitmapInfo(Header^), DIB_RGB_COLORS, SRCCOPY); finally FreeMem(Header); FreeMem(Bits); end; end; {$endif} //---------------------------------------------------------------------------------------------------------------------- {$ifdef EnableAccessible} procedure GetAccessibilityFactory; // Accessibility helper function to create a singleton class that will create or return // the IAccessible interface for the tree and the focused node. begin // Check to see if the class has already been created. if VTAccessibleFactory = nil then VTAccessibleFactory := TVTAccessibilityFactory.Create; end; {$endif} //---------------------------------------------------------------------------------------------------------------------- procedure InitializeGlobalStructures; // initialization of stuff global to the unit begin Initialized := True; // For the drag image a fast MMX blend routine is used. We have to make sure MMX is available. MMXAvailable := HasMMX; // There is a bug in Win95 and WinME (and potentially in Win98 too) regarding GetDCEx which causes sometimes // serious trouble within GDI (see method WMNCPaint). //IsWinNT := (Win32Platform and VER_PLATFORM_WIN32_NT) <> 0; IsWinNT := True; {$ifdef EnableOLE} // Initialize OLE subsystem for drag'n drop and clipboard operations. //todo: replace by Suceeded (see in windows unit) NeedToUnitialize := OleInitialize(nil) in [S_FALSE,S_OK]; {$endif} // Register the tree reference clipboard format. Others will be handled in InternalClipboarFormats. CF_VTREFERENCE := ClipboardRegisterFormat(CFSTR_VTREFERENCE); UtilityImages := TBitmap.Create; UtilityImages.Transparent := True; UtilityImages.LoadFromLazarusResource('VT_UTILITIES'); // Specify an useful timer resolution for timeGetTime. timeBeginPeriod(MinimumTimerInterval); // Delphi (at least version 6 and lower) does not provide a standard split cursor. // Hence we have to load our own. Screen.Cursors[crHeaderSplit] := LoadCursorFromLazarusResource('VT_HEADERSPLIT'); Screen.Cursors[crVertSplit] := LoadCursorFromLazarusResource('VT_VERTSPLIT'); // Clipboard format registration. // Native clipboard format. Needs a new identifier and has an average priority to allow other formats to take over. // This format is supposed to use the IStream storage format but unfortunately this does not work when // OLEFlushClipboard is used. Hence it is disabled until somebody finds a solution. CF_VIRTUALTREE := RegisterVTClipboardFormat(CFSTR_VIRTUALTREE, TBaseVirtualTree, 50, TYMED_HGLOBAL {or TYMED_ISTREAM}); // Specialized string tree formats. CF_HTML := RegisterVTClipboardFormat(CFSTR_HTML, TCustomVirtualStringTree, 80); CF_VRTFNOOBJS := RegisterVTClipboardFormat(CFSTR_RTFNOOBJS, TCustomVirtualStringTree, 84); CF_VRTF := RegisterVTClipboardFormat(CFSTR_RTF, TCustomVirtualStringTree, 85); CF_CSV := RegisterVTClipboardFormat(CFSTR_CSV, TCustomVirtualStringTree, 90); // Predefined clipboard formats. Just add them to the internal list. RegisterVTClipboardFormat(CF_TEXT, TCustomVirtualStringTree, 100); RegisterVTClipboardFormat(CF_UNICODETEXT, TCustomVirtualStringTree, 95); end; //---------------------------------------------------------------------------------------------------------------------- procedure FinalizeGlobalStructures; begin timeEndPeriod(MinimumTimerInterval); FreeAndNil(UtilityImages); if NeedToUnitialize then OleUninitialize; end; //----------------- TWorkerThread -------------------------------------------------------------------------------------- procedure AddThreadReference; begin if WorkerThread = nil then begin // Create an event used to trigger our worker thread when something is to do. WorkEvent := TEvent.Create(nil, False, False, ''); //todo: see how to check if a event was succesfully created under linux since handle is allways 0 {$ifdef Windows} if WorkEvent.Handle = TEventHandle(0) then Raise Exception.Create('VirtualTreeView - Error creating TEvent instance'); {$endif} // Create worker thread, initialize it and send it to its wait loop. WorkerThread := TWorkerThread.Create(False); end; Inc(WorkerThread.FRefCount); end; //---------------------------------------------------------------------------------------------------------------------- procedure ReleaseThreadReference(Tree: TBaseVirtualTree); begin if Assigned(WorkerThread) then begin Dec(WorkerThread.FRefCount); // Make sure there is no reference remaining to the releasing tree. Tree.InterruptValidation; if WorkerThread.FRefCount = 0 then begin with WorkerThread do begin Terminate; WorkEvent.SetEvent; //lcl: probably not necessary under fpc. Remove later // The following work around is no longer necessary with Delphi 6 and up. {$ifndef fpc} // There is a problem when the thread is freed in the exit code of a DLL. This can happen when a tree is // destroyed on unload of a DLL (e.g. control panel applet). In this case only the main thread will get // CPU time, other threads will never awake again. The VCL however waits for a thread when freeing it // which will result in a deadlock (the WaitFor call does not return because the thread does not get CPU time). // If a thread is however suspended then the VCL does not wait and all is fine. if IsLibrary then Suspend; {$endif} WorkerThread.Free; end; WorkerThread := nil; WorkEvent.Free; end; end; end; //---------------------------------------------------------------------------------------------------------------------- constructor TWorkerThread.Create(CreateSuspended: Boolean); begin inherited Create(CreateSuspended); FWaiterList := TThreadList.Create; end; //---------------------------------------------------------------------------------------------------------------------- destructor TWorkerThread.Destroy; begin // First let the ancestor stop the thread before freeing our resources. inherited; FWaiterList.Free; end; //---------------------------------------------------------------------------------------------------------------------- procedure TWorkerThread.CancelValidation(Tree: TBaseVirtualTree); var Msg: TMsg; begin // Wait for any references to this tree to be released. // Pump WM_CHANGESTATE messages so the thread doesn't block on SendMessage calls. while FCurrentTree = Tree do begin if Tree.HandleAllocated and PeekMessage(Msg, Tree.Handle, WM_CHANGESTATE, WM_CHANGESTATE, PM_REMOVE) then begin //todo: see if is correct / will work Application.ProcessMessages; //TranslateMessage(Msg); //DispatchMessage(Msg); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TWorkerThread.ChangeTreeStates(EnterStates, LeaveStates: TChangeStates); begin if Assigned(FCurrentTree) and (FCurrentTree.HandleAllocated) then SendMessage(FCurrentTree.Handle, WM_CHANGESTATE, Byte(EnterStates), Byte(LeaveStates)); end; //---------------------------------------------------------------------------------------------------------------------- procedure TWorkerThread.Execute; // Does some background tasks, like validating tree caches. var EnterStates, LeaveStates: TChangeStates; begin while not Terminated do begin WorkEvent.WaitFor(INFINITE); if not Terminated then begin // Get the next waiting tree. with FWaiterList.LockList do try if Count > 0 then begin FCurrentTree := Items[0]; // Remove this tree from waiter list. Delete(0); // If there is yet another tree to work on then set the work event to keep looping. if Count > 0 then WorkEvent.SetEvent; end else FCurrentTree := nil; finally FWaiterList.UnlockList; end; // Something to do? if Assigned(FCurrentTree) then begin try ChangeTreeStates([csValidating], [csUseCache]); EnterStates := []; if not (tsStopValidation in FCurrentTree.FStates) and FCurrentTree.DoValidateCache then EnterStates := [csUseCache]; finally LeaveStates := [csValidating, csStopValidation]; if csUseCache in EnterStates then Include(LeaveStates, csValidationNeeded); ChangeTreeStates(EnterStates, LeaveStates); FCurrentTree := nil; end; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TWorkerThread.AddTree(Tree: TBaseVirtualTree); begin Assert(Assigned(Tree), 'Tree must not be nil.'); // Remove validation stop flag, just in case it is still set. Tree.DoStateChange([], [tsStopValidation]); with FWaiterList.LockList do try if IndexOf(Tree) = -1 then Add(Tree); finally FWaiterList.UnlockList; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TWorkerThread.RemoveTree(Tree: TBaseVirtualTree); begin Assert(Assigned(Tree), 'Tree must not be nil.'); with FWaiterList.LockList do try Remove(Tree); finally FWaiterList.UnlockList; end; CancelValidation(Tree); end; //----------------- TBufferedUTF8String -------------------------------------------------------------------------------- const AllocIncrement = 2 shl 11; // Must be a power of 2. destructor TBufferedUTF8String.Destroy; begin FreeMem(FStart); inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TBufferedUTF8String.GetAsAnsiString: AnsiString; begin //an implicit conversion is done Result := AsUTF16String; end; //---------------------------------------------------------------------------------------------------------------------- function TBufferedUTF8String.GetAsUTF16String: UnicodeString; begin //todo: optimize Result := UTF8Decode(AsUTF8String); end; //---------------------------------------------------------------------------------------------------------------------- function TBufferedUTF8String.GetAsUTF8String: String; begin SetString(Result, FStart, FPosition - FStart); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBufferedUTF8String.Add(const S: String); var NewLen, LastOffset, Len: Integer; begin Len := Length(S); // Make room for the new string. if FEnd - FPosition <= Len then begin // Round up NewLen so it is always a multiple of AllocIncrement. NewLen := FEnd - FStart + (Len + AllocIncrement - 1) and not (AllocIncrement - 1); // Keep last offset to restore it correctly in the case that FStart gets a new memory block assigned. LastOffset := FPosition - FStart; ReallocMem(FStart, NewLen); FPosition := FStart + LastOffset; FEnd := FStart + NewLen; end; Move(PChar(S)^, FPosition^, Len); Inc(FPosition, Len); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBufferedUTF8String.AddNewLine; var NewLen, LastOffset: Integer; begin // Make room for the CR/LF characters. if FEnd - FPosition <= 4 then begin //todo: see in calculation of NewLen is correct for String // Round up NewLen so it is always a multiple of AllocIncrement. NewLen := FEnd - FStart + (2 + AllocIncrement - 1) and not (AllocIncrement - 1); // Keep last offset to restore it correctly in the case that FStart gets a new memory block assigned. LastOffset := FPosition - FStart; ReallocMem(FStart, NewLen); FPosition := FStart + LastOffset; FEnd := FStart + NewLen; end; FPosition^ := #13; Inc(FPosition); FPosition^ := #10; Inc(FPosition); end; //----------------- TCustomVirtualTreeOptions -------------------------------------------------------------------------- constructor TCustomVirtualTreeOptions.Create(AOwner: TBaseVirtualTree); begin FOwner := AOwner; FPaintOptions := DefaultPaintOptions; FAnimationOptions := DefaultAnimationOptions; FAutoOptions := DefaultAutoOptions; FSelectionOptions := DefaultSelectionOptions; FMiscOptions := DefaultMiscOptions; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualTreeOptions.SetAnimationOptions(const Value: TVTAnimationOptions); begin FAnimationOptions := Value; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualTreeOptions.SetAutoOptions(const Value: TVTAutoOptions); var ChangedOptions: TVTAutoOptions; begin if FAutoOptions <> Value then begin // Exclusive ORing to get all entries wich are in either set but not in both. ChangedOptions := FAutoOptions + Value - (FAutoOptions * Value); FAutoOptions := Value; with FOwner do if (toAutoSpanColumns in ChangedOptions) and not (csLoading in ComponentState) and HandleAllocated then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualTreeOptions.SetMiscOptions(const Value: TVTMiscOptions); var ToBeSet, ToBeCleared: TVTMiscOptions; begin if FMiscOptions <> Value then begin ToBeSet := Value - FMiscOptions; ToBeCleared := FMiscOptions - Value; FMiscOptions := Value; {$ifndef Windows} Exclude(FMiscOptions,toAcceptOLEDrop); Exclude(ToBeCleared,toAcceptOLEDrop); Exclude(ToBeSet,toAcceptOLEDrop); {$endif} with FOwner do if not (csLoading in ComponentState) and HandleAllocated then begin if toCheckSupport in ToBeSet + ToBeCleared then begin CheckImageListNeeded; Invalidate; end; if not (csDesigning in ComponentState) then begin if toFullRepaintOnResize in (TobeSet + ToBeCleared) then //todo_lcl_check RecreateWnd(FOwner); if toAcceptOLEDrop in ToBeSet then RegisterDragDrop(Handle, DragManager as IDropTarget); if toAcceptOLEDrop in ToBeCleared then RevokeDragDrop(Handle); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualTreeOptions.SetPaintOptions(const Value: TVTPaintOptions); var ToBeSet, ToBeCleared: TVTPaintOptions; begin if FPaintOptions <> Value then begin ToBeSet := Value - FPaintOptions; ToBeCleared := FPaintOptions - Value; FPaintOptions := Value; with FOwner do if HandleAllocated then begin {$ifdef ThemeSupport} //todo // if (tsUseThemes in FStates) or (toThemeAware in ToBeSet) then // if (toUseExplorerTheme in ToBeSet) and IsWinVistaOrAbove then // SetWindowTheme(Handle, 'explorer', nil) // else // SetWindowTheme(Handle, '', nil); {$endif ThemeSupport} if not (csLoading in ComponentState) then begin {$ifdef ThemeSupport} if (toThemeAware in ToBeSet + ToBeCleared) or (toUseExplorerTheme in ToBeSet + ToBeCleared) then begin if (toThemeAware in ToBeSet) and ThemeServices.ThemesEnabled then DoStateChange([tsUseThemes]) else if (toThemeAware in ToBeCleared) then DoStateChange([], [tsUseThemes]); PrepareBitmaps(True, False); RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_VALIDATE or RDW_FRAME); end else {$endif ThemeSupport} Invalidate; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualTreeOptions.SetSelectionOptions(const Value: TVTSelectionOptions); var ToBeSet, ToBeCleared: TVTSelectionOptions; begin if FSelectionOptions <> Value then begin ToBeSet := Value - FSelectionOptions; ToBeCleared := FSelectionOptions - Value; FSelectionOptions := Value; with FOwner do begin if (toMultiSelect in (ToBeCleared + ToBeSet)) or ([toLevelSelectConstraint, toSiblingSelectConstraint] * ToBeSet <> []) then ClearSelection; if (toExtendedFocus in ToBeCleared) and (FFocusedColumn > 0) and HandleAllocated then begin FFocusedColumn := FHeader.MainColumn; Invalidate; end; if not (toExtendedFocus in FSelectionOptions) then FFocusedColumn := FHeader.MainColumn; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualTreeOptions.AssignTo(Dest: TPersistent); begin if Dest is TCustomVirtualTreeOptions then begin with TCustomVirtualTreeOptions(Dest) do begin PaintOptions := Self.PaintOptions; AnimationOptions := Self.AnimationOptions; AutoOptions := Self.AutoOptions; SelectionOptions := Self.SelectionOptions; MiscOptions := Self.MiscOptions; end; end else inherited; end; {$i vtvdragmanager.inc} //----------------- TVirtualTreeHintWindow ----------------------------------------------------------------------------- procedure TVirtualTreeHintWindow.WMShowWindow(var Message: TLMShowWindow); // Clear hint data when the window becomes hidden. begin if not Message.Show then begin // Don't touch the last hint rectangle stored in the associated tree to avoid flickering in certain situations. Finalize(FHintData); FillChar(FHintData, SizeOf(FHintData), 0); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeHintWindow.Paint; begin with FHintData do begin if Tree is TCustomVirtualDrawTree and Assigned(Node) then begin // The draw tree has by default no hint text so let it draw the hint itself. // HintBorderWidth is a private constant in hint code and is set to two TCustomVirtualDrawTree(Tree).DoDrawHint(Canvas, Node, Rect(0, 0, Width - 2, Height - 2), Column); end else inherited; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeHintWindow.CalcHintRect(MaxWidth: Integer; const AHint: string; AData: Pointer): TRect; var P: TPoint; begin if AData = nil then // Defensive approach, it *can* happen that AData is nil. Maybe when several user defined hint classes are used. Result := Rect(0, 0, 0, 0) else begin FHintData := PVTHintData(AData)^; with FHintData do begin // The draw tree gets its hint size by the application (but only if not a header hint is about to show). // This size has already been determined in CMHintShow. if (Tree is TCustomVirtualDrawTree) and Assigned(Node) then Result := HintRect else begin //todo remove this define as soon as 0.9.30 is released to avoid future problems if Column <= NoColumn then begin BidiMode := Tree.BidiMode; Alignment := Tree.Alignment; end else begin BidiMode := Tree.Header.Columns[Column].BidiMode; Alignment := Tree.Header.Columns[Column].Alignment; end; //select font according to the type of hint if (Node = nil) or (Tree.FHintMode <> hmToolTip) then Canvas.Font := Screen.HintFont else begin Canvas.Font := Tree.Font; //necessary to set customized fonts if Tree is TCustomVirtualStringTree then with TCustomVirtualStringTree(Tree) do DoPaintText(Node, Self.Canvas, Column, ttNormal); //force the default hint font color Canvas.Font.Color := Screen.HintFont.Color; end; //let THintWindow do the job Result := inherited CalcHintRect(MaxWidth, AHint, AData); //fix position taking into account bidimode and control bounds if (Tree.HintMode <> hmTooltip) or ((Result.Right - Result.Left) < Tree.Width) then begin if BiDiMode = bdLeftToRight then begin P := Tree.ClientToScreen(Point(0, 0)); HintInfo^.HintPos.X := Max(P.X, HintInfo^.HintPos.X); end else begin if (Tree.HintMode = hmTooltip) and (Node <> nil) then begin P := Tree.ClientToScreen(Point(Min(Tree.ClientWidth, HintInfo^.CursorRect.Right), 0)); Dec(P.X, Result.Right); HintInfo^.HintPos.X := Max(P.X, HintInfo^.HintPos.X); end else Dec(HintInfo^.HintPos.X, Result.Right - 20); end; end; end; end; end; end; //----------------- TVTDragImage --------------------------------------------------------------------------------------- constructor TVTDragImage.Create(AOwner: TBaseVirtualTree); begin FOwner := AOwner; FTransparency := 128; FPreBlendBias := 0; FPostBlendBias := 0; FFade := False; FRestriction := dmrNone; FColorKey := clNone; end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTDragImage.Destroy; begin EndDrag; inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragImage.GetVisible: Boolean; // Returns True if the internal drag image is used (i.e. the system does not natively support drag images) and // the internal image is currently visible on screen. begin Result := FStates * [disHidden, disInDrag, disPrepared, disSystemSupport] = [disInDrag, disPrepared]; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragImage.InternalShowDragImage(ScreenDC: HDC); // Frequently called helper routine to actually do the blend and put it onto the screen. // Only used if the system does not support drag images. var BlendMode: TBlendMode; begin with FAlphaImage do BitBlt(Canvas.Handle, 0, 0, Width, Height, FBackImage.Canvas.Handle, 0, 0, SRCCOPY); if not FFade and (FColorKey = clNone) then BlendMode := bmConstantAlpha else BlendMode := bmMasterAlpha; with FDragImage do AlphaBlend(Canvas.Handle, FAlphaImage.Canvas.Handle, Rect(0, 0, Width, Height), Point(0, 0), BlendMode, FTransparency, FPostBlendBias); with FAlphaImage do BitBlt(ScreenDC, FImagePosition.X, FImagePosition.Y, Width, Height, Canvas.Handle, 0, 0, SRCCOPY); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragImage.MakeAlphaChannel(Source, Target: TBitmap); // Helper method to create a proper alpha channel in Target (which must be in 32 bit pixel format), depending // on the settings for the drag image and the color values in Source. // Only used if the system does not support drag images. type PBGRA = ^TBGRA; TBGRA = packed record case Boolean of False: (Color: Cardinal); True: (BGR: array[0..2] of Byte; Alpha: Byte); end; var Color, ColorKeyRef: COLORREF; UseColorKey: Boolean; SourceRun, TargetRun: PBGRA; X, Y, MaxDimension, HalfWidth, HalfHeight: Integer; T: Extended; SourceBits, TargetBits: Pointer; begin {$ifdef EnableAdvancedGraphics} SourceBits := GetBitmapBitsFromBitmap(Source.Handle); TargetBits := GetBitmapBitsFromBitmap(Target.Handle); if (SourceBits = nil) or (TargetBits = nil) then Exit; UseColorKey := ColorKey <> clNone; ColorKeyRef := ColorToRGB(ColorKey) and $FFFFFF; // Color values are in the form BGR (red on LSB) while bitmap colors are in the form ARGB (blue on LSB) // hence we have to swap red and blue in the color key. with TBGRA(ColorKeyRef) do begin X := BGR[0]; BGR[0] := BGR[2]; BGR[2] := X; end; with Target do begin MaxDimension := Max(Width, Height); HalfWidth := Width div 2; HalfHeight := Height div 2; for Y := 0 to Height - 1 do begin TargetRun := CalculateScanline(TargetBits, Width, Height, Y); SourceRun := CalculateScanline(SourceBits, Source.Width, Source.Height, Y); for X := 0 to Width - 1 do begin Color := SourceRun.Color and $FFFFFF; if UseColorKey and (Color = ColorKeyRef) then TargetRun.Alpha := 0 else begin // If the color is not the given color key (or none is used) then do full calculation of a bell curve. T := exp(-8 * Sqrt(Sqr((X - HalfWidth) / MaxDimension) + Sqr((Y - HalfHeight) / MaxDimension))); TargetRun.Alpha := Round(255 * T); end; Inc(SourceRun); Inc(TargetRun); end; end; end; {$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragImage.DragTo(const P: TPoint; ForceRepaint: Boolean): Boolean; // Moves the drag image to a new position, which is determined from the passed point P and the previous // mouse position. // ForceRepaint is True if something on the screen changed and the back image must be refreshed. var ScreenDC: HDC; DeltaX, DeltaY: Integer; // optimized drag image move support RSamp1, RSamp2, // newly added parts from screen which will be overwritten RDraw1, RDraw2, // parts to be restored to screen RScroll, RClip: TRect; // ScrollDC of the existent background begin // Determine distances to move the drag image. Take care for restrictions. case FRestriction of dmrHorizontalOnly: begin DeltaX := FLastPosition.X - P.X; DeltaY := 0; end; dmrVerticalOnly: begin DeltaX := 0; DeltaY := FLastPosition.Y - P.Y; end; else // dmrNone DeltaX := FLastPosition.X - P.X; DeltaY := FLastPosition.Y - P.Y; end; Result := (DeltaX <> 0) or (DeltaY <> 0) or ForceRepaint; if Result then begin if Visible then begin // All this stuff is only called if we have to handle the drag image ourselves. If the system supports // drag image then this is all never executed. ScreenDC := GetDC(0); try if (Abs(DeltaX) >= FDragImage.Width) or (Abs(DeltaY) >= FDragImage.Height) or ForceRepaint then begin // If moved more than image size then just restore old screen and blit image to new position. BitBlt(ScreenDC, FImagePosition.X, FImagePosition.Y, FBackImage.Width, FBackImage.Height, FBackImage.Canvas.Handle, 0, 0, SRCCOPY); if ForceRepaint then UpdateWindow(FOwner.Handle); Inc(FImagePosition.X, -DeltaX); Inc(FImagePosition.Y, -DeltaY); BitBlt(FBackImage.Canvas.Handle, 0, 0, FBackImage.Width, FBackImage.Height, ScreenDC, FImagePosition.X, FImagePosition.Y, SRCCOPY); end else begin // overlapping copy FillDragRectangles(FDragImage.Width, FDragImage.Height, DeltaX, DeltaY, RClip, RScroll, RSamp1, RSamp2, RDraw1, RDraw2); with FBackImage.Canvas do begin // restore uncovered areas of the screen if DeltaX = 0 then begin with RDraw2 do BitBlt(ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, Right, Bottom, Handle, Left, Top, SRCCOPY); end else begin if DeltaY = 0 then begin with RDraw1 do BitBlt(ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, Right, Bottom, Handle, Left, Top, SRCCOPY); end else begin with RDraw1 do BitBlt(ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, Right, Bottom, Handle, Left, Top, SRCCOPY); with RDraw2 do BitBlt(ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, Right, Bottom, Handle, Left, Top, SRCCOPY); end; end; //todo: implement ScrollDC. Alternatively reimplement drag operations {$ifndef INCOMPLETE_WINAPI} // move existent background ScrollDC(Handle, DeltaX, DeltaY, RScroll, RClip, 0, nil); {$endif} Inc(FImagePosition.X, -DeltaX); Inc(FImagePosition.Y, -DeltaY); // Get first and second additional rectangle from screen. if DeltaX = 0 then begin with RSamp2 do BitBlt(Handle, Left, Top, Right, Bottom, ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, SRCCOPY); end else if DeltaY = 0 then begin with RSamp1 do BitBlt(Handle, Left, Top, Right, Bottom, ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, SRCCOPY); end else begin with RSamp1 do BitBlt(Handle, Left, Top, Right, Bottom, ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, SRCCOPY); with RSamp2 do BitBlt(Handle, Left, Top, Right, Bottom, ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, SRCCOPY); end; end; end; InternalShowDragImage(ScreenDC); finally ReleaseDC(0, ScreenDC); end; end; FLastPosition.X := P.X; FLastPosition.Y := P.Y; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragImage.EndDrag; begin HideDragImage; FStates := FStates - [disInDrag, disPrepared]; FBackImage.Free; FBackImage := nil; FDragImage.Free; FDragImage := nil; FAlphaImage.Free; FAlphaImage := nil; end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragImage.GetDragImageRect: TRect; // Returns the current size and position of the drag image (screen coordinates). begin if Visible then begin with FBackImage do Result := Rect(FImagePosition.X, FImagePosition.Y, FImagePosition.X + Width, FImagePosition.Y + Height); end else Result := Rect(0, 0, 0, 0); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragImage.HideDragImage; var ScreenDC: HDC; begin if Visible then begin Include(FStates, disHidden); ScreenDC := GetDC(0); try // restore screen with FBackImage do BitBlt(ScreenDC, FImagePosition.X, FImagePosition.Y, Width, Height, Canvas.Handle, 0, 0, SRCCOPY); finally ReleaseDC(0, ScreenDC); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragImage.PrepareDrag(DragImage: TBitmap; const ImagePosition, HotSpot: TPoint; const DataObject: IDataObject); // Creates all necessary structures to do alpha blended dragging using the given image. // ImagePostion and Hotspot are given in screen coordinates. The first determines where to place the drag image while // the second is the initial mouse position. // This method also determines whether the system supports drag images natively. If so then only minimal structures // are created. var Width, Height: Integer; DragSourceHelper: IDragSourceHelper; DragInfo: TSHDragImage; begin Width := DragImage.Width; Height := DragImage.Height; // Determine whether the system supports the drag helper interfaces. if Assigned(DataObject) and Succeeded(CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDragSourceHelper, DragSourceHelper)) then begin Include(FStates, disSystemSupport); // Supply the drag source helper with our drag image. DragInfo.sizeDragImage.cx := Width; DragInfo.sizeDragImage.cy := Height; DragInfo.ptOffset.x := Width div 2; DragInfo.ptOffset.y := Height div 2; //todo: replace CopyImage. Alternatively reimplement Drag support {$ifndef INCOMPLETE_WINAPI} DragInfo.hbmpDragImage := CopyImage(DragImage.Handle, IMAGE_BITMAP, Width, Height, LR_COPYRETURNORG); {$else} DragInfo.hbmpDragImage := 0; {$endif} DragInfo.ColorRef := ColorToRGB(FColorKey); if not Succeeded(DragSourceHelper.InitializeFromBitmap(DragInfo, DataObject)) then begin DeleteObject(DragInfo.hbmpDragImage); Exclude(FStates, disSystemSupport); end; end else Exclude(FStates, disSystemSupport); if MMXAvailable and not (disSystemSupport in FStates) then begin FLastPosition := HotSpot; FDragImage := TBitmap.Create; FDragImage.PixelFormat := pf32Bit; FDragImage.Width := Width; FDragImage.Height := Height; FAlphaImage := TBitmap.Create; FAlphaImage.PixelFormat := pf32Bit; FAlphaImage.Width := Width; FAlphaImage.Height := Height; FBackImage := TBitmap.Create; FBackImage.PixelFormat := pf32Bit; FBackImage.Width := Width; FBackImage.Height := Height; // Copy the given drag image and apply pre blend bias if required. if FPreBlendBias = 0 then with FDragImage do BitBlt(Canvas.Handle, 0, 0, Width, Height, DragImage.Canvas.Handle, 0, 0, SRCCOPY) else AlphaBlend(DragImage.Canvas.Handle, FDragImage.Canvas.Handle, Rect(0, 0, Width, Height), Point(0, 0), bmConstantAlpha, 255, FPreBlendBias); // Create a proper alpha channel also if no fading is required (transparent parts). MakeAlphaChannel(DragImage, FDragImage); FImagePosition := ImagePosition; // Initially the drag image is hidden and will be shown during the immediately following DragEnter event. FStates := FStates + [disInDrag, disHidden, disPrepared]; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragImage.RecaptureBackground(Tree: TBaseVirtualTree; R: TRect; VisibleRegion: HRGN; CaptureNCArea, ReshowDragImage: Boolean); // Notification by the drop target tree to update the background image because something in the tree has changed. // Note: The passed rectangle is given in client coordinates of the current drop target tree (given in Tree). // The caller does not check if the given rectangle is actually within the drag image. Hence this method must do // all the checks. // This method does nothing if the system manages the drag image. {$ifndef INCOMPLETE_WINAPI} var DragRect, ClipRect: TRect; PaintTarget: TPoint; PaintOptions: TVTInternalPaintOptions; ScreenDC: HDC; {$endif} begin //todo: reimplement {$ifndef INCOMPLETE_WINAPI} // Recapturing means we want the tree to paint the new part into our back bitmap instead to the screen. if Visible then begin // Create the minimum rectangle to be recaptured. MapWindowPoints(Tree.Handle, 0, R, 2); DragRect := GetDragImageRect; IntersectRect(R, R, DragRect); OffsetRgn(VisibleRegion, -DragRect.Left, -DragRect.Top); // The target position for painting in the drag image is relative and can be determined from screen coordinates too. PaintTarget.X := R.Left - DragRect.Left; PaintTarget.Y := R.Top - DragRect.Top; // The source rectangle is determined by the offsets in the tree. MapWindowPoints(0, Tree.Handle, R, 2); OffsetRect(R, -Tree.FOffsetX, -Tree.FOffsetY); // Finally let the tree paint the relevant part and upate the drag image on screen. PaintOptions := [poBackground, poColumnColor, poDrawFocusRect, poDrawDropMark, poDrawSelection, poGridLines]; with FBackImage do begin ClipRect.TopLeft := PaintTarget; ClipRect.Right := ClipRect.Left + R.Right - R.Left; ClipRect.Bottom := ClipRect.Top + R.Bottom - R.Top; Tree.LimitPaintingToArea(Canvas, ClipRect, VisibleRegion); Tree.PaintTree(Canvas, R, PaintTarget, PaintOptions); if CaptureNCArea then begin // For the non-client area we only need the visible region of the window as limit for painting. SelectClipRgn(Canvas.Handle, VisibleRegion); // Since WM_PRINT cannot be given a position where to draw we simply move the window origin and // get the same effect. GetWindowRect(Tree.Handle, ClipRect); SetWindowOrgEx(Canvas.Handle, DragRect.Left - ClipRect.Left, DragRect.Top - ClipRect.Top, nil); //todo: see what todo here //Tree.Perform(WM_PRINT, Integer(Canvas.Handle), PRF_NONCLIENT); SetWindowOrgEx(Canvas.Handle, 0, 0, nil); end; SelectClipRgn(Canvas.Handle, 0); if ReshowDragImage then begin GDIFlush; ScreenDC := GetDC(0); try InternalShowDragImage(ScreenDC); finally ReleaseDC(0, ScreenDC); end; end; end; end; {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTDragImage.ShowDragImage; // Shows the drag image after it has been hidden by HideDragImage. // Note: there might be a new background now. // Also this method does nothing if the system manages the drag image. {$ifndef INCOMPLETE_WINAPI} var ScreenDC: HDC; {$endif} begin {$ifndef INCOMPLETE_WINAPI} if FStates * [disInDrag, disHidden, disPrepared, disSystemSupport] = [disInDrag, disHidden, disPrepared] then begin Exclude(FStates, disHidden); GDIFlush; ScreenDC := GetDC(0); try BitBlt(FBackImage.Canvas.Handle, 0, 0, FBackImage.Width, FBackImage.Height, ScreenDC, FImagePosition.X, FImagePosition.Y, SRCCOPY); InternalShowDragImage(ScreenDC); finally ReleaseDC(0, ScreenDC); end; end; {$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TVTDragImage.WillMove(const P: TPoint): Boolean; // This method determines whether the drag image would "physically" move when DragTo would be called with the same // target point. // Always returns False if the system drag image support is available. var DeltaX, DeltaY: Integer; begin Result := Visible; if Result then begin // Determine distances to move the drag image. Take care for restrictions. case FRestriction of dmrHorizontalOnly: begin DeltaX := FLastPosition.X - P.X; DeltaY := 0; end; dmrVerticalOnly: begin DeltaX := 0; DeltaY := FLastPosition.Y - P.Y; end; else // dmrNone DeltaX := FLastPosition.X - P.X; DeltaY := FLastPosition.Y - P.Y; end; Result := (DeltaX <> 0) or (DeltaY <> 0); end; end; //----------------- TVirtualTreeColumn --------------------------------------------------------------------------------- constructor TVirtualTreeColumn.Create(Collection: TCollection); begin FMinWidth := 10; FMaxWidth := 10000; FImageIndex := -1; FMargin := 4; FSpacing := 4; FText := ''; FOptions := DefaultColumnOptions; FAlignment := taLeftJustify; FBidiMode := bdLeftToRight; FColor := clWindow; FLayout := blGlyphLeft; FBonusPixel := False; FCaptionAlignment := taLeftJustify; FCheckType := ctCheckBox; FCheckState := csUncheckedNormal; FCheckBox := False; FHasImage := False; inherited Create(Collection); FWidth := Owner.FDefaultWidth; FLastWidth := Owner.FDefaultWidth; //lcl: setting FPosition here will override the Design time value //FPosition := Owner.Count - 1; // Read parent bidi mode and color values as default values. ParentBiDiModeChanged; ParentColorChanged; end; //---------------------------------------------------------------------------------------------------------------------- destructor TVirtualTreeColumn.Destroy; var I: Integer; //--------------- local function --------------------------------------------- procedure AdjustColumnIndex(var ColumnIndex: TColumnIndex); begin if Index = ColumnIndex then ColumnIndex := NoColumn else if Index < ColumnIndex then Dec(ColumnIndex); end; //--------------- end local function ----------------------------------------- begin // Check if this column is somehow referenced by its collection parent or the header. with Owner do begin // If the columns collection object is currently deleting all columns // then we don't need to check the various cached indices individually. if not FClearing then begin IndexChanged(Index, -1); AdjustColumnIndex(FHoverIndex); AdjustColumnIndex(FDownIndex); AdjustColumnIndex(FTrackIndex); AdjustColumnIndex(FClickIndex); with Header do begin AdjustColumnIndex(FAutoSizeIndex); if Index = FMainColumn then begin // If the current main column is about to be destroyed then we have to find a new main column. FMainColumn := NoColumn; for I := 0 to Count - 1 do if I <> Index then begin FMainColumn := I; Break; end; end; AdjustColumnIndex(FSortColumn); end; end; end; inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumn.GetCaptionAlignment: TAlignment; begin if coUseCaptionAlignment in FOptions then Result := FCaptionAlignment else Result := FAlignment; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumn.GetLeft: Integer; begin Result := FLeft; if [coVisible, coFixed] * FOptions <> [coVisible, coFixed] then Dec(Result, Owner.Header.Treeview.FEffectiveOffsetX); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumn.IsBiDiModeStored: Boolean; begin Result := not (coParentBiDiMode in FOptions); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumn.IsCaptionAlignmentStored: Boolean; begin Result := coUseCaptionAlignment in FOptions; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumn.IsColorStored: Boolean; begin Result := not (coParentColor in FOptions); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetAlignment(const Value: TAlignment); begin if FAlignment <> Value then begin FAlignment := Value; Changed(False); // Setting the alignment affects also the tree, hence invalidate it too. Owner.Header.TreeView.Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetBiDiMode(Value: TBiDiMode); begin if Value <> FBiDiMode then begin FBiDiMode := Value; Exclude(FOptions, coParentBiDiMode); Changed(False); // Setting the alignment affects also the tree, hence invalidate it too. Owner.Header.TreeView.Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetCaptionAlignment(const Value: TAlignment); begin if not (coUseCaptionAlignment in FOptions) or (FCaptionAlignment <> Value) then begin FCaptionAlignment := Value; Exclude(FOptions, coUseCaptionAlignment); // Setting the alignment affects also the tree, hence invalidate it too. Owner.Header.Invalidate(Self); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetColor(const Value: TColor); begin if FColor <> Value then begin FColor := Value; Exclude(FOptions, coParentColor); Changed(False); Owner.Header.TreeView.Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetCheckBox(Value: boolean); begin if Value <> FCheckBox then begin FCheckBox := Value; //lcl if FCheckBox then Owner.Header.Treeview.CheckImageListNeeded; Changed(False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetCheckState(Value: TCheckState); begin if Value <> FCheckState then begin FCheckState := Value; Changed(False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetCheckType(Value: TCheckType); begin if Value <> FCheckType then begin FCheckType := Value; Changed(False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetImageIndex(Value: TImageIndex); begin if Value <> FImageIndex then begin FImageIndex := Value; Changed(False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetLayout(Value: TVTHeaderColumnLayout); begin if FLayout <> Value then begin FLayout := Value; Changed(False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetMargin(Value: Integer); begin // Compatibility setting for -1. if Value < 0 then Value := 4; if FMargin <> Value then begin FMargin := Value; Changed(False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetMaxWidth(Value: Integer); begin if Value < FMinWidth then Value := FMinWidth; if not IsWinNT and (Value > 10000) then Value := 10000; FMaxWidth := Value; SetWidth(FWidth); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetMinWidth(Value: Integer); begin if Value < 0 then Value := 0; if Value > FMaxWidth then Value := FMaxWidth; FMinWidth := Value; SetWidth(FWidth); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetOptions(Value: TVTColumnOptions); var ToBeSet, ToBeCleared: TVTColumnOptions; AVisibleChanged, ColorChanged: Boolean; begin if FOptions <> Value then begin ToBeCleared := FOptions - Value; ToBeSet := Value - FOptions; FOptions := Value; AVisibleChanged := coVisible in (ToBeSet + ToBeCleared); ColorChanged := coParentColor in ToBeSet; if coParentBidiMode in ToBeSet then ParentBiDiModeChanged; if ColorChanged then ParentColorChanged; if coAutoSpring in ToBeSet then FSpringRest := 0; if ((coFixed in ToBeSet) or (coFixed in ToBeCleared)) and (coVisible in FOptions) then Owner.Header.RescaleHeader; Changed(False); // Need to repaint and adjust the owner tree too. //lcl: fpc refuses to compile the original code by no aparent reason. //Found: Was confounding TControl.VisibleChanged with Owner, Header.Treeview do if not (csLoading in ComponentState) and (AVisibleChanged or ColorChanged) and (UpdateCount = 0) and HandleAllocated then begin Invalidate; if AVisibleChanged then UpdateHorizontalScrollBar(False); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetPosition(Value: TColumnPosition); var Temp: TColumnIndex; begin if csLoading in Owner.Header.Treeview.ComponentState then // Only cache the position for final fixup when loading from DFM. FPosition := Value else begin if Value >= TColumnPosition(Collection.Count) then Value := Collection.Count - 1; if FPosition <> Value then begin with Owner do begin InitializePositionArray; Header.Treeview.CancelEditNode; AdjustPosition(Self, Value); Self.Changed(False); // Need to repaint. with Header do begin if (UpdateCount = 0) and Treeview.HandleAllocated then begin Invalidate(Self); Treeview.Invalidate; end; end; end; // If the moved column is now within the fixed columns then we make it fixed as well. If it's not // we clear the fixed state (in case that fixed column is moved outside fixed area). if (coFixed in FOptions) and (FPosition > 0) then Temp := Owner.ColumnFromPosition(FPosition - 1) else Temp := Owner.ColumnFromPosition(FPosition + 1); if Temp <> NoColumn then begin if coFixed in Owner[Temp].Options then Options := Options + [coFixed] else Options := Options - [coFixed] end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetSpacing(Value: Integer); begin if FSpacing <> Value then begin FSpacing := Value; Changed(False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetStyle(Value: TVirtualTreeColumnStyle); begin if FStyle <> Value then begin FStyle := Value; Changed(False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetText(const Value: String); begin if FText <> Value then begin FText := Value; Changed(False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SetWidth(Value: Integer); var EffectiveMaxWidth, EffectiveMinWidth, TotalFixedMaxWidth, TotalFixedMinWidth: Integer; I: TColumnIndex; begin if not (hsScaling in Owner.FHeader.FStates) then if ([coVisible, coFixed] * FOptions = [coVisible, coFixed]) then begin with Owner, FHeader, FFixedAreaConstraints, TreeView do begin TotalFixedMinWidth := 0; TotalFixedMaxWidth := 0; for I := 0 to FColumns.Count - 1 do if ([coVisible, coFixed] * FColumns[I].FOptions = [coVisible, coFixed]) then begin Inc(TotalFixedMaxWidth, FColumns[I].FMaxWidth); Inc(TotalFixedMinWidth, FColumns[I].FMinWidth); end; // The percentage values have precedence over the pixel values. TotalFixedMinWidth := IfThen(FMaxWidthPercent > 0, Min((ClientWidth * FMaxWidthPercent) div 100, TotalFixedMinWidth), TotalFixedMinWidth); TotalFixedMaxWidth := IfThen(FMinWidthPercent > 0, Max((ClientWidth * FMinWidthPercent) div 100, TotalFixedMaxWidth), TotalFixedMaxWidth); EffectiveMaxWidth := Min(TotalFixedMaxWidth - (GetVisibleFixedWidth - Self.FWidth), FMaxWidth); EffectiveMinWidth := Max(TotalFixedMinWidth - (GetVisibleFixedWidth - Self.FWidth), FMinWidth); Value := Min(Max(Value, EffectiveMinWidth), EffectiveMaxWidth); if FMinWidthPercent > 0 then Value := Max((ClientWidth * FMinWidthPercent) div 100 - GetVisibleFixedWidth + Self.FWidth, Value); if FMaxWidthPercent > 0 then Value := Min((ClientWidth * FMaxWidthPercent) div 100 - GetVisibleFixedWidth + Self.FWidth, Value); end; end else Value := Min(Max(Value, FMinWidth), FMaxWidth); if FWidth <> Value then begin FLastWidth := FWidth; if not (hsResizing in Owner.Header.States) then FBonusPixel := False; with Owner, Header do begin if not (hoAutoResize in FOptions) or (Index <> FAutoSizeIndex) then begin FWidth := Value; UpdatePositions; end; if not (csLoading in Treeview.ComponentState) and (UpdateCount = 0) then begin if hoAutoResize in FOptions then AdjustAutoSize(Index); Treeview.DoColumnResize(Index); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.ComputeHeaderLayout(DC: HDC; const Client: TRect; UseHeaderGlyph, UseSortGlyph: Boolean; var HeaderGlyphPos, SortGlyphPos: TPoint; var TextBounds: TRect; DrawFormat: Cardinal; CalculateTextRect: Boolean = False); // The layout of a column header is determined by a lot of factors. This method takes them all into account and // determines all necessary positions and bounds: // - for the header text // - the header glyph // - the sort glyph var TextSize: TSize; TextPos, ClientSize, HeaderGlyphSize, SortGlyphSize: TPoint; CurrentAlignment: TAlignment; MinLeft, MaxRight, TextSpacing: Integer; UseText: Boolean; R: TRect; begin UseText := Length(FText) > 0; // If nothing is to show then don't waste time with useless preparation. if not (UseText or UseHeaderGlyph or UseSortGlyph) then Exit; CurrentAlignment := CaptionAlignment; if FBidiMode <> bdLeftToRight then ChangeBiDiModeAlignment(CurrentAlignment); // Calculate sizes of the involved items. ClientSize := Point(Client.Right - Client.Left, Client.Bottom - Client.Top); with Owner, Header do begin if UseHeaderGlyph then if not FCheckBox then HeaderGlyphSize := Point(FImages.Width, FImages.Height) else HeaderGlyphSize := Point(Treeview.CheckImages.Width, Treeview.CheckImages.Height) else HeaderGlyphSize := Point(0, 0); if UseSortGlyph then begin SortGlyphSize := Point(UtilityImages.Height, UtilityImages.Height); // In any case, the sort glyph is vertically centered. SortGlyphPos.Y := (ClientSize.Y - SortGlyphSize.Y) div 2; end else SortGlyphSize := Point(0, 0); end; if UseText then begin if not (coWrapCaption in FOptions) then begin FCaptionText := FText; GetTextExtentPoint32(DC, PChar(FText), Length(FText), TextSize); Inc(TextSize.cx, 2); TextBounds := Rect(0, 0, TextSize.cx, TextSize.cy); end else begin R := Client; if FCaptionText = '' then FCaptionText := FText; GetStringDrawRect(DC, FCaptionText, R, DrawFormat); TextSize.cx := Client.Right - Client.Left; TextSize.cy := R.Bottom - R.Top; TextBounds := Rect(0, 0, TextSize.cx, TextSize.cy); end; TextSpacing := FSpacing; end else begin TextSpacing := 0; TextSize.cx := 0; TextSize.cy := 0; end; // Check first for the special case where nothing is shown except the sort glyph. if UseSortGlyph and not (UseText or UseHeaderGlyph) then begin // Center the sort glyph in the available area if nothing else is there. SortGlyphPos := Point((ClientSize.X - SortGlyphSize.X) div 2, (ClientSize.Y - SortGlyphSize.Y) div 2); end else begin // Determine extents of text and glyph and calculate positions which are clear from the layout. if (Layout in [blGlyphLeft, blGlyphRight]) or not UseHeaderGlyph then begin HeaderGlyphPos.Y := (ClientSize.Y - HeaderGlyphSize.Y) div 2; // If the text is taller than the given height, perform no vertical centration as this // would make the text even less readable. if TextSize.cy >= ClientSize.Y then TextPos.Y := 0 else TextPos.Y := (ClientSize.Y - TextSize.cy) div 2; end else begin if Layout = blGlyphTop then begin HeaderGlyphPos.Y := (ClientSize.Y - HeaderGlyphSize.Y - TextSize.cy - TextSpacing) div 2; TextPos.Y := HeaderGlyphPos.Y + HeaderGlyphSize.Y + TextSpacing; end else begin TextPos.Y := (ClientSize.Y - HeaderGlyphSize.Y - TextSize.cy - TextSpacing) div 2; HeaderGlyphPos.Y := TextPos.Y + TextSize.cy + TextSpacing; end; end; // Each alignment needs special consideration. case CurrentAlignment of taLeftJustify: begin MinLeft := FMargin; if UseSortGlyph and (FBidiMode <> bdLeftToRight) then begin // In RTL context is the sort glyph placed on the left hand side. SortGlyphPos.X := MinLeft; Inc(MinLeft, SortGlyphSize.X + FSpacing); end; if Layout in [blGlyphTop, blGlyphBottom] then begin // Header glyph is above or below text, so both must be considered when calculating // the left positition of the sort glyph (if it is on the right hand side). TextPos.X := MinLeft; if UseHeaderGlyph then begin HeaderGlyphPos.X := (ClientSize.X - HeaderGlyphSize.X) div 2; if HeaderGlyphPos.X < MinLeft then HeaderGlyphPos.X := MinLeft; MinLeft := Max(TextPos.X + TextSize.cx + TextSpacing, HeaderGlyphPos.X + HeaderGlyphSize.X + FSpacing); end else MinLeft := TextPos.X + TextSize.cx + TextSpacing; end else begin // Everything is lined up. TextSpacing might be 0 if there is no text. // This simplifies the calculation because no extra tests are necessary. if UseHeaderGlyph and (Layout = blGlyphLeft) then begin HeaderGlyphPos.X := MinLeft; Inc(MinLeft, HeaderGlyphSize.X + FSpacing); end; TextPos.X := MinLeft; Inc(MinLeft, TextSize.cx + TextSpacing); if UseHeaderGlyph and (Layout = blGlyphRight) then begin HeaderGlyphPos.X := MinLeft; Inc(MinLeft, HeaderGlyphSize.X + FSpacing); end; end; if UseSortGlyph and (FBidiMode = bdLeftToRight) then SortGlyphPos.X := MinLeft; end; taCenter: begin if Layout in [blGlyphTop, blGlyphBottom] then begin HeaderGlyphPos.X := (ClientSize.X - HeaderGlyphSize.X) div 2; TextPos.X := (ClientSize.X - TextSize.cx) div 2; if UseSortGlyph then Dec(TextPos.X, SortGlyphSize.X div 2); end else begin MinLeft := (ClientSize.X - HeaderGlyphSize.X - TextSpacing - TextSize.cx) div 2; if UseHeaderGlyph and (Layout = blGlyphLeft) then begin HeaderGlyphPos.X := MinLeft; Inc(MinLeft, HeaderGlyphSize.X + TextSpacing); end; TextPos.X := MinLeft; Inc(MinLeft, TextSize.cx + TextSpacing); if UseHeaderGlyph and (Layout = blGlyphRight) then HeaderGlyphPos.X := MinLeft; end; if UseHeaderGlyph then begin MinLeft := Min(HeaderGlyphPos.X, TextPos.X); MaxRight := Max(HeaderGlyphPos.X + HeaderGlyphSize.X, TextPos.X + TextSize.cx); end else begin MinLeft := TextPos.X; MaxRight := TextPos.X + TextSize.cx; end; // Place the sort glyph directly to the left or right of the larger item. if UseSortGlyph then if FBidiMode = bdLeftToRight then begin // Sort glyph on the right hand side. SortGlyphPos.X := MaxRight + FSpacing; end else begin // Sort glyph on the left hand side. SortGlyphPos.X := MinLeft - FSpacing - SortGlyphSize.X; end; end; else // taRightJustify MaxRight := ClientSize.X - FMargin; if UseSortGlyph and (FBidiMode = bdLeftToRight) then begin // In LTR context is the sort glyph placed on the right hand side. Dec(MaxRight, SortGlyphSize.X); SortGlyphPos.X := MaxRight; Dec(MaxRight, FSpacing); end; if Layout in [blGlyphTop, blGlyphBottom] then begin TextPos.X := MaxRight - TextSize.cx; if UseHeaderGlyph then begin HeaderGlyphPos.X := (ClientSize.X - HeaderGlyphSize.X) div 2; if HeaderGlyphPos.X + HeaderGlyphSize.X + FSpacing > MaxRight then HeaderGlyphPos.X := MaxRight - HeaderGlyphSize.X - FSpacing; MaxRight := Min(TextPos.X - TextSpacing, HeaderGlyphPos.X - FSpacing); end else MaxRight := TextPos.X - TextSpacing; end else begin // Everything is lined up. TextSpacing might be 0 if there is no text. // This simplifies the calculation because no extra tests are necessary. if UseHeaderGlyph and (Layout = blGlyphRight) then begin HeaderGlyphPos.X := MaxRight - HeaderGlyphSize.X; MaxRight := HeaderGlyphPos.X - FSpacing; end; TextPos.X := MaxRight - TextSize.cx; MaxRight := TextPos.X - TextSpacing; if UseHeaderGlyph and (Layout = blGlyphLeft) then begin HeaderGlyphPos.X := MaxRight - HeaderGlyphSize.X; MaxRight := HeaderGlyphPos.X - FSpacing; end; end; if UseSortGlyph and (FBidiMode <> bdLeftToRight) then SortGlyphPos.X := MaxRight - SortGlyphSize.X; end; end; // Once the position of each element is determined there remains only one but important step. // The horizontal positions of every element must be adjusted so that it always fits into the // given header area. This is accomplished by shorten the text appropriately. // These are the maximum bounds. Nothing goes beyond them. MinLeft := FMargin; MaxRight := ClientSize.X - FMargin; if UseSortGlyph then begin if FBidiMode = bdLeftToRight then begin // Sort glyph on the right hand side. if SortGlyphPos.X + SortGlyphSize.X > MaxRight then SortGlyphPos.X := MaxRight - SortGlyphSize.X; MaxRight := SortGlyphPos.X - FSpacing; end; // Consider also the left side of the sort glyph regardless of the bidi mode. if SortGlyphPos.X < MinLeft then SortGlyphPos.X := MinLeft; // Left border needs only adjustment if the sort glyph marks the left border. if FBidiMode <> bdLeftToRight then MinLeft := SortGlyphPos.X + SortGlyphSize.X + FSpacing; // Finally transform sort glyph to its actual position. with SortGlyphPos do begin Inc(X, Client.Left); Inc(Y, Client.Top); end; end; if UseHeaderGlyph then begin if HeaderGlyphPos.X + HeaderGlyphSize.X > MaxRight then HeaderGlyphPos.X := MaxRight - HeaderGlyphSize.X; if Layout = blGlyphRight then MaxRight := HeaderGlyphPos.X - FSpacing; if HeaderGlyphPos.X < MinLeft then HeaderGlyphPos.X := MinLeft; if Layout = blGlyphLeft then MinLeft := HeaderGlyphPos.X + HeaderGlyphSize.X + FSpacing; // Finally transform header glyph to its actual position. with HeaderGlyphPos do begin Inc(X, Client.Left); Inc(Y, Client.Top); end; end; if UseText then begin if TextPos.X < MinLeft then TextPos.X := MinLeft; OffsetRect(TextBounds, TextPos.X, TextPos.Y); if TextBounds.Right > MaxRight then TextBounds.Right := MaxRight; OffsetRect(TextBounds, Client.Left, Client.Top); if coWrapCaption in FOptions then begin // Wrap the column caption if necessary. R := TextBounds; FCaptionText := WrapString(DC, FText, R, DT_RTLREADING and DrawFormat <> 0, DrawFormat); GetStringDrawRect(DC, FCaptionText, R, DrawFormat); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.GetAbsoluteBounds(var Left, Right: Integer); // Returns the column's left and right bounds in header coordinates, that is, independent of the scrolling position. begin Left := FLeft; Right := FLeft + FWidth; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumn.GetDisplayName: string; // Returns the column text otherwise the column id is returned begin if Length(FText) > 0 then Result := FText else Result := Format('Column %d', [Index]); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumn.GetOwner: TVirtualTreeColumns; begin Result := Collection as TVirtualTreeColumns; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.Assign(Source: TPersistent); var OldOptions: TVTColumnOptions; begin if Source is TVirtualTreeColumn then begin OldOptions := FOptions; FOptions := []; BiDiMode := TVirtualTreeColumn(Source).BiDiMode; ImageIndex := TVirtualTreeColumn(Source).ImageIndex; Layout := TVirtualTreeColumn(Source).Layout; Margin := TVirtualTreeColumn(Source).Margin; MaxWidth := TVirtualTreeColumn(Source).MaxWidth; MinWidth := TVirtualTreeColumn(Source).MinWidth; Position := TVirtualTreeColumn(Source).Position; Spacing := TVirtualTreeColumn(Source).Spacing; Style := TVirtualTreeColumn(Source).Style; Text := TVirtualTreeColumn(Source).Text; Hint := TVirtualTreeColumn(Source).Hint; Width := TVirtualTreeColumn(Source).Width; Alignment := TVirtualTreeColumn(Source).Alignment; CaptionAlignment := TVirtualTreeColumn(Source).CaptionAlignment; Color := TVirtualTreeColumn(Source).Color; Tag := TVirtualTreeColumn(Source).Tag; // Order is important. Assign options last. FOptions := OldOptions; Options := TVirtualTreeColumn(Source).Options; Changed(False); end else inherited Assign(Source); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumn.Equals(OtherColumnObj: TObject): Boolean; var OtherColumn : TVirtualTreeColumn; begin if OtherColumnObj is TVirtualTreeColumn then begin OtherColumn := TVirtualTreeColumn (OtherColumnObj); Result := (BiDiMode = OtherColumn.BiDiMode) and (ImageIndex = OtherColumn.ImageIndex) and (Layout = OtherColumn.Layout) and (Margin = OtherColumn.Margin) and (MaxWidth = OtherColumn.MaxWidth) and (MinWidth = OtherColumn.MinWidth) and (Position = OtherColumn.Position) and (Spacing = OtherColumn.Spacing) and (Style = OtherColumn.Style) and (Text = OtherColumn.Text) and (Hint = OtherColumn.Hint) and (Width = OtherColumn.Width) and (Alignment = OtherColumn.Alignment) and (CaptionAlignment = OtherColumn.CaptionAlignment) and (Color = OtherColumn.Color) and (Tag = OtherColumn.Tag) and (Options = OtherColumn.Options) end else Result := False end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumn.GetRect: TRect; // Returns the rectangle this column occupies in the header (relative to (0, 0) of the non-client area). begin with TVirtualTreeColumns(GetOwner).FHeader do Result := Treeview.FHeaderRect; Inc(Result.Left, FLeft); Result.Right := Result.Left + FWidth; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.LoadFromStream(const Stream: TStream; Version: Integer); var Dummy: Integer; S: String; begin with Stream do begin ReadBuffer(Dummy, SizeOf(Dummy)); SetLength(S, Dummy); ReadBuffer(PChar(S)^, Dummy); Text := S; ReadBuffer(Dummy, SizeOf(Dummy)); SetLength(FHint, Dummy); ReadBuffer(PChar(FHint)^, Dummy); ReadBuffer(Dummy, SizeOf(Dummy)); Width := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); MinWidth := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); MaxWidth := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); Style := TVirtualTreeColumnStyle(Dummy); ReadBuffer(Dummy, SizeOf(Dummy)); ImageIndex := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); Layout := TVTHeaderColumnLayout(Dummy); ReadBuffer(Dummy, SizeOf(Dummy)); Margin := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); Spacing := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); BiDiMode := TBiDiMode(Dummy); ReadBuffer(Dummy, SizeOf(Dummy)); Options := TVTColumnOptions(Word(Dummy and $FFFF)); // Parts which have been introduced/changed with header stream version 1+. // LCL port started with header stream version 6 so no need to do the check here ReadBuffer(Dummy, SizeOf(Dummy)); Tag := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); Alignment := TAlignment(Dummy); ReadBuffer(Dummy, SizeOf(Dummy)); Color := TColor(Dummy); if coUseCaptionAlignment in FOptions then begin ReadBuffer(Dummy, SizeOf(Dummy)); CaptionAlignment := TAlignment(Dummy); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.ParentBiDiModeChanged; var Columns: TVirtualTreeColumns; begin if coParentBiDiMode in FOptions then begin Columns := GetOwner as TVirtualTreeColumns; if Assigned(Columns) and (FBidiMode <> Columns.FHeader.Treeview.BiDiMode) then begin FBiDiMode := Columns.FHeader.Treeview.BiDiMode; Changed(False); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.ParentColorChanged; var Columns: TVirtualTreeColumns; TreeViewColor: TColor; begin if coParentColor in FOptions then begin Columns := GetOwner as TVirtualTreeColumns; if Assigned(Columns) then begin TreeViewColor := Columns.FHeader.Treeview.Brush.Color; if FColor <> TreeViewColor then begin FColor := TreeViewColor; Changed(False); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.RestoreLastWidth; begin TVirtualTreeColumns(GetOwner).AnimatedResize(Index, FLastWidth); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumn.SaveToStream(const Stream: TStream); var Dummy: Integer; begin with Stream do begin Dummy := Length(FText); WriteBuffer(Dummy, SizeOf(Dummy)); WriteBuffer(PChar(FText)^, Dummy); Dummy := Length(FHint); WriteBuffer(Dummy, SizeOf(Dummy)); WriteBuffer(PChar(FHint)^, Dummy); WriteBuffer(FWidth, SizeOf(FWidth)); WriteBuffer(FMinWidth, SizeOf(FMinWidth)); WriteBuffer(FMaxWidth, SizeOf(FMaxWidth)); Dummy := Ord(FStyle); WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := FImageIndex; WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Ord(FLayout); WriteBuffer(Dummy, SizeOf(Dummy)); WriteBuffer(FMargin, SizeOf(FMargin)); WriteBuffer(FSpacing, SizeOf(FSpacing)); Dummy := Ord(FBiDiMode); WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Word(FOptions); WriteBuffer(Dummy, SizeOf(Dummy)); // parts introduced with stream version 1 WriteBuffer(FTag, SizeOf(Dummy)); Dummy := Cardinal(FAlignment); WriteBuffer(Dummy, SizeOf(Dummy)); // parts introduced with stream version 2 Dummy := Integer(FColor); WriteBuffer(Dummy, SizeOf(Dummy)); // parts introduced with stream version 6 if coUseCaptionAlignment in FOptions then begin Dummy := Cardinal(FCaptionAlignment); WriteBuffer(Dummy, SizeOf(Dummy)); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumn.UseRightToLeftReading: Boolean; begin Result := FBiDiMode <> bdLeftToRight; end; //----------------- TVirtualTreeColumns -------------------------------------------------------------------------------- constructor TVirtualTreeColumns.Create(AOwner: TVTHeader); var ColumnClass: TVirtualTreeColumnClass; begin FHeader := AOwner; // Determine column class to be used in the header. ColumnClass := AOwner.FOwner.GetColumnClass; // The owner tree always returns the default tree column class if not changed by application/descendants. inherited Create(ColumnClass); FHeaderBitmap := TBitmap.Create; FHeaderBitmap.PixelFormat := pf32Bit; FHoverIndex := NoColumn; FDownIndex := NoColumn; FClickIndex := NoColumn; FDropTarget := NoColumn; FTrackIndex := NoColumn; FDefaultWidth := 50; end; //---------------------------------------------------------------------------------------------------------------------- destructor TVirtualTreeColumns.Destroy; begin FHeaderBitmap.Free; inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetCount: Integer; begin Result := inherited Count; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetItem(Index: TColumnIndex): TVirtualTreeColumn; begin Result := TVirtualTreeColumn(inherited GetItem(Index)); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetNewIndex(P: TPoint; var OldIndex: TColumnIndex): Boolean; var NewIndex: Integer; begin Result := False; // convert to local coordinates Inc(P.Y, FHeader.FHeight); NewIndex := ColumnFromPosition(P); if NewIndex <> OldIndex then begin if OldIndex > NoColumn then FHeader.Invalidate(Items[OldIndex]); OldIndex := NewIndex; if OldIndex > NoColumn then FHeader.Invalidate(Items[OldIndex]); Result := True; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.SetDefaultWidth(Value: Integer); begin FDefaultWidth := Value; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.SetItem(Index: TColumnIndex; Value: TVirtualTreeColumn); begin inherited SetItem(Index, Value); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.AdjustAutoSize(CurrentIndex: TColumnIndex; Force: Boolean = False); // Called only if the header is in auto-size mode which means a column needs to be so large // that it fills all the horizontal space not occupied by the other columns. // CurrentIndex (if not InvalidColumn) describes which column has just been resized. var NewValue, AutoIndex, Index, RestWidth: Integer; begin if Count > 0 then begin // Determine index to be used for auto resizing. This is usually given by the owner's AutoSizeIndex, but // could be different if the column whose resize caused the invokation here is either the auto column itself // or visually to the right of the auto size column. AutoIndex := FHeader.FAutoSizeIndex; if (AutoIndex < 0) or (AutoIndex >= Count) then AutoIndex := Count - 1; if AutoIndex >= 0 then begin with FHeader.Treeview do begin if HandleAllocated then RestWidth := ClientWidth else RestWidth := Width; end; // Go through all columns and calculate the rest space remaining. for Index := 0 to Count - 1 do if (Index <> AutoIndex) and (coVisible in Items[Index].FOptions) then Dec(RestWidth, Items[Index].Width); with Items[AutoIndex] do begin NewValue := Max(MinWidth, Min(MaxWidth, RestWidth)); if Force or (FWidth <> NewValue) then begin FWidth := NewValue; UpdatePositions; FHeader.Treeview.DoColumnResize(AutoIndex); end; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.AdjustDownColumn(P: TPoint): TColumnIndex; // Determines the column from the given position and returns it. If this column is allowed to be clicked then // it is also kept for later use. begin // Convert to local coordinates. Inc(P.Y, FHeader.FHeight); Result := ColumnFromPosition(P); if (Result > NoColumn) and (Result <> FDownIndex) and (coAllowClick in Items[Result].FOptions) and (coEnabled in Items[Result].FOptions) then begin if FDownIndex > NoColumn then FHeader.Invalidate(Items[FDownIndex]); FDownIndex := Result; FHeader.Invalidate(Items[FDownIndex]); end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.AdjustHoverColumn(const P: TPoint): Boolean; // Determines the new hover column index and returns True if the index actually changed else False. begin Result := GetNewIndex(P, FHoverIndex); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.AdjustPosition(Column: TVirtualTreeColumn; Position: Cardinal); // Reorders the column position array so that the given column gets the given position. var OldPosition: Cardinal; begin OldPosition := Column.Position; if OldPosition <> Position then begin if OldPosition < Position then begin // column will be moved up so move down other entries Move(FPositionToIndex[OldPosition + 1], FPositionToIndex[OldPosition], (Position - OldPosition) * SizeOf(Cardinal)); end else begin // column will be moved down so move up other entries Move(FPositionToIndex[Position], FPositionToIndex[Position + 1], (OldPosition - Position) * SizeOf(Cardinal)); end; FPositionToIndex[Position] := Column.Index; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.CanSplitterResize(P: TPoint; Column: TColumnIndex): Boolean; begin Result := (Column > NoColumn) and ([coResizable, coVisible] * Items[Column].FOptions = [coResizable, coVisible]); DoCanSplitterResize(P, Column, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.DoCanSplitterResize(P: TPoint; Column: TColumnIndex; var Allowed: Boolean); begin if Assigned(FHeader.Treeview.FOnCanSplitterResizeColumn) then FHeader.Treeview.FOnCanSplitterResizeColumn(FHeader, P, Column, Allowed); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.DrawButtonText(DC: HDC; Caption: String; Bounds: TRect; Enabled, Hot: Boolean; DrawFormat: Cardinal; WrapCaption: Boolean); var TextSpace: Integer; Size: TSize; begin if not WrapCaption then begin // Do we need to shorten the caption due to limited space? GetTextExtentPoint32(DC, PChar(Caption), Length(Caption), Size); TextSpace := Bounds.Right - Bounds.Left; if TextSpace < Size.cx then Caption := ShortenString(DC, Caption, TextSpace); end; SetBkMode(DC, TRANSPARENT); if not Enabled then begin OffsetRect(Bounds, 1, 1); SetTextColor(DC, ColorToRGB(clBtnHighlight)); DrawText(DC, PChar(Caption), Length(Caption), Bounds, DrawFormat); OffsetRect(Bounds, -1, -1); SetTextColor(DC, ColorToRGB(clBtnShadow)); DrawText(DC, PChar(Caption), Length(Caption), Bounds, DrawFormat); end else begin if Hot then SetTextColor(DC, ColorToRGB(FHeader.Treeview.FColors.HeaderHotColor)) else SetTextColor(DC, ColorToRGB(FHeader.FFont.Color)); DrawText(DC, PChar(Caption), Length(Caption), Bounds, DrawFormat); end; end; //---------------------------------------------------------------------------------------------------------------------- // XP style header button legacy code. This procedure is only used on non-XP systems to simulate the themed // header style. // Note: the theme elements displayed here only correspond to the standard themes of Windows XP const XPMainHeaderColorUp = $DBEAEB; // Main background color of the header if drawn as being not pressed. XPMainHeaderColorDown = $D8DFDE; // Main background color of the header if drawn as being pressed. XPMainHeaderColorHover = $F3F8FA; // Main background color of the header if drawn as being under the mouse pointer. XPDarkSplitBarColor = $B2C5C7; // Dark color of the splitter bar. XPLightSplitBarColor = $FFFFFF; // Light color of the splitter bar. XPDarkGradientColor = $B8C7CB; // Darkest color in the bottom gradient. Other colors will be interpolated. XPDownOuterLineColor = $97A5A5; // Down state border color. XPDownMiddleLineColor = $B8C2C1; // Down state border color. XPDownInnerLineColor = $C9D1D0; // Down state border color. procedure TVirtualTreeColumns.DrawXPButton(DC: HDC; const ButtonR: TRect; DrawSplitter, Down, Hover: Boolean); // Helper procedure to draw an Windows XP like header button. var PaintBrush: HBRUSH; Pen, OldPen: HPEN; PenColor, FillColor: COLORREF; dRed, dGreen, dBlue: Single; Width, XPos: Integer; begin if Down then FillColor := XPMainHeaderColorDown else if Hover then FillColor := XPMainHeaderColorHover else FillColor := XPMainHeaderColorUp; PaintBrush := CreateSolidBrush(FillColor); FillRect(DC, ButtonR, PaintBrush); DeleteObject(PaintBrush); if DrawSplitter and not (Down or Hover) then begin // One solid pen for the dark line... Pen := CreatePen(PS_SOLID, 1, XPDarkSplitBarColor); OldPen := SelectObject(DC, Pen); MoveToEx(DC, ButtonR.Right - 2, ButtonR.Top + 3, nil); LineTo(DC, ButtonR.Right - 2, ButtonR.Bottom - 5); // ... and one solid pen for the light line. Pen := CreatePen(PS_SOLID, 1, XPLightSplitBarColor); DeleteObject(SelectObject(DC, Pen)); MoveToEx(DC, ButtonR.Right - 1, ButtonR.Top + 3, nil); LineTo(DC, ButtonR.Right - 1, ButtonR.Bottom - 5); SelectObject(DC, OldPen); DeleteObject(Pen); end; if Down then begin // Down state. Three lines to draw. // First one is the outer line, drawn at left, bottom and right. Pen := CreatePen(PS_SOLID, 1, XPDownOuterLineColor); OldPen := SelectObject(DC, Pen); MoveToEx(DC, ButtonR.Left, ButtonR.Top, nil); LineTo(DC, ButtonR.Left, ButtonR.Bottom - 1); LineTo(DC, ButtonR.Right - 1, ButtonR.Bottom - 1); LineTo(DC, ButtonR.Right - 1, ButtonR.Top - 1); // Second one is the middle line, which is a bit lighter. Pen := CreatePen(PS_SOLID, 1, XPDownMiddleLineColor); DeleteObject(SelectObject(DC, Pen)); MoveToEx(DC, ButtonR.Left + 1, ButtonR.Bottom - 2, nil); LineTo(DC, ButtonR.Left + 1, ButtonR.Top); LineTo(DC, ButtonR.Right - 1, ButtonR.Top); // Third line is the inner line, which is even lighter than the middle line. Pen := CreatePen(PS_SOLID, 1, XPDownInnerLineColor); DeleteObject(SelectObject(DC, Pen)); MoveToEx(DC, ButtonR.Left + 2, ButtonR.Bottom - 2, nil); LineTo(DC, ButtonR.Left + 2, ButtonR.Top + 1); LineTo(DC, ButtonR.Right - 1, ButtonR.Top + 1); // Housekeeping: SelectObject(DC, OldPen); DeleteObject(Pen); end else if Hover then begin // Hover state. There are three lines at the bottom border, but they are rendered in a way which // requires expensive construction. Width := ButtonR.Right - ButtonR.Left; if Width <= 32 then begin BitBlt(DC, ButtonR.Right - 16, ButtonR.Bottom - 3, UtilityImageSize, 3, UtilityImages.Canvas.Handle, 8 * UtilityImageSize, 0, SRCCOPY); //ImageList_DrawEx(UtilityImages.Handle, 8, DC, ButtonR.Right - 16, ButtonR.Bottom - 3, 16, 3, CLR_NONE, CLR_NONE, // ILD_NORMAL); BitBlt(DC, ButtonR.Left, ButtonR.Bottom - 3, Width div 2, 3, UtilityImages.Canvas.Handle, 6 * UtilityImageSize, 0, SRCCOPY); //ImageList_DrawEx(UtilityImages.Handle, 6, DC, ButtonR.Left, ButtonR.Bottom - 3, Width div 2, 3, CLR_NONE, // CLR_NONE, ILD_NORMAL); end else begin BitBlt(DC, ButtonR.Left, ButtonR.Bottom - 3, UtilityImageSize, 3, UtilityImages.Canvas.Handle, 6 * UtilityImageSize, 0, SRCCOPY); //ImageList_DrawEx(UtilityImages.Handle, 6, DC, ButtonR.Left, ButtonR.Bottom - 3, 16, 3, CLR_NONE, CLR_NONE, // ILD_NORMAL); // Replicate inner part as many times as need to fill up the button rectangle. XPos := ButtonR.Left + 16; repeat BitBlt(DC, XPos, ButtonR.Bottom - 3, UtilityImageSize, 3, UtilityImages.Canvas.Handle, 7 * UtilityImageSize, 0, SRCCOPY); //ImageList_DrawEx(UtilityImages.Handle, 7, DC, XPos, ButtonR.Bottom - 3, 16, 3, CLR_NONE, CLR_NONE, ILD_NORMAL); Inc(XPos, 16); until XPos + 16 >= ButtonR.Right; BitBlt(DC, ButtonR.Right - 16, ButtonR.Bottom - 3, UtilityImageSize, 3, UtilityImages.Canvas.Handle, 8 * UtilityImageSize, 0, SRCCOPY); //ImageList_DrawEx(UtilityImages.Handle, 8, DC, ButtonR.Right - 16, ButtonR.Bottom - 3, 16, 3, CLR_NONE, CLR_NONE, // ILD_NORMAL); end; end else begin // There is a three line gradient near the bottom border which transforms from the button color to a dark, // clBtnFace like color (here XPDarkGradientColor). PenColor := XPMainHeaderColorUp; dRed := ((PenColor and $FF) - (XPDarkGradientColor and $FF)) / 3; dGreen := (((PenColor shr 8) and $FF) - ((XPDarkGradientColor shr 8) and $FF)) / 3; dBlue := (((PenColor shr 16) and $FF) - ((XPDarkGradientColor shr 16) and $FF)) / 3; // First line: PenColor := PenColor - Round(dRed) - Round(dGreen) shl 8 - Round(dBlue) shl 16; Pen := CreatePen(PS_SOLID, 1, PenColor); OldPen := SelectObject(DC, Pen); MoveToEx(DC, ButtonR.Left, ButtonR.Bottom - 3, nil); LineTo(DC, ButtonR.Right, ButtonR.Bottom - 3); // Second line: PenColor := PenColor - Round(dRed) - Round(dGreen) shl 8 - Round(dBlue) shl 16; Pen := CreatePen(PS_SOLID, 1, PenColor); DeleteObject(SelectObject(DC, Pen)); MoveToEx(DC, ButtonR.Left, ButtonR.Bottom - 2, nil); LineTo(DC, ButtonR.Right, ButtonR.Bottom - 2); // Third line: Pen := CreatePen(PS_SOLID, 1, XPDarkGradientColor); DeleteObject(SelectObject(DC, Pen)); MoveToEx(DC, ButtonR.Left, ButtonR.Bottom - 1, nil); LineTo(DC, ButtonR.Right, ButtonR.Bottom - 1); // Housekeeping: DeleteObject(SelectObject(DC, OldPen)); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.FixPositions; // Fixes column positions after loading from DFM or Bidi mode change. var I: Integer; begin for I := 0 to Count - 1 do FPositionToIndex[Items[I].Position] := I; FNeedPositionsFix := False; UpdatePositions(True); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetColumnAndBounds(const P: TPoint; var ColumnLeft, ColumnRight: Integer; Relative: Boolean = True): Integer; // Returns the column where the mouse is currently in as well as the left and right bound of // this column (Left and Right are undetermined if no column is involved). var I: Integer; begin Result := InvalidColumn; if Relative and (P.X > Header.Columns.GetVisibleFixedWidth) then ColumnLeft := -FHeader.Treeview.FEffectiveOffsetX else ColumnLeft := 0; if FHeader.Treeview.UseRightToLeftAlignment then Inc(ColumnLeft, FHeader.Treeview.ComputeRTLOffset(True)); for I := 0 to Count - 1 do with Items[FPositionToIndex[I]] do if coVisible in FOptions then begin ColumnRight := ColumnLeft + FWidth; if P.X < ColumnRight then begin Result := FPositionToIndex[I]; Exit; end; ColumnLeft := ColumnRight; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetOwner: TPersistent; begin Result := FHeader; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.HandleClick(P: TPoint; Button: TMouseButton; Force, DblClick: Boolean); // Generates a click event if the mouse button has been released over the same column it was pressed first. // Alternatively, Force might be set to True to indicate that the down index does not matter (right, middle and // double click). var NewClickIndex: Integer; Shift: TShiftState; begin // Convert vertical position to local coordinates. Inc(P.Y, FHeader.FHeight); NewClickIndex := ColumnFromPosition(P); if (NewClickIndex > NoColumn) and (coAllowClick in Items[NewClickIndex].FOptions) and ((NewClickIndex = FDownIndex) or Force) then begin FClickIndex := NewClickIndex; Shift := FHeader.GetShiftState; if DblClick then Shift := Shift + [ssDouble]; if Items[NewClickIndex].FHasImage and PtInRect(Items[NewClickIndex].FImageRect, P) then begin if Items[NewClickIndex].CheckBox then begin FHeader.Treeview.UpdateColumnCheckState(Items[NewClickIndex]); FHeader.Treeview.DoHeaderCheckBoxClick(NewClickIndex, Button, Shift, P.X, P.Y); end else FHeader.Treeview.DoHeaderImageClick(NewClickIndex, Button, Shift, P.X, P.Y) end else FHeader.Treeview.DoHeaderClick(NewClickIndex, Button, Shift, P.X, P.Y); FHeader.Invalidate(Items[NewClickIndex]); end else FClickIndex := NoColumn; if (FClickIndex > NoColumn) and (FClickIndex <> NewClickIndex) then FHeader.Invalidate(Items[FClickIndex]); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.IndexChanged(OldIndex, NewIndex: Integer); // Called by a column when its index in the collection changes. If NewIndex is -1 then the column is // about to be removed, otherwise it is moved to a new index. // The method will then update the position array to reflect the change. var I: Integer; Increment: Integer; Lower, Upper: Integer; begin if NewIndex = -1 then begin // Find position in the array with the old index. Upper := High(FPositionToIndex); for I := 0 to Upper do begin if FPositionToIndex[I] = OldIndex then begin // Index found. Move all higher entries one step down and remove the last entry. if I < Upper then Move(FPositionToIndex[I + 1], FPositionToIndex[I], (Upper - I) * SizeOf(Integer)); end; // Decrease all indices, which are greater than the index to be deleted. if FPositionToIndex[I] > OldIndex then Dec(FPositionToIndex[I]); end; SetLength(FPositionToIndex, High(FPositionToIndex)); end else begin if OldIndex < NewIndex then Increment := -1 else Increment := 1; Lower := Min(OldIndex, NewIndex); Upper := Max(OldIndex, NewIndex); for I := 0 to High(FPositionToIndex) do begin if (FPositionToIndex[I] >= Lower) and (FPositionToIndex[I] < Upper) then Inc(FPositionToIndex[I], Increment) else if FPositionToIndex[I] = OldIndex then FPositionToIndex[I] := NewIndex; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.InitializePositionArray; // Ensures that the column position array contains as many entries as columns are defined. // The array is resized and initialized with default values if needed. var I, OldSize: Integer; Changed: Boolean; begin if Count <> Length(FPositionToIndex) then begin OldSize := Length(FPositionToIndex); SetLength(FPositionToIndex, Count); if Count > OldSize then begin // New items have been added, just set their position to the same as their index. for I := OldSize to Count - 1 do FPositionToIndex[I] := I; end else begin // Items have been deleted, so reindex remaining entries by decrementing values larger than the highest // possible index until no entry is higher than this limit. repeat Changed := False; for I := 0 to Count - 1 do if FPositionToIndex[I] >= Count then begin Dec(FPositionToIndex[I]); Changed := True; end; until not Changed; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.ReorderColumns(RTL: Boolean); var I: Integer; begin if RTL then begin for I := 0 to Count - 1 do FPositionToIndex[I] := Count - I - 1; end else begin for I := 0 to Count - 1 do FPositionToIndex[I] := I; end; UpdatePositions(True); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.Update(Item: TCollectionItem); begin //lcl // Skip while Destroying if csDestroying in FHeader.TreeView.ComponentState then Exit; // This is the only place which gets notified when a new column has been added or removed // and we need this event to adjust the column position array. InitializePositionArray; if csLoading in Header.Treeview.ComponentState then FNeedPositionsFix := True else UpdatePositions; // The first column which is created is by definition also the main column. if (Count > 0) and (Header.FMainColumn < 0) then FHeader.FMainColumn := 0; if not (csLoading in Header.Treeview.ComponentState) and not (hsLoading in FHeader.FStates) then begin with FHeader do begin if hoAutoResize in FOptions then AdjustAutoSize(InvalidColumn); if Assigned(Item) then Invalidate(Item as TVirtualTreeColumn) else if Treeview.HandleAllocated then begin Treeview.UpdateHorizontalScrollBar(False); Invalidate(nil); Treeview.Invalidate; end; if not (tsUpdating in Treeview.FStates) then // This is mainly to let the designer know when a change occurs at design time which // doesn't involve the object inspector (like column resizing with the mouse). // This does NOT include design time code as the communication is done via an interface. Treeview.UpdateDesigner; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.UpdatePositions(Force: Boolean = False); // Recalculates the left border of every column and updates their position property according to the // PostionToIndex array which primarily determines where each column is placed visually. var I, RunningPos: Integer; begin if not FNeedPositionsFix and (Force or (UpdateCount = 0)) then begin RunningPos := 0; for I := 0 to High(FPositionToIndex) do with Items[FPositionToIndex[I]] do begin FPosition := I; FLeft := RunningPos; if coVisible in FOptions then Inc(RunningPos, FWidth); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.Add: TVirtualTreeColumn; begin Result := TVirtualTreeColumn(inherited Add); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.AnimatedResize(Column: TColumnIndex; NewWidth: Integer); // Resizes the given column animated by scrolling the window DC. {$ifndef INCOMPLETE_WINAPI} var OldWidth: Integer; DC: HDC; I, Steps, DX: Integer; HeaderScrollRect, ScrollRect, R: TRect; NewBrush, LastBrush: HBRUSH; {$endif} begin //todo: reimplement {$ifndef INCOMPLETE_WINAPI} if not IsValidColumn(Column) then exit; // Just in case. // Make sure the width constrains are considered. if NewWidth < Items[Column].FMinWidth then NewWidth := Items[Column].FMinWidth; if NewWidth > Items[Column].FMaxWidth then NewWidth := Items[Column].FMaxWidth; OldWidth := Items[Column].Width; // Nothing to do if the width is the same. if OldWidth <> NewWidth then begin if not ( (hoDisableAnimatedResize in FHeader.Options) or (coDisableAnimatedResize in Items[Column].Options) ) then begin DC := GetWindowDC(FHeader.Treeview.Handle); with FHeader.Treeview do try Steps := 32; DX := (NewWidth - OldWidth) div Steps; // Determination of the scroll rectangle is a bit complicated since we neither want // to scroll the scrollbars nor the border of the treeview window. HeaderScrollRect := FHeaderRect; ScrollRect := HeaderScrollRect; // Exclude the header itself from scrolling. ScrollRect.Top := ScrollRect.Bottom; ScrollRect.Bottom := ScrollRect.Top + ClientHeight; ScrollRect.Right := ScrollRect.Left + ClientWidth; with Items[Column] do Inc(ScrollRect.Left, FLeft + FWidth); HeaderScrollRect.Left := ScrollRect.Left; HeaderScrollRect.Right := ScrollRect.Right; // When the new width is larger then avoid artefacts on the left hand side // by deleting a small stripe if NewWidth > OldWidth then begin R := ScrollRect; NewBrush := CreateSolidBrush(ColorToRGB(Brush.Color)); LastBrush := SelectObject(DC, NewBrush); R.Right := R.Left + DX; FillRect(DC, R, NewBrush); SelectObject(DC, LastBrush); DeleteObject(NewBrush); end else begin Inc(HeaderScrollRect.Left, DX); Inc(ScrollRect.Left, DX); end; for I := 0 to Steps - 1 do begin ScrollDC(DC, DX, 0, HeaderScrollRect, HeaderScrollRect, 0, nil); Inc(HeaderScrollRect.Left, DX); ScrollDC(DC, DX, 0, ScrollRect, ScrollRect, 0, nil); Inc(ScrollRect.Left, DX); Sleep(1); end; finally ReleaseDC(Handle, DC); end; end; Items[Column].Width := NewWidth; end; {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.Assign(Source: TPersistent); begin // Let the collection class assign the items. inherited; if Source is TVirtualTreeColumns then begin // Copying the position array is the only needed task here. FPositionToIndex := Copy(TVirtualTreeColumns(Source).FPositionToIndex, 0, MaxInt); // Make sure the left edges are correct after assignment. FNeedPositionsFix := False; UpdatePositions(True); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.Clear; begin FClearing := True; try // Since we're freeing all columns, the following have to be true when we're done. FHoverIndex := NoColumn; FDownIndex := NoColumn; FTrackIndex := NoColumn; FClickIndex := NoColumn; with Header do if not (hsLoading in FStates) then begin FAutoSizeIndex := NoColumn; FMainColumn := NoColumn; FSortColumn := NoColumn; end; inherited Clear; finally FClearing := False; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.ColumnFromPosition(const P: TPoint; Relative: Boolean = True): TColumnIndex; // Determines the current column based on the position passed in P. var I, Sum: Integer; begin Result := InvalidColumn; // The position must be within the header area, but we extend the vertical bounds to the entire treeview area. if (P.X >= 0) and (P.Y >= 0) and (P.Y <= FHeader.TreeView.Height) then with FHeader, Treeview do begin if Relative and (P.X > GetVisibleFixedWidth) then Sum := -FEffectiveOffsetX else Sum := 0; if UseRightToLeftAlignment then Inc(Sum, ComputeRTLOffset(True)); for I := 0 to Count - 1 do if coVisible in Items[FPositionToIndex[I]].FOptions then begin Inc(Sum, Items[FPositionToIndex[I]].Width); if P.X < Sum then begin Result := FPositionToIndex[I]; Break; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.ColumnFromPosition(PositionIndex: TColumnPosition): TColumnIndex; // Returns the index of the column at the given position. begin if Integer(PositionIndex) < Length(FPositionToIndex) then Result := FPositionToIndex[PositionIndex] else Result := NoColumn; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.Equals(OtherColumnsObj: TObject): Boolean; // Compares itself with the given set of columns and returns True if all published properties are the same // (including column order), otherwise False is returned. var I: Integer; OtherColumns : TVirtualTreeColumns; begin if not (OtherColumnsObj is TVirtualTreeColumns) then begin Result := False; Exit end; OtherColumns := TVirtualTreeColumns (OtherColumnsObj); // Same number of columns? Result := OtherColumns.Count = Count; if Result then begin // Same order of columns? Result := CompareMem(Pointer(FPositionToIndex), Pointer(OtherColumns.FPositionToIndex), Length(FPositionToIndex) * SizeOf(TColumnIndex)); if Result then begin for I := 0 to Count - 1 do if not Items[I].Equals(OtherColumns[I]) then begin Result := False; Break; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.GetColumnBounds(Column: TColumnIndex; out Left, Right: Integer); // Returns the left and right bound of the given column. If Column is NoColumn then the entire client width is returned. begin if Column <= NoColumn then begin Left := 0; Right := FHeader.Treeview.ClientWidth; end else begin Left := Items[Column].Left; Right := Left + Items[Column].Width; if FHeader.Treeview.UseRightToLeftAlignment then begin Inc(Left, FHeader.Treeview.ComputeRTLOffset(True)); Inc(Right, FHeader.Treeview.ComputeRTLOffset(True)); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetScrollWidth: Integer; // Returns the average width of all visible, non-fixed columns. If there is no such column the indent is returned. var I: Integer; ScrollColumnCount: Integer; begin Result := 0; ScrollColumnCount := 0; for I := 0 to FHeader.Columns.Count - 1 do begin if ([coVisible, coFixed] * FHeader.Columns[I].Options = [coVisible]) then begin Inc(Result, FHeader.Columns[I].Width); Inc(ScrollColumnCount); end; end; if ScrollColumnCount > 0 then // use average width Result := Round(Result / ScrollColumnCount) else // use indent Result := Integer(FHeader.Treeview.FIndent); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetFirstVisibleColumn(ConsiderAllowFocus: Boolean = False): TColumnIndex; // Returns the index of the first visible column or "InvalidColumn" if either no columns are defined or // all columns are hidden. // If ConsiderAllowFocus is True then the column has not only to be visible but also focus has to be allowed. var I: Integer; begin Result := InvalidColumn; for I := 0 to Count - 1 do if (coVisible in Items[FPositionToIndex[I]].FOptions) and ( (not ConsiderAllowFocus) or (coAllowFocus in Items[FPositionToIndex[I]].FOptions) ) then begin Result := FPositionToIndex[I]; Break; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetLastVisibleColumn(ConsiderAllowFocus: Boolean = False): TColumnIndex; // Returns the index of the last visible column or "InvalidColumn" if either no columns are defined or // all columns are hidden. // If ConsiderAllowFocus is True then the column has not only to be visible but also focus has to be allowed. var I: Integer; begin Result := InvalidColumn; for I := Count - 1 downto 0 do if (coVisible in Items[FPositionToIndex[I]].FOptions) and ( (not ConsiderAllowFocus) or (coAllowFocus in Items[FPositionToIndex[I]].FOptions) ) then begin Result := FPositionToIndex[I]; Break; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetNextColumn(Column: TColumnIndex): TColumnIndex; // Returns the next column in display order. Column is the index of an item in the collection (a column). var Position: Integer; begin if Column < 0 then Result := InvalidColumn else begin Position := Items[Column].Position; if Position < Count - 1 then Result := FPositionToIndex[Position + 1] else Result := InvalidColumn; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetNextVisibleColumn(Column: TColumnIndex; ConsiderAllowFocus: Boolean = False): TColumnIndex; // Returns the next visible column in display order, Column is an index into the columns list. // If ConsiderAllowFocus is True then the column has not only to be visible but also focus has to be allowed. begin Result := Column; repeat Result := GetNextColumn(Result); until (Result = InvalidColumn) or ( (coVisible in Items[Result].FOptions) and ( (not ConsiderAllowFocus) or (coAllowFocus in Items[Result].FOptions) ) ); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetPreviousColumn(Column: TColumnIndex): TColumnIndex; // Returns the previous column in display order, Column is an index into the columns list. var Position: Integer; begin if Column < 0 then Result := InvalidColumn else begin Position := Items[Column].Position; if Position > 0 then Result := FPositionToIndex[Position - 1] else Result := InvalidColumn; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetPreviousVisibleColumn(Column: TColumnIndex; ConsiderAllowFocus: Boolean = False): TColumnIndex; // Returns the previous visible column in display order, Column is an index into the columns list. // If ConsiderAllowFocus is True then the column has not only to be visible but also focus has to be allowed. begin Result := Column; repeat Result := GetPreviousColumn(Result); until (Result = InvalidColumn) or ( (coVisible in Items[Result].FOptions) and ( (not ConsiderAllowFocus) or (coAllowFocus in Items[Result].FOptions) ) ); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetVisibleColumns: TColumnsArray; // Returns a list of all currently visible columns in actual order. var I, Counter: Integer; begin SetLength(Result, Count); Counter := 0; for I := 0 to Count - 1 do if coVisible in Items[FPositionToIndex[I]].FOptions then begin Result[Counter] := Items[FPositionToIndex[I]]; Inc(Counter); end; // Set result length to actual visible count. SetLength(Result, Counter); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.GetVisibleFixedWidth: Integer; // Determines the horizontal space all visible and fixed columns occupy. var I: Integer; begin Result := 0; for I := 0 to Count - 1 do begin if Items[I].Options * [coVisible, coFixed] = [coVisible, coFixed] then Inc(Result, Items[I].Width); end; end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.IsValidColumn(Column: TColumnIndex): Boolean; // Determines whether the given column is valid or not, that is, whether it is one of the current columns. begin Result := (Column > NoColumn) and (Column < Count); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.LoadFromStream(const Stream: TStream; Version: Integer); var I, ItemCount: Integer; begin Clear; Stream.ReadBuffer(ItemCount, SizeOf(ItemCount)); // number of columns if ItemCount > 0 then begin BeginUpdate; try for I := 0 to ItemCount - 1 do Add.LoadFromStream(Stream, Version); SetLength(FPositionToIndex, ItemCount); Stream.ReadBuffer(FPositionToIndex[0], ItemCount * SizeOf(Cardinal)); UpdatePositions(True); finally EndUpdate; end; end; // Data introduced with header stream version 5 // LCL port started with header stream version 6 so no need to do the check here Stream.ReadBuffer(FDefaultWidth, SizeOf(FDefaultWidth)); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.PaintHeader(DC: HDC; const R: TRect; HOffset: Integer); // Main paint method to draw the header. const SortGlyphs: array[TSortDirection, Boolean] of Integer = ( // ascending/descending, normal/XP style (3, 5) {ascending}, (2, 4) {descending} ); var I, Y, SortIndex: Integer; Run: TRect; RightBorderFlag, NormalButtonStyle, NormalButtonFlags, PressedButtonStyle, PressedButtonFlags, RaisedButtonStyle, RaisedButtonFlags: Cardinal; DrawFormat: Cardinal; Images: TCustomImageList; ButtonRgn: HRGN; OwnerDraw, WrapCaption, AdvancedOwnerDraw: Boolean; {$ifdef ThemeSupport} Details: TThemedElementDetails; {$endif ThemeSupport} PaintInfo: THeaderPaintInfo; RequestedElements, ActualElements: THeaderPaintElements; Temp: TRect; ColCaptionText: String; ColImages: TCustomImageList; ColImageIndex: Integer; begin Run := FHeader.Treeview.FHeaderRect; FHeaderBitmap.Width := Max(Run.Right, R.Right - R.Left); FHeaderBitmap.Height := Run.Bottom; OwnerDraw := (hoOwnerDraw in FHeader.FOptions) and Assigned(FHeader.Treeview.FOnHeaderDraw) and not (csDesigning in FHeader.Treeview.ComponentState); AdvancedOwnerDraw := (hoOwnerDraw in FHeader.FOptions) and Assigned(FHeader.Treeview.FOnAdvancedHeaderDraw) and Assigned(FHeader.Treeview.FOnHeaderDrawQueryElements) and not (csDesigning in FHeader.Treeview.ComponentState); // If both draw posibillities are specified then prefer the advanced way. if AdvancedOwnerDraw then OwnerDraw := False; FillChar(PaintInfo, SizeOf(PaintInfo),#0); PaintInfo.TargetCanvas := FHeaderBitmap.Canvas; with PaintInfo, TargetCanvas do begin Font := FHeader.FFont; RaisedButtonStyle := 0; RaisedButtonFlags := 0; case FHeader.Style of hsThickButtons: begin NormalButtonStyle := BDR_RAISEDINNER or BDR_RAISEDOUTER; NormalButtonFlags := BF_LEFT or BF_TOP or BF_BOTTOM or BF_MIDDLE or BF_SOFT or BF_ADJUST; PressedButtonStyle := BDR_RAISEDINNER or BDR_RAISEDOUTER; PressedButtonFlags := NormalButtonFlags or BF_RIGHT or BF_FLAT or BF_ADJUST; end; hsFlatButtons: begin NormalButtonStyle := BDR_RAISEDINNER; NormalButtonFlags := BF_LEFT or BF_TOP or BF_BOTTOM or BF_MIDDLE or BF_ADJUST; PressedButtonStyle := BDR_SUNKENOUTER; PressedButtonFlags := BF_RECT or BF_MIDDLE or BF_ADJUST; end; else // hsPlates or hsXPStyle, values are not used in the latter case begin NormalButtonStyle := BDR_RAISEDINNER; NormalButtonFlags := BF_RECT or BF_MIDDLE or BF_SOFT or BF_ADJUST; PressedButtonStyle := BDR_SUNKENOUTER; PressedButtonFlags := BF_RECT or BF_MIDDLE or BF_ADJUST; RaisedButtonStyle := BDR_RAISEDINNER; RaisedButtonFlags := BF_LEFT or BF_TOP or BF_BOTTOM or BF_MIDDLE or BF_ADJUST; end; end; // Use shortcut for the images. Images := FHeader.FImages; // Erase background of the header. // See if the application wants to do that on its own. RequestedElements := []; if AdvancedOwnerDraw then begin PaintInfo.PaintRectangle := R; PaintInfo.Column := nil; FHeader.Treeview.DoHeaderDrawQueryElements(PaintInfo, RequestedElements); end; if hpeBackground in RequestedElements then begin FHeader.Treeview.DoAdvancedHeaderDraw(PaintInfo, [hpeBackground]); end else begin {$ifdef ThemeSupport} if tsUseThemes in FHeader.Treeview.FStates then begin Details := ThemeServices.GetElementDetails(thHeaderItemRightNormal); ThemeServices.DrawElement(Handle, Details, R, @R); end else {$endif ThemeSupport} if FHeader.Style = hsXPStyle then DrawXPButton(Handle, Run, False, False, False) else begin Brush.Color := FHeader.FBackground; FillRect(R); end; end; Run.Top := R.Top; Run.Right := R.Left; Run.Bottom := R.Bottom; // Run.Left is set in the loop // Consider right-to-left directionality. with FHeader.Treeview do if UseRightToLeftAlignment then Inc(Run.Right, ComputeRTLOffset); Temp := Run; //todo_lcl_check ShowRightBorder := (FHeader.Style = hsThickButtons) or not (hoAutoResize in FHeader.FOptions);// or //(FHeader.Treeview.BevelKind = bkNone); // Now go for each button. for I := 0 to Count - 1 do begin with Items[FPositionToIndex[I]] do if coVisible in FOptions then begin if not (coFixed in FOptions) then begin Inc(Run.Right, HOffset); HOffset := 0; end; Temp := Rect(Temp.Right, Run.Top, Max(Temp.Right, Run.Right + Width), Run.Bottom); Run.Left := Run.Right; Inc(Run.Right, Width); // Skip columns which are not visible at all. if (Run.Right > R.Left) and (Run.Right > Temp.Left) then begin // Stop painting if the rectangle is filled. if Run.Left > R.Right then Break; // Create a clip region to avoid overpainting any other area which does not belong to this column. if Temp.Right > R.Right then Temp.Right := R.Right; if Temp.Left < R.Left then Temp.Left := R.Left; ButtonRgn := CreateRectRgnIndirect(Temp); SelectClipRgn(Handle, ButtonRgn); DeleteObject(ButtonRgn); //lclheader //Under Delphi/VCL, unlike LCL, the hover index is not changed while dragging. //Here we check if dragging and not draw as hover IsHoverIndex := (Integer(FPositionToIndex[I]) = FHoverIndex) and (hoHotTrack in FHeader.FOptions) and (coEnabled in FOptions) and not (hsDragging in FHeader.States); IsDownIndex := Integer(FPositionToIndex[I]) = FDownIndex; if (coShowDropMark in FOptions) and (Integer(FPositionToIndex[I]) = FDropTarget) and (Integer(FPositionToIndex[I]) <> FDragIndex) then begin if FDropBefore then DropMark := dmmLeft else DropMark := dmmRight; end else DropMark := dmmNone; IsEnabled := (coEnabled in FOptions) and (FHeader.Treeview.Enabled); ShowHeaderGlyph := (hoShowImages in FHeader.FOptions) and Assigned(Images) and (FImageIndex > -1); ShowSortGlyph := (Integer(FPositionToIndex[I]) = FHeader.FSortColumn) and (hoShowSortGlyphs in FHeader.FOptions); WrapCaption := coWrapCaption in FOptions; PaintRectangle := Run; // This path for text columns or advanced owner draw. if (Style = vsText) or not OwnerDraw or AdvancedOwnerDraw then begin // See if the application wants to draw part of the header itself. RequestedElements := []; if AdvancedOwnerDraw then begin PaintInfo.Column := Items[FPositionToIndex[I]]; FHeader.Treeview.DoHeaderDrawQueryElements(PaintInfo, RequestedElements); end; if ShowRightBorder or (I < Count - 1) then RightBorderFlag := BF_RIGHT else RightBorderFlag := 0; if hpeBackground in RequestedElements then FHeader.Treeview.DoAdvancedHeaderDraw(PaintInfo, [hpeBackground]) else begin // Draw button first before setting the clip region. {$ifdef ThemeSupport} if tsUseThemes in FHeader.Treeview.FStates then begin if IsDownIndex then Details := ThemeServices.GetElementDetails(thHeaderItemPressed) else if IsHoverIndex then Details := ThemeServices.GetElementDetails(thHeaderItemHot) else Details := ThemeServices.GetElementDetails(thHeaderItemNormal); ThemeServices.DrawElement(Handle, Details, PaintRectangle, @PaintRectangle); end else {$endif ThemeSupport} begin if FHeader.Style = hsXPStyle then DrawXPButton(Handle, PaintRectangle, RightBorderFlag <> 0, IsDownIndex, IsHoverIndex) else if IsDownIndex then DrawEdge(Handle, PaintRectangle, PressedButtonStyle, PressedButtonFlags) else // Plates have the special case of raising on mouse over. if (FHeader.Style = hsPlates) and IsHoverIndex and (coAllowClick in FOptions) and (coEnabled in FOptions) then DrawEdge(Handle, PaintRectangle, RaisedButtonStyle, RaisedButtonFlags or RightBorderFlag) else DrawEdge(Handle, PaintRectangle, NormalButtonStyle, NormalButtonFlags or RightBorderFlag); end; end; end; PaintRectangle := Run; if (Style = vsText) or not OwnerDraw or AdvancedOwnerDraw then begin // calculate text and glyph position InflateRect(PaintRectangle, -2, -2); DrawFormat := DT_TOP or DT_NOPREFIX; case CaptionAlignment of taLeftJustify : DrawFormat := DrawFormat or DT_LEFT; taRightJustify : DrawFormat := DrawFormat or DT_RIGHT; taCenter : DrawFormat := DrawFormat or DT_CENTER; end; if UseRightToLeftReading then DrawFormat := DrawFormat + DT_RTLREADING; ComputeHeaderLayout(Handle, PaintRectangle, ShowHeaderGlyph, ShowSortGlyph, GlyphPos, SortGlyphPos, TextRectangle, DrawFormat); // Move glyph and text one pixel to the right and down to simulate a pressed button. if IsDownIndex then begin OffsetRect(TextRectangle, 1, 1); Inc(GlyphPos.X); Inc(GlyphPos.Y); Inc(SortGlyphPos.X); Inc(SortGlyphPos.Y); end; // Advanced owner draw allows to paint elements, which would normally not be painted (because of space // limitations, empty captions etc.). ActualElements := RequestedElements * [hpeHeaderGlyph, hpeSortGlyph, hpeDropMark, hpeText]; // main glyph FHasImage := False; if not (hpeHeaderGlyph in ActualElements) and ShowHeaderGlyph and (not ShowSortGlyph or (FBidiMode <> bdLeftToRight) or (GlyphPos.X + Images.Width <= SortGlyphPos.X) ) then begin if not FCheckBox then begin ColImages := Images; ColImageIndex := FImageIndex; ColImages.Draw(FHeaderBitmap.Canvas, GlyphPos.X, GlyphPos.Y, ColImageIndex, IsEnabled ); end else begin with Header.Treeview do begin CheckImageListNeeded; ColImageIndex := GetCheckImage(nil, FCheckType, FCheckState, IsEnabled); {$ifdef USE_DELPHICOMPAT} with FCheckImages do DirectMaskBlt(FHeaderBitmap.Canvas.Handle, GlyphPos.X, GlyphPos.Y, Height, Height, Canvas.Handle, ColImageIndex * Height, 0, MaskHandle); {$else} with FCheckImages do StretchMaskBlt(FHeaderBitmap.Canvas.Handle, GlyphPos.X, GlyphPos.Y, Height, Height, Canvas.Handle, ColImageIndex * Height, 0, Height, Height, MaskHandle, ColImageIndex * Height, 0, SRCCOPY); {$endif} end; end; FHasImage := True; with FImageRect do begin Left := GlyphPos.X; Top := GlyphPos.Y; Right := Left + ColImages.Width; Bottom := Top + ColImages.Height; end; end; // caption if WrapCaption then ColCaptionText := FCaptionText else ColCaptionText := Text; if not (hpeText in ActualElements) and (Length(Text) > 0) then DrawButtonText(Handle, ColCaptionText, TextRectangle, IsEnabled, IsHoverIndex and (hoHotTrack in FHeader.FOptions) and not (tsUseThemes in FHeader.Treeview.FStates), DrawFormat, WrapCaption ); // sort glyph if not (hpeSortGlyph in ActualElements) and ShowSortGlyph then begin SortIndex := SortGlyphs[FHeader.FSortDirection, tsUseThemes in FHeader.Treeview.FStates]; {$ifdef USE_DELPHICOMPAT} DirectMaskBlt(FHeaderBitmap.Canvas.Handle, SortGlyphPos.X, SortGlyphPos.Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle, SortIndex * UtilityImageSize, 0, UtilityImages.MaskHandle); {$else} StretchMaskBlt(FHeaderBitmap.Canvas.Handle, SortGlyphPos.X, SortGlyphPos.Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle, SortIndex * UtilityImageSize, 0, UtilityImageSize, UtilityImageSize, UtilityImages.MaskHandle,SortIndex * UtilityImageSize, 0, SRCCOPY); {$endif} end; // Show an indication if this column is the current drop target in a header drag operation. if not (hpeDropMark in ActualElements) and (DropMark <> dmmNone) then begin Y := (PaintRectangle.Top + PaintRectangle.Bottom - UtilityImages.Height) div 2; if DropMark = dmmLeft then {$ifdef USE_DELPHICOMPAT} DirectMaskBlt(FHeaderBitmap.Canvas.Handle, PaintRectangle.Left, Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle, 0, 0, UtilityImages.MaskHandle) {$else} StretchMaskBlt(FHeaderBitmap.Canvas.Handle, PaintRectangle.Left, Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle, 0, 0, UtilityImageSize, UtilityImageSize, UtilityImages.MaskHandle, 0, 0, SRCCOPY) {$endif} else {$ifdef USE_DELPHICOMPAT} DirectMaskBlt(FHeaderBitmap.Canvas.Handle, PaintRectangle.Right - 16, Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle, UtilityImageSize, 0, UtilityImages.MaskHandle); {$else} StretchMaskBlt(FHeaderBitmap.Canvas.Handle, PaintRectangle.Right - 16, Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle, UtilityImageSize, 0, UtilityImageSize, UtilityImageSize, UtilityImages.MaskHandle, UtilityImageSize, 0, SRCCOPY); {$endif} end; if ActualElements <> [] then begin SaveHandleState; FHeader.Treeview.DoAdvancedHeaderDraw(PaintInfo, ActualElements); RestoreHandleState; end; end else // Let application draw the header. FHeader.Treeview.DoHeaderDraw(FHeaderBitmap.Canvas, Items[FPositionToIndex[I]], PaintRectangle, IsHoverIndex, IsDownIndex, DropMark); SelectClipRgn(Handle, 0); end; end; end; // Blit the result to target. with R do BitBlt(DC, Left, Top, Right - Left, Bottom - Top, Handle, Left, Top, SRCCOPY); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.SaveToStream(const Stream: TStream); var I: Integer; begin I := Count; Stream.WriteBuffer(I, SizeOf(I)); if I > 0 then begin for I := 0 to Count - 1 do TVirtualTreeColumn(Items[I]).SaveToStream(Stream); Stream.WriteBuffer(FPositionToIndex[0], Count * SizeOf(Cardinal)); end; // Data introduced with header stream version 5. Stream.WriteBuffer(DefaultWidth, SizeOf(DefaultWidth)); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualTreeColumns.TotalWidth: Integer; var LastColumn: TColumnIndex; begin Result := 0; if (Count > 0) and (Length(FPositionToIndex) > 0) then begin LastColumn := FPositionToIndex[Count - 1]; if not (coVisible in Items[LastColumn].FOptions) then LastColumn := GetPreviousVisibleColumn(LastColumn); if LastColumn > NoColumn then with Items[LastColumn] do Result := FLeft + FWidth end; end; //----------------- TVTFixedAreaConstraints ---------------------------------------------------------------------------- constructor TVTFixedAreaConstraints.Create(AOwner: TVTHeader); begin inherited Create; FHeader := AOwner; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTFixedAreaConstraints.SetConstraints(Index: Integer; Value: TVTConstraintPercent); begin case Index of 0: if Value <> FMaxHeightPercent then begin FMaxHeightPercent := Value; if (Value > 0) and (Value < FMinHeightPercent) then FMinHeightPercent := Value; Change; end; 1: if Value <> FMaxWidthPercent then begin FMaxWidthPercent := Value; if (Value > 0) and (Value < FMinWidthPercent) then FMinWidthPercent := Value; Change; end; 2: if Value <> FMinHeightPercent then begin FMinHeightPercent := Value; if (FMaxHeightPercent > 0) and (Value > FMaxHeightPercent) then FMaxHeightPercent := Value; Change; end; 3: if Value <> FMinWidthPercent then begin FMinWidthPercent := Value; if (FMaxWidthPercent > 0) and (Value > FMaxWidthPercent) then FMaxWidthPercent := Value; Change; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTFixedAreaConstraints.Change; begin if Assigned(FOnChange) then FOnChange(Self); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTFixedAreaConstraints.Assign(Source: TPersistent); begin if Source is TVTFixedAreaConstraints then begin FMaxHeightPercent := TVTFixedAreaConstraints(Source).FMaxHeightPercent; FMaxWidthPercent := TVTFixedAreaConstraints(Source).FMaxWidthPercent; FMinHeightPercent := TVTFixedAreaConstraints(Source).FMinHeightPercent; FMinWidthPercent := TVTFixedAreaConstraints(Source).FMinWidthPercent; Change; end else inherited; end; //----------------- TVTHeader ----------------------------------------------------------------------------------------- constructor TVTHeader.Create(AOwner: TBaseVirtualTree); begin inherited Create; FOwner := AOwner; FColumns := GetColumnsClass.Create(Self); FHeight := 17; FDefaultHeight := 17; FMinHeight := 10; FMaxHeight := 10000; FFont := TFont.Create; FFont.OnChange := FontChanged; FParentFont := False; FBackground := clBtnFace; FOptions := [hoColumnResize, hoDrag, hoShowSortGlyphs]; FImageChangeLink := TChangeLink.Create; FImageChangeLink.OnChange := ImageListChange; FSortColumn := NoColumn; FSortDirection := sdAscending; FMainColumn := NoColumn; FDragImage := TVTDragImage.Create(AOwner); with FDragImage do begin Fade := False; PostBlendBias := 0; PreBlendBias := -50; Transparency := 140; end; FFixedAreaConstraints := TVTFixedAreaConstraints.Create(Self); FFixedAreaConstraints.OnChange := FixedAreaConstraintsChanged; end; //---------------------------------------------------------------------------------------------------------------------- destructor TVTHeader.Destroy; begin FDragImage.Free; FFixedAreaConstraints.Free; FImageChangeLink.Free; FFont.Free; FColumns.Clear; // TCollection's Clear method is not virtual, so we have to call our own Clear method manually. FColumns.Free; inherited; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.FontChanged(Sender: TObject); begin Invalidate(nil); end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.GetMainColumn: TColumnIndex; begin if FColumns.Count > 0 then Result := FMainColumn else Result := NoColumn; end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.GetUseColumns: Boolean; begin Result := FColumns.Count > 0; end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.IsFontStored: Boolean; begin Result := not ParentFont; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetAutoSizeIndex(Value: TColumnIndex); begin if FAutoSizeIndex <> Value then begin FAutoSizeIndex := Value; if hoAutoResize in FOptions then Columns.AdjustAutoSize(InvalidColumn); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetBackground(Value: TColor); begin if FBackground <> Value then begin FBackground := Value; Invalidate(nil); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetColumns(Value: TVirtualTreeColumns); begin FColumns.Assign(Value); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetDefaultHeight(Value: Integer); begin if Value < FMinHeight then Value := FMinHeight; if Value > FMaxHeight then Value := FMaxHeight; if FHeight = FDefaultHeight then SetHeight(Value); FDefaultHeight := Value; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetFont(const Value: TFont); begin FFont.Assign(Value); FParentFont := False; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetHeight(Value: Integer); var RelativeMaxHeight, RelativeMinHeight, EffectiveMaxHeight, EffectiveMinHeight: Integer; begin if not TreeView.HandleAllocated then begin FHeight := Value; Include(FStates, hsNeedScaling); end else begin with FFixedAreaConstraints do begin RelativeMaxHeight := ((Treeview.ClientHeight + FHeight) * FMaxHeightPercent) div 100; RelativeMinHeight := ((Treeview.ClientHeight + FHeight) * FMinHeightPercent) div 100; EffectiveMinHeight := IfThen(FMaxHeightPercent > 0, Min(RelativeMaxHeight, FMinHeight), FMinHeight); EffectiveMaxHeight := IfThen(FMinHeightPercent > 0, Max(RelativeMinHeight, FMaxHeight), FMaxHeight); Value := Min(Max(Value, EffectiveMinHeight), EffectiveMaxHeight); if FMinHeightPercent > 0 then Value := Max(RelativeMinHeight, Value); if FMaxHeightPercent > 0 then Value := Min(RelativeMaxHeight, Value); end; if FHeight <> Value then begin FHeight := Value; if not (csLoading in Treeview.ComponentState) and not (hsScaling in FStates) then RecalculateHeader; Treeview.Invalidate; UpdateWindow(Treeview.Handle); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetImages(const Value: TCustomImageList); begin if FImages <> Value then begin if Assigned(FImages) then begin FImages.UnRegisterChanges(FImageChangeLink); FImages.RemoveFreeNotification(FOwner); end; FImages := Value; if Assigned(FImages) then begin FImages.RegisterChanges(FImageChangeLink); FImages.FreeNotification(FOwner); end; if not (csLoading in Treeview.ComponentState) then Invalidate(nil); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetMainColumn(Value: TColumnIndex); begin if csLoading in Treeview.ComponentState then FMainColumn := Value else begin if Value < 0 then Value := 0; if Value > FColumns.Count - 1 then Value := FColumns.Count - 1; if Value <> FMainColumn then begin FMainColumn := Value; if Treeview.HandleAllocated then begin Treeview.MainColumnChanged; if not (toExtendedFocus in Treeview.FOptions.FSelectionOptions) then Treeview.FocusedColumn := Value; Treeview.Invalidate; end else begin if not (toExtendedFocus in Treeview.FOptions.FSelectionOptions) then Treeview.FFocusedColumn := Value; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetMaxHeight(Value: Integer); begin if Value < FMinHeight then Value := FMinHeight; if not IsWinNT and (Value > 10000) then Value := 10000; FMaxHeight := Value; SetHeight(FHeight); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetMinHeight(Value: Integer); begin if Value < 0 then Value := 0; if Value > FMaxHeight then Value := FMaxHeight; FMinHeight := Value; SetHeight(FHeight); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetOptions(Value: TVTHeaderOptions); var ToBeSet, ToBeCleared: TVTHeaderOptions; begin ToBeSet := Value - FOptions; ToBeCleared := FOptions - Value; FOptions := Value; if (hoAutoResize in (ToBeSet + ToBeCleared)) and (FColumns.Count > 0) then begin FColumns.AdjustAutoSize(InvalidColumn); if Treeview.HandleAllocated then begin Treeview.UpdateHorizontalScrollBar(False); if hoAutoResize in ToBeSet then Treeview.Invalidate; end; end; if not (csLoading in Treeview.ComponentState) and Treeview.HandleAllocated then begin if hoVisible in (ToBeSet + ToBeCleared) then RecalculateHeader; Invalidate(nil); Treeview.Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetParentFont(Value: Boolean); begin if FParentFont <> Value then begin FParentFont := Value; if FParentFont then FFont.Assign(FOwner.Font); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetSortColumn(Value: TColumnIndex); begin if csLoading in Treeview.ComponentState then FSortColumn := Value else DoSetSortColumn(Value); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetSortDirection(const Value: TSortDirection); begin if Value <> FSortDirection then begin FSortDirection := Value; Invalidate(nil); if (toAutoSort in Treeview.FOptions.FAutoOptions) and (Treeview.FUpdateCount = 0) then Treeview.SortTree(FSortColumn, FSortDirection, True); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SetStyle(Value: TVTHeaderStyle); begin if FStyle <> Value then begin FStyle := Value; if not (csLoading in Treeview.ComponentState) then Invalidate(nil); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.ChangeScale(M, D: Integer); begin FFont.Size := MulDiv(FFont.Size, M, D); end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.DetermineSplitterIndex(const P: TPoint): Boolean; // Tries to find the index of that column whose right border corresponds to P. // Result is True if column border was hit (with -3..+5 pixels tolerance). // For continuous resizing the current track index and the column's left/right border are set. // Note: The hit test is checking from right to left (or left to right in RTL mode) to make enlarging of zero-sized // columns possible. var I, VisibleFixedWidth: Integer; SplitPoint: Integer; //--------------- local function -------------------------------------------- function IsNearBy(IsFixedCol: Boolean; LeftTolerance, RightTolerance: Integer): Boolean; begin if IsFixedCol then Result := (P.X < SplitPoint + Treeview.FEffectiveOffsetX + RightTolerance) and (P.X > SplitPoint + Treeview.FEffectiveOffsetX - LeftTolerance) else Result := (P.X > VisibleFixedWidth) and (P.X < SplitPoint + RightTolerance) and (P.X > SplitPoint - LeftTolerance); end; //--------------- end local function ---------------------------------------- begin Result := False; FColumns.FTrackIndex := NoColumn; VisibleFixedWidth := FColumns.GetVisibleFixedWidth; if FColumns.Count > 0 then begin if Treeview.UseRightToLeftAlignment then begin SplitPoint := -Treeview.FEffectiveOffsetX; if Integer(Treeview.FRangeX) < Treeview.ClientWidth then Inc(SplitPoint, Treeview.ClientWidth - Integer(Treeview.FRangeX)); for I := 0 to FColumns.Count - 1 do with FColumns, Items[FPositionToIndex[I]] do if coVisible in FOptions then begin if IsNearBy(coFixed in FOptions, 5, 3) then begin if CanSplitterResize(P, FPositionToIndex[I]) then begin Result := True; FTrackIndex := FPositionToIndex[I]; // Keep the right border of this column. This and the current mouse position // directly determine the current column width. FTrackPoint.X := SplitPoint + IfThen(coFixed in FOptions, Treeview.FEffectiveOffsetX) + FWidth; FTrackPoint.Y := P.Y; Break; end; end; Inc(SplitPoint, FWidth); end; end else begin SplitPoint := -Treeview.FEffectiveOffsetX + Integer(Treeview.FRangeX); for I := FColumns.Count - 1 downto 0 do with FColumns, Items[FPositionToIndex[I]] do if coVisible in FOptions then begin if IsNearBy(coFixed in FOptions, 3, 5) then begin if CanSplitterResize(P, FPositionToIndex[I]) then begin Result := True; FTrackIndex := FPositionToIndex[I]; // Keep the left border of this column. This and the current mouse position // directly determine the current column width. FTrackPoint.X := SplitPoint + IfThen(coFixed in FOptions, Treeview.FEffectiveOffsetX) - FWidth; FTrackPoint.Y := P.Y; Break; end; end; Dec(SplitPoint, FWidth); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.DoAfterAutoFitColumn(Column: TColumnIndex); begin if Assigned(TreeView.FOnAfterAutoFitColumn) then TreeView.FOnAfterAutoFitColumn(Self, Column); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.DoAfterColumnWidthTracking(Column: TColumnIndex); // Tell the application that a column width tracking operation has been finished. begin if Assigned(TreeView.FOnAfterColumnWidthTracking) then TreeView.FOnAfterColumnWidthTracking(Self, Column); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.DoAfterHeightTracking; // Tell the application that a height tracking operation has been finished. begin if Assigned(TreeView.FOnAfterHeaderHeightTracking) then TreeView.FOnAfterHeaderHeightTracking(Self); end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.DoBeforeAutoFitColumn(Column: TColumnIndex; SmartAutoFitType: TSmartAutoFitType): Boolean; // Query the application if we may autofit a column. begin Result := True; if Assigned(TreeView.FOnBeforeAutoFitColumn) then TreeView.FOnBeforeAutoFitColumn(Self, Column, SmartAutoFitType, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.DoBeforeColumnWidthTracking(Column: TColumnIndex; Shift: TShiftState); // Tell the a application that a column width tracking operation may begin. begin if Assigned(TreeView.FOnBeforeColumnWidthTracking) then TreeView.FOnBeforeColumnWidthTracking(Self, Column, Shift); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.DoBeforeHeightTracking(Shift: TShiftState); // Tell the application that a height tracking operation may begin. begin if Assigned(TreeView.FOnBeforeHeaderHeightTracking) then TreeView.FOnBeforeHeaderHeightTracking(Self, Shift); end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.DoColumnWidthDblClickResize(Column: TColumnIndex; P: TPoint; Shift: TShiftState): Boolean; // Queries the application whether a double click on the column splitter should resize the column. begin Result := True; if Assigned(TreeView.FOnColumnWidthDblClickResize) then TreeView.FOnColumnWidthDblClickResize(Self, Column, Shift, P, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.DoColumnWidthTracking(Column: TColumnIndex; Shift: TShiftState; var TrackPoint: TPoint; P: TPoint): Boolean; begin Result := True; if Assigned(TreeView.FOnColumnWidthTracking) then TreeView.FOnColumnWidthTracking(Self, Column, Shift, TrackPoint, P, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.DoGetPopupMenu(Column: TColumnIndex; Position: TPoint): TPopupMenu; // Queries the application whether there is a column specific header popup menu. var AskParent: Boolean; begin Result := nil; if Assigned(TreeView.FOnGetPopupMenu) then TreeView.FOnGetPopupMenu(TreeView, nil, Column, Position, AskParent, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.DoHeightTracking(var P: TPoint; Shift: TShiftState): Boolean; begin Result := True; if Assigned(TreeView.FOnHeaderHeightTracking) then TreeView.FOnHeaderHeightTracking(Self, P, Shift, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.DoHeightDblClickResize(var P: TPoint; Shift: TShiftState): Boolean; begin Result := True; if Assigned(TreeView.FOnHeaderHeightDblClickResize) then TreeView.FOnHeaderHeightDblClickResize(Self, P, Shift, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.DoSetSortColumn(Value: TColumnIndex); begin if Value < NoColumn then Value := NoColumn; if Value > Columns.Count - 1 then Value := Columns.Count - 1; if FSortColumn <> Value then begin if FSortColumn > NoColumn then Invalidate(Columns[FSortColumn]); FSortColumn := Value; if FSortColumn > NoColumn then Invalidate(Columns[FSortColumn]); if (toAutoSort in Treeview.FOptions.FAutoOptions) and (Treeview.FUpdateCount = 0) then Treeview.SortTree(FSortColumn, FSortDirection, True); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.DragTo(const P: TPoint); // Moves the drag image to a new position, which is determined from the passed point P and the previous // mouse position. var I, NewTarget: Integer; // optimized drag image move support ClientP: TPoint; Left, Right: Integer; NeedRepaint: Boolean; // True if the screen needs an update (changed drop target or drop side) begin // Determine new drop target and which side of it is prefered. ClientP := Treeview.ScreenToClient(P); // Make coordinates relative to (0, 0) of the non-client area. Inc(ClientP.Y, FHeight); NewTarget := FColumns.ColumnFromPosition(ClientP); NeedRepaint := (NewTarget <> InvalidColumn) and (NewTarget <> FColumns.FDropTarget); if NewTarget >= 0 then begin FColumns.GetColumnBounds(NewTarget, Left, Right); if (ClientP.X < ((Left + Right) div 2)) <> FColumns.FDropBefore then begin NeedRepaint := True; FColumns.FDropBefore := not FColumns.FDropBefore; end; end; if NeedRepaint then begin // Invalidate columns which need a repaint. if FColumns.FDropTarget > NoColumn then begin I := FColumns.FDropTarget; FColumns.FDropTarget := NoColumn; Invalidate(FColumns.Items[I]); end; if (NewTarget > NoColumn) and (NewTarget <> FColumns.FDropTarget) then begin Invalidate(FColumns.Items[NewTarget]); FColumns.FDropTarget := NewTarget; end; end; FDragImage.DragTo(P, NeedRepaint); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.FixedAreaConstraintsChanged(Sender: TObject); // This method gets called when FFixedAreaConstraints is changed. begin Include(FStates, hsNeedScaling); if Treeview.HandleAllocated then RescaleHeader; end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.GetColumnsClass: TVirtualTreeColumnsClass; // Returns the class to be used for the actual column implementation. descendants may optionally override this and // return their own class. begin Result := TVirtualTreeColumns; end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.GetOwner: TPersistent; begin Result := FOwner; end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.GetShiftState: TShiftState; begin Result := []; if GetKeyState(VK_SHIFT) < 0 then Include(Result, ssShift); if GetKeyState(VK_LWIN) < 0 then // Mac OS X substitute of ssCtrl Include(Result, ssMeta); if GetKeyState(VK_CONTROL) < 0 then Include(Result, ssCtrl); if GetKeyState(VK_MENU) < 0 then Include(Result, ssAlt); end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.HandleHeaderMouseMove(var Message: TLMMouseMove): Boolean; var P: TPoint; I: TColumnIndex; begin Result := False; with Message do begin P := Point(XPos, YPos); if hsColumnWidthTrackPending in FStates then begin FStates := FStates - [hsColumnWidthTrackPending] + [hsColumnWidthTracking]; HandleHeaderMouseMove := True; Result := 0; end else if hsHeightTrackPending in FStates then begin FStates := FStates - [hsHeightTrackPending] + [hsHeightTracking]; HandleHeaderMouseMove := True; Result := 0; end else if hsColumnWidthTracking in FStates then begin if DoColumnWidthTracking(FColumns.FTrackIndex, GetShiftState, FTrackPoint, P) then if Treeview.UseRightToLeftAlignment then FColumns[FColumns.FTrackIndex].Width := FTrackPoint.X - XPos else FColumns[FColumns.FTrackIndex].Width := XPos - FTrackPoint.X; HandleHeaderMouseMove := True; Result := 0; end else if hsHeightTracking in FStates then begin //lclheader //fixes setting height Dec(P.Y, FHeight); if DoHeightTracking(P, GetShiftState) then SetHeight(Integer(FHeight) + P.Y); HandleHeaderMouseMove := True; Result := 0; end else begin if hsDragPending in FStates then begin P := Treeview.ClientToScreen(P); // start actual dragging if allowed if (hoDrag in FOptions) and Treeview.DoHeaderDragging(FColumns.FDownIndex) then begin if ((Abs(FDragStart.X - P.X) > DragManager.DragThreshold) or (Abs(FDragStart.Y - P.Y) > DragManager.DragThreshold)) then begin {$ifdef DEBUG_VTV}Logger.Send([lcDrag], 'HandleHeaderMouseMove - DragIndex: %d - DownIndex: %d', [FColumns.FDragIndex, FColumns.FDownIndex]);{$endif} I := FColumns.FDownIndex; FColumns.FDownIndex := NoColumn; FColumns.FHoverIndex := NoColumn; if I > NoColumn then Invalidate(FColumns[I]); //todo: implement drag image under gtk PrepareDrag(P, FDragStart); FStates := FStates - [hsDragPending] + [hsDragging]; HandleHeaderMouseMove := True; Result := 0; end; end; end else if hsDragging in FStates then begin DragTo(Treeview.ClientToScreen(P)); HandleHeaderMouseMove := True; Result := 0; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.HandleMessage(var Message: TLMessage): Boolean; // The header gets here the opportunity to handle certain messages before they reach the tree. This is important // because the tree needs to handle various non-client area messages for the header as well as some dragging/tracking // events. // By returning True the message will not be handled further, otherwise the message is then dispatched // to the proper message handlers. var P: TPoint; R: TRect; I: TColumnIndex; OldPosition: Integer; HitIndex: TColumnIndex; NewCursor: HCURSOR; Button: TMouseButton; Menu: TPopupMenu; IsInHeader, IsHSplitterHit, IsVSplitterHit: Boolean; //--------------- local function -------------------------------------------- function HSPlitterHit: Boolean; var NextCol: TColumnIndex; begin Result := (hoColumnResize in FOptions) and DetermineSplitterIndex(P); if Result and not InHeader(P) then begin NextCol := FColumns.GetNextVisibleColumn(FColumns.FTrackIndex); if not (coFixed in FColumns[FColumns.FTrackIndex].Options) or (NextCol <= NoColumn) or (coFixed in FColumns[NextCol].Options) or (P.Y > Integer(Treeview.FRangeY)) then Result := False; end; end; //--------------- end local function ---------------------------------------- begin Result := False; case Message.Msg of LM_SIZE: begin if not (tsWindowCreating in FOwner.FStates) then if (hoAutoResize in FOptions) and not (hsAutoSizing in FStates) then begin FColumns.AdjustAutoSize(InvalidColumn); Invalidate(nil); end else if not (hsScaling in FStates) then begin RescaleHeader; Invalidate(nil); end; end; CM_PARENTFONTCHANGED: if FParentFont then FFont.Assign(FOwner.Font); CM_BIDIMODECHANGED: for I := 0 to FColumns.Count - 1 do if coParentBiDiMode in FColumns[I].FOptions then FColumns[I].ParentBiDiModeChanged; LM_MBUTTONDOWN: begin //lclheader: NCMessages are given in screen coordinates unlike the ordinary with TLMMButtonDown(Message) do P:= Point(XPos, YPos); //P := Treeview.ScreenToClient(Point(XPos, YPos)); if InHeader(P) then FOwner.DoHeaderMouseDown(mbMiddle, GetShiftState, P.X, P.Y + Integer(FHeight)); end; LM_MBUTTONUP: begin with TLMMButtonUp(Message) do P:= Point(XPos, YPos); //P := FOwner.ScreenToClient(Point(XPos, YPos)); if InHeader(P) then begin FColumns.HandleClick(P, mbMiddle, True, False); FOwner.DoHeaderMouseUp(mbMiddle, GetShiftState, P.X, P.Y + Integer(FHeight)); FColumns.FDownIndex := NoColumn; end; end; LM_LBUTTONDBLCLK, LM_MBUTTONDBLCLK, LM_RBUTTONDBLCLK: begin with TLMLButtonDblClk(Message) do P := Point(XPos, YPos); if (hoHeightDblClickResize in FOptions) and InHeaderSplitterArea(P) and (FDefaultHeight > 0) then begin if DoHeightDblClickResize(P, GetShiftState) and (FDefaultHeight > 0) then SetHeight(FMinHeight); Result := True; end else if HSplitterHit and (Message.Msg = LM_LBUTTONDBLCLK) and (hoDblClickResize in FOptions) and (FColumns.FTrackIndex > NoColumn) then begin // If the click was on a splitter then resize column to smallest width. if DoColumnWidthDblClickResize(FColumns.FTrackIndex, P, GetShiftState) then AutoFitColumns(True, smaUseColumnOption, Columns.FTrackIndex, Columns.FTrackIndex); Message.Result := 0; Result := True; end else if InHeader(P) and (Message.Msg <> LM_LBUTTONDBLCLK) then begin case Message.Msg of LM_MBUTTONDBLCLK: Button := mbMiddle; LM_RBUTTONDBLCLK: Button := mbRight; else // WM_NCLBUTTONDBLCLK Button := mbLeft; end; FColumns.HandleClick(P, Button, True, True); end; end; // The "hot" area of the headers horizontal splitter is partly within the client area of the the tree, so we need // to handle WM_LBUTTONDOWN here, too. LM_LBUTTONDOWN: begin if csDesigning in Treeview.ComponentState then Exit; Application.CancelHint; // make sure no auto scrolling is active... KillTimer(Treeview.Handle, ScrollTimer); Treeview.DoStateChange([], [tsScrollPending, tsScrolling]); // ... pending editing is cancelled (actual editing remains active) KillTimer(Treeview.Handle, EditTimer); Treeview.DoStateChange([], [tsEditPending]); with TLMLButtonDown(Message) do begin // want the drag start point in screen coordinates P := Point(XPos, YPos); FDragStart := Treeview.ClientToScreen(P); //FDragStart := Point(XPos, YPos); //P := Treeview.ScreenToClient(FDragStart); end; IsInHeader := InHeader(P); IsVSplitterHit := (hoHeightResize in FOptions) and InHeaderSplitterArea(P); IsHSplitterHit := HSplitterHit; if IsVSplitterHit or IsHSplitterHit then begin FTrackStart := P; FColumns.FHoverIndex := NoColumn; if IsVSplitterHit then begin DoBeforeHeightTracking(GetShiftState); Include(FStates, hsHeightTrackPending) end else begin DoBeforeColumnWidthTracking(FColumns.FTrackIndex, GetShiftState); Include(FStates, hsColumnWidthTrackPending); end; SetCapture(Treeview.Handle); Result := True; Message.Result := 0; end else if IsInHeader then begin HitIndex := Columns.AdjustDownColumn(P); if (hoDrag in FOptions) and (HitIndex > NoColumn) and (coDraggable in FColumns[HitIndex].FOptions) then begin // Show potential drag operation. // Disabled columns do not start a drag operation because they can't be clicked. Include(FStates, hsDragPending); SetCapture(Treeview.Handle); Result := True; Message.Result := 0; end; end; // This is a good opportunity to notify the application. if IsInHeader then FOwner.DoHeaderMouseDown(mbLeft, GetShiftState, P.X, P.Y + Integer(FHeight)); end; LM_RBUTTONDOWN: begin with TLMRButtonDown(Message) do P:=Point(XPos,YPos); //P := FOwner.ScreenToClient(Point(XPos, YPos)); if InHeader(P) then FOwner.DoHeaderMouseDown(mbRight, GetShiftState, P.X, P.Y + Integer(FHeight)); end; LM_RBUTTONUP: if not (csDesigning in FOwner.ComponentState) then with TLMRButtonUp(Message) do begin Application.CancelHint; P := Point(XPos,YPos); //P := FOwner.ScreenToClient(Point(XPos, YPos)); if InHeader(P) then begin FColumns.HandleClick(P, mbRight, True, False); FOwner.DoHeaderMouseUp(mbRight, GetShiftState, P.X, P.Y + Integer(FHeight)); FColumns.FDownIndex := NoColumn; FColumns.FTrackIndex := NoColumn; Menu := FPopupMenu; if not Assigned(Menu) then Menu := DoGetPopupMenu(FColumns.ColumnFromPosition(Point(P.X, P.Y + Integer(FHeight))), P); // Trigger header popup if there's one. if Assigned(Menu) then begin KillTimer(Treeview.Handle, ScrollTimer); FColumns.FHoverIndex := NoColumn; Treeview.DoStateChange([], [tsScrollPending, tsScrolling]); Menu.PopupComponent := Treeview; P := Treeview.ClientToScreen(Point(XPos, YPos)); Menu.Popup(P.X, P.Y); HandleMessage := True; end; end; end; // When the tree window has an active mouse capture then we only get "client-area" messages. LM_LBUTTONUP: begin Application.CancelHint; if FStates <> [] then begin ReleaseCapture; //lcl if hsColumnWidthTracking in FStates then begin if not InHeader(SmallPointToPoint(TLMLButtonUp(Message).Pos)) then TreeView.Cursor := crDefault; end; if hsDragging in FStates then begin // successfull dragging moves columns with TLMLButtonUp(Message) do P := Treeview.ClientToScreen(Point(XPos, YPos)); GetWindowRect(Treeview.Handle, R); {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'Header - EndDrag / R',R);{$endif} with FColumns do begin {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'Header - EndDrag / FDropTarget: %d FDragIndex: %d FDragIndexPosition: %d', [FDropTarget, FDragIndex, FColumns[FDragIndex].Position]);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'Header - EndDrag / FDropBefore', FColumns.FDropBefore);{$endif} FDragImage.EndDrag; if (FDropTarget > -1) and (FDropTarget <> FDragIndex) and PtInRect(R, P) then begin {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'Header - EndDrag / FDropTargetPosition', FColumns[FDropTarget].Position);{$endif} OldPosition := FColumns[FDragIndex].Position; if FColumns.FDropBefore then begin if FColumns[FDragIndex].Position < FColumns[FDropTarget].Position then FColumns[FDragIndex].Position := Max(0, FColumns[FDropTarget].Position - 1) else FColumns[FDragIndex].Position := FColumns[FDropTarget].Position; end else begin if FColumns[FDragIndex].Position < FColumns[FDropTarget].Position then FColumns[FDragIndex].Position := FColumns[FDropTarget].Position else FColumns[FDragIndex].Position := FColumns[FDropTarget].Position + 1; end; Treeview.DoHeaderDragged(FDragIndex, OldPosition); end else Treeview.DoHeaderDraggedOut(FDragIndex, P); FDropTarget := NoColumn; end; Invalidate(nil); end; Result := True; Message.Result := 0; end; case Message.Msg of LM_LBUTTONUP: with TLMLButtonUp(Message) do begin if FColumns.FDownIndex > NoColumn then FColumns.HandleClick(Point(XPos, YPos), mbLeft, False, False); if FStates <> [] then FOwner.DoHeaderMouseUp(mbLeft, KeysToShiftState(Keys), XPos, YPos); end; //todo: there's a difference here { LM_NCLBUTTONUP: with TLMLButtonUp(Message) do begin P := FOwner.ScreenToClient(Point(XPos, YPos)); FColumns.HandleClick(P, mbLeft, False, False); FOwner.DoHeaderMouseUp(mbLeft, GetShiftState, P.X, P.Y + Integer(FHeight)); end; } end; if FColumns.FTrackIndex > NoColumn then begin if hsColumnWidthTracking in FStates then DoAfterColumnWidthTracking(FColumns.FTrackIndex); Invalidate(Columns[FColumns.FTrackIndex]); FColumns.FTrackIndex := NoColumn; end; if FColumns.FDownIndex > NoColumn then begin Invalidate(Columns[FColumns.FDownIndex]); FColumns.FDownIndex := NoColumn; end; if hsHeightTracking in FStates then DoAfterHeightTracking; FStates := FStates - [hsDragging, hsDragPending, hsColumnWidthTracking, hsColumnWidthTrackPending, hsHeightTracking, hsHeightTrackPending]; end; // hovering, mouse leave detection CM_MOUSELEAVE: with FColumns do begin if FHoverIndex > NoColumn then Invalidate(Items[FHoverIndex]); FHoverIndex := NoColumn; FClickIndex := NoColumn; FDownIndex := NoColumn; end; //todo: see the difference to below LM_MOUSEMOVE: with TLMMouseMove(Message), FColumns do begin //lcl HandleMessage := HandleHeaderMouseMove(TLMMouseMove(Message)); P := Point(XPos,YPos); //P := Treeview.ScreenToClient(Point(XPos, YPos)); IsInHeader := InHeader(P); if IsInHeader then begin Treeview.DoHeaderMouseMove(GetShiftState, P.X, P.Y); if ((AdjustHoverColumn(P)) or ((FDownIndex > NoColumn) and (FHoverIndex <> FDownIndex))) then begin Invalidate(nil); // todo: under lcl, the hint is show even if HintMouseMessage is not implemented // Is it necessary here? // use Delphi's internal hint handling for header hints too if hoShowHint in FOptions then begin // client coordinates! XPos := P.x; YPos := P.y; Application.HintMouseMessage(Treeview, Message); end; end; end else begin if FHoverIndex > NoColumn then Invalidate(Items[FHoverIndex]); FHoverIndex := NoColumn; FClickIndex := NoColumn; FDownIndex := NoColumn; end; //Adjust Cursor if not (csDesigning in FOwner.ComponentState) and (FStates = []) then begin //todo: see a way to store the user defined cursor. IsHSplitterHit := IsInHeader and HSplitterHit; IsVSplitterHit := (hoHeightResize in FOptions) and InHeaderSplitterArea(P); if IsVSplitterHit or IsHSplitterHit then begin NewCursor := crDefault; if IsVSplitterHit and (hoHeightResize in FOptions) then NewCursor := crVertSplit else if IsHSplitterHit then NewCursor := crHeaderSplit; Treeview.DoGetHeaderCursor(NewCursor); if NewCursor <> crDefault then begin Treeview.Cursor := NewCursor; HandleMessage := True; Message.Result := 1; end; end; end else begin Message.Result := 1; HandleMessage := True; end; end; LM_KEYDOWN, LM_KILLFOCUS: if (Message.Msg = LM_KILLFOCUS) or (TLMKeyDown(Message).CharCode = VK_ESCAPE) then begin if hsDragging in FStates then begin ReleaseCapture; FDragImage.EndDrag; Exclude(FStates, hsDragging); FColumns.FDropTarget := NoColumn; Invalidate(nil); Result := True; Message.Result := 0; end else begin if [hsColumnWidthTracking, hsHeightTracking] * FStates <> [] then begin ReleaseCapture; if hsColumnWidthTracking in FStates then DoAfterColumnWidthTracking(FColumns.FTrackIndex); if hsHeightTracking in FStates then DoAfterHeightTracking; Result := True; Message.Result := 0; end; FStates := FStates - [hsColumnWidthTracking, hsColumnWidthTrackPending, hsHeightTracking, hsHeightTrackPending]; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.ImageListChange(Sender: TObject); begin if not (csDestroying in Treeview.ComponentState) then Invalidate(nil); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.PrepareDrag(P, Start: TPoint); // Initializes dragging of the header, P is the current mouse postion and Start the initial mouse position. var HeaderR: TRect; Image: TBitmap; ImagePos: TPoint; DragColumn: TVirtualTreeColumn; begin // Determine initial position of drag image (screen coordinates). FColumns.FDropTarget := NoColumn; Start := Treeview.ScreenToClient(Start); FColumns.FDragIndex := FColumns.ColumnFromPosition(Start); DragColumn := FColumns[FColumns.FDragIndex]; HeaderR := Treeview.FHeaderRect; // Set right border of the header rectangle to the maximum extent. // Adjust top border too, it is already covered elsewhere. HeaderR.Right := FColumns.TotalWidth; HeaderR.Top := 0; // Take out influence of border since we need a seamless drag image. OffsetRect(HeaderR, -Treeview.BorderWidth, -Treeview.BorderWidth); if Treeview.UseRightToLeftAlignment then Dec(HeaderR.Left, Treeview.ComputeRTLOffset); Image := TBitmap.Create; with Image do try PixelFormat := pf32Bit; Width := DragColumn.Width; Height := FHeight; // Erase the entire image with the color key value, for the case not everything // in the image is covered by the header image. Canvas.Brush.Color := clBtnFace; Canvas.FillRect(Rect(0, 0, Width, Height)); // Now move the window origin of bitmap DC so that although the entire header is painted // only the dragged column becomes visible. SetWindowOrgEx(Canvas.Handle, DragColumn.FLeft, 0, nil); FColumns.PaintHeader(Canvas.Handle, HeaderR, 0); SetWindowOrgEx(Canvas.Handle, 0, 0, nil); if Treeview.UseRightToLeftAlignment then ImagePos := Treeview.ClientToScreen(Point(DragColumn.Left + Treeview.ComputeRTLOffset(True), 0)) else ImagePos := Treeview.ClientToScreen(Point(DragColumn.Left, 0)); //lclheader // Column rectangles are given in local window coordinates not client coordinates. // The above statement is not valid under LCL //Dec(ImagePos.Y, FHeight); if hoRestrictDrag in FOptions then FDragImage.MoveRestriction := dmrHorizontalOnly else FDragImage.MoveRestriction := dmrNone; FDragImage.PrepareDrag(Image, ImagePos, P, nil); FDragImage.ShowDragImage; finally Image.Free; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.RecalculateHeader; // Initiate a recalculation of the non-client area of the owner tree. begin if Treeview.HandleAllocated then begin Treeview.UpdateHeaderRect; //lclheader //not necessary since header is draw inside client area //SetWindowPos(Treeview.Handle, 0, 0, 0, 0, 0, SWP_FRAMECHANGED or SWP_NOMOVE or SWP_NOACTIVATE or SWP_NOOWNERZORDER or // SWP_NOSENDCHANGING or SWP_NOSIZE or SWP_NOZORDER); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.RescaleHeader; // Rescale the fixed elements (fixed columns, header itself) to FixedAreaConstraints. var FixedWidth, MaxFixedWidth, MinFixedWidth: Integer; //--------------- local function -------------------------------------------- procedure ComputeConstraints; var I: TColumnIndex; begin with FColumns do begin I := GetFirstVisibleColumn; while I > NoColumn do begin if (coFixed in FColumns[I].Options) and (FColumns[I].Width < FColumns[I].MinWidth) then FColumns[I].FWidth := FColumns[I].FMinWidth; I := GetNextVisibleColumn(I); end; FixedWidth := GetVisibleFixedWidth; end; with FFixedAreaConstraints do begin MinFixedWidth := (TreeView.ClientWidth * FMinWidthPercent) div 100; MaxFixedWidth := (TreeView.ClientWidth * FMaxWidthPercent) div 100; end; end; //----------- end local function -------------------------------------------- begin if ([csLoading, csReading, csWriting, csDestroying] * Treeview.ComponentState = []) and not (hsLoading in FStates) and Treeview.HandleAllocated then begin Include(FStates, hsScaling); SetHeight(FHeight); RecalculateHeader; with FFixedAreaConstraints do if (FMinHeightPercent > 0) or (FMaxHeightPercent > 0) then begin ComputeConstraints; with FColumns do if (FMaxWidthPercent > 0) and (FixedWidth > MaxFixedWidth) then ResizeColumns(MaxFixedWidth - FixedWidth, 0, Count - 1, [coVisible, coFixed]) else if (FMinWidthPercent > 0) and (FixedWidth < MinFixedWidth) then ResizeColumns(MinFixedWidth - FixedWidth, 0, Count - 1, [coVisible, coFixed]); FColumns.UpdatePositions; end; Exclude(FStates, hsScaling); Exclude(FStates, hsNeedScaling); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.UpdateMainColumn; // Called once the load process of the owner tree is done. begin if FMainColumn < 0 then FMainColumn := 0; if FMainColumn > FColumns.Count - 1 then FMainColumn := FColumns.Count - 1; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.UpdateSpringColumns; var I: TColumnIndex; SpringCount: Integer; Sign: Integer; ChangeBy: Single; Difference: Single; NewAccumulator: Single; begin with TreeView do ChangeBy := FHeaderRect.Right - FHeaderRect.Left - FLastWidth; if (hoAutoSpring in FOptions) and (FLastWidth <> 0) and (ChangeBy <> 0) then begin // Stay positive if downsizing the control. if ChangeBy < 0 then Sign := -1 else Sign := 1; ChangeBy := Abs(ChangeBy); // Count how many columns have spring enabled. SpringCount := 0; for I := 0 to FColumns.Count-1 do if [coVisible, coAutoSpring] * FColumns[I].FOptions = [coVisible, coAutoSpring] then Inc(SpringCount); if SpringCount > 0 then begin // Calculate the size to add/sub to each columns. Difference := ChangeBy / SpringCount; // Adjust the column's size accumulators and resize if the result is >= 1. for I := 0 to FColumns.Count - 1 do if [coVisible, coAutoSpring] * FColumns[I].FOptions = [coVisible, coAutoSpring] then begin // Sum up rest changes from previous runs and the amount from this one and store it in the // column. If there is at least one pixel difference then do a resize and reset the accumulator. NewAccumulator := FColumns[I].FSpringRest + Difference; // Set new width if at least one pixel size difference is reached. if NewAccumulator >= 1 then FColumns[I].SetWidth(FColumns[I].FWidth + (Trunc(NewAccumulator) * Sign)); FColumns[I].FSpringRest := Frac(NewAccumulator); // Keep track of the size count. ChangeBy := ChangeBy - Difference; // Exit loop if resize count drops below freezing point. if ChangeBy < 0 then Break; end; end; end; with TreeView do FLastWidth := FHeaderRect.Right - FHeaderRect.Left; end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.AllowFocus(ColumnIndex: TColumnIndex): Boolean; begin Result := False; if not FColumns.IsValidColumn(ColumnIndex) then exit; // Just in case. Result := (coAllowFocus in FColumns[ColumnIndex].Options); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.Assign(Source: TPersistent); begin if Source is TVTHeader then begin AutoSizeIndex := TVTHeader(Source).AutoSizeIndex; Background := TVTHeader(Source).Background; Columns := TVTHeader(Source).Columns; Font := TVTHeader(Source).Font; FixedAreaConstraints.Assign(TVTHeader(Source).FixedAreaConstraints); Height := TVTHeader(Source).Height; Images := TVTHeader(Source).Images; MainColumn := TVTHeader(Source).MainColumn; Options := TVTHeader(Source).Options; ParentFont := TVTHeader(Source).ParentFont; PopupMenu := TVTHeader(Source).PopupMenu; SortColumn := TVTHeader(Source).SortColumn; SortDirection := TVTHeader(Source).SortDirection; Style := TVTHeader(Source).Style; RescaleHeader; end else inherited; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.AutoFitColumns(Animated: Boolean = True; SmartAutoFitType: TSmartAutoFitType = smaUseColumnOption; RangeStartCol: Integer = NoColumn; RangeEndCol: Integer = NoColumn); //--------------- local functions ------------------------------------------- function GetUseSmartColumnWidth(ColumnIndex: TColumnIndex): Boolean; begin Result := False; case SmartAutoFitType of smaAllColumns: Result := True; smaNoColumn: Result := False; smaUseColumnOption: Result := coSmartResize in FColumns.Items[ColumnIndex].FOptions; end; end; //---------------------------------------------------------------------------- procedure DoAutoFitColumn(Column: TColumnIndex); begin with FColumns do if ([coResizable, coVisible] * Items[FPositionToIndex[Column]].FOptions = [coResizable, coVisible]) and DoBeforeAutoFitColumn(FPositionToIndex[Column], SmartAutoFitType) and not TreeView.OperationCanceled then begin if Animated then AnimatedResize(FPositionToIndex[Column], Treeview.GetMaxColumnWidth(FPositionToIndex[Column], GetUseSmartColumnWidth(FPositionToIndex[Column]))) else FColumns[FPositionToIndex[Column]].Width := Treeview.GetMaxColumnWidth(FPositionToIndex[Column], GetUseSmartColumnWidth(FPositionToIndex[Column])); DoAfterAutoFitColumn(FPositionToIndex[Column]); end; end; //--------------- end local functions ---------------------------------------- var I: Integer; StartCol, EndCol: Integer; begin StartCol := Max(NoColumn + 1, RangeStartCol); if RangeEndCol <= NoColumn then EndCol := FColumns.Count - 1 else EndCol := Min(RangeEndCol, FColumns.Count - 1); if StartCol > EndCol then Exit; // nothing to do TreeView.BeginOperation; if Assigned(TreeView.FOnBeforeAutoFitColumns) then TreeView.FOnBeforeAutoFitColumns(Self, SmartAutoFitType); for I := StartCol to EndCol do DoAutoFitColumn(I); if Assigned(TreeView.FOnAfterAutoFitColumns) then TreeView.FOnAfterAutoFitColumns(Self); Treeview.EndOperation; end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.InHeader(const P: TPoint): Boolean; // Determines whether the given point (client coordinates!) is within the header rectangle (non-client coordinates). begin //lclheader //todo: remove this function and use PtInRect directly ?? Result := PtInRect(TreeView.FHeaderRect, P); end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.InHeaderSplitterArea(P: TPoint): Boolean; // Determines whether the given point (client coordinates!) hits the horizontal splitter area of the header. var R: TRect; begin Result := (hoVisible in FOptions); if Result then begin R := Treeview.FHeaderRect; R.Top := R.Bottom - 2; Inc(R.Bottom, 2); Result := PtInRect(R, P); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.Invalidate(Column: TVirtualTreeColumn; ExpandToBorder: Boolean = False); // Because the header is in the non-client area of the tree it needs some special handling in order to initiate its // repainting. // If ExpandToBorder is True then not only the given column but everything or (depending on hoFullRepaintOnResize) just // everything to its right (or left, in RTL mode) will be invalidated (useful for resizing). This makes only sense when // a column is given. var R: TRect; begin if (hoVisible in FOptions) and Treeview.HandleAllocated then with Treeview do begin if Column = nil then R := FHeaderRect else begin R := Column.GetRect; if not (coFixed in Column.Options) then OffsetRect(R, -FEffectiveOffsetX, 0); if UseRightToLeftAlignment then OffsetRect(R, ComputeRTLOffset, 0); if ExpandToBorder then begin if (hoFullRepaintOnResize in FHeader.FOptions) then begin R.Left := FHeaderRect.Left; R.Right := FHeaderRect.Right; end else begin if UseRightToLeftAlignment then R.Left := FHeaderRect.Left else R.Right := FHeaderRect.Right; end; end; end; //lclheader RedrawWindow(Handle, @R, 0, RDW_FRAME or RDW_INVALIDATE or RDW_VALIDATE or RDW_NOINTERNALPAINT or RDW_NOERASE or RDW_NOCHILDREN); { // Current position of the owner in screen coordinates. GetWindowRect(Handle, RW); // Consider the header within this rectangle. OffsetRect(R, RW.Left, RW.Top); // Expressed in client coordinates (because RedrawWindow wants them so, they will actually become negative). MapWindowPoints(0, Handle, R, 2); RedrawWindow(Handle, @R, 0, RDW_FRAME or RDW_INVALIDATE or RDW_VALIDATE or RDW_NOINTERNALPAINT or RDW_NOERASE or RDW_NOCHILDREN); } end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.LoadFromStream(const Stream: TStream); // restore the state of the header from the given stream var Dummy, Version: Integer; S: AnsiString; OldOptions: TVTHeaderOptions; begin Include(FStates, hsLoading); with Stream do try // Switch off all options which could influence loading the columns (they will be later set again). OldOptions := FOptions; FOptions := []; // Determine whether the stream contains data without a version number. ReadBuffer(Dummy, SizeOf(Dummy)); if Dummy > -1 then begin // Seek back to undo the read operation if this is an old stream format. Seek(-SizeOf(Dummy), soFromCurrent); Version := -1; end else // Read version number if this is a "versionized" format. ReadBuffer(Version, SizeOf(Version)); Columns.LoadFromStream(Stream, Version); ReadBuffer(Dummy, SizeOf(Dummy)); AutoSizeIndex := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); Background := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); Height := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); FOptions := OldOptions; Options := TVTHeaderOptions(Word(Dummy)); // PopupMenu is neither saved nor restored ReadBuffer(Dummy, SizeOf(Dummy)); Style := TVTHeaderStyle(Dummy); // TFont has no own save routine so we do it manually with Font do begin ReadBuffer(Dummy, SizeOf(Dummy)); Color := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); Height := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); SetLength(S, Dummy); ReadBuffer(PAnsiChar(S)^, Dummy); Name := S; ReadBuffer(Dummy, SizeOf(Dummy)); Pitch := TFontPitch(Dummy); ReadBuffer(Dummy, SizeOf(Dummy)); Style := TFontStyles(LongWord(Dummy)); end; // LCL port started with header stream version 6 so no need to do the check here // Read data introduced by stream version 1+. ReadBuffer(Dummy, SizeOf(Dummy)); MainColumn := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); SortColumn := Dummy; ReadBuffer(Dummy, SizeOf(Dummy)); SortDirection := TSortDirection(Byte(Dummy)); // Read data introduced by stream version 5+. ReadBuffer(Dummy, SizeOf(Dummy)); ParentFont := Boolean(Dummy); ReadBuffer(Dummy, SizeOf(Dummy)); FMaxHeight := Integer(Dummy); ReadBuffer(Dummy, SizeOf(Dummy)); FMinHeight := Integer(Dummy); ReadBuffer(Dummy, SizeOf(Dummy)); FDefaultHeight := Integer(Dummy); with FFixedAreaConstraints do begin ReadBuffer(Dummy, SizeOf(Dummy)); FMaxHeightPercent := TVTConstraintPercent(Dummy); ReadBuffer(Dummy, Sizeof(Dummy)); FMaxWidthPercent := TVTConstraintPercent(Dummy); ReadBuffer(Dummy, SizeOf(Dummy)); FMinHeightPercent := TVTConstraintPercent(Dummy); ReadBuffer(Dummy, Sizeof(Dummy)); FMinWidthPercent := TVTConstraintPercent(Dummy); end finally Exclude(FStates, hsLoading); Treeview.DoColumnResize(NoColumn); end; end; //---------------------------------------------------------------------------------------------------------------------- function TVTHeader.ResizeColumns(ChangeBy: Integer; RangeStartCol: TColumnIndex; RangeEndCol: TColumnIndex; Options: TVTColumnOptions = [coVisible]): Integer; // Distribute the given width change to a range of columns. A 'fair' way is used to distribute ChangeBy to the columns, // while ensuring that everything that can be distributed will be distributed. var Start, I: TColumnIndex; ColCount, ToGo, Sign, Rest, MaxDelta, Difference: Integer; Constraints, Widths: Array of Integer; BonusPixel: Boolean; //--------------- local functions ------------------------------------------- function IsResizable (Column: TColumnIndex): Boolean; begin if BonusPixel then Result := Widths[Column - RangeStartCol] < Constraints[Column - RangeStartCol] else Result := Widths[Column - RangeStartCol] > Constraints[Column - RangeStartCol]; end; //--------------------------------------------------------------------------- procedure IncDelta(Column: TColumnIndex); begin if BonusPixel then Inc(MaxDelta, FColumns[Column].MaxWidth - Widths[Column - RangeStartCol]) else Inc(MaxDelta, Widths[Column - RangeStartCol] - Constraints[Column - RangeStartCol]); end; //--------------------------------------------------------------------------- function ChangeWidth(Column: TColumnIndex; Delta: Integer): Integer; begin if Delta > 0 then Delta := Min(Delta, Constraints[Column - RangeStartCol] - Widths[Column - RangeStartCol]) else Delta := Max(Delta, Constraints[Column - RangeStartCol] - Widths[Column - RangeStartCol]); Inc(Widths[Column - RangeStartCol], Delta); Dec(ToGo, Abs(Delta)); Result := Abs(Delta); end; //--------------------------------------------------------------------------- function ReduceConstraints: Boolean; var MaxWidth, MaxReserveCol, Column: TColumnIndex; begin Result := True; if not (hsScaling in FStates) or BonusPixel then Exit; MaxWidth := 0; MaxReserveCol := NoColumn; for Column := RangeStartCol to RangeEndCol do if (Options * FColumns[Column].FOptions = Options) and (FColumns[Column].FWidth > MaxWidth) then begin MaxWidth := Widths[Column - RangeStartCol]; MaxReserveCol := Column; end; if (MaxReserveCol <= NoColumn) or (Constraints[MaxReserveCol - RangeStartCol] <= 10) then Result := False else Dec(Constraints[MaxReserveCol - RangeStartCol], Constraints[MaxReserveCol - RangeStartCol] div 10); end; //----------- end local functions ------------------------------------------- begin Result := 0; if ChangeBy <> 0 then begin // Do some initialization here BonusPixel := ChangeBy > 0; Sign := IfThen(BonusPixel, 1, -1); Start := IfThen(BonusPixel, RangeStartCol, RangeEndCol); ToGo := Abs(ChangeBy); SetLength(Widths, RangeEndCol - RangeStartCol + 1); SetLength(Constraints, RangeEndCol - RangeStartCol + 1); for I := RangeStartCol to RangeEndCol do begin Widths[I - RangeStartCol] := FColumns[I].FWidth; Constraints[I - RangeStartCol] := IfThen(BonusPixel, FColumns[I].MaxWidth, FColumns[I].MinWidth); end; repeat repeat MaxDelta := 0; ColCount := 0; for I := RangeStartCol to RangeEndCol do if (Options * FColumns[I].FOptions = Options) and IsResizable(I) then begin Inc(ColCount); IncDelta(I); end; if MaxDelta < Abs(ChangeBy) then if not ReduceConstraints then Break; until (MaxDelta >= Abs(ChangeBy)) or not (hsScaling in FStates); if ColCount = 0 then Break; ToGo := Min(ToGo, MaxDelta); Difference := ToGo div ColCount; Rest := ToGo mod ColCount; if Difference > 0 then for I := RangeStartCol to RangeEndCol do if (Options * FColumns[I].FOptions = Options) and IsResizable(I) then ChangeWidth(I, Difference * Sign); // Now distribute Rest. I := Start; while Rest > 0 do begin if (Options * FColumns[I].FOptions = Options) and IsResizable(I) then if FColumns[I].FBonusPixel <> BonusPixel then begin Dec(Rest, ChangeWidth(I, Sign)); FColumns[I].FBonusPixel := BonusPixel; end; Inc(I, Sign); if (BonusPixel and (I > RangeEndCol)) or (not BonusPixel and (I < RangeStartCol)) then begin for I := RangeStartCol to RangeEndCol do if Options * FColumns[I].FOptions = Options then FColumns[I].FBonusPixel := not FColumns[I].FBonusPixel; I := Start; end; end; until ToGo <= 0; // Now set the computed widths. We also compute the result here. Include(FStates, hsResizing); for I := RangeStartCol to RangeEndCol do if (Options * FColumns[I].FOptions = Options) then begin Inc(Result, Widths[I - RangeStartCol] - FColumns[I].FWidth); FColumns[I].SetWidth(Widths[I - RangeStartCol]); end; Exclude(FStates, hsResizing); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.RestoreColumns; // Restores all columns to their width which they had before they have been auto fitted. var I: TColumnIndex; begin with FColumns do for I := Count - 1 downto 0 do if [coResizable, coVisible] * Items[FPositionToIndex[I]].FOptions = [coResizable, coVisible] then Items[I].RestoreLastWidth; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTHeader.SaveToStream(const Stream: TStream); // Saves the complete state of the header into the provided stream. var Dummy: Integer; Tmp: AnsiString; begin with Stream do begin // In previous version of VT was no header stream version defined. // For feature enhancements it is necessary, however, to know which stream // format we are trying to load. // In order to distict from non-version streams an indicator is inserted. Dummy := -1; WriteBuffer(Dummy, SizeOf(Dummy)); // Write current stream version number, nothing more is required at the time being. Dummy := VTHeaderStreamVersion; WriteBuffer(Dummy, SizeOf(Dummy)); // Save columns in case they depend on certain options (like auto size). Columns.SaveToStream(Stream); Dummy := FAutoSizeIndex; WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := FBackground; WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := FHeight; WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Word(FOptions); WriteBuffer(Dummy, SizeOf(Dummy)); // PopupMenu is neither saved nor restored Dummy := Ord(FStyle); WriteBuffer(Dummy, SizeOf(Dummy)); // TFont has no own save routine so we do it manually with Font do begin Dummy := Color; WriteBuffer(Dummy, SizeOf(Dummy)); // Need only to write one: size or height, I decided to write height. Dummy := Height; WriteBuffer(Dummy, SizeOf(Dummy)); Tmp := Name; Dummy := Length(Tmp); WriteBuffer(Dummy, SizeOf(Dummy)); WriteBuffer(PAnsiChar(Tmp)^, Dummy); Dummy := Ord(Pitch); WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Integer(Style); WriteBuffer(Dummy, SizeOf(Dummy)); end; // Data introduced by stream version 1. Dummy := FMainColumn; WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := FSortColumn; WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Byte(FSortDirection); WriteBuffer(Dummy, SizeOf(Dummy)); // Data introduced by stream version 5. Dummy := Integer(ParentFont); WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Integer(FMaxHeight); WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Integer(FMinHeight); WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Integer(FDefaultHeight); WriteBuffer(Dummy, SizeOf(Dummy)); with FFixedAreaConstraints do begin Dummy := Integer(FMaxHeightPercent); WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Integer(FMaxWidthPercent); WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Integer(FMinHeightPercent); WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := Integer(FMinWidthPercent); WriteBuffer(Dummy, SizeOf(Dummy)); end end; end; //----------------- TScrollBarOptions ---------------------------------------------------------------------------------- constructor TScrollBarOptions.Create(AOwner: TBaseVirtualTree); begin inherited Create; FOwner := AOwner; FAlwaysVisible := False; FScrollBarStyle := sbmRegular; FScrollBars := ssBoth; FIncrementX := 20; FIncrementY := 20; end; //---------------------------------------------------------------------------------------------------------------------- procedure TScrollBarOptions.SetAlwaysVisible(Value: Boolean); begin if FAlwaysVisible <> Value then begin FAlwaysVisible := Value; //todo_lcl_check if not (csLoading in FOwner.ComponentState) and FOwner.HandleAllocated then RecreateWnd(FOwner); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TScrollBarOptions.SetScrollBars(Value: TScrollStyle); begin if FScrollbars <> Value then begin FScrollBars := Value; //todo_lcl_check if not (csLoading in FOwner.ComponentState) and FOwner.HandleAllocated then RecreateWnd(FOwner); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TScrollBarOptions.SetScrollBarStyle(Value: TVTScrollBarStyle); begin {$ifndef UseFlatScrollbars} Assert(Value = sbmRegular, 'Flat scrollbars styles are disabled. Enable UseFlatScrollbars in VTConfig.inc for' + 'flat scrollbar support.'); {$endif UseFlatScrollbars} if FScrollBarStyle <> Value then begin FScrollBarStyle := Value; {$ifdef UseFlatScrollbars} if FOwner.HandleAllocated then begin // If set to regular style then don't use the emulation mode of the FlatSB APIs but the original APIs. // This is necessary because the FlatSB APIs don't respect NC paint request with limited update region // (which is necessary for the transparent drag image). FOwner.RecreateWnd; end; {$endif UseFlatScrollbars} end; end; //---------------------------------------------------------------------------------------------------------------------- function TScrollBarOptions.GetOwner: TPersistent; begin Result := FOwner; end; //---------------------------------------------------------------------------------------------------------------------- procedure TScrollBarOptions.Assign(Source: TPersistent); begin if Source is TScrollBarOptions then begin AlwaysVisible := TScrollBarOptions(Source).AlwaysVisible; HorizontalIncrement := TScrollBarOptions(Source).HorizontalIncrement; ScrollBars := TScrollBarOptions(Source).ScrollBars; ScrollBarStyle := TScrollBarOptions(Source).ScrollBarStyle; VerticalIncrement := TScrollBarOptions(Source).VerticalIncrement; end else inherited; end; //----------------- TVTColors ------------------------------------------------------------------------------------------ constructor TVTColors.Create(AOwner: TBaseVirtualTree); begin FOwner := AOwner; FColors[0] := clBtnShadow; // DisabledColor FColors[1] := clHighlight; // DropMarkColor FColors[2] := clHighLight; // DropTargetColor FColors[3] := clHighLight; // FocusedSelectionColor FColors[4] := clBtnFace; // GridLineColor FColors[5] := clBtnShadow; // TreeLineColor FColors[6] := clBtnFace; // UnfocusedSelectionColor FColors[7] := clBtnFace; // BorderColor FColors[8] := clWindowText; // HotColor FColors[9] := clHighLight; // FocusedSelectionBorderColor FColors[10] := clBtnFace; // UnfocusedSelectionBorderColor FColors[11] := clHighlight; // DropTargetBorderColor FColors[12] := clHighlight; // SelectionRectangleBlendColor FColors[13] := clHighlight; // SelectionRectangleBorderColor FColors[14] := clBtnShadow; // HeaderHotColor end; //---------------------------------------------------------------------------------------------------------------------- function TVTColors.GetColor(const Index: Integer): TColor; begin Result := FColors[Index]; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTColors.SetColor(const Index: Integer; const Value: TColor); begin if FColors[Index] <> Value then begin FColors[Index] := Value; if not (csLoading in FOwner.ComponentState) and FOwner.HandleAllocated then begin // Cause helper bitmap rebuild if the button color changed. case Index of 5: begin FOwner.PrepareBitmaps(True, False); FOwner.Invalidate; end; 7: RedrawWindow(FOwner.Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_NOERASE or RDW_NOCHILDREN) else FOwner.Invalidate; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTColors.Assign(Source: TPersistent); begin if Source is TVTColors then begin FColors := TVTColors(Source).FColors; if FOwner.FUpdateCount = 0 then FOwner.Invalidate; end else inherited; end; //----------------- TClipboardFormats ---------------------------------------------------------------------------------- constructor TClipboardFormats.Create(AOwner: TBaseVirtualTree); begin FOwner := AOwner; Sorted := True; Duplicates := dupIgnore; end; //---------------------------------------------------------------------------------------------------------------------- function TClipboardFormats.Add(const S: string): Integer; // Restrict additions to the clipbard formats to only those which are registered with the owner tree or one of its // ancestors. var Format: Word; RegisteredClass: TVirtualTreeClass; begin RegisteredClass := InternalClipboardFormats.FindFormat(S, Format); if Assigned(RegisteredClass) and FOwner.ClassType.InheritsFrom(RegisteredClass) then Result := inherited Add(S) else Result := -1; end; //---------------------------------------------------------------------------------------------------------------------- procedure TClipboardFormats.Insert(Index: Integer; const S: string); // Restrict additions to the clipbard formats to only those which are registered with the owner tree or one of its // ancestors. var Format: Word; RegisteredClass: TVirtualTreeClass; begin RegisteredClass := InternalClipboardFormats.FindFormat(S, Format); if Assigned(RegisteredClass) and FOwner.ClassType.InheritsFrom(RegisteredClass) then inherited Insert(Index, S); end; //----------------- TBaseVirtualTree ----------------------------------------------------------------------------------- constructor TBaseVirtualTree.Create(AOwner: TComponent); begin if not Initialized then InitializeGlobalStructures; inherited; ControlStyle := ControlStyle - [csSetCaption] + [csCaptureMouse, csOpaque, csReplicatable, csDisplayDragImage, csReflector]; FTotalInternalDataSize := 0; FNodeDataSize := -1; Width := 200; Height := 100; TabStop := True; ParentColor := False; FDefaultNodeHeight := 18; FDragOperations := [doCopy, doMove]; FHotCursor := crDefault; FScrollBarOptions := TScrollBarOptions.Create(Self); FFocusedColumn := NoColumn; FDragImageKind := diComplete; FLastSelectionLevel := -1; FSelectionBlendFactor := 128; FIndent := 18; FPlusBM := TBitmap.Create; FHotPlusBM := TBitmap.Create; FMinusBM := TBitmap.Create; FHotMinusBM := TBitmap.Create; BorderStyle := bsSingle; FButtonStyle := bsRectangle; FButtonFillMode := fmTreeColor; FHeader := GetHeaderClass.Create(Self); // we have an own double buffer handling DoubleBuffered := False; FCheckImageKind := ckSystemDefault; FImageChangeLink := TChangeLink.Create; FImageChangeLink.OnChange := ImageListChange; FStateChangeLink := TChangeLink.Create; FStateChangeLink.OnChange := ImageListChange; FCustomCheckChangeLink := TChangeLink.Create; FCustomCheckChangeLink.OnChange := ImageListChange; FAutoExpandDelay := 1000; FAutoScrollDelay := 1000; FAutoScrollInterval := 1; FBackground := TPicture.Create; FDefaultPasteMode := amAddChildLast; FMargin := 4; FTextMargin := 4; FDragType := dtOLE; FDragHeight := 350; FDragWidth := 200; FColors := TVTColors.Create(Self); FEditDelay := 1000; FDragImage := TVTDragImage.Create(Self); with FDragImage do begin Fade := True; PostBlendBias := 0; PreBlendBias := 0; Transparency := 200; end; SetLength(FSingletonNodeArray, 1); FAnimationDuration := 200; FSearchTimeout := 1000; FSearchStart := ssFocusedNode; FNodeAlignment := naProportional; FLineStyle := lsDotted; FIncrementalSearch := isNone; FClipboardFormats := TClipboardFormats.Create(Self); FOptions := GetOptionsClass.Create(Self); {$ifdef EnableThreadSupport} AddThreadReference; {$endif} end; //---------------------------------------------------------------------------------------------------------------------- destructor TBaseVirtualTree.Destroy; begin Exclude(FOptions.FMiscOptions, toReadOnly); {$ifdef EnableThreadSupport} ReleaseThreadReference(Self); {$endif} StopWheelPanning; //lcl FPanningWindow.Free; // Just in case it didn't happen already release the edit link. FEditLink := nil; FClipboardFormats.Free; // Clear will also free the drag manager if it is still alive. Clear; FDragImage.Free; FColors.Free; FBackground.Free; FImageChangeLink.Free; FStateChangeLink.Free; FCustomCheckChangeLink.Free; FScrollBarOptions.Free; FOptions.Free; // The window handle must be destroyed before the header is freed because it is needed in WM_NCDESTROY. //todo_lcl_check { if HandleAllocated then DestroyWindowHandle; } FreeAndNil(FHeader); if FCheckImages <> FCustomCheckImages then FCheckImages.Free; FreeMem(FRoot); FPlusBM.Free; FHotPlusBM.Free; FMinusBM.Free; FHotMinusBM.Free; inherited; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AdjustCoordinatesByIndent(var PaintInfo: TVTPaintInfo; Indent: Integer); // During painting of the main column some coordinates must be adjusted due to the tree lines. // The offset resulting from the tree lines and indentation level is given in Indent. var Offset: Integer; begin with PaintInfo do begin Offset := Indent * Integer(FIndent); if BidiMode = bdLeftToRight then begin Inc(ContentRect.Left, Offset); Inc(ImageInfo[iiNormal].XPos, Offset); Inc(ImageInfo[iiState].XPos, Offset); Inc(ImageInfo[iiCheck].XPos, Offset); end else begin Dec(ContentRect.Right, Offset); Dec(ImageInfo[iiNormal].XPos, Offset); Dec(ImageInfo[iiState].XPos, Offset); Dec(ImageInfo[iiCheck].XPos, Offset); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AdjustImageBorder(ImageWidth, ImageHeight: Integer; BidiMode: TBidiMode; VAlign: Integer; var R: TRect; var ImageInfo: TVTImageInfo); // Depending on the width of the image list as well as the given bidi mode R must be adjusted. begin if BidiMode = bdLeftToRight then begin ImageInfo.XPos := R.Left; Inc(R.Left, ImageWidth + 2); end else begin ImageInfo.XPos := R.Right - Images.Width; Dec(R.Right, ImageWidth + 2); end; ImageInfo.YPos := R.Top + VAlign - ImageHeight div 2; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AdjustTotalCount(Node: PVirtualNode; Value: Integer; Relative: Boolean = False); // Sets a node's total count to the given value and recursively adjusts the parent's total count // (actually, the adjustment is done iteratively to avoid function call overheads). var Difference: Integer; Run: PVirtualNode; begin if Relative then Difference := Value else Difference := Integer(Value) - Integer(Node.TotalCount); if Difference <> 0 then begin Run := Node; // Root node has as parent the tree view. while Assigned(Run) and (Run <> Pointer(Self)) do begin Inc(Integer(Run.TotalCount), Difference); Run := Run.Parent; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AdjustTotalHeight(Node: PVirtualNode; Value: Integer; Relative: Boolean = False); // Sets a node's total height to the given value and recursively adjusts the parent's total height. var Difference: Integer; Run: PVirtualNode; begin if Relative then Difference := Value else Difference := Integer(Value) - Integer(Node.TotalHeight); if Difference <> 0 then begin Run := Node; repeat Inc(Integer(Run.TotalHeight), Difference); // If the node is not visible or the parent node is not expanded or we are already at the top // then nothing more remains to do. if not (vsVisible in Run.States) or (Run = FRoot) or (Run.Parent = nil) or not (vsExpanded in Run.Parent.States) then Break; Run := Run.Parent; until False; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CalculateCacheEntryCount: Integer; // Calculates the size of the position cache. begin if FVisibleCount > 1 then Result := Ceil(FVisibleCount / CacheThreshold) else Result := 0; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CalculateVerticalAlignments(ShowImages, ShowStateImages: Boolean; Node: PVirtualNode; out VAlign, VButtonAlign: Integer); // Calculates the vertical alignment of the given node and its associated expand/collapse button during // a node paint cycle depending on the required node alignment style. begin // For absolute alignment the calculation is trivial. case FNodeAlignment of naFromTop: VAlign := Node.Align; naFromBottom: VAlign := NodeHeight[Node] - Node.Align; else // naProportional // Consider button and line alignment, but make sure neither the image nor the button (whichever is taller) // go out of the entire node height (100% means bottom alignment to the node's bounds). if ShowImages or ShowStateImages then begin if ShowImages then VAlign := FImages.Height else VAlign := FStateImages.Height; VAlign := MulDiv((Integer(NodeHeight[Node]) - VAlign), Node.Align, 100) + VAlign div 2; end else if toShowButtons in FOptions.FPaintOptions then VAlign := MulDiv((Integer(NodeHeight[Node]) - FPlusBM.Height), Node.Align, 100) + FPlusBM.Height div 2 else VAlign := MulDiv(Node.NodeHeight, Node.Align, 100); end; VButtonAlign := VAlign - FPlusBM.Height div 2; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ChangeCheckState(Node: PVirtualNode; Value: TCheckState): Boolean; // Sets the check state of the node according to the given value and the node's check type. // If the check state must be propagated to the parent nodes and one of them refuses to change then // nothing happens and False is returned, otherwise True. var Run: PVirtualNode; UncheckedCount, MixedCheckCount, CheckedCount: Cardinal; begin Result := not (vsChecking in Node.States); with Node^ do if Result then begin Include(States, vsChecking); if not (vsInitialized in States) then InitNode(Node); // Indicate that we are going to propagate check states up and down the hierarchy. if FCheckPropagationCount = 0 then // WL, 05.02.2004: Do not enter tsCheckPropagation more than once DoStateChange([tsCheckPropagation]); Inc(FCheckPropagationCount); // WL, 05.02.2004 // Do actions which are associated with the given check state. case CheckType of // Check state change with additional consequences for check states of the children. ctTriStateCheckBox: begin // Propagate state down to the children. if toAutoTristateTracking in FOptions.FAutoOptions then case Value of csUncheckedNormal: if Node.ChildCount > 0 then begin Run := FirstChild; CheckedCount := 0; MixedCheckCount := 0; UncheckedCount := 0; while Assigned(Run) do begin if Run.CheckType in [ctCheckBox, ctTriStateCheckBox] then begin SetCheckState(Run, csUncheckedNormal); // Check if the new child state was set successfully, otherwise we have to adjust the // node's new check state accordingly. case Run.CheckState of csCheckedNormal: Inc(CheckedCount); csMixedNormal: Inc(MixedCheckCount); csUncheckedNormal: Inc(UncheckedCount); end; end; Run := Run.NextSibling; end; // If there is still a mixed state child node checkbox then this node must be mixed checked too. if MixedCheckCount > 0 then Value := csMixedNormal else // If nodes are normally checked child nodes then the unchecked count determines what // to set for the node itself. if CheckedCount > 0 then if UncheckedCount > 0 then Value := csMixedNormal else Value := csCheckedNormal; end; csCheckedNormal: if Node.ChildCount > 0 then begin Run := FirstChild; CheckedCount := 0; MixedCheckCount := 0; UncheckedCount := 0; while Assigned(Run) do begin if Run.CheckType in [ctCheckBox, ctTriStateCheckBox] then begin SetCheckState(Run, csCheckedNormal); // Check if the new child state was set successfully, otherwise we have to adjust the // node's new check state accordingly. case Run.CheckState of csCheckedNormal: Inc(CheckedCount); csMixedNormal: Inc(MixedCheckCount); csUncheckedNormal: Inc(UncheckedCount); end; end; Run := Run.NextSibling; end; // If there is still a mixed state child node checkbox then this node must be mixed checked too. if MixedCheckCount > 0 then Value := csMixedNormal else // If nodes are normally checked child nodes then the unchecked count determines what // to set for the node itself. if CheckedCount > 0 then if UncheckedCount > 0 then Value := csMixedNormal else Value := csCheckedNormal; end; end; end; // radio button check state change ctRadioButton: if Value = csCheckedNormal then begin // Make sure only this node is checked. Run := Parent.FirstChild; while Assigned(Run) do begin if Run.CheckType = ctRadioButton then Run.CheckState := csUncheckedNormal; Run := Run.NextSibling; end; Invalidate; end; end; if Result then CheckState := Value // Set new check state else CheckState := UnpressedState[CheckState]; // Reset dynamic check state. // Propagate state up to the parent. if not (vsInitialized in Parent.States) then InitNode(Parent); if (toAutoTristateTracking in FOptions.FAutoOptions) and ([vsChecking, vsDisabled] * Parent.States = []) and (CheckType in [ctCheckBox, ctTriStateCheckBox]) and (Parent <> FRoot) and (Parent.CheckType = ctTriStateCheckBox) then Result := CheckParentCheckState(Node, Value) else Result := True; InvalidateNode(Node); Exclude(States, vsChecking); Dec(FCheckPropagationCount); // WL, 05.02.2004 if FCheckPropagationCount = 0 then // WL, 05.02.2004: Allow state change event after all check operations finished DoStateChange([], [tsCheckPropagation]); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CollectSelectedNodesLTR(MainColumn, NodeLeft, NodeRight: Integer; Alignment: TAlignment; OldRect: TRect; const NewRect: TRect): Boolean; // Helper routine used when a draw selection takes place. This version handles left-to-right directionality. // In the process of adding or removing nodes the current selection is modified which requires to pack it after // the function returns. Another side effect of this method is that a temporary list of nodes will be created // (see also InternalCacheNode) which must be inserted into the current selection by the caller. var Run, NextNode: PVirtualNode; TextRight, TextLeft, CheckOffset, CurrentTop, CurrentRight, NextTop, NextColumn, NodeWidth, Dummy: Integer; MinY, MaxY: Integer; ImageOffset, StateImageOffset: Integer; IsInOldRect, IsInNewRect: Boolean; // quick check variables for various parameters WithCheck, WithImages, WithStateImages, DoSwitch, AutoSpan: Boolean; SimpleSelection: Boolean; begin // A priori nothing changes. Result := False; // Determine minimum and maximum vertical coordinates to limit iteration to. MinY := Min(OldRect.Top, NewRect.Top); MaxY := Max(OldRect.Bottom, NewRect.Bottom); // Initialize short hand variables to speed up tests below. DoSwitch := ssCtrlOS in FDrawSelShiftState; WithCheck := (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages); // Don't check the events here as descendant trees might have overriden the DoGetImageIndex method. WithImages := Assigned(FImages); if WithImages then ImageOffset := FImages.Width + 2 else ImageOffset := 0; WithStateImages := Assigned(FStateImages); if WithStateImages then StateImageOffset := FStateImages.Width + 2 else StateImageOffset := 0; if WithCheck then CheckOffset := FCheckImages.Height + 2 else CheckOffset := 0; AutoSpan := FHeader.UseColumns and (toAutoSpanColumns in FOptions.FAutoOptions); SimpleSelection := toSimpleDrawSelection in FOptions.FSelectionOptions; // This is the node to start with. Run := InternalGetNodeAt(0, MinY, False, CurrentTop); if Assigned(Run) then begin // The initial minimal left border is determined by the identation level of the node and is dynamically adjusted. if toShowRoot in FOptions.FPaintOptions then Inc(NodeLeft, Integer((GetNodeLevel(Run) + 1) * FIndent) + FMargin) else Inc(NodeLeft, Integer(GetNodeLevel(Run) * FIndent) + FMargin); // ----- main loop // Change selection depending on the node's rectangle being in the selection rectangle or not, but // touch only those nodes which overlap either the old selection rectangle or the new one but not both. repeat // Collect offsets for check, normal and state images. TextLeft := NodeLeft; if WithCheck and (Run.CheckType <> ctNone) then Inc(TextLeft, CheckOffset); if WithImages and HasImage(Run, ikNormal, MainColumn) then Inc(TextLeft, ImageOffset); if WithStateImages and HasImage(Run, ikState, MainColumn) then Inc(TextLeft, StateImageOffset); // Ensure the node's height is determined. MeasureItemHeight(Canvas, Run); NextTop := CurrentTop + Integer(NodeHeight[Run]); // Simple selection allows to draw the selection rectangle anywhere. No intersection with node captions is // required. Only top and bottom bounds of the rectangle matter. if SimpleSelection then begin IsInOldRect := (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom); IsInNewRect := (NextTop > NewRect.Top) and (CurrentTop < NewRect.Bottom); end else begin // The right column border might be extended if column spanning is enabled. if AutoSpan then begin with FHeader.FColumns do begin NextColumn := MainColumn; repeat Dummy := GetNextVisibleColumn(NextColumn); if (Dummy = InvalidColumn) or not ColumnIsEmpty(Run, Dummy) or (Items[Dummy].BidiMode <> bdLeftToRight) then Break; NextColumn := Dummy; until False; if NextColumn = MainColumn then CurrentRight := NodeRight else GetColumnBounds(NextColumn, Dummy, CurrentRight); end; end else CurrentRight := NodeRight; // Check if we need the node's width. This is the case when the node is not left aligned or the // left border of the selection rectangle is to the right of the left node border. if (TextLeft < OldRect.Left) or (TextLeft < NewRect.Left) or (Alignment <> taLeftJustify) then begin NodeWidth := DoGetNodeWidth(Run, MainColumn); if NodeWidth >= (CurrentRight - TextLeft) then TextRight := CurrentRight else case Alignment of taLeftJustify: TextRight := TextLeft + NodeWidth; taCenter: begin TextLeft := (TextLeft + CurrentRight - NodeWidth) div 2; TextRight := TextLeft + NodeWidth; end; else // taRightJustify TextRight := CurrentRight; TextLeft := TextRight - NodeWidth; end; end else TextRight := CurrentRight; // Now determine whether we need to change the state. IsInOldRect := (OldRect.Left <= TextRight) and (OldRect.Right >= TextLeft) and (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom); IsInNewRect := (NewRect.Left <= TextRight) and (NewRect.Right >= TextLeft) and (NextTop > NewRect.Top) and (CurrentTop < NewRect.Bottom); end; if IsInOldRect xor IsInNewRect then begin Result := True; if DoSwitch then begin if vsSelected in Run.States then InternalRemoveFromSelection(Run) else InternalCacheNode(Run); end else begin if IsInNewRect then InternalCacheNode(Run) else InternalRemoveFromSelection(Run); end; end; CurrentTop := NextTop; // Get next visible node and update left node position. NextNode := GetNextVisibleNoInit(Run, True); if NextNode = nil then Break; Inc(NodeLeft, CountLevelDifference(Run, NextNode) * Integer(FIndent)); Run := NextNode; until CurrentTop > MaxY; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CollectSelectedNodesRTL(MainColumn, NodeLeft, NodeRight: Integer; Alignment: TAlignment; OldRect: TRect; const NewRect: TRect): Boolean; // Helper routine used when a draw selection takes place. This version handles right-to-left directionality. // See also comments in CollectSelectedNodesLTR. var Run, NextNode: PVirtualNode; TextRight, TextLeft, CheckOffset, CurrentTop, CurrentLeft, NextTop, NextColumn, NodeWidth, Dummy: Integer; MinY, MaxY: Integer; ImageOffset, StateImageOffset: Integer; IsInOldRect, IsInNewRect: Boolean; // quick check variables for various parameters WithCheck, WithImages, WithStateImages, DoSwitch, AutoSpan: Boolean; SimpleSelection: Boolean; begin // A priori nothing changes. Result := False; // Switch the alignment to the opposite value in RTL context. ChangeBiDiModeAlignment(Alignment); // Determine minimum and maximum vertical coordinates to limit iteration to. MinY := Min(OldRect.Top, NewRect.Top); MaxY := Max(OldRect.Bottom, NewRect.Bottom); // Initialize short hand variables to speed up tests below. DoSwitch := ssCtrlOS in FDrawSelShiftState; WithCheck := (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages); // Don't check the events here as descendant trees might have overriden the DoGetImageIndex method. WithImages := Assigned(FImages); if WithImages then ImageOffset := FImages.Width + 2 else ImageOffset := 0; WithStateImages := Assigned(FStateImages); if WithStateImages then StateImageOffset := FStateImages.Width + 2 else StateImageOffset := 0; if WithCheck then CheckOffset := FCheckImages.Height + 2 else CheckOffset := 0; AutoSpan := FHeader.UseColumns and (toAutoSpanColumns in FOptions.FAutoOptions); SimpleSelection := toSimpleDrawSelection in FOptions.FSelectionOptions; // This is the node to start with. Run := InternalGetNodeAt(0, MinY, False, CurrentTop); if Assigned(Run) then begin // The initial minimal left border is determined by the identation level of the node and is dynamically adjusted. if toShowRoot in FOptions.FPaintOptions then Dec(NodeRight, Integer((GetNodeLevel(Run) + 1) * FIndent) + FMargin) else Dec(NodeRight, Integer(GetNodeLevel(Run) * FIndent) + FMargin); // ----- main loop // Change selection depending on the node's rectangle being in the selection rectangle or not, but // touch only those nodes which overlap either the old selection rectangle or the new one but not both. repeat // Collect offsets for check, normal and state images. TextRight := NodeRight; if WithCheck and (Run.CheckType <> ctNone) then Dec(TextRight, CheckOffset); if WithImages and HasImage(Run, ikNormal, MainColumn) then Dec(TextRight, ImageOffset); if WithStateImages and HasImage(Run, ikState, MainColumn) then Dec(TextRight, StateImageOffset); // Ensure the node's height is determined. MeasureItemHeight(Canvas, Run); NextTop := CurrentTop + Integer(NodeHeight[Run]); // Simple selection allows to draw the selection rectangle anywhere. No intersection with node captions is // required. Only top and bottom bounds of the rectangle matter. if SimpleSelection then begin IsInOldRect := (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom); IsInNewRect := (NextTop > NewRect.Top) and (CurrentTop < NewRect.Bottom); end else begin // The left column border might be extended if column spanning is enabled. if AutoSpan then begin NextColumn := MainColumn; repeat Dummy := FHeader.FColumns.GetPreviousVisibleColumn(NextColumn); if (Dummy = InvalidColumn) or not ColumnIsEmpty(Run, Dummy) or (FHeader.FColumns[Dummy].BiDiMode = bdLeftToRight) then Break; NextColumn := Dummy; until False; if NextColumn = MainColumn then CurrentLeft := NodeLeft else FHeader.FColumns.GetColumnBounds(NextColumn, CurrentLeft, Dummy); end else CurrentLeft := NodeLeft; // Check if we need the node's width. This is the case when the node is not left aligned (in RTL context this // means actually right aligned) or the right border of the selection rectangle is to the left // of the right node border. if (TextRight > OldRect.Right) or (TextRight > NewRect.Right) or (Alignment <> taRightJustify) then begin NodeWidth := DoGetNodeWidth(Run, MainColumn); if NodeWidth >= (TextRight - CurrentLeft) then TextLeft := CurrentLeft else case Alignment of taLeftJustify: begin TextLeft := CurrentLeft; TextRight := TextLeft + NodeWidth; end; taCenter: begin TextLeft := (TextRight + CurrentLeft - NodeWidth) div 2; TextRight := TextLeft + NodeWidth; end; else // taRightJustify TextLeft := TextRight - NodeWidth; end; end else TextLeft := CurrentLeft; // Now determine whether we need to change the state. IsInOldRect := (OldRect.Right >= TextLeft) and (OldRect.Left <= TextRight) and (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom); IsInNewRect := (NewRect.Right >= TextLeft) and (NewRect.Left <= TextRight) and (NextTop > NewRect.Top) and (CurrentTop < NewRect.Bottom); end; if IsInOldRect xor IsInNewRect then begin Result := True; if DoSwitch then begin if vsSelected in Run.States then InternalRemoveFromSelection(Run) else InternalCacheNode(Run); end else begin if IsInNewRect then InternalCacheNode(Run) else InternalRemoveFromSelection(Run); end; end; CurrentTop := NextTop; // Get next visible node and update left node position. NextNode := GetNextVisibleNoInit(Run, True); if NextNode = nil then Break; Dec(NodeRight, CountLevelDifference(Run, NextNode) * Integer(FIndent)); Run := NextNode; until CurrentTop > MaxY; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ClearNodeBackground(const PaintInfo: TVTPaintInfo; UseBackground, Floating: Boolean; R: TRect); // Erases a node's background depending on what the application decides to do. // UseBackground determines whether or not to use the background picture, while Floating indicates // that R is given in coordinates of the small node bitmap or the superordinated target bitmap used in PaintTree. var BackColor: TColor; EraseAction: TItemEraseAction; Offset: TPoint; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'ClearNodeBackground');{$endif} with PaintInfo do begin EraseAction := eaDefault; BackColor := Brush.Color; if Floating then begin Offset := Point(-FEffectiveOffsetX, R.Top); OffsetRect(R, 0, -Offset.Y); end else Offset := Point(0, 0); DoBeforeItemErase(Canvas, Node, R, Backcolor, EraseAction); with Canvas do begin case EraseAction of eaNone: ; eaColor: begin // User has given a new background color. Brush.Color := BackColor; FillRect(R); end; else // eaDefault if UseBackground then begin if toStaticBackground in TreeOptions.PaintOptions then StaticBackground(FBackground.Bitmap, Canvas, Offset, R) else TileBackground(FBackground.Bitmap, Canvas, Offset, R); end else begin //clear the node background //note there's a bug in original VTV that can lead to wrong node paint //so, here the node is always cleared even if is selected Brush.Color := Self.Brush.Color; FillRect(R); {$ifdef DEBUG_VTV}Logger.SendColor([lcPaintDetails],'Clearing a node background - Brush.Color', Brush.Color);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Clearing Rectangle (R)', R);{$endif} if (poDrawSelection in PaintOptions) and (toFullRowSelect in FOptions.FSelectionOptions) and (vsSelected in Node.States) and not (toUseBlendedSelection in FOptions.PaintOptions) and not ((tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions) and IsWinVistaOrAbove) then begin {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails, lcDrag], 'Draw the background of a selected node');{$endif} if toShowHorzGridLines in FOptions.PaintOptions then Dec(R.Bottom); if Focused or (toPopupMode in FOptions.FPaintOptions) then begin Brush.Color := FColors.FocusedSelectionColor; Pen.Color := FColors.FocusedSelectionBorderColor; end else begin Brush.Color := FColors.UnfocusedSelectionColor; Pen.Color := FColors.UnfocusedSelectionBorderColor; end; with R do RoundRect(Left, Top, Right, Bottom, FSelectionCurveRadius, FSelectionCurveRadius); end; end; end; DoAfterItemErase(Canvas, Node, R); end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'ClearNodeBackground');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CompareNodePositions(Node1, Node2: PVirtualNode; ConsiderChildrenAbove: Boolean = False): Integer; // Tries hard and smart to quickly determine whether Node1's structural position is before Node2's position. // If ConsiderChildrenAbove is True, the nodes will be compared with their visual order in mind. // Returns 0 if Node1 = Node2, < 0 if Node1 is located before Node2 else > 0. var Run1, Run2: PVirtualNode; Level1, Level2: Cardinal; begin Assert(Assigned(Node1) and Assigned(Node2), 'Nodes must never be nil.'); if Node1 = Node2 then Result := 0 else begin if HasAsParent(Node1, Node2) then Result := IfThen(ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions), -1, 1) else if HasAsParent(Node2, Node1) then Result := IfThen(ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions), 1, -1) else begin // the given nodes are neither equal nor are they parents of each other, so go up to FRoot // for each node and compare the child indices of the top level parents // Note: neither Node1 nor Node2 can be FRoot at this point as this (a bit strange) circumstance would // be caught by the previous code. // start lookup at the same level Level1 := GetNodeLevel(Node1); Level2 := GetNodeLevel(Node2); Run1 := Node1; while Level1 > Level2 do begin Run1 := Run1.Parent; Dec(Level1); end; Run2 := Node2; while Level2 > Level1 do begin Run2 := Run2.Parent; Dec(Level2); end; // now go up until we find a common parent node (loop will safely stop at FRoot if the nodes // don't share a common parent) while Run1.Parent <> Run2.Parent do begin Run1 := Run1.Parent; Run2 := Run2.Parent; end; Result := Integer(Run1.Index) - Integer(Run2.Index); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DetermineLineImageAndSelectLevel(Node: PVirtualNode; out LineImage: TLineImage): Integer; // This method is used during paint cycles and initializes an array of line type IDs. These IDs are used to paint // the tree lines in front of the given node. // Additionally an initial count of selected parents is determined and returned which is used for specific painting. var X: Integer; Run: PVirtualNode; begin Result := 0; if toShowRoot in FOptions.FPaintOptions then X := 1 else X := 0; Run := Node; // Determine indentation level of top node. while Run.Parent <> FRoot do begin Inc(X); Run := Run.Parent; // Count selected nodes (FRoot is never selected). if vsSelected in Run.States then Inc(Result); end; // Set initial size of line index array, this will automatically initialized all entries to ltNone. SetLength(LineImage, X); // Only use lines if requested. if toShowTreeLines in FOptions.FPaintOptions then begin if toChildrenAbove in FOptions.FPaintOptions then begin Dec(X); if not HasVisiblePreviousSibling(Node) then begin if (Node.Parent <> FRoot) or HasVisibleNextSibling(Node) then LineImage[X] := ltBottomRight else LineImage[X] := ltRight; end else if (Node.Parent = FRoot) and (not HasVisibleNextSibling(Node)) then LineImage[X] := ltTopRight else LineImage[X] := ltTopDownRight; // Now go up to the root to determine the rest. Run := Node.Parent; while Run <> FRoot do begin Dec(X); if HasVisiblePreviousSibling(Run) then LineImage[X] := ltTopDown; Run := Run.Parent; end; end else begin // Start over parent traversal if necessary. Run := Node; if Run.Parent <> FRoot then begin // The very last image (the one immediately before the item label) is different. if HasVisibleNextSibling(Run) then LineImage[X - 1] := ltTopDownRight else LineImage[X - 1] := ltTopRight; Run := Run.Parent; // Now go up all parents. repeat if Run.Parent = FRoot then Break; Dec(X); if HasVisibleNextSibling(Run) then LineImage[X - 1] := ltTopDown else LineImage[X - 1] := ltNone; Run := Run.Parent; until False; end; // Prepare root level. Run points at this stage to a top level node. if (toShowRoot in FOptions.FPaintOptions) and (toShowTreeLines in FOptions.FPaintOptions) then begin // Is the top node a root node? if Run = Node then begin // First child gets the bottom-right bitmap if it isn't also the only child. if IsFirstVisibleChild(FRoot, Run) then // Is it the only child? if IsLastVisibleChild(FRoot, Run) then LineImage[0] := ltRight else LineImage[0] := ltBottomRight else // real last child if IsLastVisibleChild(FRoot, Run) then LineImage[0] := ltTopRight else LineImage[0] := ltTopDownRight; end else begin // No, top node is not a top level node. So we need different painting. if HasVisibleNextSibling(Run) then LineImage[0] := ltTopDown else LineImage[0] := ltNone; end; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DrawLineImage(const PaintInfo: TVTPaintInfo; X, Y, H, VAlign: Integer; Style: TVTLineType; Reverse: Boolean); // Draws (depending on Style) one of the 5 line types of the tree. // If Reverse is True then a right-to-left column is being drawn, hence horizontal lines must be mirrored. // X and Y describe the left upper corner of the line image rectangle, while H denotes its height (and width). var HalfWidth, TargetX: Integer; begin HalfWidth := Integer(FIndent) div 2; if Reverse then TargetX := 0 else TargetX := FIndent; with PaintInfo.Canvas do begin case Style of ltBottomRight: begin DrawDottedVLine(PaintInfo, Y + VAlign, Y + H, X + HalfWidth); DrawDottedHLine(PaintInfo, X + HalfWidth, X + TargetX, Y + VAlign); end; ltTopDown: DrawDottedVLine(PaintInfo, Y, Y + H, X + HalfWidth); ltTopDownRight: begin DrawDottedVLine(PaintInfo, Y, Y + H, X + HalfWidth); DrawDottedHLine(PaintInfo, X + HalfWidth, X + TargetX, Y + VAlign); end; ltRight: DrawDottedHLine(PaintInfo, X + HalfWidth, X + TargetX, Y + VAlign); ltTopRight: begin DrawDottedVLine(PaintInfo, Y, Y + VAlign, X + HalfWidth); DrawDottedHLine(PaintInfo, X + HalfWidth, X + TargetX, Y + VAlign); end; ltLeft: // left can also mean right for RTL context if Reverse then DrawDottedVLine(PaintInfo, Y, Y + H, X + Integer(FIndent)) else DrawDottedVLine(PaintInfo, Y, Y + H, X); ltLeftBottom: if Reverse then begin DrawDottedVLine(PaintInfo, Y, Y + H, X + Integer(FIndent)); DrawDottedHLine(PaintInfo, X, X + Integer(FIndent), Y + H); end else begin DrawDottedVLine(PaintInfo, Y, Y + H, X); DrawDottedHLine(PaintInfo, X, X + Integer(FIndent), Y + H); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.FindInPositionCache(Node: PVirtualNode; var CurrentPos: Cardinal): PVirtualNode; // Looks through the position cache and returns the node whose top position is the largest one which is smaller or equal // to the position of the given node. var L, H, I: Integer; begin L := 0; H := High(FPositionCache); while L <= H do begin I := (L + H) shr 1; if CompareNodePositions(FPositionCache[I].Node, Node) <= 0 then L := I + 1 else H := I - 1; end; if L = 0 then // High(FPositionCache) = -1 begin Result := nil; CurrentPos := 0; end else begin Result := FPositionCache[L - 1].Node; CurrentPos := FPositionCache[L - 1].AbsoluteTop; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.FindInPositionCache(Position: Cardinal; var CurrentPos: Cardinal): PVirtualNode; // Looks through the position cache and returns the node whose top position is the largest one which is smaller or equal // to the given vertical position. // The returned node does not necessarily occupy the given position but is the nearest one to start // iterating from to approach the real node for a given position. CurrentPos receives the actual position of the found // node which is needed for further iteration. var L, H, I: Integer; begin L := 0; H := High(FPositionCache); while L <= H do begin I := (L + H) shr 1; if FPositionCache[I].AbsoluteTop <= Position then L := I + 1 else H := I - 1; end; if L = 0 then // High(FPositionCache) = -1 begin Result := nil; CurrentPos := 0; end else begin Result := FPositionCache[L - 1].Node; CurrentPos := FPositionCache[L - 1].AbsoluteTop; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.FixupTotalCount(Node: PVirtualNode); // Called after loading a subtree from stream. The child count in each node is already set but not // their total count. var Child: PVirtualNode; begin // Initial total count is set to one on node creation. Child := Node.FirstChild; while Assigned(Child) do begin FixupTotalCount(Child); Inc(Node.TotalCount, Child.TotalCount); Child := Child.NextSibling; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.FixupTotalHeight(Node: PVirtualNode); // Called after loading a subtree from stream. The individual height of each node is set already, // but their total height needs an adjustment depending on their visibility state. var Child: PVirtualNode; begin // Initial total height is set to the node height on load. Child := Node.FirstChild; if vsExpanded in Node.States then begin while Assigned(Child) do begin FixupTotalHeight(Child); if vsVisible in Child.States then Inc(Node.TotalHeight, Child.TotalHeight); Child := Child.NextSibling; end; end else begin // The node is collapsed, so just update the total height of its child nodes. while Assigned(Child) do begin FixupTotalHeight(Child); Child := Child.NextSibling; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetBottomNode: PVirtualNode; begin Result := InternalGetNodeAt(0, ClientHeight - 1); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetCheckedCount: Integer; var Node: PVirtualNode; begin Result := 0; Node := GetFirstChecked; while Assigned(Node) do begin Inc(Result); Node := GetNextChecked(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetCheckState(Node: PVirtualNode): TCheckState; begin Result := Node.CheckState; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetCheckType(Node: PVirtualNode): TCheckType; begin Result := Node.CheckType; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetChildCount(Node: PVirtualNode): Cardinal; begin if (Node = nil) or (Node = FRoot) then Result := FRoot.ChildCount else Result := Node.ChildCount; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetChildrenInitialized(Node: PVirtualNode): Boolean; begin Result := not (vsHasChildren in Node.States) or (Node.ChildCount > 0); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetCutCopyCount: Integer; var Node: PVirtualNode; begin Result := 0; Node := GetFirstCutCopy; while Assigned(Node) do begin Inc(Result); Node := GetNextCutCopy(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetDisabled(Node: PVirtualNode): Boolean; begin Result := Assigned(Node) and (vsDisabled in Node.States); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetDragManager: IVTDragManager; // Returns the internal drag manager interface. If this does not yet exist then it is created here. begin if FDragManager = nil then begin FDragManager := DoCreateDragManager; if FDragManager = nil then FDragManager := TVTDragManager.Create(Self); end; Result := FDragManager; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetExpanded(Node: PVirtualNode): Boolean; begin if Assigned(Node) then Result := vsExpanded in Node.States else Result := False; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFullyVisible(Node: PVirtualNode): Boolean; // Determines whether the given node has the visibility flag set as well as all its parents are expanded. begin Assert(Assigned(Node), 'Invalid parameter.'); Result := vsVisible in Node.States; if Result and (Node <> FRoot) then Result := VisiblePath[Node]; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetHasChildren(Node: PVirtualNode): Boolean; begin if Assigned(Node) then Result := vsHasChildren in Node.States else Result := vsHasChildren in FRoot.States; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetMultiline(Node: PVirtualNode): Boolean; begin Result := Assigned(Node) and (Node <> FRoot) and (vsMultiline in Node.States); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNodeHeight(Node: PVirtualNode): Cardinal; begin if Assigned(Node) and (Node <> FRoot) then begin if toVariableNodeHeight in FOptions.FMiscOptions then begin if not (vsInitialized in Node.States) then InitNode(Node); // Ensure the node's height is determined. MeasureItemHeight(Canvas, Node); end; Result := Node.NodeHeight end else Result := 0; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNodeParent(Node: PVirtualNode): PVirtualNode; begin if Assigned(Node) and (Node.Parent <> FRoot) then Result := Node.Parent else Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetOffsetXY: TPoint; begin Result := Point(FOffsetX, FOffsetY); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetRootNodeCount: Cardinal; begin Result := FRoot.ChildCount; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetSelected(Node: PVirtualNode): Boolean; begin Result := Assigned(Node) and (vsSelected in Node.States); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetTopNode: PVirtualNode; begin Result := InternalGetNodeAt(0, 0); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetTotalCount: Cardinal; begin Inc(FUpdateCount); try ValidateNode(FRoot, True); finally Dec(FUpdateCount); end; // The root node itself doesn't count as node. Result := FRoot.TotalCount - 1; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetVerticalAlignment(Node: PVirtualNode): Byte; begin Result := Node.Align; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetVisible(Node: PVirtualNode): Boolean; // Determines if the given node is marked as being visible. begin if Node = nil then Node := FRoot; if not (vsInitialized in Node.States) then InitNode(Node); Result := vsVisible in Node.States; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetVisiblePath(Node: PVirtualNode): Boolean; // Determines if all parents of the given node are expanded and have the visibility flag set. begin Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameters.'); // FRoot is always expanded repeat Node := Node.Parent; until (Node = FRoot) or not (vsExpanded in Node.States) or not (vsVisible in Node.States); Result := Node = FRoot; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.HandleClickSelection(LastFocused, NewNode: PVirtualNode; Shift: TShiftState; DragPending: Boolean); // Handles multi-selection with mouse click. begin // Ctrl key down if ssCtrlOS in Shift then begin if ssShift in Shift then begin SelectNodes(FRangeAnchor, NewNode, True); Invalidate; end else begin if not (toSiblingSelectConstraint in FOptions.SelectionOptions) then FRangeAnchor := NewNode; // Delay selection change if a drag operation is pending. // Otherwise switch selection state here. if DragPending then DoStateChange([tsToggleFocusedSelection]) else if vsSelected in NewNode.States then RemoveFromSelection(NewNode) else AddToSelection(NewNode); end; end else // Shift key down if ssShift in Shift then begin if FRangeAnchor = nil then FRangeAnchor := FRoot.FirstChild; // select node range if Assigned(FRangeAnchor) then begin SelectNodes(FRangeAnchor, NewNode, False); Invalidate; end; end else begin // any other case if not (vsSelected in NewNode.States) then begin AddToSelection(NewNode); InvalidateNode(NewNode); end; // assign new reference item FRangeAnchor := NewNode; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.HandleDrawSelection(X, Y: Integer): Boolean; // Handles multi-selection with a focus rectangle. // Result is True if something changed in selection. var OldRect, NewRect: TRect; MainColumn: TColumnIndex; MaxValue: Integer; // limits of a node and its text NodeLeft, NodeRight: Integer; // alignment and directionality CurrentBidiMode: TBidiMode; CurrentAlignment: TAlignment; begin Result := False; // Selection changes are only done if the user drew a selection rectangle large // enough to exceed the threshold. if (FRoot.TotalCount > 1) and (tsDrawSelecting in FStates) then begin // Effective handling of node selection is done by using two rectangles stored in FSelectRec. OldRect := OrderRect(FLastSelRect); NewRect := OrderRect(FNewSelRect); ClearTempCache; MainColumn := FHeader.MainColumn; // Alignment and bidi mode determine where the node text is located within a node. if MainColumn <= NoColumn then begin CurrentBidiMode := BidiMode; CurrentAlignment := Alignment; end else begin CurrentBidiMode := FHeader.FColumns[MainColumn].BidiMode; CurrentAlignment := FHeader.FColumns[MainColumn].Alignment; end; // Determine initial left border of first node (take column reordering into account). if FHeader.UseColumns then begin // The mouse coordinates don't include any horizontal scrolling hence take this also // out from the returned column position. NodeLeft := FHeader.FColumns[MainColumn].Left - FEffectiveOffsetX; NodeRight := NodeLeft + FHeader.FColumns[MainColumn].Width; end else begin NodeLeft := 0; NodeRight := ClientWidth; end; if CurrentBidiMode = bdLeftToRight then Result := CollectSelectedNodesLTR(MainColumn, NodeLeft, NodeRight, CurrentAlignment, OldRect, NewRect) else Result := CollectSelectedNodesRTL(MainColumn, NodeLeft, NodeRight, CurrentAlignment, OldRect, NewRect); end; if Result then begin // Do some housekeeping if there was a change. MaxValue := PackArray(FSelection, FSelectionCount); if MaxValue > -1 then begin FSelectionCount := MaxValue; SetLength(FSelection, FSelectionCount); end; if FTempNodeCount > 0 then begin AddToSelection(FTempNodeCache, FTempNodeCount); ClearTempCache; end; Change(nil); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.HasVisibleNextSibling(Node: PVirtualNode): Boolean; // Helper method to determine if the given node has a visible next sibling. This is needed to // draw correct tree lines. begin // Check if there is a sibling at all. Result := Assigned(Node.NextSibling); if Result then begin repeat Node := Node.NextSibling; Result := vsVisible in Node.States; until Result or (Node.NextSibling = nil); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.HasVisiblePreviousSibling(Node: PVirtualNode): Boolean; // Helper method to determine if the given node has a visible previous sibling. This is needed to // draw correct tree lines. begin // Check if there is a sibling at all. Result := Assigned(Node.PrevSibling); if Result then begin repeat Node := Node.PrevSibling; Result := vsVisible in Node.States; until Result or (Node.PrevSibling = nil); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ImageListChange(Sender: TObject); begin if not (csDestroying in ComponentState) then Invalidate; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InitializeFirstColumnValues(var PaintInfo: TVTPaintInfo); // Determines initial index, position and cell size of the first visible column. begin PaintInfo.Column := FHeader.FColumns.GetFirstVisibleColumn; with FHeader.FColumns, PaintInfo do begin if Column > NoColumn then begin CellRect.Right := CellRect.Left + Items[Column].Width; Position := Items[Column].Position; end else Position := 0; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InitRootNode(OldSize: Cardinal = 0); // Reinitializes the root node. var NewSize: Cardinal; begin NewSize := TreeNodeSize + FTotalInternalDataSize; if FRoot = nil then FRoot := AllocMem(NewSize) else begin ReallocMem(FRoot, NewSize); FillChar(PAnsiChar(PAnsiChar(FRoot) + OldSize)^, NewSize - OldSize, 0); end; with FRoot^ do begin // Indication that this node is the root node. PrevSibling := FRoot; NextSibling := FRoot; Parent := Pointer(Self); States := [vsInitialized, vsExpanded, vsHasChildren, vsVisible]; TotalHeight := FDefaultNodeHeight; TotalCount := 1; TotalHeight := FDefaultNodeHeight; NodeHeight := FDefaultNodeHeight; Align := 50; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InterruptValidation; var WasValidating: Boolean; begin DoStateChange([tsStopValidation], [tsUseCache]); {$ifdef EnableThreadSupport} // Check the worker thread existance. It might already be gone (usually on destruction of the last tree). if Assigned(WorkerThread) then begin WasValidating := (tsValidating in FStates); WorkerThread.RemoveTree(Self); if WasValidating then DoStateChange([tsValidationNeeded]); end; {$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.IsFirstVisibleChild(Parent, Node: PVirtualNode): Boolean; // Helper method to check if Node is the same as the first visible child of Parent. var Run: PVirtualNode; begin // Find first visible child. Run := Parent.FirstChild; while Assigned(Run) and not (vsVisible in Run.States) do Run := Run.NextSibling; Result := Assigned(Run) and (Run = Node); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.IsLastVisibleChild(Parent, Node: PVirtualNode): Boolean; // Helper method to check if Node is the same as the last visible child of Parent. var Run: PVirtualNode; begin // Find last visible child. Run := Parent.LastChild; while Assigned(Run) and not (vsVisible in Run.States) do Run := Run.PrevSibling; Result := Assigned(Run) and (Run = Node); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.LimitPaintingToArea(Canvas: TCanvas; ClipRect: TRect; VisibleRegion: HRGN = 0); // Limits further painting onto the given canvas to the given rectangle. // VisibleRegion is an optional region which can be used to limit drawing further. var ClipRegion: HRGN; begin // Regions expect their coordinates in device coordinates, hence we have to transform the region rectangle. LPtoDP(Canvas.Handle, ClipRect, 2); ClipRegion := CreateRectRgnIndirect(ClipRect); if VisibleRegion <> 0 then CombineRgn(ClipRegion, ClipRegion, VisibleRegion, RGN_AND); SelectClipRgn(Canvas.Handle, ClipRegion); DeleteObject(ClipRegion); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.LoadPanningCursors; begin with Screen do begin Cursors[crVT_MOVEALL]:=LoadCursorFromLazarusResource('VT_MOVEALL'); Cursors[crVT_MOVEEW]:=LoadCursorFromLazarusResource('VT_MOVEEW'); Cursors[crVT_MOVENS]:=LoadCursorFromLazarusResource('VT_MOVENS'); Cursors[crVT_MOVENW]:=LoadCursorFromLazarusResource('VT_MOVENW'); Cursors[crVT_MOVESW]:=LoadCursorFromLazarusResource('VT_MOVESW'); Cursors[crVT_MOVESE]:=LoadCursorFromLazarusResource('VT_MOVESE'); Cursors[crVT_MOVENE]:=LoadCursorFromLazarusResource('VT_MOVENE'); Cursors[crVT_MOVEW]:=LoadCursorFromLazarusResource('VT_MOVEW'); Cursors[crVT_MOVEE]:=LoadCursorFromLazarusResource('VT_MOVEE'); Cursors[crVT_MOVEN]:=LoadCursorFromLazarusResource('VT_MOVEN'); Cursors[crVT_MOVES]:=LoadCursorFromLazarusResource('VT_MOVES'); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.MakeNewNode: PVirtualNode; var Size: Cardinal; begin Size := TreeNodeSize; if not (csDesigning in ComponentState) then begin // Make sure FNodeDataSize is valid. if FNodeDataSize = -1 then ValidateNodeDataSize(FNodeDataSize); // Take record alignment into account. Inc(Size, FNodeDataSize); end; Result := AllocMem(Size + FTotalInternalDataSize); // Fill in some default values. with Result^ do begin TotalCount := 1; TotalHeight := FDefaultNodeHeight; NodeHeight := FDefaultNodeHeight; States := [vsVisible]; Align := 50; end; end; {$ifdef PACKARRAYPASCAL} function TBaseVirtualTree.PackArray(const TheArray: TNodeArray; Count: Integer): Integer; var Source, Dest: ^PVirtualNode; ConstOne: PtrInt; begin Source := Pointer(TheArray); ConstOne := 1; Result := 0; // Do the fastest scan possible to find the first entry while (Count <> 0) and {not Odd(NativeInt(Source^))} (PtrInt(Source^) and ConstOne = 0) do begin Inc(Result); Inc(Source); Dec(Count); end; if Count <> 0 then begin Dest := Source; repeat // Skip odd entries if {not Odd(NativeInt(Source^))} PtrInt(Source^) and ConstOne = 0 then begin Dest^ := Source^; Inc(Result); Inc(Dest); end; Inc(Source); // Point to the next entry Dec(Count); until Count = 0; end; end; {$else} //---------------------------------------------------------------------------------------------------------------------- {$IMPLICITEXCEPTIONS OFF} function TBaseVirtualTree.PackArray(TheArray: TNodeArray; Count: Integer): Integer; assembler; // Removes all entries from the selection array which are no longer in use. The selection array must be sorted for this // algo to work. Values which must be removed are marked with bit 0 (LSB) set. This little trick works because memory // is always allocated DWORD aligned. Since the selection array must be sorted while determining the entries to be // removed it is much more efficient to increment the entry in question instead of setting it to nil (which would break // the ordered appearance of the list). // // On enter EAX contains self reference, EDX the address to TheArray and ECX Count // The returned value is the number of remaining entries in the array, so the caller can reallocate (shorten) // the selection array if needed or -1 if nothing needs to be changed. asm PUSH EBX PUSH EDI PUSH ESI MOV ECX, EDX //fpc: count is in EDX. Move to ECX MOV ESI, [EBP+8] //fpc: TheArray is in EBP+8 MOV EDX, -1 JCXZ @@Finish // Empty list? INC EDX // init remaining entries counter MOV EDI, ESI // source and destination point to the list memory MOV EBX, 1 // use a register instead of immediate operant to check against @@PreScan: TEST [ESI], EBX // do the fastest scan possible to find the first entry // which must be removed JNZ @@DoMainLoop INC EDX ADD ESI, 4 DEC ECX JNZ @@PreScan JMP @@Finish @@DoMainLoop: MOV EDI, ESI @@MainLoop: TEST [ESI], EBX // odd entry? JNE @@Skip // yes, so skip this one MOVSD // else move the entry to new location INC EDX // count the moved entries DEC ECX JNZ @@MainLoop // do it until all entries are processed JMP @@Finish @@Skip: ADD ESI, 4 // point to the next entry DEC ECX JNZ @@MainLoop // do it until all entries are processed @@Finish: MOV EAX, EDX // prepare return value POP ESI POP EDI POP EBX end; {$IMPLICITEXCEPTIONS ON} {$endif} //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.PrepareBitmaps(NeedButtons, NeedLines: Boolean); // initializes the contents of the internal bitmaps const LineBitsDotted: array [0..8] of Word = ($55, $AA, $55, $AA, $55, $AA, $55, $AA, $55); LineBitsSolid: array [0..7] of Word = (0, 0, 0, 0, 0, 0, 0, 0); var PatternBitmap: HBITMAP; Bits: Pointer; Size: TSize; {$ifdef ThemeSupport} //Theme: HTHEME; R: TRect; const TVP_HOTGLYPH = 4; {$endif ThemeSupport} //--------------- local function -------------------------------------------- procedure FillBitmap (ABitmap: TBitmap); begin with ABitmap, Canvas do begin ABitmap.Width := Size.cx; ABitmap.Height := Size.cy; {$Ifdef ThemeSupport} if IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions) then begin if (FHeader.FMainColumn > NoColumn) and not (coParentColor in FHeader.FColumns[FHeader.FMainColumn].FOptions) then Brush.Color := FHeader.FColumns[FHeader.FMainColumn].Color else Brush.Color := Self.Brush.Color; end else begin {$EndIf ThemeSupport} MaskHandle := 0; Transparent := True; TransparentColor := clFuchsia; Brush.Color := clFuchsia; {$Ifdef ThemeSupport} end; {$EndIf ThemeSupport} FillRect(Rect(0, 0, ABitmap.Width, ABitmap.Height)); end; end; //--------------- end local function ---------------------------------------- begin Size.cx := 9; Size.cy := 9; {$ifdef ThemeSupport} //todo { if tsUseThemes in FStates then begin Theme := OpenThemeData(Handle, 'TREEVIEW'); if IsWinVistaOrAbove and (toUseExplorerTheme in FOptions.FPaintOptions) then begin R := Rect(0, 0, 100, 100); GetThemePartSize(Theme, FPlusBM.Canvas.Handle, TVP_GLYPH, GLPS_OPENED, @R, TS_TRUE, Size); end; end else Theme := 0; } {$endif ThemeSupport} if NeedButtons then begin with FMinusBM, Canvas do begin // box is always of odd size FillBitmap(FMinusBM); FillBitmap(FHotMinusBM); if not (IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions)) then begin if FButtonStyle = bsTriangle then begin Brush.Color := clBlack; Pen.Color := clBlack; Polygon([Point(0, 2), Point(8, 2), Point(4, 6)]); end else begin // Button style is rectangular. Now ButtonFillMode determines how to fill the interior. if FButtonFillMode in [fmTreeColor, fmWindowColor, fmTransparent] then begin case FButtonFillMode of fmTreeColor: Brush.Color := Self.Brush.Color; fmWindowColor: Brush.Color := clWindow; end; Pen.Color := FColors.TreeLineColor; Rectangle(0, 0, Width, Height); Pen.Color := Self.Font.Color; MoveTo(2, Width div 2); LineTo(Width - 2 , Width div 2); end else FMinusBM.LoadFromLazarusResource('VT_XPBUTTONMINUS'); FHotMinusBM.Canvas.Draw(0, 0, FMinusBM); end; end; end; with FPlusBM, Canvas do begin FillBitmap(FPlusBM); FillBitmap(FHotPlusBM); if not (IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions)) then begin if FButtonStyle = bsTriangle then begin Brush.Color := clBlack; Pen.Color := clBlack; Polygon([Point(2, 0), Point(6, 4), Point(2, 8)]); end else begin // Button style is rectangular. Now ButtonFillMode determines how to fill the interior. if FButtonFillMode in [fmTreeColor, fmWindowColor, fmTransparent] then begin case FButtonFillMode of fmTreeColor: Brush.Color := Self.Brush.Color; fmWindowColor: Brush.Color := clWindow; end; Pen.Color := FColors.TreeLineColor; Rectangle(0, 0, Width, Height); Pen.Color := Self.Font.Color; MoveTo(2, Width div 2); LineTo(Width - 2 , Width div 2); MoveTo(Width div 2, 2); LineTo(Width div 2, Width - 2); end else FPlusBM.LoadFromLazarusResource('VT_XPBUTTONPLUS'); FHotPlusBM.Canvas.Draw(0, 0, FPlusBM); end; end; end; {$ifdef ThemeSupport} //todo // Overwrite glyph images if theme is active. { if (tsUseThemes in FStates) and (Theme <> 0) then begin R := Rect(0, 0, Size.cx, Size.cy); DrawThemeBackground(Theme, FPlusBM.Canvas.Handle, TVP_GLYPH, GLPS_CLOSED, R, nil); DrawThemeBackground(Theme, FMinusBM.Canvas.Handle, TVP_GLYPH, GLPS_OPENED, R, nil); if IsWinVistaOrAbove and (toUseExplorerTheme in FOptions.FPaintOptions) then begin DrawThemeBackground(Theme, FHotPlusBM.Canvas.Handle, TVP_HOTGLYPH, GLPS_CLOSED, R, nil); DrawThemeBackground(Theme, FHotMinusBM.Canvas.Handle, TVP_HOTGLYPH, GLPS_OPENED, R, nil); end else begin FHotPlusBM.Canvas.Draw(0, 0, FPlusBM); FHotMinusBM.Canvas.Draw(0, 0, FMinusBM); end; end; } {$endif ThemeSupport} end; if NeedLines then begin if FDottedBrush <> 0 then DeleteObject(FDottedBrush); case FLineStyle of lsDotted: Bits := @LineBitsDotted; lsSolid: Bits := @LineBitsSolid; else // lsCustomStyle Bits := @LineBitsDotted; DoGetLineStyle(Bits); end; PatternBitmap := CreateBitmap(8, 8, 1, 1, Bits); FDottedBrush := CreatePatternBrush(PatternBitmap); DeleteObject(PatternBitmap); end; {$ifdef ThemeSupport} // if Theme <> 0 then // CloseThemeData(Theme); {$endif} end; //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetAlignment(const Value: TAlignment); begin if FAlignment <> Value then begin FAlignment := Value; if not (csLoading in ComponentState) then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetAnimationDuration(const Value: Cardinal); begin FAnimationDuration := Value; if FAnimationDuration = 0 then Exclude(FOptions.FAnimationOptions, toAnimatedToggle) else Include(FOptions.FAnimationOptions, toAnimatedToggle); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetBackground(const Value: TPicture); begin FBackground.Assign(Value); Invalidate; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetBackgroundOffset(const Index, Value: Integer); begin case Index of 0: if FBackgroundOffsetX <> Value then begin FBackgroundOffsetX := Value; Invalidate; end; 1: if FBackgroundOffsetY <> Value then begin FBackgroundOffsetY := Value; Invalidate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- { procedure TBaseVirtualTree.SetBorderStyle(Value: TBorderStyle); begin if FBorderStyle <> Value then begin FBorderStyle := Value; RecreateWnd; end; end; } //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetBottomNode(Node: PVirtualNode); var Run: PVirtualNode; R: TRect; begin if Assigned(Node) then begin // make sure all parents of the node are expanded Run := Node.Parent; while Run <> FRoot do begin if not (vsExpanded in Run.States) then ToggleNode(Run); Run := Run.Parent; end; R := GetDisplayRect(Node, FHeader.MainColumn, True); DoSetOffsetXY(Point(FOffsetX, FOffsetY + ClientHeight - R.Top - Integer(NodeHeight[Node])), [suoRepaintScrollbars, suoUpdateNCArea]); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetBottomSpace(const Value: Cardinal); begin if FBottomSpace <> Value then begin FBottomSpace := Value; UpdateVerticalScrollbar(True); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetButtonFillMode(const Value: TVTButtonFillMode); begin if FButtonFillMode <> Value then begin FButtonFillMode := Value; if not (csLoading in ComponentState) then begin PrepareBitmaps(True, False); if HandleAllocated then Invalidate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetButtonStyle(const Value: TVTButtonStyle); begin if FButtonStyle <> Value then begin FButtonStyle := Value; if not (csLoading in ComponentState) then begin PrepareBitmaps(True, False); if HandleAllocated then Invalidate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetCheckImageKind(Value: TCheckImageKind); begin if FCheckImageKind <> Value then begin FCheckImageKind := Value; if toCheckSupport in FOptions.FMiscOptions then UpdateCheckImageList; if HandleAllocated and (FUpdateCount = 0) and not (csLoading in ComponentState) then InvalidateRect(Handle, nil, False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetCheckState(Node: PVirtualNode; Value: TCheckState); begin if (Node.CheckState <> Value) and not (vsDisabled in Node.States) and DoChecking(Node, Value) then DoCheckClick(Node, Value); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetCheckType(Node: PVirtualNode; Value: TCheckType); begin if (Node.CheckType <> Value) and not (toReadOnly in FOptions.FMiscOptions) then begin Node.CheckType := Value; Node.CheckState := csUncheckedNormal; // For check boxes with tri-state check box parents we have to initialize differently. if (toAutoTriStateTracking in FOptions.FAutoOptions) and (Value in [ctCheckBox, ctTriStateCheckBox]) and (Node.Parent <> FRoot) then begin if not (vsInitialized in Node.Parent.States) then InitNode(Node.Parent); if (Node.Parent.CheckType = ctTriStateCheckBox) and (Node.Parent.CheckState in [csUncheckedNormal, csCheckedNormal]) then CheckState[Node] := Node.Parent.CheckState; end; InvalidateNode(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetChildCount(Node: PVirtualNode; NewChildCount: Cardinal); // Changes a node's child structure to accomodate the new child count. This is used to add or delete // child nodes to/from the end of the node's child list. To insert or delete a specific node a separate // routine is used. var Remaining: Cardinal; Index: Cardinal; Child: PVirtualNode; Count: Integer; NewHeight: Integer; begin if not (toReadOnly in FOptions.FMiscOptions) then begin if Node = nil then Node := FRoot; if NewChildCount = 0 then DeleteChildren(Node) else begin // If nothing changed then do nothing. if NewChildCount <> Node.ChildCount then begin InterruptValidation; NewHeight := 0; if NewChildCount > Node.ChildCount then begin Remaining := NewChildCount - Node.ChildCount; Count := Remaining; // New nodes to add. if Assigned(Node.LastChild) then Index := Node.LastChild.Index + 1 else begin Index := 0; Include(Node.States, vsHasChildren); end; Node.States := Node.States - [vsAllChildrenHidden, vsHeightMeasured]; // New nodes are by default always visible, so we don't need to check the visibility. while Remaining > 0 do begin Child := MakeNewNode; Child.Index := Index; Child.PrevSibling := Node.LastChild; if Assigned(Node.LastChild) then Node.LastChild.NextSibling := Child; Child.Parent := Node; Node.LastChild := Child; if Node.FirstChild = nil then Node.FirstChild := Child; Dec(Remaining); Inc(Index); // The actual node height will later be computed once it is clear // whether this node has a variable node height or not. Inc(NewHeight, Child.NodeHeight); end; if vsExpanded in Node.States then begin AdjustTotalHeight(Node, NewHeight, True); if FullyVisible[Node] then Inc(Integer(FVisibleCount), Count); end; AdjustTotalCount(Node, Count, True); Node.ChildCount := NewChildCount; if (FUpdateCount = 0) and (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then Sort(Node, FHeader.FSortColumn, FHeader.FSortDirection, True); InvalidateCache; end else begin // Nodes have to be deleted. Remaining := Node.ChildCount - NewChildCount; while Remaining > 0 do begin DeleteNode(Node.LastChild); Dec(Remaining); end; end; if FUpdateCount = 0 then begin ValidateCache; UpdateScrollBars(True); Invalidate; end; if Node = FRoot then StructureChange(nil, crChildAdded) else StructureChange(Node, crChildAdded); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetClipboardFormats(const Value: TClipboardFormats); var I: Integer; begin // Add string by string instead doing an Assign or AddStrings because the list may return -1 for // invalid entries which cause trouble for the standard implementation. FClipboardFormats.Clear; for I := 0 to Value.Count - 1 do FClipboardFormats.Add(Value[I]); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetColors(const Value: TVTColors); begin FColors.Assign(Value); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetCustomCheckImages(const Value: TBitmap); begin if FCustomCheckImages <> Value then begin if Assigned(FCustomCheckImages) then begin // Reset the internal check image list reference too, if necessary. if FCheckImages = FCustomCheckImages then FCheckImages := nil; end; FCustomCheckImages := Value; // Check if currently custom check images are active. if FCheckImageKind = ckCustom then FCheckImages := Value; if not (csLoading in ComponentState) then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetDefaultNodeHeight(Value: Cardinal); begin if Value = 0 then Value := 18; if FDefaultNodeHeight <> Value then begin DoStateChange([tsNeedScale]); Inc(Integer(FRoot.TotalHeight), Integer(Value) - Integer(FDefaultNodeHeight)); Inc(SmallInt(FRoot.NodeHeight), Integer(Value) - Integer(FDefaultNodeHeight)); FDefaultNodeHeight := Value; InvalidateCache; if (FUpdateCount = 0) and HandleAllocated and not (csLoading in ComponentState) then begin ValidateCache; UpdateScrollBars(True); ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, True); Invalidate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetDisabled(Node: PVirtualNode; Value: Boolean); begin if Assigned(Node) and (Value xor (vsDisabled in Node.States)) then begin if Value then Include(Node.States, vsDisabled) else Exclude(Node.States, vsDisabled); if FUpdateCount = 0 then InvalidateNode(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetExpanded(Node: PVirtualNode; Value: Boolean); begin if Assigned(Node) and (Node <> FRoot) and (Value xor (vsExpanded in Node.States)) then ToggleNode(Node); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetFocusedColumn(Value: TColumnIndex); begin if (FFocusedColumn <> Value) and DoFocusChanging(FFocusedNode, FFocusedNode, FFocusedColumn, Value) then begin CancelEditNode; InvalidateColumn(FFocusedColumn); InvalidateColumn(Value); FFocusedColumn := Value; if Assigned(FFocusedNode) and not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) then begin if ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions)) then InvalidateNode(FFocusedNode); end; if Assigned(FDropTargetNode) then InvalidateNode(FDropTargetNode); DoFocusChange(FFocusedNode, FFocusedColumn); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetFocusedNode(Value: PVirtualNode); var WasDifferent: Boolean; begin WasDifferent := Value <> FFocusedNode; DoFocusNode(Value, True); // Do change event only if there was actually a change. if WasDifferent and (FFocusedNode = Value) then DoFocusChange(FFocusedNode, FFocusedColumn); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetFullyVisible(Node: PVirtualNode; Value: Boolean); // This method ensures that a node is visible and all its parent nodes are expanded and also visible // if Value is True. Otherwise the visibility flag of the node is reset but the expand state // of the parent nodes stays untouched. begin Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter'); IsVisible[Node] := Value; if Value then begin repeat Node := Node.Parent; if Node = FRoot then Break; if not (vsExpanded in Node.States) then ToggleNode(Node); if not (vsVisible in Node.States) then IsVisible[Node] := True; until False; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetHasChildren(Node: PVirtualNode; Value: Boolean); begin if Assigned(Node) and not (toReadOnly in FOptions.FMiscOptions) then begin if Value then Include(Node.States, vsHasChildren) else begin Exclude(Node.States, vsHasChildren); DeleteChildren(Node); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetHeader(const Value: TVTHeader); begin FHeader.Assign(Value); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetImages(const Value: TCustomImageList); begin if FImages <> Value then begin if Assigned(FImages) then begin FImages.UnRegisterChanges(FImageChangeLink); FImages.RemoveFreeNotification(Self); end; FImages := Value; if Assigned(FImages) then begin FImages.RegisterChanges(FImageChangeLink); FImages.FreeNotification(Self); end; if not (csLoading in ComponentState) then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetIndent(Value: Cardinal); begin if FIndent <> Value then begin FIndent := Value; if not (csLoading in ComponentState) and (FUpdateCount = 0) and HandleAllocated then begin UpdateScrollBars(True); Invalidate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetLineMode(const Value: TVTLineMode); begin if FLineMode <> Value then begin FLineMode := Value; if HandleAllocated and not (csLoading in ComponentState) then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetLineStyle(const Value: TVTLineStyle); begin if FLineStyle <> Value then begin FLineStyle := Value; if not (csLoading in ComponentState) then begin PrepareBitmaps(False, True); if HandleAllocated then Invalidate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetMargin(Value: Integer); begin if FMargin <> Value then begin FMargin := Value; if HandleAllocated and not (csLoading in ComponentState) then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetMultiline(Node: PVirtualNode; const Value: Boolean); begin if Assigned(Node) and (Node <> FRoot) then if Value <> (vsMultiline in Node.States) then begin if Value then Include(Node.States, vsMultiline) else Exclude(Node.States, vsMultiline); if FUpdateCount = 0 then InvalidateNode(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetNodeAlignment(const Value: TVTNodeAlignment); begin if FNodeAlignment <> Value then begin FNodeAlignment := Value; if HandleAllocated and not (csReading in ComponentState) then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetNodeDataSize(Value: Integer); var LastRootCount: Cardinal; begin if Value < -1 then Value := -1; if FNodeDataSize <> Value then begin FNodeDataSize := Value; if not (csLoading in ComponentState) and not (csDesigning in ComponentState) then begin LastRootCount := FRoot.ChildCount; Clear; SetRootNodeCount(LastRootCount); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetNodeHeight(Node: PVirtualNode; Value: Cardinal); var Difference: Integer; begin if Assigned(Node) and (Node <> FRoot) and (Node.NodeHeight <> Value) and not (toReadOnly in FOptions.FMiscOptions) then begin Difference := Integer(Value) - Integer(Node.NodeHeight); Node.NodeHeight := Value; AdjustTotalHeight(Node, Difference, True); // If an edit operation is currently active then update the editors boundaries as well. UpdateEditBounds; // Stay away from touching the node cache while it is being validated. if not (tsValidating in FStates) and FullyVisible[Node] then begin InvalidateCache; if FUpdateCount = 0 then begin ValidateCache; InvalidateToBottom(Node); UpdateScrollBars(True); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetNodeParent(Node: PVirtualNode; const Value: PVirtualNode); begin if Assigned(Node) and Assigned(Value) and (Node.Parent <> Value) then MoveTo(Node, Value, amAddChildLast, False); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetOffsetX(const Value: Integer); begin DoSetOffsetXY(Point(Value, FOffsetY), DefaultScrollUpdateFlags); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetOffsetXY(const Value: TPoint); begin DoSetOffsetXY(Value, DefaultScrollUpdateFlags); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetOffsetY(const Value: Integer); begin DoSetOffsetXY(Point(FOffsetX, Value), DefaultScrollUpdateFlags); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetOptions(const Value: TCustomVirtualTreeOptions); begin FOptions.Assign(Value); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetRootNodeCount(Value: Cardinal); begin // Don't set the root node count until all other properties (in particular the OnInitNode event) have been set. if csLoading in ComponentState then begin FRoot.ChildCount := Value; DoStateChange([tsNeedRootCountUpdate]); end else if FRoot.ChildCount <> Value then begin BeginUpdate; InterruptValidation; SetChildCount(FRoot, Value); EndUpdate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetScrollBarOptions(Value: TScrollBarOptions); begin FScrollBarOptions.Assign(Value); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetSearchOption(const Value: TVTIncrementalSearch); begin if FIncrementalSearch <> Value then begin FIncrementalSearch := Value; if FIncrementalSearch = isNone then begin KillTimer(Handle, SearchTimer); FSearchBuffer := ''; FLastSearchNode := nil; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetSelected(Node: PVirtualNode; Value: Boolean); begin if not FSelectionLocked and Assigned(Node) and (Node <> FRoot) and (Value xor (vsSelected in Node.States)) then begin if Value then begin if FSelectionCount = 0 then FRangeAnchor := Node else if not (toMultiSelect in FOptions.FSelectionOptions) then ClearSelection; AddToSelection(Node); // Make sure there is a valid column selected (if there are columns at all). if ((FFocusedColumn < 0) or not (coVisible in FHeader.Columns[FFocusedColumn].Options)) and (FHeader.MainColumn > NoColumn) then if ([coVisible, coAllowFocus] * FHeader.Columns[FHeader.MainColumn].Options = [coVisible, coAllowFocus]) then FFocusedColumn := FHeader.MainColumn else FFocusedColumn := FHeader.Columns.GetFirstVisibleColumn(True); if FRangeAnchor = nil then FRangeAnchor := Node; end else begin RemoveFromSelection(Node); if FSelectionCount = 0 then ResetRangeAnchor; end; if FullyVisible[Node] then InvalidateNode(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetSelectionCurveRadius(const Value: Cardinal); begin if FSelectionCurveRadius <> Value then begin FSelectionCurveRadius := Value; if HandleAllocated and not (csLoading in ComponentState) then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetStateImages(const Value: TCustomImageList); begin if FStateImages <> Value then begin if Assigned(FStateImages) then begin FStateImages.UnRegisterChanges(FStateChangeLink); FStateImages.RemoveFreeNotification(Self); end; FStateImages := Value; if Assigned(FStateImages) then begin FStateImages.RegisterChanges(FStateChangeLink); FStateImages.FreeNotification(Self); end; if HandleAllocated and not (csLoading in ComponentState) then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetTextMargin(Value: Integer); begin if FTextMargin <> Value then begin FTextMargin := Value; if not (csLoading in ComponentState) then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetTopNode(Node: PVirtualNode); var R: TRect; Run: PVirtualNode; begin if Assigned(Node) then begin // make sure all parents of the node are expanded Run := Node.Parent; while Run <> FRoot do begin if not (vsExpanded in Run.States) then ToggleNode(Run); Run := Run.Parent; end; R := GetDisplayRect(Node, FHeader.MainColumn, True); //lclheader if hoVisible in FHeader.Options then Dec(R.Top, FHeader.Height); SetOffsetY(FOffsetY - R.Top); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetUpdateState(Updating: Boolean); begin // The check for visibility is necessary otherwise the tree is automatically shown when // updating is allowed. As this happens internally the VCL does not get notified and // still assumes the control is hidden. This results in weird "cannot focus invisible control" errors. //lcl todo if Visible and HandleAllocated and (FUpdateCount = 0) then SendMessage(Handle, WM_SETREDRAW, Ord(not Updating), 0); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetVerticalAlignment(Node: PVirtualNode; Value: Byte); begin if Value > 100 then Value := 100; if Node.Align <> Value then begin Node.Align := Value; if FullyVisible[Node] then InvalidateNode(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetVisible(Node: PVirtualNode; Value: Boolean); // Sets the visibility style of the given node according to Value. var NeedUpdate: Boolean; begin Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.'); if Value <> (vsVisible in Node.States) then begin InterruptValidation; NeedUpdate := False; if Value then begin Include(Node.States, vsVisible); if vsExpanded in Node.Parent.States then AdjustTotalHeight(Node.Parent, Node.TotalHeight, True); if VisiblePath[Node] then begin Inc(FVisibleCount, 1 + CountVisibleChildren(Node)); NeedUpdate := True; end; // Update the hidden children flag of the parent. // Since this node is now visible we simply have to remove the flag. Exclude(Node.Parent.States, vsAllChildrenHidden); end else begin Exclude(Node.States, vsVisible); if vsExpanded in Node.Parent.States then AdjustTotalHeight(Node.Parent, -Integer(Node.TotalHeight), True); if VisiblePath[Node] then begin Dec(FVisibleCount, 1 + CountVisibleChildren(Node)); NeedUpdate := True; end; if FUpdateCount = 0 then DetermineHiddenChildrenFlag(Node.Parent) else Include(FStates, tsUpdateHiddenChildrenNeeded) end; InvalidateCache; if NeedUpdate and (FUpdateCount = 0) then begin ValidateCache; UpdateScrollBars(True); Invalidate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetVisiblePath(Node: PVirtualNode; Value: Boolean); // If Value is True then all parent nodes of Node are expanded. begin Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.'); if Value then begin repeat Node := Node.Parent; if Node = FRoot then Break; if not (vsExpanded in Node.States) then ToggleNode(Node); until False; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.StaticBackground(Source: TBitmap; Target: TCanvas; const Offset: TPoint; const R: TRect); // Draws the given source graphic so that it stays static in the given rectangle which is relative to the target bitmap. // The graphic is aligned so that it always starts at the upper left corner of the target canvas. // Offset gives the position of the target window as a possible superordinated surface. const DST = $00AA0029; // Ternary Raster Operation - Destination unchanged var PicRect: TRect; AreaRect: TRect; DrawRect: TRect; begin // clear background Target.Brush.Color := Brush.Color; Target.FillRect(R); // Picture rect in relation to client viewscreen. PicRect := Rect(FBackgroundOffsetX, FBackgroundOffsetY, FBackgroundOffsetX + Source.Width, FBackgroundOffsetY + Source.Height); // Area to be draw in relation to client viewscreen. AreaRect := Rect(Offset.X + R.Left, Offset.Y + R.Top, Offset.X + R.Right, Offset.Y + R.Bottom); // If picture falls in AreaRect, return intersection (DrawRect). if IntersectRect(DrawRect, PicRect, AreaRect) then begin // Draw portion of image which falls in canvas area. if Source.Transparent then begin // Leave transparent area as destination unchanged (DST), copy non-transparent areas to canvas (SRCCOPY). with DrawRect do MaskBlt(Target.Handle, Left - Offset.X, Top - Offset.Y, (Right - Offset.X) - (Left - Offset.X), (Bottom - Offset.Y) - (Top - Offset.Y), Source.Canvas.Handle, Left - PicRect.Left, DrawRect.Top - PicRect.Top, Source.MaskHandle, Left - PicRect.Left, Top - PicRect.Top, MakeROP4(DST, SRCCOPY)); end else begin // copy image to destination with DrawRect do BitBlt(Target.Handle, Left - Offset.X, Top - Offset.Y, (Right - Offset.X) - (Left - Offset.X), (Bottom - Offset.Y) - (Top - Offset.Y) + R.Top, Source.Canvas.Handle, Left - PicRect.Left, DrawRect.Top - PicRect.Top, SRCCOPY); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.TileBackground(Source: TBitmap; Target: TCanvas; const Offset: TPoint; R: TRect); // Draws the given source graphic so that it tiles into the given rectangle which is relative to the target bitmap. // The graphic is aligned so that it always starts at the upper left corner of the target canvas. // Offset gives the position of the target window in an possible superordinated surface. var SourceX, SourceY, TargetX, DeltaY: Integer; begin with Target do begin SourceY := (R.Top + Offset.Y + FBackgroundOffsetY) mod Source.Height; // Always wrap the source coordinates into positive range. if SourceY < 0 then SourceY := Source.Height + SourceY; // Tile image vertically until target rect is filled. while R.Top < R.Bottom do begin SourceX := (R.Left + Offset.X + FBackgroundOffsetX) mod Source.Width; // always wrap the source coordinates into positive range if SourceX < 0 then SourceX := Source.Width + SourceX; TargetX := R.Left; // height of strip to draw DeltaY := Min(R.Bottom - R.Top, Source.Height - SourceY); // tile the image horizontally while TargetX < R.Right do begin BitBlt(Handle, TargetX, R.Top, Min(R.Right - TargetX, Source.Width - SourceX), DeltaY, Source.Canvas.Handle, SourceX, SourceY, SRCCOPY); Inc(TargetX, Source.Width - SourceX); SourceX := 0; end; Inc(R.Top, Source.Height - SourceY); SourceY := 0; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ToggleCallback(Step, StepSize: Integer; Data: Pointer): Boolean; var Column: TColumnIndex; Run: TRect; SecondaryStepSize: Integer; //--------------- local functions ------------------------------------------- procedure EraseLine; var LocalBrush: HBRUSH; begin with TToggleAnimationData(Data^), FHeader.FColumns do begin // Iterate through all columns and erase background in their local color. // LocalBrush is a brush in the color of the particular column. Column := GetFirstVisibleColumn; while (Column > InvalidColumn) and (Run.Left < ClientWidth) do begin GetColumnBounds(Column, Run.Left, Run.Right); if coParentColor in Items[Column].FOptions then FillRect(DC, Run, Brush) else begin LocalBrush := CreateSolidBrush(ColorToRGB(Items[Column].Color)); FillRect(DC, Run, LocalBrush); DeleteObject(LocalBrush); end; Column := GetNextVisibleColumn(Column); end; end; end; //--------------------------------------------------------------------------- procedure DoScrollUp(DC: HDC; Brush: HBRUSH; Area: TRect; Steps: Integer); begin {$ifndef INCOMPLETE_WINAPI} ScrollDC(DC, 0, -Steps, Area, Area, 0, nil); {$endif} if Step = 0 then if not FHeader.UseColumns then FillRect(DC, Rect(Area.Left, Area.Bottom - Steps - 1, Area.Right, Area.Bottom), Brush) else begin Run := Rect(Area.Left, Area.Bottom - Steps - 1, Area.Right, Area.Bottom); EraseLine; end; end; //--------------------------------------------------------------------------- procedure DoScrollDown(DC: HDC; Brush: HBRUSH; Area: TRect; Steps: Integer); begin {$ifndef INCOMPLETE_WINAPI} ScrollDC(DC, 0, Steps, Area, Area, 0, nil); {$endif} if Step = 0 then if not FHeader.UseColumns then FillRect(DC, Rect(Area.Left, Area.Top, Area.Right, Area.Top + Steps + 1), Brush) else begin Run := Rect(Area.Left, Area.Top, Area.Right, Area.Top + Steps + 1); EraseLine; end; end; //--------------- end local functions --------------------------------------- begin Result := True; if StepSize > 0 then begin SecondaryStepSize := 0; with TToggleAnimationData(Data^) do begin if Mode1 <> tamNoScroll then begin if Mode1 = tamScrollUp then DoScrollUp(DC, Brush, R1, StepSize) else DoScrollDown(DC, Brush, R1, StepSize); if (Mode2 <> tamNoScroll) and (ScaleFactor > 0) then begin // As this routine is able to scroll two independent areas at once, the missing StepSize is // computed in that case. To ensure the maximal accuracy the rounding error is accumulated. SecondaryStepSize := Round((StepSize + MissedSteps) * ScaleFactor); MissedSteps := MissedSteps + StepSize * ScaleFactor - SecondaryStepSize; end; end else SecondaryStepSize := StepSize; if Mode2 <> tamNoScroll then if Mode2 = tamScrollUp then DoScrollUp(DC, Brush, R2, SecondaryStepSize) else DoScrollDown(DC, Brush, R2, SecondaryStepSize); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CMColorChange(var Message: TLMessage); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'CMColorChange');{$endif} if not (csLoading in ComponentState) then begin PrepareBitmaps(True, False); if HandleAllocated then Invalidate; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'CMColorChange');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CMBiDiModeChanged(var Message: TLMessage); begin inherited; if UseRightToLeftAlignment then FEffectiveOffsetX := Integer(FRangeX) - ClientWidth + FOffsetX else FEffectiveOffsetX := -FOffsetX; if FEffectiveOffsetX < 0 then FEffectiveOffsetX := 0; if toAutoBidiColumnOrdering in FOptions.FAutoOptions then FHeader.FColumns.ReorderColumns(UseRightToLeftAlignment); FHeader.Invalidate(nil); {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FEffectiveOffsetX after CMBidiModeChanged',FEffectiveOffsetX);{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CMDenySubclassing(var Message: TLMessage); // If a Windows XP Theme Manager component is used in the application it will try to subclass all controls which do not // explicitly deny this. Virtual Treeview knows how to handle XP themes so it does not need subclassing. begin Message.Result := 1; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoDragMsg(ADragMessage: TDragMessage; APosition: TPoint; ADragObject: TDragObject; ATarget: TControl; ADocking: Boolean): LRESULT; var S: TObject; KeyState: LongWord; P: TPoint; Formats: TFormatArray; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DoDragMsg');{$endif} S := ADragObject; Formats := nil; // Let the ancestor handle dock operations. if S is TDragDockObject then inherited else begin // We need an extra check for the control drag object as there might be other objects not derived from // this class (e.g. TActionDragObject). if not (tsUserDragObject in FStates) and (S is TDragControlObject) then S := (S as TDragControlObject).Control; case ADragMessage of dmDragEnter, dmDragLeave, dmDragMove: begin if ADragMessage = dmDragEnter then DoStateChange([tsVCLDragging]); if ADragMessage = dmDragLeave then DoStateChange([], [tsVCLDragging]); if ADragMessage = dmDragMove then with ScreenToClient(APosition) do DoAutoScroll(X, Y); KeyState := 0; // Alt key will be queried by the KeysToShiftState function in DragOver. if GetKeyState(VK_SHIFT) < 0 then KeyState := KeyState or MK_SHIFT; if GetKeyState(VK_CONTROL) < 0 then KeyState := KeyState or MK_CONTROL; // Allowed drop effects are simulated for VCL dd. FVCLDragEffect := DROPEFFECT_MOVE or DROPEFFECT_COPY; DragOver(S, KeyState, TDragState(ADragMessage), APosition, FVCLDragEffect); Result := LRESULT(FVCLDragEffect); FLastVCLDragTarget := FDropTargetNode; if (ADragMessage = dmDragLeave) and Assigned(FDropTargetNode) then begin InvalidateNode(FDropTargetNode); FDropTargetNode := nil; end; end; dmDragDrop: begin KeyState := 0; // Alt key will be queried by the KeysToShiftState function in DragOver if GetKeyState(VK_SHIFT) < 0 then KeyState := KeyState or MK_SHIFT; if GetKeyState(VK_CONTROL) < 0 then KeyState := KeyState or MK_CONTROL; // allowed drop effects are simulated for VCL dd, // replace target node with cached node from other VCL dd messages if Assigned(FDropTargetNode) then InvalidateNode(FDropTargetNode); FDropTargetNode := FLastVCLDragTarget; P := ScreenToClient(APosition); DoDragDrop(S, nil, Formats, KeysToShiftState(KeyState), P, FVCLDragEffect, FLastDropMode); if Assigned(FDropTargetNode) then begin InvalidateNode(FDropTargetNode); FDropTargetNode := nil; end; end; dmFindTarget: begin Result := LRESULT(ControlAtPos(ScreenToClient(APosition), False)); if Result = 0 then Result := LRESULT(Self); // This is a reliable place to check whether VCL drag has // really begun. if tsVCLDragPending in FStates then DoStateChange([tsVCLDragging], [tsVCLDragPending, tsEditPending, tsClearPending]); end; end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DoDragMsg');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CMFontChanged(var Message: TLMessage); var HeaderMessage: TLMessage; begin inherited; if not (csLoading in ComponentState) then PrepareBitmaps(True, False); HeaderMessage.Msg := CM_PARENTFONTCHANGED; HeaderMessage.WParam := 0; HeaderMessage.LParam := 0; HeaderMessage.Result := 0; FHeader.HandleMessage(HeaderMessage); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CMHintShow(var Message: TCMHintShow); // Determines hint message (tooltip) and out-of-hint rect. // Note: A special handling is needed here because we cannot pass wide strings back to the caller. // I had to introduce the hint data record anyway so we can use this to pass the hint string. // We still need to set a dummy hint string in the message to make the VCL showing the hint window. var NodeRect: TRect; SpanColumn, Dummy, ColLeft, ColRight: Integer; HitInfo: THitInfo; ShowOwnHint: Boolean; IsFocusedOrEditing: Boolean; ParentForm: TCustomForm; BottomRightCellContentMargin: TPoint; LineBreakStyle: TVTTooltipLineBreakStyle; begin with Message do begin Result := 1; if PtInRect(FLastHintRect, HintInfo.CursorPos) then Exit; // Determine node for which to show hint/tooltip. with HintInfo^ do GetHitTestInfoAt(CursorPos.X, CursorPos.Y, True, HitInfo); // Make sure a hint is only shown if the tree or at least its parent form is active. // Active editing is ok too as long as we don't want the hint for the current edit node. if IsEditing then IsFocusedOrEditing := HitInfo.HitNode <> FFocusedNode else begin IsFocusedOrEditing := Focused; ParentForm := GetParentForm(Self); if Assigned(ParentForm) then IsFocusedOrEditing := ParentForm.Focused or Application.Active; end; if (GetCapture = 0) and ShowHint and not (Dragging or IsMouseSelecting) and ([tsScrolling] * FStates = []) and (FHeader.States = []) and IsFocusedOrEditing then begin with HintInfo^ do begin Result := 0; ShowOwnHint := False; // First check whether there is a header hint to show. if FHeader.UseColumns and (hoShowHint in FHeader.FOptions) and FHeader.InHeader(CursorPos) then begin CursorRect := FHeaderRect; // Convert the cursor rectangle into real client coordinates. OffsetRect(CursorRect, 0, -Integer(FHeader.FHeight)); HitInfo.HitColumn := FHeader.FColumns.GetColumnAndBounds(CursorPos, CursorRect.Left, CursorRect.Right); // align the vertical hint position on the bottom bound of the header, but // avoid overlapping of mouse cursor and hint HintPos.Y := Max(HintPos.Y, ClientToScreen(Point(0, CursorRect.Bottom)).Y); // Note: the test for the left mouse button in ControlState might cause problems whenever the VCL does not // realize when the button is released. This, for instance, happens when doing OLE drag'n drop and // cancel this with ESC. if (HitInfo.HitColumn > -1) and not (csLButtonDown in ControlState) then begin FHintData.DefaultHint := FHeader.FColumns[HitInfo.HitColumn].FHint; if FHintData.DefaultHint <> '' then ShowOwnHint := True else Result := 1; end else Result := 1; end else begin // Default mode is handled as would the tree be a usual VCL control (no own hint window necessary). if FHintMode = hmDefault then HintStr := GetShortHint(Hint) else begin if Assigned(HitInfo.HitNode) and (HitInfo.HitColumn > InvalidColumn) then begin // A draw tree should only display a hint when at least its OnGetHintSize // event handler is assigned. if Self is TCustomVirtualDrawTree then begin FHintData.HintRect := Rect(0, 0, 0, 0); with Self as TCustomVirtualDrawTree do DoGetHintSize(HitInfo.HitNode, HitInfo.HitColumn, FHintData.HintRect); ShowOwnHint := not IsRectEmpty(FHintData.HintRect); end else // For string trees a decision about showing the hint or not is based // on the hint string (if it is empty then no hint is shown). ShowOwnHint := True; if ShowOwnHint then begin if HitInfo.HitColumn > NoColumn then begin FHeader.FColumns.GetColumnBounds(HitInfo.HitColumn, ColLeft, ColRight); // The right column border might be extended if column spanning is enabled. if toAutoSpanColumns in FOptions.FAutoOptions then begin SpanColumn := HitInfo.HitColumn; repeat Dummy := FHeader.FColumns.GetNextVisibleColumn(SpanColumn); if (Dummy = InvalidColumn) or not ColumnIsEmpty(HitInfo.HitNode, Dummy) then Break; SpanColumn := Dummy; until False; if SpanColumn <> HitInfo.HitColumn then FHeader.FColumns.GetColumnBounds(SpanColumn, Dummy, ColRight); end; end else begin ColLeft := 0; ColRight := ClientWidth; end; FHintData.DefaultHint := ''; if FHintMode <> hmTooltip then begin // Node specific hint text. CursorRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, False); CursorRect.Left := ColLeft; CursorRect.Right := ColRight; // Align the vertical hint position on the bottom bound of the node, but // avoid overlapping of mouse cursor and hint. HintPos.Y := Max(HintPos.Y, ClientToScreen(CursorRect.BottomRight).Y) + 2; end else begin // Tool tip to show. This means the full caption of the node must be displayed. if vsMultiline in HitInfo.HitNode.States then begin if hiOnItemLabel in HitInfo.HitPositions then begin ShowOwnHint := True; NodeRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, True, False); end; end else begin NodeRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, True, True, True); BottomRightCellContentMargin := DoGetCellContentMargin(HitInfo.HitNode, HitInfo.HitColumn, ccmtBottomRightOnly); ShowOwnHint := (HitInfo.HitColumn > InvalidColumn) and PtInRect(NodeRect, CursorPos) and (CursorPos.X <= ColRight) and (CursorPos.X >= ColLeft) and ( // Show hint also if the node text is partially out of the client area. // "ColRight - 1", since the right column border is not part of this cell. ( (NodeRect.Right + BottomRightCellContentMargin.X) > Min(ColRight - 1, ClientWidth) ) or (NodeRect.Left < Max(ColLeft, 0)) or ( (NodeRect.Bottom + BottomRightCellContentMargin.Y) > ClientHeight ) or (NodeRect.Top < 0) ); end; if ShowOwnHint then begin // Node specific hint text given will be retrieved when needed. FHintData.DefaultHint := ''; HintPos := ClientToScreen(Point(NodeRect.Left, NodeRect.Top)); CursorRect := NodeRect; end else // nothing to show Result := 1; end; end else Result := 1; // Avoid hint if this is a draw tree returning an empty hint rectangle. end else begin // No node so fall back to control's hint (if indicated) or show nothing. if FHintMode = hmHintAndDefault then HintStr := GetShortHint(Hint) else Result := 1; end; end; end; {$ifdef DEBUG_VTV}Logger.Send([lcHint], 'ShowOwnHint: %s Result: %d', [BoolToStr(ShowOwnHint, True), Result]);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcHint], 'CursorRect', CursorRect);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcHint], 'CursorPos', CursorPos);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcHint], 'HintMaxWidth', HintMaxWidth);{$endif} // If hint must be show and is not the control's hint then get the hint // from the node or from the DefaultHint if ShowOwnHint and (Result = 0) then begin LineBreakStyle := hlbDefault; FLastHintRect := CursorRect; if Length(FHintData.DefaultHint) > 0 then HintStr := FHintData.DefaultHint else if FHintMode = hmToolTip then HintStr := DoGetNodeToolTip(HitInfo.HitNode, HitInfo.HitColumn, LineBreakStyle) else HintStr := DoGetNodeHint(HitInfo.HitNode, HitInfo.HitColumn, LineBreakStyle); // Determine actual line break style depending on what was returned by the methods and what's in the node. if (LineBreakStyle = hlbDefault) and Assigned(HitInfo.HitNode) and (vsMultiline in HitInfo.HitNode.States) then LineBreakStyle := hlbForceMultiLine; if LineBreakStyle = hlbForceMultiLine then begin // NodeRect is already calculated for ToolTip if FHintMode <> hmTooltip then NodeRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, True, False); HintMaxWidth := NodeRect.Right - NodeRect.Left; end; HintWindowClass := GetHintWindowClass; FHintData.Tree := Self; FHintData.Column := HitInfo.HitColumn; FHintData.Node := HitInfo.HitNode; FHintData.HintInfo := HintInfo; HintData := @FHintData; end else FLastHintRect := Rect(0, 0, 0, 0); end; // Remind that a hint is about to show. if Result = 0 then DoStateChange([tsHint]) else DoStateChange([], [tsHint]); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CMMouseLeave(var Message: TLMessage); var LeaveStates: TVirtualTreeStates; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'CMMouseLeave');{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcMessages],'FCurrentHotNode',hexStr(FCurrentHotNode));{$endif} // Reset the last used hint rectangle in case the mouse enters the window within the bounds if Assigned(FHintData.Tree) then FHintData.Tree.FLastHintRect := Rect(0, 0, 0, 0); LeaveStates := [tsHint]; if [tsWheelPanning, tsWheelScrolling] * FStates = [] then begin if HandleAllocated then KillTimer(Handle, ScrollTimer); LeaveStates := LeaveStates + [tsScrollPending, tsScrolling]; end; DoStateChange([], LeaveStates); if Assigned(FCurrentHotNode) then begin DoHotChange(FCurrentHotNode, nil); if (toHotTrack in FOptions.PaintOptions) or (toCheckSupport in FOptions.FMiscOptions) then InvalidateNode(FCurrentHotNode); FCurrentHotNode := nil; end; Header.FColumns.FDownIndex := NoColumn; Header.FColumns.FHoverIndex := NoColumn; inherited CMMouseLeave(Message); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'CMMouseLeave');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CMMouseWheel(var Message: TLMMouseEvent); var ScrollAmount: Integer; ScrollLines: DWORD; RTLFactor: Integer; WheelFactor: Double; begin //todo: rename to WM* {$ifdef DEBUG_VTV}Logger.EnterMethod([lcScroll],'CMMouseWheel');{$endif} StopWheelPanning; inherited WMMouseWheel(Message); if Message.Result = 0 then begin with Message do begin Result := 1; WheelFactor := WheelDelta / WHEEL_DELTA; if (FRangeY > Cardinal(ClientHeight)) and (not (ssShift in State)) then begin {$ifdef DEBUG_VTV}Logger.Send([lcScroll],'Scroll Vertical - WheelDelta', WheelDelta);{$endif} // Scroll vertically if there's something to scroll... if ssCtrlOS in State then ScrollAmount := Trunc(WheelFactor * ClientHeight) else begin SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, @ScrollLines, 0); if ScrollLines = WHEEL_PAGESCROLL then ScrollAmount := Integer(Trunc(WheelFactor * ClientHeight)) else ScrollAmount := Integer(Trunc(WheelFactor * ScrollLines * FDefaultNodeHeight)); end; SetOffsetY(FOffsetY + ScrollAmount); end else begin // ...else scroll horizontally if there's something to scroll. if UseRightToLeftAlignment then RTLFactor := -1 else RTLFactor := 1; if ssCtrlOS in State then ScrollAmount := Trunc(WheelFactor * (ClientWidth - FHeader.Columns.GetVisibleFixedWidth)) else begin SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, @ScrollLines, 0); ScrollAmount := Trunc(WheelFactor * ScrollLines * FHeader.Columns.GetScrollWidth); end; SetOffsetX(FOffsetX + RTLFactor * ScrollAmount); end; end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcScroll],'CMMouseWheel');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- {$ifdef EnableNativeTVM} procedure TBaseVirtualTree.TVMGetItem(var Message: TLMessage); // Screen reader support function. The method returns information about a particular node. const StateMask = TVIS_STATEIMAGEMASK or TVIS_OVERLAYMASK or TVIS_EXPANDED or TVIS_DROPHILITED or TVIS_CUT or TVIS_SELECTED or TVIS_FOCUSED; var Item: PTVItemEx; Node: PVirtualNode; Ghosted: Boolean; ImageIndex: Integer; R: TRect; Text: String; {$ifndef UNICODE} ANSIText: ANSIString; {$endif} begin // We can only return valid data if a nodes reference is given. Item := Pointer(Message.LParam); Message.Result := Ord(((Item.mask and TVIF_HANDLE) <> 0) and Assigned(Item.hItem)); if Message.Result = 1 then begin Node := Pointer(Item.hItem); // Child count requested? if (Item.mask and TVIF_CHILDREN) <> 0 then Item.cChildren := Node.ChildCount; // Index for normal image requested? if (Item.mask and TVIF_IMAGE) <> 0 then begin Item.iImage := -1; DoGetImageIndex(Node, ikNormal, -1, Ghosted, Item.iImage); end; // Index for selected image requested? if (Item.mask and TVIF_SELECTEDIMAGE) <> 0 then begin Item.iSelectedImage := -1; DoGetImageIndex(Node, ikSelected, -1, Ghosted, Item.iSelectedImage); end; // State info requested? if (Item.mask and TVIF_STATE) <> 0 then begin // Everything, which is possible is returned. Item.stateMask := StateMask; Item.state := 0; if Node = FFocusedNode then Item.state := Item.state or TVIS_FOCUSED; if vsSelected in Node.States then Item.state := Item.state or TVIS_SELECTED; if vsCutOrCopy in Node.States then Item.state := Item.state or TVIS_CUT; if Node = FDropTargetNode then Item.state := Item.state or TVIS_DROPHILITED; if vsExpanded in Node.States then Item.state := Item.state or TVIS_EXPANDED; // Construct state image and overlay image indices. They are one based, btw. // and zero means there is no image. ImageIndex := -1; DoGetImageIndex(Node, ikState, -1, Ghosted, ImageIndex); Item.state := Item.state or Byte(IndexToStateImageMask(ImageIndex + 1)); ImageIndex := -1; DoGetImageIndex(Node, ikOverlay, -1, Ghosted, ImageIndex); Item.state := Item.state or Byte(IndexToOverlayMask(ImageIndex + 1)); end; // Node caption requested? if (Item.mask and TVIF_TEXT) <> 0 then begin GetTextInfo(Node, -1, Font, R, Text); {$ifdef UNICODE} StrLCopy(Item.pszText, PChar(Text), Item.cchTextMax - 1); Item.pszText[Length(Text)] := #0; {$else} // Convert the Unicode implicitely to ANSI using the current locale. ANSIText := Text; StrLCopy(Item.pszText, PChar(ANSIText), Item.cchTextMax - 1); Item.pszText[Length(ANSIText)] := #0; {$endif} end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.TVMGetItemRect(var Message: TLMessage); // Screen read support function. This method returns a node's display rectangle. var TextOnly: Boolean; Node: PVirtualNode; begin // The lparam member is used two-way. On enter it contains a pointer to the item (node). // On exit it is to be considered as pointer to a rectangle structure. Node := Pointer(Pointer(Message.LParam)^); Message.Result := Ord(IsVisible[Node]); if Message.Result <> 0 then begin TextOnly := Message.WParam <> 0; PRect(Message.LParam)^ := GetDisplayRect(Node, -1, TextOnly); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.TVMGetNextItem(var Message: TLMessage); // Screen read support function. This method returns a node depending on the requested case. var Node: PVirtualNode; begin // Start with a nil result. Message.Result := 0; Node := Pointer(Message.LParam); case Message.WParam of TVGN_CARET: Message.Result := Integer(FFocusedNode); TVGN_CHILD: if Assigned(Node) then Message.Result := Integer(GetFirstChild(Node)); TVGN_DROPHILITE: Message.Result := Integer(FDropTargetNode); TVGN_FIRSTVISIBLE: Message.Result := Integer(GetFirstVisible(nil, True)); TVGN_LASTVISIBLE: Message.Result := Integer(GetLastVisible(nil, True)); TVGN_NEXT: if Assigned(Node) then Message.Result := Integer(GetNextSibling(Node)); TVGN_NEXTVISIBLE: if Assigned(Node) then Message.Result := Integer(GetNextVisible(Node, True)); TVGN_PARENT: if Assigned(Node) and (Node <> FRoot) and (Node.Parent <> FRoot) then Message.Result := Integer(Node.Parent); TVGN_PREVIOUS: if Assigned(Node) then Message.Result := Integer(GetPreviousSibling(Node)); TVGN_PREVIOUSVISIBLE: if Assigned(Node) then Message.Result := Integer(GetPreviousVisible(Node, True)); TVGN_ROOT: Message.Result := Integer(GetFirst); end; end; {$endif} //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMCancelMode(var Message: TLMNoParams); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMCancelMode');{$endif} // Clear any transient state. KillTimer(Handle, ExpandTimer); KillTimer(Handle, EditTimer); KillTimer(Handle, ScrollTimer); KillTimer(Handle, SearchTimer); FSearchBuffer := ''; FLastSearchNode := nil; DoStateChange([], [tsClearPending, tsEditPending, tsOLEDragPending, tsVCLDragPending, tsDrawSelecting, tsDrawSelPending, tsIncrementalSearching]); //lcl does not has a inherited procedure //inherited WMCancelMode(Message); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMCancelMode');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMChangeState(var Message: TLMessage); var EnterStates, LeaveStates: TVirtualTreeStates; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMChangeState');{$endif} EnterStates := []; if csStopValidation in TChangeStates(Byte(Message.WParam)) then Include(EnterStates, tsStopValidation); if csUseCache in TChangeStates(Byte(Message.WParam)) then Include(EnterStates, tsUseCache); if csValidating in TChangeStates(Byte(Message.WParam)) then Include(EnterStates, tsValidating); if csValidationNeeded in TChangeStates(Byte(Message.WParam)) then Include(EnterStates, tsValidationNeeded); LeaveStates := []; if csStopValidation in TChangeStates(Byte(Message.LParam)) then Include(LeaveStates, tsStopValidation); if csUseCache in TChangeStates(Byte(Message.LParam)) then Include(LeaveStates, tsUseCache); if csValidating in TChangeStates(Byte(Message.LParam)) then Include(LeaveStates, tsValidating); if csValidationNeeded in TChangeStates(Byte(Message.LParam)) then Include(LeaveStates, tsValidationNeeded); DoStateChange(EnterStates, LeaveStates); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMChangeState');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMChar(var Message: TLMChar); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMChar');{$endif} if tsIncrementalSearchPending in FStates then begin HandleIncrementalSearch(Message.CharCode); DoStateChange([], [tsIncrementalSearchPending]); end; inherited WMChar(Message); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMChar');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMContextMenu(var Message: TLMContextMenu); // This method is called when a popup menu is about to be displayed. // We have to cancel some pending states here to avoid interferences. //lcl: handle mouse up here because MouseUp is not called when popup is show var HitInfo: THitInfo; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMContextMenu');{$endif} DoStateChange([], [tsClearPending, tsEditPending, tsOLEDragPending, tsVCLDragPending]); {$ifdef ContextMenuBeforeMouseUp} if Assigned(PopupMenu) then begin if FHeader.FStates = [] then begin Application.CancelHint; if IsMouseSelecting then begin // Reset selection state already here, before the inherited handler opens the default menu. DoStateChange([], [tsDrawSelecting, tsDrawSelPending]); Invalidate; end; inherited WMContextMenu(Message); if (toRightClickSelect in FOptions.FSelectionOptions) then begin // get information about the hit GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseUp(0, HitInfo); end; end; end else inherited WMContextMenu(Message); {$else} if not (tsPopupMenuShown in FStates) then inherited WMContextMenu(Message); {$endif} {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMContextMenu');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMCopy(var Message: TLMNoParams); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMCopy');{$endif} CopyToClipboard; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMCopy');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMCut(var Message: TLMNoParams); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMCut');{$endif} CutToClipboard; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMCut');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMEnable(var Message: TLMNoParams); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMEnable');{$endif} //LCL does not has inherited WMEnable //inherited WMEnable(Message); RedrawWindow(Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_NOERASE or RDW_NOCHILDREN); {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMEnable');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMEraseBkgnd(var Message: TLMEraseBkgnd); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcEraseBkgnd],'WMEraseBkgnd');{$endif} Message.Result := 1; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcEraseBkgnd],'WMEraseBkgnd');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMGetDlgCode(var Message: TLMNoParams); begin {$ifdef DEBUG_VTV}Logger.Send([lcMessages],'WMGetDlgCode');{$endif} Message.Result := DLGC_WANTCHARS or DLGC_WANTARROWS; if FWantTabs then Message.Result := Message.Result or DLGC_WANTTAB; end; //---------------------------------------------------------------------------------------------------------------------- {$ifdef EnableAccessible} procedure TBaseVirtualTree.WMGetObject(var Message: TLMessage); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMGetObject');{$endif} if GetAccessibilityFactory <> nil then begin // Create the IAccessibles for the tree view and tree view items, if necessary. if FAccessible = nil then FAccessible := GetAccessibilityFactory.CreateIAccessible(Self); if FAccessibleItem = nil then FAccessibleItem := GetAccessibilityFactory.CreateIAccessible(Self); if Cardinal(Message.LParam) = OBJID_CLIENT then if Assigned(Accessible) then Message.Result := LresultFromObject(IID_IAccessible, Message.WParam, FAccessible) else Message.Result := 0; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMGetObject');{$endif} end; {$endif} //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMHScroll(var Message: TLMHScroll); //--------------- local functions ------------------------------------------- function GetRealScrollPosition: Integer; var SI: TScrollInfo; Code: Integer; begin SI.cbSize := SizeOf(TScrollInfo); SI.fMask := SIF_TRACKPOS; Code := SB_HORZ; {$ifdef UseFlatScrollbars} FlatSB_GetScrollInfo(Handle, Code, SI); {$else} GetScrollInfo(Handle, Code, SI); {$endif UseFlatScrollbars} Result := SI.nTrackPos; end; //--------------- end local functions --------------------------------------- var RTLFactor: Integer; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMHScroll');{$endif} if UseRightToLeftAlignment then RTLFactor := -1 else RTLFactor := 1; case Message.ScrollCode of SB_BOTTOM: SetOffsetX(-Integer(FRangeX)); SB_ENDSCROLL: begin DoStateChange([], [tsThumbTracking]); // avoiding to adjust the vertical scroll position while tracking makes it much smoother // but we need to adjust the final position here then UpdateHorizontalScrollBar(False); end; SB_LINELEFT: SetOffsetX(FOffsetX + RTLFactor * FScrollBarOptions.FIncrementX); SB_LINERIGHT: SetOffsetX(FOffsetX - RTLFactor * FScrollBarOptions.FIncrementX); SB_PAGELEFT: SetOffsetX(FOffsetX + RTLFactor * (ClientWidth - FHeader.Columns.GetVisibleFixedWidth)); SB_PAGERIGHT: SetOffsetX(FOffsetX - RTLFactor * (ClientWidth - FHeader.Columns.GetVisibleFixedWidth)); SB_THUMBPOSITION, SB_THUMBTRACK: begin DoStateChange([tsThumbTracking]); {$if DEFINED(LCLQt) OR DEFINED(LCLCarbon)} if UseRightToLeftAlignment then SetOffsetX(-Integer(FRangeX) + ClientWidth + Message.Pos) else SetOffsetX(-Message.Pos); {$else} if UseRightToLeftAlignment then SetOffsetX(-Integer(FRangeX) + ClientWidth + GetRealScrollPosition) else SetOffsetX(-GetRealScrollPosition); {$endif} end; SB_TOP: SetOffsetX(0); end; Message.Result := 0; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMHScroll');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMKeyDown(var Message: TLMKeyDown); // Keyboard event handling for node focus, selection, node specific popup menus and help invokation. // For a detailed description of every action done here read the help. var Shift: TShiftState; Node, Temp, LastFocused: PVirtualNode; Offset: Integer; ClearPending, NeedInvalidate, DoRangeSelect, HandleMultiSelect: Boolean; Context: Integer; ParentControl: TWinControl; R: TRect; NewCheckState: TCheckState; TempColumn, NewColumn: TColumnIndex; ActAsGrid: Boolean; ForceSelection: Boolean; NewWidth, NewHeight: Integer; RTLFactor: Integer; // for tabulator handling GetStartColumn: function(ConsiderAllowFocus: Boolean = False): TColumnIndex of object; GetNextColumn: function(Column: TColumnIndex; ConsiderAllowFocus: Boolean = False): TColumnIndex of object; GetNextNode: TGetNextNodeProc; KeyState: TKeyboardState; Buffer: array[0..1] of Char; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMKeyDown');{$endif} // Make form key preview work and let application modify the key if it wants this. inherited WMKeyDown(Message); with Message do begin Shift := KeyDataToShiftState(KeyData); // Ask the application if the default key handling is desired. if DoKeyAction(CharCode, Shift) then begin if (tsKeyCheckPending in FStates) and (CharCode <> VK_SPACE) then begin DoStateChange([], [tskeyCheckPending]); FCheckNode.CheckState := UnpressedState[FCheckNode.CheckState]; RepaintNode(FCheckNode); FCheckNode := nil; end; if CharCode in [VK_HOME, VK_END, VK_PRIOR, VK_NEXT, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_BACK, VK_TAB] then begin HandleMultiSelect := (ssShift in Shift) and (toMultiSelect in FOptions.FSelectionOptions) and not IsEditing; // Flag to avoid range selection in case of single node advance. DoRangeSelect := (CharCode in [VK_HOME, VK_END, VK_PRIOR, VK_NEXT]) and HandleMultiSelect and not IsEditing; NeedInvalidate := DoRangeSelect or (FSelectionCount > 1); ActAsGrid := toGridExtensions in FOptions.FMiscOptions; ClearPending := (Shift = []) or (ActAsGrid and not (ssShift in Shift)) or not (toMultiSelect in FOptions.FSelectionOptions) or (CharCode in [VK_TAB, VK_BACK]); // Keep old focused node for range selection. Use a default node if none was focused until now. LastFocused := FFocusedNode; if (LastFocused = nil) and (Shift <> []) then LastFocused := GetFirstVisible(nil, True); // Set an initial range anchor if there is not yet one. if FRangeAnchor = nil then FRangeAnchor := GetFirstSelected; if FRangeAnchor = nil then FRangeAnchor := GetFirst; if UseRightToLeftAlignment then RTLFactor := -1 else RTLFactor := 1; // Determine new focused node. case CharCode of VK_HOME, VK_END: begin if (CharCode = VK_END) xor UseRightToLeftAlignment then begin GetStartColumn := FHeader.FColumns.GetLastVisibleColumn; GetNextColumn := FHeader.FColumns.GetPreviousVisibleColumn; GetNextNode := GetPreviousVisible; Node := GetLastVisible(nil, True); end else begin GetStartColumn := FHeader.FColumns.GetFirstVisibleColumn; GetNextColumn := FHeader.FColumns.GetNextVisibleColumn; GetNextNode := GetNextVisible; Node := GetFirstVisible(nil, True); end; // Advance to next/previous visible column. if FHeader.UseColumns then NewColumn := GetStartColumn else NewColumn := NoColumn; // Find a column for the new/current node which can be focused. // Make the 'DoFocusChanging' for finding a valid column // identifiable from the 'DoFocusChanging' raised later on by // "FocusedNode := Node;" while (NewColumn > NoColumn) and not DoFocusChanging(FFocusedNode, FFocusedNode, FFocusedColumn, NewColumn) do NewColumn := GetNextColumn(NewColumn); if NewColumn > InvalidColumn then begin if (Shift = [ssCtrlOS]) and not ActAsGrid then begin ScrollIntoView(Node, toCenterScrollIntoView in FOptions.SelectionOptions, not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions)); if (CharCode = VK_HOME) and not UseRightToLeftAlignment then SetOffsetX(0) else SetOffsetX(-MaxInt); end else begin if not ActAsGrid or (ssCtrlOS in Shift) then FocusedNode := Node; if ActAsGrid and not (toFullRowSelect in FOptions.FSelectionOptions) then FocusedColumn := NewColumn; end; end; end; VK_PRIOR: if ssCtrlOS in Shift then SetOffsetY(FOffsetY + ClientHeight) else begin Offset := 0; // If there's no focused node then just take the very first visible one. if FFocusedNode = nil then Node := GetFirstVisible(nil, True) else begin // Go up as many nodes as comprise together a size of ClientHeight. Node := FFocusedNode; while True do begin Temp := GetPreviousVisible(Node, True); NewHeight := NodeHeight[Node]; if (Temp = nil) or (Offset + NewHeight >= ClientHeight) then Break; Node := Temp; Inc(Offset, NodeHeight[Node]); end; end; FocusedNode := Node; end; VK_NEXT: if ssCtrlOS in Shift then SetOffsetY(FOffsetY - ClientHeight) else begin Offset := 0; // If there's no focused node then just take the very last one. if FFocusedNode = nil then Node := GetLastVisible(nil, True) else begin // Go up as many nodes as comprise together a size of ClientHeight. Node := FFocusedNode; while True do begin Temp := GetNextVisible(Node, True); NewHeight := NodeHeight[Node]; if (Temp = nil) or (Offset + NewHeight >= ClientHeight) then Break; Node := Temp; Inc(Offset, NewHeight); end; end; FocusedNode := Node; end; VK_UP: begin // scrolling without selection change if ssCtrlOS in Shift then SetOffsetY(FOffsetY + Integer(FDefaultNodeHeight)) else begin if FFocusedNode = nil then Node := GetLastVisible(nil, True) else Node := GetPreviousVisible(FFocusedNode, True); if Assigned(Node) then begin EndEditNode; if HandleMultiSelect and (CompareNodePositions(LastFocused, FRangeAnchor) > 0) and Assigned(FFocusedNode) then RemoveFromSelection(FFocusedNode); if FFocusedColumn <= NoColumn then FFocusedColumn := FHeader.MainColumn; FocusedNode := Node; end else if Assigned(FFocusedNode) then InvalidateNode(FFocusedNode); end; end; VK_DOWN: begin // scrolling without selection change if ssCtrlOS in Shift then SetOffsetY(FOffsetY - Integer(FDefaultNodeHeight)) else begin if FFocusedNode = nil then Node := GetFirstVisible(nil, True) else Node := GetNextVisible(FFocusedNode, True); if Assigned(Node) then begin EndEditNode; if HandleMultiSelect and (CompareNodePositions(LastFocused, FRangeAnchor) < 0) and Assigned(FFocusedNode) then RemoveFromSelection(FFocusedNode); if FFocusedColumn <= NoColumn then FFocusedColumn := FHeader.MainColumn; FocusedNode := Node; end else if Assigned(FFocusedNode) then InvalidateNode(FFocusedNode); end; end; VK_LEFT: begin // special handling if ssCtrlOS in Shift then SetOffsetX(FOffsetX + RTLFactor * FHeader.Columns.GetScrollWidth) else begin // other special cases Context := NoColumn; if (toExtendedFocus in FOptions.FSelectionOptions) and (toGridExtensions in FOptions.FMiscOptions) then begin Context := FHeader.Columns.GetPreviousVisibleColumn(FFocusedColumn, True); if Context > -1 then FocusedColumn := Context end else if Assigned(FFocusedNode) and (vsExpanded in FFocusedNode.States) and (Shift = []) and (vsHasChildren in FFocusedNode.States) then ToggleNode(FFocusedNode) else begin if FFocusedNode = nil then FocusedNode := GetFirstVisible(nil, True) else begin if FFocusedNode.Parent <> FRoot then Node := FFocusedNode.Parent else Node := nil; if Assigned(Node) then begin if HandleMultiSelect then begin // and a third special case if FFocusedNode.Index > 0 then DoRangeSelect := True else if CompareNodePositions(Node, FRangeAnchor) > 0 then RemoveFromSelection(FFocusedNode); end; FocusedNode := Node; end; end; end; end; end; VK_RIGHT: begin // special handling if ssCtrlOS in Shift then SetOffsetX(FOffsetX - RTLFactor * FHeader.Columns.GetScrollWidth) else begin // other special cases Context := NoColumn; if (toExtendedFocus in FOptions.FSelectionOptions) and (toGridExtensions in FOptions.FMiscOptions) then begin Context := FHeader.Columns.GetNextVisibleColumn(FFocusedColumn, True); if Context > -1 then FocusedColumn := Context; end else if Assigned(FFocusedNode) and not (vsExpanded in FFocusedNode.States) and (Shift = []) and (vsHasChildren in FFocusedNode.States) then ToggleNode(FFocusedNode) else begin if FFocusedNode = nil then FocusedNode := GetFirstVisible(nil, True) else begin Node := GetFirstVisibleChild(FFocusedNode); if Assigned(Node) then begin if HandleMultiSelect and (CompareNodePositions(Node, FRangeAnchor) < 0) then RemoveFromSelection(FFocusedNode); FocusedNode := Node; end; end; end; end; end; VK_BACK: if tsIncrementalSearching in FStates then DoStateChange([tsIncrementalSearchPending]) else if Assigned(FFocusedNode) and (FFocusedNode.Parent <> FRoot) then FocusedNode := FocusedNode.Parent; VK_TAB: if (toExtendedFocus in FOptions.FSelectionOptions) and FHeader.UseColumns then begin // In order to avoid duplicating source code just to change the direction // we use function variables. if ssShift in Shift then begin GetStartColumn := FHeader.FColumns.GetLastVisibleColumn; GetNextColumn := FHeader.FColumns.GetPreviousVisibleColumn; GetNextNode := GetPreviousVisible; end else begin GetStartColumn := FHeader.FColumns.GetFirstVisibleColumn; GetNextColumn := FHeader.FColumns.GetNextVisibleColumn; GetNextNode := GetNextVisible; end; // Advance to next/previous visible column/node. Node := FFocusedNode; NewColumn := GetNextColumn(FFocusedColumn, True); repeat // Find a column for the current node which can be focused. while (NewColumn > NoColumn) and not DoFocusChanging(FFocusedNode, Node, FFocusedColumn, NewColumn) do NewColumn := GetNextColumn(NewColumn, True); if NewColumn > NoColumn then begin // Set new node and column in one go. SetFocusedNodeAndColumn(Node, NewColumn); Break; end; // No next column was accepted for the current node. So advance to next node and try again. Node := GetNextNode(Node); NewColumn := GetStartColumn; until Node = nil; end; end; // Clear old selection if required but take care to select the new focused node if it was not selected before. ForceSelection := False; if ClearPending and ((LastFocused <> FFocusedNode) or (FSelectionCount <> 1)) then begin ClearSelection; ForceSelection := True; end; // Determine new selection anchor. if Shift = [] then begin FRangeAnchor := FFocusedNode; FLastSelectionLevel := GetNodeLevel(FFocusedNode); end; // Finally change the selection for a specific range of nodes. if DoRangeSelect then ToggleSelection(LastFocused, FFocusedNode); // Make sure the new focused node is also selected. if Assigned(FFocusedNode) and ((LastFocused <> FFocusedNode) or ForceSelection) then AddToSelection(FFocusedNode); // If a repaint is needed then paint the entire tree because of the ClearSelection call, if NeedInvalidate then Invalidate; {$ifdef LCLGtk2} //workaround for changing focus bug if CharCode <> VK_TAB then CharCode := 0; {$endif} end else begin // Second chance for keys not directly concerned with selection changes. // For +, -, /, * keys on the main keyboard (not numpad) there is no virtual key code defined. // We have to do special processing to get them working too. //todo: reimplement {$ifndef INCOMPLETE_WINAPI} GetKeyboardState(KeyState); // Avoid conversion to control characters. We have captured the control key state already in Shift. KeyState[VK_CONTROL] := 0; if ToASCII(Message.CharCode, (Message.KeyData shr 16) and 7, KeyState, @Buffer, 0) > 0 then begin case Buffer[0] of '*': CharCode := VK_MULTIPLY; '+': CharCode := VK_ADD; '/': CharCode := VK_DIVIDE; '-': CharCode := VK_SUBTRACT; end; end; // According to http://www.it-faq.pl/mskb/99/337.HTM there is a problem with ToASCII when used in conjunction // with dead chars. The article recommends to call ToASCII twice to restore a deleted flag in the key message // structure under certain circumstances. It turned out it is best to always call ToASCII twice. ToASCII(Message.CharCode, (Message.KeyData shr 16) and 7, KeyState, @Buffer, 0); {$endif} case CharCode of VK_F2: if (Shift = []) and Assigned(FFocusedNode) and CanEdit(FFocusedNode, FFocusedColumn) then begin FEditColumn := FFocusedColumn; DoEdit; end; VK_ADD: if not (tsIncrementalSearching in FStates) then begin if ssCtrlOS in Shift then if {$ifdef ReverseFullExpandHotKey} not {$endif ReverseFullExpandHotKey} (ssShift in Shift) then FullExpand else FHeader.AutoFitColumns else if Assigned(FFocusedNode) and not (vsExpanded in FFocusedNode.States) then ToggleNode(FFocusedNode); end else DoStateChange([tsIncrementalSearchPending]); VK_SUBTRACT: if not (tsIncrementalSearching in FStates) then begin if ssCtrlOS in Shift then if {$ifdef ReverseFullExpandHotKey} not {$endif ReverseFullExpandHotKey} (ssShift in Shift) then FullCollapse else FHeader.RestoreColumns else if Assigned(FFocusedNode) and (vsExpanded in FFocusedNode.States) then ToggleNode(FFocusedNode); end else DoStateChange([tsIncrementalSearchPending]); VK_MULTIPLY: if not (tsIncrementalSearching in FStates) then begin if Assigned(FFocusedNode) then FullExpand(FFocusedNode); end else DoStateChange([tsIncrementalSearchPending]); VK_DIVIDE: if not (tsIncrementalSearching in FStates) then begin if Assigned(FFocusedNode) then FullCollapse(FFocusedNode); end else DoStateChange([tsIncrementalSearchPending]); VK_ESCAPE: // cancel actions currently in progress begin if IsMouseSelecting then begin DoStateChange([], [tsDrawSelecting, tsDrawSelPending]); Invalidate; end //gtk1 does not like to free a component in KeyDown {$ifndef LCLGtk} else if IsEditing then CancelEditNode; {$endif} end; VK_SPACE: if (toCheckSupport in FOptions.FMiscOptions) and Assigned(FFocusedNode) and (FFocusedNode.CheckType <> ctNone) then begin if (FStates * [tsKeyCheckPending, tsMouseCheckPending] = []) and Assigned(FFocusedNode) and not (vsDisabled in FFocusedNode.States) then begin with FFocusedNode^ do NewCheckState := DetermineNextCheckState(CheckType, CheckState); if DoChecking(FFocusedNode, NewCheckState) then begin DoStateChange([tsKeyCheckPending]); FCheckNode := FFocusedNode; FPendingCheckState := NewCheckState; FCheckNode.CheckState := PressedState[FCheckNode.CheckState]; RepaintNode(FCheckNode); end; end; end else DoStateChange([tsIncrementalSearchPending]); VK_F1: if Assigned(FOnGetHelpContext) then begin Context := 0; if Assigned(FFocusedNode) then begin Node := FFocusedNode; // Traverse the tree structure up to the root. repeat FOnGetHelpContext(Self, Node, 0, Context); Node := Node.Parent; until (Node = FRoot) or (Context <> 0); end; // If no help context could be found try the tree's one or its parent's contexts. ParentControl := Self; while Assigned(ParentControl) and (Context = 0) do begin Context := ParentControl.HelpContext; ParentControl := ParentControl.Parent; end; if Context <> 0 then Application.HelpContext(Context); end; VK_APPS: if Assigned(FFocusedNode) then begin R := GetDisplayRect(FFocusedNode, FFocusedColumn, True); Offset := DoGetNodeWidth(FFocusedNode, FFocusedColumn); if FFocusedColumn >= 0 then begin if Offset > FHeader.Columns[FFocusedColumn].Width then Offset := FHeader.Columns[FFocusedColumn].Width; end else begin if Offset > ClientWidth then Offset := ClientWidth; end; DoPopupMenu(FFocusedNode, FFocusedColumn, Point(R.Left + Offset div 2, (R.Top + R.Bottom) div 2)); end; Ord('a'), Ord('A'): if ssCtrlOS in Shift then SelectAll(True) else DoStateChange([tsIncrementalSearchPending]); else begin // Use the key for incremental search. // Since we are dealing with Unicode all the time there should be a more sophisticated way // of checking for valid characters for incremental search. // This is available but would require to include a significant amount of Unicode character // properties, so we stick with the simple space check. if (Shift * [ssCtrlOS, ssAlt] = []) and (CharCode >= 32) then DoStateChange([tsIncrementalSearchPending]); end; end; end; end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMKeyDown');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMKeyUp(var Message: TLMKeyUp); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMKeyUp');{$endif} inherited WMKeyUp(Message); case Message.CharCode of VK_SPACE: if tsKeyCheckPending in FStates then begin DoStateChange([], [tskeyCheckPending]); if FCheckNode = FFocusedNode then DoCheckClick(FCheckNode, FPendingCheckState); InvalidateNode(FCheckNode); FCheckNode := nil; end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMKeyUp');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMKillFocus(var Msg: TLMKillFocus); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMKillFocus');{$endif} inherited WMKillFocus(Msg); // Remove hint if shown currently. Application.CancelHint; // Stop wheel panning if active. StopWheelPanning; // Don't let any timer continue if the tree is no longer the active control (except change timers). KillTimer(Handle, ExpandTimer); KillTimer(Handle, EditTimer); KillTimer(Handle, ScrollTimer); KillTimer(Handle, SearchTimer); FSearchBuffer := ''; FLastSearchNode := nil; DoStateChange([], [tsScrollPending, tsScrolling, tsEditPending, tsLeftButtonDown, tsRightButtonDown, tsMiddleButtonDown, tsOLEDragPending, tsVCLDragPending, tsIncrementalSearching, tsNodeHeightTrackPending, tsNodeHeightTracking]); if (FSelectionCount > 0) or not (toGhostedIfUnfocused in FOptions.FPaintOptions) then Invalidate else if Assigned(FFocusedNode) then InvalidateNode(FFocusedNode); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMKillFocus');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMLButtonDblClk(var Message: TLMLButtonDblClk); var HitInfo: THitInfo; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMLButtonDblClk');{$endif} DoStateChange([tsLeftDblClick]); inherited WMLButtonDblClk(Message); // get information about the hit GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseDblClick(Message, HitInfo); DoStateChange([], [tsLeftDblClick]); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMLButtonDblClk');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMLButtonDown(var Message: TLMLButtonDown); var HitInfo: THitInfo; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMLButtonDown');{$endif} DoStateChange([tsLeftButtonDown]); inherited WMLButtonDown(Message); // get information about the hit GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); {$ifdef DEBUG_VTV} if HitInfo.HitNode <> nil then Logger.Send([lcPaintHeader, lcMouseEvent],'WMLButtonDown - HitNode.Index', HitInfo.HitNode^.Index); {$endif} HandleMouseDown(Message, HitInfo); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMLButtonDown');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMLButtonUp(var Message: TLMLButtonUp); var HitInfo: THitInfo; begin DoStateChange([], [tsLeftButtonDown, tsNodeHeightTracking, tsNodeHeightTrackPending]); // get information about the hit GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseUp(Message.Keys, HitInfo); inherited WMLButtonUp(Message); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMLButtonUp');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMMButtonDblClk(var Message: TLMMButtonDblClk); var HitInfo: THitInfo; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMMButtonDblClk');{$endif} DoStateChange([tsMiddleDblClick]); inherited WMMButtonDblClk(Message); // get information about the hit if toMiddleClickSelect in FOptions.FSelectionOptions then begin GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseDblClick(Message, HitInfo); end; DoStateChange([], [tsMiddleDblClick]); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMMButtonDblClk');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMMButtonDown(var Message: TLMMButtonDown); var HitInfo: THitInfo; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMMButtonDown');{$endif} DoStateChange([tsMiddleButtonDown]); if FHeader.FStates = [] then begin inherited WMMButtonDown(Message); // Start wheel panning or scrolling if not already active, allowed and scrolling is useful at all. if (toWheelPanning in FOptions.FMiscOptions) and ([tsWheelScrolling, tsWheelPanning] * FStates = []) and ((Integer(FRangeX) > ClientWidth) or (Integer(FRangeY) > ClientHeight)) then begin FLastClickPos := SmallPointToPoint(Message.Pos); StartWheelPanning(FLastClickPos); end else begin StopWheelPanning; // Get information about the hit. if toMiddleClickSelect in FOptions.FSelectionOptions then begin GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseDown(Message, HitInfo); end; end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMMButtonDown');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMMButtonUp(var Message: TLMMButtonUp); var HitInfo: THitInfo; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMMButtonUp');{$endif} DoStateChange([], [tsMiddleButtonDown]); // If wheel panning/scrolling is active and the mouse has not yet been moved then the user starts wheel auto scrolling. // Indicate this by removing the panning flag. Otherwise (the mouse has moved meanwhile) stop panning. if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then begin if tsWheelScrolling in FStates then DoStateChange([], [tsWheelPanning]) else StopWheelPanning; end else if FHeader.FStates = [] then begin inherited WMMButtonUp(Message); // get information about the hit if toMiddleClickSelect in FOptions.FSelectionOptions then begin GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseUp(Message.Keys, HitInfo); end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod('WMMButtonUp');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- {$ifdef EnableNCFunctions} procedure TBaseVirtualTree.WMNCCalcSize(var Message: TLMNCCalcSize); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMNCCalcSize');{$endif} inherited WMNCCalcSize(Message); with FHeader do if hoVisible in FHeader.FOptions then with Message.CalcSize_Params^ do Inc(rgrc[0].Top, FHeight); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMNCCalcSize');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMNCHitTest(var Message: TWMNCHitTest); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMNCHitTest');{$endif} inherited WMNCHitTest(Message); if not (csDesigning in ComponentState) and (hoVisible in FHeader.FOptions) and FHeader.InHeader(ScreenToClient(SmallPointToPoint(Message.Pos))) then Message.Result := HTBORDER; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMNCHitTest');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMNCPaint(var Message: TRealWMNCPaint); var DC: HDC; R: TRect; Flags: DWORD; {$ifdef ThemeSupport} ExStyle: Integer; TempRgn: HRGN; BorderWidth, BorderHeight: Integer; {$endif ThemeSupport} begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMNCPaint');{$endif} {$ifdef ThemeSupport} if tsUseThemes in FStates then begin // If theming is enabled and the client edge border is set for the window then prevent the default window proc // from painting the old border to avoid flickering. ExStyle := GetWindowLong(Handle, GWL_EXSTYLE); if (ExStyle and WS_EX_CLIENTEDGE) <> 0 then begin GetWindowRect(Handle, R); // Determine width of the client edge. BorderWidth := GetSystemMetrics(SM_CXEDGE); BorderHeight := GetSystemMetrics(SM_CYEDGE); InflateRect(R, -BorderWidth, -BorderHeight); TempRgn := CreateRectRgnIndirect(R); // Exclude the border from the message region if there is one. Otherwise just use the inflated // window area region. if Message.Rgn <> 1 then CombineRgn(TempRgn, Message.Rgn, TempRgn, RGN_AND); DefWindowProc(Handle, Message.Msg, Integer(TempRgn), 0); DeleteObject(TempRgn); end else DefaultHandler(Message); end else {$endif ThemeSupport} DefaultHandler(Message); Flags := DCX_CACHE or DCX_CLIPSIBLINGS or DCX_WINDOW or DCX_VALIDATE; if (Message.Rgn = 1) or not IsWinNT then DC := GetDCEx(Handle, 0, Flags) else DC := GetDCEx(Handle, Message.Rgn, Flags or DCX_INTERSECTRGN); if DC <> 0 then begin if hoVisible in FHeader.FOptions then begin R := FHeaderRect; FHeader.FColumns.PaintHeader(DC, R, -FEffectiveOffsetX); end; OriginalWMNCPaint(DC); ReleaseDC(Handle, DC); end; {$ifdef ThemeSupport} if tsUseThemes in FStates then ThemeServices.PaintBorder(Self, False); {$endif ThemeSupport} {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMNCPaint');{$endif} end; {$endif} //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMPaint(var Message: TLMPaint); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMPaint');{$endif} //todo: //Windows.GetUpdateRect is always empty because BeginPaint was called //see if PaintStruct has the same rect {$ifndef INCOMPLETE_WINAPI} if tsVCLDragging in FStates then ImageList_DragShowNolock(False); {$endif} if csPaintCopy in ControlState then FUpdateRect := ClientRect else FUpdateRect := Message.PaintStruct^.rcPaint; {$ifdef DEBUG_VTV}Logger.Send([lcPaint],'FUpdateRect', FUpdateRect);{$endif} inherited WMPaint(Message); {$ifndef INCOMPLETE_WINAPI} if tsVCLDragging in FStates then ImageList_DragShowNolock(True); {$endif} {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMPaint');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMPaste(var Message: TLMNoParams); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMPaste');{$endif} PasteFromClipboard; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMPaste');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- {$ifdef EnablePrintFunctions} procedure TBaseVirtualTree.WMPrint(var Message: TWMPrint); // This message is sent to request that the tree draws itself to a given device context. This includes not only // the client area but also the non-client area (header!). begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMPrint');{$endif} // Draw only if the window is visible or visibility is not required. if ((Message.Flags and PRF_CHECKVISIBLE) = 0) or IsWindowVisible(Handle) then Header.Columns.PaintHeader(Message.DC, FHeaderRect, -FEffectiveOffsetX); inherited WMPrint(Message); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMPrint');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMPrintClient(var Message: TWMPrintClient); var Window: TRect; Target: TPoint; Canvas: TCanvas; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMPrintClient');{$endif} // Draw only if the window is visible or visibility is not required. if ((Message.Flags and PRF_CHECKVISIBLE) = 0) or IsWindowVisible(Handle) then begin // Determine area of the entire tree to be displayed in the control. Window := ClientRect; Target := Window.TopLeft; // The Window rectangle is given in client coordinates. We have to convert it into // a sliding window of the tree image. OffsetRect(Window, FEffectiveOffsetX, -FOffsetY); Canvas := TCanvas.Create; try Canvas.Handle := Message.DC; PaintTree(Canvas, Window, Target, [poBackground, poDrawFocusRect, poDrawDropMark, poDrawSelection, poGridLines]); finally Canvas.Handle := 0; Canvas.Free; end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMPrintClient');{$endif} end; {$endif} //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMRButtonDblClk(var Message: TLMRButtonDblClk); var HitInfo: THitInfo; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMRButtonDblClk');{$endif} DoStateChange([tsRightDblClick]); inherited WMRButtonDblClk(Message); // get information about the hit if toMiddleClickSelect in FOptions.FSelectionOptions then begin GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseDblClick(Message, HitInfo); end; DoStateChange([], [tsRightDblClick]); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMRButtonDblClk');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMRButtonDown(var Message: TLMRButtonDown); var HitInfo: THitInfo; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMRButtonDown');{$endif} DoStateChange([tsRightButtonDown]); if FHeader.FStates = [] then begin inherited WMRButtonDown(Message); // get information about the hit if toRightClickSelect in FOptions.FSelectionOptions then begin GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseDown(Message, HitInfo); end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMRButtonDown');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMRButtonUp(var Message: TLMRButtonUp); // handle right click selection and node specific popup menu var HitInfo: THitInfo; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMRButtonUp');{$endif} DoStateChange([], [tsPopupMenuShown, tsRightButtonDown]); if FHeader.FStates = [] then begin Application.CancelHint; if IsMouseSelecting and Assigned(PopupMenu) then begin // Reset selection state already here, before the inherited handler opens the default menu. DoStateChange([], [tsDrawSelecting, tsDrawSelPending]); Invalidate; end; inherited WMRButtonUp(Message); // get information about the hit GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); if toRightClickSelect in FOptions.FSelectionOptions then HandleMouseUp(Message.Keys, HitInfo); if not Assigned(PopupMenu) then DoPopupMenu(HitInfo.HitNode, HitInfo.HitColumn, Point(Message.XPos, Message.YPos)); end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMRButtonUp');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMSetFocus(var Msg: TLMSetFocus); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMSetFocus') ;{$endif} inherited WMSetFocus(Msg); if (FSelectionCount > 0) or not (toGhostedIfUnfocused in FOptions.FPaintOptions) then Invalidate; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMSetFocus');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMSize(var Message: TLMSize); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMSize');{$endif} inherited WMSize(Message); // Need to update scroll bars here. This will cause a recursion because of the change of the client area // when changing a scrollbar. Usually this is no problem since with the second level recursion no change of the // window size happens (the same values for the scrollbars are set, which shouldn't cause a window size change). // Appearently, this applies not to all systems, however. if HandleAllocated and ([tsSizing, tsWindowCreating] * FStates = []) and (ClientHeight > 0) then try DoStateChange([tsSizing]); // This call will invalidate the entire non-client area which needs recalculation on resize. FHeader.RescaleHeader; FHeader.UpdateSpringColumns; UpdateScrollBars(True); if (tsEditing in FStates) and not FHeader.UseColumns then UpdateEditBounds; finally DoStateChange([], [tsSizing]); end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMSize');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- {$ifdef ThemeSupport} {$ifdef Windows} //todo procedure TBaseVirtualTree.WMThemeChanged(var Message: TLMessage); begin inherited; ThemeServices.UpdateThemes; if ThemeServices.ThemesEnabled and (toThemeAware in TreeOptions.PaintOptions) then DoStateChange([tsUseThemes]) else DoStateChange([], [tsUseThemes]); RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_VALIDATE or RDW_FRAME); end; {$endif} {$endif ThemeSupport} //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMTimer(var Message: TLMTimer); // centralized timer handling happens here begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages,lcTimer],'WMTimer');{$endif} with Message do begin {$ifdef DEBUG_VTV}Logger.Send([lcTimer],'TimerId',TimerId);{$endif} case TimerID of ExpandTimer: DoDragExpand; EditTimer: DoEdit; ScrollTimer: begin if tsScrollPending in FStates then begin Application.CancelHint; // Scroll delay has elapsed, set to normal scroll interval now. SetTimer(Handle, ScrollTimer, FAutoScrollInterval, nil); DoStateChange([tsScrolling], [tsScrollPending]); end; DoTimerScroll; end; ChangeTimer: DoChange(FLastChangedNode); StructureChangeTimer: DoStructureChange(FLastStructureChangeNode, FLastStructureChangeReason); SearchTimer: begin // When this event triggers then the user did not pressed any key for the specified timeout period. // Hence incremental searching is stopped. DoStateChange([], [tsIncrementalSearching]); KillTimer(Handle, SearchTimer); FSearchBuffer := ''; FLastSearchNode := nil; end; end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages,lcTimer],'WMTimer');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WMVScroll(var Message: TLMVScroll); //--------------- local functions ------------------------------------------- function GetRealScrollPosition: Integer; var SI: TScrollInfo; Code: Integer; begin SI.cbSize := SizeOf(TScrollInfo); SI.fMask := SIF_TRACKPOS; Code := SB_VERT; {$ifdef UseFlatScrollbars} FlatSB_GetScrollInfo(Handle, Code, SI); {$else} GetScrollInfo(Handle, Code, SI); {$endif UseFlatScrollbars} Result := SI.nTrackPos; {$ifdef DEBUG_VTV}Logger.Send([lcScroll],'GetRealScrollPosition',Result);{$endif} end; //--------------- end local functions --------------------------------------- begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcScroll],'WMVScroll');{$endif} //{$ifdef DEBUG_VTV}Logger.SendCallStack([lcScroll],'CallStack');{$endif} case Message.ScrollCode of SB_BOTTOM: SetOffsetY(-Integer(FRoot.TotalHeight)); SB_ENDSCROLL: begin DoStateChange([], [tsThumbTracking]); // Avoiding to adjust the horizontal scroll position while tracking makes scrolling much smoother // but we need to adjust the final position here then. UpdateScrollBars(True); // Really weird invalidation needed here (and I do it only because it happens so rarely), because // when showing the horizontal scrollbar while scrolling down using the down arrow button, // the button will be repainted on mouse up (at the wrong place in the far right lower corner)... RedrawWindow(Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_NOERASE or RDW_NOCHILDREN); end; SB_LINEUP: SetOffsetY(FOffsetY + FScrollBarOptions.FIncrementY); SB_LINEDOWN: SetOffsetY(FOffsetY - FScrollBarOptions.FIncrementY); SB_PAGEUP: SetOffsetY(FOffsetY + ClientHeight); SB_PAGEDOWN: SetOffsetY(FOffsetY - ClientHeight); SB_THUMBPOSITION, SB_THUMBTRACK: begin DoStateChange([tsThumbTracking]); {$if DEFINED(LCLQt) OR DEFINED(LCLCarbon)} SetOffsetY(-Message.Pos); {$else} SetOffsetY(-GetRealScrollPosition); {$endif} end; SB_TOP: SetOffsetY(0); end; Message.Result := 0; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcScroll],'WMVScroll');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AddToSelection(Node: PVirtualNode); var Changed: Boolean; begin if not FSelectionLocked then begin Assert(Assigned(Node), 'Node must not be nil!'); FSingletonNodeArray[0] := Node; Changed := InternalAddToSelection(FSingletonNodeArray, 1, False); if Changed then begin InvalidateNode(Node); Change(Node); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AddToSelection(const NewItems: TNodeArray; NewLength: Integer; ForceInsert: Boolean = False); // Adds the given items all at once into the current selection array. NewLength is the amount of // nodes to add (necessary to allow NewItems to be larger than the actual used entries). // ForceInsert is True if nodes must be inserted without consideration of level select constraint or // already set selected flags (e.g. when loading from stream). // Note: In the case ForceInsert is True the caller is responsible for making sure the new nodes aren't already in the // selection array! var Changed: Boolean; begin Changed := InternalAddToSelection(NewItems, NewLength, ForceInsert); if Changed then begin if NewLength = 1 then begin InvalidateNode(NewItems[0]); Change(NewItems[0]); end else begin Invalidate; Change(nil); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; out NextNonEmpty: TColumnIndex); // Used in descendants to modify the paint rectangle of the current column while painting a certain node. begin // Since cells are always drawn from left to right the next column index is independent of the // bidi mode, but not the column borders, which might change depending on the cell's content. NextNonEmpty := FHeader.FColumns.GetNextVisibleColumn(PaintInfo.Column); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AdjustPanningCursor(X, Y: Integer); // Triggered by a mouse move when wheel panning/scrolling is active. // Loads the proper cursor which indicates into which direction scrolling is done. var NewCursor: HCURSOR; ScrollHorizontal, ScrollVertical: Boolean; begin ScrollHorizontal := Integer(FRangeX) > ClientWidth; ScrollVertical := Integer(FRangeY) > ClientHeight; if (Abs(X - FLastClickPos.X) < 8) and (Abs(Y - FLastClickPos.Y) < 8) then begin // Mouse is in the neutral zone. if ScrollHorizontal then begin if ScrollVertical then NewCursor := crVT_MOVEALL else NewCursor := crVT_MOVEEW end else NewCursor := crVT_MOVENS; end else begin // One of 8 directions applies: north, north-east, east, south-east, south, south-west, west and north-west. // Check also if scrolling in the particular direction is possible. if ScrollVertical and ScrollHorizontal then begin // All directions allowed. if X - FlastClickPos.X < -8 then begin // Left hand side. if Y - FLastClickPos.Y < -8 then NewCursor := crVT_MOVENW else if Y - FLastClickPos.Y > 8 then NewCursor := crVT_MOVESW else NewCursor := crVT_MOVEW; end else if X - FLastClickPos.X > 8 then begin // Right hand side. if Y - FLastClickPos.Y < -8 then NewCursor := crVT_MOVENE else if Y - FLastClickPos.Y > 8 then NewCursor := crVT_MOVESE else NewCursor := crVT_MOVEE; end else begin // Up or down. if Y < FLastClickPos.Y then NewCursor := crVT_MOVEN else NewCursor := crVT_MOVES; end; end else if ScrollHorizontal then begin // Only horizontal movement allowed. if X < FlastClickPos.X then NewCursor := crVT_MOVEW else NewCursor := crVT_MOVEE; end else begin // Only vertical movement allowed. if Y < FlastClickPos.Y then NewCursor := crVT_MOVEN else NewCursor := crVT_MOVES; end; end; // Now load the cursor and apply it. {$ifdef Windows} LCLIntf.SetCursor(Screen.Cursors[NewCursor]); {$else} Cursor := NewCursor; {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AdviseChangeEvent(StructureChange: Boolean; Node: PVirtualNode; Reason: TChangeReason); // Used to register a delayed change event. If StructureChange is False then we have a selection change event (without // a specific reason) otherwise it is a structure change. begin if StructureChange then begin if tsStructureChangePending in FStates then begin if HandleAllocated then KillTimer(Handle,StructureChangeTimer); end else DoStateChange([tsStructureChangePending]); FLastStructureChangeNode := Node; if FLastStructureChangeReason = crIgnore then FLastStructureChangeReason := Reason else if Reason <> crIgnore then FLastStructureChangeReason := crAccumulated; end else begin if tsChangePending in FStates then KillTimer(Handle, ChangeTimer) else DoStateChange([tsChangePending]); FLastChangedNode := Node; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.AllocateInternalDataArea(Size: Cardinal): Cardinal; // Simple registration method to be called by each descendant to claim their internal data area. // Result is the offset from the begin of the node to the internal data area of the calling tree class. begin Assert((FRoot = nil) or (FRoot.ChildCount = 0), 'Internal data allocation must be done before any node is created.'); {$ifdef DEBUG_VTV}Logger.Send('FTotalInternalDataSize BEFORE',FTotalInternalDataSize);{$endif} {$ifdef DEBUG_VTV}Logger.Send('Size',Size);{$endif} {$ifdef DEBUG_VTV}Logger.Send('TreeNodeSize',TreeNodeSize);{$endif} Result := TreeNodeSize + FTotalInternalDataSize; {$ifdef DEBUG_VTV}Logger.Send('Result',Result);{$endif} Inc(FTotalInternalDataSize, (Size + 3) and not 3); {$ifdef DEBUG_VTV}Logger.Send('FTotalInternalDataSize AFTER', FTotalInternalDataSize);{$endif} InitRootNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.Animate(Steps, Duration: Cardinal; Callback: TVTAnimationCallback; Data: Pointer); // This method does the calculation part of an animation as used for node toggling and hint animations. // Steps is the maximum amount of animation steps to do and Duration determines the milliseconds the animation // has to run. Callback is a task specific method which is called in the loop for every step and Data is simply // something to pass on to the callback. // The callback is called with the current step, the current step size and the Data parameter. Since the step amount // as well as the step size are possibly adjusted during the animation, it is impossible to determine if the current // step is the last step, even if the original step amount is known. To solve this problem the callback will be // called after the loop has finished with a step size of 0 indicating so to execute any post processing. var StepSize, RemainingTime, RemainingSteps, NextTimeStep, CurrentStep, StartTime, CurrentTime: Cardinal; begin {$ifndef Windows} //Is necessary to properly implement timeGetTime in non Windows Exit; {$endif} if not (tsInAnimation in FStates) and (Duration > 0) then begin DoStateChange([tsInAnimation]); try RemainingTime := Duration; RemainingSteps := Steps; // Determine the initial step size which is either 1 if the needed steps are less than the number of // steps possible given by the duration or > 1 otherwise. StepSize := Round(Max(1, RemainingSteps / Duration)); RemainingSteps := RemainingSteps div StepSize; CurrentStep := 0; while (RemainingSteps > 0) and (RemainingTime > 0) and not Application.Terminated do begin StartTime := timeGetTime; NextTimeStep := StartTime + RemainingTime div RemainingSteps; if not Callback(CurrentStep, StepSize, Data) then Break; // Keep duration for this step for rest calculation. CurrentTime := timeGetTime; // Wait until the calculated time has been reached. while CurrentTime < NextTimeStep do CurrentTime := timeGetTime; // Subtract the time this step really needed. if RemainingTime >= CurrentTime - StartTime then begin Dec(RemainingTime, CurrentTime - StartTime); Dec(RemainingSteps); end else begin RemainingTime := 0; RemainingSteps := 0; end; // If the remaining time per step is less than one time step then we have to decrease the // step count and increase the step size. if (RemainingSteps > 0) and ((RemainingTime div RemainingSteps) < 1) then begin repeat Inc(StepSize); RemainingSteps := RemainingTime div StepSize; until (RemainingSteps <= 0) or ((RemainingTime div RemainingSteps) >= 1); end; CurrentStep := Cardinal(Steps) - RemainingSteps; end; if not Application.Terminated then Callback(0, 0, Data); finally DoStateChange([], [tsCancelHintAnimation, tsInAnimation]); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.BeginOperation; // Called to indicate that a long-running operation has been started. begin Inc(FOperationCount); if FOperationCount = 1 then FOperationCanceled := False; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CalculateSelectionRect(X, Y: Integer): Boolean; // Recalculates old and new selection rectangle given that X, Y are new mouse coordinates. // Returns True if there was a change since the last call. var MaxValue: Integer; begin //lclheader if hoVisible in FHeader.Options then Dec(Y, FHeader.Height); if tsDrawSelecting in FStates then FLastSelRect := FNewSelRect; FNewSelRect.BottomRight := Point(X + FEffectiveOffsetX, Y - FOffsetY); if FNewSelRect.Right < 0 then FNewSelRect.Right := 0; if FNewSelRect.Bottom < 0 then FNewSelRect.Bottom := 0; MaxValue := ClientWidth; if FRangeX > Cardinal(MaxValue) then MaxValue := FRangeX; if FNewSelRect.Right > MaxValue then FNewSelRect.Right := MaxValue; MaxValue := ClientHeight; if FRangeY > Cardinal(MaxValue) then MaxValue := FRangeY; if FNewSelRect.Bottom > MaxValue then FNewSelRect.Bottom := MaxValue; Result := not CompareMem(@FLastSelRect, @FNewSelRect, SizeOf(FNewSelRect)); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CanAutoScroll: Boolean; // Determines if auto scrolling is currently allowed. var IsDropTarget: Boolean; IsDrawSelecting: Boolean; IsWheelPanning: Boolean; begin // Don't scroll the client area if the header is currently doing tracking or dragging. // Do auto scroll only if there is a draw selection in progress or the tree is the current drop target or // wheel panning/scrolling is active. IsDropTarget := Assigned(FDragManager) and VTVDragManager.IsDropTarget; IsDrawSelecting := [tsDrawSelPending, tsDrawSelecting] * FStates <> []; IsWheelPanning := [tsWheelPanning, tsWheelScrolling] * FStates <> []; Result := ((toAutoScroll in FOptions.FAutoOptions) or IsWheelPanning) and (FHeader.FStates = []) and (IsDrawSelecting or IsDropTarget or (tsVCLDragging in FStates) or IsWheelPanning); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CanShowDragImage: Boolean; // Determines whether a drag image should be shown. begin Result := FDragImageKind <> diNoImage; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.Change(Node: PVirtualNode); begin AdviseChangeEvent(False, Node, crIgnore); if FUpdateCount = 0 then begin if (FChangeDelay > 0) and not (tsSynchMode in FStates) then SetTimer(Handle, ChangeTimer, FChangeDelay, nil) else DoChange(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ChangeScale(M, D: Integer); var DoScale: Boolean; begin inherited; if (M <> D) and (toAutoChangeScale in FOptions.FAutoOptions) then begin if (csLoading in ComponentState) then DoScale := tsNeedScale in FStates else DoScale := True; if DoScale then begin FDefaultNodeHeight := MulDiv(FDefaultNodeHeight, M, D); FHeader.ChangeScale(M, D); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CheckParentCheckState(Node: PVirtualNode; NewCheckState: TCheckState): Boolean; // Checks all siblings of node to determine which check state Node's parent must get. var CheckCount, BoxCount: Cardinal; PartialCheck: Boolean; Run: PVirtualNode; begin CheckCount := 0; BoxCount := 0; PartialCheck := False; Run := Node.Parent.FirstChild; while Assigned(Run) do begin if Run = Node then begin // The given node cannot be checked because it does not yet have its new check state (as this depends // on the outcome of this method). Instead NewCheckState is used as this contains the new state the node // will get if this method returns True. if Run.CheckType in [ctCheckBox, ctTriStateCheckBox] then begin Inc(BoxCount); if NewCheckState in [csCheckedNormal, csCheckedPressed] then Inc(CheckCount); PartialCheck := PartialCheck or (NewCheckState = csMixedNormal); end; end else if Run.CheckType in [ctCheckBox, ctTriStateCheckBox] then begin Inc(BoxCount); if Run.CheckState in [csCheckedNormal, csCheckedPressed] then Inc(CheckCount); PartialCheck := PartialCheck or (Run.CheckState = csMixedNormal); end; Run := Run.NextSibling; end; if (CheckCount = 0) and not PartialCheck then NewCheckState := csUncheckedNormal else if CheckCount < BoxCount then NewCheckState := csMixedNormal else NewCheckState := csCheckedNormal; Node := Node.Parent; Result := DoChecking(Node, NewCheckState); if Result then begin DoCheckClick(Node, NewCheckState); // Recursively adjust parent of parent. with Node^ do begin if not (vsInitialized in Parent.States) then InitNode(Parent); if ([vsChecking, vsDisabled] * Parent.States = []) and (Parent <> FRoot) and (Parent.CheckType = ctTriStateCheckBox) then Result := CheckParentCheckState(Node, NewCheckState); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ClearTempCache; // make sure the temporary node cache is in a reliable state begin FTempNodeCache := nil; FTempNodeCount := 0; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ColumnIsEmpty(Node: PVirtualNode; Column: TColumnIndex): Boolean; // Returns True if the given column is to be considered as being empty. This will usually be determined by // descendants as the base tree implementation has not enough information to decide. begin Result := True; if Assigned(FOnGetCellIsEmpty) then FOnGetCellIsEmpty(Self, Node, Column, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ComputeRTLOffset(ExcludeScrollbar: Boolean): Integer; // Computes the horizontal offset needed when all columns are automatically right aligned (in RTL bidi mode). // ExcludeScrollbar determines if the left-hand vertical scrollbar is to be included (if visible) or not. var HeaderWidth: Integer; ScrollbarVisible: Boolean; begin ScrollbarVisible := (Integer(FRangeY) > ClientHeight) and (ScrollbarOptions.Scrollbars in [ssVertical, ssBoth]); if ScrollbarVisible then Result := GetSystemMetrics(SM_CXVSCROLL) else Result := 0; // Make everything right aligned. HeaderWidth := FHeaderRect.Right - FHeaderRect.Left; if Integer(FRangeX) + Result <= HeaderWidth then Result := HeaderWidth - Integer(FRangeX); // Otherwise take only left-hand vertical scrollbar into account. if ScrollbarVisible and ExcludeScrollbar then Dec(Result, GetSystemMetrics(SM_CXVSCROLL)); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CountLevelDifference(Node1, Node2: PVirtualNode): Integer; // This method counts how many indentation levels the given nodes are apart. If both nodes have the same parent then the // difference is 0 otherwise the result is basically GetNodeLevel(Node2) - GetNodeLevel(Node1), but with sign. // If the result is negative then Node2 is less intended than Node1. var Level1, Level2: Integer; begin Assert(Assigned(Node1) and Assigned(Node2), 'Both nodes must be Assigned.'); Level1 := 0; while Node1.Parent <> FRoot do begin Inc(Level1); Node1 := Node1.Parent; end; Level2 := 0; while Node2.Parent <> FRoot do begin Inc(Level2); Node2 := Node2.Parent; end; Result := Level2 - Level1; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CountVisibleChildren(Node: PVirtualNode): Cardinal; // Returns the number of visible child nodes of the given node. begin Result := 0; // The node's direct children... if vsExpanded in Node.States then begin // ...and their children. Node := Node.FirstChild; while Assigned(Node) do begin if vsVisible in Node.States then Inc(Result, CountVisibleChildren(Node) + 1); Node := Node.NextSibling; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CreateParams(var Params: TCreateParams); const ScrollBar: array[TScrollStyle] of Cardinal = (0, WS_HSCROLL, WS_VSCROLL, WS_HSCROLL or WS_VSCROLL, 0,0,0); begin //todo_lcl inherited CreateParams(Params); with Params do begin Style := Style or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or ScrollBar[ScrollBarOptions.FScrollBars]; if toFullRepaintOnResize in FOptions.FMiscOptions then WindowClass.style := WindowClass.style or CS_HREDRAW or CS_VREDRAW else WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW); //lcl: Ctl3D is not used in LCL. Has the same meaning of BorderStyle = bsSingle { if BorderStyle = bsSingle then begin if Ctl3D then begin ExStyle := ExStyle or WS_EX_CLIENTEDGE; Style := Style and not WS_BORDER; end else Style := Style or WS_BORDER; end else Style := Style and not WS_BORDER; } //todo_lcl_low //AddBiDiModeExStyle(ExStyle); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CreateWnd; // Initializes data which depends on a valid window handle. begin DoStateChange([tsWindowCreating]); inherited; {$ifdef DEBUG_VTV}Logger.Send([lcInfo],'Handle (CreateWnd)',Handle);{$endif} DoStateChange([], [tsWindowCreating]); {$ifdef ThemeSupport} if ThemeServices.ThemesEnabled and (toThemeAware in TreeOptions.PaintOptions) then begin DoStateChange([tsUseThemes]); //todo //if (toUseExplorerTheme in FOptions.FPaintOptions) and IsWinVistaOrAbove then // SetWindowTheme(Handle, 'explorer', nil); end else {$endif ThemeSupport} DoStateChange([], [tsUseThemes]); // Because of the special recursion and update stopper when creating the window (or resizing it) // we have to manually trigger the auto size calculation here. if hsNeedScaling in FHeader.FStates then FHeader.RescaleHeader; //lcl: Call with Force argument to true since AdjustAutoSize is not called in Loaded if hoAutoResize in FHeader.FOptions then FHeader.FColumns.AdjustAutoSize(InvalidColumn, True); // Initialize flat scroll bar library if required. {$ifdef UseFlatScrollbars} if FScrollBarOptions.FScrollBarStyle <> sbmRegular then begin InitializeFlatSB(Handle); FlatSB_SetScrollProp(Handle, WSB_PROP_HSTYLE, ScrollBarProp[FScrollBarOptions.ScrollBarStyle], False); FlatSB_SetScrollProp(Handle, WSB_PROP_VSTYLE, ScrollBarProp[FScrollBarOptions.ScrollBarStyle], False); end; {$endif UseFlatScrollbars} PrepareBitmaps(True, True); {$ifdef Windows} // Register tree as OLE drop target. if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.FMiscOptions) then RegisterDragDrop(Handle, VTVDragManager as IDropTarget); {$endif} if toCheckSupport in FOptions.FMiscOptions then CheckImageListNeeded; UpdateScrollBars(True); UpdateHeaderRect; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DestroyHandle; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'DestroyHandle');{$endif} //lcl: this code was originally called is response to WM_NCDESTROY // see if there will be issues calling here InterruptValidation; KillTimer(Handle, ChangeTimer); KillTimer(Handle, StructureChangeTimer); {$ifdef Windows} if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.FMiscOptions) then RevokeDragDrop(Handle); {$endif} // Clean up other stuff. DeleteObject(FDottedBrush); FDottedBrush := 0; CancelEditNode; inherited; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'DestroyHandle');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DetermineHiddenChildrenFlag(Node: PVirtualNode); // Update the hidden children flag of the given node. var Run: PVirtualNode; begin if Node.ChildCount = 0 then begin if vsHasChildren in Node.States then Exclude(Node.States, vsAllChildrenHidden) else Include(Node.States, vsAllChildrenHidden); end else begin // Iterate through all siblings and stop when one visible is found. Run := Node.FirstChild; while Assigned(Run) do Run := Run.NextSibling; if Assigned(Run) then Exclude(Node.States, vsAllChildrenHidden) else Include(Node.States, vsAllChildrenHidden); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DetermineHiddenChildrenFlagAllNodes; var Run: PVirtualNode; begin Run := GetFirstNoInit(False); while Assigned(Run) do begin DetermineHiddenChildrenFlag(Run); Run := GetNextNoInit(Run); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DetermineHitPositionLTR(var HitInfo: THitInfo; Offset, Right: Integer; Alignment: TAlignment); // This method determines the hit position within a node with left-to-right orientation. var MainColumnHit: Boolean; Run: PVirtualNode; Indent, TextWidth, ImageOffset: Integer; begin MainColumnHit := HitInfo.HitColumn = FHeader.MainColumn; Indent := 0; // If columns are not used or the main column is hit then the tree indentation must be considered too. if MainColumnHit then begin if toFixedIndent in FOptions.FPaintOptions then Indent := FIndent else begin Run := HitInfo.HitNode; while (Run.Parent <> FRoot) do begin Inc(Indent, FIndent); Run := Run.Parent; end; if toShowRoot in FOptions.FPaintOptions then Inc(Indent, FIndent); end; end; if Offset < Indent then begin // Position is to the left of calculated indentation which can only happen for the main column. // Check whether it corresponds to a button/checkbox. if (toShowButtons in FOptions.FPaintOptions) and (vsHasChildren in HitInfo.HitNode.States) then begin // Position of button is interpreted very generously to avoid forcing the user // to click exactly into the 9x9 pixels area. The entire node height and one full // indentation level is accepted as button hit. if Offset >= Indent - Integer(FIndent) then Include(HitInfo.HitPositions, hiOnItemButton); if Offset >= Indent - FPlusBM.Width then Include(HitInfo.HitPositions, hiOnItemButtonExact); end; // no button hit so position is on indent if HitInfo.HitPositions = [] then Include(HitInfo.HitPositions, hiOnItemIndent); end else begin // The next hit positions can be: // - on the check box // - on the state image // - on the normal image // - to the left of the text area // - on the label or // - to the right of the text area // (in this order). // In report mode no hit other than in the main column is possible. if MainColumnHit or not (toReportMode in FOptions.FMiscOptions) then begin ImageOffset := Indent + FMargin; // Check support is only available for the main column. if MainColumnHit and (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages) and (HitInfo.HitNode.CheckType <> ctNone) then Inc(ImageOffset, FCheckImages.Height + 2); if MainColumnHit and (Offset < ImageOffset) then begin HitInfo.HitPositions := [hiOnItem]; if (HitInfo.HitNode.CheckType <> ctNone) then Include(HitInfo.HitPositions, hiOnItemCheckBox); end else begin if Assigned(FStateImages) and HasImage(HitInfo.HitNode, ikState, HitInfo.HitColumn) then Inc(ImageOffset, FStateImages.Width + 2); if Offset < ImageOffset then Include(HitInfo.HitPositions, hiOnStateIcon) else begin if Assigned(FImages) and HasImage(HitInfo.HitNode, ikNormal, HitInfo.HitColumn) then Inc(ImageOffset, FImages.Width + 2); if Offset < ImageOffset then Include(HitInfo.HitPositions, hiOnNormalIcon) else begin // ImageOffset contains now the left border of the node label area. This is used to calculate the // correct alignment in the column. TextWidth := DoGetNodeWidth(HitInfo.HitNode, HitInfo.HitColumn); // Check if the text can be aligned at all. This is only possible if there is enough room // in the remaining text rectangle. if TextWidth > Right - ImageOffset then Include(HitInfo.HitPositions, hiOnItemLabel) else begin case Alignment of taCenter: begin Indent := (ImageOffset + Right - TextWidth) div 2; if Offset < Indent then Include(HitInfo.HitPositions, hiOnItemLeft) else if Offset < Indent + TextWidth then Include(HitInfo.HitPositions, hiOnItemLabel) else Include(HitInfo.HitPositions, hiOnItemRight) end; taRightJustify: begin Indent := Right - TextWidth; if Offset < Indent then Include(HitInfo.HitPositions, hiOnItemLeft) else Include(HitInfo.HitPositions, hiOnItemLabel); end; else // taLeftJustify if Offset < ImageOffset + TextWidth then Include(HitInfo.HitPositions, hiOnItemLabel) else Include(HitInfo.HitPositions, hiOnItemRight); end; end; end; end; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DetermineHitPositionRTL(var HitInfo: THitInfo; Offset, Right: Integer; Alignment: TAlignment); // This method determines the hit position within a node with right-to-left orientation. var MainColumnHit: Boolean; Run: PVirtualNode; Indent, TextWidth, ImageOffset: Integer; begin MainColumnHit := HitInfo.HitColumn = FHeader.MainColumn; // If columns are not used or the main column is hit then the tree indentation must be considered too. if MainColumnHit then begin if toFixedIndent in FOptions.FPaintOptions then Dec(Right, FIndent) else begin Run := HitInfo.HitNode; while (Run.Parent <> FRoot) do begin Dec(Right, FIndent); Run := Run.Parent; end; if toShowRoot in FOptions.FPaintOptions then Dec(Right, FIndent); end; end; if Offset >= Right then begin // Position is to the right of calculated indentation which can only happen for the main column. // Check whether it corresponds to a button/checkbox. if (toShowButtons in FOptions.FPaintOptions) and (vsHasChildren in HitInfo.HitNode.States) then begin // Position of button is interpreted very generously to avoid forcing the user // to click exactly into the 9x9 pixels area. The entire node height and one full // indentation level is accepted as button hit. if Offset <= Right + Integer(FIndent) then Include(HitInfo.HitPositions, hiOnItemButton); if Offset <= Right + FPlusBM.Width then Include(HitInfo.HitPositions, hiOnItemButtonExact); end; // no button hit so position is on indent if HitInfo.HitPositions = [] then Include(HitInfo.HitPositions, hiOnItemIndent); end else begin // The next hit positions can be: // - on the check box // - on the state image // - on the normal image // - to the left of the text area // - on the label or // - to the right of the text area // (in this order). // In report mode no hit other than in the main column is possible. if MainColumnHit or not (toReportMode in FOptions.FMiscOptions) then begin ImageOffset := Right - FMargin; // Check support is only available for the main column. if MainColumnHit and (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages) and (HitInfo.HitNode.CheckType <> ctNone) then Dec(ImageOffset, FCheckImages.Height + 2); if MainColumnHit and (Offset > ImageOffset) then begin HitInfo.HitPositions := [hiOnItem]; if (HitInfo.HitNode.CheckType <> ctNone) then Include(HitInfo.HitPositions, hiOnItemCheckBox); end else begin if Assigned(FStateImages) and HasImage(HitInfo.HitNode, ikState, HitInfo.HitColumn) then Dec(ImageOffset, FStateImages.Width + 2); if Offset > ImageOffset then Include(HitInfo.HitPositions, hiOnStateIcon) else begin if Assigned(FImages) and HasImage(HitInfo.HitNode, ikNormal, HitInfo.HitColumn) then Dec(ImageOffset, FImages.Width + 2); if Offset > ImageOffset then Include(HitInfo.HitPositions, hiOnNormalIcon) else begin // ImageOffset contains now the right border of the node label area. This is used to calculate the // correct alignment in the column. TextWidth := DoGetNodeWidth(HitInfo.HitNode, HitInfo.HitColumn); // Check if the text can be aligned at all. This is only possible if there is enough room // in the remaining text rectangle. if TextWidth > ImageOffset then Include(HitInfo.HitPositions, hiOnItemLabel) else begin // Consider bidi mode here. In RTL context does left alignment actually mean right alignment // and vice versa. ChangeBiDiModeAlignment(Alignment); case Alignment of taCenter: begin Indent := (ImageOffset - TextWidth) div 2; if Offset < Indent then Include(HitInfo.HitPositions, hiOnItemLeft) else if Offset < Indent + TextWidth then Include(HitInfo.HitPositions, hiOnItemLabel) else Include(HitInfo.HitPositions, hiOnItemRight) end; taRightJustify: begin Indent := ImageOffset - TextWidth; if Offset < Indent then Include(HitInfo.HitPositions, hiOnItemLeft) else Include(HitInfo.HitPositions, hiOnItemLabel); end; else // taLeftJustify if Offset > TextWidth then Include(HitInfo.HitPositions, hiOnItemRight) else Include(HitInfo.HitPositions, hiOnItemLabel); end; end; end; end; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DetermineNextCheckState(CheckType: TCheckType; CheckState: TCheckState): TCheckState; // Determines the next check state in case the user click the check image or pressed the space key. begin case CheckType of ctTriStateCheckBox, ctCheckBox: if CheckState = csCheckedNormal then Result := csUncheckedNormal else Result := csCheckedNormal; ctRadioButton: Result := csCheckedNormal; ctButton: Result := csUncheckedNormal; else Result := csMixedNormal; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DetermineScrollDirections(X, Y: Integer): TScrollDirections; // Determines which direction the client area must be scrolled depending on the given position. begin Result:= []; if CanAutoScroll then begin // Calculation for wheel panning/scrolling is a bit different to normal auto scroll. if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then begin if (X - FLastClickPos.X) < -8 then Include(Result, sdLeft); if (X - FLastClickPos.X) > 8 then Include(Result, sdRight); if (Y - FLastClickPos.Y) < -8 then Include(Result, sdUp); if (Y - FLastClickPos.Y) > 8 then Include(Result, sdDown); end else begin if (X < Integer(FDefaultNodeHeight)) and (FEffectiveOffsetX <> 0) then Include(Result, sdLeft); if (ClientWidth + FEffectiveOffsetX < Integer(FRangeX)) and (X > ClientWidth - Integer(FDefaultNodeHeight)) then Include(Result, sdRight); //lclheader if (ClientHeight - FOffsetY < Integer(FRangeY)) and (Y > inherited GetClientRect.Bottom - Integer(FDefaultNodeHeight)) then Include(Result, sdDown); if hoVisible in FHeader.FOptions then Dec(Y, FHeader.Height); if (Y < Integer(FDefaultNodeHeight)) and (FOffsetY <> 0) then Include(Result, sdUp); //todo: probably the code below is bug due to poor timeGetTime implementation // Since scrolling during dragging is not handled via the timer we do a check here whether the auto // scroll timeout already has elapsed or not. if (Result <> []) and ((Assigned(FDragManager) and VTVDragManager.IsDropTarget) or (FindDragTarget(Point(X, Y), False) = Self)) then begin if FDragScrollStart = 0 then FDragScrollStart := timeGetTime; // Reset any scroll direction to avoid scroll in the case the user is dragging and the auto scroll time has not // yet elapsed. if ((timeGetTime - FDragScrollStart) < FAutoScrollDelay) then Result := []; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoAdvancedHeaderDraw(var PaintInfo: THeaderPaintInfo; const Elements: THeaderPaintElements); begin if Assigned(FOnAdvancedHeaderDraw) then FOnAdvancedHeaderDraw(FHeader, PaintInfo, Elements); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoAfterCellPaint(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const CellRect: TRect); begin if Assigned(FOnAfterCellPaint) then FOnAfterCellPaint(Self, Canvas, Node, Column, CellRect); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoAfterItemErase(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect); begin if Assigned(FOnAfterItemErase) then FOnAfterItemErase(Self, Canvas, Node, ItemRect); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoAfterItemPaint(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect); begin if Assigned(FOnAfterItemPaint) then FOnAfterItemPaint(Self, Canvas, Node, ItemRect); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoAfterPaint(Canvas: TCanvas); begin if Assigned(FOnAfterPaint) then FOnAfterPaint(Self, Canvas); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoAutoScroll(X, Y: Integer); begin FScrollDirections := DetermineScrollDirections(X, Y); if FStates * [tsWheelPanning, tsWheelScrolling] = [] then begin if FScrollDirections = [] then begin if ((FStates * [tsScrollPending, tsScrolling]) <> []) then begin KillTimer(Handle, ScrollTimer); DoStateChange([], [tsScrollPending, tsScrolling]); end; end else begin // start auto scroll if not yet done if (FStates * [tsScrollPending, tsScrolling]) = [] then begin DoStateChange([tsScrollPending]); SetTimer(Handle, ScrollTimer, FAutoScrollDelay, nil); end; end; end; end; procedure TBaseVirtualTree.DoAutoSize; begin //The default DoAutoSize makes the editors be placed wrongly when scrolling end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoBeforeDrag(Node: PVirtualNode; Column: TColumnIndex): Boolean; begin Result := False; if Assigned(FOnDragAllowed) then FOnDragAllowed(Self, Node, Column, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoBeforeCellPaint(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect); {$ifdef LCLWin32} var UpdateRect: TRect; {$endif} begin //todo: implement under non win32 if Assigned(FOnBeforeCellPaint) then begin {$ifdef LCLWin32} if CellPaintMode = cpmGetContentMargin then begin // Prevent drawing if we are only about to get the margin. As this also clears the update rect we need to save it. GetUpdateRect(Handle, UpdateRect, False); SetUpdateState(True); end; {$endif} FOnBeforeCellPaint(Self, Canvas, Node, Column, CellPaintMode, CellRect, ContentRect); {$ifdef LCLWin32} if CellPaintMode = cpmGetContentMargin then begin SetUpdateState(False); InvalidateRect(Handle, @UpdateRect, False); end; {$endif} end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoBeforeItemErase(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect; var Color: TColor; var EraseAction: TItemEraseAction); begin if Assigned(FOnBeforeItemErase) then FOnBeforeItemErase(Self, Canvas, Node, ItemRect, Color, EraseAction); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoBeforeItemPaint(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect): Boolean; begin // By default custom draw will not be used, so the tree handles drawing the node. Result := False; if Assigned(FOnBeforeItemPaint) then FOnBeforeItemPaint(Self, Canvas, Node, ItemRect, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoBeforePaint(Canvas: TCanvas); begin if Assigned(FOnBeforePaint) then FOnBeforePaint(Self, Canvas); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoCancelEdit: Boolean; // Called when the current edit action or a pending edit must be cancelled. begin KillTimer(Handle, EditTimer); DoStateChange([], [tsEditPending]); Result := (tsEditing in FStates) and FEditLink.CancelEdit; if Result then begin DoStateChange([], [tsEditing]); if Assigned(FOnEditCancelled) then FOnEditCancelled(Self, FEditColumn); FEditLink := nil; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoCanEdit(Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean); begin if Assigned(FOnEditing) then FOnEditing(Self, Node, Column, Allowed); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoChange(Node: PVirtualNode); begin KillTimer(Handle, ChangeTimer); if Assigned(FOnChange) then FOnChange(Self, Node); // This is a good place to reset the cached node. This is the same as the node passed in here. // This is necessary to allow descendants to override this method and get the node then. DoStateChange([], [tsChangePending]); FLastChangedNode := nil; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoCheckClick(Node: PVirtualNode; NewCheckState: TCheckState); begin if ChangeCheckState(Node, NewCheckState) then DoChecked(Node); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoChecked(Node: PVirtualNode); begin if Assigned(FOnChecked) then FOnChecked(Self, Node); {$ifdef EnableAccessible} NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); {$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoChecking(Node: PVirtualNode; var NewCheckState: TCheckState): Boolean; // Determines if a node is allowed to change its check state to NewCheckState. begin if toReadOnly in FOptions.FMiscOptions then Result := False else begin Result := True; if Assigned(FOnChecking) then FOnChecking(Self, Node, NewCheckState, Result); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoCollapsed(Node: PVirtualNode); begin if Assigned(FOnCollapsed) then FOnCollapsed(Self, Node); {$ifdef EnableAccessible} NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); {$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoCollapsing(Node: PVirtualNode): Boolean; begin Result := True; if Assigned(FOnCollapsing) then FOnCollapsing(Self, Node, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoColumnClick(Column: TColumnIndex; Shift: TShiftState); begin if Assigned(FOnColumnClick) then FOnColumnClick(Self, Column, Shift); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoColumnDblClick(Column: TColumnIndex; Shift: TShiftState); begin if Assigned(FOnColumnDblClick) then FOnColumnDblClick(Self, Column, Shift); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoColumnResize(Column: TColumnIndex); var R: TRect; Run: PVirtualNode; begin if not (csLoading in ComponentState) and HandleAllocated then begin // Reset all vsHeightMeasured flags if we are in multiline mode. Run := GetFirstInitialized; while Assigned(Run) do begin if vsMultiline in Run.States then Exclude(Run.States, vsHeightMeasured); Run := GetNextInitialized(Run); end; UpdateHorizontalScrollBar(True); if Column > NoColumn then begin // Invalidate client area from the current column all to the right (or left in RTL mode). R := ClientRect; //lclheader if hoVisible in FHeader.FOptions then Inc(R.Bottom, FHeader.Height); if not (toAutoSpanColumns in FOptions.FAutoOptions) then if UseRightToLeftAlignment then R.Right := FHeader.Columns[Column].Left + FHeader.Columns[Column].Width + ComputeRTLOffset else R.Left := FHeader.Columns[Column].Left; InvalidateRect(Handle, @R, False); FHeader.Invalidate(FHeader.Columns[Column], True); end; if [hsColumnWidthTracking, hsResizing] * FHeader.States = [hsColumnWidthTracking] then UpdateWindow(Handle); if not (tsUpdating in FStates) then UpdateDesigner; // design time only if Assigned(FOnColumnResize) and not (hsResizing in FHeader.States) then FOnColumnResize(FHeader, Column); // If the tree is currently in edit state then notify edit link. if tsEditing in FStates then UpdateEditBounds; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoCompare(Node1, Node2: PVirtualNode; Column: TColumnIndex): Integer; begin Result := 0; if Assigned(FOnCompareNodes) then FOnCompareNodes(Self, Node1, Node2, Column, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoCreateDataObject: IDataObject; begin Result := nil; if Assigned(FOnCreateDataObject) then FOnCreateDataObject(Self, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoCreateDragManager: IVTDragManager; begin Result := nil; if Assigned(FOnCreateDragManager) then FOnCreateDragManager(Self, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoCreateEditor(Node: PVirtualNode; Column: TColumnIndex): IVTEditLink; begin Result := nil; if Assigned(FOnCreateEditor) then begin FOnCreateEditor(Self, Node, Column, Result); if Result = nil then ShowError(SEditLinkIsNil, hcTFEditLinkIsNil); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoDragging(P: TPoint); // Initiates finally the drag'n drop operation and returns after DD is finished. //--------------- local function -------------------------------------------- function GetDragOperations: LongWord; begin if FDragOperations = [] then Result := DROPEFFECT_COPY or DROPEFFECT_MOVE or DROPEFFECT_LINK else begin Result := 0; if doCopy in FDragOperations then Result := Result or DROPEFFECT_COPY; if doLink in FDragOperations then Result := Result or DROPEFFECT_LINK; if doMove in FDragOperations then Result := Result or DROPEFFECT_MOVE; end; end; //--------------- end local function ---------------------------------------- var DragEffect, AllowedEffects: LongWord; I: Integer; DragObject: TDragObject; DataObject: IDataObject; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DoDragging');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcDrag],'Stack');{$endif} DataObject := nil; // Dragging is dragging, nothing else. DoCancelEdit; if Assigned(FCurrentHotNode) then begin InvalidateNode(FCurrentHotNode); FCurrentHotNode := nil; end; // Select the focused node if not already done. if Assigned(FFocusedNode) and not (vsSelected in FFocusedNode.States) then begin InternalAddToSelection(FFocusedNode, False); InvalidateNode(FFocusedNode); end; UpdateWindow(Handle); // Keep a list of all currently selected nodes as this list might change, // but we have probably to delete currently selected nodes. FDragSelection := GetSortedSelection(True); try DoStateChange([tsOLEDragging], [tsOLEDragPending, tsClearPending]); // An application might create a drag object like used during VCL dd. This is not required for OLE dd but // required as parameter. DragObject := nil; DoStartDrag(DragObject); DragObject.Free; DataObject := VTVDragManager.DataObject; PrepareDragImage(P, DataObject); FLastDropMode := dmOnNode; // Don't forget to initialize the result. It might never be touched. DragEffect := DROPEFFECT_NONE; AllowedEffects := GetDragOperations; try DragAndDrop(AllowedEffects, DataObject, DragEffect); VTVDragManager.ForceDragLeave; finally GetCursorPos(P); P := ScreenToClient(P); DoEndDrag(Self, P.X, P.Y); FDragImage.EndDrag; // Finish the operation. if (DragEffect = DROPEFFECT_MOVE) and (toAutoDeleteMovedNodes in TreeOptions.AutoOptions) then begin // The operation was a move so delete the previously selected nodes. BeginUpdate; try // The list of selected nodes was retrieved in resolved state. That means there can never be a node // in the list whose parent (or its parent etc.) is also selected. for I := 0 to High(FDragSelection) do DeleteNode(FDragSelection[I]); finally EndUpdate; end; end; DoStateChange([], [tsOLEDragging]); end; finally FDragSelection := nil; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DoDragging');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoDragExpand; var SourceTree: TBaseVirtualTree; begin KillTimer(Handle, ExpandTimer); if Assigned(FDropTargetNode) and (vsHasChildren in FDropTargetNode.States) and not (vsExpanded in FDropTargetNode.States) then begin if Assigned(FDragManager) then SourceTree := TBaseVirtualTree(VTVDragManager.DragSource) else SourceTree := nil; if not VTVDragManager.DropTargetHelperSupported and Assigned(SourceTree) then SourceTree.FDragImage.HideDragImage; ToggleNode(FDropTargetNode); UpdateWindow(Handle); if not VTVDragManager.DropTargetHelperSupported and Assigned(SourceTree) then SourceTree.FDragImage.ShowDragImage; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoDragOver(Source: TObject; Shift: TShiftState; State: TDragState; const Pt: TPoint; Mode: TDropMode; var Effect: LongWord): Boolean; begin Result := False; if Assigned(FOnDragOver) then FOnDragOver(Self, Source, Shift, State, Pt, Mode, Effect, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoDragDrop(Source: TObject; DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState; const Pt: TPoint; var Effect: LongWord; Mode: TDropMode); begin if Assigned(FOnDragDrop) then FOnDragDrop(Self, Source, {DataObject, }Formats, Shift, Pt, Effect, Mode); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoEdit; begin Application.CancelHint; KillTimer(Handle, ScrollTimer); KillTimer(Handle, EditTimer); DoStateChange([], [tsEditPending]); if Assigned(FFocusedNode) and not (vsDisabled in FFocusedNode.States) and not (toReadOnly in FOptions.FMiscOptions) and (FEditLink = nil) then begin FEditLink := DoCreateEditor(FFocusedNode, FEditColumn); if Assigned(FEditLink) then begin DoStateChange([tsEditing], [tsDrawSelecting, tsDrawSelPending, tsToggleFocusedSelection, tsOLEDragPending, tsOLEDragging, tsClearPending, tsScrollPending, tsScrolling, tsMouseCheckPending]); ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, not (toDisableAutoscrollOnEdit in FOptions.AutoOptions)); if FEditLink.PrepareEdit(Self, FFocusedNode, FEditColumn) then begin UpdateEditBounds; // Node needs repaint because the selection rectangle and static text must disappear. InvalidateNode(FFocusedNode); if not FEditLink.BeginEdit then DoStateChange([], [tsEditing]); end else DoStateChange([], [tsEditing]); if not (tsEditing in FStates) then FEditLink := nil; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoEndDrag(Target: TObject; X, Y: Integer); // Does some housekeeping for VCL drag'n drop; begin inherited; DragFinished; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoEndEdit: Boolean; begin KillTimer(Handle, EditTimer); Result := (tsEditing in FStates) and FEditLink.EndEdit; if Result then begin DoStateChange([], [tsEditing]); FEditLink := nil; if Assigned(FOnEdited) then FOnEdited(Self, FFocusedNode, FEditColumn); end; DoStateChange([], [tsEditPending]); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoExpanded(Node: PVirtualNode); begin if Assigned(FOnExpanded) then FOnExpanded(Self, Node); {$ifdef EnableAccessible} NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); {$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoExpanding(Node: PVirtualNode): Boolean; begin Result := True; if Assigned(FOnExpanding) then FOnExpanding(Self, Node, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoFocusChange(Node: PVirtualNode; Column: TColumnIndex); begin if Assigned(FOnFocusChanged) then FOnFocusChanged(Self, Node, Column); {$ifdef EnableAccessible} NotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); NotifyWinEvent(EVENT_OBJECT_NAMECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); NotifyWinEvent(EVENT_OBJECT_SELECTION, Handle, OBJID_CLIENT, CHILDID_SELF); NotifyWinEvent(EVENT_OBJECT_FOCUS, Handle, OBJID_CLIENT, CHILDID_SELF); {$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoFocusChanging(OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex): Boolean; begin Result := (OldColumn = NewColumn) or FHeader.AllowFocus(NewColumn); if Assigned(FOnFocusChanging) then FOnFocusChanging(Self, OldNode, NewNode, OldColumn, NewColumn, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoFocusNode(Node: PVirtualNode; Ask: Boolean); begin if not (tsEditing in FStates) or EndEditNode then begin if Node = FRoot then Node := nil; if (FFocusedNode <> Node) and (not Ask or DoFocusChanging(FFocusedNode, Node, FFocusedColumn, FFocusedColumn)) then begin if Assigned(FFocusedNode) then begin // Do automatic collapsing of last focused node if enabled. This is however only done if // old and new focused node have a common parent node. if (toAutoExpand in FOptions.FAutoOptions) and Assigned(Node) and (Node.Parent = FFocusedNode.Parent) and (vsExpanded in FFocusedNode.States) then ToggleNode(FFocusedNode) else InvalidateNode(FFocusedNode); end; FFocusedNode := Node; end; // Have to scroll the node into view, even it is the same node as before. if Assigned(FFocusedNode) then begin // Make sure a valid column is set if columns are used and no column has currently the focus. if FHeader.UseColumns and (not FHeader.FColumns.IsValidColumn(FFocusedColumn)) then FFocusedColumn := FHeader.MainColumn; // Do automatic expansion of the newly focused node if enabled. if (toAutoExpand in FOptions.FAutoOptions) and not (vsExpanded in FFocusedNode.States) then ToggleNode(FFocusedNode); InvalidateNode(FFocusedNode); if (FUpdateCount = 0) and not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) then ScrollIntoView(FFocusedNode, (toCenterScrollIntoView in FOptions.SelectionOptions) and (MouseButtonDown * FStates = []), not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions)); end; // Reset range anchor if necessary. if FSelectionCount = 0 then ResetRangeAnchor; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoFreeNode(Node: PVirtualNode); begin if Node = FLastChangedNode then FLastChangedNode := nil; if Node = FCurrentHotNode then FCurrentHotNode := nil; if Node = FDropTargetNode then FDropTargetNode := nil; if Assigned(FOnFreeNode) and ([vsInitialized, vsInitialUserData] * Node.States <> []) then FOnFreeNode(Self, Node); FreeMem(Node); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoGetCellContentMargin(Node: PVirtualNode; Column: TColumnIndex; CellContentMarginType: TVTCellContentMarginType = ccmtAllSides; Canvas: TCanvas = nil): TPoint; // Determines the margins of the content rectangle caused by DoBeforeCellPaint. // Note that shrinking the content rectangle results in positive margins whereas enlarging the content rectangle results // in negative margins. var CellRect, ContentRect: TRect; begin Result := Point(0, 0); if Assigned(FOnBeforeCellPaint) then // Otherwise DoBeforeCellPaint has no effect. begin if Canvas = nil then Canvas := Self.Canvas; // Determine then node's cell rectangle and content rectangle before calling DoBeforeCellPaint. CellRect := GetDisplayRect(Node, Column, True); ContentRect := CellRect; DoBeforeCellPaint(Canvas, Node, Column, cpmGetContentMargin, CellRect, ContentRect); // Calculate the changes caused by DoBeforeCellPaint. case CellContentMarginType of ccmtAllSides: // Calculate the width difference and high difference. Result := Point((CellRect.Right - CellRect.Left) - (ContentRect.Right - ContentRect.Left), (CellRect.Bottom - CellRect.Top) - (ContentRect.Bottom - ContentRect.Top)); ccmtTopLeftOnly: // Calculate the left margin and top margin only. Result := Point(ContentRect.Left - CellRect.Left, ContentRect.Top - CellRect.Top); ccmtBottomRightOnly: // Calculate the right margin and bottom margin only. Result := Point(CellRect.Right - ContentRect.Right, CellRect.Bottom - ContentRect.Bottom); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoGetCursor(var Cursor: TCursor); begin if Assigned(FOnGetCursor) then FOnGetCursor(Self, Cursor); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoGetHeaderCursor(var Cursor: HCURSOR); begin if Assigned(FOnGetHeaderCursor) then FOnGetHeaderCursor(FHeader, Cursor); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoGetImageIndex(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var Index: Integer): TCustomImageList; // Queries the application/descendant about certain image properties for a node. // Returns a custom image list if given by the callee, otherwise nil. begin Result := nil; // First try the enhanced event to allow for custom image lists. if Assigned(FOnGetImageEx) then FOnGetImageEx(Self, Node, Kind, Column, Ghosted, Index, Result) else if Assigned(FOnGetImage) then FOnGetImage(Self, Node, Kind, Column, Ghosted, Index); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoGetImageText(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var ImageText: String); // Queries the application/descendant about alternative image text for a node. begin if Assigned(FOnGetImageText) then FOnGetImageText(Self, Node, Kind, Column, ImageText); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoGetLineStyle(var Bits: Pointer); begin if Assigned(FOnGetLineStyle) then FOnGetLineStyle(Self, Bits); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoGetNodeHint(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; begin Result := Hint; LineBreakStyle := hlbDefault; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoGetNodeTooltip(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; begin Result := Hint; LineBreakStyle := hlbDefault; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer; begin Result := 0; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoGetPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Position: TPoint): TPopupMenu; // Queries the application whether there is a node specific popup menu. var Run: PVirtualNode; AskParent: Boolean; begin Result := nil; if Assigned(FOnGetPopupMenu) then begin Run := Node; if Assigned(Run) then begin AskParent := True; repeat FOnGetPopupMenu(Self, Run, Column, Position, AskParent, Result); Run := Run.Parent; until (Run = FRoot) or Assigned(Result) or not AskParent; end else FOnGetPopupMenu(Self, nil, -1, Position, AskParent, Result); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoGetUserClipboardFormats(var Formats: TFormatEtcArray); begin if Assigned(FOnGetUserClipboardFormats) then FOnGetUserClipboardFormats(Self, Formats); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Assigned(FOnHeaderClick) then FOnHeaderClick(FHeader, Column, Button, Shift, X, Y); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderDblClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Assigned(FOnHeaderDblClick) then FOnHeaderDblClick(FHeader, Column, Button, Shift, X, Y); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderImageClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Assigned(FOnHeaderImageClick) then FOnHeaderImageClick(FHeader, Column, Button, Shift, X, Y) else if Assigned(FOnHeaderClick) then FOnHeaderClick(FHeader, Column, Button, Shift, X, Y) end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderCheckBoxClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Assigned(FOnHeaderCheckBoxClick) then FOnHeaderCheckBoxClick(FHeader, Column, Button, Shift, X, Y); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderDragged(Column: TColumnIndex; OldPosition: TColumnPosition); begin if Assigned(FOnHeaderDragged) then FOnHeaderDragged(FHeader, Column, OldPosition); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderDraggedOut(Column: TColumnIndex; const DropPosition: TPoint); begin if Assigned(FOnHeaderDraggedOut) then FOnHeaderDraggedOut(FHeader, Column, DropPosition); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoHeaderDragging(Column: TColumnIndex): Boolean; begin Result := True; if Assigned(FOnHeaderDragging) then FOnHeaderDragging(FHeader, Column, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderDraw(Canvas: TCanvas; Column: TVirtualTreeColumn; const R: TRect; Hover, Pressed: Boolean; DropMark: TVTDropMarkMode); begin if Assigned(FOnHeaderDraw) then FOnHeaderDraw(FHeader, Canvas, Column, R, Hover, Pressed, DropMark); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderDrawQueryElements(var PaintInfo: THeaderPaintInfo; var Elements: THeaderPaintElements); begin if Assigned(FOnHeaderDrawQueryElements) then FOnHeaderDrawQueryElements(FHeader, PaintInfo, Elements); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Assigned(FOnHeaderMouseDown) then FOnHeaderMouseDown(FHeader, Button, Shift, X, Y); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderMouseMove(Shift: TShiftState; X, Y: Integer); begin if Assigned(FOnHeaderMouseMove) then FOnHeaderMouseMove(FHeader, Shift, X, Y); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHeaderMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Assigned(FOnHeaderMouseUp) then FOnHeaderMouseUp(FHeader, Button, Shift, X, Y); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoHotChange(Old, New: PVirtualNode); begin if Assigned(FOnHotChange) then FOnHotChange(Self, Old, New); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoIncrementalSearch(Node: PVirtualNode; const Text: String): Integer; begin Result := 0; if Assigned(FOnIncrementalSearch) then FOnIncrementalSearch(Self, Node, Text, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoInitChildren(Node: PVirtualNode; var ChildCount: Cardinal); begin if Assigned(FOnInitChildren) then FOnInitChildren(Self, Node, ChildCount); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoInitNode(Parent, Node: PVirtualNode; var InitStates: TVirtualNodeInitStates); begin if Assigned(FOnInitNode) then FOnInitNode(Self, Parent, Node, InitStates); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoKeyAction(var CharCode: Word; var Shift: TShiftState): Boolean; begin Result := True; if Assigned(FOnKeyAction) then FOnKeyAction(Self, CharCode, Shift, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoLoadUserData(Node: PVirtualNode; Stream: TStream); begin if Assigned(FOnLoadNode) then if Node = FRoot then FOnLoadNode(Self, nil, Stream) else FOnLoadNode(Self, Node, Stream); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoMeasureItem(TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer); begin if Assigned(FOnMeasureItem) then FOnMeasureItem(Self, TargetCanvas, Node, NodeHeight); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoNodeCopied(Node: PVirtualNode); begin if Assigned(FOnNodeCopied) then FOnNodeCopied(Self, Node); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoNodeCopying(Node, NewParent: PVirtualNode): Boolean; begin Result := True; if Assigned(FOnNodeCopying) then FOnNodeCopying(Self, Node, NewParent, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoNodeHeightDblClickResize(Node: PVirtualNode; Column: TColumnIndex; Shift: TShiftState; P: TPoint): Boolean; begin Result := True; if Assigned(FOnNodeHeightDblClickResize) then FOnNodeHeightDblClickResize(Self, Node, Column, Shift, P, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoNodeHeightTracking(Node: PVirtualNode; Column: TColumnIndex; Shift: TShiftState; var TrackPoint: TPoint; P: TPoint): Boolean; begin Result := True; if Assigned(FOnNodeHeightTracking) then FOnNodeHeightTracking(Self, Node, Column, Shift, TrackPoint, P, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoNodeMoved(Node: PVirtualNode); begin if Assigned(FOnNodeMoved) then FOnNodeMoved(Self, Node); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoNodeMoving(Node, NewParent: PVirtualNode): Boolean; begin Result := True; if Assigned(FOnNodeMoving) then FOnNodeMoving(Self, Node, NewParent, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoPaintBackground(Canvas: TCanvas; const R: TRect): Boolean; begin Result := False; if Assigned(FOnPaintBackground) then FOnPaintBackground(Self, Canvas, R, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoPaintDropMark(Canvas: TCanvas; Node: PVirtualNode; const R: TRect); // draws the drop mark into the given rectangle // Note: Changed properties of the given canvas should be reset to their previous values. var SaveBrushColor: TColor; SavePenStyle: TPenStyle; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DoPaintDropMark');{$endif} if FLastDropMode in [dmAbove, dmBelow] then with Canvas do begin {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'DropMode in [dmAbove,dmBelow]');{$endif} SavePenStyle := Pen.Style; Pen.Style := psClear; SaveBrushColor := Brush.Color; Brush.Color := FColors.DropMarkColor; {$ifdef DEBUG_VTV}Logger.SendColor([lcDrag],'Brush.Color',Brush.Color);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'R',R);{$endif} if FLastDropMode = dmAbove then begin Polygon([Point(R.Left + 2, R.Top), Point(R.Right - 2, R.Top), Point(R.Right - 2, R.Top + 6), Point(R.Right - 6, R.Top + 2), Point(R.Left + 6 , R.Top + 2), Point(R.Left + 2, R.Top + 6) ]); end else Polygon([Point(R.Left + 2, R.Bottom - 1), Point(R.Right - 2, R.Bottom - 1), Point(R.Right - 2, R.Bottom - 8), Point(R.Right - 7, R.Bottom - 3), Point(R.Left + 7 , R.Bottom - 3), Point(R.Left + 2, R.Bottom - 8) ]); Brush.Color := SaveBrushColor; Pen.Style := SavePenStyle; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DoPaintDropMark');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoPaintNode(var PaintInfo: TVTPaintInfo); begin end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Position: TPoint); // Support for node dependent popup menus. var Menu: TPopupMenu; begin Menu := DoGetPopupMenu(Node, Column, Position); if Assigned(Menu) then begin DoStateChange([tsPopupMenuShown]); KillTimer(Handle, EditTimer); Menu.PopupComponent := Self; with ClientToScreen(Position) do Menu.Popup(X, Y); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; begin Result := E_FAIL; if Assigned(FOnRenderOLEData) then FOnRenderOLEData(Self, FormatEtcIn, Medium, ForClipboard, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoReset(Node: PVirtualNode); begin if Assigned(FOnResetNode) then FOnResetNode(Self, Node); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoSaveUserData(Node: PVirtualNode; Stream: TStream); begin if Assigned(FOnSaveNode) then if Node = FRoot then FOnSaveNode(Self, nil, Stream) else FOnSaveNode(Self, Node, Stream); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoScroll(DeltaX, DeltaY: Integer); begin if Assigned(FOnScroll) then FOnScroll(Self, DeltaX, DeltaY); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoSetOffsetXY(Value: TPoint; Options: TScrollUpdateOptions; ClipRect: PRect = nil): Boolean; // Actual offset setter used to scroll the client area, update scroll bars and invalidating the header (all optional). // Returns True if the offset really changed otherwise False is returned. var DeltaX: Integer; DeltaY: Integer; DWPStructure: THandle;//HDWP; I: Integer; P: TPoint; R: TRect; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcScroll],'DoSetOffsetXY');{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcScroll],'Value',Value);{$endif} //{$ifdef DEBUG_VTV}Logger.SendCallStack([lcScroll],'CallStack');{$endif} // Range check, order is important here. if Value.X < (ClientWidth - Integer(FRangeX)) then Value.X := ClientWidth - Integer(FRangeX); if Value.X > 0 then Value.X := 0; DeltaX := Value.X - FOffsetX; if UseRightToLeftAlignment then DeltaX := -DeltaX; if Value.Y < (ClientHeight - Integer(FRangeY)) then Value.Y := ClientHeight - Integer(FRangeY); if Value.Y > 0 then Value.Y := 0; DeltaY := Value.Y - FOffsetY; {$ifdef DEBUG_VTV}Logger.Send([lcScroll],'FOffsetX: %d FOffsetY: %d',[FOffsetX,FOffsetY]);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcScroll],'DeltaX: %d DeltaY: %d',[DeltaX,DeltaY]);{$endif} Result := (DeltaX <> 0) or (DeltaY <> 0); if Result then begin FOffsetX := Value.X; FOffsetY := Value.Y; Application.CancelHint; if FUpdateCount = 0 then begin // The drag image from VCL controls need special consideration. {$ifndef INCOMPLETE_WINAPI} if tsVCLDragging in FStates then ImageList_DragShowNolock(False); {$endif} if (suoScrollClientArea in Options) and not (tsToggling in FStates) then begin // Have to invalidate the entire window if there's a background. if (toShowBackground in FOptions.FPaintOptions) and (FBackground.Graphic is TBitmap) then begin //todo: reimplement {$ifndef INCOMPLETE_WINAPI} // Since we don't use ScrollWindow here we have to move all client windows ourselves. DWPStructure := BeginDeferWindowPos(ControlCount); for I := 0 to ControlCount - 1 do if Controls[I] is TWinControl then begin with Controls[I] as TWinControl do DWPStructure := DeferWindowPos(DWPStructure, Handle, 0, Left + DeltaX, Top + DeltaY, 0, 0, SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOSIZE); if DWPStructure = 0 then Break; end; if DWPStructure <> 0 then EndDeferWindowPos(DWPStructure); InvalidateRect(Handle, nil, False); {$endif} end else begin if (DeltaX <> 0) and (Header.Columns.GetVisibleFixedWidth > 0) then begin // When fixed columns exists we have to scroll separately horizontally and vertically. // Horizontally is scroll only the client area not occupied by fixed columns and // vertically entire client area (or clipping area if one exists). R := ClientRect; R.Left := Header.Columns.GetVisibleFixedWidth; //lclheader if hoVisible in FHeader.FOptions then begin Inc(R.Top,FHeader.Height); Inc(R.Bottom,FHeader.Height); end; //scrollwindow implementation under gtk is broken {$ifdef Gtk} InvalidateRect(Handle, nil, True); {$else} ScrollWindow(Handle, DeltaX, 0, @R, @R); if DeltaY <> 0 then ScrollWindow(Handle, 0, DeltaY, @R, @R); {$endif} end else begin //lclheader if ClipRect <> nil then begin {$ifdef DEBUG_VTV}Logger.SendWarning([lcWarning], 'DoSetOffsetXY called with a non nil ClipRect');{$endif} R := ClipRect^; end else R := ClientRect; if hoVisible in FHeader.FOptions then begin Inc(R.Top, FHeader.Height); Inc(R.Bottom, FHeader.Height); end; {$ifdef DEBUG_VTV}Logger.Send([lcScroll], 'Rect to Scroll', R);{$endif} //todo: temporary hack to avoid some drawing problems. //Will be removed when scrollwindowex is properly implemented in all widgets {$ifdef LCLQt} ScrollWindow(Handle, DeltaX, DeltaY, @R, @R); {$else} {$ifdef Gtk} InvalidateRect(Handle, nil, True); {$else} ScrollWindowEx(Handle, DeltaX, DeltaY, @R, @R,0, nil, SW_INVALIDATE or SW_SCROLLCHILDREN); {$endif} {$endif} end; end; end; if suoUpdateNCArea in Options then begin if DeltaX <> 0 then begin if (suoRepaintHeader in Options) and (hoVisible in FHeader.FOptions) then FHeader.Invalidate(nil); if not (tsSizing in FStates) and (FScrollBarOptions.ScrollBars in [ssHorizontal, ssBoth]) then UpdateHorizontalScrollBar(suoRepaintScrollbars in Options); end; if (DeltaY <> 0) and ([tsThumbTracking, tsSizing] * FStates = []) then begin UpdateVerticalScrollBar(suoRepaintScrollbars in Options); if not (FHeader.UseColumns or IsMouseSelecting) and (FScrollBarOptions.ScrollBars in [ssHorizontal, ssBoth]) then UpdateHorizontalScrollBar(suoRepaintScrollbars in Options); end; end; {$ifndef INCOMPLETE_WINAPI} if tsVCLDragging in FStates then ImageList_DragShowNolock(True); {$endif} end; // Finally update "hot" node if hot tracking is activated GetCursorPos(P); P := ScreenToClient(P); if PtInRect(ClientRect, P) then HandleHotTrack(P.X, P.Y); DoScroll(DeltaX, DeltaY); end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcScroll],'DoSetOffsetXY');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoShowScrollbar(Bar: Integer; Show: Boolean); begin {$ifdef UseFlatScrollbars} FlatSB_ShowScrollBar(Handle, Bar, Show); {$else} ShowScrollBar(Handle, Bar, Show); {$endif UseFlatScrollbars}; if Assigned(FOnShowScrollbar) then FOnShowScrollbar(Self, Bar, Show); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoStartDrag(var DragObject: TDragObject); begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DoStartDrag');{$endif} {$ifdef DEBUG_VTV}Logger.SendCallStack([lcDrag],'Stack');{$endif} inherited; // Check if the application created an own drag object. This is needed to pass the correct source in // OnDragOver and OnDragDrop. if Assigned(DragObject) then DoStateChange([tsUserDragObject]); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DoStartDrag');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoStateChange(Enter: TVirtualTreeStates; Leave: TVirtualTreeStates = []); var ActualEnter, ActualLeave: TVirtualTreeStates; begin if Assigned(FOnStateChange) then begin ActualEnter := Enter - FStates; ActualLeave := FStates * Leave; if (ActualEnter + ActualLeave) <> [] then FOnStateChange(Self, Enter, Leave); end; FStates := FStates + Enter - Leave; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoStructureChange(Node: PVirtualNode; Reason: TChangeReason); begin if HandleAllocated then KillTimer(Handle, StructureChangeTimer); if Assigned(FOnStructureChange) then FOnStructureChange(Self, Node, Reason); // This is a good place to reset the cached node and reason. These are the same as the values passed in here. // This is necessary to allow descendants to override this method and get them. DoStateChange([], [tsStructureChangePending]); FLastStructureChangeNode := nil; FLastStructureChangeReason := crIgnore; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoTimerScroll; var P, ClientP: TPoint; InRect, Panning: Boolean; R, ClipRect: TRect; DeltaX, DeltaY: Integer; begin GetCursorPos(P); //lclheader R := inherited GetClientRect; ClipRect := R; {$ifndef INCOMPLETE_WINAPI} MapWindowPoints(Handle, 0, R, 2); {$endif} InRect := PtInRect(R, P); ClientP := ScreenToClient(P); Panning := [tsWheelPanning, tsWheelScrolling] * FStates <> []; if IsMouseSelecting or InRect or Panning or CanScroll(ClientP) then begin DeltaX := 0; DeltaY := 0; if sdUp in FScrollDirections then begin if Panning then DeltaY := FLastClickPos.Y - ClientP.Y - 8 else if InRect then DeltaY := Min(FScrollBarOptions.FIncrementY, ClientHeight) else DeltaY := Min(FScrollBarOptions.FIncrementY, ClientHeight) * Abs(R.Top - P.Y); if FOffsetY = 0 then Exclude(FScrollDirections, sdUp); end; if sdDown in FScrollDirections then begin if Panning then DeltaY := FLastClickPos.Y - ClientP.Y + 8 else if InRect then DeltaY := -Min(FScrollBarOptions.FIncrementY, ClientHeight) else DeltaY := -Min(FScrollBarOptions.FIncrementY, ClientHeight) * Abs(P.Y - R.Bottom); if (ClientHeight - FOffsetY) = Integer(FRangeY) then Exclude(FScrollDirections, sdDown); end; if sdLeft in FScrollDirections then begin if Panning then DeltaX := FLastClickPos.X - ClientP.X - 8 else if InRect then DeltaX := FScrollBarOptions.FIncrementX else DeltaX := FScrollBarOptions.FIncrementX * Abs(R.Left - P.X); if FEffectiveOffsetX = 0 then Exclude(FScrollDirections, sdleft); end; if sdRight in FScrollDirections then begin if Panning then DeltaX := FLastClickPos.X - ClientP.X + 8 else if InRect then DeltaX := -FScrollBarOptions.FIncrementX else DeltaX := -FScrollBarOptions.FIncrementX * Abs(P.X - R.Right); if (ClientWidth + FEffectiveOffsetX) = Integer(FRangeX) then Exclude(FScrollDirections, sdRight); end; if UseRightToLeftAlignment then DeltaX := - DeltaX; if IsMouseSelecting then begin // In order to avoid scrolling the area which needs a repaint due to the changed selection rectangle // we limit the scroll area explicitely. OffsetRect(ClipRect, DeltaX, DeltaY); DoSetOffsetXY(Point(FOffsetX + DeltaX, FOffsetY + DeltaY), DefaultScrollUpdateFlags, @ClipRect); // When selecting with the mouse then either update only the parts of the window which have been uncovered // by the scroll operation if no change in the selection happend or invalidate and redraw the entire // client area otherwise (to avoid the time consuming task of determining the display rectangles of every // changed node). if CalculateSelectionRect(ClientP.X, ClientP.Y) and HandleDrawSelection(ClientP.X, ClientP.Y) then InvalidateRect(Handle, nil, False) else begin // The selection did not change so invalidate only the part of the window which really needs an update. // 1) Invalidate the parts uncovered by the scroll operation. Add another offset range, we have to // scroll only one stripe but have to update two. OffsetRect(ClipRect, DeltaX, DeltaY); SubtractRect(ClipRect, ClientRect, ClipRect); InvalidateRect(Handle, @ClipRect, False); // 2) Invalidate the selection rectangles. UnionRect(ClipRect, OrderRect(FNewSelRect), OrderRect(FLastSelRect)); OffsetRect(ClipRect, FOffsetX, FOffsetY); InvalidateRect(Handle, @ClipRect, False); end; end else begin // Scroll only if there is no drag'n drop in progress. Drag'n drop scrolling is handled in DragOver. if ((FDragManager = nil) or not VTVDragManager.IsDropTarget) and ((DeltaX <> 0) or (DeltaY <> 0)) then DoSetOffsetXY(Point(FOffsetX + DeltaX, FOffsetY + DeltaY), DefaultScrollUpdateFlags, nil); end; UpdateWindow(Handle); if (FScrollDirections = []) and ([tsWheelPanning, tsWheelScrolling] * FStates = []) then begin KillTimer(Handle, ScrollTimer); DoStateChange([], [tsScrollPending, tsScrolling]); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DoUpdating(State: TVTUpdateState); begin if Assigned(FOnUpdating) then FOnUpdating(Self, State); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DoValidateCache: Boolean; // This method fills the cache, which is used to speed up searching for nodes. // The strategy is simple: Take the current number of visible nodes and distribute evenly a number of marks // (which are stored in FPositionCache) so that iterating through the tree doesn't cost too much time. // If there are less than 'CacheThreshold' nodes in the tree then the cache remains empty. // Result is True if the cache was filled without interruption, otherwise False. // Note: You can adjust the maximum number of nodes between two cache entries by changing CacheThreshold. var EntryCount, CurrentTop, Index: Cardinal; CurrentNode, Temp: PVirtualNode; begin EntryCount := 0; if not (tsStopValidation in FStates) then begin if FStartIndex = 0 then FPositionCache := nil; if FVisibleCount > CacheThreshold then begin EntryCount := CalculateCacheEntryCount; SetLength(FPositionCache, EntryCount); if FStartIndex > EntryCount then FStartIndex := EntryCount; // Optimize validation by starting with FStartIndex if set. if (FStartIndex > 0) and Assigned(FPositionCache[FStartIndex - 1].Node) then begin // Index is the current entry in FPositionCache. Index := FStartIndex - 1; // Running term for absolute top value. CurrentTop := FPositionCache[Index].AbsoluteTop; // Running node pointer. CurrentNode := FPositionCache[Index].Node; end else begin // Index is the current entry in FPositionCache. Index := 0; // Running term for absolute top value. CurrentTop := 0; // Running node pointer. CurrentNode := GetFirstVisibleNoInit(nil, True); end; // EntryCount serves as counter for processed nodes here. This value can always start at 0 as // the validation either starts also at index 0 or an index which is always a multiple of CacheThreshold // and EntryCount is only used with modulo CacheThreshold. EntryCount := 0; if Assigned(CurrentNode) then begin while not (tsStopValidation in FStates) do begin if (EntryCount mod CacheThreshold) = 0 then begin // New cache entry to set up. with FPositionCache[Index] do begin Node := CurrentNode; AbsoluteTop := CurrentTop; end; Inc(Index); end; Inc(CurrentTop, NodeHeight[CurrentNode]); // Advance to next visible node. Temp := GetNextVisibleNoInit(CurrentNode, True); // If there is no further node or the cache is full then stop the loop. if (Temp = nil) or (Integer(Index) = Length(FPositionCache)) then Break; CurrentNode := Temp; Inc(EntryCount); end; end; // Finalize the position cache so no nil entry remains there. if not (tsStopValidation in FStates) and (Integer(Index) <= High(FPositionCache)) then begin SetLength(FPositionCache, Index + 1); with FPositionCache[Index] do begin Node := CurrentNode; AbsoluteTop := CurrentTop; end; end; end; end; Result := (EntryCount > 0) and not (tsStopValidation in FStates); // In variable node height mode it might have happend that some or all of the nodes have been adjusted in their // height. During validation updates of the scrollbars is disabled so let's do this here. if Result and (toVariableNodeHeight in FOptions.FMiscOptions) then UpdateScrollbars(True); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DragAndDrop(AllowedEffects: LongWord; DataObject: IDataObject; DragEffect: LongWord); begin {$ifdef Windows} ActiveX.DoDragDrop(DataObject, VTVDragManager as IDropSource, AllowedEffects, @DragEffect); {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DragCanceled; // Does some housekeeping for VCL drag'n drop; begin inherited; DragFinished; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DragDrop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; var Shift: TShiftState; EnumFormat: IEnumFormatEtc; Fetched: LongWord; OLEFormat: TFormatEtc; Formats: TFormatArray; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DragDrop');{$endif} KillTimer(Handle, ExpandTimer); KillTimer(Handle, ScrollTimer); DoStateChange([], [tsScrollPending, tsScrolling]); Formats := nil; // Ask explicitly again whether the action is allowed. Otherwise we may accept a drop which is intentionally not // allowed but cannot be prevented by the application because when the tree was scrolling while dropping // no DragOver event is created by the OLE subsystem. Result := DragOver(VTVDragManager.DragSource, KeyState, dsDragMove, Pt, Effect); try if (Result <> NOERROR) or ((Effect and not DROPEFFECT_SCROLL) = DROPEFFECT_NONE) then Result := E_FAIL else begin try Shift := KeysToShiftState(KeyState); if tsLeftButtonDown in FStates then Include(Shift, ssLeft); if tsMiddleButtonDown in FStates then Include(Shift, ssMiddle); if tsRightButtonDown in FStates then Include(Shift, ssRight); Pt := ScreenToClient(Pt); // Determine which formats we can get and pass them along with the data object to the drop handler. Result := DataObject.EnumFormatEtc(DATADIR_GET, EnumFormat); if Failed(Result) then Abort; Result := EnumFormat.Reset; if Failed(Result) then Abort; // create a list of available formats while EnumFormat.Next(1, OLEFormat, @Fetched) = S_OK do begin SetLength(Formats, Length(Formats) + 1); Formats[High(Formats)] := OLEFormat.cfFormat; end; DoDragDrop(VTVDragManager.DragSource, DataObject, Formats, Shift, Pt, Effect, FLastDropMode); except // An unhandled exception here leaks memory. Application.HandleException(Self); Result := E_UNEXPECTED; end; end; finally if Assigned(FDropTargetNode) then begin InvalidateNode(FDropTargetNode); FDropTargetNode := nil; end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DragDrop');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DragEnter(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; // callback routine for the drop target interface var Shift: TShiftState; Accept: Boolean; R: TRect; HitInfo: THitInfo; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DragEnter');{$endif} try // Determine acceptance of drag operation and reset scroll start time. FDragScrollStart := 0; Shift := KeysToShiftState(KeyState); if tsLeftButtonDown in FStates then Include(Shift, ssLeft); if tsMiddleButtonDown in FStates then Include(Shift, ssMiddle); if tsRightButtonDown in FStates then Include(Shift, ssRight); Pt := ScreenToClient(Pt); Effect := SuggestDropEffect(VTVDragManager.DragSource, Shift, Pt, Effect); Accept := DoDragOver(VTVDragManager.DragSource, Shift, dsDragEnter, Pt, FLastDropMode, Effect); if not Accept then Effect := DROPEFFECT_NONE else begin // Set initial drop target node and drop mode. GetHitTestInfoAt(Pt.X, Pt.Y, True, HitInfo); if Assigned(HitInfo.HitNode) then begin FDropTargetNode := HitInfo.HitNode; R := GetDisplayRect(HitInfo.HitNode, FHeader.MainColumn, False); if hiOnItemLabel in HitInfo.HitPositions then FLastDropMode := dmOnNode else if ((R.Top + R.Bottom) div 2) > Pt.Y then FLastDropMode := dmAbove else FLastDropMode := dmBelow; end else FLastDropMode := dmNowhere; end; // If the drag source is a virtual tree then we know how to control the drag image // and can show it even if the source is not the target tree. // This is only necessary if we cannot use the drag image helper interfaces. if not VTVDragManager.DropTargetHelperSupported and Assigned(VTVDragManager.DragSource) then TBaseVirtualTree(VTVDragManager.DragSource).FDragImage.ShowDragImage; Result := NOERROR; except Result := E_UNEXPECTED; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DragEnter');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DragFinished; // Called by DragCancelled or EndDrag to make up for the still missing mouse button up messages. // These are important for such important things like popup menus. var P: TPoint; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DragFinished');{$endif} DoStateChange([], [tsVCLDragPending, tsVCLDragging, tsUserDragObject]); GetCursorPos(P); P := ScreenToClient(P); if tsRightButtonDown in FStates then Perform(LM_RBUTTONUP, 0, Longint(PointToSmallPoint(P))) else if tsMiddleButtonDown in FStates then Perform(LM_MBUTTONUP, 0, Longint(PointToSmallPoint(P))) else Perform(LM_LBUTTONUP, 0, Longint(PointToSmallPoint(P))); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DragFinished');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DragLeave; var Effect: LongWord; begin KillTimer(Handle, ExpandTimer); if not VTVDragManager.DropTargetHelperSupported and Assigned(VTVDragManager.DragSource) then TBaseVirtualTree(VTVDragManager.DragSource).FDragImage.HideDragImage; if Assigned(FDropTargetNode) then begin InvalidateNode(FDropTargetNode); FDropTargetNode := nil; end; UpdateWindow(Handle); Effect := 0; DoDragOver(nil, [], dsDragLeave, Point(0, 0), FLastDropMode, Effect); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.DragOver(Source: TObject; KeyState: LongWord; DragState: TDragState; Pt: TPoint; var Effect: LongWord): HResult; // callback routine for the drop target interface var Shift: TShiftState; Accept, DragImageWillMove, WindowScrolled: Boolean; OldR, R: TRect; NewDropMode: TDropMode; HitInfo: THitInfo; ImageHit: Boolean; LabelHit: Boolean; DragPos: TPoint; Tree: TBaseVirtualTree; LastNode: PVirtualNode; DeltaX, DeltaY: Integer; ScrollOptions: TScrollUpdateOptions; begin //{$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DragOver');{$endif} //todo: the check to FDragManager disable drag images in non windows. //This should be reviewed as soon as drag image is implemented in non windows if Assigned(FDragManager) and not VTVDragManager.DropTargetHelperSupported and (Source is TBaseVirtualTree) then begin Tree := Source as TBaseVirtualTree; ScrollOptions := [suoUpdateNCArea]; end else begin Tree := nil; ScrollOptions := DefaultScrollUpdateFlags; end; try DragPos := Pt; Pt := ScreenToClient(Pt); //{$ifdef DEBUG_VTV}Logger.Send([lcDrag],'Pt',Pt);{$endif} // Check if we have to scroll the client area. FScrollDirections := DetermineScrollDirections(Pt.X, Pt.Y); DeltaX := 0; DeltaY := 0; if FScrollDirections <> [] then begin // Determine amount to scroll. if sdUp in FScrollDirections then begin DeltaY := Min(FScrollBarOptions.FIncrementY, ClientHeight); if FOffsetY = 0 then Exclude(FScrollDirections, sdUp); end; if sdDown in FScrollDirections then begin DeltaY := -Min(FScrollBarOptions.FIncrementY, ClientHeight); if (ClientHeight - FOffsetY) = Integer(FRangeY) then Exclude(FScrollDirections, sdDown); end; if sdLeft in FScrollDirections then begin DeltaX := FScrollBarOptions.FIncrementX; if FEffectiveOffsetX = 0 then Exclude(FScrollDirections, sdleft); end; if sdRight in FScrollDirections then begin DeltaX := -FScrollBarOptions.FIncrementX; if (ClientWidth + FEffectiveOffsetX) = Integer(FRangeX) then Exclude(FScrollDirections, sdRight); end; WindowScrolled := DoSetOffsetXY(Point(FOffsetX + DeltaX, FOffsetY + DeltaY), ScrollOptions, nil); end else WindowScrolled := False; // Determine acceptance of drag operation as well as drag target. Shift := KeysToShiftState(KeyState); if tsLeftButtonDown in FStates then Include(Shift, ssLeft); if tsMiddleButtonDown in FStates then Include(Shift, ssMiddle); if tsRightButtonDown in FStates then Include(Shift, ssRight); GetHitTestInfoAt(Pt.X, Pt.Y, True, HitInfo); ImageHit := HitInfo.HitPositions * [hiOnNormalIcon, hiOnStateIcon] <> []; LabelHit := hiOnItemLabel in HitInfo.HitPositions; // In report mode only direct hits of the node captions/images in the main column are accepted as hits. if (toReportMode in FOptions.FMiscOptions) and not ((LabelHit or ImageHit) and (HitInfo.HitColumn = FHeader.MainColumn)) then HitInfo.HitNode := nil; if Assigned(HitInfo.HitNode) then begin R := GetDisplayRect(HitInfo.HitNode, NoColumn, False); if LabelHit or ImageHit or not (toShowDropmark in FOptions.FPaintOptions) then NewDropMode := dmOnNode else if ((R.Top + R.Bottom) div 2) > Pt.Y then NewDropMode := dmAbove else NewDropMode := dmBelow; end else begin NewDropMode := dmNowhere; R := Rect(0, 0, 0, 0); end; if Assigned(Tree) then DragImageWillMove := Tree.FDragImage.WillMove(DragPos) else DragImageWillMove := False; if (HitInfo.HitNode <> FDropTargetNode) or (FLastDropMode <> NewDropMode) then begin // Something in the tree will change. This requires to update the screen and/or the drag image. FLastDropMode := NewDropMode; if HitInfo.HitNode <> FDropTargetNode then begin KillTimer(Handle, ExpandTimer); // The last target node is needed for the rectangle determination but must already be set for // the recapture call, hence it must be stored somewhere. LastNode := FDropTargetNode; FDropTargetNode := HitInfo.HitNode; // In order to show a selection rectangle a column must be focused. if FFocusedColumn <= NoColumn then FFocusedColumn := FHeader.MainColumn; if Assigned(LastNode) and Assigned(FDropTargetNode) then begin // Optimize the case that the selection moved between two nodes. OldR := GetDisplayRect(LastNode, NoColumn, False); UnionRect(R, R, OldR); if Assigned(Tree) then begin if WindowScrolled then UpdateWindowAndDragImage(Tree, ClientRect, True, not DragImageWillMove) else UpdateWindowAndDragImage(Tree, R, False, not DragImageWillMove); end else InvalidateRect(Handle, @R, False); end else begin if Assigned(LastNode) then begin // Repaint last target node. OldR := GetDisplayRect(LastNode, NoColumn, False); if Assigned(Tree) then begin if WindowScrolled then UpdateWindowAndDragImage(Tree, ClientRect, WindowScrolled, not DragImageWillMove) else UpdateWindowAndDragImage(Tree, OldR, False, not DragImageWillMove); end else InvalidateRect(Handle, @OldR, False); end else begin if Assigned(Tree) then begin if WindowScrolled then UpdateWindowAndDragImage(Tree, ClientRect, WindowScrolled, not DragImageWillMove) else UpdateWindowAndDragImage(Tree, R, False, not DragImageWillMove); end else InvalidateRect(Handle, @R, False); end; end; // Start auto expand timer if necessary. if (toAutoDropExpand in FOptions.FAutoOptions) and Assigned(FDropTargetNode) and (vsHasChildren in FDropTargetNode.States) then SetTimer(Handle, ExpandTimer, FAutoExpandDelay, nil); end else begin // Only the drop mark position changed so invalidate the current drop target node. if Assigned(Tree) then begin if WindowScrolled then UpdateWindowAndDragImage(Tree, ClientRect, WindowScrolled, not DragImageWillMove) else UpdateWindowAndDragImage(Tree, R, False, not DragImageWillMove); end else InvalidateRect(Handle, @R, False); end; end else begin // No change in the current drop target or drop mode. This might still mean horizontal or vertical scrolling. if Assigned(Tree) and ((DeltaX <> 0) or (DeltaY <> 0)) then UpdateWindowAndDragImage(Tree, ClientRect, WindowScrolled, not DragImageWillMove); end; Update; if Assigned(Tree) and DragImageWillMove then Tree.FDragImage.DragTo(DragPos, False); Effect := SuggestDropEffect(Source, Shift, Pt, Effect); Accept := DoDragOver(Source, Shift, DragState, Pt, FLastDropMode, Effect); if not Accept then Effect := DROPEFFECT_NONE; if WindowScrolled then Effect := Effect or LongWord(DROPEFFECT_SCROLL); Result := NOERROR; except Result := E_UNEXPECTED; end; //{$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DragOver');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DrawDottedHLine(const PaintInfo: TVTPaintInfo; Left, Right, Top: Integer); // Draws a horizontal line with alternating pixels (this style is not supported for pens under Win9x). var R: TRect; begin with PaintInfo, Canvas do begin Brush.Color := Self.Brush.Color; R := Rect(Min(Left, Right), Top, Max(Left, Right) + 1, Top + 1); LCLIntf.FillRect(Handle, R, FDottedBrush); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DrawDottedVLine(const PaintInfo: TVTPaintInfo; Top, Bottom, Left: Integer); // Draws a vertical line with alternating pixels (this style is not supported for pens under Win9x). var R: TRect; begin with PaintInfo, Canvas do begin Brush.Color := Self.Brush.Color; R := Rect(Left, Min(Top, Bottom), Left + 1, Max(Top, Bottom) + 1); LCLIntf.FillRect(Handle, R, FDottedBrush); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.EndOperation; // Called to indicate that a long-running operation has finished. begin Assert(FOperationCount > 0, 'EndOperation must not be called when no operation in progress.'); Dec(FOperationCount); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.FindNodeInSelection(P: PVirtualNode; out Index: Integer; LowBound, HighBound: Integer): Boolean; // Search routine to find a specific node in the selection array. // LowBound and HighBound determine the range in which to search the node. // Either value can be -1 to denote the maximum range otherwise LowBound must be less or equal HighBound. var L, H, I, C: PtrInt; begin Result := False; L := 0; if LowBound >= 0 then L := LowBound; H := FSelectionCount - 1; if HighBound >= 0 then H := HighBound; while L <= H do begin I := (L + H) shr 1; C := PtrInt(FSelection[I]) - PtrInt(P); if C < 0 then L := I + 1 else begin H := I - 1; if C = 0 then begin Result := True; L := I; end; end; end; Index := L; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.FinishChunkHeader(Stream: TStream; StartPos, EndPos: Integer); // used while streaming out a node to finally write out the size of the chunk var Size: Integer; begin // seek back to the second entry in the chunk header Stream.Position := StartPos + SizeOf(Integer); // determine size of chunk without the chunk header Size := EndPos - StartPos - SizeOf(TChunkHeader); // write the size... Stream.Write(Size, SizeOf(Size)); // ... and seek to the last endposition Stream.Position := EndPos; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.FontChanged(AFont: TObject); // Little helper function for font changes (as they are not tracked in TBitmap/TCanvas.OnChange). begin FFontChanged := True; FOldFontChange(AFont); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetBorderDimensions: TSize; // Returns the overall width of the current window border, depending on border styles. // Note: these numbers represent the system's standards not special properties, which can be set for TWinControl // (e.g. bevels, border width). var Styles: Integer; begin Result.cx := 0; Result.cy := 0; Styles := GetWindowLong(Handle, GWL_STYLE); if (Styles and WS_BORDER) <> 0 then begin Dec(Result.cx); Dec(Result.cy); end; if (Styles and WS_THICKFRAME) <> 0 then begin Dec(Result.cx, GetSystemMetrics(SM_CXFIXEDFRAME)); Dec(Result.cy, GetSystemMetrics(SM_CYFIXEDFRAME)); end; Styles := GetWindowLong(Handle, GWL_EXSTYLE); if (Styles and WS_EX_CLIENTEDGE) <> 0 then begin Dec(Result.cx, GetSystemMetrics(SM_CXEDGE)); Dec(Result.cy, GetSystemMetrics(SM_CYEDGE)); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetCheckImage(Node: PVirtualNode; ImgCheckType: TCheckType = ctNone; ImgCheckState: TCheckState = csUncheckedNormal; ImgEnabled: Boolean = False): Integer; // Determines the index into the check image list for the given node depending on the check type // and enabled state. const // Four dimensional array consisting of image indices for the check type, the check state, the enabled state and the // hot state. CheckStateToCheckImage: array[ctCheckBox..ctButton, csUncheckedNormal..csMixedPressed, Boolean, Boolean] of Integer = ( // ctCheckBox, ctTriStateCheckBox ( // csUncheckedNormal (disabled [not hot, hot], enabled [not hot, hot]) ((ckCheckUncheckedDisabled, ckCheckUncheckedDisabled), (ckCheckUncheckedNormal, ckCheckUncheckedHot)), // csUncheckedPressed (disabled [not hot, hot], enabled [not hot, hot]) ((ckCheckUncheckedDisabled, ckCheckUncheckedDisabled), (ckCheckUncheckedPressed, ckCheckUncheckedPressed)), // csCheckedNormal ((ckCheckCheckedDisabled, ckCheckCheckedDisabled), (ckCheckCheckedNormal, ckCheckCheckedHot)), // csCheckedPressed ((ckCheckCheckedDisabled, ckCheckCheckedDisabled), (ckCheckCheckedPressed, ckCheckCheckedPressed)), // csMixedNormal ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedNormal, ckCheckMixedHot)), // csMixedPressed ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedPressed, ckCheckMixedPressed)) ), // ctRadioButton ( // csUncheckedNormal (disabled [not hot, hot], enabled [not hot, hot]) ((ckRadioUncheckedDisabled, ckRadioUncheckedDisabled), (ckRadioUncheckedNormal, ckRadioUncheckedHot)), // csUncheckedPressed (disabled [not hot, hot], enabled [not hot, hot]) ((ckRadioUncheckedDisabled, ckRadioUncheckedDisabled), (ckRadioUncheckedPressed, ckRadioUncheckedPressed)), // csCheckedNormal ((ckRadioCheckedDisabled, ckRadioCheckedDisabled), (ckRadioCheckedNormal, ckRadioCheckedHot)), // csCheckedPressed ((ckRadioCheckedDisabled, ckRadioCheckedDisabled), (ckRadioCheckedPressed, ckRadioCheckedPressed)), // csMixedNormal (should never appear with ctRadioButton) ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedNormal, ckCheckMixedHot)), // csMixedPressed (should never appear with ctRadioButton) ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedPressed, ckCheckMixedPressed)) ), // ctButton ( // csUncheckedNormal (disabled [not hot, hot], enabled [not hot, hot]) ((ckButtonDisabled, ckButtonDisabled), (ckButtonNormal, ckButtonHot)), // csUncheckedPressed (disabled [not hot, hot], enabled [not hot, hot]) ((ckButtonDisabled, ckButtonDisabled), (ckButtonPressed, ckButtonPressed)), // csCheckedNormal ((ckButtonDisabled, ckButtonDisabled), (ckButtonNormal, ckButtonHot)), // csCheckedPressed ((ckButtonDisabled, ckButtonDisabled), (ckButtonPressed, ckButtonPressed)), // csMixedNormal (should never appear with ctButton) ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedNormal, ckCheckMixedHot)), // csMixedPressed (should never appear with ctButton) ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedPressed, ckCheckMixedPressed)) ) ); var AType: TCheckType; begin if not Assigned(Node) then Result := CheckStateToCheckImage[ImgCheckType, ImgCheckState, ImgEnabled, False] else if Node.CheckType = ctNone then Result := -1 else begin AType := Node.CheckType; if AType = ctTriStateCheckBox then AType := ctCheckBox; Result := CheckStateToCheckImage[AType, Node.CheckState, not (vsDisabled in Node.States) and Enabled, Node = FCurrentHotNode]; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CheckImageListNeeded; begin if FCheckImages <> nil then Exit; if FCheckImageKind = ckCustom then FCheckImages := FCustomCheckImages else begin FCheckImages := TBitmap.Create; FCheckImages.Transparent := True; FCheckImages.LoadFromLazarusResource(CheckImagesStrings[FCheckImageKind]); end; end; function TBaseVirtualTree.GetClientRect: TRect; begin Result := inherited; //lclheader if HandleAllocated and (hoVisible in FHeader.FOptions) then Dec(Result.Bottom, FHeader.Height); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetColumnClass: TVirtualTreeColumnClass; begin Result := TVirtualTreeColumn; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetHeaderClass: TVTHeaderClass; begin Result := TVTHeader; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetHintWindowClass: THintWindowClass; // Returns the default hint window class used for the tree. Descendants can override it to use their own classes. begin Result := TVirtualTreeHintWindow; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.GetImageIndex(var Info: TVTPaintInfo; Kind: TVTImageKind; InfoIndex: TVTImageInfoIndex; DefaultImages: TCustomImageList); // Retrieves the image index and an eventual customized image list for drawing. var CustomImages: TCustomImageList; begin with Info do begin ImageInfo[InfoIndex].Index := -1; ImageInfo[InfoIndex].Ghosted := False; CustomImages := DoGetImageIndex(Node, Kind, Column, ImageInfo[InfoIndex].Ghosted, ImageInfo[InfoIndex].Index); if Assigned(CustomImages) then ImageInfo[InfoIndex].Images := CustomImages else ImageInfo[InfoIndex].Images := DefaultImages; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetMaxRightExtend: Cardinal; // Determines the maximum with of the currently visible part of the tree, depending on the length // of the node texts. This method is used for determining the horizontal scroll range if no columns are used. var Node, NextNode: PVirtualNode; TopPosition: Integer; NodeLeft, CurrentWidth: Integer; WithCheck: Boolean; CheckOffset: Integer; begin Node := InternalGetNodeAt(0, 0, True, TopPosition); Result := 0; if toShowRoot in FOptions.FPaintOptions then NodeLeft := (GetNodeLevel(Node) + 1) * FIndent else NodeLeft := GetNodeLevel(Node) * FIndent; if Assigned(FStateImages) then Inc(NodeLeft, FStateImages.Width + 2); if Assigned(FImages) then Inc(NodeLeft, FImages.Width + 2); WithCheck := (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages); if WithCheck then CheckOffset := FCheckImages.Height + 2 else CheckOffset := 0; while Assigned(Node) do begin if not (vsInitialized in Node.States) then InitNode(Node); if WithCheck and (Node.CheckType <> ctNone) then Inc(NodeLeft, CheckOffset); CurrentWidth := DoGetNodeWidth(Node, NoColumn); if Integer(Result) < (NodeLeft + CurrentWidth) then Result := NodeLeft + CurrentWidth; Inc(TopPosition, NodeHeight[Node]); //lclheader: Height -> ClientHeight if TopPosition > ClientHeight then Break; if WithCheck and (Node.CheckType <> ctNone) then Dec(NodeLeft, CheckOffset); // Get next visible node and update left node position. NextNode := GetNextVisible(Node, True); if NextNode = nil then Break; Inc(NodeLeft, CountLevelDifference(Node, NextNode) * Integer(FIndent)); Node := NextNode; end; Inc(Result, FMargin); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.GetNativeClipboardFormats(var Formats: TFormatEtcArray); // Returns the supported clipboard formats of the tree. begin InternalClipboardFormats.EnumerateFormats(TVirtualTreeClass(ClassType), Formats, FClipboardFormats); // Ask application/descendants for self defined formats. DoGetUserClipboardFormats(Formats); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetOperationCanceled; begin Result := FOperationCanceled and (FOperationCount > 0); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetOptionsClass: TTreeOptionsClass; begin Result := TCustomVirtualTreeOptions; end; //---------------------------------------------------------------------------------------------------------------------- {$i olemethods.inc} //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.HandleHotTrack(X, Y: Integer); // Updates the current "hot" node. var HitInfo: THitInfo; CheckPositions: THitPositions; ButtonIsHit, DoInvalidate: Boolean; begin DoInvalidate := False; // Get information about the hit. GetHitTestInfoAt(X, Y, True, HitInfo); // Only make the new node being "hot" if its label is hit or full row selection is enabled. CheckPositions := [hiOnItemLabel, hiOnItemCheckbox]; // If running under Windows Vista using the explorer theme hitting the buttons makes the node hot, too. if (IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions)) then Include(CheckPositions, hiOnItemButtonExact); if (CheckPositions * HitInfo.HitPositions = []) and not (toFullRowSelect in FOptions.FSelectionOptions) then HitInfo.HitNode := nil; if (HitInfo.HitNode <> FCurrentHotNode) or (HitInfo.HitColumn <> FCurrentHotColumn) then begin DoInvalidate := (toHotTrack in FOptions.PaintOptions) or (toCheckSupport in FOptions.FMiscOptions); DoHotChange(FCurrentHotNode, HitInfo.HitNode); if Assigned(FCurrentHotNode) and DoInvalidate then InvalidateNode(FCurrentHotNode); FCurrentHotNode := HitInfo.HitNode; FCurrentHotColumn := HitInfo.HitColumn; end; ButtonIsHit := (hiOnItemButtonExact in HitInfo.HitPositions) and (toHotTrack in FOptions.FPaintOptions); if Assigned(FCurrentHotNode) and ((FHotNodeButtonHit <> ButtonIsHit) or DoInvalidate) then begin FHotNodeButtonHit := ButtonIsHit and (toHotTrack in FOptions.FPaintOptions); InvalidateNode(FCurrentHotNode); end else if not Assigned(FCurrentHotNode) then FHotNodeButtonHit := False; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.HandleIncrementalSearch(CharCode: Word); var Run, Stop: PVirtualNode; GetNextNode: TGetNextNodeProc; NewSearchText: String; SingleLetter, PreviousSearch: Boolean; // True if VK_BACK was sent. SearchDirection: TVTSearchDirection; //--------------- local functions ------------------------------------------- procedure SetupNavigation; // If the search buffer is empty then we start searching with the next node after the last one, otherwise // we continue with the last one. Node navigation function is set up too here, to avoid frequent checks. var FindNextNode: Boolean; begin FindNextNode := (Length(FSearchBuffer) = 0) or (Run = nil) or SingleLetter or PreviousSearch; case FIncrementalSearch of isVisibleOnly: if SearchDirection = sdForward then begin GetNextNode := GetNextVisible; if FindNextNode then begin if Run = nil then Run := GetFirstVisible(nil, True) else begin Run := GetNextVisible(Run, True); // Do wrap around. if Run = nil then Run := GetFirstVisible(nil, True); end; end; end else begin GetNextNode := GetPreviousVisible; if FindNextNode then begin if Run = nil then Run := GetLastVisible(nil, True) else begin Run := GetPreviousVisible(Run, True); // Do wrap around. if Run = nil then Run := GetLastVisible(nil, True); end; end; end; isInitializedOnly: if SearchDirection = sdForward then begin GetNextNode := GetNextNoInit; if FindNextNode then begin if Run = nil then Run := GetFirstNoInit else begin Run := GetNextNoInit(Run); // Do wrap around. if Run = nil then Run := GetFirstNoInit; end; end; end else begin GetNextNode := GetPreviousNoInit; if FindNextNode then begin if Run = nil then Run := GetLastNoInit else begin Run := GetPreviousNoInit(Run); // Do wrap around. if Run = nil then Run := GetLastNoInit; end; end; end; else // isAll if SearchDirection = sdForward then begin GetNextNode := GetNext; if FindNextNode then begin if Run = nil then Run := GetFirst else begin Run := GetNext(Run); // Do wrap around. if Run = nil then Run := GetFirst; end; end; end else begin GetNextNode := GetPrevious; if FindNextNode then begin if Run = nil then Run := GetLast else begin Run := GetPrevious(Run); // Do wrap around. if Run = nil then Run := GetLast; end; end; end; end; end; //--------------------------------------------------------------------------- //todo: reimplement {$ifndef INCOMPLETE_WINAPI} function CodePageFromLocale(Language: DWord): Integer; // Determines the code page for a given locale. // Unfortunately there is no easier way than this, currently. var Buf: array[0..6] of Char; begin GetLocaleInfo(Language, LOCALE_IDEFAULTANSICODEPAGE, Buf, 6); Result := StrToIntDef(Buf, GetACP); end; //--------------------------------------------------------------------------- function KeyUnicode(C: Char): WideChar; // Converts the given character into its corresponding Unicode character // depending on the active keyboard layout. begin MultiByteToWideChar(CodePageFromLocale(GetKeyboardLayout(0) and $FFFF), MB_USEGLYPHCHARS, @C, 1, @Result, 1); end; {$endif} //--------------- end local functions --------------------------------------- var FoundMatch: Boolean; NewChar: WideChar; begin //todo: handle correctly unicode char after WideString -> String conversion KillTimer(Handle, SearchTimer); if FIncrementalSearch <> isNone then begin if CharCode <> 0 then begin DoStateChange([tsIncrementalSearching]); // Convert the given virtual key code into a Unicode character based on the current locale. //todo: reimplement {$ifndef INCOMPLETE_WINAPI} NewChar := KeyUnicode(Char(CharCode)); {$else} NewChar := Char(CharCode); {$endif} PreviousSearch := NewChar = WideChar(VK_BACK); // We cannot do a search with an empty search buffer. if not PreviousSearch or (FSearchBuffer <> '') then begin // Determine which method to use to advance nodes and the start node to search from. case FSearchStart of ssAlwaysStartOver: Run := nil; ssFocusedNode: Run := FFocusedNode; else // ssLastHit Run := FLastSearchNode; end; // Make sure the start node corresponds to the search criterion. if Assigned(Run) then begin case FIncrementalSearch of isInitializedOnly: if not (vsInitialized in Run.States) then Run := nil; isVisibleOnly: if not FullyVisible[Run] then Run := nil; end; end; Stop := Run; // VK_BACK temporarily changes search direction to opposite mode. if PreviousSearch then begin if SearchDirection = sdBackward then SearchDirection := sdForward else SearchDirection := sdBackward end else SearchDirection := FSearchDirection; // The "single letter mode" is used to advance quickly from node to node when pressing the same key several times. SingleLetter := (Length(FSearchBuffer) = 1) and not PreviousSearch and (FSearchBuffer[1] = NewChar); // However if the current hit (if there is one) would fit also with a repeated character then // don't use single letter mode. if SingleLetter and (DoIncrementalSearch(Run, FSearchBuffer + NewChar) = 0) then SingleLetter := False; SetupNavigation; FoundMatch := False; if Assigned(Run) then begin if SingleLetter then NewSearchText := FSearchBuffer else if PreviousSearch then begin SetLength(FSearchBuffer, Length(FSearchBuffer) - 1); NewSearchText := FSearchBuffer; end else NewSearchText := FSearchBuffer + NewChar; repeat if DoIncrementalSearch(Run, NewSearchText) = 0 then begin FoundMatch := True; Break; end; // Advance to next node if we have not found a match. Run := GetNextNode(Run); // Do wrap around start or end of tree. if (Run <> Stop) and (Run = nil) then SetupNavigation; until Run = Stop; end; if FoundMatch then begin ClearSelection; FSearchBuffer := NewSearchText; FLastSearchNode := Run; FocusedNode := Run; Selected[Run] := True; FLastSearchNode := Run; end else // Play an acoustic signal if nothing could be found but don't beep if only the currently // focused node matches. if Assigned(Run) and (DoIncrementalSearch(Run, NewSearchText) <> 0) then Beep; end; end; // Restart search timeout interval. SetTimer(Handle, SearchTimer, FSearchTimeout, nil); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.HandleMouseDblClick(var Message: TLMMouse; const HitInfo: THitInfo); var NewCheckState: TCheckState; Node: PVirtualNode; MayEdit: Boolean; begin MayEdit := not (tsEditing in FStates) and (toEditOnDblClick in FOptions.FMiscOptions); if tsEditPending in FStates then begin KillTimer(Handle, EditTimer); DoStateChange([], [tsEditPending]); end; if not (tsEditing in FStates) or DoEndEdit then begin if HitInfo.HitColumn = FHeader.FColumns.FClickIndex then DoColumnDblClick(HitInfo.HitColumn, KeysToShiftState(Message.Keys)); Node := nil; if (hiOnItem in HitInfo.HitPositions) and (hitInfo.HitColumn > NoColumn) and (coFixed in FHeader.FColumns[HitInfo.HitColumn].FOptions) then begin if hiUpperSplitter in HitInfo.HitPositions then Node := GetPreviousVisible(HitInfo.HitNode, True) else if hiLowerSplitter in HitInfo.HitPositions then Node := HitInfo.HitNode end; if Assigned(Node) and (Node <> FRoot) and (toNodeHeightDblClickResize in FOptions.FMiscOptions) then begin if DoNodeHeightDblClickResize(Node, HitInfo.HitColumn, KeysToShiftState(Message.Keys), Point(Message.XPos, Message.YPos)) then begin SetNodeHeight(Node, FDefaultNodeHeight); UpdateWindow(Handle); MayEdit := False; end; end else if hiOnItemCheckBox in HitInfo.HitPositions then begin if (FStates * [tsMouseCheckPending, tsKeyCheckPending] = []) and not (vsDisabled in HitInfo.HitNode.States) then begin with HitInfo.HitNode^ do NewCheckState := DetermineNextCheckState(CheckType, CheckState); if DoChecking(HitInfo.HitNode, NewCheckState) then begin DoStateChange([tsMouseCheckPending]); FCheckNode := HitInfo.HitNode; FPendingCheckState := NewCheckState; FCheckNode.CheckState := PressedState[FCheckNode.CheckState]; InvalidateNode(HitInfo.HitNode); MayEdit := False; end; end; end else begin if hiOnItemButton in HitInfo.HitPositions then begin ToggleNode(HitInfo.HitNode); MayEdit := False; end else begin if toToggleOnDblClick in FOptions.FMiscOptions then begin if ((([hiOnItemButton, hiOnItemLabel, hiOnNormalIcon, hiOnStateIcon] * HitInfo.HitPositions) <> []) or ((toFullRowSelect in FOptions.FSelectionOptions) and Assigned(HitInfo.HitNode))) then begin ToggleNode(HitInfo.HitNode); MayEdit := False; end; end; end; end; end; if MayEdit and Assigned(FFocusedNode) and (FFocusedNode = HitInfo.HitNode) and (FFocusedColumn = HitInfo.HitColumn) and CanEdit(FFocusedNode, HitInfo.HitColumn) then begin DoStateChange([tsEditPending]); FEditColumn := FFocusedcolumn; SetTimer(Handle, EditTimer, FEditDelay, nil); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.HandleMouseDown(var Message: TLMMouse; var HitInfo: THitInfo); // centralized mouse button down handling var LastFocused: PVirtualNode; Column: TColumnIndex; ShiftState: TShiftState; // helper variables to shorten boolean equations/expressions AutoDrag, // automatic (or allowed) drag start IsHit, // the node's caption or images are hit IsCellHit, // for grid extension or full row select (but not check box, button) IsAnyHit, // either IsHit or IsCellHit IsHeightTracking, // height tracking MultiSelect, // multiselection is enabled ShiftEmpty, // ShiftState = [] NodeSelected: Boolean; // the new node (if any) is selected NewColumn: Boolean; // column changed NewNode: Boolean; // Node changed. NeedChange: Boolean; // change event is required for selection change CanClear: Boolean; NewCheckState: TCheckState; AltPressed: Boolean; // Pressing the Alt key enables special processing for selection. FullRowDrag: Boolean; // Start dragging anywhere within a node's bound. NodeRect: TRect; FocusCanChange: Boolean; begin if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then begin StopWheelPanning; Exit; end; if tsEditPending in FStates then begin KillTimer(Handle, EditTimer); DoStateChange([], [tsEditPending]); end; if not (tsEditing in FStates) or DoEndEdit then begin // Focus change. Don't use the SetFocus method as this does not work for MDI windows. if not Focused and CanFocus then begin LCLIntf.SetFocus(Handle); // Repeat the hit test as an OnExit event might got triggered that could modify the tree. GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); end; // Keep clicked column in case the application needs it. FHeader.FColumns.FClickIndex := HitInfo.HitColumn; // Change column only if we have hit the node label. if (hiOnItemLabel in HitInfo.HitPositions) or (toFullRowSelect in FOptions.FSelectionOptions) or (toGridExtensions in FOptions.FMiscOptions) then begin NewColumn := FFocusedColumn <> HitInfo.HitColumn; if toExtendedFocus in FOptions.FSelectionOptions then Column := HitInfo.HitColumn else Column := FHeader.MainColumn; end else begin NewColumn := False; Column := FFocusedColumn; end; if NewColumn and (not FHeader.AllowFocus(Column)) then begin NewColumn := False; Column := FFocusedColumn; end; NewNode := FFocusedNode <> HitInfo.HitNode; // Translate keys and filter out shift and control key. ShiftState := KeysToShiftState(Message.Keys) * [ssShift, ssCtrlOS, ssAlt]; if ssAlt in ShiftState then begin AltPressed := True; // Remove the Alt key from the shift state. It is not meaningful there. Exclude(ShiftState, ssAlt); end else AltPressed := False; // Various combinations determine what states the tree enters now. // We initialize shorthand variables to avoid the following expressions getting too large // and to avoid repeative expensive checks. IsHit := not AltPressed and not (toSimpleDrawSelection in FOptions.FSelectionOptions) and ((hiOnItemLabel in HitInfo.HitPositions) or (hiOnNormalIcon in HitInfo.HitPositions)); IsCellHit := not AltPressed and not IsHit and Assigned(HitInfo.HitNode) and ([hiOnItemButton, hiOnItemCheckBox] * HitInfo.HitPositions = []) and ((toFullRowSelect in FOptions.FSelectionOptions) or ((toGridExtensions in FOptions.FMiscOptions) and (HitInfo.HitColumn > NoColumn))); IsAnyHit := IsHit or IsCellHit; MultiSelect := toMultiSelect in FOptions.FSelectionOptions; ShiftEmpty := ShiftState = []; NodeSelected := IsAnyHit and (vsSelected in HitInfo.HitNode.States); FullRowDrag := toFullRowDrag in FOptions.FMiscOptions; IsHeightTracking := (Message.Msg = LM_LBUTTONDOWN) and (toNodeHeightResize in FOptions.FMiscOptions) and (hiOnItem in HitInfo.HitPositions) and ([hiUpperSplitter, hiLowerSplitter] * HitInfo.HitPositions <> []) and ((HitInfo.HitColumn > NoColumn) and (coFixed in FHeader.FColumns[HitInfo.HitColumn].Options)); // Dragging might be started in the inherited handler manually (which is discouraged for stability reasons) // the test for manual mode is done below (after the focused node is set). AutoDrag := ((DragMode = dmAutomatic) or Dragging) and (not IsCellHit or FullRowDrag); // Query the application to learn if dragging may start now (if set to dmManual). if Assigned(HitInfo.HitNode) and not AutoDrag and (DragMode = dmManual) then AutoDrag := DoBeforeDrag(HitInfo.HitNode, Column) and (not IsCellHit or FullRowDrag); // handle node height tracking if IsHeightTracking then begin if hiUpperSplitter in HitInfo.HitPositions then FHeightTrackNode := GetPreviousVisible(HitInfo.HitNode, True) else FHeightTrackNode := HitInfo.HitNode; if Assigned(FHeightTrackNode) and (FHeightTrackNode <> FRoot) then begin FHeightTrackColumn := HitInfo.HitColumn; NodeRect := GetDisplayRect(FHeightTrackNode, FHeightTrackColumn, False); FHeightTrackPoint := Point(NodeRect.Left, NodeRect.Top); DoStateChange([tsNodeHeightTrackPending]); Exit; end; end; // handle button clicks if (hiOnItemButton in HitInfo.HitPositions) and (vsHasChildren in HitInfo.HitNode.States) then begin ToggleNode(HitInfo.HitNode); Exit; end; // check event if hiOnItemCheckBox in HitInfo.HitPositions then begin if (FStates * [tsMouseCheckPending, tsKeyCheckPending] = []) and not (vsDisabled in HitInfo.HitNode.States) then begin with HitInfo.HitNode^ do NewCheckState := DetermineNextCheckState(CheckType, CheckState); if DoChecking(HitInfo.HitNode, NewCheckState) then begin DoStateChange([tsMouseCheckPending]); FCheckNode := HitInfo.HitNode; FPendingCheckState := NewCheckState; FCheckNode.CheckState := PressedState[FCheckNode.CheckState]; InvalidateNode(HitInfo.HitNode); end; end; Exit; end; // Keep this node's level in case we need it for constraint selection. if (FRoot.ChildCount > 0) and ShiftEmpty or (FSelectionCount = 0) then if Assigned(HitInfo.HitNode) then FLastSelectionLevel := GetNodeLevel(HitInfo.HitNode) else FLastSelectionLevel := GetNodeLevel(GetLastVisibleNoInit(nil, True)); // pending clearance if MultiSelect and ShiftEmpty and not (hiOnItemCheckbox in HitInfo.HitPositions) and IsAnyHit and AutoDrag and NodeSelected and not FSelectionLocked then DoStateChange([tsClearPending]); // immediate clearance // Determine for the right mouse button if there is a popup menu. In this case and if drag'n drop is pending // the current selection has to stay as it is. with HitInfo, Message do CanClear := not AutoDrag and (not (tsRightButtonDown in FStates) or not HasPopupMenu(HitNode, HitColumn, Point(XPos, YPos))); //lcl FocusCanChange := DoFocusChanging(FFocusedNode, HitInfo.HitNode, FFocusedColumn, Column); if not FSelectionLocked and FocusCanChange and ((not (IsAnyHit or FullRowDrag) and MultiSelect and ShiftEmpty) or (IsAnyHit and (not NodeSelected or (NodeSelected and CanClear)) and (ShiftEmpty or not MultiSelect))) then begin Assert(not (tsClearPending in FStates), 'Pending and direct clearance are mutual exclusive!'); // If the currently hit node was already selected then we have to reselect it again after clearing the current // selection, but without a change event if it is the only selected node. // The same applies if the Alt key is pressed, which allows to start drawing the selection rectangle also // on node captions and images. Here the previous selection state does not matter, though. if NodeSelected or (AltPressed and Assigned(HitInfo.HitNode) and (HitInfo.HitColumn = FHeader.MainColumn)) then begin NeedChange := FSelectionCount > 1; InternalClearSelection; InternalAddToSelection(HitInfo.HitNode, True); if NeedChange then begin Invalidate; Change(nil); end; end else ClearSelection; end; // pending node edit if Focused and ((hiOnItemLabel in HitInfo.HitPositions) or ((toGridExtensions in FOptions.FMiscOptions) and (hiOnItem in HitInfo.HitPositions))) and NodeSelected and not NewColumn and ShiftEmpty then DoStateChange([tsEditPending]); // User starts a selection with a selection rectangle. if not (toDisableDrawSelection in FOptions.FSelectionOptions) and not (IsHit or FullRowDrag) and MultiSelect then begin SetCapture(Handle); DoStateChange([tsDrawSelPending]); FDrawSelShiftState := ShiftState; FNewSelRect := Rect(Message.XPos + FEffectiveOffsetX, Message.YPos - FOffsetY, Message.XPos + FEffectiveOffsetX, Message.YPos - FOffsetY); //lclheader if hoVisible in FHeader.Options then OffsetRect(FNewSelRect, 0, -FHeader.Height); {$ifdef DEBUG_VTV}Logger.Send([lcSelection],'FNewSelRect', FNewSelRect);{$endif} FLastSelRect := Rect(0, 0, 0, 0); if not IsCellHit then Exit; end; // Keep current mouse position. FLastClickPos := Point(Message.XPos, Message.YPos); // Handle selection and node focus change. if IsAnyHit and FocusCanChange then begin if NewColumn then begin InvalidateColumn(FFocusedColumn); InvalidateColumn(Column); FFocusedColumn := Column; end; if DragKind = dkDock then begin KillTimer(Handle, ScrollTimer); DoStateChange([], [tsScrollPending, tsScrolling]); end; // Get the currently focused node to make multiple multi-selection blocks possible. LastFocused := FFocusedNode; if NewNode then DoFocusNode(HitInfo.HitNode, False); if MultiSelect and not ShiftEmpty then HandleClickSelection(LastFocused, HitInfo.HitNode, ShiftState, AutoDrag) else begin if ShiftEmpty then FRangeAnchor := HitInfo.HitNode; // If the hit node is not yet selected then do it now. if not NodeSelected then AddToSelection(HitInfo.HitNode); end; if NewNode or NewColumn then begin ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions)); DoFocusChange(FFocusedNode, FFocusedColumn); end; end; // Drag'n drop initiation // If we lost focus in the interim the button states would be cleared in WM_KILLFOCUS. if AutoDrag and IsAnyHit and (FStates * [tsLeftButtonDown, tsRightButtonDown, tsMiddleButtonDown] <> []) then BeginDrag(False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.HandleMouseUp(Keys: PtrUInt; const HitInfo: THitInfo); // Counterpart to the mouse down handler. var ReselectFocusedNode: Boolean; begin ReleaseCapture; if not (tsVCLDragPending in FStates) then begin // reset pending or persistent states if IsMouseSelecting then begin DoStateChange([], [tsDrawSelecting, tsDrawSelPending, tsToggleFocusedSelection]); Invalidate; end; if tsClearPending in FStates then begin ReselectFocusedNode := Assigned(FFocusedNode) and (vsSelected in FFocusedNode.States); ClearSelection; if ReselectFocusedNode then AddToSelection(FFocusedNode); end; if (tsToggleFocusedSelection in FStates) and (HitInfo.HitNode = FFocusedNode) then begin if vsSelected in HitInfo.HitNode.States then RemoveFromSelection(HitInfo.HitNode) else AddToSelection(HitInfo.HitNode); InvalidateNode(HitInfo.HitNode); end; DoStateChange([], [tsOLEDragPending, tsOLEDragging, tsClearPending, tsDrawSelPending, tsToggleFocusedSelection, tsScrollPending, tsScrolling]); KillTimer(Handle, ScrollTimer); if tsMouseCheckPending in FStates then begin DoStateChange([], [tsMouseCheckPending]); // Is the mouse still over the same node? if (HitInfo.HitNode = FCheckNode) and (hiOnItem in HitInfo.HitPositions) then DoCheckClick(FCheckNode, FPendingCheckState) else FCheckNode.CheckState := UnpressedState[FCheckNode.CheckState]; InvalidateNode(FCheckNode); FCheckNode := nil; end; if (FHeader.FColumns.FClickIndex > NoColumn) and (FHeader.FColumns.FClickIndex = HitInfo.HitColumn) then DoColumnClick(HitInfo.HitColumn, KeysToShiftState(Keys)); // handle a pending edit event if tsEditPending in FStates then begin // Is the mouse still over the same node? if (HitInfo.HitNode = FFocusedNode) and (hiOnItem in HitInfo.HitPositions) and CanEdit(FFocusedNode, HitInfo.HitColumn) and (toEditOnClick in FOptions.FMiscOptions) then begin FEditColumn := FFocusedColumn; SetTimer(Handle, EditTimer, FEditDelay, nil); end else DoStateChange([], [tsEditPending]); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.HasImage(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex): Boolean; // Determines whether the given node has got an image of the given kind in the given column. // Returns True if so, otherwise False. var Ghosted: Boolean; Index: Integer; begin Index := -1; Ghosted := False; DoGetImageIndex(Node, Kind, Column, Ghosted, Index); Result := Index > -1; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.HasPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Pos: TPoint): Boolean; // Determines whether the tree got a popup menu, either in its PopupMenu property, via the OnGetPopupMenu event or // through inheritance. The latter case must be checked by the descendant which must override this method. begin Result := Assigned(PopupMenu) or Assigned(DoGetPopupMenu(Node, Column, Pos)); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InitChildren(Node: PVirtualNode); // Initiates the initialization of the child number of the given node. var Count: Cardinal; begin if Assigned(Node) and (Node <> FRoot) and (vsHasChildren in Node.States) then begin Count := Node.ChildCount; DoInitChildren(Node, Count); if Count = 0 then begin // Remove any child node which is already there. DeleteChildren(Node); Exclude(Node.States, vsHasChildren); end else SetChildCount(Node, Count); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InitNode(Node: PVirtualNode); // Initiates the initialization of the given node to allow the application to load needed data for it. var InitStates: TVirtualNodeInitStates; begin with Node^ do begin Include(States, vsInitialized); InitStates := []; if Parent = FRoot then DoInitNode(nil, Node, InitStates) else DoInitNode(Parent, Node, InitStates); if ivsDisabled in InitStates then Include(States, vsDisabled); if ivsHasChildren in InitStates then Include(States, vsHasChildren); if ivsSelected in InitStates then begin FSingletonNodeArray[0] := Node; InternalAddToSelection(FSingletonNodeArray, 1, False); end; if ivsMultiline in InitStates then Include(States, vsMultiline); // Expanded may already be set (when called from ReinitNode) or be set in DoInitNode, allow both. if (vsExpanded in Node.States) xor (ivsExpanded in InitStates) then begin // Expand node if not yet done (this will automatically initialize child nodes). if ivsExpanded in InitStates then ToggleNode(Node) else // If the node already was expanded then explicitly trigger child initialization. if vsHasChildren in Node.States then InitChildren(Node); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InternalAddFromStream(Stream: TStream; Version: Integer; Node: PVirtualNode); // Loads all details for Node (including its children) from the given stream. // Because the new nodes might be selected this method also fixes the selection array. var Stop: PVirtualNode; Index: Integer; LastTotalHeight: Cardinal; WasFullyVisible: Boolean; begin Assert(Node <> FRoot, 'The root node cannot be loaded from stream.'); // Keep the current total height value of Node as it has already been applied // but might change in the load and fixup code. We have to adjust that afterwards. LastTotalHeight := Node.TotalHeight; WasFullyVisible := FullyVisible[Node]; // Read in the new nodes. ReadNode(Stream, Version, Node); // One time update of node-internal states and the global visibility counter. // This is located here to ease and speed up the loading process. FixupTotalCount(Node); AdjustTotalCount(Node.Parent, Node.TotalCount - 1, True); // -1 because Node itself was already set. FixupTotalHeight(Node); AdjustTotalHeight(Node.Parent, Node.TotalHeight - LastTotalHeight, True); // New nodes are always visible, so the visible node count has been increased already. // If Node is now invisible we have to take back this increment and don't need to add any visible child node. if not FullyVisible[Node] then begin if WasFullyVisible then Dec(FVisibleCount); end else // It can never happen that the node is now fully visible but was not before as this would require // that the visibility state of one of its parents has changed, which cannot happen during loading. Inc(FVisibleCount, CountVisibleChildren(Node)); // Fix selection array. ClearTempCache; if Node = FRoot then Stop := nil else Stop := Node.NextSibling; if toMultiSelect in FOptions.FSelectionOptions then begin // Add all nodes which were selected before to the current selection (unless they are already there). while Node <> Stop do begin if (vsSelected in Node.States) and not FindNodeInSelection(Node, Index, 0, High(FSelection)) then InternalCacheNode(Node); Node := GetNextNoInit(Node); end; if FTempNodeCount > 0 then AddToSelection(FTempNodeCache, FTempNodeCount, True); ClearTempCache; end else // No further selected nodes allowed so delete the corresponding flag in all new nodes. while Node <> Stop do begin Exclude(Node.States, vsSelected); Node := GetNextNoInit(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.InternalAddToSelection(Node: PVirtualNode; ForceInsert: Boolean): Boolean; begin Assert(Assigned(Node), 'Node must not be nil!'); FSingletonNodeArray[0] := Node; Result := InternalAddToSelection(FSingletonNodeArray, 1, ForceInsert); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.InternalAddToSelection(const NewItems: TNodeArray; NewLength: Integer; ForceInsert: Boolean): Boolean; // Internal version of method AddToSelection which does not trigger OnChange events var I, J: Integer; CurrentEnd: Integer; Constrained, SiblingConstrained: Boolean; begin // The idea behind this code is to use a kind of reverse merge sort. QuickSort is quite fast // and would do the job here too but has a serious problem with already sorted lists like FSelection. // 1) Remove already selected items, mark all other as being selected. if ForceInsert then begin for I := 0 to NewLength - 1 do Include(NewItems[I].States, vsSelected); end else begin Constrained := toLevelSelectConstraint in FOptions.FSelectionOptions; if Constrained and (FLastSelectionLevel = -1) then FLastSelectionLevel := GetNodeLevel(NewItems[0]); SiblingConstrained := toSiblingSelectConstraint in FOptions.FSelectionOptions; if SiblingConstrained and (FRangeAnchor = nil) then FRangeAnchor := NewItems[0]; for I := 0 to NewLength - 1 do if ([vsSelected, vsDisabled] * NewItems[I].States <> []) or (Constrained and (Cardinal(FLastSelectionLevel) <> GetNodeLevel(NewItems[I]))) or (SiblingConstrained and (FRangeAnchor.Parent <> NewItems[I].Parent)) then Inc(PtrUInt(NewItems[I])) else Include(NewItems[I].States, vsSelected); end; I := PackArray(NewItems, NewLength); if I > -1 then NewLength := I; Result := NewLength > 0; if Result then begin // 2) Sort the new item list so we can easily traverse it. if NewLength > 1 then QuickSort(NewItems, 0, NewLength - 1); // 3) Make room in FSelection for the new items. if FSelectionCount + NewLength >= Length(FSelection) then SetLength(FSelection, FSelectionCount + NewLength); // 4) Merge in new items J := NewLength - 1; CurrentEnd := FSelectionCount - 1; while J >= 0 do begin // First insert all new entries which are greater than the greatest entry in the old list. // If the current end marker is < 0 then there's nothing more to move in the selection // array and only the remaining new items must be inserted. if CurrentEnd >= 0 then begin while (J >= 0) and (NewItems[J] > FSelection[CurrentEnd]) do begin FSelection[CurrentEnd + J + 1] := NewItems[J]; Dec(J); end; // early out if nothing more needs to be copied if J < 0 then Break; end else begin // insert remaining new entries at position 0 Move(NewItems[0], FSelection[0], (J + 1) * SizeOf(Pointer)); // nothing more to do so exit main loop Break; end; // find the last entry in the remaining selection list which is smaller then the largest // entry in the remaining new items list FindNodeInSelection(NewItems[J], I, 0, CurrentEnd); Dec(I); // move all entries which are greater than the greatest entry in the new items list up // so the remaining gap travels down to where new items must be inserted Move(FSelection[I + 1], FSelection[I + J + 2], (CurrentEnd - I) * SizeOf(Pointer)); CurrentEnd := I; end; Inc(FSelectionCount, NewLength); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InternalCacheNode(Node: PVirtualNode); // Adds the given node to the temporary node cache (used when collecting possibly large amounts of nodes). var Len: Cardinal; begin Len := Length(FTempNodeCache); if FTempNodeCount = Len then begin if Len < 100 then Len := 100 else Len := Len + Len div 10; SetLength(FTempNodeCache, Len); end; FTempNodeCache[FTempNodeCount] := Node; Inc(FTempNodeCount); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InternalClearSelection; var Count: Integer; begin // It is possible that there are invalid node references in the selection array // if the tree update is locked and changes in the structure were made. // Handle this potentially dangerous situation by packing the selection array explicitely. if FUpdateCount > 0 then begin Count := PackArray(FSelection, FSelectionCount); if Count > -1 then begin FSelectionCount := Count; SetLength(FSelection, FSelectionCount); end; end; while FSelectionCount > 0 do begin Dec(FSelectionCount); Exclude(FSelection[FSelectionCount].States, vsSelected); end; ResetRangeAnchor; FSelection := nil; DoStateChange([], [tsClearPending]); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InternalConnectNode(Node, Destination: PVirtualNode; Target: TBaseVirtualTree; Mode: TVTNodeAttachMode); // Connects Node with Destination depending on Mode. // No error checking takes place. Node as well as Destination must be valid. Node must never be a root node and // Destination must not be a root node if Mode is amInsertBefore or amInsertAfter. var Run: PVirtualNode; begin // Keep in mind that the destination node might belong to another tree. with Target do begin case Mode of amInsertBefore: begin Node.PrevSibling := Destination.PrevSibling; Destination.PrevSibling := Node; Node.NextSibling := Destination; Node.Parent := Destination.Parent; Node.Index := Destination.Index; if Node.PrevSibling = nil then Node.Parent.FirstChild := Node else Node.PrevSibling.NextSibling := Node; // reindex all following nodes Run := Destination; while Assigned(Run) do begin Inc(Run.Index); Run := Run.NextSibling; end; Inc(Destination.Parent.ChildCount); Include(Destination.Parent.States, vsHasChildren); AdjustTotalCount(Destination.Parent, Node.TotalCount, True); // Add the new node's height only if its parent is expanded. if Destination.Parent.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then AdjustTotalHeight(Destination.Parent, Node.TotalHeight, True); if FullyVisible[Node] then Inc(FVisibleCount, CountVisibleChildren(Node) + 1); end; amInsertAfter: begin Node.NextSibling := Destination.NextSibling; Destination.NextSibling := Node; Node.PrevSibling := Destination; Node.Parent := Destination.Parent; if Node.NextSibling = nil then Node.Parent.LastChild := Node else Node.NextSibling.PrevSibling := Node; Node.Index := Destination.Index; // reindex all following nodes Run := Node; while Assigned(Run) do begin Inc(Run.Index); Run := Run.NextSibling; end; Inc(Destination.Parent.ChildCount); Include(Destination.Parent.States, vsHasChildren); AdjustTotalCount(Destination.Parent, Node.TotalCount, True); // Add the new node's height only if its parent is expanded. if Destination.Parent.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then AdjustTotalHeight(Destination.Parent, Node.TotalHeight, True); if FullyVisible[Node] then Inc(FVisibleCount, CountVisibleChildren(Node) + 1); end; amAddChildFirst: begin if Assigned(Destination.FirstChild) then begin // If there's a first child then there must also be a last child. Destination.FirstChild.PrevSibling := Node; Node.NextSibling := Destination.FirstChild; Destination.FirstChild := Node; end else begin // First child node at this location. Destination.FirstChild := Node; Destination.LastChild := Node; Node.NextSibling := nil; end; Node.PrevSibling := nil; Node.Parent := Destination; Node.Index := 0; // reindex all following nodes Run := Node.NextSibling; while Assigned(Run) do begin Inc(Run.Index); Run := Run.NextSibling; end; Inc(Destination.ChildCount); Include(Destination.States, vsHasChildren); AdjustTotalCount(Destination, Node.TotalCount, True); // Add the new node's height only if its parent is expanded. if Destination.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then AdjustTotalHeight(Destination, Node.TotalHeight, True); if FullyVisible[Node] then Inc(FVisibleCount, CountVisibleChildren(Node) + 1); end; amAddChildLast: begin if Assigned(Destination.LastChild) then begin // If there's a last child then there must also be a first child. Destination.LastChild.NextSibling := Node; Node.PrevSibling := Destination.LastChild; Destination.LastChild := Node; end else begin // first child node at this location Destination.FirstChild := Node; Destination.LastChild := Node; Node.PrevSibling := nil; end; Node.NextSibling := nil; Node.Parent := Destination; if Assigned(Node.PrevSibling) then Node.Index := Node.PrevSibling.Index + 1 else Node.Index := 0; Inc(Destination.ChildCount); Include(Destination.States, vsHasChildren); AdjustTotalCount(Destination, Node.TotalCount, True); // Add the new node's height only if its parent is expanded. if Destination.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then AdjustTotalHeight(Destination, Node.TotalHeight, True); if FullyVisible[Node] then Inc(FVisibleCount, CountVisibleChildren(Node) + 1); end; else // amNoWhere: do nothing end; // Remove temporary states. Node.States := Node.States - [vsChecking, vsCutOrCopy, vsDeleting, vsClearing]; // Update the hidden children flag of the parent. if (Mode <> amNoWhere) and (Node.Parent <> FRoot) then begin // If we have added a visible node then simply remove the all-children-hidden flag. if vsVisible in Node.States then Exclude(Node.Parent.States, vsAllChildrenHidden) else // If we have added an invisible node and this is the only child node then // make sure the all-children-hidden flag is in a determined state. // If there were child nodes before then no action is needed. if Node.Parent.ChildCount = 1 then Include(Node.Parent.States, vsAllChildrenHidden); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.InternalData(Node: PVirtualNode): Pointer; begin Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InternalDisconnectNode(Node: PVirtualNode; KeepFocus: Boolean; Reindex: Boolean = True); // Disconnects the given node from its parent and siblings. The node's pointer are not reset so they can still be used // after return from this method (probably a very short time only!). // If KeepFocus is True then the focused node is not reset. This is useful if the given node is reconnected to the tree // immediately after return of this method and should stay being the focused node if it was it before. // Note: Node must not be nil or the root node. var Parent, Run: PVirtualNode; Index: Integer; AdjustHeight: Boolean; begin Assert(Assigned(Node) and (Node <> FRoot), 'Node must neither be nil nor the root node.'); if (Node = FFocusedNode) and not KeepFocus then begin DoFocusNode(nil, False); DoFocusChange(FFocusedNode, FFocusedColumn); end; if Node = FRangeAnchor then ResetRangeAnchor; // Update the hidden children flag of the parent. if (Node.Parent <> FRoot) and not (vsClearing in Node.Parent.States) then if FUpdateCount = 0 then DetermineHiddenChildrenFlag(Node.Parent) else Include(FStates, tsUpdateHiddenChildrenNeeded); if not (vsDeleting in Node.States) then begin // Some states are only temporary so take them out. Node.States := Node.States - [vsChecking]; Parent := Node.Parent; Dec(Parent.ChildCount); AdjustHeight := Parent.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible]; if Parent.ChildCount = 0 then begin Parent.States := Parent.States - [vsAllChildrenHidden, vsHasChildren]; if (Parent <> FRoot) and (vsExpanded in Parent.States) then Exclude(Parent.States, vsExpanded); end; AdjustTotalCount(Parent, -Integer(Node.TotalCount), True); if AdjustHeight then AdjustTotalHeight(Parent, -Integer(Node.TotalHeight), True); if FullyVisible[Node] then Dec(FVisibleCount, CountVisibleChildren(Node) + 1); if Assigned(Node.PrevSibling) then Node.PrevSibling.NextSibling := Node.NextSibling else Parent.FirstChild := Node.NextSibling; if Assigned(Node.NextSibling) then begin Node.NextSibling.PrevSibling := Node.PrevSibling; // Reindex all following nodes. if Reindex then begin Run := Node.NextSibling; Index := Node.Index; while Assigned(Run) do begin Run.Index := Index; Inc(Index); Run := Run.NextSibling; end; end; end else Parent.LastChild := Node.PrevSibling; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.InternalGetNodeAt(X, Y: Integer): PVirtualNode; var Dummy: Integer; begin Result := InternalGetNodeAt(X, Y, True, Dummy); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.InternalGetNodeAt(X, Y: Integer; Relative: Boolean; var NodeTop: Integer): PVirtualNode; //lclheader this is the original version of GetNodeAt used internally since expects coordinates // relative to the image tree. In LCL the image tree and control coordinates are different // when header is visible // This method returns the node that occupies the specified point, or nil if there's none. // If Relative is True then X and Y are given in client coordinates otherwise they are considered as being // absolute values into the virtual tree image (regardless of the current offsets in the tree window). // NodeTop gets the absolute or relative top position of the node returned or is untouched if no node // could be found. var AbsolutePos, CurrentPos: Cardinal; begin if Y < 0 then Exit(nil); AbsolutePos := Y; if Relative then Inc(AbsolutePos, -FOffsetY); // CurrentPos tracks a running term of the current position to test for. // It corresponds always to the top position of the currently considered node. CurrentPos := 0; // If the cache is available then use it. if tsUseCache in FStates then Result := FindInPositionCache(AbsolutePos, CurrentPos) else Result := GetFirstVisibleNoInit(nil, True); // Determine node, of which position and height corresponds to the scroll position most closely. while Assigned(Result) and (Result <> FRoot) do begin if AbsolutePos < (CurrentPos + NodeHeight[Result]) then Break; Inc(CurrentPos, NodeHeight[Result]); Result := GetNextVisibleNoInit(Result, True); end; if Result = FRoot then Result := nil; // Since the given vertical position is likely not the same as the top position // of the found node this top position is returned. if Assigned(Result) then begin NodeTop := CurrentPos; if Relative then Inc(NodeTop, FOffsetY); //{$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'GetNodeAt Result: ',Result^.Index);{$endif} end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InternalRemoveFromSelection(Node: PVirtualNode); // Special version to mark a node to be no longer in the current selection. PackArray must // be used to remove finally those entries. var Index: Integer; begin // Because pointers are always DWORD aligned we can simply increment all those // which we want to have removed (see also PackArray) and still have the // order in the list preserved. if FindNodeInSelection(Node, Index, -1, -1) then begin Exclude(Node.States, vsSelected); Inc(PtrUInt(FSelection[Index])); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InvalidateCache; // Marks the cache as invalid. begin DoStateChange([tsValidationNeeded], [tsUseCache]); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.MarkCutCopyNodes; // Sets the vsCutOrCopy style in every currently selected but not disabled node to indicate it is // now part of a clipboard operation. var Nodes: TNodeArray; I: Integer; begin Nodes := nil; if FSelectionCount > 0 then begin // need the current selection sorted to exclude selected nodes which are children, grandchildren etc. of // already selected nodes Nodes := GetSortedSelection(False); for I := 0 to High(Nodes) do with Nodes[I]^ do if not (vsDisabled in States) then Include(States, vsCutOrCopy); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.Loaded; var LastRootCount: Cardinal; IsReadOnly: Boolean; begin inherited; // If a root node count has been set during load of the tree then update its child structure now // as this hasn't been done yet in this case. if (tsNeedRootCountUpdate in FStates) and (FRoot.ChildCount > 0) then begin DoStateChange([], [tsNeedRootCountUpdate]); IsReadOnly := toReadOnly in FOptions.FMiscOptions; Exclude(FOptions.FMiscOptions, toReadOnly); LastRootCount := FRoot.ChildCount; FRoot.ChildCount := 0; BeginUpdate; SetChildCount(FRoot, LastRootCount); EndUpdate; if IsReadOnly then Include(FOptions.FMiscOptions, toReadOnly); end; // Prevent the object inspector at design time from marking the header as being modified // when auto resize is enabled. Updating; try FHeader.UpdateMainColumn; FHeader.FColumns.FixPositions; if toAutoBidiColumnOrdering in FOptions.FAutoOptions then FHeader.FColumns.ReorderColumns(UseRightToLeftAlignment); FHeader.RecalculateHeader; //lclheader //AdjustAutoSize is called inside CreateWnd. Don't call here //Keep the commented code until we get sure of not being necessary //if hoAutoResize in FHeader.FOptions then // FHeader.FColumns.AdjustAutoSize(InvalidColumn, True); finally Updated; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.MainColumnChanged; begin DoCancelEdit; {$ifdef EnableAccessible} NotifyWinEvent(EVENT_OBJECT_NAMECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.MouseMove(Shift: TShiftState; X, Y: Integer); var R: TRect; NewCursor: TCursor; HitInfo: THitInfo; P: TPoint; Node: PVirtualNode; begin // lcl: Adjust cursor if ([tsWheelPanning, tsWheelScrolling] * FStates = []) then begin // Apply own cursors only if there is no global cursor set. if Screen.Cursor = crDefault then begin NewCursor := crDefault; if (toNodeHeightResize in FOptions.FMiscOptions) then begin GetCursorPos(P); P := ScreenToClient(P); GetHitTestInfoAt(P.X, P.Y, True, HitInfo); if (hiOnItem in HitInfo.HitPositions) and ([hiUpperSplitter, hiLowerSplitter] * HitInfo.HitPositions <> []) and ((hitInfo.HitColumn > NoColumn) and (coFixed in FHeader.FColumns[HitInfo.HitColumn].FOptions)) then begin if hiUpperSplitter in HitInfo.HitPositions then Node := GetPreviousVisible(HitInfo.HitNode, True) else Node := HitInfo.HitNode; if Assigned(Node) and (Node <> FRoot) then NewCursor := crVertSplit; end; end; if (NewCursor = crDefault) and (toHotTrack in FOptions.PaintOptions) and Assigned(FCurrentHotNode) then NewCursor := FHotCursor; DoGetCursor(NewCursor); Cursor := NewCursor; end; end; if tsNodeHeightTrackPending in FStates then begin // Remove hint if shown currently. Application.CancelHint; // Stop wheel panning if active. StopWheelPanning; // Stop timers KillTimer(Handle, ExpandTimer); KillTimer(Handle, EditTimer); KillTimer(Handle, ScrollTimer); KillTimer(Handle, SearchTimer); FSearchBuffer := ''; FLastSearchNode := nil; DoStateChange([tsNodeHeightTracking], [tsScrollPending, tsScrolling, tsEditPending, tsOLEDragPending, tsVCLDragPending, tsIncrementalSearching, tsNodeHeightTrackPending]); end; if tsDrawSelPending in FStates then begin // Remove current selection in case the user clicked somewhere in the window (but not a node) // and moved the mouse. if CalculateSelectionRect(X, Y) then begin //lclheader R := FNewSelRect; if hoVisible in FHeader.Options then OffsetRect(R, 0, FHeader.Height); InvalidateRect(Handle, @R, False); UpdateWindow(Handle); if (Abs(FNewSelRect.Right - FNewSelRect.Left) > DragManager.DragThreshold) or (Abs(FNewSelRect.Bottom - FNewSelRect.Top) > DragManager.DragThreshold) then begin if tsClearPending in FStates then begin DoStateChange([], [tsClearPending]); ClearSelection; end; DoStateChange([tsDrawSelecting], [tsDrawSelPending]); // Reset to main column for multiselection. FocusedColumn := FHeader.MainColumn; // The current rectangle may already include some node captions. Handle this. if HandleDrawSelection(X, Y) then InvalidateRect(Handle, nil, False); end; end; end else begin if tsNodeHeightTracking in FStates then begin // Handle height tracking. if DoNodeHeightTracking(FHeightTrackNode, FHeightTrackColumn, FHeader.GetShiftState, FHeightTrackPoint, Point(X, Y)) then begin // Avoid negative (or zero) node heights. if FHeightTrackPoint.Y >= Y then Y := FHeightTrackPoint.Y + 1; SetNodeHeight(FHeightTrackNode, Y - FHeightTrackPoint.Y); UpdateWindow(Handle); Exit; end; end; // If both wheel panning and auto scrolling are pending then the user moved the mouse while holding down the // middle mouse button. This means panning is being used, hence remove the wheel scroll flag. if [tsWheelPanning, tsWheelScrolling] * FStates = [tsWheelPanning, tsWheelScrolling] then begin if ((Abs(FLastClickPos.X - X) >= DragManager.DragThreshold) or (Abs(FLastClickPos.Y - Y) >= DragManager.DragThreshold)) then DoStateChange([], [tsWheelScrolling]); end; // Really start dragging if the mouse has been moved more than the threshold. if (tsOLEDragPending in FStates) and ((Abs(FLastClickPos.X - X) >= FDragThreshold) or (Abs(FLastClickPos.Y - Y) >= FDragThreshold)) then DoDragging(FLastClickPos) else begin if CanAutoScroll then DoAutoScroll(X, Y); if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then AdjustPanningCursor(X, Y); if not IsMouseSelecting then begin HandleHotTrack(X, Y); inherited MouseMove(Shift, X, Y); end else begin // Handle draw selection if required, but don't do the work twice if the // auto scrolling code already cares about the selection. if not (tsScrolling in FStates) and CalculateSelectionRect(X, Y) then begin // If something in the selection changed then invalidate the entire // tree instead trying to figure out the display rects of all changed nodes. if HandleDrawSelection(X, Y) then InvalidateRect(Handle, nil, False) else begin UnionRect(R, OrderRect(FNewSelRect), OrderRect(FLastSelRect)); OffsetRect(R, -FEffectiveOffsetX, FOffsetY); if hoVisible in FHeader.Options then OffsetRect(R, 0, FHeader.Height); InvalidateRect(Handle, @R, False); end; UpdateWindow(Handle); end; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.Notification(AComponent: TComponent; Operation: TOperation); begin if (AComponent <> Self) and (Operation = opRemove) then begin // Check for components linked to the tree. if AComponent = FImages then begin Images := nil; if not (csDestroying in ComponentState) then Invalidate; end else if AComponent = FStateImages then begin StateImages := nil; if not (csDestroying in ComponentState) then Invalidate; end else if AComponent = PopupMenu then PopupMenu := nil else // Check for components linked to the header. if AComponent = FHeader.FImages then FHeader.Images := nil else if AComponent = FHeader.PopupMenu then FHeader.PopupMenu := nil; end; inherited; end; //---------------------------------------------------------------------------------------------------------------------- {$ifdef EnableNCFunctions} procedure TBaseVirtualTree.OriginalWMNCPaint(DC: HDC); // Unfortunately, the painting for the non-client area in TControl is not always correct and does also not consider // existing clipping regions, so it has been modified here to take this into account. const InnerStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0); OuterStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0); EdgeStyles: array[TBevelKind] of Integer = (0, 0, BF_SOFT, BF_FLAT); Ctl3DStyles: array[Boolean] of Integer = (BF_MONO, 0); var RC, RW: TRect; EdgeSize: Integer; Size: TSize; begin if (BevelKind <> bkNone) or (BorderWidth > 0) then begin RC := Rect(0, 0, Width, Height); Size := GetBorderDimensions; InflateRect(RC, Size.cx, Size.cy); RW := RC; if BevelKind <> bkNone then begin DrawEdge(DC, RC, InnerStyles[BevelInner] or OuterStyles[BevelOuter], Byte(BevelEdges) or EdgeStyles[BevelKind] or Ctl3DStyles[Ctl3D]); EdgeSize := 0; if BevelInner <> bvNone then Inc(EdgeSize, BevelWidth); if BevelOuter <> bvNone then Inc(EdgeSize, BevelWidth); with RC do begin if beLeft in BevelEdges then Inc(Left, EdgeSize); if beTop in BevelEdges then Inc(Top, EdgeSize); if beRight in BevelEdges then Dec(Right, EdgeSize); if beBottom in BevelEdges then Dec(Bottom, EdgeSize); end; end; // Repaint only the part in the original clipping region and not yet drawn parts. IntersectClipRect(DC, RC.Left, RC.Top, RC.Right, RC.Bottom); // Determine inner rectangle to exclude (RC corresponds then to the client area). InflateRect(RC, -BorderWidth, -BorderWidth); // Remove the inner rectangle. ExcludeClipRect(DC, RC.Left, RC.Top, RC.Right, RC.Bottom); // Erase parts not drawn. Brush.Color := FColors.BorderColor; Windows.FillRect(DC, RW, Brush.Handle); end; end; {$endif} //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.Paint; // Window paint routine. Used when the tree window needs to be updated. var Window: TRect; Target: TPoint; Temp: Integer; Options: TVTInternalPaintOptions; RTLOffset: Integer; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaint],'Paint');{$endif} Options := [poBackground, poColumnColor, poDrawFocusRect, poDrawDropMark, poDrawSelection, poGridLines]; if UseRightToLeftAlignment and FHeader.UseColumns then RTLOffset := ComputeRTLOffset(True) else RTLOffset := 0; // The update rect has already been filled in WMPaint, as it is the window's update rect, which gets // reset when BeginPaint is called (in the ancestor). // The difference to the DC's clipbox is that it is also valid with internal paint operations used // e.g. by the Explorer while dragging, but show window content while dragging is disabled. if not IsRectEmpty(FUpdateRect) then begin Temp := Header.Columns.GetVisibleFixedWidth; if Temp = 0 then begin Window := FUpdateRect; {$ifdef DEBUG_VTV}Logger.Send([lcHeaderOffset], 'FUpdateRect', FUpdateRect);{$endif} Target := Window.TopLeft; //lclheader if hoVisible in FHeader.FOptions then begin if Target.Y < FHeader.Height then begin Window.Top := 0; Target.Y := FHeader.Height; end else begin Dec(Window.Top, FHeader.Height); end; Dec(Window.Bottom, FHeader.Height); if RectVisible(Canvas.Handle, FHeaderRect) then begin {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'RectVisible = True');{$endif} FHeader.FColumns.PaintHeader(Canvas.Handle, FHeaderRect, -FEffectiveOffsetX); end; with FHeaderRect do ExcludeClipRect(Canvas.Handle, Left, Top, Right, Bottom); end; // The clipping rectangle is given in client coordinates of the window. We have to convert it into // a sliding window of the tree image. {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FEffectiveOffsetX: %d, RTLOffset: %d, OffsetY: %d',[FEffectiveOffsetX,RTLOffset,FOffsetY]);{$endif} OffsetRect(Window, FEffectiveOffsetX - RTLOffset, -FOffsetY); //{$ifdef DEBUG_VTV}Logger.Active:=Logger.CalledBy('DoDragging');{$endif} PaintTree(Canvas, Window, Target, Options); //{$ifdef DEBUG_VTV}Logger.Active:=True;{$endif} end else begin {$ifdef DEBUG_VTV}Logger.Send([lcPaint],'VisibleFixedWidth > 0');{$endif} // First part, fixed columns Window := ClientRect; Window.Right := Temp; Target := Window.TopLeft; //lclheader if hoVisible in FHeader.FOptions then begin //Target is always (0,0) due to call to ClientRect, so no need set Top to 0 //also no need to decrease bottom because ClientRect already computes header Inc(Target.Y, FHeader.Height); if RectVisible(Canvas.Handle, FHeaderRect) then begin {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader], 'RectVisible = True');{$endif} FHeader.FColumns.PaintHeader(Canvas.Handle, FHeaderRect, -FEffectiveOffsetX); end; with FHeaderRect do ExcludeClipRect(Canvas.Handle,Left,Top,Right,Bottom); end; OffsetRect(Window, -RTLOffset, -FOffsetY); PaintTree(Canvas, Window, Target, Options); // Second part, other columns Window := GetClientRect; if Temp > Window.Right then begin {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaint],'Paint');{$endif} Exit; end; Window.Left := Temp; Target := Window.TopLeft; //lclheader if hoVisible in FHeader.FOptions then Inc(Target.Y, FHeader.Height); {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'FEffectiveOffsetX: %d, RTLOffset: %d, OffsetY: %d',[FEffectiveOffsetX,RTLOffset,FOffsetY]);{$endif} OffsetRect(Window, FEffectiveOffsetX - RTLOffset, -FOffsetY); PaintTree(Canvas, Window, Target, Options); end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaint],'Paint');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.PaintCheckImage(const PaintInfo: TVTPaintInfo); procedure DrawCheckButton(Canvas: TCanvas; Index: Integer; const R: TRect; Flat: Boolean); var ButtonState: Cardinal; ButtonType: Cardinal; begin if Index < 8 then ButtonType := DFCS_BUTTONRADIO else ButtonType := DFCS_BUTTONCHECK; if Index >= 16 then ButtonType := ButtonType or DFCS_BUTTON3STATE; case Index mod 4 of 0: ButtonState := 0; 1: ButtonState := DFCS_HOT; 2: ButtonState := DFCS_PUSHED; else ButtonState := DFCS_INACTIVE; end; if Index in [4..7, 12..19] then ButtonState := ButtonState or DFCS_CHECKED; if Flat then ButtonState := ButtonState or DFCS_FLAT; DrawFrameControl(Canvas.Handle, R, DFC_BUTTON, ButtonType or ButtonState); end; var R: TRect; {$ifdef ThemeSupport} Details: TThemedElementDetails; {$endif} UseThemes: Boolean; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcCheck],'PaintCheckImage');{$endif} with PaintInfo, ImageInfo[iiCheck] do begin {$ifdef ThemeSupport} UseThemes := (tsUseThemes in FStates) and (FCheckImageKind = ckSystemDefault); {$else} UseThemes := False; {$endif} if UseThemes or ((FCheckImageKind in [ckSystemFlat, ckSystemDefault]) and not (Index in [21..24])) then begin {$ifdef ThemeSupport} if UseThemes then begin R := Rect(XPos - 1, YPos, XPos + 16, YPos + 16); Details.Element := teButton; case Index of 0..8: // radio buttons begin Details.Part := BP_RADIOBUTTON; Details.State := Index; end; 9..20: // check boxes begin Details.Part := BP_CHECKBOX; Details.State := Index - 8; end; 21..24: // buttons begin Details.Part := BP_PUSHBUTTON; Details.State := Index - 20; end; else Details.Part := 0; Details.State := 0; end; ThemeServices.DrawElement(Canvas.Handle, Details, R); {$ifdef USE_DELPHICOMPAT} if Index in [21..24] then with UtilityImages do DirectMaskBlt(PaintInfo.Canvas.Handle, XPos - 1, YPos, Height, Height, Canvas.Handle, 4 * Height, 0, MaskHandle); {$else} if Index in [21..24] then with UtilityImages do StretchMaskBlt(PaintInfo.Canvas.Handle, XPos - 1, YPos, Height, Height, Canvas.Handle, 4 * Height, 0, Height, Height, MaskHandle, 4 * Height, 0, SRCCOPY); {$endif} end else {$endif} begin R := Rect(XPos + 1, YPos + 1, XPos + 14, YPos + 14); DrawCheckButton(Canvas, Index - 1, R, FCheckImageKind = ckSystemFlat); end; end else with FCheckImages do begin {$ifdef USE_DELPHICOMPAT} DirectMaskBlt(PaintInfo.Canvas.Handle, XPos, YPos, Height, Height, Canvas.Handle, Index * Height, 0, MaskHandle); {$else} StretchMaskBlt(PaintInfo.Canvas.Handle, XPos, YPos, Height, Height, Canvas.Handle, Index * Height, 0, Height, Height, MaskHandle, Index * Height, 0, SRCCOPY); {$endif} end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcCheck],'PaintCheckImage');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.PaintImage(var PaintInfo: TVTPaintInfo; ImageInfoIndex: TVTImageInfoIndex; DoOverlay: Boolean); var CutNode: Boolean; PaintFocused: Boolean; DrawEffect: TGraphicsDrawEffect; begin with PaintInfo do begin CutNode := (vsCutOrCopy in Node.States) and (tsCutPending in FStates); PaintFocused := Focused or (toGhostedIfUnfocused in FOptions.FPaintOptions); // Since the overlay image must be specified together with the image to draw // it is meaningfull to retrieve it in advance. if DoOverlay then GetImageIndex(PaintInfo, ikOverlay, iiOverlay, Images) else PaintInfo.ImageInfo[iiOverlay].Index := -1; with ImageInfo[ImageInfoIndex] do begin if (vsSelected in Node.States) and not (Ghosted or CutNode) then begin if PaintFocused or (toPopupMode in FOptions.FPaintOptions) then Images.BlendColor := FColors.FocusedSelectionColor else Images.BlendColor := FColors.UnfocusedSelectionColor; end else Images.BlendColor := Color; if (vsDisabled in Node.States) or not Enabled then DrawEffect := gdeDisabled else // Blend image if enabled and the tree has the focus (or ghosted images must be drawn also if unfocused) ... if (toUseBlendedImages in FOptions.FPaintOptions) and PaintFocused // ... and the image is ghosted... and (Ghosted or // ... or it is not the check image and the node is selected (but selection is not for the entire row)... ((vsSelected in Node.States) and not (toFullRowSelect in FOptions.FSelectionOptions) and not (toGridExtensions in FOptions.FMiscOptions)) or // ... or the node must be shown in cut mode. CutNode) then DrawEffect := gdeShadowed else DrawEffect := gdeNormal; if (vsSelected in Node.States) and not Ghosted then Images.BlendColor := clDefault; Images.Draw(Canvas, XPos, YPos, Index, DrawEffect); // Now, draw the overlay. // Delphi version has the ability to use the built in overlay indices of windows system image lists // Since this is system dependent the LCL version will support only custom overlays // Note: XPos and YPos are those of the normal images. if PaintInfo.ImageInfo[iiOverlay].Index >= 0 then ImageInfo[iiOverlay].Images.Draw(Canvas, XPos, YPos, ImageInfo[iiOverlay].Index); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.PaintNodeButton(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const R: TRect; ButtonX, ButtonY: Integer; BidiMode: TBiDiMode); var Bitmap: TBitmap; XPos: Integer; IsHot: Boolean; begin IsHot := (toHotTrack in FOptions.FPaintOptions) and (FCurrentHotNode = Node) and FHotNodeButtonHit; if vsExpanded in Node.States then begin if IsHot then Bitmap := FHotMinusBM else Bitmap := FMinusBM; end else begin if IsHot then Bitmap := FHotPlusBM else Bitmap := FPlusBM; end; // Draw the node's plus/minus button according to the directionality. if BidiMode = bdLeftToRight then XPos := R.Left + ButtonX else XPos := R.Right - ButtonX - Bitmap.Width; // Need to draw this masked. Canvas.Draw(XPos, R.Top + ButtonY, Bitmap); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.PaintTreeLines(const PaintInfo: TVTPaintInfo; VAlignment, IndentSize: Integer; LineImage: TLineImage); var I: Integer; XPos, Offset: Integer; NewStyles: TLineImage; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'PaintTreeLines');{$endif} NewStyles := nil; with PaintInfo do begin if BidiMode = bdLeftToRight then begin XPos := CellRect.Left; Offset := FIndent; end else begin Offset := -Integer(FIndent); XPos := CellRect.Right + Offset; end; case FLineMode of lmBands: if poGridLines in PaintInfo.PaintOptions then begin // Convert the line images in correct bands. SetLength(NewStyles, Length(LineImage)); for I := IndentSize - 1 downto 0 do begin {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FLineMode = lmBands');{$endif} if (vsExpanded in Node.States) and not (vsAllChildrenHidden in Node.States) then NewStyles[I] := ltLeft else case LineImage[I] of ltRight, ltBottomRight, ltTopDownRight, ltTopRight: NewStyles[I] := ltLeftBottom; ltNone: // Have to take over the image to the right of this one. A no line entry can never appear as // last entry so I don't need an end check here. if LineImage[I + 1] in [ltNone, ltTopRight] then NewStyles[I] := NewStyles[I + 1] else NewStyles[I] := ltLeft; ltTopDown: // Have to check the image to the right of this one. A top down line can never appear as // last entry so I don't need an end check here. if LineImage[I + 1] in [ltNone, ltTopRight] then NewStyles[I] := NewStyles[I + 1] else NewStyles[I] := ltLeft; end; end; PaintInfo.Canvas.Font.Color := FColors.GridLineColor; for I := 0 to IndentSize - 1 do begin DrawLineImage(PaintInfo, XPos, CellRect.Top, NodeHeight[Node] - 1, VAlignment, NewStyles[I], BidiMode <> bdLeftToRight); Inc(XPos, Offset); end; end; else // lmNormal {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FLineMode = lmNormal');{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif} PaintInfo.Canvas.Font.Color := FColors.TreeLineColor; {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Font.Color);{$endif} for I := 0 to IndentSize - 1 do begin DrawLineImage(PaintInfo, XPos, CellRect.Top, NodeHeight[Node], VAlignment, LineImage[I], BidiMode <> bdLeftToRight); Inc(XPos, Offset); end; end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'PaintTreeLines');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.PaintSelectionRectangle(Target: TCanvas; WindowOrgX: Integer; const SelectionRect: TRect; TargetRect: TRect); // Helper routine to draw a selection rectangle in the mode determined by DrawSelectionMode. var BlendRect: TRect; TextColorBackup, BackColorBackup: COLORREF; // used to restore forground and background colors when drawing a selection rectangle begin {$ifdef DEBUG_VTV}Logger.Send([lcSelection], 'SelectionRect at PaintSelection', SelectionRect);{$endif} if ((FDrawSelectionMode = smDottedRectangle) and not (tsUseThemes in FStates)) or not MMXAvailable then begin // Classical selection rectangle using dotted borderlines. TextColorBackup := GetTextColor(Target.Handle); SetTextColor(Target.Handle, $FFFFFF); BackColorBackup := GetBkColor(Target.Handle); SetBkColor(Target.Handle, 0); Target.DrawFocusRect(SelectionRect); SetTextColor(Target.Handle, TextColorBackup); SetBkColor(Target.Handle, BackColorBackup); end else begin // Modern alpha blended style. OffsetRect(TargetRect, WindowOrgX, 0); if IntersectRect(BlendRect, OrderRect(SelectionRect), TargetRect) then begin OffsetRect(BlendRect, -WindowOrgX, 0); AlphaBlend(0, Target.Handle, BlendRect, Point(0, 0), bmConstantAlphaAndColor, FSelectionBlendFactor, ColorToRGB(FColors.SelectionRectangleBlendColor)); Target.Brush.Color := FColors.SelectionRectangleBorderColor; Target.FrameRect(SelectionRect); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.PrepareCell(var PaintInfo: TVTPaintInfo; WindowOrgX, MaxWidth: Integer); // This method is called immediately before a cell's content is drawn und is responsible to paint selection colors etc. var TextColorBackup, BackColorBackup: COLORREF; FocusRect, InnerRect: TRect; {$ifdef ThemeSupport} RowRect: TRect; //Theme: HTHEME; {$endif ThemeSupport} //--------------- local functions ------------------------------------------- procedure AlphaBlendSelection(Color: TColor); var R: TRect; begin // Take into account any window offset and size limitations in the target bitmap, as this is only as large // as necessary and might not cover the whole node. For normal painting this does not matter (because of // clipping) but for the MMX code there is no such check and it will crash badly when bitmap boundaries are // crossed. R := InnerRect; OffsetRect(R, -WindowOrgX, 0); if R.Left < 0 then R.Left := 0; if R.Right > MaxWidth then R.Right := MaxWidth; AlphaBlend(0, PaintInfo.Canvas.Handle, R, Point(0, 0), bmConstantAlphaAndColor, FSelectionBlendFactor, ColorToRGB(Color)); end; //--------------------------------------------------------------------------- {$ifdef ThemeSupport} //todo { procedure DrawBackground(State: Integer); begin with PaintInfo do if (toGridExtensions in FOptions.FMiscOptions) or (toFullRowSelect in FOptions.FSelectionOptions) then DrawThemeBackground(Theme, Canvas.Handle, TVP_TREEITEM, State, RowRect, @CellRect) else DrawThemeBackground(Theme, Canvas.Handle, TVP_TREEITEM, State, InnerRect, nil); end; } {$endif ThemeSupport} //--------------- end local functions --------------------------------------- begin {$ifdef ThemeSupport} //todo { if IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions) then begin RowRect := Rect(0, PaintInfo.CellRect.Top, FRangeX, PaintInfo.CellRect.Bottom); if toShowVertGridLines in FOptions.PaintOptions then Dec(RowRect.Right); Theme := OpenThemeData(Handle, 'TREEVIEW'); end else Theme := 0; } {$endif ThemeSupport} with PaintInfo, Canvas do begin // Fill cell background if its color differs from tree background. with FHeader.FColumns do if poColumnColor in PaintOptions then begin Brush.Color := Items[Column].Color; FillRect(CellRect); end; // Let the application customize the cell background and the content rectangle. DoBeforeCellPaint(Canvas, Node, Column, cpmPaint, CellRect, ContentRect); InnerRect := ContentRect; // The selection rectangle depends on alignment. if not (toGridExtensions in FOptions.FMiscOptions) then begin case Alignment of taLeftJustify: with InnerRect do if Left + NodeWidth < Right then Right := Left + NodeWidth; taCenter: with InnerRect do if (Right - Left) > NodeWidth then begin Left := (Left + Right - NodeWidth) div 2; Right := Left + NodeWidth; end; taRightJustify: with InnerRect do if (Right - Left) > NodeWidth then Left := Right - NodeWidth; end; end; if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.FSelectionOptions) then begin // Fill the selection rectangle. if poDrawSelection in PaintOptions then begin if Node = FDropTargetNode then begin if (FLastDropMode = dmOnNode) or (vsSelected in Node.States) then begin Brush.Color := FColors.DropTargetColor; Pen.Color := FColors.DropTargetBorderColor; if (toGridExtensions in FOptions.FMiscOptions) or (toFullRowSelect in FOptions.FSelectionOptions) then InnerRect := CellRect; if not IsRectEmpty(InnerRect) then if MMXAvailable and (toUseBlendedSelection in FOptions.PaintOptions) then AlphaBlendSelection(Brush.Color) else with InnerRect do RoundRect(Left, Top, Right, Bottom, FSelectionCurveRadius, FSelectionCurveRadius); end else begin //lcl: Is not necessary to set the style here //Brush.Style := bsClear; end; end else if vsSelected in Node.States then begin if Focused or (toPopupMode in FOptions.FPaintOptions) then begin Brush.Color := FColors.FocusedSelectionColor; Pen.Color := FColors.FocusedSelectionBorderColor; end else begin Brush.Color := FColors.UnfocusedSelectionColor; Pen.Color := FColors.UnfocusedSelectionBorderColor; end; if (toGridExtensions in FOptions.FMiscOptions) or (toFullRowSelect in FOptions.FSelectionOptions) then InnerRect := CellRect; if not IsRectEmpty(InnerRect) then {$ifdef ThemeSupport} //todo { if Theme <> 0 then begin // If the node is also hot, its background will be drawn later. if not (toHotTrack in FOptions.FPaintOptions) or (Node <> FCurrentHotNode) or ((Column <> FCurrentHotColumn) and not (toFullRowSelect in FOptions.FSelectionOptions)) then DrawBackground(IfThen(Self.Focused, TREIS_SELECTED, TREIS_SELECTEDNOTFOCUS)); end else } {$endif ThemeSupport} if MMXAvailable and (toUseBlendedSelection in FOptions.PaintOptions) then AlphaBlendSelection(Brush.Color) else with InnerRect do RoundRect(Left, Top, Right, Bottom, FSelectionCurveRadius, FSelectionCurveRadius); end; end; end; {$ifdef ThemeSupport} //todo { if (Theme <> 0) and (toHotTrack in FOptions.FPaintOptions) and (Node = FCurrentHotNode) and ((Column = FCurrentHotColumn) or (toFullRowSelect in FOptions.FSelectionOptions)) then DrawBackground(IfThen((vsSelected in Node.States) and not (toAlwaysHideSelection in FOptions.FPaintOptions), TREIS_HOTSELECTED, TREIS_HOT)); } {$endif ThemeSupport} if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.FSelectionOptions) then begin // draw focus rect if (poDrawFocusRect in PaintOptions) and (Focused or (toPopupMode in FOptions.FPaintOptions)) and (FFocusedNode = Node) and ( (Column = FFocusedColumn) {$ifdef ThemeSupport} //todo { or (not (toExtendedFocus in FOptions.FSelectionOptions) and (toFullRowSelect in FOptions.FSelectionOptions) and (Theme <> 0) ) } {$endif ThemeSupport} ) then begin TextColorBackup := GetTextColor(Handle); SetTextColor(Handle, $FFFFFF); BackColorBackup := GetBkColor(Handle); SetBkColor(Handle, 0); {$ifdef ThemeSupport} //todo { if not (toExtendedFocus in FOptions.FSelectionOptions) and (toFullRowSelect in FOptions.FSelectionOptions) and (Theme <> 0) then FocusRect := RowRect else } {$endif ThemeSupport} if toGridExtensions in FOptions.FMiscOptions then FocusRect := CellRect else FocusRect := InnerRect; {$ifdef ThemeSupport} //todo { if Theme <> 0 then InflateRect(FocusRect, -1, -1); } {$endif ThemeSupport} LCLIntf.DrawFocusRect(Handle, FocusRect); SetTextColor(Handle, TextColorBackup); SetBkColor(Handle, BackColorBackup); end; end; end; {$ifdef ThemeSupport} //todo { if Theme <> 0 then CloseThemeData(Theme); } {$endif ThemeSupport} end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ReadChunk(Stream: TStream; Version: Integer; Node: PVirtualNode; ChunkType, ChunkSize: Integer): Boolean; // Called while loading a tree structure, Node is already valid (allocated) at this point. // The function handles the base and user chunks, any other chunk is marked as being unknown (result becomes False) // and skipped. descendants may handle them by overriding this method. // Returns True if the chunk could be handled, otherwise False. var ChunkBody: TBaseChunkBody; Run: PVirtualNode; LastPosition: Integer; begin case ChunkType of BaseChunk: begin // Load base chunk's body (chunk header has already been consumed). Stream.Read(ChunkBody, SizeOf(ChunkBody)); with Node^ do begin // Set states first, in case the node is invisible. States := ChunkBody.States; NodeHeight := ChunkBody.NodeHeight; TotalHeight := NodeHeight; Align := ChunkBody.Align; CheckState := ChunkBody.CheckState; CheckType := ChunkBody.CheckType; ChildCount := ChunkBody.ChildCount; // Create and read child nodes. while ChunkBody.ChildCount > 0 do begin Run := MakeNewNode; Run.PrevSibling := Node.LastChild; if Assigned(Run.PrevSibling) then Run.Index := Run.PrevSibling.Index + 1; if Assigned(Node.LastChild) then Node.LastChild.NextSibling := Run else Node.FirstChild := Run; Node.LastChild := Run; Run.Parent := Node; ReadNode(Stream, Version, Run); Dec(ChunkBody.ChildCount); end; end; Result := True; end; UserChunk: if ChunkSize > 0 then begin // need to know whether the data was read LastPosition := Stream.Position; DoLoadUserData(Node, Stream); // compare stream position to learn whether the data was read Result := Stream.Position > LastPosition; // Improve stability by advancing the stream to the chunk's real end if // the application did not read what has been written. if not Result or (Stream.Position <> (LastPosition + ChunkSize)) then Stream.Position := LastPosition + ChunkSize; end else Result := True; else // unknown chunk, skip it Stream.Position := Stream.Position + ChunkSize; Result := False; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ReadNode(Stream: TStream; Version: Integer; Node: PVirtualNode); // Reads the anchor chunk of each node and initiates reading the sub chunks for this node var Header: TChunkHeader; EndPosition: Integer; begin with Stream do begin // Read anchor chunk of the node. Stream.Read(Header, SizeOf(Header)); if Header.ChunkType = NodeChunk then begin EndPosition := Stream.Position + Header.ChunkSize; // Read all subchunks until the indicated chunk end position is reached in the stream. while Position < EndPosition do begin // Read new chunk header. Stream.Read(Header, SizeOf(Header)); ReadChunk(Stream, Version, Node, Header.ChunkType, Header.ChunkSize); end; // If the last chunk does not end at the given end position then there is something wrong. if Position <> EndPosition then ShowError(SCorruptStream2, hcTFCorruptStream2); end else ShowError(SCorruptStream1, hcTFCorruptStream1); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.RedirectFontChangeEvent(Canvas: TCanvas); begin if @Canvas.Font.OnChange <> @FOldFontChange then begin FOldFontChange := Canvas.Font.OnChange; Canvas.Font.OnChange := FontChanged; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.RemoveFromSelection(Node: PVirtualNode); var Index: Integer; begin if not FSelectionLocked then begin Assert(Assigned(Node), 'Node must not be nil!'); if vsSelected in Node.States then begin Exclude(Node.States, vsSelected); if FindNodeInSelection(Node, Index, -1, -1) and (Index < FSelectionCount - 1) then Move(FSelection[Index + 1], FSelection[Index], (FSelectionCount - Index - 1) * 4); if FSelectionCount > 0 then Dec(FSelectionCount); SetLength(FSelection, FSelectionCount); if FSelectionCount = 0 then ResetRangeAnchor; Change(Node); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ResetRangeAnchor; // Called when there is no selected node anymore and the selection range anchor needs a new value. begin FRangeAnchor := FFocusedNode; FLastSelectionLevel := -1; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.RestoreFontChangeEvent(Canvas: TCanvas); begin Canvas.Font.OnChange := FOldFontChange; FOldFontChange := nil; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SelectNodes(StartNode, EndNode: PVirtualNode; AddOnly: Boolean); // Selects a range of nodes and unselects all other eventually selected nodes which are not in this range if // AddOnly is False. // EndNode must be visible while StartNode does not necessarily as in the case where the last focused node is the start // node but it is a child of a node which has been collapsed previously. In this case the first visible parent node // is used as start node. StartNode can be nil in which case the very first node in the tree is used. var NodeFrom, NodeTo, LastAnchor: PVirtualNode; Index: Integer; begin Assert(Assigned(EndNode), 'EndNode must not be nil!'); if not FSelectionLocked then begin ClearTempCache; if StartNode = nil then StartNode := GetFirstVisibleNoInit(nil, True) else if not FullyVisible[StartNode] then begin StartNode := GetPreviousVisible(StartNode, True); if StartNode = nil then StartNode := GetFirstVisibleNoInit(nil, True) end; if CompareNodePositions(StartNode, EndNode, True) < 0 then begin NodeFrom := StartNode; NodeTo := EndNode; end else begin NodeFrom := EndNode; NodeTo := StartNode; end; // The range anchor will be reset by the following call. LastAnchor := FRangeAnchor; if not AddOnly then InternalClearSelection; while NodeFrom <> NodeTo do begin InternalCacheNode(NodeFrom); NodeFrom := GetNextVisible(NodeFrom, True); end; // select last node too InternalCacheNode(NodeFrom); // now add them all in "one" step AddToSelection(FTempNodeCache, FTempNodeCount); ClearTempCache; if Assigned(LastAnchor) and FindNodeInSelection(LastAnchor, Index, -1, -1) then FRangeAnchor := LastAnchor; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SetFocusedNodeAndColumn(Node: PVirtualNode; Column: TColumnIndex); var OldColumn: TColumnIndex; WasDifferent: Boolean; begin if not FHeader.AllowFocus(Column) then Column := FFocusedColumn; WasDifferent := (Node <> FFocusedNode) or (Column <> FFocusedColumn); OldColumn := FFocusedColumn; FFocusedColumn := Column; DoFocusNode(Node, True); // Check if the change was accepted. if FFocusedNode = Node then begin CancelEditNode; if WasDifferent then DoFocusChange(FFocusedNode, FFocusedColumn); end else // If the user did not accept the new cell to focus then set also the focused column back // to its original state. FFocusedColumn := OldColumn; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SkipNode(Stream: TStream); // Skips the data for the next node in the given stream (including the child nodes). var Header: TChunkHeader; begin with Stream do begin // read achor chunk of the node Stream.Read(Header, SizeOf(Header)); if Header.ChunkType = NodeChunk then Stream.Position := Stream.Position + Header.ChunkSize else ShowError(SCorruptStream1, hcTFCorruptStream1); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.StartWheelPanning(const Position: TPoint); // Called when wheel panning should start. A little helper window is created to indicate the reference position, // which determines in which direction and how far wheel panning/scrolling will happen. //--------------- local function -------------------------------------------- function CreateClipRegion: HRGN; // In order to avoid doing all the transparent drawing ourselves we use a // window region for the wheel window. // Since we only work on a very small image (32x32 pixels) this is acceptable. var Start, X, Y, ImageHeight, ImageWidth: Integer; Temp: HRGN; begin Assert(not FPanningWindow.Image.Empty, 'Invalid wheel panning image.'); ImageWidth := FPanningWindow.Image.Width; ImageHeight := FPanningWindow.Image.Height; // Create an initial region on which we operate. Result := CreateRectRgn(0, 0, 0, 0); with FPanningWindow.Image.Canvas do begin for Y := 0 to ImageHeight - 1 do begin Start := -1; for X := 0 to ImageWidth - 1 do begin // Start a new span if we found a non-transparent pixel and no span is currently started. if (Start = -1) and (Pixels[X, Y] <> clFuchsia) then Start := X else if (Start > -1) and (Pixels[X, Y] = clFuchsia) then begin // A non-transparent span is finished. Add it to the result region. Temp := CreateRectRgn(Start, Y, X, Y + 1); CombineRgn(Result, Result, Temp, RGN_OR); DeleteObject(Temp); Start := -1; end; end; // If there is an open span then add this also to the result region. if Start > -1 then begin Temp := CreateRectRgn(Start, Y, ImageWidth, Y + 1); CombineRgn(Result, Result, Temp, RGN_OR); DeleteObject(Temp); end; end; end; // The resulting region is used as window region so we must not delete it. // Windows will own it after the assignment below. end; //--------------- end local function ---------------------------------------- var ImageName: string; begin // Set both panning and scrolling flag. One will be removed shortly depending on whether the middle mouse button is // released before the mouse is moved or vice versa. The first case is referred to as wheel scrolling while the // latter is called wheel panning. KillTimer(Handle, ScrollTimer); DoStateChange([tsWheelPanning, tsWheelScrolling]); if FPanningWindow = nil then begin FPanningWindow := TVirtualPanningWindow.Create; LoadPanningCursors; end; FPanningWindow.Start(Handle, ClientToScreen(Position)); if Integer(FRangeX) > ClientWidth then begin if Integer(FRangeY) > ClientHeight then ImageName := 'VT_MOVEALL_BMP' else ImageName := 'VT_MOVEEW_BMP' end else ImageName := 'VT_MOVENS_BMP'; FPanningWindow.Image.LoadFromLazarusResource(ImageName); FPanningWindow.Show(CreateClipRegion); // Setup the panscroll timer and capture all mouse input. SetFocus; SetCapture(Handle); AdjustPanningCursor(Position.X, Position.Y); SetTimer(Handle, ScrollTimer, 20, nil); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.StopWheelPanning; // Stops panning if currently active and destroys the helper window. begin if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then begin // Release the mouse capture and stop the panscroll timer. KillTimer(Handle, ScrollTimer); ReleaseCapture; DoStateChange([], [tsWheelPanning, tsWheelScrolling]); FPanningWindow.Stop; {$ifndef Windows} Cursor := crDefault; {$endif} end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.StructureChange(Node: PVirtualNode; Reason: TChangeReason); begin AdviseChangeEvent(True, Node, Reason); if FUpdateCount = 0 then begin if (FChangeDelay > 0) and not (tsSynchMode in FStates) then SetTimer(Handle, StructureChangeTimer, FChangeDelay, nil) else DoStructureChange(Node, Reason); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.SuggestDropEffect(Source: TObject; Shift: TShiftState; const Pt: TPoint; AllowedEffects: LongWord): LongWord; // determines the drop action to take if the drag'n drop operation ends on this tree // Note: Source can be any Delphi object not just a virtual tree begin Result := AllowedEffects; // prefer MOVE if source and target are the same control, otherwise whatever is allowed as initial value if Assigned(Source) and (Source = Self) then if (AllowedEffects and DROPEFFECT_MOVE) <> 0 then Result := DROPEFFECT_MOVE else // no change else // drag between different applicatons if (AllowedEffects and DROPEFFECT_COPY) <> 0 then Result := DROPEFFECT_COPY; // consider modifier keys and what is allowed at the moment, if none of the following conditions apply then // the initial value just set is used if ssCtrlOS in Shift then begin // copy or link if ssShift in Shift then begin // link if (AllowedEffects and DROPEFFECT_LINK) <> 0 then Result := DROPEFFECT_LINK; end else begin // copy if (AllowedEffects and DROPEFFECT_COPY) <> 0 then Result := DROPEFFECT_COPY; end; end else begin // move, link or default if ssShift in Shift then begin // move if (AllowedEffects and DROPEFFECT_MOVE) <> 0 then Result := DROPEFFECT_MOVE; end else begin // link or default if ssAlt in Shift then begin // link if (AllowedEffects and DROPEFFECT_LINK) <> 0 then Result := DROPEFFECT_LINK; end; // else default end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ToggleSelection(StartNode, EndNode: PVirtualNode); // Switchs the selection state of a range of nodes. // Note: This method is specifically designed to help selecting ranges with the keyboard and considers therefore // the range anchor. var NodeFrom, NodeTo: PVirtualNode; NewSize: Integer; Position: Integer; begin if not FSelectionLocked then begin Assert(Assigned(EndNode), 'EndNode must not be nil!'); if StartNode = nil then StartNode := FRoot.FirstChild else if not FullyVisible[StartNode] then StartNode := GetPreviousVisible(StartNode, True); Position := CompareNodePositions(StartNode, EndNode); // nothing to do if start and end node are the same if Position <> 0 then begin if Position < 0 then begin NodeFrom := StartNode; NodeTo := EndNode; end else begin NodeFrom := EndNode; NodeTo := StartNode; end; ClearTempCache; // 1) toggle the start node if it is before the range anchor if CompareNodePositions(NodeFrom, FRangeAnchor) < 0 then if not (vsSelected in NodeFrom.States) then InternalCacheNode(NodeFrom) else InternalRemoveFromSelection(NodeFrom); // 2) toggle all nodes within the range NodeFrom := GetNextVisible(NodeFrom, True); while NodeFrom <> NodeTo do begin if not (vsSelected in NodeFrom.States) then InternalCacheNode(NodeFrom) else InternalRemoveFromSelection(NodeFrom); NodeFrom := GetNextVisible(NodeFrom, True); end; // 3) toggle end node if it is after the range anchor if CompareNodePositions(NodeFrom, FRangeAnchor) > 0 then if not (vsSelected in NodeFrom.States) then InternalCacheNode(NodeFrom) else InternalRemoveFromSelection(NodeFrom); // Do some housekeeping if there was a change. NewSize := PackArray(FSelection, FSelectionCount); if NewSize > -1 then begin FSelectionCount := NewSize; SetLength(FSelection, FSelectionCount); end; // If the range went over the anchor then we need to reselect it. if not (vsSelected in FRangeAnchor.States) then InternalCacheNode(FRangeAnchor); if FTempNodeCount > 0 then AddToSelection(FTempNodeCache, FTempNodeCount); ClearTempCache; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.UnselectNodes(StartNode, EndNode: PVirtualNode); // Deselects a range of nodes. // EndNode must be visible while StartNode must not as in the case where the last focused node is the start node // but it is a child of a node which has been collapsed previously. In this case the first visible parent node // is used as start node. StartNode can be nil in which case the very first node in the tree is used. var NodeFrom, NodeTo: PVirtualNode; NewSize: Integer; begin if not FSelectionLocked then begin Assert(Assigned(EndNode), 'EndNode must not be nil!'); if StartNode = nil then StartNode := FRoot.FirstChild else if not FullyVisible[StartNode] then begin StartNode := GetPreviousVisible(StartNode, True); if StartNode = nil then StartNode := FRoot.FirstChild end; if CompareNodePositions(StartNode, EndNode) < 0 then begin NodeFrom := StartNode; NodeTo := EndNode; end else begin NodeFrom := EndNode; NodeTo := StartNode; end; while NodeFrom <> NodeTo do begin InternalRemoveFromSelection(NodeFrom); NodeFrom := GetNextVisible(NodeFrom, True); end; // Deselect last node too. InternalRemoveFromSelection(NodeFrom); // Do some housekeeping. NewSize := PackArray(FSelection, FSelectionCount); if NewSize > -1 then begin FSelectionCount := NewSize; SetLength(FSelection, FSelectionCount); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.UpdateCheckImageList; begin if FCheckImages <> FCustomCheckImages then FCheckImages.Free; FCheckImages := nil; CheckImageListNeeded; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.UpdateColumnCheckState(Col: TVirtualTreeColumn); begin Col.CheckState := DetermineNextCheckState(Col.CheckType, Col.CheckState); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.UpdateDesigner; var ParentForm: TCustomForm; begin if (csDesigning in ComponentState) and not (csUpdating in ComponentState) then begin ParentForm := GetParentForm(Self); if Assigned(ParentForm) and Assigned(ParentForm.Designer) then ParentForm.Designer.Modified; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.UpdateHeaderRect; // Calculates the rectangle the header occupies in non-client area. // These coordinates are in window rectangle. var OffsetX, OffsetY: Integer; //EdgeSize: Integer; Size: TSize; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintHeader],'UpdateHeaderRect');{$endif} FHeaderRect := Rect(0, 0, Width, Height); // Consider borders... Size := GetBorderDimensions; //lclheader //Adjust rect size Inc(FHeaderRect.Right,Size.cx*2); // ... and bevels. OffsetX := BorderWidth; OffsetY := BorderWidth; //todo_lcl { if BevelKind <> bkNone then begin EdgeSize := 0; if BevelInner <> bvNone then Inc(EdgeSize, BevelWidth); if BevelOuter <> bvNone then Inc(EdgeSize, BevelWidth); if beLeft in BevelEdges then Inc(OffsetX, EdgeSize); if beTop in BevelEdges then Inc(OffsetY, EdgeSize); end; } InflateRect(FHeaderRect, -OffsetX, -OffsetY); if hoVisible in FHeader.FOptions then begin if FHeaderRect.Left <= FHeaderRect.Right then FHeaderRect.Bottom := FHeaderRect.Top + Integer(FHeader.FHeight) else FHeaderRect := Rect(0, 0, 0, 0); end else FHeaderRect.Bottom := FHeaderRect.Top; {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'FHeaderRect',FHeaderRect);{$endif} {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintHeader],'UpdateHeaderRect');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.UpdateEditBounds; // Used to update the bounds of the current node editor if editing is currently active. var R: TRect; Dummy: Integer; CurrentAlignment: TAlignment; CurrentBidiMode: TBidiMode; begin if tsEditing in FStates then begin if vsMultiline in FFocusedNode.States then R := GetDisplayRect(FFocusedNode, FEditColumn, True, False) else R := GetDisplayRect(FFocusedNode, FEditColumn, True, True); if (toGridExtensions in FOptions.FMiscOptions) then begin // Adjust edit bounds depending on alignment and bidi mode. if FEditColumn <= NoColumn then begin CurrentAlignment := Alignment; CurrentBidiMode := BiDiMode; end else begin CurrentAlignment := FHeader.Columns[FEditColumn].FAlignment; CurrentBidiMode := FHeader.Columns[FEditColumn].FBidiMode; end; // Consider bidi mode here. In RTL context does left alignment actually mean right alignment and vice versa. if CurrentBidiMode <> bdLeftToRight then ChangeBiDiModeAlignment(CurrentAlignment); if CurrentAlignment = taLeftJustify then FHeader.Columns.GetColumnBounds(FEditColumn, Dummy, R.Right) else FHeader.Columns.GetColumnBounds(FEditColumn, R.Left, Dummy); end; if toShowHorzGridLines in TreeOptions.PaintOptions then Dec(R.Bottom); FEditLink.SetBounds(R); end; end; //---------------------------------------------------------------------------------------------------------------------- const ScrollMasks: array[Boolean] of Cardinal = (0, SIF_DISABLENOSCROLL); const // Region identifiers for GetRandomRgn { CLIPRGN = 1; METARGN = 2; APIRGN = 3; } SYSRGN = 4; procedure TBaseVirtualTree.UpdateWindowAndDragImage(const Tree: TBaseVirtualTree; TreeRect: TRect; UpdateNCArea, ReshowDragImage: Boolean); // Method to repaint part of the window area which is not covered by the drag image and to initiate a recapture // of the drag image. // Note: This method must only be called during a drag operation and the tree passed in is the one managing the current // drag image (so it is the actual drag source). {$ifndef INCOMPLETE_WINAPI} var DragRegion, // the region representing the drag image UpdateRegion, // the unclipped region within the tree to be updated NCRegion: HRGN; // the region representing the non-client area of the tree DragRect, NCRect: TRect; RedrawFlags: Cardinal; VisibleTreeRegion: HRGN; DC: HDC; {$endif} begin //todo: reimplement {$ifndef INCOMPLETE_WINAPI} if IntersectRect(TreeRect, TreeRect, ClientRect) then begin // Retrieve the visible region of the window. This is important to avoid overpainting parts of other windows // which overlap this one. VisibleTreeRegion := CreateRectRgn(0, 0, 1, 1); DC := GetDCEx(Handle, 0, DCX_CACHE or DCX_WINDOW or DCX_CLIPSIBLINGS or DCX_CLIPCHILDREN); GetRandomRgn(DC, VisibleTreeRegion, SYSRGN); ReleaseDC(Handle, DC); // In Win9x the returned visible region is given in client coordinates. We need it in screen coordinates, though. if not IsWinNT then with ClientToScreen(Point(0, 0)) do OffsetRgn(VisibleTreeRegion, X, Y); // The drag image will figure out itself what part of the rectangle can be recaptured. // Recapturing is not done by taking a snapshot of the screen, but by letting the tree draw itself // into the back bitmap of the drag image. So the order here is unimportant. Tree.FDragImage.RecaptureBackground(Self, TreeRect, VisibleTreeRegion, UpdateNCArea, ReshowDragImage); // Calculate the screen area not covered by the drag image and which needs an update. DragRect := Tree.FDragImage.GetDragImageRect; MapWindowPoints(0, Handle, DragRect, 2); DragRegion := CreateRectRgnIndirect(DragRect); // Start with non-client area if requested. if UpdateNCArea then begin // Compute the part of the non-client area which must be updated. // Determine the outer rectangle of the entire tree window. GetWindowRect(Handle, NCRect); // Express the tree window rectangle in client coordinates (because RedrawWindow wants them so). MapWindowPoints(0, Handle, NCRect, 2); NCRegion := CreateRectRgnIndirect(NCRect); // Determine client rect in screen coordinates and create another region for it. UpdateRegion := CreateRectRgnIndirect(ClientRect); // Create a region which only contains the NC part by subtracting out the client area. CombineRgn(NCRegion, NCRegion, UpdateRegion, RGN_DIFF); // Subtract also out what is hidden by the drag image. CombineRgn(NCRegion, NCRegion, DragRegion, RGN_DIFF); RedrawWindow(Handle, nil, NCRegion, RDW_FRAME or RDW_NOERASE or RDW_NOCHILDREN or RDW_INVALIDATE or RDW_VALIDATE or RDW_UPDATENOW); DeleteObject(NCRegion); DeleteObject(UpdateRegion); end; UpdateRegion := CreateRectRgnIndirect(TreeRect); RedrawFlags := RDW_INVALIDATE or RDW_VALIDATE or RDW_UPDATENOW or RDW_NOERASE or RDW_NOCHILDREN; // Remove the part of the update region which is covered by the drag image. CombineRgn(UpdateRegion, UpdateRegion, DragRegion, RGN_DIFF); RedrawWindow(Handle, nil, UpdateRegion, RedrawFlags); DeleteObject(UpdateRegion); DeleteObject(DragRegion); DeleteObject(VisibleTreeRegion); end; {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ValidateCache; // Starts cache validation if not already done by adding this instance to the worker thread's waiter list // (if not already there) and signalling the thread it can start validating. begin // Wait for thread to stop validation if it is currently validating this tree's cache. InterruptValidation; FStartIndex := 0; {$ifdef EnableThreadSupport} if tsValidationNeeded in FStates then begin // Tell the thread this tree needs actually something to do. WorkerThread.AddTree(Self); WorkEvent.SetEvent; end; {$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ValidateNodeDataSize(var Size: Integer); begin Size := 0; if Assigned(FOnGetNodeDataSize) then FOnGetNodeDataSize(Self, Size); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WndProc(var Message: TLMessage); var Handled: Boolean; begin Handled := False; // Try the header whether it needs to take this message. if Assigned(FHeader) and (FHeader.FStates <> []) then Handled := FHeader.HandleMessage(Message); if not Handled then begin // For auto drag mode, let tree handle itself, instead of TControl. if not (csDesigning in ComponentState) and ((Message.Msg = LM_LBUTTONDOWN) or (Message.Msg = LM_LBUTTONDBLCLK)) then begin Handled := (DragMode = dmAutomatic) and (DragKind = dkDrag); if Handled then begin if not IsControlMouseMsg(TLMMouse(Message)) then begin //lclheader //let the header handle the message here //otherwise no header click event will be fired FHeader.HandleMessage(Message); ControlState := ControlState + [csLButtonDown]; Dispatch(Message); // overrides TControl's BeginDrag end; end; end; if not Handled and Assigned(FHeader) then Handled := FHeader.HandleMessage(Message); if not Handled then inherited; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WriteChunks(Stream: TStream; Node: PVirtualNode); // Writes the core chunks for Node into the stream. // Note: descendants can optionally override this method to add other node specific chunks. // Keep in mind that this method is also called for the root node. Using this fact in descendants you can // create a kind of "global" chunks not directly bound to a specific node. var Header: TChunkHeader; LastPosition, ChunkSize: Integer; Chunk: TBaseChunk; Run: PVirtualNode; begin with Stream do begin // 1. The base chunk... LastPosition := Position; Chunk.Header.ChunkType := BaseChunk; with Node^, Chunk do begin Body.ChildCount := ChildCount; Body.NodeHeight := NodeHeight; // Some states are only temporary so take them out as they make no sense at the new location. Body.States := States - [vsChecking, vsCutOrCopy, vsDeleting, vsInitialUserData, vsHeightMeasured]; Body.Align := Align; Body.CheckState := CheckState; Body.CheckType := CheckType; Body.Reserved := 0; end; // write the base chunk Write(Chunk, SizeOf(Chunk)); // 2. ... directly followed by the child node chunks (actually they are child chunks of // the base chunk) if vsInitialized in Node.States then begin Run := Node.FirstChild; while Assigned(Run) do begin WriteNode(Stream, Run); Run := Run.NextSibling; end; end; FinishChunkHeader(Stream, LastPosition, Position); // 3. write user data LastPosition := Position; Header.ChunkType := UserChunk; Write(Header, SizeOf(Header)); DoSaveUserData(Node, Stream); // check if the application actually wrote data ChunkSize := Position - LastPosition - SizeOf(TChunkHeader); // seek back to start of chunk if nothing has been written if ChunkSize = 0 then begin Position := LastPosition; Size := Size - SizeOf(Header); end else FinishChunkHeader(Stream, LastPosition, Position); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.WriteNode(Stream: TStream; Node: PVirtualNode); // Writes the "cover" chunk for Node to Stream and initiates writing child nodes and chunks. var LastPosition: Integer; Header: TChunkHeader; begin // Initialize the node first if necessary and wanted. if toInitOnSave in FOptions.FMiscOptions then begin if not (vsInitialized in Node.States) then InitNode(Node); if (vsHasChildren in Node.States) and (Node.ChildCount = 0) then InitChildren(Node); end; with Stream do begin LastPosition := Position; // Emit the anchor chunk. Header.ChunkType := NodeChunk; Write(Header, SizeOf(Header)); // Write other chunks to stream taking their size into this chunk's size. WriteChunks(Stream, Node); // Update chunk size. FinishChunkHeader(Stream, LastPosition, Position); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.AbsoluteIndex(Node: PVirtualNode): Cardinal; begin Result := 0; while Assigned(Node) and (Node <> FRoot) do begin if not (vsInitialized in Node.States) then InitNode(Node); if Assigned(Node.PrevSibling) then begin // if there's a previous sibling then add its total count to the result Node := Node.PrevSibling; Inc(Result, Node.TotalCount); end else begin Node := Node.Parent; if Node <> FRoot then Inc(Result); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.AddChild(Parent: PVirtualNode; UserData: Pointer = nil): PVirtualNode; // Adds a new node to the given parent node. This is simply done by increasing the child count of the // parent node. If Parent is nil then the new node is added as (last) top level node. // UserData can be used to set the first 4 bytes of the user data area to an initial value which can be used // in OnInitNode and will also cause to trigger the OnFreeNode event (if <> nil) even if the node is not yet // "officially" initialized. // AddChild is a compatibility method and will implicitly validate the parent node. This is however // against the virtual paradigm and hence I dissuade from its usage. var NodeData: ^Pointer; begin if not (toReadOnly in FOptions.FMiscOptions) then begin CancelEditNode; if Parent = nil then Parent := FRoot; if not (vsInitialized in Parent.States) then InitNode(Parent); // Locally stop updates of the tree in order to avoid usage of the new node before it is correctly set up. // If the update count was 0 on enter then there will be a correct update at the end of this method. Inc(FUpdateCount); try SetChildCount(Parent, Parent.ChildCount + 1); // Update the hidden children flag of the parent. Nodes are added as being visible by default. Exclude(Parent.States, vsAllChildrenHidden); finally Dec(FUpdateCount); end; Result := Parent.LastChild; // Check if there is initial user data and there is also enough user data space allocated. if Assigned(UserData) then if FNodeDataSize >= 4 then begin NodeData := Pointer(PByte(@Result.Data) + FTotalInternalDataSize); NodeData^ := UserData; Include(Result.States, vsInitialUserData); end else ShowError(SCannotSetUserData, hcTFCannotSetUserData); InvalidateCache; if FUpdateCount = 0 then begin ValidateCache; if tsStructureChangePending in FStates then begin if Parent = FRoot then StructureChange(nil, crChildAdded) else StructureChange(Parent, crChildAdded); end; if (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then Sort(Parent, FHeader.FSortColumn, FHeader.FSortDirection, True); InvalidateToBottom(Parent); //lcl //Calling UpdateHorizontalScrollBar without a header leads to a //wrong NodeWidth because the node is not initialized at this time. //As result the horizontal scrollbar is not correctly //sized and the node can not be selected by a click. if HandleAllocated then UpdateVerticalScrollBar(True) end; end else Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AddFromStream(Stream: TStream; TargetNode: PVirtualNode); // loads nodes from the given stream and adds them to TargetNode // the current content is not cleared before the load process starts (see also LoadFromStream) var ThisID: TMagicID; Version, Count: Cardinal; Node: PVirtualNode; begin if not (toReadOnly in FOptions.FMiscOptions) then begin // check first whether this is a stream we can read Stream.ReadBuffer(ThisID, SizeOf(TMagicID)); if (ThisID[0] = MagicID[0]) and (ThisID[1] = MagicID[1]) and (ThisID[2] = MagicID[2]) and (ThisID[5] = MagicID[5]) then begin Version := Word(ThisID[3]); if Version <= VTTreeStreamVersion then begin BeginUpdate; try if Version < 2 then Count := MaxInt else Stream.ReadBuffer(Count, SizeOf(Count)); while (Stream.Position < Stream.Size) and (Count > 0) do begin Dec(Count); Node := MakeNewNode; InternalConnectNode(Node, TargetNode, Self, amAddChildLast); InternalAddFromStream(Stream, Version, Node); end; if TargetNode = FRoot then DoNodeCopied(nil) else DoNodeCopied(TargetNode); finally EndUpdate; end; end else ShowError(SWrongStreamVersion, hcTFWrongStreamVersion); end else ShowError(SWrongStreamVersion, hcTFWrongStreamVersion); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.AfterConstruction; begin inherited; if FRoot = nil then InitRootNode; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.Assign(Source: TPersistent); begin if (Source is TBaseVirtualTree) and not (toReadOnly in FOptions.FMiscOptions) then with Source as TBaseVirtualTree do begin Self.Align := Align; Self.Anchors := Anchors; Self.AutoScrollDelay := AutoScrollDelay; Self.AutoScrollInterval := AutoScrollInterval; Self.AutoSize := AutoSize; Self.Background := Background; //todo_lcl { Self.BevelEdges := BevelEdges; Self.BevelInner := BevelInner; Self.BevelKind := BevelKind; Self.BevelOuter := BevelOuter; Self.BevelWidth := BevelWidth; } Self.BiDiMode := BiDiMode; Self.BorderStyle := BorderStyle; Self.BorderWidth := BorderWidth; Self.ChangeDelay := ChangeDelay; Self.CheckImageKind := CheckImageKind; Self.Color := Color; Self.Colors.Assign(Colors); Self.Constraints.Assign(Constraints); Self.DefaultNodeHeight := DefaultNodeHeight; Self.DefaultPasteMode := DefaultPasteMode; Self.DragCursor := DragCursor; Self.DragImageKind := DragImageKind; Self.DragKind := DragKind; Self.DragMode := DragMode; Self.Enabled := Enabled; Self.Font := Font; Self.Header := Header; Self.HintMode := HintMode; Self.HotCursor := HotCursor; Self.Images := Images; //Self.ImeMode := ImeMode; //Self.ImeName := ImeName; Self.Indent := Indent; Self.Margin := Margin; Self.NodeAlignment := NodeAlignment; Self.NodeDataSize := NodeDataSize; Self.TreeOptions := TreeOptions; //Self.ParentBiDiMode := ParentBiDiMode; Self.ParentColor := ParentColor; Self.ParentFont := ParentFont; Self.ParentShowHint := ParentShowHint; Self.PopupMenu := PopupMenu; Self.RootNodeCount := RootNodeCount; Self.ScrollBarOptions := ScrollBarOptions; Self.ShowHint := ShowHint; Self.StateImages := StateImages; Self.TabOrder := TabOrder; Self.TabStop := TabStop; Self.Visible := Visible; Self.SelectionCurveRadius := SelectionCurveRadius; Self.SelectionBlendFactor := SelectionBlendFactor; end else inherited; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.BeginDrag(Immediate: Boolean; Threshold: Integer); // Reintroduced method to allow to start OLE drag'n drop as well as VCL drag'n drop. begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'BeginDrag');{$endif} if FDragType = dtVCL then begin DoStateChange([tsVCLDragPending]); inherited; end else if (FStates * [tsOLEDragPending, tsOLEDragging]) = [] then begin // Drag start position has already been recorded in WMMouseDown. if Threshold < 0 then FDragThreshold := DragManager.DragThreshold else FDragThreshold := Threshold; if Immediate then DoDragging(FLastClickPos) else DoStateChange([tsOLEDragPending]); end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'BeginDrag');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.BeginSynch; // Starts the synchronous update mode (if not already active). begin if not (csDestroying in ComponentState) then begin if FSynchUpdateCount = 0 then begin DoUpdating(usBeginSynch); // Stop all timers... KillTimer(Handle, ChangeTimer); KillTimer(Handle, StructureChangeTimer); KillTimer(Handle, ExpandTimer); KillTimer(Handle, EditTimer); KillTimer(Handle, ScrollTimer); KillTimer(Handle, SearchTimer); FSearchBuffer := ''; FLastSearchNode := nil; DoStateChange([], [tsEditPending, tsScrollPending, tsScrolling, tsIncrementalSearching]); // ...and trigger pending update states. if tsStructureChangePending in FStates then DoStructureChange(FLastStructureChangeNode, FLastStructureChangeReason); if tsChangePending in FStates then DoChange(FLastChangedNode); end else DoUpdating(usSynch); end; Inc(FSynchUpdateCount); DoStateChange([tsSynchMode]); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.BeginUpdate; begin if not (csDestroying in ComponentState) then begin if FUpdateCount = 0 then begin DoUpdating(usBegin); SetUpdateState(True); end else DoUpdating(usUpdate); end; Inc(FUpdateCount); DoStateChange([tsUpdating]); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CancelCutOrCopy; // Resets nodes which are marked as being cut. var Run: PVirtualNode; begin if ([tsCutPending, tsCopyPending] * FStates) <> [] then begin Run := FRoot.FirstChild; while Assigned(Run) do begin if vsCutOrCopy in Run.States then Exclude(Run.States, vsCutOrCopy); Run := GetNextNoInit(Run); end; end; DoStateChange([], [tsCutPending, tsCopyPending]); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CancelEditNode: Boolean; // Called by the application or the current edit link to cancel the edit action. begin if HandleAllocated and ([tsEditing, tsEditPending] * FStates <> []) then Result := DoCancelEdit else Result := True; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CancelOperation; // Called by the application to cancel a long-running operation. begin if FOperationCount > 0 then FOperationCanceled := True; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CanEdit(Node: PVirtualNode; Column: TColumnIndex): Boolean; // Returns True if the given node can be edited. begin Result := (toEditable in FOptions.FMiscOptions) and Enabled and not (toReadOnly in FOptions.FMiscOptions); DoCanEdit(Node, Column, Result); end; function TBaseVirtualTree.CanScroll(const ClientMousePos: TPoint): Boolean; // Determines whether auto scrolling can occur based on current mouse cursor position. begin Result := False; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.Clear; begin if not (toReadOnly in FOptions.FMiscOptions) or (csDestroying in ComponentState) then begin BeginUpdate; try InterruptValidation; if IsEditing then CancelEditNode; if ClipboardStates * FStates <> [] then begin OleSetClipBoard(nil); DoStateChange([], ClipboardStates); end; ClearSelection; FFocusedNode := nil; FLastSelected := nil; FCurrentHotNode := nil; FDropTargetNode := nil; FLastChangedNode := nil; FRangeAnchor := nil; FCheckNode := nil; FLastVCLDragTarget := nil; FLastSearchNode := nil; DeleteChildren(FRoot, True); FOffsetX := 0; FOffsetY := 0; finally EndUpdate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ClearChecked; var Node: PVirtualNode; begin Node := RootNode.FirstChild; while Assigned(Node) do begin if Node.CheckState <> csUncheckedNormal then CheckState[Node] := csUncheckedNormal; Node := GetNextNoInit(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ClearSelection; var Node: PVirtualNode; R: TRect; Counter: Integer; begin if not FSelectionLocked and (FSelectionCount > 0) and not (csDestroying in ComponentState) then begin if (FUpdateCount = 0) and HandleAllocated and (FVisibleCount > 0) then begin // Iterate through nodes currently visible in the client area and invalidate them. Node := TopNode; if Assigned(Node) then R := GetDisplayRect(Node, NoColumn, False); Counter := FSelectionCount; while Assigned(Node) do begin R.Bottom := R.Top + Integer(NodeHeight[Node]); if vsSelected in Node.States then begin InvalidateRect(Handle, @R, False); Dec(Counter); // Only try as many nodes as are selected. if Counter = 0 then Break; end; R.Top := R.Bottom; if R.Top > ClientHeight then Break; Node := GetNextVisibleNoInit(Node, True); end; end; InternalClearSelection; Change(nil); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CopyTo(Source: PVirtualNode; Tree: TBaseVirtualTree; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean): PVirtualNode; // A simplified CopyTo method to allow to copy nodes to the root of another tree. begin Result := CopyTo(Source, Tree.FRoot, Mode, ChildrenOnly); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CopyTo(Source, Target: PVirtualNode; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean): PVirtualNode; // Copies Source and all its child nodes to Target. // Mode is used to specify further where to add the new node actually (as sibling of Target or as child of Target). // Result is the newly created node to which source has been copied if ChildrenOnly is False or just contains Target // in the other case. // ChildrenOnly determines whether to copy also the source node or only its child nodes. var TargetTree: TBaseVirtualTree; Stream: TMemoryStream; begin Assert(TreeFromNode(Source) = Self, 'The source tree must contain the source node.'); Result := nil; if (Mode <> amNoWhere) and Assigned(Source) and (Source <> FRoot) then begin // Assume that an empty destination means the root in this (the source) tree. if Target = nil then begin TargetTree := Self; Target := FRoot; Mode := amAddChildFirst; end else TargetTree := TreeFromNode(Target); if not (toReadOnly in TargetTree.FOptions.FMiscOptions) then begin if Target = TargetTree.FRoot then begin case Mode of amInsertBefore: Mode := amAddChildFirst; amInsertAfter: Mode := amAddChildLast; end; end; Stream := TMemoryStream.Create; try // Write all nodes into a temprary stream depending on the ChildrenOnly flag. if not ChildrenOnly then WriteNode(Stream, Source) else begin Source := Source.FirstChild; while Assigned(Source) do begin WriteNode(Stream, Source); Source := Source.NextSibling; end; end; // Now load the serialized nodes into the target node (tree). TargetTree.BeginUpdate; try Stream.Position := 0; while Stream.Position < Stream.Size do begin Result := TargetTree.MakeNewNode; InternalConnectNode(Result, Target, TargetTree, Mode); TargetTree.InternalAddFromStream(Stream, VTTreeStreamVersion, Result); if not DoNodeCopying(Result, Target) then begin TargetTree.DeleteNode(Result); Result := nil; end else DoNodeCopied(Result); end; if ChildrenOnly then Result := Target; finally TargetTree.EndUpdate; end; finally Stream.Free; end; with TargetTree do begin InvalidateCache; if FUpdateCount = 0 then begin ValidateCache; UpdateScrollBars(True); Invalidate; end; StructureChange(Source, crNodeCopied); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CopyToClipBoard; var DataObject: IDataObject; begin if FSelectionCount > 0 then begin DataObject := TVTDataObject.Create(Self, True) as IDataObject; if OleSetClipBoard(DataObject) = S_OK then begin MarkCutCopyNodes; DoStateChange([tsCopyPending]); Invalidate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.CutToClipBoard; var DataObject: IDataObject; begin if (FSelectionCount > 0) and not (toReadOnly in FOptions.FMiscOptions) then begin DataObject := TVTDataObject.Create(Self, True) as IDataObject; if OleSetClipBoard(DataObject) = S_OK then begin MarkCutCopyNodes; DoStateChange([tsCutPending], [tsCopyPending]); Invalidate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DefaultHandler(var AMessage); begin //used to avoid default handler of LM_MOUSEWHEEL end; procedure TBaseVirtualTree.DeleteChildren(Node: PVirtualNode; ResetHasChildren: Boolean = False); // Removes all children and their children from memory without changing the vsHasChildren style by default. var Run, Mark: PVirtualNode; LastTop, LastLeft, NewSize: Integer; ParentVisible: Boolean; begin if (Node.ChildCount > 0) and not (toReadOnly in FOptions.FMiscOptions) then begin Assert(not (tsIterating in FStates), 'Deleting nodes during tree iteration leads to invalid pointers.'); // The code below uses some flags for speed improvements which may cause invalid pointers if updates of // the tree happen. Hence switch updates off until we have finished the operation. Inc(FUpdateCount); try InterruptValidation; LastLeft := -FEffectiveOffsetX; LastTop := FOffsetY; // Make a local copy of the visibility state of this node to speed up // adjusting the visible nodes count. ParentVisible := Node = FRoot; if not ParentVisible then ParentVisible := FullyVisible[Node] and (vsExpanded in Node.States); // Show that we are clearing the child list, to avoid registering structure change events. Include(Node.States, vsClearing); Run := Node.LastChild; while Assigned(Run) do begin if ParentVisible and (vsVisible in Run.States) then Dec(FVisibleCount); Include(Run.States, vsDeleting); Mark := Run; Run := Run.PrevSibling; // Important, to avoid exchange of invalid pointers while disconnecting the node. if Assigned(Run) then Run.NextSibling := nil; DeleteNode(Mark); end; Exclude(Node.States, vsClearing); if ResetHasChildren then Exclude(Node.States, vsHasChildren); if Node <> FRoot then Exclude(Node.States, vsExpanded); Node.ChildCount := 0; if (Node = FRoot) or (vsDeleting in Node.States) then begin Node.TotalHeight := FDefaultNodeHeight + NodeHeight[Node]; Node.TotalCount := 1; end else begin AdjustTotalHeight(Node, NodeHeight[Node]); AdjustTotalCount(Node, 1); end; Node.FirstChild := nil; Node.LastChild := nil; finally Dec(FUpdateCount); end; InvalidateCache; if FUpdateCount = 0 then begin NewSize := PackArray(FSelection, FSelectionCount); if NewSize > -1 then begin FSelectionCount := NewSize; SetLength(FSelection, FSelectionCount); end; ValidateCache; UpdateScrollbars(True); // Invalidate entire tree if it scrolled e.g. to make the last node also the // bottom node in the treeview. if (LastLeft <> FOffsetX) or (LastTop <> FOffsetY) then Invalidate else InvalidateToBottom(Node); end; StructureChange(Node, crChildDeleted); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DeleteNode(Node: PVirtualNode; Reindex: Boolean = True); var LastTop, LastLeft: Integer; LastParent: PVirtualNode; WasInSynchMode: Boolean; ParentClearing: Boolean; begin if Assigned(Node) and (Node <> FRoot) and not (toReadOnly in FOptions.FMiscOptions) then begin Assert(not (tsIterating in FStates), 'Deleting nodes during tree iteration leads to invalid pointers.'); // Determine parent node for structure change notification. ParentClearing := vsClearing in Node.Parent.States; LastParent := Node.Parent; if not ParentClearing then begin if LastParent = FRoot then StructureChange(nil, crChildDeleted) else StructureChange(LastParent, crChildDeleted); end; LastLeft := -FEffectiveOffsetX; LastTop := FOffsetY; if vsSelected in Node.States then begin if FUpdateCount = 0 then begin // Go temporarily into sync mode to avoid a delayed change event for the node // when unselecting. WasInSynchMode := tsSynchMode in FStates; Include(FStates, tsSynchMode); RemoveFromSelection(Node); if not WasInSynchMode then Exclude(FStates, tsSynchMode); InvalidateToBottom(LastParent); end else InternalRemoveFromSelection(Node); end else InvalidateToBottom(LastParent); if tsHint in FStates then begin Application.CancelHint; DoStateChange([], [tsHint]); end; DeleteChildren(Node); InternalDisconnectNode(Node, False, Reindex); DoFreeNode(Node); if not ParentClearing then begin DetermineHiddenChildrenFlag(LastParent); InvalidateCache; if FUpdateCount = 0 then begin ValidateCache; UpdateScrollbars(True); // Invalidate entire tree if it scrolled e.g. to make the last node also the // bottom node in the treeview. if (LastLeft <> FOffsetX) or (LastTop <> FOffsetY) then Invalidate; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DeleteSelectedNodes; // Deletes all currently selected nodes (including their child nodes). var Nodes: TNodeArray; I: Integer; LevelChange: Boolean; begin Nodes := nil; if (FSelectionCount > 0) and not (toReadOnly in FOptions.FMiscOptions) then begin BeginUpdate; try Nodes := GetSortedSelection(True); for I := High(Nodes) downto 1 do begin LevelChange := Nodes[I].Parent <> Nodes[I - 1].Parent; DeleteNode(Nodes[I], LevelChange); end; DeleteNode(Nodes[0]); finally EndUpdate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.Dragging: Boolean; begin // Check for both OLE drag'n drop as well as VCL drag'n drop. Result := ([tsOLEDragPending, tsOLEDragging] * FStates <> []) or inherited Dragging; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.EditNode(Node: PVirtualNode; Column: TColumnIndex): Boolean; // Application triggered edit event for the given node. // Returns True if the tree started editing otherwise False. begin Assert(Assigned(Node), 'Node must not be nil.'); Assert((Column > InvalidColumn) and (Column < FHeader.Columns.Count), 'Column must be a valid column index (-1 if no header is shown).'); Result := tsEditing in FStates; // If the tree is already editing then we don't disrupt this. if not Result and not (toReadOnly in FOptions.FMiscOptions) then begin FocusedNode := Node; if Assigned(FFocusedNode) and (Node = FFocusedNode) and CanEdit(FFocusedNode, Column) then begin FEditColumn := Column; if not (vsInitialized in Node.States) then InitNode(Node); DoEdit; Result := tsEditing in FStates; end else Result := False; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.EndEditNode: Boolean; // Called to finish a current edit action or stop the edit timer if an edit operation is pending. begin if [tsEditing, tsEditPending] * FStates <> [] then Result := DoEndEdit else Result := True; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.EndSynch; begin if FSynchUpdateCount > 0 then Dec(FSynchUpdateCount); if not (csDestroying in ComponentState) then begin if FSynchUpdateCount = 0 then begin DoStateChange([], [tsSynchMode]); DoUpdating(usEndSynch); end else DoUpdating(usSynch); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.EndUpdate; var NewSize: Integer; begin if FUpdateCount > 0 then Dec(FUpdateCount); if not (csDestroying in ComponentState) then begin if (FUpdateCount = 0) and (tsUpdating in FStates) then begin if tsUpdateHiddenChildrenNeeded in FStates then begin DetermineHiddenChildrenFlagAllNodes; Exclude(FStates, tsUpdateHiddenChildrenNeeded); end; DoStateChange([], [tsUpdating]); NewSize := PackArray(FSelection, FSelectionCount); if NewSize > -1 then begin FSelectionCount := NewSize; SetLength(FSelection, FSelectionCount); end; InvalidateCache; ValidateCache; if HandleAllocated then UpdateScrollBars(False); if tsStructureChangePending in FStates then DoStructureChange(FLastStructureChangeNode, FLastStructureChangeReason); try if tsChangePending in FStates then DoChange(FLastChangedNode); finally if toAutoSort in FOptions.FAutoOptions then SortTree(FHeader.FSortColumn, FHeader.FSortDirection, True); SetUpdateState(False); if HandleAllocated then Invalidate; UpdateDesigner; end; end; if FUpdateCount = 0 then DoUpdating(usEnd) else DoUpdating(usUpdate); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ExecuteAction(Action: TBasicAction): Boolean; // Some support for standard actions. begin Result := inherited ExecuteAction(Action); if not Result then begin Result := Action is TEditSelectAll; if Result then SelectAll(False) else begin Result := Action is TEditCopy; if Result then CopyToClipboard else if not (toReadOnly in FOptions.FMiscOptions) then begin Result := Action is TEditCut; if Result then CutToClipBoard else begin Result := Action is TEditPaste; if Result then PasteFromClipboard else begin Result := Action is TEditDelete; if Result then DeleteSelectedNodes end; end; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.FinishCutOrCopy; // Deletes nodes which are marked as being cutted. var Run, ToDelete: PVirtualNode; begin if tsCutPending in FStates then begin Run := FRoot.FirstChild; while Assigned(Run) do begin if vsCutOrCopy in Run.States then begin ToDelete := Run; Run := GetNextNoInit(Run); DeleteNode(ToDelete); end else Run := GetNextNoInit(Run); end; DoStateChange([], [tsCutPending]); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.FlushClipboard; // Used to render the data which is currently on the clipboard (finishes delayed rendering). begin if ClipboardStates * FStates <> [] then begin DoStateChange([tsClipboardFlushing]); OleFlushClipboard; CancelCutOrCopy; DoStateChange([], [tsClipboardFlushing]); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.FullCollapse(Node: PVirtualNode = nil); // This routine collapses all expanded nodes in the subtree given by Node or the whole tree if Node is FRoot or nil. // Only nodes which are expanded will be collapsed. This excludes uninitialized nodes but nodes marked as visible // will still be collapsed if they are expanded. var Stop: PVirtualNode; begin if FRoot.TotalCount > 1 then begin if Node = FRoot then Node := nil; DoStateChange([tsCollapsing]); BeginUpdate; try Stop := Node; Node := GetLastVisibleNoInit(Node, True); if Assigned(Node) then begin repeat if [vsHasChildren, vsExpanded] * Node.States = [vsHasChildren, vsExpanded] then ToggleNode(Node); Node := GetPreviousNoInit(Node); until Node = Stop; // Collapse the start node too. if Assigned(Node) and ([vsHasChildren, vsExpanded] * Node.States = [vsHasChildren, vsExpanded]) then ToggleNode(Node); end; finally EndUpdate; DoStateChange([], [tsCollapsing]); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.FullExpand(Node: PVirtualNode = nil); // This routine expands all collapsed nodes in the subtree given by Node or the whole tree if Node is FRoot or nil. // All nodes on the way down are initialized so this procedure might take a long time. // Since all nodes are validated, the tree cannot make use of optimatizations. Hence it is counter productive and you // should consider avoiding its use. var Stop: PVirtualNode; begin if FRoot.TotalCount > 1 then begin DoStateChange([tsExpanding]); BeginUpdate; try if Node = nil then begin Node := FRoot.FirstChild; Stop := nil; end else begin Stop := Node.NextSibling; if Stop = nil then begin Stop := Node; repeat Stop := Stop.Parent; until (Stop = FRoot) or Assigned(Stop.NextSibling); if Stop = FRoot then Stop := nil else Stop := Stop.NextSibling; end; end; // Initialize the start node. Others will be initialized in GetNext. if not (vsInitialized in Node.States) then InitNode(Node); repeat if not (vsExpanded in Node.States) then ToggleNode(Node); Node := GetNext(Node); until Node = Stop; finally EndUpdate; DoStateChange([], [tsExpanding]); end; end; end; //---------------------------------------------------------------------------------------------------------------------- {$ifndef fpc} function TBaseVirtualTree.GetControlsAlignment: TAlignment; begin Result := FAlignment; end; {$endif} //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetDisplayRect(Node: PVirtualNode; Column: TColumnIndex; TextOnly: Boolean; Unclipped: Boolean = False; ApplyCellContentMargin: Boolean = False): TRect; // Determines the client coordinates the given node covers, depending on scrolling, expand state etc. // If the given node cannot be found (because one of its parents is collapsed or it is invisible) then an empty // rectangle is returned. // If TextOnly is True then only the text bounds are returned, that is, the resulting rectangle's left and right border // are updated according to bidi mode, alignment and text width of the node. // If Unclipped is True (which only makes sense if also TextOnly is True) then the calculated text rectangle is // not clipped if the text does not entirely fit into the text space. This is special handling needed for hints. // If ApplyCellContentMargin is True (which only makes sense if also TextOnly is True) then the calculated text // rectangle respects the cell content margin. // If Column is -1 then the entire client width is used before determining the node's width otherwise the bounds of the // particular column are used. // Note: Column must be a valid column and is used independent of whether the header is visible or not. var Temp: PVirtualNode; Offset: Cardinal; Indent, TextWidth: Integer; MainColumnHit: Boolean; CurrentBidiMode: TBidiMode; CurrentAlignment: TAlignment; MaxUnclippedHeight: Integer; TM: TTextMetric; ExtraVerticalMargin: Integer; begin //{$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintHeader],'GetDisplayRect');{$endif} Assert(Assigned(Node), 'Node must not be nil.'); Assert(Node <> FRoot, 'Node must not be the hidden root node.'); MainColumnHit := (Column + 1) in [0, FHeader.MainColumn + 1]; if not (vsInitialized in Node.States) then InitNode(Node); Result := Rect(0, 0, 0, 0); // Check whether the node is visible (determine indentation level btw.). Temp := Node; if not (vsVisible in Temp.States) then Exit; Indent := 0; while Temp <> FRoot do begin if not (vsVisible in Temp.States) or not (vsExpanded in Temp.Parent.States) then Exit; Temp := Temp.Parent; if MainColumnHit and (Temp <> FRoot) then Inc(Indent, FIndent); end; // Here we know the node is visible. Offset := 0; if tsUseCache in FStates then begin // If we can use the position cache then do a binary search to find a cached node which is as close as possible // to the current node. Iterate then through all following and visible nodes and sum up their heights. Temp := FindInPositionCache(Node, Offset); while Assigned(Temp) and (Temp <> Node) do begin Inc(Offset, NodeHeight[Temp]); Temp := GetNextVisibleNoInit(Temp, True); end; end else begin // If the cache is not available then go straight through all nodes up to the root and sum up their heights. Temp := Node; repeat Temp := GetPreviousVisibleNoInit(Temp, True); if Temp = nil then Break; Inc(Offset, NodeHeight[Temp]); until False; end; Result := Rect(0, Offset, Max(FRangeX, ClientWidth), Offset + NodeHeight[Node]); // Limit left and right bounds to the given column (if any) and move bounds according to current scroll state. if Column > NoColumn then begin FHeader.FColumns.GetColumnBounds(Column, Result.Left, Result.Right); // The right column border is not part of this cell. Dec(Result.Right); OffsetRect(Result, 0, FOffsetY); end else OffsetRect(Result, -FEffectiveOffsetX, FOffsetY); // Limit left and right bounds further if only the text area is required. if TextOnly then begin // Start with the offset of the text in the column and consider the indentation level too. Offset := FMargin + Indent; // If the text of a node is involved then we have to consider directionality and alignment too. if Column <= NoColumn then begin CurrentBidiMode := BidiMode; CurrentAlignment := Alignment; end else begin CurrentBidiMode := FHeader.FColumns[Column].BidiMode; CurrentAlignment := FHeader.FColumns[Column].Alignment; end; if MainColumnHit then begin if toShowRoot in FOptions.FPaintOptions then Inc(Offset, FIndent); if (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages) and (Node.CheckType <> ctNone) then Inc(Offset, FCheckImages.Height + 2); end; // Consider associated images. if Assigned(FStateImages) and HasImage(Node, ikState, Column) then Inc(Offset, FStateImages.Width + 2); if Assigned(FImages) and HasImage(Node, ikNormal, Column) then Inc(Offset, FImages.Width + 2); // Offset contains now the distance from the left or right border of the rectangle (depending on bidi mode). // Now consider the alignment too and calculate the final result. if CurrentBidiMode = bdLeftToRight then begin Inc(Result.Left, Offset); // Left-to-right reading does not need any special adjustment of the alignment. end else begin Dec(Result.Right, Offset); // Consider bidi mode here. In RTL context does left alignment actually mean right alignment and vice versa. ChangeBiDiModeAlignment(CurrentAlignment); end; TextWidth := DoGetNodeWidth(Node, Column); // Keep cell height before applying cell content margin in order to increase cell height if text does not fit // and Unclipped it true (see below). MaxUnclippedHeight := Result.Bottom - Result.Top; if ApplyCellContentMargin then DoBeforeCellPaint(Self.Canvas, Node, Column, cpmGetContentMargin, Result, Result); if Unclipped then begin // The caller requested the text coordinates unclipped. This means they must be calculated so as would // there be enough space, regardless of column bounds etc. // The layout still depends on the available space too, because this determines the position // of the unclipped text rectangle. if Result.Right - Result.Left < TextWidth - 1 then if CurrentBidiMode = bdLeftToRight then CurrentAlignment := taLeftJustify else CurrentAlignment := taRightJustify; // Increase cell height (up to MaxUnclippedHeight determined above) if text does not fit. GetTextMetrics(Self.Canvas.Handle, TM); ExtraVerticalMargin := Math.Min(TM.tmHeight, MaxUnclippedHeight) - (Result.Bottom - Result.Top); if ExtraVerticalMargin > 0 then InflateRect(Result, 0, (ExtraVerticalMargin + 1) div 2); case CurrentAlignment of taCenter: begin Result.Left := (Result.Left + Result.Right - TextWidth) div 2; Result.Right := Result.Left + TextWidth; end; taRightJustify: Result.Left := Result.Right - TextWidth; else // taLeftJustify Result.Right := Result.Left + TextWidth - 1; end; end else // Modify rectangle only if the text fits entirely into the given room. if Result.Right - Result.Left > TextWidth then case CurrentAlignment of taCenter: begin Result.Left := (Result.Left + Result.Right - TextWidth) div 2; Result.Right := Result.Left + TextWidth; end; taRightJustify: Result.Left := Result.Right - TextWidth; else // taLeftJustify Result.Right := Result.Left + TextWidth; end; end; //lclheader //todo: add a parameter to decide if the result must be returned as //a tree offset or a control offset if hoVisible in FHeader.FOptions then OffsetRect(Result, 0, FHeader.Height); //{$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'DisplayRect for Node '+IntToStr(Node^.Index),Result);{$endif} //{$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintHeader],'GetDisplayRect');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirst(ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the first node in the tree while optionally considering toChildrenAbove. begin if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin if vsHasChildren in FRoot.States then begin Result := FRoot; // Child nodes are the first choice if possible. if Assigned(Result.FirstChild) then begin while Assigned(Result.FirstChild) do begin Result := Result.FirstChild; if not (vsInitialized in Result.States) then InitNode(Result); if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then InitChildren(Result); end; end else Result := nil; end else Result := nil; end else Result := FRoot.FirstChild; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstChecked(State: TCheckState = csCheckedNormal; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the first node in the tree with the given check state. begin Result := GetNextChecked(nil, State, ConsiderChildrenAbove); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstChild(Node: PVirtualNode): PVirtualNode; // Returns the first child of the given node. The result node is initialized before exit. begin if (Node = nil) or (Node = FRoot) then Result := FRoot.FirstChild else begin if not (vsInitialized in Node.States) then InitNode(Node); if vsHasChildren in Node.States then begin if Node.ChildCount = 0 then InitChildren(Node); Result := Node.FirstChild; end else Result := nil; end; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstCutCopy(ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the first node in the tree which is currently marked for a clipboard operation. // See also GetNextCutCopy for comments on initialization. begin Result := GetNextCutCopy(nil, ConsiderChildrenAbove); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstInitialized(ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the first node which is already initialized. begin Result := GetFirstNoInit(ConsiderChildrenAbove); if Assigned(Result) and not (vsInitialized in Result.States) then Result := GetNextInitialized(Result, ConsiderChildrenAbove); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstLeaf: PVirtualNode; // Returns the first node in the tree which has currently no children. // The result is initialized if necessary. begin Result := GetNextLeaf(nil); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstLevel(NodeLevel: Cardinal): PVirtualNode; // Returns the first node in the tree on a specific level. // The result is initialized if necessary. begin Result := GetFirstNoInit(True); while Assigned(Result) and (GetNodeLevel(Result) <> NodeLevel) do Result := GetNextNoInit(Result, True); if Assigned(Result) and (GetNodeLevel(Result) <> NodeLevel) then // i.e. there is no node with the desired level in the tree Result := nil; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstNoInit(ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the first node in the tree while optionally considering toChildrenAbove. // No initialization is performed. begin if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin if vsHasChildren in FRoot.States then begin Result := FRoot; // Child nodes are the first choice if possible. if Assigned(Result.FirstChild) then begin while Assigned(Result.FirstChild) do Result := Result.FirstChild; end else Result := nil; end else Result := nil; end else Result := FRoot.FirstChild; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstSelected(ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the first node in the current selection while optionally considering toChildrenAbove. begin Result := GetNextSelected(nil, ConsiderChildrenAbove); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstVisible(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode; // Returns the first visible node in the tree while optionally considering toChildrenAbove. // If necessary nodes are initialized on demand. begin Result := Node; if not Assigned(Result) then Result := FRoot; if vsHasChildren in Result.States then begin if Result.ChildCount = 0 then InitChildren(Result); // Child nodes are the first choice if possible. if Assigned(Result.FirstChild) then begin Result := GetFirstChild(Result); if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin repeat // Search the first visible sibling. while Assigned(Result.NextSibling) and not (vsVisible in Result.States) do begin Result := Result.NextSibling; // Init node on demand as this might change the visibility. if not (vsInitialized in Result.States) then InitNode(Result); end; // If there a no visible siblings take the parent. if not (vsVisible in Result.States) then begin Result := Result.Parent; if Result = FRoot then Result := nil; Break; end else begin if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then InitChildren(Result); if (not Assigned(Result.FirstChild)) or (not (vsExpanded in Result.States)) then Break; end; Result := Result.FirstChild; if not (vsInitialized in Result.States) then InitNode(Result); until False; end else begin // If there are no children or the first child is not visible then search the sibling nodes or traverse parents. if not (vsVisible in Result.States) then begin repeat // Is there a next sibling? if Assigned(Result.NextSibling) then begin Result := Result.NextSibling; // The visible state can be removed during initialization so init the node first. if not (vsInitialized in Result.States) then InitNode(Result); if vsVisible in Result.States then Break; end else begin // No sibling anymore, so use the parent's next sibling. if Result.Parent <> FRoot then Result := Result.Parent else begin // There are no further nodes to examine, hence there is no further visible node. Result := nil; Break; end; end; until False; end; end; end else Result := nil; end else Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstVisibleChild(Node: PVirtualNode): PVirtualNode; // Returns the first visible child node of Node. If necessary nodes are initialized on demand. begin if Node = nil then Node := FRoot; Result := GetFirstChild(Node); if Assigned(Result) and not (vsVisible in Result.States) then Result := GetNextVisibleSibling(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstVisibleChildNoInit(Node: PVirtualNode): PVirtualNode; // Returns the first visible child node of Node. begin if Node = nil then Node := FRoot; Result := Node.FirstChild; if Assigned(Result) and not (vsVisible in Result.States) then Result := GetNextVisibleSiblingNoInit(ResulT); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetFirstVisibleNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode; // Returns the first visible node in the tree or given subtree while optionally considering toChildrenAbove. // No initialization is performed. begin Result := Node; if not Assigned(Result) then Result := FRoot; if vsHasChildren in Result.States then begin // Child nodes are the first choice if possible. if Assigned(Result.FirstChild) then begin Result := Result.FirstChild; if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin repeat // Search the first visible sibling. while Assigned(Result.NextSibling) and not (vsVisible in Result.States) do Result := Result.NextSibling; // If there a no visible siblings take the parent. if not (vsVisible in Result.States) then begin Result := Result.Parent; if Result = FRoot then Result := nil; Break; end else if (not Assigned(Result.FirstChild)) or (not (vsExpanded in Result.States))then Break; Result := Result.FirstChild; until False; end else begin // If there are no children or the first child is not visible then search the sibling nodes or traverse parents. if not (vsVisible in Result.States) then begin repeat // Is there a next sibling? if Assigned(Result.NextSibling) then begin Result := Result.NextSibling; if vsVisible in Result.States then Break; end else begin // No sibling anymore, so use the parent's next sibling. if Result.Parent <> FRoot then Result := Result.Parent else begin // There are no further nodes to examine, hence there is no further visible node. Result := nil; Break; end; end; until False; end; end; end else Result := nil; end else Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.GetHitTestInfoAt(X, Y: Integer; Relative: Boolean; var HitInfo: THitInfo); // Determines the node that occupies the specified point or nil if there's none. The parameter Relative determines // whether to consider X and Y as being client coordinates (if True) or as being absolute tree coordinates. // HitInfo is filled with flags describing the hit further. var ColLeft, ColRight: Integer; NodeTop: Integer; InitialColumn, NextColumn: TColumnIndex; CurrentBidiMode: TBidiMode; CurrentAlignment: TAlignment; NodeRect: TRect; begin HitInfo.HitNode := nil; HitInfo.HitPositions := []; HitInfo.HitColumn := NoColumn; // Determine if point lies in the tree's client area. if X < 0 then Include(HitInfo.HitPositions, hiToLeft) else if X > Max(FRangeX, ClientWidth) then Include(HitInfo.HitPositions, hiToRight); //lclheader if Y < IfThen(hoVisible in FHeader.Options, FHeader.Height) then Include(HitInfo.HitPositions, hiAbove) else if Y > Max(FRangeY, inherited GetClientRect.Bottom) then Include(HitInfo.HitPositions, hiBelow); // If the point is in the tree area then check the nodes. if HitInfo.HitPositions = [] then begin // Convert position into absolute coordinate if necessary. if Relative then begin if X > Header.Columns.GetVisibleFixedWidth then Inc(X, FEffectiveOffsetX); //lclheader if hoVisible in FHeader.Options then Dec(Y, FHeader.Height); Dec(Y, FOffsetY); end; HitInfo.HitNode := InternalGetNodeAt(X, Y, False, NodeTop); if HitInfo.HitNode = nil then Include(HitInfo.HitPositions, hiNowhere) else begin // At this point we need some info about the node, so it must be initialized. if not (vsInitialized in HitInfo.HitNode.States) then InitNode(HitInfo.HitNode); if FHeader.UseColumns then begin HitInfo.HitColumn := FHeader.Columns.GetColumnAndBounds(Point(X, Y), ColLeft, ColRight, False); // If auto column spanning is enabled then look for the last non empty column. if toAutoSpanColumns in FOptions.FAutoOptions then begin InitialColumn := HitInfo.HitColumn; // Search to the left of the hit column for empty columns. while (HitInfo.HitColumn > NoColumn) and ColumnIsEmpty(HitInfo.HitNode, HitInfo.HitColumn) do begin NextColumn := FHeader.FColumns.GetPreviousVisibleColumn(HitInfo.HitColumn); if NextColumn = InvalidColumn then Break; HitInfo.HitColumn := NextColumn; Dec(ColLeft, FHeader.FColumns[NextColumn].Width); end; // Search to the right of the hit column for empty columns. repeat InitialColumn := FHeader.FColumns.GetNextVisibleColumn(InitialColumn); if (InitialColumn = InvalidColumn) or not ColumnIsEmpty(HitInfo.HitNode, InitialColumn) then Break; Inc(ColRight, FHeader.FColumns[InitialColumn].Width); until False; end; // Make the X position and the right border relative to the start of the column. Dec(X, ColLeft); Dec(ColRight, ColLeft); end else begin HitInfo.HitColumn := NoColumn; ColRight := Max(FRangeX, ClientWidth); end; ColLeft := 0; if HitInfo.HitColumn = InvalidColumn then Include(HitInfo.HitPositions, hiNowhere) else begin // From now on X is in "column" coordinates (relative to the left column border). HitInfo.HitPositions := [hiOnItem]; // Avoid getting the display rect if this is not necessary. if toNodeHeightResize in FOptions.FMiscOptions then begin NodeRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, False); if Y <= (NodeRect.Top - FOffsetY + 1) then Include(HitInfo.HitPositions, hiUpperSplitter) else if Y >= (NodeRect.Bottom - FOffsetY - 3) then Include(HitInfo.HitPositions, hiLowerSplitter); end; if HitInfo.HitColumn <= NoColumn then begin CurrentBidiMode := BidiMode; CurrentAlignment := Alignment; end else begin CurrentBidiMode := FHeader.FColumns[HitInfo.HitColumn].BidiMode; CurrentAlignment := FHeader.FColumns[HitInfo.HitColumn].Alignment; end; if CurrentBidiMode = bdLeftToRight then DetermineHitPositionLTR(HitInfo, X, ColRight, CurrentAlignment) else DetermineHitPositionRTL(HitInfo, X, ColRight, CurrentAlignment); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetLast(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the very last node in the tree branch given by Node and initializes the nodes all the way down including the // result. toChildrenAbove is optionally considered. By using Node = nil the very last node in the tree is returned. var Next: PVirtualNode; begin Result := GetLastChild(Node); if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then while Assigned(Result) do begin // Test if there is a next last child. If not keep the node from the last run. // Otherwise use the next last child. Next := GetLastChild(Result); if Next = nil then Break; Result := Next; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetLastInitialized(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the very last initialized child node in the tree branch given by Node. begin Result := GetLastNoInit(Node, ConsiderChildrenAbove); if Assigned(Result) and not (vsInitialized in Result.States) then Result := GetPreviousInitialized(Result, ConsiderChildrenAbove); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetLastNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the very last node in the tree branch given by Node without initialization. var Next: PVirtualNode; begin Result := GetLastChildNoInit(Node); if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then while Assigned(Result) do begin // Test if there is a next last child. If not keep the node from the last run. // Otherwise use the next last child. Next := GetLastChildNoInit(Result); if Next = nil then Break; Result := Next; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetLastChild(Node: PVirtualNode): PVirtualNode; // Determines the last child of the given node and initializes it if there is one. begin if (Node = nil) or (Node = FRoot) then Result := FRoot.LastChild else begin if not (vsInitialized in Node.States) then InitNode(Node); if vsHasChildren in Node.States then begin if Node.ChildCount = 0 then InitChildren(Node); Result := Node.LastChild; end else Result := nil; end; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetLastChildNoInit(Node: PVirtualNode): PVirtualNode; // Determines the last child of the given node but does not initialize it. begin if (Node = nil) or (Node = FRoot) then Result := FRoot.LastChild else begin if vsHasChildren in Node.States then Result := Node.LastChild else Result := nil; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetLastVisible(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode; // Returns the very last visible node in the tree while optionally considering toChildrenAbove. // The nodes are intialized all the way down including the result node. var Next: PVirtualNode; begin Result := GetLastVisibleChild(Node); if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then while Assigned(Result) do begin // Test if there is a next last visible child. If not keep the node from the last run. // Otherwise use the next last visible child. Next := GetLastVisibleChild(Result); if Next = nil then Break; Result := Next; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetLastVisibleChild(Node: PVirtualNode): PVirtualNode; // Determines the last visible child of the given node and initializes it if necessary. begin if (Node = nil) or (Node = FRoot) then Result := GetLastChild(FRoot) else if FullyVisible[Node] and (vsExpanded in Node.States) then Result := GetLastChild(Node) else Result := nil; if Assigned(Result) and not (vsVisible in Result.States) then Result := GetPreviousVisibleSibling(Result); if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetLastVisibleChildNoInit(Node: PVirtualNode): PVirtualNode; // Determines the last visible child of the given node without initialization. begin if (Node = nil) or (Node = FRoot) then Result := GetLastChildNoInit(FRoot) else if FullyVisible[Node] and (vsExpanded in Node.States) then Result := GetLastChildNoInit(Node) else Result := nil; if Assigned(Result) and not (vsVisible in Result.States) then Result := GetPreviousVisibleSiblingNoInit(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetLastVisibleNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode; // Returns the very last visible node in the tree while optionally considering toChildrenAbove. // No initialization is performed. var Next: PVirtualNode; begin Result := GetLastVisibleChildNoInit(Node); if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then while Assigned(Result) do begin // Test if there is a next last visible child. If not keep the node from the last run. // Otherwise use the next last visible child. Next := GetLastVisibleChildNoInit(Result); if Next = nil then Break; Result := Next; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetMaxColumnWidth(Column: TColumnIndex; UseSmartColumnWidth: Boolean = False): Integer; // This method determines the width of the largest node in the given column. // If UseSmartColumnWidth is True then only the visible nodes which are in view will be considered // Note: If UseSmartColumnWidth is False then every visible node in the tree will be initialized contradicting so // the virtual paradigm. var Run, LastNode, NextNode: PVirtualNode; NodeLeft, TextLeft, CurrentWidth: Integer; WithCheck, WithImages, WithStateImages: Boolean; CheckOffset, ImageOffset, StateImageOffset: Integer; begin if OperationCanceled then begin // Behave non-destructive. Result := FHeader.FColumns[Column].Width; Exit; end else Result := 0; BeginOperation; if Assigned(FOnBeforeGetMaxColumnWidth) then FOnBeforeGetMaxColumnWidth(FHeader, Column, UseSmartColumnWidth); // Don't check the event here as descendant trees might have overriden the DoGetImageIndex method. WithImages := Assigned(FImages); if WithImages then ImageOffset := FImages.Width + 2 else ImageOffset := 0; WithStateImages := Assigned(FStateImages); if WithStateImages then StateImageOffset := FStateImages.Width + 2 else StateImageOffset := 0; if Assigned(FCheckImages) then CheckOffset := FCheckImages.Height + 2 else CheckOffset := 0; if UseSmartColumnWidth then // Get first visible node which is in view. Run := GetTopNode else Run := GetFirstVisible(nil, True); if Column = FHeader.MainColumn then begin if toFixedIndent in FOptions.FPaintOptions then NodeLeft := FIndent else begin if toShowRoot in FOptions.FPaintOptions then NodeLeft := Integer((GetNodeLevel(Run) + 1) * FIndent) else NodeLeft := Integer(GetNodeLevel(Run) * FIndent); end; WithCheck := (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages); end else begin NodeLeft := 0; WithCheck := False; end; // Consider node margin at the left of the nodes. Inc(NodeLeft, FMargin); // Decide where to stop. if UseSmartColumnWidth then LastNode := GetNextVisible(BottomNode) else LastNode := nil; while Assigned(Run) and not OperationCanceled do begin TextLeft := NodeLeft; if WithCheck and (Run.CheckType <> ctNone) then Inc(TextLeft, CheckOffset); if WithImages and HasImage(Run, ikNormal, Column) then Inc(TextLeft, ImageOffset); if WithStateImages and HasImage(Run, ikState, Column) then Inc(TextLeft, StateImageOffset); CurrentWidth := DoGetNodeWidth(Run, Column); Inc(CurrentWidth, DoGetCellContentMargin(Run, Column).X); if Result < (TextLeft + CurrentWidth) then Result := TextLeft + CurrentWidth; // Get next visible node and update left node position if needed. NextNode := GetNextVisible(Run, True); if NextNode = LastNode then Break; if (Column = Header.MainColumn) and not (toFixedIndent in FOptions.FPaintOptions) then Inc(NodeLeft, CountLevelDifference(Run, NextNode) * Integer(FIndent)); Run := NextNode; end; if toShowVertGridLines in FOptions.FPaintOptions then Inc(Result); if Assigned(FOnAfterGetMaxColumnWidth) then FOnAfterGetMaxColumnWidth(FHeader, Column, Result); EndOperation; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNext(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns next node in tree while optionally considering toChildrenAbove. The Result will be initialized if needed. begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin // If this node has no siblings use the parent. if not Assigned(Result.NextSibling) then begin Result := Result.Parent; if Result = FRoot then begin Result := nil; end; end else begin // There is at least one sibling so take it. Result := Result.NextSibling; // Has this node got children? Initialize them if necessary. if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then InitChildren(Result); // Now take a look at the children. while Assigned(Result.FirstChild) do begin Result := Result.FirstChild; if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then InitChildren(Result); end; end; end else begin // Has this node got children? if vsHasChildren in Result.States then begin // Yes, there are child nodes. Initialize them if necessary. if Result.ChildCount = 0 then InitChildren(Result); end; // if there is no child node try siblings if Assigned(Result.FirstChild) then Result := Result.FirstChild else begin repeat // Is there a next sibling? if Assigned(Result.NextSibling) then begin Result := Result.NextSibling; Break; end else begin // No sibling anymore, so use the parent's next sibling. if Result.Parent <> FRoot then Result := Result.Parent else begin // There are no further nodes to examine, hence there is no further visible node. Result := nil; Break; end; end; until False; end; end; end; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal; ConsiderChildrenAbove: Boolean = False): PVirtualNode; begin if (Node = nil) or (Node = FRoot) then Result := GetFirstNoInit(ConsiderChildrenAbove) else Result := GetNextNoInit(Node, ConsiderChildrenAbove); while Assigned(Result) and (Result.CheckState <> State) do Result := GetNextNoInit(Result, ConsiderChildrenAbove); if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextCutCopy(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the next node in the tree which is currently marked for a clipboard operation. Since only visible nodes can // be marked (or they are hidden after they have been marked) it is not necessary to initialize nodes to check for // child nodes. The result, however, is initialized if necessary. begin if ClipboardStates * FStates <> [] then begin if (Node = nil) or (Node = FRoot) then Result := GetFirstNoInit(ConsiderChildrenAbove) else Result := GetNextNoInit(Node, ConsiderChildrenAbove); while Assigned(Result) and not (vsCutOrCopy in Result.States) do Result := GetNextNoInit(Result, ConsiderChildrenAbove); if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end else Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextInitialized(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the next node in tree which is initialized. begin Result := Node; repeat Result := GetNextNoInit(Result, ConsiderChildrenAbove); until (Result = nil) or (vsInitialized in Result.States); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextLeaf(Node: PVirtualNode): PVirtualNode; // Returns the next node in the tree which has currently no children. // The result is initialized if necessary. begin if (Node = nil) or (Node = FRoot) then Result := FRoot.FirstChild else Result := GetNext(Node); while Assigned(Result) and (vsHasChildren in Result.States) do Result := GetNext(Result); if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode; // Returns the next node in the tree on a specific level. // The result is initialized if necessary. var StartNodeLevel: Cardinal; begin Result := nil; if Assigned(Node) and (Node <> FRoot) then begin StartNodeLevel := GetNodeLevel(Node); if StartNodeLevel < NodeLevel then begin Result := GetNext(Node); if Assigned(Result) and (GetNodeLevel(Result) <> NodeLevel) then Result := GetNextLevel(Result, NodeLevel); end else if StartNodeLevel = NodeLevel then begin Result := Node.NextSibling; if not Assigned(Result) then // i.e. start node was a last sibling begin Result := Node.Parent; if Assigned(Result) then begin // go to next anchestor of the start node which has a next sibling (if exists) while Assigned(Result) and not Assigned(Result.NextSibling) do Result := Result.Parent; if Assigned(Result) then Result := GetNextLevel(Result.NextSibling, NodeLevel); end; end; end else // i.e. StartNodeLevel > NodeLevel Result := GetNextLevel(Node.Parent, NodeLevel); end; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean): PVirtualNode; // Optimized version of GetNext performing no initialization, but optionally considering toChildrenAbove. begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin // If this node has no siblings use the parent. if not Assigned(Result.NextSibling) then begin Result := Result.Parent; if Result = FRoot then begin Result := nil; end; end else begin // There is at least one sibling so take it. Result := Result.NextSibling; // Now take a look at the children. while Assigned(Result.FirstChild) do begin Result := Result.FirstChild; end; end; end else begin // If there is no child node try siblings. if Assigned(Result.FirstChild) then Result := Result.FirstChild else begin repeat // Is there a next sibling? if Assigned(Result.NextSibling) then begin Result := Result.NextSibling; Break; end else begin // No sibling anymore, so use the parent's next sibling. if Result.Parent <> FRoot then Result := Result.Parent else begin // There are no further nodes to examine, hence there is no further visible node. Result := nil; Break; end; end; until False; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the next node in the tree which is currently selected. Since children of unitialized nodes cannot be // in the current selection (because they simply do not exist yet) it is not necessary to initialize nodes here. // The result however is initialized if necessary. begin if FSelectionCount > 0 then begin if (Node = nil) or (Node = FRoot) then Result := GetFirstNoInit(ConsiderChildrenAbove) else Result := GetNextNoInit(Node, ConsiderChildrenAbove); while Assigned(Result) and not (vsSelected in Result.States) do Result := GetNextNoInit(Result, ConsiderChildrenAbove); if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end else Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextSibling(Node: PVirtualNode): PVirtualNode; // Returns the next sibling of Node and initializes it if necessary. begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); Result := Result.NextSibling; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextSiblingNoInit(Node: PVirtualNode): PVirtualNode; // Returns the next sibling of Node performing no initialization. begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); Result := Result.NextSibling; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; // Returns next node in tree, with regard to Node, which is visible. // Nodes which need an initialization (including the result) are initialized. // toChildrenAbove is optionally considered which is the default here. var ForceSearch: Boolean; begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); // If the given node is not visible then look for a parent node which is visible, otherwise we will // likely go unnecessarily through a whole bunch of invisible nodes. if not FullyVisible[Result] then Result := GetVisibleParent(Result); if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin repeat // If there a no siblings anymore, go up one level. if not Assigned(Result.NextSibling) then begin Result := Result.Parent; if Result = FRoot then begin Result := nil; Break; end; if not (vsInitialized in Result.States) then InitNode(Result); if vsVisible in Result.States then Break; end else begin // There is at least one sibling so take it. Result := Result.NextSibling; if not (vsInitialized in Result.States) then InitNode(Result); if not (vsVisible in Result.States) then Continue; // Now take a look at the children. // As the children are initialized while toggling, we don't need to do this here. while (vsExpanded in Result.States) and Assigned(Result.FirstChild) do begin Result := Result.FirstChild; if not (vsInitialized in Result.States) then InitNode(Result); if not (vsVisible in Result.States) then Break; end; // If we found a visible node we don't need to search any longer. if vsVisible in Result.States then Break; end; until False; end else begin // Has this node got children? if [vsHasChildren, vsExpanded] * Result.States = [vsHasChildren, vsExpanded] then begin // Yes, there are child nodes. Initialize them if necessary. if Result.ChildCount = 0 then InitChildren(Result); end; // Child nodes are the first choice if possible. if (vsExpanded in Result.States) and Assigned(Result.FirstChild) then begin Result := GetFirstChild(Result); ForceSearch := False; end else ForceSearch := True; // If there are no children or the first child is not visible then search the sibling nodes or traverse parents. if Assigned(Result) and (ForceSearch or not (vsVisible in Result.States)) then begin repeat // Is there a next sibling? if Assigned(Result.NextSibling) then begin Result := Result.NextSibling; if not (vsInitialized in Result.States) then InitNode(Result); if vsVisible in Result.States then Break; end else begin // No sibling anymore, so use the parent's next sibling. if Result.Parent <> FRoot then Result := Result.Parent else begin // There are no further nodes to examine, hence there is no further visible node. Result := nil; Break; end; end; until False; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; // Returns the next node in tree, with regard to Node, which is visible. // toChildrenAbove is optionally considered (which is the default). No initialization is done. var ForceSearch: Boolean; begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin repeat // If there a no siblings anymore, go up one level. if not Assigned(Result.NextSibling) then begin Result := Result.Parent; if Result = FRoot then begin Result := nil; Break; end; if vsVisible in Result.States then Break; end else begin // There is at least one sibling so take it. Result := Result.NextSibling; if not (vsVisible in Result.States) then Continue; // Now take a look at the children. while (vsExpanded in Result.States) and Assigned(Result.FirstChild) do begin Result := Result.FirstChild; if not (vsVisible in Result.States) then Break; end; // If we found a visible node we don't need to search any longer. if vsVisible in Result.States then Break; end; until False; end else begin // If the given node is not visible then look for a parent node which is visible, otherwise we will // likely go unnecessarily through a whole bunch of invisible nodes. if not FullyVisible[Result] then Result := GetVisibleParent(Result); // Child nodes are the first choice if possible. if (vsExpanded in Result.States) and Assigned(Result.FirstChild) then begin Result := Result.FirstChild; ForceSearch := False; end else ForceSearch := True; // If there are no children or the first child is not visible then search the sibling nodes or traverse parents. if ForceSearch or not (vsVisible in Result.States) then begin repeat // Is there a next sibling? if Assigned(Result.NextSibling) then begin Result := Result.NextSibling; if vsVisible in Result.States then Break; end else begin // No sibling anymore, so use the parent's next sibling. if Result.Parent <> FRoot then Result := Result.Parent else begin // There are no further nodes to examine, hence there is no further visible node. Result := nil; Break; end; end; until False; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextVisibleSibling(Node: PVirtualNode): PVirtualNode; // Returns the next visible sibling after Node. Initialization is done implicitly. begin Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.'); Result := Node; repeat Result := GetNextSibling(Result); until not Assigned(Result) or (vsVisible in Result.States); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNextVisibleSiblingNoInit(Node: PVirtualNode): PVirtualNode; // Returns the next visible sibling after Node. begin Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.'); Result := Node; repeat Result := Result.NextSibling; until not Assigned(Result) or (vsVisible in Result.States); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNodeAt(X, Y: Integer): PVirtualNode; // Overloaded variant of GetNodeAt to easy life of application developers which do not need to have the exact // top position returned and always use client coordinates. var Dummy: Integer; begin Result := GetNodeAt(X, Y, True, Dummy); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNodeAt(X, Y: Integer; Relative: Boolean; var NodeTop: Integer): PVirtualNode; var OffsetByHeader: Boolean; begin //lclheader OffsetByHeader := Relative and (hoVisible in FHeader.Options); if OffsetByHeader then Dec(Y, FHeader.Height); Result := InternalGetNodeAt(X, Y, Relative, NodeTop); //lclheader if OffsetByHeader then Inc(NodeTop, FHeader.Height); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNodeData(Node: PVirtualNode): Pointer; // Returns the address of the user defined data area in the node. begin Assert(FNodeDataSize > 0, 'NodeDataSize not initialized.'); if (FNodeDataSize <= 0) or (Node = nil) or (Node = FRoot) then Result := nil else Result := PByte(@Node.Data) + FTotalInternalDataSize; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetNodeLevel(Node: PVirtualNode): Cardinal; // returns the level of the given node var Run: PVirtualNode; begin Result := 0; if Assigned(Node) and (Node <> FRoot) then begin Run := Node.Parent; while Run <> FRoot do begin Run := Run.Parent; Inc(Result); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPrevious(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns previous node in tree. If ConsiderChildrenAbove is True the function considers // whether toChildrenAbove is currently set, otherwise the result will always be the previous // node in top-down order regardless of the current PaintOptions. // The Result will be initialized if needed. var Run: PVirtualNode; begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin // Has this node got children? Initialize them if necessary. if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then InitChildren(Result); // If there is a last child, take it; if not try the previous sibling. if Assigned(Result.LastChild) then Result := Result.LastChild else if Assigned(Result.PrevSibling) then Result := Result.PrevSibling else begin // If neither a last child nor a previous sibling exist, go the tree upwards and // look, wether one of the parent nodes have a previous sibling. If not the result // will ne nil. repeat Result := Result.Parent; Run := nil; if Result <> FRoot then Run := Result.PrevSibling else Result := nil; until Assigned(Run) or (Result = nil); if Assigned(Run) then Result := Run; end; end else begin // Is there a previous sibling? if Assigned(Node.PrevSibling) then begin // Go down and find the last child node. Result := GetLast(Node.PrevSibling); if Result = nil then Result := Node.PrevSibling; end else // no previous sibling so the parent of the node is the previous visible node if Node.Parent <> FRoot then Result := Node.Parent else Result := nil; end; end; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal; ConsiderChildrenAbove: Boolean = False): PVirtualNode; begin if (Node = nil) or (Node = FRoot) then Result := GetLastNoInit(nil, ConsiderChildrenAbove) else Result := GetPreviousNoInit(Node, ConsiderChildrenAbove); while Assigned(Result) and (Result.CheckState <> State) do Result := GetPreviousNoInit(Result, ConsiderChildrenAbove); if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousCutCopy(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the previous node in the tree which is currently marked for a clipboard operation. Since only visible nodes can // be marked (or they are hidden after they have been marked) it is not necessary to initialize nodes to check for // child nodes. The result, however, is initialized if necessary. begin if ClipboardStates * FStates <> [] then begin if (Node = nil) or (Node = FRoot) then Result := GetLastNoInit(nil, ConsiderChildrenAbove) else Result := GetPreviousNoInit(Node, ConsiderChildrenAbove); while Assigned(Result) and not (vsCutOrCopy in Result.States) do Result := GetPreviousNoInit(Result, ConsiderChildrenAbove); if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end else Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousInitialized(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the previous node in tree which is initialized. begin Result := Node; repeat Result := GetPreviousNoInit(Result, ConsiderChildrenAbove); until (Result = nil) or (vsInitialized in Result.States); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousLeaf(Node: PVirtualNode): PVirtualNode; // Returns the previous node in the tree which has currently no children. // The result is initialized if necessary. begin if (Node = nil) or (Node = FRoot) then Result := FRoot.LastChild else Result := GetPrevious(Node); while Assigned(Result) and (vsHasChildren in Result.States) do Result := GetPrevious(Result); if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode; // Returns the previous node in the tree on a specific level. // The result is initialized if necessary. var StartNodeLevel: Cardinal; Run: PVirtualNode; begin Result := nil; if Assigned(Node) and (Node <> FRoot) then begin StartNodeLevel := GetNodeLevel(Node); if StartNodeLevel < NodeLevel then begin Result := Node.PrevSibling; if Assigned(Result) then begin // go to last descendant of previous sibling with desired node level (if exists) Run := Result; while Assigned(Run) and (GetNodeLevel(Run) < NodeLevel) do begin Result := Run; Run := GetLastChild(Run); end; if Assigned(Run) and (GetNodeLevel(Run) = NodeLevel) then Result := Run else begin if Assigned(Result.PrevSibling) then Result := GetPreviousLevel(Result, NodeLevel) else if Assigned(Result) and (Result.Parent <> FRoot) then Result := GetPreviousLevel(Result.Parent, NodeLevel) else Result := nil; end; end else Result := GetPreviousLevel(Node.Parent, NodeLevel); end else if StartNodeLevel = NodeLevel then begin Result := Node.PrevSibling; if not Assigned(Result) then // i.e. start node was a first sibling begin Result := Node.Parent; if Assigned(Result) then Result := GetPreviousLevel(Result, NodeLevel); end; end else // i.e. StartNodeLevel > NodeLevel Result := GetPreviousLevel(Node.Parent, NodeLevel); end; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns previous node in tree, optionally considering toChildrenAbove. No initialization is performed. var Run: PVirtualNode; begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin // If there is a last child, take it; if not try the previous sibling. if Assigned(Result.LastChild) then Result := Result.LastChild else if Assigned(Result.PrevSibling) then Result := Result.PrevSibling else begin // If neither a last child nor a previous sibling exist, go the tree upwards and // look, wether one of the parent nodes have a previous sibling. If not the result // will ne nil. repeat Result := Result.Parent; Run := nil; if Result <> FRoot then Run := Result.PrevSibling else Result := nil; until Assigned(Run) or (Result = nil); if Assigned(Run) then Result := Run; end; end else begin // Is there a previous sibling? if Assigned(Node.PrevSibling) then begin // Go down and find the last child node. Result := GetLastNoInit(Node.PrevSibling); if Result = nil then Result := Node.PrevSibling; end else // No previous sibling so the parent of the node is the previous node. if Node.Parent <> FRoot then Result := Node.Parent else Result := nil end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the previous node in the tree which is currently selected. Since children of unitialized nodes cannot be // in the current selection (because they simply do not exist yet) it is not necessary to initialize nodes here. // The result however is initialized if necessary. begin if FSelectionCount > 0 then begin if (Node = nil) or (Node = FRoot) then Result := FRoot.LastChild else Result := GetPreviousNoInit(Node, ConsiderChildrenAbove); while Assigned(Result) and not (vsSelected in Result.States) do Result := GetPreviousNoInit(Result, ConsiderChildrenAbove); if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end else Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousSibling(Node: PVirtualNode): PVirtualNode; // Get next sibling of Node, initialize it if necessary. begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); Result := Result.PrevSibling; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousSiblingNoInit(Node: PVirtualNode): PVirtualNode; // Get next sibling of Node, performes no initialization. begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); Result := Result.PrevSibling; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; // Returns the previous node in tree, with regard to Node, which is visible. // Nodes which need an initialization (including the result) are initialized. // toChildrenAbove is optionally considered which is the default here. var Marker: PVirtualNode; begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); repeat // If the given node is not visible then look for a parent node which is visible and use its last visible // child or the parent node (if there is no visible child) as result. if not FullyVisible[Result] then begin Result := GetVisibleParent(Result); if Result = FRoot then Result := nil; Marker := GetLastVisible(Result, True); if Assigned(Marker) then Result := Marker; end else begin if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin repeat if Assigned(Result.LastChild) and (vsExpanded in Result.States) then begin Result := Result.LastChild; if not (vsInitialized in Result.States) then InitNode(Result); if vsVisible in Result.States then Break; end else if Assigned(Result.PrevSibling) then begin if not (vsInitialized in Result.PrevSibling.States) then InitNode(Result.PrevSibling); if vsVisible in Result.PrevSibling.States then begin Result := Result.PrevSibling; Break; end; end else begin Marker := nil; repeat Result := Result.Parent; if Result <> FRoot then Marker := GetPreviousVisibleSibling(Result) else Result := nil; until Assigned(Marker) or (Result = nil); if Assigned(Marker) then Result := Marker; Break; end; until False; end else begin repeat // Is there a previous sibling node? if Assigned(Result.PrevSibling) then begin Result := Result.PrevSibling; // Initialize the new node and check its visibility. if not (vsInitialized in Result.States) then InitNode(Result); if vsVisible in Result.States then begin // If there are visible child nodes then use the last one. Marker := GetLastVisible(Result, True); if Assigned(Marker) then Result := Marker; Break; end; end else begin // No previous sibling there so the parent node is the nearest previous node. Result := Result.Parent; if Result = FRoot then Result := nil; Break; end; until False; end; if Assigned(Result) and not (vsInitialized in Result.States) then InitNode(Result); end; until not Assigned(Result) or (vsVisible in Result.States); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; // Returns the previous node in tree, with regard to Node, which is visible. // toChildrenAbove is optionally considered which is the default here. var Marker: PVirtualNode; begin Result := Node; if Assigned(Result) then begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); repeat // If the given node is not visible then look for a parent node which is visible and use its last visible // child or the parent node (if there is no visible child) as result. if not FullyVisible[Result] then begin Result := GetVisibleParent(Result); if Result = FRoot then Result := nil; Marker := GetLastVisibleNoInit(Result, True); if Assigned(Marker) then Result := Marker; end else begin if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then begin repeat // Is the current node expanded and has children? if (vsExpanded in Result.States) and Assigned(Result.LastChild) then begin Result := Result.LastChild; if vsVisible in Result.States then Break; end else if Assigned(Result.PrevSibling) then begin // No children anymore, so take the previous sibling. if vsVisible in Result.PrevSibling.States then begin Result := Result.PrevSibling; Break; end; end else begin // No children and no previous siblings, so walk up the tree and look wether // a parent has a previous visible sibling. If that is the case take it, // otherwise there is no previous visible node. Marker := nil; repeat Result := Result.Parent; if Result <> FRoot then Marker := GetPreviousVisibleSiblingNoInit(Result) else Result := nil; until Assigned(Marker) or (Result = nil); if Assigned(Marker) then Result := Marker; Break; end; until False; end else begin repeat // Is there a previous sibling node? if Assigned(Result.PrevSibling) then begin Result := Result.PrevSibling; if vsVisible in Result.States then begin // If there are visible child nodes then use the last one. Marker := GetLastVisibleNoInit(Result, True); if Assigned(Marker) then Result := Marker; Break; end; end else begin // No previous sibling there so the parent node is the nearest previous node. Result := Result.Parent; if Result = FRoot then Result := nil; Break; end; until False; end; end; until not Assigned(Result) or (vsVisible in Result.States); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousVisibleSibling(Node: PVirtualNode): PVirtualNode; // Returns the previous visible sibling before Node. Initialization is done implicitly. begin Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.'); Result := Node; repeat Result := GetPreviousSibling(Result); until not Assigned(Result) or (vsVisible in Result.States); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetPreviousVisibleSiblingNoInit(Node: PVirtualNode): PVirtualNode; // Returns the previous visible sibling before Node. begin Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.'); Result := Node; repeat Result := Result.PrevSibling; until not Assigned(Result) or (vsVisible in Result.States); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetSortedCutCopySet(Resolve: Boolean): TNodeArray; // Same as GetSortedSelection but with nodes marked as being part in the current cut/copy set (e.g. for clipboard). var Run: PVirtualNode; Counter: Cardinal; //--------------- local function -------------------------------------------- procedure IncludeThisNode(Node: PVirtualNode); // adds the given node to the result var Len: Cardinal; begin Len := Length(Result); if Counter = Len then begin if Len < 100 then Len := 100 else Len := Len + Len div 10; SetLength(Result, Len); end; Result[Counter] := Node; Inc(Counter); end; //--------------- end local function ---------------------------------------- begin Run := FRoot.FirstChild; Counter := 0; if Resolve then begin // Resolving is actually easy: just find the first cutted node in logical order // and then never go deeper in level than this node as long as there's a sibling node. // Restart the search for a cutted node (at any level) if there are no further siblings. while Assigned(Run) do begin if vsCutOrCopy in Run.States then begin IncludeThisNode(Run); if Assigned(Run.NextSibling) then Run := Run.NextSibling else begin // If there are no further siblings then go up one or more levels until a node is // found or all nodes have been processed. Although we consider here only initialized // nodes we don't need to make any special checks as only initialized nodes can also be selected. repeat Run := Run.Parent; until (Run = FRoot) or Assigned(Run.NextSibling); if Run = FRoot then Break else Run := Run.NextSibling; end; end else Run := GetNextNoInit(Run); end; end else while Assigned(Run) do begin if vsCutOrCopy in Run.States then IncludeThisNode(Run); Run := GetNextNoInit(Run); end; // set the resulting array to its real length SetLength(Result, Counter); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetSortedSelection(Resolve: Boolean): TNodeArray; // Returns a list of selected nodes sorted in logical order, that is, as they appear in the tree. // If Resolve is True then nodes which are children of other selected nodes are not put into the new array. // This feature is in particuar important when doing drag'n drop as in this case all selected node plus their children // need to be considered. A selected node which is child (grand child etc.) of another selected node is then // automatically included and doesn't need to be explicitely mentioned in the returned selection array. // // Note: The caller is responsible for freeing the array. Allocation is done here. Usually, though, freeing the array // doesn't need additional attention as it is automatically freed by Delphi when it gets out of scope. var Run: PVirtualNode; Counter: Cardinal; begin SetLength(Result, FSelectionCount); if FSelectionCount > 0 then begin Run := FRoot.FirstChild; Counter := 0; if Resolve then begin // Resolving is actually easy: just find the first selected node in logical order // and then never go deeper in level than this node as long as there's a sibling node. // Restart the search for a selected node (at any level) if there are no further siblings. while Assigned(Run) do begin if vsSelected in Run.States then begin Result[Counter] := Run; Inc(Counter); if Assigned(Run.NextSibling) then Run := Run.NextSibling else begin // If there are no further siblings then go up one or more levels until a node is // found or all nodes have been processed. Although we consider here only initialized // nodes we don't need to make any special checks as only initialized nodes can also be selected. repeat Run := Run.Parent; until (Run = FRoot) or Assigned(Run.NextSibling); if Run = FRoot then Break else Run := Run.NextSibling; end; end else Run := GetNextNoInit(Run); end; end else while Assigned(Run) do begin if vsSelected in Run.States then begin Result[Counter] := Run; Inc(Counter); end; Run := GetNextNoInit(Run); end; // Since we may have skipped some nodes the result array is likely to be smaller than the // selection array, hence shorten the result to true length. if Integer(Counter) < Length(Result) then SetLength(Result, Counter); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.GetTextInfo(Node: PVirtualNode; Column: TColumnIndex; const AFont: TFont; var R: TRect; out Text: String); // Generic base method for editors, hint windows etc. to get some info about a node. begin R := Rect(0, 0, 0, 0); Text := ''; AFont.Assign(Font); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetTreeRect: TRect; // Returns the true size of the tree in pixels. This size is at least ClientHeight x ClientWidth and depends on // the expand state, header size etc. // Note: if no columns are used then the width of the tree is determined by the largest node which is currently in the // client area. This might however not be the largest node in the entire tree. begin Result := Rect(0, 0, Max(FRangeX, ClientWidth), Max(FRangeY, ClientHeight)); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetVisibleParent(Node: PVirtualNode): PVirtualNode; // Returns the first (nearest) parent node of Node which is visible. // This method is one of the seldom cases where the hidden root node could be returned. begin Assert(Assigned(Node), 'Node must not be nil.'); Assert(Node <> FRoot, 'Node must not be the hidden root node.'); Result := Node.Parent; while (Result <> FRoot) and not FullyVisible[Result] do Result := Result.Parent; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.HasAsParent(Node, PotentialParent: PVirtualNode): Boolean; // Determines whether Node has got PotentialParent as one of its parents. var Run: PVirtualNode; begin Result := Assigned(Node) and Assigned(PotentialParent) and (Node <> PotentialParent); if Result then begin Run := Node; while (Run <> FRoot) and (Run <> PotentialParent) do Run := Run.Parent; Result := Run = PotentialParent; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.InsertNode(Node: PVirtualNode; Mode: TVTNodeAttachMode; UserData: Pointer = nil): PVirtualNode; // Adds a new node relative to Node. The final position is determined by Mode. // UserData can be used to set the first 4 bytes of the user data area to an initial value which can be used // in OnInitNode and will also cause to trigger the OnFreeNode event (if <> nil) even if the node is not yet // "officially" initialized. // InsertNode is a compatibility method and will implicitly validate the given node if the new node // is to be added as child node. This is however against the virtual paradigm and hence I dissuade from its usage. var NodeData: ^Pointer; begin if Mode <> amNoWhere then begin CancelEditNode; if Node = nil then Node := FRoot; // we need a new node... Result := MakeNewNode; // avoid erronous attach modes if Node = FRoot then begin case Mode of amInsertBefore: Mode := amAddChildFirst; amInsertAfter: Mode := amAddChildLast; end; end; // Validate given node in case the new node becomes its child. if (Mode in [amAddChildFirst, amAddChildLast]) and not (vsInitialized in Node.States) then InitNode(Node); InternalConnectNode(Result, Node, Self, Mode); // Check if there is initial user data and there is also enough user data space allocated. if Assigned(UserData) then if FNodeDataSize >= 4 then begin NodeData := Pointer(PByte(@Result.Data) + FTotalInternalDataSize); NodeData^ := UserData; Include(Result.States, vsInitialUserData); end else ShowError(SCannotSetUserData, hcTFCannotSetUserData); if FUpdateCount = 0 then begin // If auto sort is enabled then sort the node or its parent (depending on the insert mode). if (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then case Mode of amInsertBefore, amInsertAfter: // Here no initialization is necessary because *if* a node has already got children then it // must also be initialized. // Note: Node can never be FRoot at this point. Sort(Node.Parent, FHeader.FSortColumn, FHeader.FSortDirection, True); amAddChildFirst, amAddChildLast: Sort(Node, FHeader.FSortColumn, FHeader.FSortDirection, True); end; UpdateScrollbars(True); if Mode = amInsertBefore then InvalidateToBottom(Result) else InvalidateToBottom(Node); end; StructureChange(Result, crNodeAdded); end else Result := nil; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InvalidateChildren(Node: PVirtualNode; Recursive: Boolean); // Invalidates Node and its immediate children. // If Recursive is True then all grandchildren are invalidated as well. // The node itself is initialized if necessary and its child nodes are created (and initialized too if // Recursive is True). var Run: PVirtualNode; begin if Assigned(Node) then begin if not (vsInitialized in Node.States) then InitNode(Node); InvalidateNode(Node); if (vsHasChildren in Node.States) and (Node.ChildCount = 0) then InitChildren(Node); Run := Node.FirstChild; end else Run := FRoot.FirstChild; while Assigned(Run) do begin InvalidateNode(Run); if Recursive then InvalidateChildren(Run, True); Run := Run.NextSibling; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InvalidateColumn(Column: TColumnIndex); // Invalidates the client area part of a column. var R: TRect; begin if (FUpdateCount = 0) and HandleAllocated and FHeader.FColumns.IsValidColumn(Column) then begin R := ClientRect; //lclheader if hoVisible in FHeader.FOptions then OffsetRect(R, 0, FHeader.Height); FHeader.Columns.GetColumnBounds(Column, R.Left, R.Right); InvalidateRect(Handle, @R, False); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.InvalidateNode(Node: PVirtualNode): TRect; // Initiates repaint of the given node and returns the just invalidated rectangle. begin if (FUpdateCount = 0) and HandleAllocated then begin Result := GetDisplayRect(Node, NoColumn, False); InvalidateRect(Handle, @Result, False); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InvalidateToBottom(Node: PVirtualNode); // Initiates repaint of client area starting at given node. If this node is not visible or not yet initialized // then nothing happens. var R: TRect; begin if FUpdateCount = 0 then begin if (Node = nil) or (Node = FRoot) then Invalidate else if (vsInitialized in Node.States) and (vsVisible in Node.States) then begin R := GetDisplayRect(Node, -1, False); if R.Top < ClientHeight then begin if (toChildrenAbove in FOptions.FPaintOptions) and (vsExpanded in Node.States) then Dec(R.Top, Node.TotalHeight + NodeHeight[Node]); R.Bottom := ClientHeight; //lclheader if hoVisible in FHeader.FOptions then Inc(R.Bottom, FHeader.Height); InvalidateRect(Handle, @R, False); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.InvertSelection(VisibleOnly: Boolean); // Inverts the current selection (so nodes which are selected become unselected and vice versa). // If VisibleOnly is True then only visible nodes are considered. var Run: PVirtualNode; NewSize: Integer; NextFunction: TGetNextNodeProc; TriggerChange: Boolean; begin if not FSelectionLocked and (toMultiSelect in FOptions.FSelectionOptions) then begin Run := FRoot.FirstChild; ClearTempCache; if VisibleOnly then NextFunction := GetNextVisibleNoInit else NextFunction := GetNextNoInit; while Assigned(Run) do begin if vsSelected in Run.States then InternalRemoveFromSelection(Run) else InternalCacheNode(Run); Run := NextFunction(Run); end; // do some housekeeping // Need to trigger the OnChange event from here if nodes were only deleted but not added. TriggerChange := False; NewSize := PackArray(FSelection, FSelectionCount); if NewSize > -1 then begin FSelectionCount := NewSize; SetLength(FSelection, FSelectionCount); TriggerChange := True; end; if FTempNodeCount > 0 then begin AddToSelection(FTempNodeCache, FTempNodeCount); ClearTempCache; TriggerChange := False; end; Invalidate; if TriggerChange then Change(nil); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.IsEditing: Boolean; begin Result := tsEditing in FStates; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.IsMouseSelecting: Boolean; begin Result := (tsDrawSelPending in FStates) or (tsDrawSelecting in FStates); end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.IterateSubtree(Node: PVirtualNode; Callback: TVTGetNodeProc; Data: Pointer; Filter: TVirtualNodeStates = []; DoInit: Boolean = False; ChildNodesOnly: Boolean = False): PVirtualNode; // Iterates through the all children and grandchildren etc. of Node (or the entire tree if Node = nil) // and calls for each node the provided callback method (which must not be empty). // Filter determines which nodes to consider (an empty set denotes all nodes). // If DoInit is True then nodes which aren't initialized yet will be initialized. // Note: During execution of the callback the application can set Abort to True. In this case the iteration is stopped // and the last accessed node (the one on which the callback set Abort to True) is returned to the caller. // Otherwise (no abort) nil is returned. var Stop: PVirtualNode; Abort: Boolean; GetNextNode: TGetNextNodeProc; WasIterating: Boolean; begin Assert(Node <> FRoot, 'Node must not be the hidden root node.'); WasIterating := tsIterating in FStates; DoStateChange([tsIterating]); try // prepare function to be used when advancing if DoInit then GetNextNode := GetNext else GetNextNode := GetNextNoInit; Abort := False; if Node = nil then Stop := nil else begin if not (vsInitialized in Node.States) and DoInit then InitNode(Node); // The stopper does not need to be initialized since it is not taken into the enumeration. Stop := Node.NextSibling; if Stop = nil then begin Stop := Node; repeat Stop := Stop.Parent; until (Stop = FRoot) or Assigned(Stop.NextSibling); if Stop = FRoot then Stop := nil else Stop := Stop.NextSibling; end; end; // Use first node if we start with the root. if Node = nil then Node := GetFirstNoInit; if Assigned(Node) then begin if not (vsInitialized in Node.States) and DoInit then InitNode(Node); // Skip given node if only the child nodes are requested. if ChildNodesOnly then begin if Node.ChildCount = 0 then Node := nil else Node := GetNextNode(Node); end; if Filter = [] then begin // unfiltered loop while Assigned(Node) and (Node <> Stop) do begin Callback(Self, Node, Data, Abort); if Abort then Break; Node := GetNextNode(Node); end; end else begin // filtered loop while Assigned(Node) and (Node <> Stop) do begin if Node.States * Filter = Filter then Callback(Self, Node, Data, Abort); if Abort then Break; Node := GetNextNode(Node) end; end; end; if Abort then Result := Node else Result := nil; finally if not WasIterating then DoStateChange([], [tsIterating]); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.LoadFromFile(const FileName: TFileName); var FileStream: TFileStream; begin FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try LoadFromStream(FileStream); finally FileStream.Free; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.LoadFromStream(Stream: TStream); // Clears the current content of the tree and loads a new structure from the given stream. var ThisID: TMagicID; Version, Count: Cardinal; Node: PVirtualNode; begin if not (toReadOnly in FOptions.FMiscOptions) then begin Clear; // Check first whether this is a stream we can read. if Stream.Read(ThisID, SizeOf(TMagicID)) < SizeOf(TMagicID) then ShowError(SStreamTooSmall, hcTFStreamTooSmall); if (ThisID[0] = MagicID[0]) and (ThisID[1] = MagicID[1]) and (ThisID[2] = MagicID[2]) and (ThisID[5] = MagicID[5]) then begin Version := Word(ThisID[3]); if Version <= VTTreeStreamVersion then begin BeginUpdate; try // LCL port started with tree stream version 2 so no need to do the check here Stream.ReadBuffer(Count, SizeOf(Count)); while (Stream.Position < Stream.Size) and (Count > 0) do begin Dec(Count); Node := MakeNewNode; InternalConnectNode(Node, FRoot, Self, amAddChildLast); InternalAddFromStream(Stream, Version, Node); end; DoNodeCopied(nil); finally EndUpdate; end; end else ShowError(SWrongStreamVersion, hcTFWrongStreamVersion); end else ShowError(SWrongStreamFormat, hcTFWrongStreamFormat); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.MeasureItemHeight(const Canvas: TCanvas; Node: PVirtualNode); // If the height of the given node has not yet been measured then do it now. var NewNodeHeight: Integer; begin if not (vsHeightMeasured in Node.States) then begin Include(Node.States, vsHeightMeasured); NewNodeHeight := Node.NodeHeight; DoMeasureItem(Canvas, Node, NewNodeHeight); if NewNodeHeight <> Node.NodeHeight then SetNodeHeight(Node, NewNodeHeight); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.MoveTo(Node: PVirtualNode; Tree: TBaseVirtualTree; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean); // A simplified method to allow to move nodes to the root of another tree. begin MoveTo(Node, Tree.FRoot, Mode, ChildrenOnly); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.MoveTo(Source, Target: PVirtualNode; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean); // Moves the given node (and all its children) to Target. Source must belong to the tree instance which calls this // MoveTo method. Mode determines how to connect Source to Target. // This method might involve a change of the tree if Target belongs to a different tree than Source. var TargetTree: TBaseVirtualTree; Allowed: Boolean; NewNode: PVirtualNode; Stream: TMemoryStream; begin Assert(TreeFromNode(Source) = Self, 'The source tree must contain the source node.'); // When moving nodes then source and target must not be the same node unless only the source's children are // moved and they are inserted before or after the node itself. Allowed := (Source <> Target) or ((Mode in [amInsertBefore, amInsertAfter]) and ChildrenOnly); if Allowed and (Mode <> amNoWhere) and Assigned(Source) and (Source <> FRoot) and not (toReadOnly in FOptions.FMiscOptions) then begin // Assume that an empty destination means the root in this (the source) tree. if Target = nil then begin TargetTree := Self; Target := FRoot; Mode := amAddChildFirst; end else TargetTree := TreeFromNode(Target); if Target = TargetTree.FRoot then begin case Mode of amInsertBefore: Mode := amAddChildFirst; amInsertAfter: Mode := amAddChildLast; end; end; // Make sure the target node is initialized. if not (vsInitialized in Target.States) then InitNode(Target) else if (vsHasChildren in Target.States) and (Target.ChildCount = 0) then InitChildren(Target); if TargetTree = Self then begin // Simple case: move node(s) within the same tree. if Target = FRoot then Allowed := DoNodeMoving(Source, nil) else Allowed := DoNodeMoving(Source, Target); if Allowed then begin // Check first that Source is not added as new child to a target node which // is already a child of Source. // Consider the case Source and Target are the same node, but only child nodes are moved. if (Source <> Target) and HasAsParent(Target, Source) then ShowError(SWrongMoveError, hcTFWrongMoveError); if not ChildrenOnly then begin // Disconnect from old location. InternalDisconnectNode(Source, True); // Connect to new location. InternalConnectNode(Source, Target, Self, Mode); DoNodeMoved(Source); end else begin // Only child nodes should be moved. Insertion order depends on move mode. if Mode = amAddChildFirst then begin Source := Source.LastChild; while Assigned(Source) do begin NewNode := Source.PrevSibling; // Disconnect from old location. InternalDisconnectNode(Source, True, False); // Connect to new location. InternalConnectNode(Source, Target, Self, Mode); DoNodeMoved(Source); Source := NewNode; end; end else begin Source := Source.FirstChild; while Assigned(Source) do begin NewNode := Source.NextSibling; // Disconnect from old location. InternalDisconnectNode(Source, True, False); // Connect to new location. InternalConnectNode(Source, Target, Self, Mode); DoNodeMoved(Source); Source := NewNode; end; end; end; end; end else begin // Difficult case: move node(s) to another tree. // In opposition to node copying we ask only once if moving is allowed because // we cannot take back a move once done. if Target = TargetTree.FRoot then Allowed := DoNodeMoving(Source, nil) else Allowed := DoNodeMoving(Source, Target); if Allowed then begin Stream := TMemoryStream.Create; try // Write all nodes into a temporary stream depending on the ChildrenOnly flag. if not ChildrenOnly then WriteNode(Stream, Source) else begin Source := Source.FirstChild; while Assigned(Source) do begin WriteNode(Stream, Source); Source := Source.NextSibling; end; end; // Now load the serialized nodes into the target node (tree). TargetTree.BeginUpdate; try Stream.Position := 0; while Stream.Position < Stream.Size do begin NewNode := TargetTree.MakeNewNode; InternalConnectNode(NewNode, Target, TargetTree, Mode); TargetTree.InternalAddFromStream(Stream, VTTreeStreamVersion, NewNode); DoNodeMoved(NewNode); end; finally TargetTree.EndUpdate; end; finally Stream.Free; end; // finally delete original nodes BeginUpdate; try if ChildrenOnly then DeleteChildren(Source) else DeleteNode(Source); finally EndUpdate; end; end; end; InvalidateCache; if (FUpdateCount = 0) and Allowed then begin ValidateCache; UpdateScrollBars(True); Invalidate; if TargetTree <> Self then TargetTree.Invalidate; end; StructureChange(Source, crNodeMoved); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.PaintTree(TargetCanvas: TCanvas; const Window: TRect; Target: TPoint; PaintOptions: TVTInternalPaintOptions; PixelFormat: TPixelFormat); // This is the core paint routine of the tree. It is responsible for maintaining the paint cycles per node as well // as coordinating drawing of the various parts of the tree image. // TargetCanvas is the canvas to which to draw the tree image. This is usually the tree window itself but could well // be a bitmap or printer canvas. // Window determines which part of the entire tree image to draw. The full size of the virtual image is determined // by GetTreeRect. // Target is the position in TargetCanvas where to draw the tree part specified by Window. // PaintOptions determines what of the tree to draw. For different tasks usually different parts need to be drawn, with // a full image in the window, selected only nodes for a drag image etc. const ImageKind: array[Boolean] of TVTImageKind = (ikNormal, ikSelected); var DrawSelectionRect, UseBackground, ShowImages, ShowStateImages, ShowCheckImages, UseColumns, IsMainColumn: Boolean; {$ifdef ManualClipNeeded} YCorrect, {$endif} VAlign, IndentSize, ButtonX, ButtonY: Integer; LineImage: TLineImage; PaintInfo: TVTPaintInfo; // all necessary information about a node to pass to the paint routines R, // the area of an entire node in its local coordinate TargetRect, // the area of a node (part) in the target canvas SelectionRect: TRect; // ordered rectangle used for drawing the selection focus rect NextColumn: TColumnIndex; BaseOffset: Integer; // top position of the top node to draw given in absolute tree coordinates NodeBitmap: TBitmap; // small buffer to draw flicker free MaximumRight, // maximum horizontal target position MaximumBottom: Integer; // maximum vertical target position SelectLevel: Integer; // > 0 if current node is selected or child/grandchild etc. of a selected node FirstColumn: TColumnIndex; // index of first column which is at least partially visible in the given window begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaint],'PaintTree');{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaint, lcHeaderOffset],'Window',Window);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaint, lcHeaderOffset],'Target',Target);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'ClientRect',ClientRect);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'TreeRect',GetTreeRect);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'OffsetX: %d OffsetY: %d',[OffsetX,OffsetY]);{$endif} //lcl changes to 24bit color depth when screen depth is 32 bit //todo: remove when this limitation is removed {$ifdef Windows} if (PixelFormat = pfDevice) and (ScreenInfo.ColorDepth = 32) then PixelFormat := pf32bit; {$endif} if not (tsPainting in FStates) then begin DoStateChange([tsPainting]); try DoBeforePaint(TargetCanvas); // Create small bitmaps and initialize default values. // The bitmaps are used to paint one node at a time and to draw the result to the target (e.g. screen) in one step, // to prevent flickering. NodeBitmap := TBitmap.Create; // For alpha blending we need the 32 bit pixel format. For other targets there might be a need for a certain // pixel format (e.g. printing). if MMXAvailable and ((FDrawSelectionMode = smBlendedRectangle) or (tsUseThemes in FStates) or (toUseBlendedSelection in FOptions.PaintOptions)) then NodeBitmap.PixelFormat := pf32Bit else NodeBitmap.PixelFormat := PixelFormat; // Prepare paint info structure and lock the back bitmap canvas to avoid that it gets freed on the way. FillChar(PaintInfo, SizeOf(PaintInfo), 0); PaintInfo.Canvas := NodeBitmap.Canvas; NodeBitmap.Canvas.Lock; try {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FNewSelRect', FNewSelRect);{$endif} // Prepare the current selection rectangle once. The corner points are absolute tree coordinates. SelectionRect := OrderRect(FNewSelRect); {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails, lcSelection],'SelectionRect', SelectionRect);{$endif} DrawSelectionRect := IsMouseSelecting and not IsRectEmpty(SelectionRect); {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'DrawSelectionRect',DrawSelectionRect);{$endif} // R represents an entire node (all columns), but is a bit unprecise when it comes to // trees without any column defined, because FRangeX only represents the maximum width of all // nodes in the client area (not all defined nodes). There might be, however, wider nodes somewhere. Without full // validation I cannot better determine the width, though. By using at least the control's width it is ensured // that the tree is fully displayed on screen. R := Rect(0, 0, Max(FRangeX, ClientWidth), 0); NodeBitmap.Width := Window.Right - Window.Left; // For quick checks some intermediate variables are used. UseBackground := (toShowBackground in FOptions.FPaintOptions) and (FBackground.Graphic is TBitmap) and (poBackground in PaintOptions); ShowImages := Assigned(FImages); ShowStateImages := Assigned(FStateImages); ShowCheckImages := Assigned(FCheckImages) and (toCheckSupport in FOptions.FMiscOptions); {$ifdef DEBUG_VTV}Logger.Send([lcCheck],'ShowCheckImages',ShowCheckImages);{$endif} UseColumns := FHeader.UseColumns; // Adjust paint options to tree settings. Hide selection if told so or the tree is unfocused. if (toAlwaysHideSelection in FOptions.FPaintOptions) or (not Focused and (toHideSelection in FOptions.FPaintOptions)) then Exclude(PaintOptions, poDrawSelection); if toHideFocusRect in FOptions.FPaintOptions then Exclude(PaintOptions, poDrawFocusRect); // Determine node to start drawing with. BaseOffset := 0; PaintInfo.Node := InternalGetNodeAt(0, Window.Top, False, BaseOffset); if PaintInfo.Node = nil then BaseOffset := Window.Top; {$ifdef DEBUG_VTV}Logger.Send([lcPaint, lcHeaderOffset],'BaseOffset',BaseOffset);{$endif} // Transform selection rectangle into node bitmap coordinates. if DrawSelectionRect then OffsetRect(SelectionRect, 0, -BaseOffset); {$ifdef DEBUG_VTV}Logger.Send([lcSelection], 'SelectionRect fixed by BaseOffset', SelectionRect);{$endif} // The target rectangle holds the coordinates of the exact area to blit in target canvas coordinates. // It is usually smaller than an entire node and wanders while the paint loop advances. MaximumRight := Target.X + (Window.Right - Window.Left); MaximumBottom := Target.Y + (Window.Bottom - Window.Top); {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader, lcHeaderOffset],'MaximumRight: %d MaximumBottom: %d',[MaximumRight,MaximumBottom]);{$endif} TargetRect := Rect(Target.X, Target.Y - (Window.Top - BaseOffset), MaximumRight, 0); TargetRect.Bottom := TargetRect.Top; // This marker gets the index of the first column which is visible in the given window. // This is needed for column based background colors. FirstColumn := InvalidColumn; if Assigned(PaintInfo.Node) then begin ButtonX := Round((Integer(FIndent) - FPlusBM.Width) / 2); // ----- main node paint loop while Assigned(PaintInfo.Node) do begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'PaintNode');{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeIndex',PaintInfo.Node^.Index);{$endif} {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'BaseOffset',BaseOffset);{$endif} {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif} // Determine LineImage, SelectionLevel and IndentSize SelectLevel := DetermineLineImageAndSelectLevel(PaintInfo.Node, LineImage); IndentSize := Length(LineImage); if not (toFixedIndent in FOptions.FPaintOptions) then ButtonX := (IndentSize - 1) * FIndent + Round((FIndent - FPlusBM.Width) / 2); // Initialize node if not already done. if not (vsInitialized in PaintInfo.Node.States) then InitNode(PaintInfo.Node); if (vsSelected in PaintInfo.Node.States) and not (toChildrenAbove in FOptions.FPaintOptions) then Inc(SelectLevel); // Ensure the node's height is determined. MeasureItemHeight(PaintInfo.Canvas, PaintInfo.Node); // Adjust the brush origin for dotted lines depending on the current source position. // It is applied some lines later, as the canvas might get reallocated, when changing the node bitmap. PaintInfo.BrushOrigin := Point(Window.Left and 1, BaseOffset and 1); Inc(BaseOffset, PaintInfo.Node.NodeHeight); TargetRect.Bottom := TargetRect.Top + PaintInfo.Node.NodeHeight; {$ifdef DEBUG_VTV}Logger.Send([lcHeaderOffset], 'TargetRect for Node ' + IntToStr(PaintInfo.Node.Index), TargetRect);{$endif} // If poSelectedOnly is active then do the following stuff only for selected nodes or nodes // which are children of selected nodes. if (SelectLevel > 0) or not (poSelectedOnly in PaintOptions) then begin // Adjust height of temporary node bitmap. with NodeBitmap do begin if Height <> PaintInfo.Node.NodeHeight then begin {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Setting the Node Height');{$endif} Height := PaintInfo.Node.NodeHeight; // Make sure the buffer bitmap and target bitmap use the same transformation mode. {$ifndef Gtk} SetMapMode(Canvas.Handle, GetMapMode(TargetCanvas.Handle)); {$endif} SetWindowOrgEx(Canvas.Handle, Window.Left, 0, nil); R.Bottom := PaintInfo.Node.NodeHeight; end; // Set the origin of the canvas' brush. This depends on the node heights. //todo: see if is necessary. According to docs is only necessary when HALFTONE is set {$ifndef INCOMPLETE_WINAPI} with PaintInfo do SetBrushOrgEx(Canvas.Handle, BrushOrigin.X, BrushOrigin.Y, nil); {$endif} end; CalculateVerticalAlignments(ShowImages, ShowStateImages, PaintInfo.Node, VAlign, ButtonY); // Let application decide whether the node should normally be drawn or by the application itself. if not DoBeforeItemPaint(PaintInfo.Canvas, PaintInfo.Node, R) then begin // Init paint options for the background painting. PaintInfo.PaintOptions := PaintOptions; {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif} // The node background can contain a single color, a bitmap or can be drawn by the application. ClearNodeBackground(PaintInfo, UseBackground, True, Rect(Window.Left, TargetRect.Top, Window.Right, TargetRect.Bottom)); {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPaintBitmap],'After Clear BackGround',NodeBitmap);{$endif} {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif} // Prepare column, position and node clipping rectangle. PaintInfo.CellRect := R; {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'PaintInfo.CellRect',PaintInfo.CellRect);{$endif} if UseColumns then InitializeFirstColumnValues(PaintInfo); // Now go through all visible columns (there's still one run if columns aren't used). with FHeader.FColumns do begin while ((PaintInfo.Column > InvalidColumn) or not UseColumns) and (PaintInfo.CellRect.Left < Window.Right) do begin if UseColumns then begin PaintInfo.Column := FPositionToIndex[PaintInfo.Position]; if FirstColumn = InvalidColumn then FirstColumn := PaintInfo.Column; PaintInfo.BidiMode := Items[PaintInfo.Column].FBiDiMode; PaintInfo.Alignment := Items[PaintInfo.Column].FAlignment; end else begin PaintInfo.Column := NoColumn; PaintInfo.BidiMode := BidiMode; PaintInfo.Alignment := FAlignment; end; {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails], 'Column Paint - PaintInfo.Position: %d PaintInfo.Column: %d',[PaintInfo.Position,PaintInfo.Column]);{$endif} PaintInfo.PaintOptions := PaintOptions; with PaintInfo do begin if (tsEditing in FStates) and (Node = FFocusedNode) and ((Column = FEditColumn) or not UseColumns) then Exclude(PaintOptions, poDrawSelection); if not UseColumns or ((vsSelected in Node.States) and (toFullRowSelect in FOptions.FSelectionOptions) and (poDrawSelection in PaintOptions)) or (coParentColor in Items[PaintInfo.Column].Options) then Exclude(PaintOptions, poColumnColor); end; IsMainColumn := PaintInfo.Column = FHeader.MainColumn; // Consider bidi mode here. In RTL context means left alignment actually right alignment and vice versa. if PaintInfo.BidiMode <> bdLeftToRight then ChangeBiDiModeAlignment(PaintInfo.Alignment); // Paint the current cell if it is marked as being visible or columns aren't used and // if this cell belongs to the main column if only the main column should be drawn. if (not UseColumns or (coVisible in Items[PaintInfo.Column].FOptions)) and (not (poMainOnly in PaintOptions) or IsMainColumn) then begin AdjustPaintCellRect(PaintInfo, NextColumn); // Paint the cell only if it is in the current window. if PaintInfo.CellRect.Right > Window.Left then begin with PaintInfo do begin // Fill in remaining values in the paint info structure. NodeWidth := DoGetNodeWidth(Node, Column, Canvas); // Not the entire cell is covered by text. Hence we need a running rectangle to follow up. ContentRect := CellRect; // Set up the distance from column border (margin). if BidiMode <> bdLeftToRight then Dec(ContentRect.Right, FMargin) else Inc(ContentRect.Left, FMargin); if ShowCheckImages and IsMainColumn then begin ImageInfo[iiCheck].Index := GetCheckImage(Node); if ImageInfo[iiCheck].Index > -1 then begin AdjustImageBorder(FCheckImages.Height, FCheckImages.Height, BidiMode, VAlign, ContentRect, ImageInfo[iiCheck]); ImageInfo[iiCheck].Ghosted := False; end; end else ImageInfo[iiCheck].Index := -1; if ShowStateImages then begin GetImageIndex(PaintInfo, ikState, iiState, FStateImages); if ImageInfo[iiState].Index > -1 then AdjustImageBorder(FStateImages.Width, FStateImages.Height, BidiMode, VAlign, ContentRect, ImageInfo[iiState]); end else ImageInfo[iiState].Index := -1; if ShowImages then begin GetImageIndex(PaintInfo, ImageKind[vsSelected in Node.States], iiNormal, FImages); if ImageInfo[iiNormal].Index > -1 then AdjustImageBorder(FImages.Width, FImages.Height, BidiMode, VAlign, ContentRect, ImageInfo[iiNormal]); end else ImageInfo[iiNormal].Index := -1; // Take the space for the tree lines into account. if IsMainColumn then AdjustCoordinatesByIndent(PaintInfo, IfThen(toFixedIndent in FOptions.FPaintOptions, 1, IndentSize)); if UseColumns then LimitPaintingToArea(Canvas, CellRect); // Paint the horizontal grid line. if (poGridLines in PaintOptions) and (toShowHorzGridLines in FOptions.FPaintOptions) then begin Canvas.Font.Color := FColors.GridLineColor; if IsMainColumn and (FLineMode = lmBands) then begin if BidiMode = bdLeftToRight then begin DrawDottedHLine(PaintInfo, CellRect.Left + IfThen(toFixedIndent in FOptions.FPaintOptions, 1, IndentSize) * Integer(FIndent), CellRect.Right - 1, CellRect.Bottom - 1); end else begin DrawDottedHLine(PaintInfo, CellRect.Left, CellRect.Right - IfThen(toFixedIndent in FOptions.FPaintOptions, 1, IndentSize) * Integer(FIndent) - 1, CellRect.Bottom - 1); end; end else DrawDottedHLine(PaintInfo, CellRect.Left, CellRect.Right, CellRect.Bottom - 1); Dec(CellRect.Bottom); Dec(ContentRect.Bottom); end; if UseColumns then begin // Paint vertical grid line. // Don't draw if this is the last column and the header is in autosize mode. if (poGridLines in PaintOptions) and (toShowVertGridLines in FOptions.FPaintOptions) and (not (hoAutoResize in FHeader.FOptions) or (Position < TColumnPosition(Count - 1))) then begin if (BidiMode = bdLeftToRight) or not ColumnIsEmpty(Node, Column) then begin Canvas.Font.Color := FColors.GridLineColor; DrawDottedVLine(PaintInfo, CellRect.Top, CellRect.Bottom, CellRect.Right - 1); end; Dec(CellRect.Right); Dec(ContentRect.Right); end; end; // Prepare background and focus rect for the current cell. PrepareCell(PaintInfo, Window.Left, NodeBitmap.Width); {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif} // Some parts are only drawn for the main column. if IsMainColumn then begin if toShowTreeLines in FOptions.FPaintOptions then PaintTreeLines(PaintInfo, VAlign, IfThen(toFixedIndent in FOptions.FPaintOptions, 1, IndentSize), LineImage); // Show node button if allowed, if there child nodes and at least one of the child // nodes is visible or auto button hiding is disabled. if (toShowButtons in FOptions.FPaintOptions) and (vsHasChildren in Node.States) and not ((vsAllChildrenHidden in Node.States) and (toAutoHideButtons in TreeOptions.FAutoOptions)) then PaintNodeButton(Canvas, Node, Column, CellRect, ButtonX, ButtonY, BidiMode); if ImageInfo[iiCheck].Index > -1 then PaintCheckImage(PaintInfo); end; {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif} if ImageInfo[iiState].Index > -1 then PaintImage(PaintInfo, iiState, False); if ImageInfo[iiNormal].Index > -1 then PaintImage(PaintInfo, iiNormal, True); {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif} // Now let descendants or applications draw whatever they want, // but don't draw the node if it is currently being edited. if not ((tsEditing in FStates) and (Node = FFocusedNode) and ((Column = FEditColumn) or not UseColumns)) then DoPaintNode(PaintInfo); {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif} DoAfterCellPaint(Canvas, Node, Column, CellRect); end; end; // leave after first run if columns aren't used if not UseColumns then Break; end else NextColumn := GetNextVisibleColumn(PaintInfo.Column); SelectClipRgn(PaintInfo.Canvas.Handle, 0); // Stop column loop if there are no further columns in the given window. if (PaintInfo.CellRect.Left >= Window.Right) or (NextColumn = InvalidColumn) then Break; // Move on to next column which might not be the one immediately following the current one // because of auto span feature. PaintInfo.Position := Items[NextColumn].Position; // Move clip rectangle and continue. if coVisible in Items[NextColumn].FOptions then with PaintInfo do begin Items[NextColumn].GetAbsoluteBounds(CellRect.Left, CellRect.Right); CellRect.Bottom := Node.NodeHeight; ContentRect.Bottom := Node.NodeHeight; end; end; end; // This node is finished, notify descendants/application. with PaintInfo do begin DoAfterItemPaint(Canvas, Node, R); // Final touch for this node: mark it if it is the current drop target node. if (Node = FDropTargetNode) and (toShowDropmark in FOptions.FPaintOptions) and (poDrawDropMark in PaintOptions) then DoPaintDropMark(Canvas, Node, R); end; end; with PaintInfo.Canvas do begin if DrawSelectionRect then begin PaintSelectionRectangle(PaintInfo.Canvas, Window.Left, SelectionRect, Rect(0, 0, NodeBitmap.Width, NodeBitmap.Height)); end; {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPaintBitmap],'NodeBitmap ' + IntToStr(PaintInfo.Node^.Index), NodeBitmap);{$endif} {$ifdef DEBUG_VTV}Logger.SendIf([lcPaintDetails, lcHeaderOffset],'TargetRect.Top < Target.Y '+ Logger.RectToStr(TargetRect) +' '+Logger.PointToStr(Target),TargetRect.Top < Target.Y);{$endif} {$ifdef Gtk} //lclheader // This is a brute force fix AKA hack to prevent the header being cleared // when the tree is scrolled (YOffset < 0) and the mouse is over the header // Other widgetsets are not affected because excludecliprect works different (better?) // this must be removed when/if the paint coordinate is modified to be header aware YCorrect := 0; if hoVisible in FHeader.Options then begin if TargetRect.Top < FHeader.Height then YCorrect := FHeader.Height - TargetRect.Top; end; {$ifdef DEBUG_VTV}Logger.SendIf([lcPaintDetails],'YCorrect ' + IntToStr(YCorrect), YCorrect > 0);{$endif} {$endif} // Put the constructed node image onto the target canvas. with TargetRect, NodeBitmap do BitBlt(TargetCanvas.Handle, Left, Top {$ifdef ManualClipNeeded} + YCorrect{$endif}, Width, Height, Canvas.Handle, Window.Left, {$ifdef ManualClipNeeded}YCorrect{$else}0{$endif}, SRCCOPY); end; end; Inc(TargetRect.Top, PaintInfo.Node.NodeHeight); {$ifdef DEBUG_VTV}Logger.SendIf([lcPaintHeader,lcDrag],'Last Node to be painted: '+ IntToStr(PaintInfo.Node^.Index) +' (TargetRect.Top >= MaximumBottom)',TargetRect.Top >= MaximumBottom);{$endif} if TargetRect.Top >= MaximumBottom then begin {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'PaintNode');{$endif} Break; end; // Keep selection rectangle coordinates in sync. if DrawSelectionRect then OffsetRect(SelectionRect, 0, -PaintInfo.Node.NodeHeight); // Advance to next visible node. PaintInfo.Node := GetNextVisible(PaintInfo.Node, True); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'PaintNode');{$endif} end; end; // Erase rest of window not covered by a node. if TargetRect.Top < MaximumBottom then begin {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'UseBackground',UseBackground);{$endif} {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'UseColumns',UseColumns);{$endif} // Keep the horizontal target position to determine the selection rectangle offset later (if necessary). BaseOffset := Target.X; Target := TargetRect.TopLeft; R := Rect(TargetRect.Left, 0, TargetRect.Left, MaximumBottom - Target.Y); TargetRect := Rect(0, 0, MaximumRight - Target.X, MaximumBottom - Target.Y); {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeBitmap.Handle',NodeBitmap.Handle);{$endif} NodeBitmap.PixelFormat := pf32Bit; NodeBitmap.Width := TargetRect.Right - TargetRect.Left; NodeBitmap.Height := TargetRect.Bottom - TargetRect.Top; // Make sure the buffer bitmap and target bitmap use the same transformation mode. {$ifndef Gtk} SetMapMode(NodeBitmap.Canvas.Handle, GetMapMode(TargetCanvas.Handle)); {$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeBitmap.Handle after changing height to background',NodeBitmap.Handle);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'TargetRect',TargetRect);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeBitmap Width: %d Height: %d',[NodeBitmap.Width,NodeBitmap.Height]);{$endif} // Call back application/descendants whether they want to erase this area. SetWindowOrgEx(NodeBitmap.Canvas.Handle, Target.X, 0, nil); if not DoPaintBackground(NodeBitmap.Canvas, TargetRect) then begin if UseBackground then begin SetWindowOrgEx(NodeBitmap.Canvas.Handle, 0, 0, nil); if toStaticBackground in TreeOptions.PaintOptions then StaticBackground(FBackground.Bitmap, NodeBitmap.Canvas, Target, TargetRect) else TileBackground(FBackground.Bitmap, NodeBitmap.Canvas, Target, TargetRect); end else begin // Consider here also colors of the columns. if UseColumns then begin with FHeader.FColumns do begin // If there is no content in the tree then the first column has not yet been determined. if FirstColumn = InvalidColumn then begin FirstColumn := GetFirstVisibleColumn; repeat if FirstColumn <> InvalidColumn then begin R.Left := Items[FirstColumn].Left; R.Right := R.Left + Items[FirstColumn].FWidth; if R.Right > TargetRect.Left then Break; FirstColumn := GetNextVisibleColumn(FirstColumn); end; until FirstColumn = InvalidColumn; end else begin R.Left := Items[FirstColumn].Left; R.Right := R.Left + Items[FirstColumn].FWidth; end; NodeBitmap.Canvas.Font.Color := FColors.GridLineColor; while (FirstColumn <> InvalidColumn) and (R.Left < TargetRect.Right + Target.X) do begin if (poGridLines in PaintOptions) and (toFullVertGridLines in FOptions.FPaintOptions) and (toShowVertGridLines in FOptions.FPaintOptions) and (not (hoAutoResize in FHeader.FOptions) or (Cardinal(FirstColumn) < TColumnPosition(Count - 1))) then begin DrawDottedVLine(PaintInfo, R.Top, R.Bottom, R.Right - 1); Dec(R.Right); end; if not (coParentColor in Items[FirstColumn].FOptions) then NodeBitmap.Canvas.Brush.Color := Items[FirstColumn].FColor else NodeBitmap.Canvas.Brush.Color := Brush.Color; NodeBitmap.Canvas.FillRect(R); FirstColumn := GetNextVisibleColumn(FirstColumn); if FirstColumn <> InvalidColumn then begin R.Left := Items[FirstColumn].Left; R.Right := R.Left + Items[FirstColumn].FWidth; end; end; // Erase also the part of the tree not covert by a column. if R.Right < TargetRect.Right + Target.X then begin R.Left := R.Right; R.Right := TargetRect.Right + Target.X; // Prevent erasing the last vertical grid line. if (poGridLines in PaintOptions) and (toFullVertGridLines in FOptions.FPaintOptions) and (toShowVertGridLines in FOptions.FPaintOptions) and (not (hoAutoResize in FHeader.FOptions)) then Inc(R.Left); NodeBitmap.Canvas.Brush.Color := Brush.Color; NodeBitmap.Canvas.FillRect(R); end; end; SetWindowOrgEx(NodeBitmap.Canvas.Handle, 0, 0, nil); end else begin {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'ErasingBackGround');{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'TargetRect',TargetRect);{$endif} // No columns nor bitmap background. Simply erase it with the tree color. SetWindowOrgEx(NodeBitmap.Canvas.Handle, 0, 0, nil); NodeBitmap.Canvas.Brush.Color := Brush.Color; NodeBitmap.Canvas.FillRect(TargetRect); end; end; end; SetWindowOrgEx(NodeBitmap.Canvas.Handle, 0, 0, nil); {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'DrawSelectionRect',DrawSelectionRect);{$endif} if DrawSelectionRect then begin R := OrderRect(FNewSelRect); // Remap the selection rectangle to the current window of the tree. // Since Target has been used for other tasks BaseOffset got the left extent of the target position here. OffsetRect(R, -Target.X + BaseOffset - Window.Left, -Target.Y + FOffsetY); //todo: see if is necessary {$ifndef INCOMPLETE_WINAPI} SetBrushOrgEx(NodeBitmap.Canvas.Handle, 0, Target.X and 1, nil); {$endif} PaintSelectionRectangle(NodeBitmap.Canvas, 0, R, TargetRect); end; {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeBitmap.Canvas.Height',NodeBitmap.Canvas.Height);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeBitmap.Canvas.ClipRect',NodeBitmap.Canvas.ClipRect);{$endif} {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Target',Target);{$endif} {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPaintBitmap],'BackGroundBitmap',NodeBitmap);{$endif} with Target, NodeBitmap do BitBlt(TargetCanvas.Handle, X, Y, Width, Height, Canvas.Handle, 0, 0, SRCCOPY); end; finally NodeBitmap.Canvas.Unlock; NodeBitmap.Free; end; DoAfterPaint(TargetCanvas); finally DoStateChange([], [tsPainting]); end; end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaint],'PaintTree');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.PasteFromClipboard: Boolean; // Reads what is currently on the clipboard into the tree (if the format is supported). // Note: If the application wants to have text or special formats to be inserted then it must implement // its own code (OLE). Here only the native tree format is accepted. var Data: IDataObject; Source: TBaseVirtualTree; begin Result := False; if not (toReadOnly in FOptions.FMiscOptions) then begin if OleGetClipboard(Data) <> S_OK then ShowError(SClipboardFailed, hcTFClipboardFailed) else try // Try to get the source tree of the operation to optimize the operation. Source := GetTreeFromDataObject(Data); Result := ProcessOLEData(Source, Data, FFocusedNode, FDefaultPasteMode, Assigned(Source) and (tsCutPending in Source.FStates)); if Assigned(Source) then if Source <> Self then Source.FinishCutOrCopy else DoStateChange([], [tsCutPending]); finally Data := nil; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.PrepareDragImage(Hotspot: TPoint; const DataObject: IDataObject); // Initiates an image drag operation. Hotspot is the position of the mouse in client coordinates. var PaintOptions: TVTInternalPaintOptions; TreeRect, PaintRect: TRect; LocalSpot, ImagePos, PaintTarget: TPoint; Image: TBitmap; begin if CanShowDragImage then begin // Determine the drag rectangle which is a square around the hot spot. Operate in virtual tree space. LocalSpot := HotSpot; Dec(LocalSpot.X, -FEffectiveOffsetX); Dec(LocalSpot.Y, FOffsetY); TreeRect := Rect(LocalSpot.X - FDragWidth div 2, LocalSpot.Y - FDragHeight div 2, LocalSpot.X + FDragWidth div 2, LocalSpot.Y + FDragHeight div 2); // Check that we have a valid rectangle. with TreeRect do begin PaintRect := TreeRect; //lclheader if hoVisible in FHeader.Options then OffsetRect(PaintRect, 0, -FHeader.Height); if Left < 0 then begin PaintTarget.X := -Left; PaintRect.Left := 0; end else PaintTarget.X := 0; if Top < 0 then begin PaintTarget.Y := -PaintRect.Top; PaintRect.Top := 0; end else PaintTarget.Y := 0; end; Image := TBitmap.Create; with Image do try PixelFormat := pf32Bit; Width := TreeRect.Right - TreeRect.Left; Height := TreeRect.Bottom - TreeRect.Top; // Erase the entire image with the color key value, for the case not everything // in the image is covered by the tree image. Canvas.Brush.Color := Brush.Color; Canvas.FillRect(Rect(0, 0, Width, Height)); PaintOptions := [poDrawSelection, poSelectedOnly]; if FDragImageKind = diMainColumnOnly then Include(PaintOptions, poMainOnly); PaintTree(Image.Canvas, PaintRect, PaintTarget, PaintOptions); // Once we have got the drag image we can convert all necessary coordinates into screen space. OffsetRect(TreeRect, -FEffectiveOffsetX, FOffsetY); ImagePos := ClientToScreen(TreeRect.TopLeft); HotSpot := ClientToScreen(HotSpot); FDragImage.ColorKey := Brush.Color; FDragImage.PrepareDrag(Image, ImagePos, HotSpot, DataObject); finally Image.Free; end; end; end; //---------------------------------------------------------------------------------------------------------------------- {$ifdef EnablePrint} procedure TBaseVirtualTree.Print(Printer: TPrinter; PrintHeader: Boolean); var SaveTreeFont: TFont; // Remembers the tree's current font. SaveHeaderFont: TFont; // Remembers the header's current font. ImgRect, // Describes the dimensions of Image. TreeRect, // The total VTree dimensions. DestRect, // Dimensions of PrinterImage. SrcRect: TRect; // Clip dimensions from Image -> PrinterImage P: TPoint; // Used by PaintTree. Options: TVTInternalPaintOptions; // Used by PaintTree. Image, // Complete Tree is drawn to this image. PrinterImage: TBitmap; // This is the image that gets printed. SaveColor: TColor; // Remembers the VTree Color. pTxtHeight, // Height of font in the TPrinter.Canvas vTxtHeight, // Height of font in the VTree Canvas vPageWidth, vPageHeight, // Printer height in VTree resolution xPageNum, yPageNum, // # of pages (except the occasional last one) xPage, yPage: Integer; // Loop counter Scale: Extended; // Scale factor between Printer Canvas and VTree Canvas LogFont: TLogFont; begin if Assigned(Printer) then begin BeginUpdate; // Grid lines are the only parts which are desirable when printing. Options := [poGridLines]; // Remember the tree font. SaveTreeFont := TFont.Create; SaveTreeFont.Assign(Font); // Create a new font for printing which does not use clear type output (but is antialiased, if possible) // and which has the highest possible quality. GetObject(Font.Handle, SizeOf(TLogFont), @LogFont); LogFont.lfQuality := ANTIALIASED_QUALITY; Font.Handle := CreateFontIndirect(LogFont); // Create an image that will hold the complete VTree Image := TBitmap.Create; Image.PixelFormat := pf32Bit; PrinterImage := nil; try TreeRect := GetTreeRect; Image.Width := TreeRect.Right - TreeRect.Left; P := Point(0, 0); if (hoVisible in FHeader.Options) and PrintHeader then begin Inc(TreeRect.Bottom, FHeader.Height); Inc(P.Y, FHeader.Height); end; Image.Height := TreeRect.Bottom - TreeRect.Top; ImgRect.Left := 0; ImgRect.Top := 0; ImgRect.Right := Image.Width; // Force the background to white color during the rendering. SaveColor := Color; Color := clWhite; // Print header if it is visible. if (hoVisible in FHeader.Options) and PrintHeader then begin SaveHeaderFont := TFont.Create; try SaveHeaderFont.Assign(FHeader.Font); // Create a new font for printing which does not use clear type output (but is antialiased, if possible) // and which has the highest possible quality. GetObject(FHeader.Font.Handle, SizeOf(TLogFont), @LogFont); LogFont.lfQuality := ANTIALIASED_QUALITY; FHeader.Font.Handle := CreateFontIndirect(LogFont); ImgRect.Bottom := FHeader.Height; FHeader.FColumns.PaintHeader(Image.Canvas.Handle, ImgRect, 0); FHeader.Font := SaveHeaderFont; finally SaveHeaderFont.Free; end; end; // The image's height is already adjusted for the header if it is visible. ImgRect.Bottom := Image.Height; PaintTree(Image.Canvas, ImgRect, P, Options, pf32Bit); Color := SaveColor; // Activate the printer Printer.BeginDoc; Printer.Canvas.Font := Font; // Now we can calculate the scaling : pTxtHeight := Printer.Canvas.TextHeight('Tj'); vTxtHeight := Canvas.TextHeight('Tj'); Scale := pTxtHeight / vTxtHeight; // Create an Image that has the same dimensions as the printer canvas but // scaled to the VTree resolution: PrinterImage := TBitmap.Create; vPageHeight := Round(Printer.PageHeight / Scale); vPageWidth := Round(Printer.PageWidth / Scale); // We do a minumum of one page. xPageNum := Trunc(Image.Width / vPageWidth); yPageNum := Trunc(Image.Height / vPageHeight); PrinterImage.Width := vPageWidth; PrinterImage.Height := vPageHeight; // Split vertically: for yPage := 0 to yPageNum do begin DestRect.Left := 0; DestRect.Top := 0; DestRect.Right := PrinterImage.Width; DestRect.Bottom := PrinterImage.Height; // Split horizontally: for xPage := 0 to xPageNum do begin SrcRect.Left := vPageWidth * xPage; SrcRect.Top := vPageHeight * yPage; SrcRect.Right := vPageWidth * xPage + PrinterImage.Width; SrcRect.Bottom := SrcRect.Top + vPageHeight; // Clear the image PrinterImage.Canvas.Brush.Color := clWhite; PrinterImage.Canvas.FillRect(Rect(0, 0, PrinterImage.Width, PrinterImage.Height)); PrinterImage.Canvas.CopyRect(DestRect, Image.Canvas, SrcRect); PrtStretchDrawDIB(Printer.Canvas, Rect(0, 0, Printer.PageWidth, Printer.PageHeight - 1), PrinterImage); if xPage <> xPageNum then Printer.NewPage; end; if yPage <> yPageNum then Printer.NewPage; end; // Restore tree font. Font := SaveTreeFont; SaveTreeFont.Free; Printer.EndDoc; finally PrinterImage.Free; Image.Free; EndUpdate; end; end; end; {$endif} //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ProcessDrop(DataObject: IDataObject; TargetNode: PVirtualNode; var Effect: LongWord; Mode: TVTNodeAttachMode): Boolean; // Recreates the (sub) tree structure serialized into memory and provided by DataObject. The new nodes are attached to // the passed node or FRoot if TargetNode is nil. // Returns True on success, i.e. the CF_VIRTUALTREE format is supported by the data object and the structure could be // recreated, otherwise False. var Source: TBaseVirtualTree; begin Result := False; if Mode = amNoWhere then Effect := DROPEFFECT_NONE else begin BeginUpdate; // try to get the source tree of the operation Source := GetTreeFromDataObject(DataObject); if Assigned(Source) then Source.BeginUpdate; try try // Before adding the new nodes try to optimize the operation if source and target tree reside in // the same application and operation is a move. if ((Effect and DROPEFFECT_MOVE) <> 0) and Assigned(Source) then begin // If both copy and move are specified then prefer a copy because this is not destructing. Result := ProcessOLEData(Source, DataObject, TargetNode, Mode, (Effect and DROPEFFECT_COPY) = 0); // Since we made an optimized move or a copy there's no reason to act further after DoDragging returns. Effect := DROPEFFECT_NONE; end else // Act only if move or copy operation is requested. if (Effect and (DROPEFFECT_MOVE or DROPEFFECT_COPY)) <> 0 then Result := ProcessOLEData(Source, DataObject, TargetNode, Mode, False) else Result := False; except Effect := DROPEFFECT_NONE; end; finally if Assigned(Source) then Source.EndUpdate; EndUpdate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ReinitChildren(Node: PVirtualNode; Recursive: Boolean); // Forces all child nodes of Node to be reinitialized. // If Recursive is True then also the grandchildren are reinitialized. var Run: PVirtualNode; begin if Assigned(Node) then begin InitChildren(Node); Run := Node.FirstChild; end else begin InitChildren(FRoot); Run := FRoot.FirstChild; end; while Assigned(Run) do begin ReinitNode(Run, Recursive); Run := Run.NextSibling; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ReinitNode(Node: PVirtualNode; Recursive: Boolean); // Forces the given node and all its children (if recursive is True) to be initialized again without // modifying any data in the nodes nor deleting children (unless the application requests a different amount). begin if Assigned(Node) and (Node <> FRoot) then begin // Remove dynamic styles. Node.States := Node.States - [vsChecking, vsCutOrCopy, vsDeleting, vsHeightMeasured]; InitNode(Node); end; if Recursive then ReinitChildren(Node, True); end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.RepaintNode(Node: PVirtualNode); // Causes an immediate repaint of the given node. var R: Trect; begin if Assigned(Node) and (Node <> FRoot) then begin R := GetDisplayRect(Node, -1, False); RedrawWindow(Handle, @R, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE or RDW_VALIDATE or RDW_NOCHILDREN); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ResetNode(Node: PVirtualNode); // Deletes all children of the given node and marks it as being uninitialized. begin DoCancelEdit; if (Node = nil) or (Node = FRoot) then Clear else begin DoReset(Node); DeleteChildren(Node); // Remove initialized and other dynamic styles, keep persistent styles. Node.States := Node.States - [vsInitialized, vsChecking, vsCutOrCopy, vsDeleting, vsHasChildren, vsExpanded, vsHeightMeasured]; InvalidateNode(Node); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SaveToFile(const FileName: TFileName); // Saves the entire content of the tree into a file (see further notes in SaveToStream). var FileStream: TFileStream; begin FileStream := TFileStream.Create(FileName, fmCreate); try SaveToStream(FileStream); finally FileStream.Free; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SaveToStream(Stream: TStream; Node: PVirtualNode = nil); // Saves Node and all its children to Stream. If Node is nil then all top level nodes will be stored. // Note: You should be careful about assuming what is actually saved. The problem here is that we are dealing with // virtual data. The tree can so not know what it has to save. The only fact we reliably know is the tree's // structure. To be flexible for future enhancements as well as unknown content (unknown to the tree class which // is saving/loading the stream) a chunk based approach is used here. Every tree class handles only those // chunks which are not handled by an anchestor class and are known by the class. // // The base tree class saves only the structure of the tree along with application provided data. descendants may // optionally add their own chunks to store additional information. See: WriteChunks. var Count: Cardinal; begin Stream.Write(MagicID, SizeOf(MagicID)); if Node = nil then begin // Keep number of top level nodes for easy restauration. Count := FRoot.ChildCount; Stream.WriteBuffer(Count, SizeOf(Count)); // Save entire tree here. Node := FRoot.FirstChild; while Assigned(Node) do begin WriteNode(Stream, Node); Node := Node.NextSibling; end; end else begin Count := 1; Stream.WriteBuffer(Count, SizeOf(Count)); WriteNode(Stream, Node); end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ScrollIntoView(Node: PVirtualNode; Center: Boolean; Horizontally: Boolean = False): Boolean; // Scrolls the tree so that the given node is in the client area and returns True if the tree really has been // scrolled (e.g. to avoid further updates) else returns False. If extened focus is enabled then the tree will also // be horizontally scrolled if needed. // Note: All collapsed parents of the node are expanded. var R: TRect; Run: PVirtualNode; UseColumns, HScrollBarVisible: Boolean; ScrolledVertically, ScrolledHorizontally: Boolean; OffY, OffYM: Integer; begin //todo: minimize calls to ClientHeight and ClientWidth ScrolledVertically := False; ScrolledHorizontally := False; if Assigned(Node) and (Node <> FRoot) then begin // Make sure all parents of the node are expanded. Run := Node.Parent; while Run <> FRoot do begin if not (vsExpanded in Run.States) then ToggleNode(Run); Run := Run.Parent; end; UseColumns := FHeader.UseColumns; if UseColumns and FHeader.FColumns.IsValidColumn(FFocusedColumn) then R := GetDisplayRect(Node, FFocusedColumn, not (toGridExtensions in FOptions.FMiscOptions)) else R := GetDisplayRect(Node, NoColumn, not (toGridExtensions in FOptions.FMiscOptions)); // The returned rectangle can never be empty after the expand code above. // 1) scroll vertically //lclheader if hoVisible in FHeader.FOptions then OffsetRect(R, 0, -FHeader.Height); if R.Top < 0 then begin if Center then SetOffsetY(FOffsetY - R.Top + ClientHeight div 2) else SetOffsetY(FOffsetY - R.Top); ScrolledVertically := True; end else if (R.Bottom > ClientHeight) or Center then begin HScrollBarVisible := (ScrollBarOptions.ScrollBars in [ssBoth, ssHorizontal]) and (ScrollBarOptions.AlwaysVisible or (Integer(FRangeX) > ClientWidth)); if Center then SetOffsetY(FOffsetY - R.Bottom + ClientHeight div 2) else begin // Leave additional space at the bottom to have scrollrect start with full row. OffY := FOffsetY - R.Bottom + ClientHeight; OffYM := OffY mod DefaultNodeHeight; if OffYM <> 0 then OffY := OffY - (DefaultNodeHeight + OffYM); SetOffsetY(OffY); end; // When scrolling up and the horizontal scroll appears because of the operation // then we have to move up the node the horizontal scrollbar's height too // in order to avoid that the scroll bar hides the node which we wanted to have in view. if not UseColumns and not HScrollBarVisible and (Integer(FRangeX) > ClientWidth) then SetOffsetY(FOffsetY - GetSystemMetrics(SM_CYHSCROLL)); ScrolledVertically := True; end; if Horizontally then // 2) scroll horizontally ScrolledHorizontally := ScrollIntoView(FFocusedColumn, Center); end; Result := ScrolledVertically or ScrolledHorizontally; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.ScrollIntoView(Column: TColumnIndex; Center: Boolean): Boolean; // Scrolls the columns so that the given column is in the client area and returns True if the columns really have been // scrolled (e.g. to avoid further updates) else returns False. var ColumnLeft, ColumnRight: Integer; NewOffset: Integer; begin Result := False; if not FHeader.UseColumns then exit; if not FHeader.Columns.IsValidColumn(Column) then exit; // Just in case. ColumnLeft := Header.Columns.Items[Column].Left; ColumnRight := ColumnLeft + Header.Columns.Items[Column].Width; NewOffset := FEffectiveOffsetX; if Center then begin NewOffset := FEffectiveOffsetX + ColumnLeft - (Header.Columns.GetVisibleFixedWidth div 2) - (ClientWidth div 2) + ((ColumnRight - ColumnLeft) div 2); if NewOffset <> FEffectiveOffsetX then begin if UseRightToLeftAlignment then SetOffsetX(-Integer(FRangeX) + ClientWidth + NewOffset) else SetOffsetX(-NewOffset); end; Result := True; end else begin if FHeader.Columns.Count > 1 then begin if ColumnRight > ClientWidth then NewOffset := FEffectiveOffsetX + (ColumnRight - ClientWidth) else if ColumnLeft < Header.Columns.GetVisibleFixedWidth then NewOffset := FEffectiveOffsetX - (Header.Columns.GetVisibleFixedWidth - ColumnLeft); end; if NewOffset <> FEffectiveOffsetX then begin if UseRightToLeftAlignment then SetOffsetX(-Integer(FRangeX) + ClientWidth + NewOffset) else SetOffsetX(-NewOffset); end; Result := True; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SelectAll(VisibleOnly: Boolean); // Select all nodes in the tree. // If VisibleOnly is True then only visible nodes are selected. var Run: PVirtualNode; NextFunction: TGetNextNodeProc; begin if not FSelectionLocked and (toMultiSelect in FOptions.FSelectionOptions) then begin ClearTempCache; if VisibleOnly then begin Run := GetFirstVisible(nil, True); NextFunction := GetNextVisible; end else begin Run := GetFirst; NextFunction := GetNext; end; while Assigned(Run) do begin if not(vsSelected in Run.States) then InternalCacheNode(Run); Run := NextFunction(Run); end; if FTempNodeCount > 0 then AddToSelection(FTempNodeCache, FTempNodeCount); ClearTempCache; Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.Sort(Node: PVirtualNode; Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); // Sorts the given node. The application is queried about how to sort via the OnCompareNodes event. // Column is simply passed to the the compare function so the application can also sort in a particular column. // In order to free the application from taking care about the sort direction the parameter Direction is used. // This way the application can always sort in increasing order, while this method reorders nodes according to this flag. //--------------- local functions ------------------------------------------- function MergeAscending(A, B: PVirtualNode): PVirtualNode; // Merges A and B (which both must be sorted via Compare) into one list. var Dummy: TVirtualNode; begin // This avoids checking for Result = nil in the loops. Result := @Dummy; while Assigned(A) and Assigned(B) do begin if DoCompare(A, B, Column) <= 0 then begin Result.NextSibling := A; Result := A; A := A.NextSibling; end else begin Result.NextSibling := B; Result := B; B := B.NextSibling; end; end; // Just append the list which is not nil (or set end of result list to nil if both lists are nil). if Assigned(A) then Result.NextSibling := A else Result.NextSibling := B; // return start of the new merged list Result := Dummy.NextSibling; end; //--------------------------------------------------------------------------- function MergeDescending(A, B: PVirtualNode): PVirtualNode; // Merges A and B (which both must be sorted via Compare) into one list. var Dummy: TVirtualNode; begin // this avoids checking for Result = nil in the loops Result := @Dummy; while Assigned(A) and Assigned(B) do begin if DoCompare(A, B, Column) >= 0 then begin Result.NextSibling := A; Result := A; A := A.NextSibling; end else begin Result.NextSibling := B; Result := B; B := B.NextSibling; end; end; // Just append the list which is not nil (or set end of result list to nil if both lists are nil). if Assigned(A) then Result.NextSibling := A else Result.NextSibling := B; // Return start of the newly merged list. Result := Dummy.NextSibling; end; //--------------------------------------------------------------------------- function MergeSortAscending(var Node: PVirtualNode; N: Cardinal): PVirtualNode; // Sorts the list of nodes given by Node (which must not be nil). var A, B: PVirtualNode; begin if N > 1 then begin A := MergeSortAscending(Node, N div 2); B := MergeSortAscending(Node, (N + 1) div 2); Result := MergeAscending(A, B); end else begin Result := Node; Node := Node.NextSibling; Result.NextSibling := nil; end; end; //--------------------------------------------------------------------------- function MergeSortDescending(var Node: PVirtualNode; N: Cardinal): PVirtualNode; // Sorts the list of nodes given by Node (which must not be nil). var A, B: PVirtualNode; begin if N > 1 then begin A := MergeSortDescending(Node, N div 2); B := MergeSortDescending(Node, (N + 1) div 2); Result := MergeDescending(A, B); end else begin Result := Node; Node := Node.NextSibling; Result.NextSibling := nil; end; end; //--------------- end local functions --------------------------------------- var Run: PVirtualNode; Index: Cardinal; begin InterruptValidation; if tsEditPending in FStates then begin KillTimer(Handle, EditTimer); DoStateChange([], [tsEditPending]); end; if not (tsEditing in FStates) or DoEndEdit then begin if Node = nil then Node := FRoot; if vsHasChildren in Node.States then begin if (Node.ChildCount = 0) and DoInit then InitChildren(Node); // Make sure the children are valid, so they can be sorted at all. if DoInit and (Node.ChildCount > 0) then ValidateChildren(Node, False); // Child count might have changed. if Node.ChildCount > 1 then begin // Sort the linked list, check direction flag only once. if Direction = sdAscending then Node.FirstChild := MergeSortAscending(Node.FirstChild, Node.ChildCount) else Node.FirstChild := MergeSortDescending(Node.FirstChild, Node.ChildCount); // Consolidate the child list finally. Run := Node.FirstChild; Run.PrevSibling := nil; Index := 0; repeat Run.Index := Index; Inc(Index); if Run.NextSibling = nil then Break; Run.NextSibling.PrevSibling := Run; Run := Run.NextSibling; until False; Node.LastChild := Run; InvalidateCache; end; if FUpdateCount = 0 then begin ValidateCache; Invalidate; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.SortTree(Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); //--------------- local function -------------------------------------------- procedure DoSort(Node: PVirtualNode); // Recursively sorts Node and its child nodes. var Run: PVirtualNode; begin Sort(Node, Column, Direction, DoInit); Run := Node.FirstChild; while Assigned(Run) do begin if DoInit and not (vsInitialized in Run.States) then InitNode(Run); if vsInitialized in Run.States then DoSort(Run); Run := Run.NextSibling; end; end; //--------------- end local function ---------------------------------------- begin // Instead of wrapping the sort using BeginUpdate/EndUpdate simply the update counter // is modified. Otherwise the EndUpdate call will recurse here. Inc(FUpdateCount); try if Column > InvalidColumn then DoSort(FRoot); InvalidateCache; finally if FUpdateCount > 0 then Dec(FUpdateCount); if FUpdateCount = 0 then begin ValidateCache; Invalidate; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ToggleNode(Node: PVirtualNode); // Changes a node's expand state to the opposite state. var Child: PVirtualNode; HeightDelta, StepsR1, StepsR2, Steps: Integer; TogglingTree, ChildrenInView, NeedFullInvalidate, NeedUpdate, NodeInView, PosHoldable, TotalFit: Boolean; ToggleData: TToggleAnimationData; //--------------- local functions ------------------------------------------- procedure UpdateRanges; // This function is used to adjust FRangeX/FRangeY in order to correctly // reflect the tree's state after a toggle, because it is essential that // these values are correct if we need to scroll afterwards. To avoid a // useless call to UpdateScrollbars we do it right here. begin if FRoot.TotalHeight < FDefaultNodeHeight then FRoot.TotalHeight := FDefaultNodeHeight; FRangeY := FRoot.TotalHeight - FRoot.NodeHeight + FBottomSpace; if FHeader.UseColumns then FRangeX := FHeader.FColumns.TotalWidth else FRangeX := GetMaxRightExtend; end; //--------------------------------------------------------------------------- procedure PrepareAnimation; // Prepares ToggleData. var R: TRect; S: Integer; M: TToggleAnimationMode; begin with ToggleData do begin Window := Handle; DC := GetDC(Handle); //lcl: setting Color to Brush seems not necessary //Self.Brush.Color := Color; Brush := Self.Brush.Reference.Handle; if (Mode1 <> tamNoScroll) and (Mode2 <> tamNoScroll) then begin if StepsR1 < StepsR2 then begin // As the primary rectangle is always R1 we will get a much smoother // animation if R1 is the one that will be scrolled more. R := R2; R2 := R1; R1 := R; M := Mode2; Mode2 := Mode1; Mode1 := M; S := StepsR2; StepsR2 := StepsR1; StepsR1 := S; end; ScaleFactor := StepsR2 / StepsR1; MissedSteps := 0; end; if Mode1 <> tamNoScroll then Steps := StepsR1 else Steps := StepsR2; end; end; //--------------- end local functions --------------------------------------- begin Assert(Assigned(Node), 'Node must not be nil.'); TogglingTree := tsToggling in FStates; ChildrenInView := False; HeightDelta := 0; NeedFullInvalidate := False; NeedUpdate := False; NodeInView := False; PosHoldable := False; TotalFit := False; // We don't need to switch the expand state if the node is being deleted otherwise some // updates (e.g. visible node count) are done twice with disasterous results). if [vsDeleting, vsToggling] * Node.States = [] then begin try DoStateChange([tsToggling]); Include(Node.States, vsToggling); if vsExpanded in Node.States then begin if DoCollapsing(Node) then begin NeedUpdate := True; if (FUpdateCount = 0) and (toAnimatedToggle in FOptions.FAnimationOptions) and not (tsCollapsing in FStates) then begin Application.CancelHint; UpdateWindow(Handle); // animated collapsing with ToggleData do begin // Determine the animation behaviour and rectangle. If toChildrenAbove is set, the behaviour is depending // on the position of the node to be collapsed. R1 := GetDisplayRect(Node, NoColumn, False); Mode2 := tamNoScroll; HeightDelta := -Node.TotalHeight + NodeHeight[Node]; if toChildrenAbove in FOptions.FPaintOptions then begin PosHoldable := (FOffsetY + (Integer(Node.TotalHeight - NodeHeight[Node]))) <= 0; NodeInView := R1.Top < ClientHeight; StepsR1 := 0; if NodeInView then begin if PosHoldable or not (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) then begin // Scroll the child nodes down. Mode1 := tamScrollDown; R1.Bottom := R1.Top; R1.Top := 0; StepsR1 := Min(R1.Bottom - R1.Top + 1, Node.TotalHeight - NodeHeight[Node]); end else begin // The position cannot be kept. So scroll the node up to its future position. Mode1 := tamScrollUp; R1.Top := Max(0, R1.Top + HeightDelta); R1.Bottom := ClientHeight; StepsR1 := FOffsetY - HeightDelta; end; end; end else begin if (Integer(FRangeY) + FOffsetY - R1.Bottom + HeightDelta >= ClientHeight - R1.Bottom) or (Integer(FRangeY) <= ClientHeight) or (FOffsetY = 0) or not (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) then begin // Do a simple scroll up over the child nodes. Mode1 := tamScrollUp; Inc(R1.Top, NodeHeight[Node]); R1.Bottom := ClientHeight; StepsR1 := Min(R1.Bottom - R1.Top + 1, -HeightDelta); end else begin // Scroll the node down to its future position. As FOffsetY will change we need to invalidate the // whole tree. Mode1 := tamScrollDown; StepsR1 := Min(-FOffsetY, ClientHeight - Integer(FRangeY) -FOffsetY - HeightDelta); R1.Top := 0; R1.Bottom := Min(ClientHeight, R1.Bottom + Steps); NeedFullInvalidate := True; end; end; // No animation necessary if the node is below the current client height. if R1.Top < ClientHeight then begin PrepareAnimation; try Animate(Steps, FAnimationDuration, ToggleCallback, @ToggleData); finally ReleaseDC(Window, DC); end; end; end; end; // collapse the node AdjustTotalHeight(Node, NodeHeight[Node]); if FullyVisible[Node] then Dec(FVisibleCount, CountVisibleChildren(Node)); Exclude(Node.States, vsExpanded); DoCollapsed(Node); // Remove child nodes now, if enabled. if (toAutoFreeOnCollapse in FOptions.FAutoOptions) and (Node.ChildCount > 0) then begin DeleteChildren(Node); Include(Node.States, vsHasChildren); end; end; end else if DoExpanding(Node) then begin NeedUpdate := True; // expand the node, need to adjust the height if not (vsInitialized in Node.States) then InitNode(Node); if (vsHasChildren in Node.States) and (Node.ChildCount = 0) then InitChildren(Node); // Avoid setting the vsExpanded style if there are no child nodes. if Node.ChildCount > 0 then begin // Iterate through the child nodes without initializing them. We have to determine the entire height. Child := Node.FirstChild; repeat if vsVisible in Child.States then Inc(HeightDelta, Child.TotalHeight); Child := Child.NextSibling; until Child = nil; // Getting the display rectangle is already done here as it is needed for toChildrenAbove in any case. if (toChildrenAbove in FOptions.FPaintOptions) or (FUpdateCount = 0) then begin with ToggleData do begin R1 := GetDisplayRect(Node, NoColumn, False); Mode2 := tamNoScroll; TotalFit := HeightDelta + Integer(NodeHeight[Node]) <= ClientHeight; if toChildrenAbove in FOptions.FPaintOptions then begin // The main goal with toChildrenAbove being set is to keep the nodes visual position so the user does // not get confused. Therefore we need to scroll the view when the expanding is done. PosHoldable := TotalFit and (Integer(FRangeY) - ClientHeight >= 0) ; ChildrenInView := (R1.Top - HeightDelta) >= 0; NodeInView := R1.Bottom <= ClientHeight; end else begin PosHoldable := TotalFit; ChildrenInView := R1.Bottom + HeightDelta <= ClientHeight; end; R1.Bottom := ClientHeight; end; end; if FUpdateCount = 0 then begin // Do animated expanding if enabled. if (ToggleData.R1.Top < ClientHeight) and ([tsPainting, tsExpanding] * FStates = []) and (toAnimatedToggle in FOptions.FAnimationOptions)then begin Application.CancelHint; UpdateWindow(Handle); // animated expanding with ToggleData do begin if toChildrenAbove in FOptions.FPaintOptions then begin // At first check if we hold the position, which is the most common case. if not (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) or (PosHoldable and ( (NodeInView and ChildrenInView) or not (toAutoScrollOnExpand in FOptions.FAutoOptions) )) then begin Mode1 := tamScrollUp; R1 := Rect(R1.Left, 0, R1.Right, R1.Top); StepsR1 := Min(HeightDelta, R1.Bottom); end else begin // If we will not hold the node's visual position we mostly scroll in both directions. Mode1 := tamScrollDown; Mode2 := tamScrollUp; R2 := Rect(R1.Left, 0, R1.Right, R1.Top); if not (toAutoScrollOnExpand in FOptions.FAutoOptions) then begin // If we shall not or cannot scroll to the desired extent we calculate the new position (with // max FOffsetY applied) and animate it that way. StepsR1 := -FOffsetY - Max(Integer(FRangeY) + HeightDelta - ClientHeight, 0) + HeightDelta; if (Integer(FRangeY) + HeightDelta - ClientHeight) <= 0 then Mode2 := tamNoScroll else StepsR2 := Min(Integer(FRangeY) + HeightDelta - ClientHeight, R2.Bottom); end else begin if TotalFit and NodeInView and (Integer(FRangeY) + HeightDelta > ClientHeight) then begin // If the whole subtree will fit into the client area and the node is currently fully visible, // the first child will be made the top node if possible. if HeightDelta >= R1.Top then StepsR1 := Abs(R1.Top - HeightDelta) else StepsR1 := ClientHeight - Integer(FRangeY); end else if Integer(FRangeY) + HeightDelta <= ClientHeight then begin // We cannot make the first child the top node as we cannot scroll to that extent, // so we do a simple scroll down. Mode2 := tamNoScroll; StepsR1 := HeightDelta; end else // If the subtree does not fit into the client area at once, the expanded node will // be made the bottom node. StepsR1 := ClientHeight - R1.Top - Integer(NodeHeight[Node]); if Mode2 <> tamNoScroll then begin if StepsR1 > 0 then StepsR2 := Min(R1.Top, HeightDelta - StepsR1) else begin // If the node is already at the bottom scrolling is needed. Mode1 := tamNoScroll; StepsR2 := Min(HeightDelta, R1.Bottom); end; end; end; end; end else begin // toChildrenAbove is not set. if (PosHoldable and ChildrenInView) or not (toAutoScrollOnExpand in FOptions.FAutoOptions) or not (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) or (R1.Top <= 0) then begin // If the node will stay at its visual position, do a simple down-scroll. Mode1 := tamScrollDown; Inc(R1.Top, NodeHeight[Node]); StepsR1 := Min(R1.Bottom - R1.Top, HeightDelta); end else begin // We will not hold the nodes visual position so perform a double scroll. Mode1 := tamScrollUp; Mode2 := tamScrollDown; R1.Bottom := R1.Top + Integer(NodeHeight[Node]) + 1; R1.Top := 0; R2 := Rect(R1.Left, R1.Bottom, R1.Right, ClientHeight); StepsR1 := Min(HeightDelta - (ClientHeight - R2.Top), R1.Bottom - Integer(NodeHeight[Node])); StepsR2 := ClientHeight - R2.Top; end; end; if ClientHeight >= R1.Top then begin PrepareAnimation; try Animate(Steps, FAnimationDuration, ToggleCallback, @ToggleData); finally ReleaseDC(Window, DC); end; end; end; end; end; Include(Node.States, vsExpanded); AdjustTotalHeight(Node, HeightDelta, True); if FullyVisible[Node] then Inc(FVisibleCount, CountVisibleChildren(Node)); DoExpanded(Node); end; end; if NeedUpdate then begin InvalidateCache; if FUpdateCount = 0 then begin ValidateCache; if Node.ChildCount > 0 then begin UpdateRanges; if [tsPainting, tsExpanding] * FStates = [] then begin if (vsExpanded in Node.States) and ((toAutoScrollOnExpand in FOptions.FAutoOptions) or (toChildrenAbove in FOptions.FPaintOptions)) then begin if toChildrenAbove in FOptions.FPaintOptions then begin NeedFullInvalidate := True; if (PosHoldable and ChildrenInView and NodeInView) or not (toAutoScrollOnExpand in FOptions.FAutoOptions) then SetOffsetY(FOffsetY - Integer(HeightDelta)) else if TotalFit and NodeInView then SetOffsetY(FOffsetY - GetDisplayRect(GetFirstVisible(Node, True), NoColumn, False).Top) else BottomNode := Node; end else begin // Scroll as much child nodes into view as possible if the node has been expanded. if PosHoldable then NeedFullInvalidate := ScrollIntoView(GetLastVisible(Node, True), False) else begin TopNode := Node; NeedFullInvalidate := True; end; end; end else begin // If we have collapsed the node or toAutoScrollOnExpand is not set, we try to keep the nodes // visual position. if toChildrenAbove in FOptions.FPaintOptions then SetOffsetY(FOffsetY - Integer(HeightDelta)); NeedFullInvalidate := True; end; end; UpdateScrollbars(True); // Check for automatically scrolled tree. if NeedFullInvalidate then Invalidate else InvalidateToBottom(Node); end else InvalidateNode(Node); end else UpdateRanges; end; finally Exclude(Node.States, vsToggling); if not TogglingTree then DoStateChange([], [tsToggling]); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.UpdateAction(Action: TBasicAction): Boolean; // Support for standard actions. begin if not Focused then Result := inherited UpdateAction(Action) else begin Result := (Action is TEditCut) or (Action is TEditCopy) or (Action is TEditDelete); if Result then TAction(Action).Enabled := (FSelectionCount > 0) and ((Action is TEditDelete) or (FClipboardFormats.Count > 0)) else begin Result := Action is TEditPaste; if Result then TAction(Action).Enabled := True else begin Result := Action is TEditSelectAll; if Result then TAction(Action).Enabled := (toMultiSelect in FOptions.FSelectionOptions) and (FVisibleCount > 0) else Result := inherited UpdateAction(Action); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.UpdateHorizontalScrollBar(DoRepaint: Boolean); var ScrollInfo: TScrollInfo; begin if FHeader.UseColumns then FRangeX := FHeader.FColumns.TotalWidth else FRangeX := GetMaxRightExtend; if tsUpdating in FStates then exit; // Adjust effect scroll offset depending on bidi mode. if UseRightToLeftAlignment then FEffectiveOffsetX := Integer(FRangeX) - ClientWidth + FOffsetX else FEffectiveOffsetX := -FOffsetX; if FScrollBarOptions.ScrollBars in [ssHorizontal, ssBoth] then begin FillChar(ScrollInfo, SizeOf(ScrollInfo), 0); //LCL automatically set cbSize field //ScrollInfo.cbSize := SizeOf(ScrollInfo); ScrollInfo.fMask := SIF_ALL; {$ifdef UseFlatScrollbars} FlatSB_GetScrollInfo(Handle, SB_HORZ, ScrollInfo); {$else} GetScrollInfo(Handle, SB_HORZ, ScrollInfo); {$endif UseFlatScrollbars} if (Integer(FRangeX) > ClientWidth) or FScrollBarOptions.AlwaysVisible then begin DoShowScrollBar(SB_HORZ, True); ScrollInfo.nMin := 0; ScrollInfo.nMax := FRangeX; ScrollInfo.nPos := FEffectiveOffsetX; ScrollInfo.nPage := Max(0, ClientWidth); ScrollInfo.fMask := SIF_ALL or ScrollMasks[FScrollBarOptions.AlwaysVisible]; {$ifdef UseFlatScrollbars} FlatSB_SetScrollInfo(Handle, SB_HORZ, ScrollInfo, DoRepaint); {$else} SetScrollInfo(Handle, SB_HORZ, ScrollInfo, DoRepaint); {$endif UseFlatScrollbars} end else begin ScrollInfo.nMin := 0; ScrollInfo.nMax := 0; ScrollInfo.nPos := 0; ScrollInfo.nPage := 0; DoShowScrollBar(SB_HORZ, False); {$ifdef UseFlatScrollbars} FlatSB_SetScrollInfo(Handle, SB_HORZ, ScrollInfo, False); {$else} SetScrollInfo(Handle, SB_HORZ, ScrollInfo, False); {$endif UseFlatScrollbars} end; // Since the position is automatically changed if it doesn't meet the range // we better read the current position back to stay synchronized. {$ifdef UseFlatScrollbars} FEffectiveOffsetX := FlatSB_GetScrollPos(Handle, SB_HORZ); {$else} //todo: Use get scrollinfo instead of GetScrollPos?? FEffectiveOffsetX := GetScrollPos(Handle, SB_HORZ); {$endif UseFlatScrollbars} if UseRightToLeftAlignment then SetOffsetX(-Integer(FRangeX) + ClientWidth + FEffectiveOffsetX) else SetOffsetX(-FEffectiveOffsetX); end else begin DoShowScrollBar(SB_HORZ, False); // Reset the current horizontal offset to account for window resize etc. SetOffsetX(FOffsetX); end; {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FEffectiveOffsetX after UpdateHScrollbar',FEffectiveOffsetX);{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.UpdateScrollBars(DoRepaint: Boolean); // adjusts scrollbars to reflect current size and paint offset of the tree begin if HandleAllocated then begin UpdateVerticalScrollBar(DoRepaint); UpdateHorizontalScrollBar(DoRepaint); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.UpdateVerticalScrollBar(DoRepaint: Boolean); var ScrollInfo: TScrollInfo; begin // Total node height includes the height of the invisible root node. if FRoot.TotalHeight < FDefaultNodeHeight then FRoot.TotalHeight := FDefaultNodeHeight; FRangeY := FRoot.TotalHeight - FRoot.NodeHeight + FBottomSpace; if tsUpdating in FStates then exit; if FScrollBarOptions.ScrollBars in [ssVertical, ssBoth] then begin //LCL automatically set cbSize field //ScrollInfo.cbSize := SizeOf(ScrollInfo); ScrollInfo.fMask := SIF_ALL; {$ifdef UseFlatScrollbars} FlatSB_GetScrollInfo(Handle, SB_VERT, ScrollInfo); {$else} GetScrollInfo(Handle, SB_VERT, ScrollInfo); {$endif UseFlatScrollbars} if (Integer(FRangeY) > ClientHeight) or FScrollBarOptions.AlwaysVisible then begin DoShowScrollBar(SB_VERT, True); ScrollInfo.nMin := 0; ScrollInfo.nMax := FRangeY; ScrollInfo.nPos := -FOffsetY; ScrollInfo.nPage := Max(0, ClientHeight); ScrollInfo.fMask := SIF_ALL or ScrollMasks[FScrollBarOptions.AlwaysVisible]; {$ifdef UseFlatScrollbars} FlatSB_SetScrollInfo(Handle, SB_VERT, ScrollInfo, DoRepaint); {$else} SetScrollInfo(Handle, SB_VERT, ScrollInfo, DoRepaint); {$endif UseFlatScrollbars} end else begin ScrollInfo.nMin := 0; ScrollInfo.nMax := 0; ScrollInfo.nPos := 0; ScrollInfo.nPage := 0; DoShowScrollBar(SB_VERT, False); {$ifdef UseFlatScrollbars} FlatSB_SetScrollInfo(Handle, SB_VERT, ScrollInfo, False); {$else} SetScrollInfo(Handle, SB_VERT, ScrollInfo, False); {$endif UseFlatScrollbars} end; // Since the position is automatically changed if it doesn't meet the range // we better read the current position back to stay synchronized. {$ifdef UseFlatScrollbars} SetOffsetY(-FlatSB_GetScrollPos(Handle, SB_VERT)); {$else} SetOffsetY(-GetScrollPos(Handle, SB_VERT)); {$endif UseFlatScrollBars} end else begin DoShowScrollbar(SB_VERT, False); // Reset the current vertical offset to account for window resize etc. SetOffsetY(FOffsetY); end; end; //---------------------------------------------------------------------------------------------------------------------- //lcl: the current implementation in TControl is exactly equal to this. // disable for now and reenable in the case the TControl implementation change { function TBaseVirtualTree.UseRightToLeftReading: Boolean; // The tree can handle right-to-left reading also on non-middle-east systems, so we cannot use the same function as // it is implemented in TControl. begin Result := BiDiMode <> bdLeftToRight; end; } //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ValidateChildren(Node: PVirtualNode; Recursive: Boolean); // Ensures that the children of the given node (and all their children, if Recursive is True) are initialized. // Node must already be initialized var Child: PVirtualNode; begin if Node = nil then Node := FRoot; if (vsHasChildren in Node.States) and (Node.ChildCount = 0) then InitChildren(Node); Child := Node.FirstChild; while Assigned(Child) do begin ValidateNode(Child, Recursive); Child := Child.NextSibling; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ValidateNode(Node: PVirtualNode; Recursive: Boolean); // Ensures that the given node (and all its children, if Recursive is True) are initialized. var Child: PVirtualNode; begin if Node = nil then Node := FRoot else if not (vsInitialized in Node.States) then InitNode(Node); if Recursive then begin if (vsHasChildren in Node.States) and (Node.ChildCount = 0) then InitChildren(Node); Child := Node.FirstChild; while Assigned(Child) do begin ValidateNode(Child, recursive); Child := Child.NextSibling; end; end; end; //----------------- TCustomStringTreeOptions --------------------------------------------------------------------------- constructor TCustomStringTreeOptions.Create(AOwner: TBaseVirtualTree); begin inherited; FStringOptions := DefaultStringOptions; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomStringTreeOptions.SetStringOptions(const Value: TVTStringOptions); var ChangedOptions: TVTStringOptions; begin if FStringOptions <> Value then begin // Exclusive ORing to get all entries wich are in either set but not in both. ChangedOptions := FStringOptions + Value - (FStringOptions * Value); FStringOptions := Value; with FOwner do if (toShowStaticText in ChangedOptions) and not (csLoading in ComponentState) and HandleAllocated then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomStringTreeOptions.AssignTo(Dest: TPersistent); begin if Dest is TCustomStringTreeOptions then begin with TCustomStringTreeOptions(Dest) do StringOptions := Self.StringOptions; end; // Let ancestors assign their options to the destination class. inherited; end; //----------------- TVTEdit -------------------------------------------------------------------------------------------- // Implementation of a generic node caption editor. constructor TVTEdit.Create(Link: TStringEditLink); begin inherited Create(nil); ShowHint := False; ParentShowHint := False; // This assignment increases the reference count for the interface. FRefLink := Link; // This reference is used to access the link. FLink := Link; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.CMAutoAdjust(var Message: TLMessage); begin AutoAdjustSize; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.CMExit(var Message: TLMessage); begin if Assigned(FLink) and not FLink.FStopping then with FLink, FTree do begin if (toAutoAcceptEditChange in TreeOptions.StringOptions) then DoEndEdit else DoCancelEdit; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.CNCommand(var Message: TLMCommand); begin if Assigned(FLink) and Assigned(FLink.FTree) and (Message.NotifyCode = EN_UPDATE) and not (toGridExtensions in FLink.FTree.FOptions.FMiscOptions) and not (vsMultiline in FLink.FNode.States) then // Instead directly calling AutoAdjustSize it is necessary on Win9x/Me to decouple this notification message // and eventual resizing. Hence we use a message to accomplish that. if IsWinNT then AutoAdjustSize else PostMessage(Handle, CM_AUTOADJUST, 0, 0); end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.DoRelease(Data: PtrInt); begin Free; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.WMChar(var Message: TLMChar); begin if not (Message.CharCode in [VK_ESCAPE, VK_TAB]) then inherited; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.WMDestroy(var Message: TLMDestroy); begin // If editing stopped by other means than accept or cancel then we have to do default processing for // pending changes. if Assigned(FLink) and not FLink.FStopping then begin with FLink, FTree do begin if (toAutoAcceptEditChange in TreeOptions.StringOptions) and Modified then Text[FNode, FColumn] := FEdit.Text; end; FLink := nil; FRefLink := nil; end; inherited; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.WMGetDlgCode(var Message: TLMNoParams); begin inherited; Message.Result := Message.Result or DLGC_WANTALLKEYS or DLGC_WANTTAB or DLGC_WANTARROWS; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.WMKeyDown(var Message: TLMKeyDown); // Handles some control keys. var Shift: TShiftState; EndEdit: Boolean; Tree: TBaseVirtualTree; begin case Message.CharCode of VK_ESCAPE: begin Tree := FLink.FTree; FLink.FTree.DoCancelEdit; Tree.SetFocus; end; VK_RETURN: begin EndEdit := not (vsMultiline in FLink.FNode.States); if not EndEdit then begin // If a multiline node is being edited the finish editing only if Ctrl+Enter was pressed, // otherwise allow to insert line breaks into the text. Shift := KeyDataToShiftState(Message.KeyData); EndEdit := ssCtrlOS in Shift; end; if EndEdit then begin Tree := FLink.FTree; FLink.FTree.InvalidateNode(FLink.FNode); FLink.FTree.DoEndEdit; Tree.SetFocus; end; end; VK_UP: begin if not (vsMultiline in FLink.FNode.States) then Message.CharCode := VK_LEFT; inherited; end; VK_DOWN: begin if not (vsMultiline in FLink.FNode.States) then Message.CharCode := VK_RIGHT; inherited; end; else inherited; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.AutoAdjustSize; // Changes the size of the edit to accomodate as much as possible of its text within its container window. // NewChar describes the next character which will be added to the edit's text. var DC: HDC; Size: TSize; LastFont: THandle; begin if not (vsMultiline in FLink.FNode.States) then begin DC := GetDC(Handle); LastFont := SelectObject(DC, Font.Reference.Handle); try // Read needed space for the current text. GetTextExtentPoint32(DC, PChar(Text), Length(Text), Size); Inc(Size.cx, 2 * FLink.FTree.FTextMargin); // Repaint associated node if the edit becomes smaller. if Size.cx < Width then FLink.FTree.InvalidateNode(FLink.FNode); if FLink.FAlignment = taRightJustify then FLink.SetBounds(Rect(Left + Width - Size.cx, Top, Left + Width, Top + Height)) else FLink.SetBounds(Rect(Left, Top, Left + Size.cx, Top + Height)); finally SelectObject(DC, LastFont); ReleaseDC(Handle, DC); end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.CreateParams(var Params: TCreateParams); begin inherited; // Only with multiline style we can use the text formatting rectangle. // This does not harm formatting as single line control, if we don't use word wrapping. with Params do begin //todo: delphi uses Multiline for all //Style := Style or ES_MULTILINE; if vsMultiline in FLink.FNode.States then begin Style := Style and not (ES_AUTOHSCROLL or WS_HSCROLL) or WS_VSCROLL or ES_AUTOVSCROLL; Style := Style or ES_MULTILINE; end; if tsUseThemes in FLink.FTree.FStates then begin Style := Style and not WS_BORDER; ExStyle := ExStyle or WS_EX_CLIENTEDGE; end else begin Style := Style or WS_BORDER; ExStyle := ExStyle and not WS_EX_CLIENTEDGE; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVTEdit.Release; begin if HandleAllocated then Application.QueueAsyncCall(DoRelease, 0); end; //----------------- TStringEditLink ------------------------------------------------------------------------------------ constructor TStringEditLink.Create; begin inherited; FEdit := TVTEdit.Create(Self); with FEdit do begin Visible := False; BorderStyle := bsSingle; AutoSize := False; end; end; //---------------------------------------------------------------------------------------------------------------------- destructor TStringEditLink.Destroy; begin FEdit.Release; inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TStringEditLink.BeginEdit: Boolean; // Notifies the edit link that editing can start now. descendants may cancel node edit // by returning False. begin Result := not FStopping; if Result then begin FEdit.Show; FEdit.SelectAll; FEdit.SetFocus; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TStringEditLink.SetEdit(const Value: TVTEdit); begin if Assigned(FEdit) then FEdit.Free; FEdit := Value; end; //---------------------------------------------------------------------------------------------------------------------- function TStringEditLink.CancelEdit: Boolean; begin Result := not FStopping; if Result then begin FStopping := True; FEdit.Hide; FTree.CancelEditNode; FEdit.FLink := nil; FEdit.FRefLink := nil; end; end; //---------------------------------------------------------------------------------------------------------------------- function TStringEditLink.EndEdit: Boolean; begin Result := not FStopping; if Result then try FStopping := True; if FEdit.Modified then FTree.Text[FNode, FColumn] := FEdit.Text; FEdit.Hide; FEdit.FLink := nil; FEdit.FRefLink := nil; except FStopping := False; raise; end; end; //---------------------------------------------------------------------------------------------------------------------- function TStringEditLink.GetBounds: TRect; begin Result := FEdit.BoundsRect; end; //---------------------------------------------------------------------------------------------------------------------- function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; // Retrieves the true text bounds from the owner tree. var Text: String; begin Result := Tree is TCustomVirtualStringTree; if Result then begin FTree := Tree as TCustomVirtualStringTree; FNode := Node; FColumn := Column; // Initial size, font and text of the node. FTree.GetTextInfo(Node, Column, FEdit.Font, FTextBounds, Text); FEdit.Font.Color := clWindowText; FEdit.Parent := Tree; FEdit.HandleNeeded; FEdit.Text := Text; if Column <= NoColumn then begin FEdit.BidiMode := FTree.BidiMode; FAlignment := FTree.Alignment; end else begin FEdit.BidiMode := FTree.Header.Columns[Column].BidiMode; FAlignment := FTree.Header.Columns[Column].Alignment; end; if FEdit.BidiMode <> bdLeftToRight then ChangeBidiModeAlignment(FAlignment); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TStringEditLink.ProcessMessage(var Message: TLMessage); begin FEdit.WindowProc(Message); end; //---------------------------------------------------------------------------------------------------------------------- procedure TStringEditLink.SetBounds(R: TRect); // Sets the outer bounds of the edit control and the actual edit area in the control. var Offset: Integer; begin if not FStopping then begin with R do begin // Set the edit's bounds but make sure there's a minimum width and the right border does not // extend beyond the parent's left/right border. if Left < 0 then Left := 0; if Right - Left < 30 then begin if FAlignment = taRightJustify then Left := Right - 30 else Right := Left + 30; end; if Right > FTree.ClientWidth then Right := FTree.ClientWidth; FEdit.BoundsRect := R; // The selected text shall exclude the text margins and be centered vertically. // We have to take out the two pixel border of the edit control as well as a one pixel "edit border" the // control leaves around the (selected) text. R := FEdit.ClientRect; Offset := 2; if tsUseThemes in FTree.FStates then Inc(Offset); InflateRect(R, -FTree.FTextMargin + Offset, Offset); if not (vsMultiline in FNode.States) then OffsetRect(R, 0, FTextBounds.Top - FEdit.Top); SendMessage(FEdit.Handle, EM_SETRECTNP, 0, PtrUInt(@R)); end; end; end; //----------------- TCustomVirtualString ------------------------------------------------------------------------------- constructor TCustomVirtualStringTree.Create(AOwner: TComponent); begin inherited; if (Owner = nil) or (([csReading, csDesigning] * Owner.ComponentState) = [csDesigning]) then FDefaultText := 'Node'; FInternalDataOffset := AllocateInternalDataArea(SizeOf(Cardinal)); end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.GetRenderStartValues(Source: TVSTTextSourceType; out Node: PVirtualNode; out NextNodeProc: TGetNextNodeProc); begin case Source of tstInitialized: begin Node := GetFirstInitialized; NextNodeProc := GetNextInitialized; end; tstSelected: begin Node := GetFirstSelected; NextNodeProc := GetNextSelected; end; tstCutCopySet: begin Node := GetFirstCutCopy; NextNodeProc := GetNextCutCopy; end; tstVisible: begin Node := GetFirstVisible(nil, True); NextNodeProc := GetNextVisible; end; else // tstAll Node := GetFirst; NextNodeProc := GetNext; end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.GetImageText(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex): String; begin Assert(Assigned(Node), 'Node must not be nil.'); if not (vsInitialized in Node.States) then InitNode(Node); Result := ''; DoGetImageText(Node, Kind, Column, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.GetOptions: TCustomStringTreeOptions; begin Result := FOptions as TCustomStringTreeOptions; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.GetText(Node: PVirtualNode; Column: TColumnIndex): String; begin Assert(Assigned(Node), 'Node must not be nil.'); if not (vsInitialized in Node.States) then InitNode(Node); Result := FDefaultText; DoGetText(Node, Column, ttNormal, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.InitializeTextProperties(var PaintInfo: TVTPaintInfo); // Initializes default values for customization in PaintNormalText. begin with PaintInfo do begin // Set default font values first. Canvas.Font := Font; if (toHotTrack in FOptions.FPaintOptions) and (Node = FCurrentHotNode) then begin if not IsWinVistaOrAbove or not (tsUseThemes in FStates) or not (toUseExplorerTheme in FOptions.FPaintOptions) then Canvas.Font.Style := Canvas.Font.Style + [fsUnderline]; Canvas.Font.Color := FColors.HotColor; end; // Change the font color only if the node also is drawn in selected style. if poDrawSelection in PaintOptions then begin if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.FSelectionOptions) then begin if Node = FDropTargetNode then begin if (FLastDropMode = dmOnNode) or (vsSelected in Node.States) and (not IsWinVistaOrAbove or not (tsUseThemes in FStates) or not (toUseExplorerTheme in FOptions.FPaintOptions)) then Canvas.Font.Color := clHighlightText; end else if vsSelected in Node.States then begin if (Focused or (toPopupMode in FOptions.FPaintOptions)) and (not IsWinVistaOrAbove or not (tsUseThemes in FStates) or not (toUseExplorerTheme in FOptions.FPaintOptions)) then Canvas.Font.Color := clHighlightText; end; end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.PaintNormalText(var PaintInfo: TVTPaintInfo; TextOutFlags: Integer; Text: String); // This method is responsible for painting the given text to target canvas (under consideration of the given rectangles). // The text drawn here is considered as the normal text in a node. // Note: NodeWidth is the actual width of the text to be drawn. This does not necessarily correspond to the width of // the node rectangle. The clipping rectangle comprises the entire node (including tree lines, buttons etc.). var TripleWidth: Integer; R: TRect; DrawFormat: Cardinal; Size: TSize; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'PaintNormalText') ;{$endif} InitializeTextProperties(PaintInfo); with PaintInfo do begin R := ContentRect; //todo_lcl See how TextStyle should be set //Canvas.TextFlags := 0; // Multiline nodes don't need special font handling or text manipulation. // Note: multiline support requires the Unicode version of DrawText, which is able to do word breaking. // The emulation in this unit does not support this so we have to use the OS version. However // DrawTextW is only available on NT/2000/XP and up. Hence there is only partial multiline support // for 9x/Me. if vsMultiline in Node.States then begin InflateRect(R, -FTextMargin, 0); DoPaintText(Node, Canvas, Column, ttNormal); // Disabled node color overrides all other variants. if (vsDisabled in Node.States) or not Enabled then Canvas.Font.Color := FColors.DisabledColor; // The edit control flag will ensure that no partial line is displayed, that is, only lines // which are (vertically) fully visible are drawn. DrawFormat := DT_NOPREFIX or DT_WORDBREAK or DT_END_ELLIPSIS or DT_EDITCONTROL or AlignmentToDrawFlag[Alignment]; if BidiMode <> bdLeftToRight then DrawFormat := DrawFormat or DT_RTLREADING; end else begin InflateRect(R, -FTextMargin, 0); FFontChanged := False; TripleWidth := FEllipsisWidth; DoPaintText(Node, Canvas, Column, ttNormal); if FFontChanged then begin // If the font has been changed then the ellipsis width must be recalculated. TripleWidth := 0; // Recalculate also the width of the normal text. GetTextExtentPoint32(Canvas.Handle, PChar(Text), Length(Text), Size); NodeWidth := Size.cx + 2 * FTextMargin; end; // Disabled node color overrides all other variants. if (vsDisabled in Node.States) or not Enabled then Canvas.Font.Color := FColors.DisabledColor; DrawFormat := DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE; if BidiMode <> bdLeftToRight then DrawFormat := DrawFormat or DT_RTLREADING; // Check if the text must be shortend. if (Column > -1) and ((NodeWidth - 2 * FTextMargin) > R.Right - R.Left) then begin Text := DoShortenString(Canvas, Node, Column, Text, R.Right - R.Left, TripleWidth); if Alignment = taRightJustify then DrawFormat := DrawFormat or DT_RIGHT else DrawFormat := DrawFormat or DT_LEFT; end else DrawFormat := DrawFormat or AlignmentToDrawFlag[Alignment]; end; //todo_lcl_check if not Canvas.TextStyle.Opaque then SetBkMode(Canvas.Handle, TRANSPARENT) else SetBkMode(Canvas.Handle, OPAQUE); {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Canvas.Brush.Color',Canvas.Brush.Color);{$endif} DoTextDrawing(PaintInfo, Text, R, DrawFormat); end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'PaintNormalText');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.PaintStaticText(const PaintInfo: TVTPaintInfo; TextOutFlags: Integer; const Text: String); // This method retrives and draws the static text bound to a particular node. var R: TRect; DrawFormat: Cardinal; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'PaintStaticText');{$endif} with PaintInfo do begin Canvas.Font := Font; if toFullRowSelect in FOptions.FSelectionOptions then begin if Node = FDropTargetNode then begin if (FLastDropMode = dmOnNode) or (vsSelected in Node.States)then Canvas.Font.Color := clHighlightText else Canvas.Font.Color := Font.Color; end else if vsSelected in Node.States then begin if Focused or (toPopupMode in FOptions.FPaintOptions) then Canvas.Font.Color := clHighlightText else Canvas.Font.Color := Font.Color; end; end; DrawFormat := DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE; //todo_lcl See how Canvas.TextStyle should be //Canvas.TextFlags := 0; DoPaintText(Node, Canvas, Column, ttStatic); // Disabled node color overrides all other variants. if (vsDisabled in Node.States) or not Enabled then Canvas.Font.Color := FColors.DisabledColor; R := ContentRect; if Alignment = taRightJustify then Dec(R.Right, NodeWidth + FTextMargin) else Inc(R.Left, NodeWidth + FTextMargin); //todo_lcl_check if not Canvas.TextStyle.Opaque then SetBkMode(Canvas.Handle, TRANSPARENT) else SetBkMode(Canvas.Handle, OPAQUE); DrawText(Canvas.Handle, PChar(Text), Length(Text), R, DrawFormat) end; {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'PaintStaticText');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.SetDefaultText(const Value: String); begin if FDefaultText <> Value then begin FDefaultText := Value; if not (csLoading in ComponentState) then Invalidate; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.SetOptions(const Value: TCustomStringTreeOptions); begin FOptions.Assign(Value); end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.SetText(Node: PVirtualNode; Column: TColumnIndex; const Value: String); begin DoNewText(Node, Column, Value); InvalidateNode(Node); end; //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.CMFontChanged(var Msg: TLMessage); // Whenever a new font is applied to the tree some default values are determined to avoid frequent // determination of the same value. var MemDC: HDC; Run: PVirtualNode; TM: TTextMetric; Size: TSize; Data: PInteger; begin inherited; MemDC := CreateCompatibleDC(0); try SelectObject(MemDC, Font.Reference.Handle); GetTextMetrics(MemDC, TM); FTextHeight := TM.tmHeight; GetTextExtentPoint32(MemDC, '...', 3, Size); FEllipsisWidth := Size.cx; finally DeleteDC(MemDC); end; // Have to reset all node widths. Run := FRoot.FirstChild; while Assigned(Run) do begin Data := InternalData(Run); if Assigned(Data) then Data^ := 0; Run := GetNextNoInit(Run); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; out NextNonEmpty: TColumnIndex); // In the case a node spans several columns (if enabled) we need to determine how many columns. // Note: the autospan feature can only be used with left-to-right layout. begin if (toAutoSpanColumns in FOptions.FAutoOptions) and FHeader.UseColumns and (PaintInfo.BidiMode = bdLeftToRight) then with FHeader.FColumns, PaintInfo do begin // Start with the directly following column. NextNonEmpty := GetNextVisibleColumn(Column); // Auto spanning columns can only be used for left-to-right directionality because the tree is drawn // from left to right. For RTL directionality it would be necessary to draw it from right to left. // While this could be managed, it becomes impossible when directionality is mixed. repeat if (NextNonEmpty = InvalidColumn) or not ColumnIsEmpty(Node, NextNonEmpty) or (Items[NextNonEmpty].BidiMode <> bdLeftToRight) then Break; Inc(CellRect.Right, Items[NextNonEmpty].Width); NextNonEmpty := GetNextVisibleColumn(NextNonEmpty); until False; end else inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.CalculateTextWidth(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: String): Integer; // Determines the width of the given text. begin Result := 2 * FTextMargin; if Length(Text) > 0 then begin Canvas.Font := Font; DoPaintText(Node, Canvas, Column, ttNormal); Inc(Result, DoTextMeasuring(Canvas, Node, Column, Text)); end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.ColumnIsEmpty(Node: PVirtualNode; Column: TColumnIndex): Boolean; // For hit tests it is necessary to consider cases where columns are empty and automatic column spanning is enabled. // This method simply checks the given column's text and if this is empty then the column is considered as being empty. begin Result := Length(Text[Node, Column]) = 0; // If there is no text then let the ancestor decide if the column is to be considered as being empty // (e.g. by asking the application). If there is text then the column is never be considered as being empty. if Result then Result := inherited ColumnIsEmpty(Node, Column); end; //---------------------------------------------------------------------------------------------------------------------- {$ifndef LCLWin32} procedure TCustomVirtualStringTree.CopyToClipBoard; begin if FSelectionCount > 0 then begin MarkCutCopyNodes; DoStateChange([tsCopyPending]); Clipboard.AsText := ContentToUTF8(tstCutCopySet, #9); DoStateChange([], [tsCopyPending]); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.CutToClipBoard; begin //todo: currently there's no way in LCL to know when the clipboard was used CopyToClipBoard; end; {$endif} //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.DoCreateEditor(Node: PVirtualNode; Column: TColumnIndex): IVTEditLink; begin Result := inherited DoCreateEditor(Node, Column); // Enable generic label editing support if the application does not have own editors. if Result = nil then Result := TStringEditLink.Create; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.DoGetNodeHint(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; begin Result := inherited DoGetNodeHint(Node, Column, LineBreakStyle); if Assigned(FOnGetHint) then FOnGetHint(Self, Node, Column, LineBreakStyle, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.DoGetNodeTooltip(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; begin Result := inherited DoGetNodeToolTip(Node, Column, LineBreakStyle); if Assigned(FOnGetHint) then FOnGetHint(Self, Node, Column, LineBreakStyle, Result) else Result := Text[Node, Column]; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer; // Returns the text width of the given node in pixels. // This width is stored in the node's data member to increase access speed. var Data: PInteger; begin if (Column > NoColumn) and (vsMultiline in Node.States) then Result := FHeader.Columns[Column].Width else begin if Canvas = nil then Canvas := Self.Canvas; if Column = FHeader.MainColumn then begin // Primary column or no columns. Data := InternalData(Node); if Assigned(Data) then begin Result := Data^; if Result = 0 then begin Data^ := CalculateTextWidth(Canvas, Node, Column, Text[Node, Column]); Result := Data^; end; end else Result := 0; end else // any other column Result := CalculateTextWidth(Canvas, Node, Column, Text[Node, Column]); end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.DoGetText(Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var Text: String); begin if Assigned(FOnGetText) then FOnGetText(Self, Node, Column, TextType, Text); end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.DoIncrementalSearch(Node: PVirtualNode; const Text: String): Integer; // Since the string tree has access to node text it can do incremental search on its own. Use the event to // override the default behavior. begin Result := 0; if Assigned(FOnIncrementalSearch) then FOnIncrementalSearch(Self, Node, Text, Result) else // Default behavior is to match the search string with the start of the node text. if Pos(Text, GetText(Node, FocusedColumn)) <> 1 then Result := 1; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.DoNewText(Node: PVirtualNode; Column: TColumnIndex; const Text: String); begin if Assigned(FOnNewText) then FOnNewText(Self, Node, Column, Text); // The width might have changed, so update the scrollbar. if FUpdateCount = 0 then UpdateHorizontalScrollBar(True); end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.DoPaintNode(var PaintInfo: TVTPaintInfo); // Main output routine to print the text of the given node using the space provided in PaintInfo.ContentRect. var S: String; TextOutFlags: Integer; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'TCustomVirtualStringTree.DoPaintNode');{$endif} // Set a new OnChange event for the canvas' font so we know if the application changes it in the callbacks. // This long winded procedure is necessary because font changes (as well as brush and pen changes) are // unfortunately not announced via the Canvas.OnChange event. RedirectFontChangeEvent(PaintInfo.Canvas); // Determine main text direction as well as other text properties. TextOutFlags := ETO_CLIPPED or RTLFlag[PaintInfo.BidiMode <> bdLeftToRight]; S := Text[PaintInfo.Node, PaintInfo.Column]; // Paint the normal text first... if Length(S) > 0 then PaintNormalText(PaintInfo, TextOutFlags, S); // ... and afterwards the static text if not centered and the node is not multiline enabled. if (Alignment <> taCenter) and not (vsMultiline in PaintInfo.Node.States) and (toShowStaticText in TreeOptions.FStringOptions) then begin S := ''; with PaintInfo do DoGetText(Node, Column, ttStatic, S); if Length(S) > 0 then PaintStaticText(PaintInfo, TextOutFlags, S); end; RestoreFontChangeEvent(PaintInfo.Canvas); {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'TCustomVirtualStringTree.DoPaintNode');{$endif} end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.DoPaintText(Node: PVirtualNode; const Canvas: TCanvas; Column: TColumnIndex; TextType: TVSTTextType); begin if Assigned(FOnPaintText) then FOnPaintText(Self, Canvas, Node, Column, TextType); end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.DoShortenString(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const S: String; Width: Integer; EllipsisWidth: Integer = 0): String; var Done: Boolean; begin Done := False; if Assigned(FOnShortenString) then FOnShortenString(Self, Canvas, Node, Column, S, Width, Result, Done); if not Done then Result := ShortenString(Canvas.Handle, S, Width, EllipsisWidth); end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.DoTextDrawing(var PaintInfo: TVTPaintInfo; const Text: String; CellRect: TRect; DrawFormat: Cardinal); var DefaultDraw: Boolean; begin DefaultDraw := True; if Assigned(FOnDrawText) then FOnDrawText(Self, PaintInfo.Canvas, PaintInfo.Node, PaintInfo.Column, Text, CellRect, DefaultDraw); if DefaultDraw then DrawText(PaintInfo.Canvas.Handle, PChar(Text), Length(Text), CellRect, DrawFormat); end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.DoTextMeasuring(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: String): Integer; var Size: TSize; R: TRect; DrawFormat: Integer; begin GetTextExtentPoint32(Canvas.Handle, PChar(Text), Length(Text), Size); if vsMultiLine in Node.States then begin DrawFormat := DT_CALCRECT or DT_NOPREFIX or DT_WORDBREAK or DT_END_ELLIPSIS or DT_EDITCONTROL or AlignmentToDrawFlag[Alignment]; if BidiMode <> bdLeftToRight then DrawFormat := DrawFormat or DT_RTLREADING; R := Rect(0, 0, Size.cx, MaxInt); DrawText(Canvas.Handle, PChar(Text), Length(Text), R, DrawFormat); Size.cx := R.Right - R.Left; end; Result := Size.cx; if Assigned(FOnMeasureTextWidth) then FOnMeasureTextWidth(Self, Canvas, Node, Column, Text, Result); end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.GetOptionsClass: TTreeOptionsClass; begin Result := TCustomStringTreeOptions; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.InternalData(Node: PVirtualNode): Pointer; begin if (Node = FRoot) or (Node = nil) then Result := nil else Result := PByte(Node) + FInternalDataOffset; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.MainColumnChanged; var Run: PVirtualNode; Data: PInteger; begin inherited; // Have to reset all node widths. Run := FRoot.FirstChild; while Assigned(Run) do begin Data := InternalData(Run); if Assigned(Data) then Data^ := 0; Run := GetNextNoInit(Run); end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.ReadChunk(Stream: TStream; Version: Integer; Node: PVirtualNode; ChunkType, ChunkSize: Integer): Boolean; // read in the caption chunk if there is one var NewText: String; begin case ChunkType of CaptionChunk: begin NewText := ''; if ChunkSize > 0 then begin SetLength(NewText, ChunkSize); Stream.Read(PChar(NewText)^, ChunkSize); end; // Do a new text event regardless of the caption content to allow removing the default string. Text[Node, FHeader.MainColumn] := NewText; Result := True; end; else Result := inherited ReadChunk(Stream, Version, Node, ChunkType, ChunkSize); end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; // Returns string expressions of all currently selected nodes in the Medium structure. begin Result := inherited RenderOLEData(FormatEtcIn, Medium, ForClipboard); if Failed(Result) then try if ForClipboard then Medium.hGlobal := ContentToClipboard(FormatEtcIn.cfFormat, tstCutCopySet) else Medium.hGlobal := ContentToClipboard(FormatEtcIn.cfFormat, tstSelected); // Fill rest of the Medium structure if rendering went fine. if Medium.hGlobal <> 0 then begin Medium.tymed := TYMED_HGLOBAL; Medium.PunkForRelease := nil; Result := S_OK; end; except Result := E_FAIL; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.WriteChunks(Stream: TStream; Node: PVirtualNode); // Adds another sibling chunk for Node storing the label if the node is initialized. // Note: If the application stores a node's caption in the node's data member (which will be quite common) and needs to // store more node specific data then it should use the OnSaveNode event rather than the caption autosave function // (take out soSaveCaption from StringOptions). Otherwise the caption is unnecessarily stored twice. var Header: TChunkHeader; S: String; Len: Integer; begin inherited; if (toSaveCaptions in TreeOptions.FStringOptions) and (Node <> FRoot) and (vsInitialized in Node.States) then with Stream do begin // Read the node's caption (primary column only). S := Text[Node, FHeader.MainColumn]; Len := Length(S); if Len > 0 then begin // Write a new sub chunk. Header.ChunkType := CaptionChunk; Header.ChunkSize := Len; Write(Header, SizeOf(Header)); Write(PChar(S)^, Len); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.ComputeNodeHeight(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; S: String): Integer; // Default node height calculation for multi line nodes. This method can be used by the application to delegate the // computation to the string tree. // Canvas is used to compute that value by using its current font settings. // Node and Column describe the cell to be used for the computation. // S is the string for which the height must be computed. If this string is empty the cell text is used instead. var DrawFormat: Cardinal; BidiMode: TBidiMode; Alignment: TAlignment; PaintInfo: TVTPaintInfo; Dummy: TColumnIndex; LineImage: TLineImage; begin if Length(S) = 0 then S := Text[Node, Column]; DrawFormat := DT_TOP or DT_NOPREFIX or DT_CALCRECT or DT_WORDBREAK; if Column <= NoColumn then begin BidiMode := Self.BidiMode; Alignment := Self.Alignment; end else begin BidiMode := Header.Columns[Column].BidiMode; Alignment := Header.Columns[Column].Alignment; end; if BidiMode <> bdLeftToRight then ChangeBidiModeAlignment(Alignment); // Allow for autospanning. PaintInfo.Node := Node; PaintInfo.BidiMode := BidiMode; PaintInfo.Column := Column; PaintInfo.CellRect := Rect(0, 0, 0, 0); if Column > NoColumn then begin PaintInfo.CellRect.Right := FHeader.Columns[Column].Width - FTextMargin; PaintInfo.CellRect.Left := FTextMargin + FMargin; if Column = Header.MainColumn then begin if toFixedIndent in FOptions.FPaintOptions then SetLength(LineImage, 1) else DetermineLineImageAndSelectLevel(Node, LineImage); Inc(PaintInfo.CellRect.Left, Length(LineImage) * Integer(Indent)); end; end else PaintInfo.CellRect.Right := ClientWidth; AdjustPaintCellRect(PaintInfo, Dummy); if BidiMode <> bdLeftToRight then DrawFormat := DrawFormat or DT_RIGHT or DT_RTLREADING else DrawFormat := DrawFormat or DT_LEFT; DrawText(Canvas.Handle, PChar(S), Length(S), PaintInfo.CellRect, DrawFormat); Result := PaintInfo.CellRect.Bottom - PaintInfo.CellRect.Top; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.ContentToHTML(Source: TVSTTextSourceType; const Caption: String = ''): String; // Renders the current tree content (depending on Source) as HTML text encoded in UTF-8. // If Caption is not empty then it is used to create and fill the header for the table built here. // Based on ideas and code from Frank van den Bergh and Andreas H?rstemeier. var Buffer: TBufferedUTF8String; //--------------------------------------------------------------------------- procedure WriteColorAsHex(Color: TColor); var WinColor: COLORREF; I: Integer; Component, Value: Byte; begin Buffer.Add('#'); WinColor := ColorToRGB(Color); I := 1; while I <= 6 do begin Component := WinColor and $FF; Value := 48 + (Component shr 4); if Value > $39 then Inc(Value, 7); Buffer.Add(AnsiChar(Value)); Inc(I); Value := 48 + (Component and $F); if Value > $39 then Inc(Value, 7); Buffer.Add(AnsiChar(Value)); Inc(I); WinColor := WinColor shr 8; end; end; //--------------------------------------------------------------------------- procedure WriteStyle(const Name: AnsiString; Font: TFont); // Creates a CSS style entry with the given name for the given font. // If Name is empty then the entry is created as inline style. begin if Length(Name) = 0 then Buffer.Add(' style="{font:') else begin Buffer.Add('.'); Buffer.Add(Name); Buffer.Add('{font:'); end; if fsUnderline in Font.Style then Buffer.Add(' underline'); if fsItalic in Font.Style then Buffer.Add(' italic'); if fsBold in Font.Style then Buffer.Add(' bold'); if Font.Size < 0 then Buffer.Add(Format(' %dpx "%s";', [Font.Height, Font.Name])) else Buffer.Add(Format(' %dpt "%s";', [Font.Size, Font.Name])); Buffer.Add('color:'); WriteColorAsHex(Font.Color); Buffer.Add(';}'); if Length(Name) = 0 then Buffer.Add('"'); end; //--------------- end local functions --------------------------------------- var I, J : Integer; Level, MaxLevel: Cardinal; AddHeader: String; Save, Run: PVirtualNode; GetNextNode: TGetNextNodeProc; Text: String; RenderColumns: Boolean; Columns: TColumnsArray; ColumnColors: array of String; Index: Integer; IndentWidth, LineStyleText: String; Alignment: TAlignment; BidiMode: TBidiMode; CellPadding: String; begin Buffer := TBufferedUTF8String.Create; try // For customization by the application or descendants we use again the redirected font change event. RedirectFontChangeEvent(Canvas); CellPadding := Format('padding-left:%dpx;padding-right:%0:dpx;', [FMargin]); IndentWidth := IntToStr(FIndent); AddHeader := ' '; // Add title if adviced so by giving a caption. if Length(Caption) > 0 then AddHeader := AddHeader + 'caption="' + Caption + '"'; if Borderstyle <> bsNone then AddHeader := AddHeader + Format(' border="%d" frame=box', [BorderWidth + 1]); Buffer.Add(''); // Create HTML table based on the tree structure. To simplify formatting we use styles defined in a small CSS area. Buffer.Add(''); Buffer.AddNewLine; // General table properties. Buffer.Add(''); Buffer.AddNewLine; Columns := nil; ColumnColors := nil; RenderColumns := FHeader.UseColumns; if RenderColumns then begin Columns := FHeader.FColumns.GetVisibleColumns; SetLength(ColumnColors, Length(Columns)); end; GetRenderStartValues(Source, Run, GetNextNode); Save := Run; MaxLevel := 0; // The table consists of visible columns and rows as used in the tree, but the main tree column is splitted // into several HTML columns to accomodate the indentation. while Assigned(Run) do begin if (CanExportNode(Run)) then begin Level := GetNodeLevel(Run); if Level > MaxLevel then MaxLevel := Level; end; Run := GetNextNode(Run); end; if RenderColumns then begin if Assigned(FOnBeforeHeaderExport) then FOnBeforeHeaderExport(Self, etHTML); Buffer.Add(''); Buffer.AddNewLine; // Make the first row in the HTML table an image of the tree header. for I := 0 to High(Columns) do begin if Assigned(FOnBeforeColumnExport) then FOnBeforeColumnExport(Self, etHTML, Columns[I]); Buffer.Add(''); if Assigned(FOnAfterColumnExport) then FOnAfterColumnExport(Self, etHTML, Columns[I]); end; Buffer.Add(''); Buffer.AddNewLine; if Assigned(FOnAfterHeaderExport) then FOnAfterHeaderExport(self, etHTML); end; // Now go through the tree. Run := Save; while Assigned(Run) do begin if ((not CanExportNode(Run)) or (Assigned(FonBeforeNodeExport) and (not FOnBeforeNodeExport(Self, etHTML, Run)))) then begin Run := GetNextNode(Run); Continue; end; Level := GetNodeLevel(Run); Buffer.Add(' '); Buffer.AddNewLine; I := 0; while (I < Length(Columns)) or not RenderColumns do begin if RenderColumns then Index := Columns[I].Index else Index := NoColumn; if not RenderColumns or (coVisible in Columns[I].FOptions) then begin // Call back the application to know about font customization. Canvas.Font := Font; FFontChanged := False; DoPaintText(Run, Canvas, Index, ttNormal); if Index = Header.MainColumn then begin // Create a cell for each indentation level. if RenderColumns and not (coParentColor in Columns[I].FOptions) then begin for J := 1 to Level do begin Buffer.Add(''); end; end else begin for J := 1 to Level do if J = 1 then begin Buffer.Add(' '); end else Buffer.Add(' '); end; end; if FFontChanged then begin Buffer.Add(' '); end; if not RenderColumns then Break; Inc(I); end; if Assigned(FOnAfterNodeExport) then FOnAfterNodeExport(Self, etHTML, Run); Run := GetNextNode(Run); Buffer.Add(' '); Buffer.AddNewLine; end; Buffer.Add('
    bdLeftToRight then begin ChangeBidiModeAlignment(Alignment); Buffer.Add(' dir="rtl"'); end; // Consider aligment. case Alignment of taRightJustify: Buffer.Add(' align=right'); taCenter: Buffer.Add(' align=center'); else Buffer.Add(' align=left'); end; Index := Columns[I].Index; // Merge cells of the header emulation in the main column. if (MaxLevel > 0) and (Index = Header.MainColumn) then begin Buffer.Add(' colspan="'); Buffer.Add(IntToStr(MaxLevel + 1)); Buffer.Add('"'); end; // The color of the header is usually clBtnFace. Buffer.Add(' bgcolor='); WriteColorAsHex(clBtnFace); // Set column width in pixels. Buffer.Add(' width="'); Buffer.Add(IntToStr(Columns[I].Width)); Buffer.Add('px">'); if Length(Columns[I].Text) > 0 then Buffer.Add(Columns[I].Text); Buffer.Add('
        bdLeftToRight then begin ChangeBidiModeAlignment(Alignment); Buffer.Add(' dir="rtl"'); end; // Consider aligment. case Alignment of taRightJustify: Buffer.Add(' align=right'); taCenter: Buffer.Add(' align=center'); else Buffer.Add(' align=left'); end; // Merge cells in the main column. if (MaxLevel > 0) and (Index = FHeader.MainColumn) and (Level < MaxLevel) then begin Buffer.Add(' colspan="'); Buffer.Add(IntToStr(MaxLevel - Level + 1)); Buffer.Add('"'); end; if RenderColumns and not (coParentColor in Columns[I].FOptions) then begin Buffer.Add(' bgcolor='); WriteColorAsHex(Columns[I].Color); end; Buffer.Add('>'); Text := Self.Text[Run, Index]; if Length(Text) > 0 then Buffer.Add(Text); Buffer.Add('
    '); RestoreFontChangeEvent(Canvas); Result := Buffer.AsUTF8String; finally Buffer.Free; end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.CanExportNode(Node: PVirtualNode ): Boolean; begin Result := True; case FOptions.ExportMode of emChecked: Result := Node.CheckState = csCheckedNormal; emUnchecked: Result := Node.CheckState = csUncheckedNormal; end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.ContentToRTF(Source: TVSTTextSourceType): AnsiString; // Renders the current tree content (depending on Source) as RTF (rich text). // Based on ideas and code from Frank van den Bergh and Andreas H?rstemeier. var Fonts: TStringList; Colors: TFpList; CurrentFontIndex, CurrentFontColor, CurrentFontSize: Integer; Buffer: TBufferedUTF8String; //--------------- local functions ------------------------------------------- procedure SelectFont(Font: string); var I: Integer; begin I := Fonts.IndexOf(Font); if I > -1 then begin // Font has already been used if I <> CurrentFontIndex then begin Buffer.Add('\f'); Buffer.Add(IntToStr(I)); CurrentFontIndex := I; end; end else begin I := Fonts.Add(Font); Buffer.Add('\f'); Buffer.Add(IntToStr(I)); CurrentFontIndex := I; end; end; //--------------------------------------------------------------------------- procedure SelectColor(Color: TColor); var I: Integer; begin I := Colors.IndexOf(Pointer(Color)); if I > -1 then begin // Color has already been used if I <> CurrentFontColor then begin Buffer.Add('\cf'); Buffer.Add(IntToStr(I + 1)); CurrentFontColor := I; end; end else begin I := Colors.Add(Pointer(Color)); Buffer.Add('\cf'); Buffer.Add(IntToStr(I + 1)); CurrentFontColor := I; end; end; //--------------------------------------------------------------------------- procedure TextPlusFont(const Text: String; Font: TFont); var UseUnderline, UseItalic, UseBold: Boolean; I: Integer; WText: UnicodeString; begin if Length(Text) > 0 then begin WText := UTF8Decode(Text); UseUnderline := fsUnderline in Font.Style; if UseUnderline then Buffer.Add('\ul'); UseItalic := fsItalic in Font.Style; if UseItalic then Buffer.Add('\i'); UseBold := fsBold in Font.Style; if UseBold then Buffer.Add('\b'); SelectFont(Font.Name); SelectColor(Font.Color); if Font.Size <> CurrentFontSize then begin // Font size must be given in half points. Buffer.Add('\fs'); Buffer.Add(IntToStr(2 * Font.Size)); CurrentFontSize := Font.Size; end; // Use escape sequences to note Unicode text. Buffer.Add(' '); // Note: Unicode values > 32767 must be expressed as negative numbers. This is implicitly done // by interpreting the wide chars (word values) as small integers. for I := 1 to Length(WText) do begin if (Text[I] = WideLF) then Buffer.Add( '{\par}' ) else if (Text[i] <> WideCR) then begin Buffer.Add(Format('\u%d\''3f', [SmallInt(WText[I])])); Continue; end; end; if UseUnderline then Buffer.Add('\ul0'); if UseItalic then Buffer.Add('\i0'); if UseBold then Buffer.Add('\b0'); end; end; //--------------- end local functions --------------------------------------- var Level, LastLevel: Integer; I, J: Integer; Save, Run: PVirtualNode; GetNextNode: TGetNextNodeProc; S, Tabs : String; Text: String; Twips: Integer; RenderColumns: Boolean; Columns: TColumnsArray; Index: Integer; Alignment: TAlignment; BidiMode: TBidiMode; begin Buffer := TBufferedUTF8String.Create; try // For customization by the application or descendants we use again the redirected font change event. RedirectFontChangeEvent(Canvas); Fonts := TStringList.Create; Colors := TFpList.Create; CurrentFontIndex := -1; CurrentFontColor := -1; CurrentFontSize := -1; Columns := nil; Tabs := ''; LastLevel := 0; RenderColumns := FHeader.UseColumns; if RenderColumns then Columns := FHeader.FColumns.GetVisibleColumns; GetRenderStartValues(Source, Run, GetNextNode); Save := Run; // First make a table structure. The \rtf and other header stuff is included // when the font and color tables are created. Buffer.Add('\uc1\trowd\trgaph70'); J := 0; if RenderColumns then begin for I := 0 to High(Columns) do begin Inc(J, Columns[I].Width); // This value must be expressed in twips (1 inch = 1440 twips). Twips := Round(1440 * J / Screen.PixelsPerInch); Buffer.Add('\cellx'); Buffer.Add(IntToStr(Twips)); end; end else begin Twips := Round(1440 * ClientWidth / Screen.PixelsPerInch); Buffer.Add('\cellx'); Buffer.Add(IntToStr(Twips)); end; // Fill table header. if RenderColumns then begin if Assigned(FOnBeforeHeaderExport) then FonBeforeHeaderExport(Self, etRTF); Buffer.Add('\pard\intbl'); for I := 0 to High(Columns) do begin if Assigned(FOnBeforeColumnExport) then FOnBeforeColumnExport(Self, etRTF, Columns[I]); Alignment := Columns[I].CaptionAlignment; BidiMode := Columns[I].BidiMode; // Alignment is not supported with older RTF formats, however it will be ignored. if BidiMode <> bdLeftToRight then ChangeBidiModeAlignment(Alignment); case Alignment of taRightJustify: Buffer.Add('\qr'); taCenter: Buffer.Add('\qc'); end; TextPlusFont(Columns[I].Text, Header.Font); Buffer.Add('\cell'); if Assigned(FOnAfterColumnExport) then FOnAfterColumnExport( self, etRTF, Columns[I] ); end; Buffer.Add('\row'); if Assigned(FOnAfterHeaderExport) then FOnAfterHeaderExport(Self, etRTF); end; // Now write the contents. Run := Save; while Assigned(Run) do begin if ((not CanExportNode(Run)) or (Assigned(FOnBeforeNodeExport) and (not FOnBeforeNodeExport(Self, etRTF, Run)))) then begin Run := GetNextNode(Run); Continue; end; I := 0; while not RenderColumns or (I < Length(Columns)) do begin if RenderColumns then begin Index := Columns[I].Index; Alignment := Columns[I].Alignment; BidiMode := Columns[I].BidiMode; end else begin Index := NoColumn; Alignment := FAlignment; BidiMode := Self.BidiMode; end; if not RenderColumns or (coVisible in Columns[I].Options) then begin Text := Self.Text[Run, Index]; Buffer.Add('\pard\intbl'); // Alignment is not supported with older RTF formats, however it will be ignored. if BidiMode <> bdLeftToRight then ChangeBidiModeAlignment(Alignment); case Alignment of taRightJustify: Buffer.Add('\qr'); taCenter: Buffer.Add('\qc'); end; // Call back the application to know about font customization. Canvas.Font := Font; FFontChanged := False; DoPaintText(Run, Canvas, Index, ttNormal); if Index = Header.MainColumn then begin Level := GetNodeLevel(Run); if Level <> LastLevel then begin LastLevel := Level; Tabs := ''; for J := 0 to Level - 1 do Tabs := Tabs + '\tab'; end; if Level > 0 then begin Buffer.Add(Tabs); Buffer.Add(' '); TextPlusFont(Text, Canvas.Font); Buffer.Add('\cell'); end else begin TextPlusFont(Text, Canvas.Font); Buffer.Add('\cell'); end; end else begin TextPlusFont(Text, Canvas.Font); Buffer.Add('\cell'); end; end; if not RenderColumns then Break; Inc(I); end; Buffer.Add('\row'); if (Assigned(FOnAfterNodeExport)) then FOnAfterNodeExport(Self, etRTF, Run); Run := GetNextNode(Run); end; Buffer.Add('\pard\par'); // Build lists with fonts and colors. They have to be at the start of the document. S := '{\rtf1\ansi\ansicpg1252\deff0\deflang1043{\fonttbl'; for I := 0 to Fonts.Count - 1 do S := S + Format('{\f%d %s;}', [I, Fonts[I]]); S := S + '}'; S := S + '{\colortbl;'; for I := 0 to Colors.Count - 1 do begin J := ColorToRGB(TColor(Colors[I])); S := S + Format('\red%d\green%d\blue%d;', [J and $FF, (J shr 8) and $FF, (J shr 16) and $FF]); end; S := S + '}'; Result := S + Buffer.AsAnsiString + '}'; Fonts.Free; Colors.Free; RestoreFontChangeEvent(Canvas); finally Buffer.Free; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.ContentToCustom(Source: TVSTTextSourceType); // Generic export procedure which polls the application at every stage of the export. var I: Integer; Save, Run: PVirtualNode; GetNextNode: TGetNextNodeProc; RenderColumns: Boolean; Columns: TColumnsArray; begin Columns := nil; GetRenderStartValues(Source, Run, GetNextNode); Save := Run; RenderColumns := FHeader.UseColumns and ( hoVisible in FHeader.Options ); if Assigned(FOnBeforeTreeExport) then FOnBeforeTreeExport(Self, etCustom); // Fill table header. if RenderColumns then begin if Assigned(FOnBeforeHeaderExport) then FOnBeforeHeaderExport(Self, etCustom); Columns := FHeader.FColumns.GetVisibleColumns; for I := 0 to High(Columns) do begin if Assigned(FOnBeforeColumnExport) then FOnBeforeColumnExport(Self, etCustom, Columns[I]); if Assigned(FOnColumnExport) then FOnColumnExport(Self, etCustom, Columns[I]); if Assigned(FOnAfterColumnExport) then FOnAfterColumnExport(Self, etCustom, Columns[I]); end; if Assigned(FOnAfterHeaderExport) then FOnAfterHeaderExport(Self, etCustom); end; // Now write the content. Run := Save; while Assigned(Run) do begin if CanExportNode(Run) then begin if Assigned(FOnBeforeNodeExport) then FOnBeforeNodeExport(Self, etCustom, Run); if Assigned(FOnNodeExport) then FOnNodeExport(Self, etCustom, Run); if Assigned(FOnAfterNodeExport) then FOnAfterNodeExport(Self, etCustom, Run); end; Run := GetNextNode(Run); end; if Assigned(FOnAfterTreeExport) then FOnAfterTreeExport(Self, etCustom); end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.ContentToAnsi(Source: TVSTTextSourceType; const Separator: String): AnsiString; var Buffer: TBufferedUTF8String; begin Buffer := TBufferedUTF8String.Create; try AddContentToBuffer(Buffer, Source, Separator); finally Result := Buffer.AsAnsiString; Buffer.Destroy; end; end; function TCustomVirtualStringTree.ContentToText(Source: TVSTTextSourceType; const Separator: String): AnsiString; begin Result := ContentToAnsi(Source, Separator); end; function TCustomVirtualStringTree.ContentToUnicode(Source: TVSTTextSourceType; const Separator: String): UnicodeString; begin Result := ContentToUTF16(Source, Separator); end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.AddContentToBuffer(Buffer: TBufferedUTF8String; Source: TVSTTextSourceType; const Separator: String); // Renders the current tree content (depending on Source) as UTF8 text. // If an entry contains the separator char or double quotes then it is wrapped with double quotes // and existing double quotes are duplicated. var RenderColumns: Boolean; Tabs: String; GetNextNode: TGetNextNodeProc; Run, Save: PVirtualNode; Level, MaxLevel: Cardinal; Columns: TColumnsArray; LastColumn: TVirtualTreeColumn; Index, I: Integer; Text: String; begin Columns := nil; RenderColumns := FHeader.UseColumns; if RenderColumns then Columns := FHeader.FColumns.GetVisibleColumns; GetRenderStartValues(Source, Run, GetNextNode); Save := Run; // The text consists of visible groups representing the columns, which are separated by one or more separator // characters. There are always MaxLevel separator chars in a line (main column only). Either before the caption // to ident it or after the caption to make the following column aligned. MaxLevel := 0; while Assigned(Run) do begin Level := GetNodeLevel(Run); If Level > MaxLevel then MaxLevel := Level; Run := GetNextNode(Run); end; Tabs := DupeString(Separator, MaxLevel); // First line is always the header if used. if RenderColumns then begin LastColumn := Columns[High(Columns)]; for I := 0 to High(Columns) do begin Buffer.Add(Columns[I].Text); if Columns[I] <> LastColumn then begin if Columns[I].Index = Header.MainColumn then begin Buffer.Add(Tabs); Buffer.Add(Separator); end else Buffer.Add(Separator); end; end; Buffer.AddNewLine; end else LastColumn := nil; Run := Save; if RenderColumns then begin while Assigned(Run) do begin if (not CanExportNode(Run) or (Assigned(FOnBeforeNodeExport) and (not FOnBeforeNodeExport(Self, etText, Run)))) then begin Run := GetNextNode(Run); Continue; end; for I := 0 to High(Columns) do begin if coVisible in Columns[I].Options then begin Index := Columns[I].Index; // This line implicitly converts the Unicode text to ANSI. Text := Self.Text[Run, Index]; if Index = Header.MainColumn then begin Level := GetNodeLevel(Run); Buffer.Add(Copy(Tabs, 1, Integer(Level) * Length(Separator))); // Wrap the text with quotation marks if it contains the separator character. if (Pos(Separator, Text) > 0) or (Pos('"', Text) > 0) then Buffer.Add(AnsiQuotedStr(Text, '"')) else Buffer.Add(Text); Buffer.Add(Copy(Tabs, 1, Integer(MaxLevel - Level) * Length(Separator))); end else if (Pos(Separator, Text) > 0) or (Pos('"', Text) > 0) then Buffer.Add(AnsiQuotedStr(Text, '"')) else Buffer.Add(Text); if Columns[I] <> LastColumn then Buffer.Add(Separator); end; end; if Assigned(FOnAfterNodeExport) then FOnAfterNodeExport(Self, etText, Run); Run := GetNextNode(Run); Buffer.AddNewLine; end; end else begin while Assigned(Run) do begin if ((not CanExportNode(Run)) or (Assigned(FOnBeforeNodeExport) and (not FOnBeforeNodeExport(Self, etText, Run)))) then begin Run := GetNextNode(Run); Continue; end; // This line implicitly converts the Unicode text to ANSI. Text := Self.Text[Run, NoColumn]; Level := GetNodeLevel(Run); Buffer.Add(Copy(Tabs, 1, Integer(Level) * Length(Separator))); Buffer.Add(Text); Buffer.AddNewLine; if Assigned(FOnAfterNodeExport) then FonAfterNodeExport(Self, etText, Run); Run := GetNextNode(Run); end; end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.ContentToUTF16(Source: TVSTTextSourceType; const Separator: String): UnicodeString; var Buffer: TBufferedUTF8String; begin Buffer := TBufferedUTF8String.Create; try AddContentToBuffer(Buffer, Source, Separator); finally Result := Buffer.AsUTF16String; Buffer.Destroy; end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.ContentToUTF8(Source: TVSTTextSourceType; const Separator: String): String; var Buffer: TBufferedUTF8String; begin Buffer := TBufferedUTF8String.Create; try AddContentToBuffer(Buffer, Source, Separator); finally Result := Buffer.AsUTF8String; Buffer.Destroy; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.GetTextInfo(Node: PVirtualNode; Column: TColumnIndex; const AFont: TFont; var R: TRect; out Text: String); // Returns the font, the text and its bounding rectangle to the caller. R is returned as the closest // bounding rectangle around Text. var NewHeight: Integer; TM: TTextMetric; begin // Get default font and initialize the other parameters. //inherited GetTextInfo(Node, Column, AFont, R, Text); Canvas.Font := AFont; FFontChanged := False; RedirectFontChangeEvent(Canvas); DoPaintText(Node, Canvas, Column, ttNormal); if FFontChanged then begin AFont.Assign(Canvas.Font); GetTextMetrics(Canvas.Handle, TM); NewHeight := TM.tmHeight; end else // Otherwise the correct font is already there and we only need to set the correct height. NewHeight := FTextHeight; RestoreFontChangeEvent(Canvas); // Alignment to the actual text. Text := Self.Text[Node, Column]; R := GetDisplayRect(Node, Column, True, not (vsMultiline in Node.States)); if toShowHorzGridLines in TreeOptions.PaintOptions then Dec(R.Bottom); InflateRect(R, 0, -(R.Bottom - R.Top - NewHeight) div 2); end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.InvalidateNode(Node: PVirtualNode): TRect; var Data: PInteger; begin Result := inherited InvalidateNode(Node); // Reset node width so changed text attributes are applied correctly. if Assigned(Node) then begin Data := InternalData(Node); if Assigned(Data) then Data^ := 0; // Reset height measured flag too to cause a re-issue of the OnMeasureItem event. Exclude(Node.States, vsHeightMeasured); end; end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualStringTree.Path(Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; Delimiter: Char): String; // Constructs a string containing the node and all its parents. The last character in the returned path is always the // given delimiter. var S: String; begin if (Node = nil) or (Node = FRoot) then Result := Delimiter else begin Result := ''; while Node <> FRoot do begin DoGetText(Node, Column, TextType, S); Result := S + Delimiter + Result; Node := Node.Parent; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.ReinitNode(Node: PVirtualNode; Recursive: Boolean); var Data: PInteger; begin inherited; // Reset node width so changed text attributes are applied correctly. if Assigned(Node) and (Node <> FRoot) then begin Data := InternalData(Node); if Assigned(Data) then Data^ := 0; // vsHeightMeasured is already removed in the base tree. end; end; //----------------- TVirtualStringTree --------------------------------------------------------------------------------- function TVirtualStringTree.GetOptions: TStringTreeOptions; begin Result := FOptions as TStringTreeOptions; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualStringTree.SetOptions(const Value: TStringTreeOptions); begin FOptions.Assign(Value); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualStringTree.GetOptionsClass: TTreeOptionsClass; begin Result := TStringTreeOptions; end; //----------------- TCustomVirtualDrawTree ----------------------------------------------------------------------------- procedure TCustomVirtualDrawTree.DoDrawHint(Canvas: TCanvas; Node: PVirtualNode; const R: TRect; Column: TColumnIndex); begin if Assigned(FOnDrawHint) then FOnDrawHint(Self, Canvas, Node, R, Column); end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualDrawTree.DoGetCellContentMargin(Node: PVirtualNode; Column: TColumnIndex; CellContentMarginType: TVTCellContentMarginType = ccmtAllSides; Canvas: TCanvas = nil): TPoint; begin Result := Point(0, 0); if Canvas = nil then Canvas := Self.Canvas; if Assigned(FOnGetCellContentMargin) then FOnGetCellContentMargin(Self, Canvas, Node, Column, CellContentMarginType, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualDrawTree.DoGetHintSize(Node: PVirtualNode; Column: TColumnIndex; var R: TRect); begin if Assigned(FOnGetHintSize) then FOnGetHintSize(Self, Node, Column, R); end; //---------------------------------------------------------------------------------------------------------------------- function TCustomVirtualDrawTree.DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer; begin Result := 2 * FTextMargin; if Canvas = nil then Canvas := Self.Canvas; if Assigned(FOnGetNodeWidth) then FOnGetNodeWidth(Self, Canvas, Node, Column, Result); end; //---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualDrawTree.DoPaintNode(var PaintInfo: TVTPaintInfo); begin if Assigned(FOnDrawNode) then FOnDrawNode(Self, PaintInfo); end; //----------------- TVirtualDrawTree ----------------------------------------------------------------------------------- function TVirtualDrawTree.GetOptions: TVirtualTreeOptions; begin Result := FOptions as TVirtualTreeOptions; end; //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualDrawTree.SetOptions(const Value: TVirtualTreeOptions); begin FOptions.Assign(Value); end; //---------------------------------------------------------------------------------------------------------------------- function TVirtualDrawTree.GetOptionsClass: TTreeOptionsClass; begin Result := TVirtualTreeOptions; end; //---------------------------------------------------------------------------------------------------------------------- initialization {$I virtualtrees.lrs} // Necessary for dynamic package loading. Initialized := False; NeedToUnitialize := False; finalization if Initialized then FinalizeGlobalStructures; InternalClipboardFormats.Free; InternalClipboardFormats := nil; {$ifdef EnableAccessible} if VTAccessibleFactory <> nil then begin VTAccessibleFactory.Free; VTAccessibleFactory := nil; end; {$endif} end. doublecmd-0.8.2/components/KASToolBar/0000775000175000017500000000000013244011205016563 5ustar alexxalexxdoublecmd-0.8.2/components/KASToolBar/kascomp.pas0000664000175000017500000000111012677725617020752 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit KASComp; interface uses KASToolBar, KASProgressBar, KASPathEdit, KASToolItems, KASComboBox, LazarusPackageIntf; implementation procedure Register; begin RegisterUnit('KASToolBar', @KASToolBar.Register); RegisterUnit('KASProgressBar', @KASProgressBar.Register); RegisterUnit('KASPathEdit', @KASPathEdit.Register); RegisterUnit('KASComboBox', @KASComboBox.Register); end; initialization RegisterPackage('KASComp', @Register); end. doublecmd-0.8.2/components/KASToolBar/kasprogressbar.pas0000664000175000017500000001131512014201074022320 0ustar alexxalexx{ Double Commander Components ------------------------------------------------------------------------- Extended ProgressBar class Copyright (C) 2010 Przemyslaw Nagay (cobines@gmail.com) Copyright (C) 2011-2012 Koblov Alexander (Alexx2000@mail.ru) Windows 7 implementation based on "Windows 7 Component Library" by Daniel Wischnewski (http://www.gumpi.com/blog) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in a file called COPYING along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. } unit KASProgressBar; {$mode objfpc}{$H+} interface uses LCLType, Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ComCtrls {$IFDEF LCLWIN32} , InterfaceBase, ComObj, dwTaskbarList {$ENDIF} {$IFDEF LCLGTK2} , Gtk2 {$ENDIF} {$IFDEF LCLQT} , qt4, qtwidgets {$ENDIF} ; type { TKASProgressBar } TKASProgressBar = class(TProgressBar) private FShowInTaskbar: Boolean; {$IFDEF LCLWIN32} FTaskBarEntryHandle: HWND; FTaskbarList: ITaskbarList; FTaskbarList3: ITaskbarList3; {$ENDIF} protected {$IFDEF LCLWIN32} procedure InitializeWnd; override; {$ENDIF} procedure DoOnResize; override; public constructor Create(AOwner: TComponent); override; procedure SetProgress(CurrentValue: Int64; MaxValue: Int64; BarText: String = ''); published property ShowInTaskbar: Boolean read FShowInTaskbar write FShowInTaskbar default False; end; procedure Register; implementation procedure Register; begin RegisterComponents('KASComponents',[TKASProgressBar]); end; { TKASProgressBar } {$IFDEF LCLWIN32} procedure TKASProgressBar.InitializeWnd; var aOwnerForm: TWinControl; begin inherited InitializeWnd; if CheckWin32Version(6, 1) then begin aOwnerForm:= GetParentForm(Self); if Assigned(aOwnerForm) and (aOwnerForm <> Application.MainForm) then FTaskBarEntryHandle := aOwnerForm.Handle else FTaskBarEntryHandle := Widgetset.AppHandle; end; end; {$ENDIF} procedure TKASProgressBar.DoOnResize; begin inherited; Max := Width; end; constructor TKASProgressBar.Create(AOwner: TComponent); begin inherited Create(AOwner); {$IFDEF LCLWIN32} FTaskbarList3 := nil; FTaskBarEntryHandle := INVALID_HANDLE_VALUE; // Works only under Windows 7 and higher if CheckWin32Version(6, 1) then try FTaskbarList := ITaskbarList(CreateComObject(CLSID_TaskbarList)); FTaskbarList.HrInit; FTaskbarList.QueryInterface(CLSID_TaskbarList3, FTaskbarList3); except FTaskbarList3 := nil; end; {$ENDIF} {$IFDEF LCLGTK2} // Have to disable LCLGTK2 default progress bar text // set in TGtk2WSProgressBar.UpdateProgressBarText. BarShowText := False; {$ENDIF} end; procedure TKASProgressBar.SetProgress(CurrentValue: Int64; MaxValue: Int64; BarText: String); {$IFDEF LCLGTK2} var wText: String; {$ENDIF} {$IFDEF LCLQT} var wText: WideString; {$ENDIF} begin if MaxValue <> 0 then Position := Round(CurrentValue * Max / MaxValue) else Position := 0; {$IFDEF LCLWIN32} if FShowInTaskbar and (FTaskBarEntryHandle <> INVALID_HANDLE_VALUE) and Assigned(FTaskbarList3) then begin FTaskbarList3.SetProgressValue(FTaskBarEntryHandle, Position, Max); end; {$ENDIF} {$IFDEF LCLGTK2} { %v - the current progress value. %l - the lower bound for the progress value. %u - the upper bound for the progress value. %p - the current progress percentage. } if BarText <> '' then wText := BarText + ' (%p%%)' else wText := '%p%%'; gtk_progress_set_format_string(PGtkProgress(Self.Handle), PChar(wText)); // Have to reset 'show_text' every time because LCLGTK2 will set it according to BarShowText. gtk_progress_set_show_text(PGtkProgress(Self.Handle), True); {$ENDIF} {$IFDEF LCLQT} { %p - is replaced by the percentage completed. %v - is replaced by the current value. %m - is replaced by the total number of steps. } if BarText <> '' then wText := WideString(BarText) + ' (%p%)' else wText := '%p%'; QProgressBar_setFormat(QProgressBarH(TQtProgressBar(Self.Handle).Widget), @wText); //QProgressBar_setTextVisible(QProgressBarH(TQtProgressBar(Self.Handle).Widget), True); {$ENDIF} end; end. doublecmd-0.8.2/components/KASToolBar/kastoolbar.pas0000664000175000017500000007702513105121372021447 0ustar alexxalexx{ Double Commander components ------------------------------------------------------------------------- Toolbar panel class Copyright (C) 2006-2016 Koblov Alexander (Alexx2000@mail.ru) contributors: 2012 Przemyslaw Nagay (cobines@gmail.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in a file called COPYING along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. } unit KASToolBar; {$mode objfpc}{$H+} interface uses Classes, SysUtils, LResources, Forms, Controls, ComCtrls, Graphics, Dialogs, ExtCtrls, Buttons, FileUtil, Menus, DCXmlConfig, KASToolItems, LCLVersion; type TOnToolButtonClick = procedure (Sender: TObject) of object; TOnToolButtonMouseUpDown = procedure (Sender: TObject; Button: TMouseButton; Shift:TShiftState; X,Y:Integer) of object; TOnToolButtonMouseMove = procedure (Sender: TObject; Shift:TShiftState; X,Y:Integer; NumberOfButton: Integer) of object; TOnToolButtonDragOver = procedure(Sender, Source: TObject; X,Y: Integer; State: TDragState; var Accept: Boolean; NumberOfButton: Integer) of object; TOnToolButtonDragDrop = procedure(Sender, Source: TObject; X, Y: Integer) of object; TOnToolButtonEndDrag = procedure(Sender, Target: TObject; X,Y: Integer) of object; TOnLoadButtonGlyph = function (ToolItem: TKASToolItem; iIconSize: Integer; clBackColor: TColor): TBitmap of object; TOnToolItemExecute = procedure (ToolItem: TKASToolItem) of object; TOnConfigLoadItem = function (Config: TXmlConfig; Node: TXmlNode): TKASToolItem of object; TOnToolItemShortcutsHint = function (ToolItem: TKASNormalItem): String of object; TTypeOfConfigurationLoad = (tocl_FlushCurrentToolbarContent, tocl_AddToCurrentToolbarContent); TKASToolBar = class; { TKASToolButton } TKASToolButton = class(TSpeedButton) private FToolItem: TKASToolItem; function GetToolBar: TKASToolBar; protected procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); override; public constructor Create(AOwner: TComponent; Item: TKASToolItem); reintroduce; property ToolBar: TKASToolBar read GetToolBar; property ToolItem: TKASToolItem read FToolItem; end; { TKASToolDivider } TKASToolDivider = class(TKASToolButton) protected procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); override; procedure Paint; override; end; { TKASToolBar } TKASToolBar = class(TToolBar, IToolOwner) private FButtonHeight: Integer; FButtonWidth: Integer; FFlat: Boolean; FGlyphSize: Integer; FRadioToolBar: Boolean; FRowHeight: Integer; FShowDividerAsButton: Boolean; FToolItemExecutors: TFPList; FToolItems: TKASToolBarItems; FToolPopupMenu: TPopupMenu; FOwnsToolItems: Boolean; {$if lcl_fullversion < 1010000} FUpdateCount: Integer; {$endif} FOnToolButtonClick: TOnToolButtonClick; FOnToolButtonMouseDown: TOnToolButtonMouseUpDown; FOnToolButtonMouseUp: TOnToolButtonMouseUpDown; FOnToolButtonMouseMove: TOnToolButtonMouseMove; FOnToolButtonDragOver: TOnToolButtonDragOver; FOnToolButtonDragDrop: TOnToolButtonDragDrop; FOnToolButtonEndDrag: TOnToolButtonEndDrag; FOnLoadButtonGlyph: TOnLoadButtonGlyph; FOnToolItemExecute: TOnToolItemExecute; FOnToolItemShortcutsHint: TOnToolItemShortcutsHint; FKASToolBarFlags: TToolBarFlags; FResizeButtonsNeeded: Boolean; procedure AssignToolButtonProperties(ToolButton: TKASToolButton); procedure ClearExecutors; function CreateButton(Item: TKASToolItem): TKASToolButton; function ExecuteToolItem(Item: TKASToolItem): Boolean; function FindButton(Button: TKASToolButton): Integer; function GetChangePath: String; function GetEnvVar: String; function GetToolItemShortcutsHint(Item: TKASToolItem): String; function LoadBtnIcon(IconPath: String): TBitMap; procedure DrawLinkIcon(Image: TBitMap); function GetButton(Index: Integer): TKASToolButton; procedure InsertButton(InsertAt: Integer; ToolButton: TKASToolButton); procedure SetButtonHeight(const AValue: Integer); procedure SetButtonWidth(const AValue: Integer); procedure SetChangePath(const {%H-}AValue: String); procedure SetEnvVar(const {%H-}AValue: String); procedure SetFlat(const AValue: Boolean); procedure SetGlyphSize(const AValue: Integer); procedure ShowMenu(ToolButton: TKASToolButton); procedure ToolButtonClick(Sender: TObject); procedure ToolButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift:TShiftState; X,Y:Integer); procedure ToolButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift:TShiftState; X,Y:Integer); procedure ToolButtonMouseMove(Sender: TObject; Shift:TShiftState; X,Y:Integer); procedure ToolButtonDragOver(Sender, Source: TObject; X,Y: Integer; State: TDragState; var Accept: Boolean); procedure ToolButtonDragDrop(Sender, Source: TObject; X,Y: Integer); procedure ToolButtonEndDrag(Sender, Target: TObject; X, Y: Integer); procedure ToolItemLoaded(Item: TKASToolItem); procedure ToolMenuClicked(Sender: TObject); procedure UpdateButtonsTags; protected procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: Integer; WithThemeSpace: Boolean); override; procedure ControlsAligned; override; procedure FontChanged(Sender: TObject); override; function WrapButtons(UseWidth: integer; out NewWidth, NewHeight: Integer; Simulate: boolean): Boolean; procedure ResizeButtons; public constructor Create(TheOwner: TComponent); override; destructor Destroy; override; function AddButton(Item: TKASToolItem): TKASToolButton; procedure AddToolItemExecutor(ToolItemClass: TKASToolItemClass; ExecuteFunction: TOnToolItemExecute); procedure Clear; procedure ClickItem(ToolItemID: String); overload; function InsertButton(InsertAt: Integer; Item: TKASToolItem): TKASToolButton; function InsertButton(InsertAt: TKASToolButton; Item: TKASToolItem): TKASToolButton; procedure MoveButton(ButtonIndex, MovePosition: Integer); procedure MoveButton(SourceButton: TKASToolButton; TargetToolBar: TKASToolBar; InsertAt: TKASToolButton); procedure RemoveButton(Index: Integer); procedure RemoveButton(Button: TKASToolButton); procedure RemoveToolItemExecutor(ExecuteFunction: TOnToolItemExecute); procedure UncheckAllButtons; procedure UpdateIcon(ToolButton: TKASToolButton); procedure UseItems(AItems: TKASToolBarItems); procedure LoadConfiguration(Config: TXmlConfig; RootNode: TXmlNode; Loader: TKASToolBarLoader; ConfigurationLoadType:TTypeOfConfigurationLoad); procedure SaveConfiguration(Config: TXmlConfig; RootNode: TXmlNode); procedure BeginUpdate; override; procedure EndUpdate; override; procedure SetButtonSize(NewButtonWidth, NewButtonHeight: Integer); function PublicExecuteToolItem(Item: TKASToolItem): Boolean; property Buttons[Index: Integer]: TKASToolButton read GetButton; property RowHeight: Integer read FRowHeight; published property OnLoadButtonGlyph : TOnLoadButtonGlyph read FOnLoadButtonGlyph write FOnLoadButtonGlyph; property OnToolButtonClick: TOnToolButtonClick read FOnToolButtonClick write FOnToolButtonClick; property OnToolButtonMouseDown: TOnToolButtonMouseUpDown read FOnToolButtonMouseDown write FOnToolButtonMouseDown; property OnToolButtonMouseUp: TOnToolButtonMouseUpDown read FOnToolButtonMouseUp write FOnToolButtonMouseUp; property OnToolButtonMouseMove: TOnToolButtonMouseMove read FOnToolButtonMouseMove write FOnToolButtonMouseMove; property OnToolButtonDragDrop: TOnToolButtonDragDrop read FOnToolButtonDragDrop write FOnToolButtonDragDrop; property OnToolButtonEndDrag: TOnToolButtonEndDrag read FOnToolButtonEndDrag write FOnToolButtonEndDrag; property OnToolButtonDragOver: TOnToolButtonDragOver read FOnToolButtonDragOver write FOnToolButtonDragOver; property OnToolItemExecute: TOnToolItemExecute read FOnToolItemExecute write FOnToolItemExecute; property OnToolItemShortcutsHint: TOnToolItemShortcutsHint read FOnToolItemShortcutsHint write FOnToolItemShortcutsHint; property RadioToolBar: Boolean read FRadioToolBar write FRadioToolBar default False; property Flat: Boolean read FFlat write SetFlat default False; property GlyphSize: Integer read FGlyphSize write SetGlyphSize; property ButtonHeight: Integer read FButtonHeight write SetButtonHeight default 22; property ButtonWidth: Integer read FButtonWidth write SetButtonWidth default 23; property ShowDividerAsButton: Boolean read FShowDividerAsButton write FShowDividerAsButton default False; property ChangePath: String read GetChangePath write SetChangePath; property EnvVar: String read GetEnvVar write SetEnvVar; end; procedure Register; implementation uses Themes, types, math, DCOSUtils; type PToolItemExecutor = ^TToolItemExecutor; TToolItemExecutor = record ToolItemClass: TKASToolItemClass; ToolItemExecute: TOnToolItemExecute; end; procedure Register; begin RegisterComponents('KASComponents',[TKASToolBar]); end; { TKASToolBar } procedure TKASToolBar.InsertButton(InsertAt: Integer; ToolButton: TKASToolButton); begin if InsertAt < 0 then InsertAt:= 0; if InsertAt > ButtonList.Count then InsertAt:= ButtonList.Count; ButtonList.Insert(InsertAt, ToolButton); FToolItems.Insert(InsertAt, ToolButton.ToolItem); UpdateButtonsTags; ResizeButtons; end; function TKASToolBar.InsertButton(InsertAt: TKASToolButton; Item: TKASToolItem): TKASToolButton; var Index: Integer; begin Index := ButtonList.IndexOf(InsertAt); if Index < 0 then Index := ButtonCount; Result := InsertButton(Index, Item); end; procedure TKASToolBar.CalculatePreferredSize(var PreferredWidth, PreferredHeight: Integer; WithThemeSpace: Boolean); begin WrapButtons(Width, PreferredWidth, PreferredHeight, True); end; procedure TKASToolBar.ControlsAligned; var NewWidth, NewHeight: integer; begin if tbfPlacingControls in FKASToolBarFlags then exit; Include(FKASToolBarFlags, tbfPlacingControls); try WrapButtons(Width, NewWidth, NewHeight, False); finally Exclude(FKASToolBarFlags, tbfPlacingControls); end; end; procedure TKASToolBar.FontChanged(Sender: TObject); begin inherited FontChanged(Sender); ResizeButtons; end; function TKASToolBar.WrapButtons(UseWidth: integer; out NewWidth, NewHeight: Integer; Simulate: boolean): Boolean; var ARect: TRect; x: Integer; y: Integer; CurControl: TControl; StartX: Integer; procedure CalculatePosition; var NewBounds: TRect; begin NewBounds := Bounds(x, y, CurControl.Width, RowHeight); repeat if (not Wrapable) or (NewBounds.Right <= ARect.Right) or (NewBounds.Left = StartX) then begin // control fits into the row x := NewBounds.Left; y := NewBounds.Top; break; end; // try next row NewBounds.Left := StartX; NewBounds.Right := NewBounds.Left + CurControl.Width; inc(NewBounds.Top, RowHeight); inc(NewBounds.Bottom, RowHeight); until false; end; var CurClientRect: TRect; AdjustClientFrame: TRect; i: Integer; w, h: Longint; begin Result := True; NewWidth := 0; NewHeight := 0; DisableAlign; BeginUpdate; try CurClientRect := ClientRect; inc(CurClientRect.Right, UseWidth - Width); ARect := CurClientRect; AdjustClientRect(ARect); AdjustClientFrame.Left := ARect.Left - CurClientRect.Left; AdjustClientFrame.Top := ARect.Top - CurClientRect.Top; AdjustClientFrame.Right := CurClientRect.Right - ARect.Right; AdjustClientFrame.Bottom := CurClientRect.Bottom - ARect.Bottom; //DebugLn(['TToolBar.WrapButtons ',DbgSName(Self),' ARect=',dbgs(ARect)]); // important: top, left button must start in the AdjustClientRect top, left // otherwise Toolbar.AutoSize=true will create an endless loop StartX := ARect.Left; x := StartX; y := ARect.Top; for i := 0 to ButtonList.Count - 1 do begin CurControl := TControl(ButtonList[i]); if not CurControl.IsControlVisible then Continue; CalculatePosition; w := CurControl.Width; h := CurControl.Height; if (not Simulate) and ((CurControl.Left <> x) or (CurControl.Top <> y)) then begin CurControl.SetBounds(x,y,w,h); // Note: do not use SetBoundsKeepBase end; // adjust NewWidth, NewHeight NewWidth := Max(NewWidth, x + w + AdjustClientFrame.Right); NewHeight := Max(NewHeight, y + h + AdjustClientFrame.Bottom); // step to next position inc(x,w); end; finally EndUpdate; EnableAlign; end; end; procedure TKASToolBar.ResizeButtons; var w, h: LongInt; i: Integer; CurControl: TControl; begin if FUpdateCount > 0 then begin FResizeButtonsNeeded := True; Exit; end; InvalidatePreferredChildSizes; FRowHeight := ButtonHeight; // Row height is at least initial button height // First recalculate RowHeight. for i := 0 to ButtonList.Count - 1 do begin CurControl := TControl(ButtonList[i]); w := ButtonWidth; h := ButtonHeight; CurControl.GetPreferredSize(w, h); if FRowHeight < h then FRowHeight := h; end; FResizeButtonsNeeded := False; // Now resize buttons. DisableAlign; BeginUpdate; try for i := 0 to ButtonList.Count - 1 do begin CurControl := TControl(ButtonList[i]); w := ButtonWidth; h := RowHeight; CurControl.GetPreferredSize(w, h); if (CurControl.Width <> w) or (CurControl.Height <> h) then CurControl.SetBounds(CurControl.Left, CurControl.Top, w, h); end; InvalidatePreferredSize; AdjustSize; finally EndUpdate; EnableAlign; end; end; procedure TKASToolBar.SaveConfiguration(Config: TXmlConfig; RootNode: TXmlNode); var Node: TXmlNode; Item: TKASToolItem; i: Integer; begin if ButtonCount > 0 then begin Node := Config.AddNode(RootNode, 'Row'); for i := 0 to ButtonCount - 1 do begin Item := TKASToolButton(Buttons[i]).ToolItem; Item.Save(Config, Node); end; end; end; procedure TKASToolBar.DrawLinkIcon(Image: TBitMap); var sizeLink : Integer; bmLinkIcon : TBitmap; {$IFDEF LCLGTK2} bmTempIcon : TBitmap; {$ENDIF} ToolItem: TKASNormalItem; begin if (Image = nil) or (FOnLoadButtonGlyph = nil) then Exit; sizeLink := FGlyphSize div 2; ToolItem := TKASNormalItem.Create; ToolItem.Icon := 'emblem-symbolic-link'; bmLinkIcon:= FOnLoadButtonGlyph(ToolItem, sizeLink, clBtnFace); ToolItem.Free; if Assigned(bmLinkIcon) then begin {$IFDEF LCLGTK2} // Under GTK2 can not draw over alpha transparent pixels bmTempIcon := TBitmap.Create; bmTempIcon.Assign(Image); Image.FreeImage; Image.SetSize(FGlyphSize, FGlyphSize); Image.Canvas.Brush.Color := clBtnFace; Image.Canvas.FillRect(0, 0, FGlyphSize, FGlyphSize); Image.Canvas.Draw(0, 0, bmTempIcon); bmTempIcon.Free; {$ENDIF} Image.Canvas.Draw(FGlyphSize-sizeLink+2,FGlyphSize-sizeLink+2, bmLinkIcon); Image.TransparentColor:= clBtnFace; Image.Transparent:= True; bmLinkIcon.Free; end; end; function TKASToolBar.LoadBtnIcon(IconPath: String): TBitMap; var picture: TPicture; begin if (IconPath = '') or (not mbFileExists(IconPath)) then Exit(nil); Picture := TPicture.Create; try Picture.LoadFromFile(IconPath); Result := TBitmap.Create; Result.Assign(Picture.Bitmap); finally FreeAndNil(Picture); end; end; procedure TKASToolBar.LoadConfiguration(Config: TXmlConfig; RootNode: TXmlNode; Loader: TKASToolBarLoader; ConfigurationLoadType:TTypeOfConfigurationLoad); var Node: TXmlNode; begin BeginUpdate; if ConfigurationLoadType=tocl_FlushCurrentToolbarContent then begin Clear; end; try Node := Config.FindNode(RootNode, 'Row', False); if Assigned(Node) then Loader.Load(Config, Node, @ToolItemLoaded); finally EndUpdate; end; end; procedure TKASToolBar.AssignToolButtonProperties(ToolButton: TKASToolButton); begin ToolButton.OnClick:= @ToolButtonClick; ToolButton.OnMouseDown:= @ToolButtonMouseDown; ToolButton.OnMouseUp:= @ToolButtonMouseUp; ToolButton.OnMouseMove:= @ToolButtonMouseMove; ToolButton.OnDragDrop:= @ToolButtonDragDrop; ToolButton.OnDragOver:= @ToolButtonDragOver; ToolButton.OnEndDrag:= @ToolButtonEndDrag; end; function TKASToolBar.GetChangePath: String; begin end; function TKASToolBar.GetEnvVar: String; begin end; function TKASToolBar.GetToolItemShortcutsHint(Item: TKASToolItem): String; begin Result := ''; if Assigned(FOnToolItemShortcutsHint) and (Item is TKASNormalItem) then Result := FOnToolItemShortcutsHint(TKASNormalItem(Item)); end; function TKASToolBar.GetButton(Index: Integer): TKASToolButton; begin Result:= TKASToolButton(ButtonList.Items[Index]); end; procedure TKASToolBar.SetChangePath(const AValue: String); begin end; procedure TKASToolBar.SetEnvVar(const AValue: String); begin end; procedure TKASToolBar.SetFlat(const AValue: Boolean); var I: Integer; begin FFlat:= AValue; for I:= 0 to ButtonList.Count - 1 do TKASToolButton(ButtonList.Items[I]).Flat:= FFlat; end; procedure TKASToolBar.SetGlyphSize(const AValue: Integer); var I: Integer; begin if FGlyphSize = AValue then Exit; FGlyphSize:= AValue; BeginUpdate; try for I := 0 to ButtonList.Count - 1 do UpdateIcon(TKASToolButton(ButtonList[i])); finally EndUpdate; end; end; procedure TKASToolBar.ShowMenu(ToolButton: TKASToolButton); procedure MakeMenu(PopupMenu: TMenuItem; MenuItem: TKASMenuItem); var I: Integer; Item: TKASToolItem; PopupMenuItem: TMenuItem; BitmapTmp: TBitmap = nil; sText: String; begin for I := 0 to MenuItem.SubItems.Count - 1 do begin Item := MenuItem.SubItems.Items[I]; if Item is TKASSeparatorItem then begin PopupMenu.AddSeparator; end else begin PopupMenuItem := TMenuItem.Create(PopupMenu); sText := Item.GetEffectiveText; if sText = '' then sText := Item.GetEffectiveHint; PopupMenuItem.Caption := StringReplace(StringReplace(sText, #$0A, ' | ', [rfReplaceAll]), ' | ----', '', [rfReplaceAll]); if Item is TKASNormalItem then begin if Assigned(FOnLoadButtonGlyph) then BitmapTmp := FOnLoadButtonGlyph(Item, 16, clMenu); if not Assigned(BitmapTmp) then BitmapTmp := LoadBtnIcon(TKASNormalItem(Item).Icon); PopupMenuItem.Bitmap := BitmapTmp; FreeAndNil(BitmapTmp); end; PopupMenuItem.Tag := PtrInt(Item); PopupMenuItem.OnClick := TNotifyEvent(@ToolMenuClicked); PopupMenu.Add(PopupMenuItem); if Item is TKASMenuItem then MakeMenu(PopupMenuItem, TKASMenuItem(Item)); end; end; end; var Point: TPoint; begin FToolPopupMenu.Free; FToolPopupMenu := TPopupMenu.Create(Self); MakeMenu(FToolPopupMenu.Items, ToolButton.ToolItem as TKASMenuItem); Point.x := ToolButton.Left; Point.y := ToolButton.Top + ToolButton.Height; Point := Self.ClientToScreen(Point); FToolPopupMenu.PopUp(Point.x, Point.y); end; procedure TKASToolBar.ToolButtonClick(Sender: TObject); var Button: TKASToolButton; begin Button := Sender as TKASToolButton; // Do not allow depressing down buttons. if FRadioToolBar and not Button.Down then Button.Down := True; if not ExecuteToolItem(Button.ToolItem) then begin if Assigned(FOnToolButtonClick) then FOnToolButtonClick(Button) else if Button.ToolItem is TKASMenuItem then begin ShowMenu(Button); end; end; end; procedure TKASToolBar.ToolButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift:TShiftState; X,Y:Integer); begin if Assigned(FOnToolButtonMouseDown) then FOnToolButtonMouseDown(Sender, Button, Shift, X,Y); end; procedure TKASToolBar.ToolButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift:TShiftState; X,Y:Integer); begin if Assigned(FOnToolButtonMouseUp) then FOnToolButtonMouseUp(Sender, Button, Shift, X,Y); end; procedure TKASToolBar.ToolItemLoaded(Item: TKASToolItem); begin AddButton(Item); end; procedure TKASToolBar.ToolMenuClicked(Sender: TObject); begin ExecuteToolItem(TKASToolItem((Sender as TMenuItem).Tag)); end; procedure TKASToolBar.ToolButtonMouseMove(Sender: TObject; Shift:TShiftState; X,Y:Integer); begin if Assigned(FOnToolButtonMouseMove) then FOnToolButtonMouseMove(Sender, Shift, X,Y, (Sender as TSpeedButton).Tag); end; procedure TKASToolBar.ToolButtonDragOver(Sender, Source: TObject; X,Y: Integer; State: TDragState; var Accept: Boolean); begin if Assigned(FOnToolButtonDragOver) then FOnToolButtonDragOver(Sender, Source, X,Y, State, Accept, (Sender as TSpeedButton).Tag); end; procedure TKASToolBar.ToolButtonDragDrop(Sender, Source: TObject; X,Y: Integer); begin if Assigned(FOnToolButtonDragDrop) then FOnToolButtonDragDrop(Sender, Source, X, Y); end; procedure TKASToolBar.ToolButtonEndDrag(Sender, Target: TObject; X, Y: Integer); begin if Assigned(FOnToolButtonEndDrag) then FOnToolButtonEndDrag(Sender, Target, X, Y); end; procedure TKASToolBar.MoveButton(ButtonIndex, MovePosition: Integer); begin ButtonList.Move(ButtonIndex, MovePosition); FToolItems.Move(ButtonIndex, MovePosition); UpdateButtonsTags; ResizeButtons; end; procedure TKASToolBar.MoveButton(SourceButton: TKASToolButton; TargetToolBar: TKASToolBar; InsertAt: TKASToolButton); var Index: Integer; begin Index := FindButton(SourceButton); if (Index <> -1) and (FToolItems[Index] = SourceButton.ToolItem) then begin SourceButton.FToolItem := nil; TargetToolBar.InsertButton(InsertAt, FToolItems.ReleaseItem(Index)); ButtonList.Delete(Index); Application.ReleaseComponent(SourceButton); // Free later UpdateButtonsTags; Resize; end; end; procedure TKASToolBar.UpdateButtonsTags; var I: Integer; begin for I:= 0 to ButtonList.Count - 1 do TKASToolButton(ButtonList.Items[I]).Tag:= I; end; procedure TKASToolBar.UpdateIcon(ToolButton: TKASToolButton); var Bitmap: TBitmap = nil; begin try if Assigned(FOnLoadButtonGlyph) then Bitmap := FOnLoadButtonGlyph(ToolButton.ToolItem, FGlyphSize, clBtnFace); if not Assigned(Bitmap) and (ToolButton.ToolItem is TKASNormalItem) then Bitmap := LoadBtnIcon(TKASNormalItem(ToolButton.ToolItem).Icon); try if (ToolButton.ToolItem is TKASMenuItem) and Assigned(Bitmap) then DrawLinkIcon(Bitmap); ToolButton.Glyph.Assign(Bitmap); finally Bitmap.Free; end; except // Ignore end; end; procedure TKASToolBar.UseItems(AItems: TKASToolBarItems); var i: Integer; Button: TKASToolButton; begin if Assigned(AItems) then begin BeginUpdate; Clear; if FOwnsToolItems then FToolItems.Free; FToolItems := AItems; FOwnsToolItems := False; // Insert the existing items as buttons. for i := 0 to FToolItems.Count - 1 do begin Button := CreateButton(FToolItems.Items[i]); if Assigned(Button) then ButtonList.Insert(ButtonCount, Button); end; UpdateButtonsTags; ResizeButtons; EndUpdate; end; end; procedure TKASToolBar.Clear; var I: Integer; begin BeginUpdate; for I := 0 to ButtonList.Count - 1 do TKASToolButton(ButtonList.Items[I]).Free; ButtonList.Clear; if Assigned(FToolItems) then FToolItems.Clear; EndUpdate; end; procedure TKASToolBar.ClearExecutors; var I: Integer; begin for I := 0 to FToolItemExecutors.Count - 1 do Dispose(PToolItemExecutor(FToolItemExecutors[I])); FToolItemExecutors.Clear; end; procedure TKASToolBar.ClickItem(ToolItemID: String); var I: Integer; Button: TKASToolButton; NormalItem: TKASNormalItem; begin for I := 0 to ButtonList.Count - 1 do begin Button := TKASToolButton(ButtonList.Items[I]); if Button.ToolItem is TKASNormalItem then begin NormalItem := TKASNormalItem(Button.ToolItem); if NormalItem.ID = ToolItemID then begin Button.Click; Break; end; if Button.ToolItem.CheckExecute(ToolItemID) then Break; end; end; end; procedure TKASToolBar.SetButtonHeight(const AValue: Integer); begin SetButtonSize(ButtonWidth, AValue); end; procedure TKASToolBar.SetButtonWidth(const AValue: Integer); begin SetButtonSize(AValue, ButtonHeight); end; constructor TKASToolBar.Create(TheOwner: TComponent); begin inherited Create(TheOwner); FGlyphSize:= 16; // by default FUpdateCount:= 0; FButtonWidth := 23; FButtonHeight := 22; FKASToolBarFlags := []; FToolItemExecutors := TFPList.Create; FToolItems := TKASToolBarItems.Create; FOwnsToolItems := True; end; function TKASToolBar.CreateButton(Item: TKASToolItem): TKASToolButton; begin if Assigned(Item) then begin if FOwnsToolItems then Item.SetToolOwner(Self); if Item is TKASSeparatorItem then begin Result := TKASToolDivider.Create(Self, Item); end else begin Result := TKASToolButton.Create(Self, Item); Result.ShowHint := True; Result.Caption := Item.GetEffectiveText; Result.Hint := Item.GetEffectiveHint; end; Result.Flat := FFlat; if FRadioToolBar then begin Result.GroupIndex := 1; Result.AllowAllUp := True; end; Result.ShowCaption := ShowCaptions; UpdateIcon(Result); AssignToolButtonProperties(Result); Result.Parent := Self; end else Result := nil; end; destructor TKASToolBar.Destroy; begin if not FOwnsToolItems then FToolItems := nil; // Unassign before Clear so that items are not cleared. Clear; inherited Destroy; ClearExecutors; FToolItemExecutors.Free; if FOwnsToolItems then FToolItems.Free; end; function TKASToolBar.ExecuteToolItem(Item: TKASToolItem): Boolean; var I: Integer; Executor: PToolItemExecutor; BestMatch: PToolItemExecutor = nil; begin for I := 0 to FToolItemExecutors.Count - 1 do begin Executor := PToolItemExecutor(FToolItemExecutors[I]); if Assigned(Executor^.ToolItemExecute) and Item.InheritsFrom(Executor^.ToolItemClass) and (not Assigned(BestMatch) or (Executor^.ToolItemClass.InheritsFrom(BestMatch^.ToolItemClass))) then begin BestMatch := Executor; end; end; Result := Assigned(BestMatch); if Result then BestMatch^.ToolItemExecute(Item); end; { TKASToolBar.PublicExecuteToolItem } function TKASToolBar.PublicExecuteToolItem(Item: TKASToolItem): Boolean; begin result:=ExecuteToolItem(Item); end; procedure TKASToolBar.BeginUpdate; begin {$if lcl_fullversion < 1010000} Inc(FUpdateCount); {$endif} inherited BeginUpdate; DisableAutoSizing; end; procedure TKASToolBar.EndUpdate; begin EnableAutoSizing; inherited EndUpdate; {$if lcl_fullversion < 1010000} Dec(FUpdateCount); {$endif} if (FUpdateCount = 0) and FResizeButtonsNeeded then ResizeButtons; end; function TKASToolBar.FindButton(Button: TKASToolButton): Integer; var I: Integer; begin for I := 0 to ButtonList.Count - 1 do if TKASToolButton(ButtonList[I]) = Button then Exit(I); Result := -1; end; procedure TKASToolBar.SetButtonSize(NewButtonWidth, NewButtonHeight: Integer); begin FButtonWidth := NewButtonWidth; FButtonHeight := NewButtonHeight; ResizeButtons; end; function TKASToolBar.AddButton(Item: TKASToolItem): TKASToolButton; begin Result := InsertButton(ButtonCount, Item); end; procedure TKASToolBar.AddToolItemExecutor(ToolItemClass: TKASToolItemClass; ExecuteFunction: TOnToolItemExecute); var Executor: PToolItemExecutor; begin New(Executor); FToolItemExecutors.Add(Executor); Executor^.ToolItemClass := ToolItemClass; Executor^.ToolItemExecute := ExecuteFunction; end; function TKASToolBar.InsertButton(InsertAt: Integer; Item: TKASToolItem): TKASToolButton; begin Result := CreateButton(Item); if Assigned(Result) then InsertButton(InsertAt, Result); end; procedure TKASToolBar.RemoveButton(Index: Integer); var Button: TKASToolButton; begin Button := TKASToolButton(ButtonList.Items[Index]); ButtonList.Delete(Index); Button.Free; FToolItems.Remove(Index); UpdateButtonsTags; Resize; end; procedure TKASToolBar.RemoveButton(Button: TKASToolButton); var Index: Integer; begin Index := FindButton(Button); if Index <> -1 then RemoveButton(Index); end; procedure TKASToolBar.RemoveToolItemExecutor(ExecuteFunction: TOnToolItemExecute); var Executor: PToolItemExecutor; I: Integer; begin for I := FToolItemExecutors.Count - 1 downto 0 do begin Executor := PToolItemExecutor(FToolItemExecutors[I]); if (TMethod(Executor^.ToolItemExecute).Code = TMethod(ExecuteFunction).Code) and (TMethod(Executor^.ToolItemExecute).Data = TMethod(ExecuteFunction).Data) then begin Dispose(Executor); FToolItemExecutors.Delete(I); end; end; end; procedure TKASToolBar.UncheckAllButtons; var I: Integer; begin for I:= 0 to ButtonCount - 1 do Buttons[I].Down:= False; end; { TKASToolButton } procedure TKASToolButton.CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); var TextSize: TSize; begin if Assigned(Parent) then begin if ShowCaption and (Caption <> EmptyStr) then begin // Size to extent of the icon + caption. // Minimum size is the ButtonWidth x RowHeight of the toolbar. TextSize := Canvas.TextExtent(Caption); PreferredWidth := Max(TextSize.cx + Glyph.Width + 16, ToolBar.ButtonWidth); PreferredHeight := Max(TextSize.cy + 4, ToolBar.RowHeight); end else begin PreferredWidth := ToolBar.ButtonWidth; PreferredHeight := ToolBar.RowHeight; end; end else inherited; end; constructor TKASToolButton.Create(AOwner: TComponent; Item: TKASToolItem); begin inherited Create(AOwner); FToolItem := Item; end; function TKASToolButton.GetToolBar: TKASToolBar; begin Result := Parent as TKASToolBar; end; { TKASToolDivider } procedure TKASToolDivider.CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); begin if Assigned(Parent) and (Parent is TKASToolBar) and not TKASToolBar(Parent).FShowDividerAsButton then begin PreferredWidth := 5; PreferredHeight := TKASToolBar(Parent).RowHeight; end else inherited; end; procedure TKASToolDivider.Paint; var DividerRect: TRect; Details: TThemedElementDetails; begin if Assigned(Parent) and (Parent is TKASToolBar) and not TKASToolBar(Parent).FShowDividerAsButton then begin DividerRect:= ClientRect; Details:= ThemeServices.GetElementDetails(ttbSeparatorNormal); // Theme services have no strict rule to draw divider in the center, // so we should calculate rectangle here // on windows 7 divider can't be less than 4 pixels if (DividerRect.Right - DividerRect.Left) > 5 then begin DividerRect.Left := (DividerRect.Left + DividerRect.Right) div 2 - 3; DividerRect.Right := DividerRect.Left + 5; end; ThemeServices.DrawElement(Canvas.GetUpdatedHandle([csBrushValid, csPenValid]), Details, DividerRect); end else inherited Paint; end; end. doublecmd-0.8.2/components/KASToolBar/kascombobox.pas0000664000175000017500000001023213104055077021607 0ustar alexxalexx{ Double Commander Components ------------------------------------------------------------------------- Extended ComboBox classes Copyright (C) 2012 Przemyslaw Nagay (cobines@gmail.com) Copyright (C) 2015-2017 Alexander Koblov (alexx2000@mail.ru) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . } unit KASComboBox; {$mode objfpc}{$H+} interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, LCLVersion; type { TComboBoxWithDelItems } {en Combo box that allows removing items with Shift+Delete. } TComboBoxWithDelItems = class(TComboBox) protected procedure KeyDown(var Key: Word; Shift: TShiftState); override; end; { TComboBoxAutoWidth } TComboBoxAutoWidth = class(TComboBox) protected procedure CalculatePreferredSize( var PreferredWidth, PreferredHeight: Integer; WithThemeSpace: Boolean); override; procedure CalculateSize(MaxWidth: Integer; var NeededWidth: Integer); {$if lcl_fullversion >= 1070000} procedure DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy; const AXProportion, AYProportion: Double); override; {$endif} end; procedure Register; implementation uses LCLType, LCLIntf; procedure Register; begin RegisterComponents('KASComponents',[TComboBoxWithDelItems, TComboBoxAutoWidth]); end; { TComboBoxWithDelItems } procedure TComboBoxWithDelItems.KeyDown(var Key: Word; Shift: TShiftState); var Index: Integer; begin if DroppedDown and (Key = VK_DELETE) and (Shift = [ssShift]) then begin Index := ItemIndex; if (Index >= 0) and (Index < Items.Count) then begin Items.Delete(Index); ItemIndex := Index; Key := 0; end; end; inherited KeyDown(Key, Shift); end; { TComboBoxAutoWidth } procedure TComboBoxAutoWidth.CalculatePreferredSize(var PreferredWidth, PreferredHeight: Integer; WithThemeSpace: Boolean); var AWidth: Integer; begin inherited CalculatePreferredSize(PreferredWidth, PreferredHeight, WithThemeSpace); if csDesigning in ComponentState then Exit; if (Parent = nil) or (not Parent.HandleAllocated) then Exit; AWidth := Constraints.MinMaxWidth(10000); CalculateSize(AWidth, PreferredWidth); end; procedure TComboBoxAutoWidth.CalculateSize(MaxWidth: Integer; var NeededWidth: Integer); var DC: HDC; R: TRect; I, M: Integer; Flags: Cardinal; OldFont: HGDIOBJ; LabelText: String; Idx: Integer = -1; begin if Items.Count = 0 then LabelText:= Text else begin M := Canvas.TextWidth(Text); for I := 0 to Items.Count - 1 do begin Flags := Canvas.TextWidth(Items[I]); if Flags > M then begin M := Flags; Idx := I; end; end; if Idx < 0 then LabelText := Text else begin LabelText := Items[Idx]; end; end; if LabelText = '' then begin NeededWidth := 1; Exit; end; DC := GetDC(Parent.Handle); try R := Rect(0, 0, MaxWidth, 10000); OldFont := SelectObject(DC, HGDIOBJ(Font.Reference.Handle)); Flags := DT_CALCRECT or DT_EXPANDTABS; DrawText(DC, PChar(LabelText), Length(LabelText), R, Flags); SelectObject(DC, OldFont); NeededWidth := R.Right - R.Left + GetSystemMetrics(SM_CXVSCROLL) * 2; finally ReleaseDC(Parent.Handle, DC); end; end; {$if lcl_fullversion >= 1070000} procedure TComboBoxAutoWidth.DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy; const AXProportion, AYProportion: Double); begin // Don't auto adjust horizontal layout inherited DoAutoAdjustLayout(AMode, 1.0, AYProportion); end; {$endif} end. doublecmd-0.8.2/components/KASToolBar/kastoolitems.pas0000664000175000017500000003547112205740427022033 0ustar alexxalexx{ Double Commander ------------------------------------------------------------------------- Basic tool items types for KASToolBar Copyright (C) 2012 Przemyslaw Nagay (cobines@gmail.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } unit KASToolItems; {$mode objfpc}{$H+} interface uses Classes, SysUtils, DCXmlConfig, DCBasicTypes; type TKASToolBarItems = class; TKASToolItem = class; TOnLoadToolItem = procedure (Item: TKASToolItem) of object; {$interfaces corba} IToolOwner = interface ['{A7908D38-1E13-4E8D-8FA7-8830A2FF9290}'] function ExecuteToolItem(Item: TKASToolItem): Boolean; function GetToolItemShortcutsHint(Item: TKASToolItem): String; end; {$interfaces default} { TKASToolBarLoader } TKASToolBarLoader = class protected function CreateItem(Node: TXmlNode): TKASToolItem; virtual; public procedure Load(Config: TXmlConfig; RootNode: TXmlNode; OnLoadToolItem: TOnLoadToolItem); virtual; end; { TKASToolItem } TKASToolItem = class private FToolOwner: IToolOwner; FUserData: Pointer; protected property ToolOwner: IToolOwner read FToolOwner; public procedure Assign(OtherItem: TKASToolItem); virtual; function CheckExecute(ToolItemID: String): Boolean; virtual; function Clone: TKASToolItem; virtual; abstract; function ConfigNodeName: String; virtual; abstract; function GetEffectiveHint: String; virtual; abstract; function GetEffectiveText: String; virtual; abstract; procedure Load(Config: TXmlConfig; Node: TXmlNode; Loader: TKASToolBarLoader); virtual; abstract; procedure Save(Config: TXmlConfig; Node: TXmlNode); procedure SaveContents(Config: TXmlConfig; Node: TXmlNode); virtual; abstract; procedure SetToolOwner(AToolOwner: IToolOwner); virtual; property UserData: Pointer read FUserData write FUserData; end; TKASToolItemClass = class of TKASToolItem; { TKASSeparatorItem } TKASSeparatorItem = class(TKASToolItem) procedure Assign(OtherItem: TKASToolItem); override; function Clone: TKASToolItem; override; function ConfigNodeName: String; override; function GetEffectiveHint: String; override; function GetEffectiveText: String; override; procedure Load(Config: TXmlConfig; Node: TXmlNode; Loader: TKASToolBarLoader); override; procedure SaveContents(Config: TXmlConfig; Node: TXmlNode); override; end; { TKASNormalItem } TKASNormalItem = class(TKASToolItem) strict private FID: String; // Unique identificator of the button function GetID: String; strict protected procedure SaveHint(Config: TXmlConfig; Node: TXmlNode); virtual; procedure SaveIcon(Config: TXmlConfig; Node: TXmlNode); virtual; procedure SaveText(Config: TXmlConfig; Node: TXmlNode); virtual; public Icon: String; Text: String; Hint: String; procedure Assign(OtherItem: TKASToolItem); override; function CheckExecute(ToolItemID: String): Boolean; override; function Clone: TKASToolItem; override; function ConfigNodeName: String; override; function GetEffectiveHint: String; override; function GetEffectiveText: String; override; function GetShortcutsHint: String; procedure Load(Config: TXmlConfig; Node: TXmlNode; Loader: TKASToolBarLoader); override; procedure SaveContents(Config: TXmlConfig; Node: TXmlNode); override; property ID: String read GetID; end; { TKASMenuItem } TKASMenuItem = class(TKASNormalItem) procedure ToolItemLoaded(Item: TKASToolItem); private FItems: TKASToolBarItems; public constructor Create; reintroduce; destructor Destroy; override; procedure Assign(OtherItem: TKASToolItem); override; function CheckExecute(ToolItemID: String): Boolean; override; function Clone: TKASToolItem; override; function ConfigNodeName: String; override; procedure Load(Config: TXmlConfig; Node: TXmlNode; Loader: TKASToolBarLoader); override; procedure SaveContents(Config: TXmlConfig; Node: TXmlNode); override; procedure SetToolOwner(AToolOwner: IToolOwner); override; property SubItems: TKASToolBarItems read FItems; end; { TKASToolBarItems } TKASToolBarItems = class private FButtons: TFPList; function GetButton(Index: Integer): TKASToolItem; function GetButtonCount: Integer; procedure SetButton(Index: Integer; const AValue: TKASToolItem); public constructor Create; destructor Destroy; override; function Add(Item: TKASToolItem): Integer; procedure Clear; function Insert(InsertAt: Integer; Item: TKASToolItem): Integer; procedure Move(FromIndex, ToIndex: Integer); {en Returns the item at Index, removes it from the list but does not free it like Remove. } function ReleaseItem(Index: Integer): TKASToolItem; procedure Remove(Index: Integer); property Count: Integer read GetButtonCount; property Items[Index: Integer]: TKASToolItem read GetButton write SetButton; default; end; { TKASToolBarSerializer } TKASToolBarSerializer = class private FDeserializedItem: TKASToolItem; procedure SetDeserializedItem(Item: TKASToolItem); public function Deserialize(Stream: TStream; Loader: TKASToolBarLoader): TKASToolItem; procedure Serialize(Stream: TStream; Item: TKASToolItem); end; const MenuItemConfigNode = 'Menu'; NormalItemConfigNode = 'Normal'; SeparatorItemConfigNode = 'Separator'; implementation uses DCStrUtils; { TKASToolItem } procedure TKASToolItem.Assign(OtherItem: TKASToolItem); begin FUserData := OtherItem.FUserData; end; function TKASToolItem.CheckExecute(ToolItemID: String): Boolean; begin Result := False; end; procedure TKASToolItem.Save(Config: TXmlConfig; Node: TXmlNode); begin Node := Config.AddNode(Node, ConfigNodeName); SaveContents(Config, Node); end; procedure TKASToolItem.SetToolOwner(AToolOwner: IToolOwner); begin FToolOwner := AToolOwner; end; { TKASToolBarSerializer } function TKASToolBarSerializer.Deserialize(Stream: TStream; Loader: TKASToolBarLoader): TKASToolItem; var Config: TXmlConfig; begin Result := nil; FDeserializedItem := nil; Config := TXmlConfig.Create; try Config.ReadFromStream(Stream); Loader.Load(Config, Config.RootNode, @SetDeserializedItem); Result := FDeserializedItem; finally Config.Free; end; end; procedure TKASToolBarSerializer.Serialize(Stream: TStream; Item: TKASToolItem); var Config: TXmlConfig; begin Config := TXmlConfig.Create; try Item.Save(Config, Config.RootNode); Config.WriteToStream(Stream); finally Config.Free; end; end; procedure TKASToolBarSerializer.SetDeserializedItem(Item: TKASToolItem); begin FDeserializedItem := Item; end; { TKASToolBarLoader } function TKASToolBarLoader.CreateItem(Node: TXmlNode): TKASToolItem; begin if Node.CompareName(MenuItemConfigNode) = 0 then Result := TKASMenuItem.Create else if Node.CompareName(NormalItemConfigNode) = 0 then Result := TKASNormalItem.Create else if Node.CompareName(SeparatorItemConfigNode) = 0 then Result := TKASSeparatorItem.Create else Result := nil; end; procedure TKASToolBarLoader.Load(Config: TXmlConfig; RootNode: TXmlNode; OnLoadToolItem: TOnLoadToolItem); var Node: TXmlNode; Item: TKASToolItem; begin Node := RootNode.FirstChild; while Assigned(Node) do begin Item := CreateItem(Node); if Assigned(Item) then try Item.Load(Config, Node, Self); OnLoadToolItem(Item); Item := nil; finally FreeAndNil(Item); end; Node := Node.NextSibling; end; end; { TKASMenuItem } procedure TKASMenuItem.Assign(OtherItem: TKASToolItem); var MenuItem: TKASMenuItem; Item: TKASToolItem; I: Integer; begin inherited Assign(OtherItem); if OtherItem is TKASMenuItem then begin MenuItem := TKASMenuItem(OtherItem); FItems.Clear; for I := 0 to MenuItem.SubItems.Count - 1 do begin Item := MenuItem.SubItems.Items[I].Clone; Item.SetToolOwner(ToolOwner); FItems.Add(Item); end; end; end; function TKASMenuItem.CheckExecute(ToolItemID: String): Boolean; var I: Integer; begin Result := inherited CheckExecute(ToolItemID); if not Result then begin for I := 0 to SubItems.Count - 1 do begin if SubItems[I].CheckExecute(ToolItemID) then Exit(True); end; end; end; function TKASMenuItem.Clone: TKASToolItem; begin Result := TKASMenuItem.Create; Result.Assign(Self); end; function TKASMenuItem.ConfigNodeName: String; begin Result := MenuItemConfigNode; end; constructor TKASMenuItem.Create; begin FItems := TKASToolBarItems.Create; end; destructor TKASMenuItem.Destroy; begin inherited Destroy; FItems.Free; end; procedure TKASMenuItem.Load(Config: TXmlConfig; Node: TXmlNode; Loader: TKASToolBarLoader); begin inherited Load(Config, Node, Loader); SubItems.Clear; Node := Config.FindNode(Node, 'MenuItems', False); if Assigned(Node) then Loader.Load(Config, Node, @ToolItemLoaded); end; procedure TKASMenuItem.SaveContents(Config: TXmlConfig; Node: TXmlNode); var I: Integer; begin inherited SaveContents(Config, Node); if SubItems.Count > 0 then begin Node := Config.AddNode(Node, 'MenuItems'); for I := 0 to SubItems.Count - 1 do SubItems.Items[I].Save(Config, Node); end; end; procedure TKASMenuItem.SetToolOwner(AToolOwner: IToolOwner); var I: Integer; begin inherited SetToolOwner(AToolOwner); for I := 0 to SubItems.Count - 1 do SubItems.Items[I].SetToolOwner(ToolOwner); end; procedure TKASMenuItem.ToolItemLoaded(Item: TKASToolItem); begin Item.SetToolOwner(ToolOwner); SubItems.Add(Item); end; { TKASDividerItem } procedure TKASSeparatorItem.Assign(OtherItem: TKASToolItem); begin inherited Assign(OtherItem); end; function TKASSeparatorItem.Clone: TKASToolItem; begin Result := TKASSeparatorItem.Create; Result.Assign(Self); end; function TKASSeparatorItem.ConfigNodeName: String; begin Result := SeparatorItemConfigNode; end; function TKASSeparatorItem.GetEffectiveHint: String; begin Result := ''; end; function TKASSeparatorItem.GetEffectiveText: String; begin Result := ''; end; procedure TKASSeparatorItem.Load(Config: TXmlConfig; Node: TXmlNode; Loader: TKASToolBarLoader); begin // Empty. end; procedure TKASSeparatorItem.SaveContents(Config: TXmlConfig; Node: TXmlNode); begin // Empty. end; { TKASNormalItem } procedure TKASNormalItem.Assign(OtherItem: TKASToolItem); var NormalItem: TKASNormalItem; begin inherited Assign(OtherItem); if OtherItem is TKASNormalItem then begin // Don't copy ID. NormalItem := TKASNormalItem(OtherItem); Icon := NormalItem.Icon; Text := NormalItem.Text; Hint := NormalItem.Hint; end; end; function TKASNormalItem.CheckExecute(ToolItemID: String): Boolean; begin Result := (ID = ToolItemID); if Result and Assigned(FToolOwner) then FToolOwner.ExecuteToolItem(Self); end; function TKASNormalItem.Clone: TKASToolItem; begin Result := TKASNormalItem.Create; Result.Assign(Self); end; function TKASNormalItem.ConfigNodeName: String; begin Result := NormalItemConfigNode; end; function TKASNormalItem.GetEffectiveHint: String; var ShortcutsHint: String; begin Result := Hint; ShortcutsHint := GetShortcutsHint; if ShortcutsHint <> '' then AddStrWithSep(Result, '(' + ShortcutsHint + ')', ' '); end; function TKASNormalItem.GetEffectiveText: String; begin Result := Text; end; function TKASNormalItem.GetID: String; var Guid: TGuid; begin if FID = EmptyStr then begin if CreateGUID(Guid) = 0 then FID := GUIDToString(Guid) else FID := IntToStr(Random(MaxInt)); end; Result := FID; end; function TKASNormalItem.GetShortcutsHint: String; begin if Assigned(FToolOwner) then Result := FToolOwner.GetToolItemShortcutsHint(Self) else Result := ''; end; procedure TKASNormalItem.Load(Config: TXmlConfig; Node: TXmlNode; Loader: TKASToolBarLoader); begin Node := Node.FirstChild; while Assigned(Node) do begin if Node.CompareName('ID') = 0 then FID := Config.GetContent(Node) else if Node.CompareName('Text') = 0 then Text := Config.GetContent(Node) else if Node.CompareName('Icon') = 0 then Icon := Config.GetContent(Node) else if Node.CompareName('Hint') = 0 then Hint := Config.GetContent(Node); Node := Node.NextSibling; end; end; procedure TKASNormalItem.SaveContents(Config: TXmlConfig; Node: TXmlNode); begin Config.AddValue(Node, 'ID', ID); SaveText(Config, Node); SaveIcon(Config, Node); SaveHint(Config, Node); end; procedure TKASNormalItem.SaveHint(Config: TXmlConfig; Node: TXmlNode); begin Config.AddValueDef(Node, 'Hint', Hint, ''); end; procedure TKASNormalItem.SaveIcon(Config: TXmlConfig; Node: TXmlNode); begin Config.AddValueDef(Node, 'Icon', Icon, ''); end; procedure TKASNormalItem.SaveText(Config: TXmlConfig; Node: TXmlNode); begin Config.AddValueDef(Node, 'Text', Text, ''); end; { TKASToolBarItems } constructor TKASToolBarItems.Create; begin FButtons := TFPList.Create; end; destructor TKASToolBarItems.Destroy; begin Clear; inherited Destroy; FButtons.Free; end; function TKASToolBarItems.Insert(InsertAt: Integer; Item: TKASToolItem): Integer; begin FButtons.Insert(InsertAt, Item); Result := InsertAt; end; procedure TKASToolBarItems.Move(FromIndex, ToIndex: Integer); begin FButtons.Move(FromIndex, ToIndex); end; function TKASToolBarItems.ReleaseItem(Index: Integer): TKASToolItem; begin Result := TKASToolItem(FButtons[Index]); FButtons.Delete(Index); end; function TKASToolBarItems.Add(Item: TKASToolItem): Integer; begin Result := FButtons.Add(Item); end; procedure TKASToolBarItems.Remove(Index: Integer); begin TKASToolItem(FButtons[Index]).Free; FButtons.Delete(Index); end; procedure TKASToolBarItems.Clear; var i: Integer; begin for i := 0 to FButtons.Count - 1 do TKASToolItem(FButtons[i]).Free; FButtons.Clear; end; function TKASToolBarItems.GetButtonCount: Integer; begin Result := FButtons.Count; end; function TKASToolBarItems.GetButton(Index: Integer): TKASToolItem; begin Result := TKASToolItem(FButtons[Index]); end; procedure TKASToolBarItems.SetButton(Index: Integer; const AValue: TKASToolItem); begin TKASToolItem(FButtons[Index]).Free; FButtons[Index] := AValue; end; end. doublecmd-0.8.2/components/KASToolBar/kaspathedit.pas0000664000175000017500000002072212630667552021620 0ustar alexxalexx{ Double Commander Components ------------------------------------------------------------------------- Path edit class with auto complete feature Copyright (C) 2012-2014 Alexander Koblov (alexx2000@mail.ru) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in a file called COPYING along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. } unit KASPathEdit; {$mode delphi} interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, ShellCtrls, LCLType; type { TKASPathEdit } TKASPathEdit = class(TEdit) private FPanel: THintWindow; FListBox: TListBox; FKeyDown: Word; FAutoComplete: Boolean; FObjectTypes: TObjectTypes; FFileSortType: TFileSortType; private procedure AutoComplete(const Path: String); procedure SetObjectTypes(const AValue: TObjectTypes); procedure FormChangeBoundsEvent(Sender: TObject); procedure ListBoxClick(Sender: TObject); procedure ListBoxMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private procedure ShowListBox; procedure HideListBox; protected {$IF DEFINED(LCLWIN32)} procedure CreateWnd; override; {$ENDIF} procedure DoExit; override; procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure KeyUpAfterInterface(var Key: Word; Shift: TShiftState); override; public constructor Create(AOwner: TComponent); override; published property ObjectTypes: TObjectTypes read FObjectTypes write SetObjectTypes; property FileSortType: TFileSortType read FFileSortType write FFileSortType; end; procedure Register; implementation uses LazUTF8, Math {$IF DEFINED(LCLWIN32)} , ComObj {$ENDIF} ; {$IF DEFINED(LCLWIN32)} const SHACF_AUTOAPPEND_FORCE_ON = $40000000; SHACF_AUTOSUGGEST_FORCE_ON = $10000000; SHACF_FILESYS_ONLY = $00000010; SHACF_FILESYS_DIRS = $00000020; function SHAutoComplete(hwndEdit: HWND; dwFlags: DWORD): HRESULT; stdcall; external 'shlwapi.dll'; function SHAutoCompleteX(hwndEdit: HWND; ObjectTypes: TObjectTypes): Boolean; var dwFlags: DWORD; begin if (ObjectTypes = []) then Exit(False); dwFlags := SHACF_AUTOAPPEND_FORCE_ON or SHACF_AUTOSUGGEST_FORCE_ON; if (otNonFolders in ObjectTypes) then dwFlags := dwFlags or SHACF_FILESYS_ONLY else if (otFolders in ObjectTypes) then dwFlags := dwFlags or SHACF_FILESYS_DIRS; Result:= (SHAutoComplete(hwndEdit, dwFlags) = 0); end; {$ENDIF} procedure Register; begin RegisterComponents('KASComponents', [TKASPathEdit]); end; { TKASPathEdit } procedure TKASPathEdit.AutoComplete(const Path: String); var I: LongWord; BasePath: String; begin FListBox.Clear; if Pos(PathDelim, Path) > 0 then begin BasePath:= ExtractFilePath(Path); TCustomShellTreeView.GetFilesInDir( BasePath, ExtractFileName(Path) + '*', FObjectTypes, FListBox.Items, FFileSortType ); if (FListBox.Items.Count > 0) then begin ShowListBox; // Make absolute file name for I:= 0 to FListBox.Items.Count - 1 do FListBox.Items[I]:= BasePath + FListBox.Items[I]; // Calculate ListBox height with FListBox.ItemRect(0) do I:= Bottom - Top; // TListBox.ItemHeight sometimes don't work under GTK2 with FListBox do begin if Items.Count = 1 then FPanel.ClientHeight:= Self.Height else FPanel.ClientHeight:= I * IfThen(Items.Count > 10, 11, Items.Count + 1); end; end; end; if (FListBox.Items.Count = 0) then HideListBox; end; procedure TKASPathEdit.SetObjectTypes(const AValue: TObjectTypes); begin if FObjectTypes = AValue then Exit; FObjectTypes:= AValue; {$IF DEFINED(LCLWIN32)} if HandleAllocated then RecreateWnd(Self); if FAutoComplete then {$ENDIF} FAutoComplete:= (FObjectTypes <> []); end; procedure TKASPathEdit.FormChangeBoundsEvent(Sender: TObject); begin HideListBox; end; procedure TKASPathEdit.ListBoxClick(Sender: TObject); begin if FListBox.ItemIndex >= 0 then begin Text:= FListBox.Items[FListBox.ItemIndex]; SelStart:= UTF8Length(Text); HideListBox; SetFocus; end; end; procedure TKASPathEdit.ListBoxMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin FListBox.ItemIndex:= FListBox.ItemAtPos(Classes.Point(X, Y), True); end; procedure TKASPathEdit.ShowListBox; begin if (FPanel = nil) then begin FPanel:= THintWindow.Create(Self); FPanel.Color:= clForm; FListBox.Parent:= FPanel; with Parent.ClientToScreen(CLasses.Point(Left, Top)) do begin FPanel.Left:= X; FPanel.Top:= Y + Height; end; FPanel.Width:= Width; FPanel.Visible:= True; Application.AddOnDeactivateHandler(FormChangeBoundsEvent, True); GetParentForm(Self).AddHandlerOnChangeBounds(FormChangeBoundsEvent, True); end; end; procedure TKASPathEdit.HideListBox; begin if (FPanel <> nil) then begin FPanel.Visible:= False; FListBox.Parent:= nil; FreeAndNil(FPanel); Application.RemoveOnDeactivateHandler(FormChangeBoundsEvent); GetParentForm(Self).RemoveHandlerOnChangeBounds(FormChangeBoundsEvent); end; end; {$IF DEFINED(LCLWIN32)} procedure TKASPathEdit.CreateWnd; begin inherited CreateWnd; FAutoComplete:= not SHAutoCompleteX(Handle, FObjectTypes); end; {$ENDIF} procedure TKASPathEdit.DoExit; begin HideListBox; inherited DoExit; end; procedure TKASPathEdit.KeyDown(var Key: Word; Shift: TShiftState); begin FKeyDown:= Key; case Key of VK_ESCAPE, VK_RETURN, VK_SELECT: begin HideListBox; end; VK_UP: if Assigned(FPanel) then begin Key:= 0; if FListBox.ItemIndex = -1 then FListBox.ItemIndex:= FListBox.Items.Count - 1 else if FListBox.ItemIndex - 1 < 0 then FListBox.ItemIndex:= - 1 else FListBox.ItemIndex:= FListBox.ItemIndex - 1; if FListBox.ItemIndex >= 0 then Text:= FListBox.Items[FListBox.ItemIndex] else Text:= ExtractFilePath(Text); SelStart:= UTF8Length(Text); end; VK_DOWN: if Assigned(FPanel) then begin Key:= 0; if FListBox.ItemIndex + 1 >= FListBox.Items.Count then FListBox.ItemIndex:= -1 else if FListBox.ItemIndex = -1 then FListBox.ItemIndex:= IfThen(FListBox.Items.Count > 0, 0, -1) else FListBox.ItemIndex:= FListBox.ItemIndex + 1; if FListBox.ItemIndex >= 0 then Text:= FListBox.Items[FListBox.ItemIndex] else Text:= ExtractFilePath(Text); SelStart:= UTF8Length(Text); end; end; inherited KeyDown(Key, Shift); {$IFDEF LCLGTK2} // Workaround for GTK2 - up and down arrows moving through controls. if Key in [VK_UP, VK_DOWN] then Key:= 0; {$ENDIF} end; procedure TKASPathEdit.KeyUpAfterInterface(var Key: Word; Shift: TShiftState); begin if (FKeyDown = Key) and FAutoComplete and not (Key in [VK_ESCAPE, VK_RETURN, VK_SELECT, VK_UP, VK_DOWN]) then begin if Modified then begin Modified:= False; AutoComplete(Text); end; end; inherited KeyUpAfterInterface(Key, Shift); {$IF DEFINED(LCLWIN32)} // Windows auto-completer eats the TAB so LCL doesn't get it and doesn't move to next control. if not FAutoComplete and (Key = VK_TAB) then GetParentForm(Self).SelectNext(Self, True, True); {$ENDIF} end; constructor TKASPathEdit.Create(AOwner: TComponent); begin inherited Create(AOwner); FListBox:= TListBox.Create(Self); FListBox.TabStop:= False; FListBox.Align:= alClient; FListBox.ClickOnSelChange:= False; FListBox.OnClick:= ListBoxClick; FListBox.OnMouseMove:= ListBoxMouseMove; FAutoComplete:= True; FFileSortType:= fstFoldersFirst; FObjectTypes:= [otNonFolders, otFolders]; end; end. doublecmd-0.8.2/components/KASToolBar/dwtaskbarlist.pas0000664000175000017500000001446612014201074022160 0ustar alexxalexxunit dwTaskbarList; {$mode delphi}{$H+} interface uses Messages , Windows ; const CLSID_TaskbarList: TGUID = '{56FDF344-FD6D-11D0-958A-006097C9A090}'; CLSID_TaskbarList2: TGUID = '{602D4995-B13A-429B-A66E-1935E44F4317}'; CLSID_TaskbarList3: TGUID = '{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}'; const THBF_ENABLED = $0000; THBF_DISABLED = $0001; THBF_DISMISSONCLICK = $0002; THBF_NOBACKGROUND = $0004; THBF_HIDDEN = $0008; const THB_BITMAP = $0001; THB_ICON = $0002; THB_TOOLTIP = $0004; THB_FLAGS = $0008; const THBN_CLICKED = $1800; const TBPF_NOPROGRESS = $00; TBPF_INDETERMINATE = $01; TBPF_NORMAL = $02; TBPF_ERROR= $04; TBPF_PAUSED = $08; const TBATF_USEMDITHUMBNAIL: DWORD = $00000001; TBATF_USEMDILIVEPREVIEW: DWORD = $00000002; const WM_DWMSENDICONICTHUMBNAIL = $0323; WM_DWMSENDICONICLIVEPREVIEWBITMAP = $0326; type TTipString = array[0..259] of WideChar; PTipString = ^TTipString; tagTHUMBBUTTON = packed record dwMask : DWORD; iId , iBitmap : UINT; hIcon : HICON; szTip : TTipString; dwFlags : DWORD; end; THUMBBUTTON = tagTHUMBBUTTON; THUMBBUTTONLIST = ^THUMBBUTTON; TThumbButton = THUMBBUTTON; TThumbButtonList = array of TThumbButton; type ITaskbarList = interface ['{56FDF342-FD6D-11D0-958A-006097C9A090}'] procedure HrInit; safecall; procedure AddTab(hwnd: HWND); safecall; procedure DeleteTab(hwnd: HWND); safecall; procedure ActivateTab(hwnd: HWND); safecall; procedure SetActiveAlt(hwnd: HWND); safecall; end; ITaskbarList2 = interface(ITaskbarList) ['{602D4995-B13A-429B-A66E-1935E44F4317}'] procedure MarkFullscreenWindow(hwnd: HWND; fFullscreen: Bool); safecall; end; ITaskbarList3 = interface(ITaskbarList2) ['{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}'] procedure SetProgressValue(hwnd: HWND; ullCompleted, ullTotal: ULONGLONG); safecall; procedure SetProgressState(hwnd: HWND; tbpFlags: DWORD); safecall; procedure RegisterTab(hwndTab: HWND; hwndMDI: HWND); safecall; procedure UnregisterTab(hwndTab: HWND); safecall; procedure SetTabOrder(hwndTab: HWND; hwndInsertBefore: HWND); safecall; procedure SetTabActive(hwndTab: HWND; hwndMDI: HWND; tbatFlags: DWORD); safecall; procedure ThumbBarAddButtons(hwnd: HWND; cButtons: UINT; Button: THUMBBUTTONLIST); safecall; procedure ThumbBarUpdateButtons(hwnd: HWND; cButtons: UINT; pButton: THUMBBUTTONLIST); safecall; procedure ThumbBarSetImageList(hwnd: HWND; himl: HIMAGELIST); safecall; procedure SetOverlayIcon(hwnd: HWND; hIcon: HICON; pszDescription: LPCWSTR); safecall; procedure SetThumbnailTooltip(hwnd: HWND; pszTip: LPCWSTR); safecall; procedure SetThumbnailClip(hwnd: HWND; prcClip: PRect); safecall; end; const DWM_SIT_DISPLAYFRAME = $00000001; // Display a window frame around the provided bitmap DWMWA_FORCE_ICONIC_REPRESENTATION = 7; // [set] Force this window to display iconic thumbnails. DWMWA_HAS_ICONIC_BITMAP = 10; // [set] Indicates an available bitmap when there is no better thumbnail representation. DWMWA_DISALLOW_PEEK = 11; // [set] Don't invoke Peek on the window. type TWMDwmSendIconicLivePreviewBitmap = TWMNoParams; TWMDwmSendIconicThumbnail = packed record Msg : Cardinal; Unused : Integer; Height , Width : Word; Result : LongInt; end; function DwmInvalidateIconicBitmaps(hwnd: HWND): HRESULT; function DwmSetIconicLivePreviewBitmap(hwnd: HWND; hbmp: HBITMAP; pptClient: PPoint; dwSITFlags: DWORD): HRESULT; function DwmSetIconicThumbnail(hWnd: HWND; hBmp: HBITMAP; dwSITFlags: DWORD): HRESULT; function DwmSetWindowAttribute(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; function PrintWindow(hwnd: HWND; hdcBlt: HDC; nFlags: UINT): BOOL; implementation var hDWMAPI: HMODULE; _DwmInvalidateIconicBitmaps: function(hwnd: HWND): HRESULT; stdcall; _DwmSetIconicThumbnail: function(hWnd: HWND; hBmp: HBITMAP; dwSITFlags: DWORD): HRESULT; stdcall; _DwmSetIconicLivePreviewBitmap: function(hwnd: HWND; hbmp: HBITMAP; pptClient: PPoint; dwSITFlags: DWORD): HRESULT; stdcall; _DwmSetWindowAttribute: function(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; stdcall; _PrintWindow: function(hwnd: HWND; hdcBlt: HDC; nFlags: UINT): BOOL; stdcall; procedure InitDwmApi; begin if hDWMAPI = 0 then begin hDWMAPI := LoadLibrary('DWMAPI.DLL'); if hDWMAPI = 0 then begin hDWMAPI := THandle(-1); end else begin _DwmInvalidateIconicBitmaps := GetProcAddress(hDWMAPI, 'DwmInvalidateIconicBitmaps'); _DwmSetIconicLivePreviewBitmap := GetProcAddress(hDWMAPI, 'DwmSetIconicLivePreviewBitmap'); _DwmSetIconicThumbnail := GetProcAddress(hDWMAPI, 'DwmSetIconicThumbnail'); _DwmSetWindowAttribute := GetProcAddress(hDWMAPI, 'DwmSetWindowAttribute'); end; end; end; function DwmInvalidateIconicBitmaps(hwnd: HWND): HRESULT; begin InitDwmApi; if Assigned(_DwmInvalidateIconicBitmaps) then Result := _DwmInvalidateIconicBitmaps(hwnd) else Result := E_NOTIMPL; end; function DwmSetIconicLivePreviewBitmap(hwnd: HWND; hbmp: HBITMAP; pptClient: PPoint; dwSITFlags: DWORD): HRESULT; begin InitDwmApi; if Assigned(_DwmSetIconicLivePreviewBitmap) then Result := _DwmSetIconicLivePreviewBitmap(hwnd, hbmp, pptClient, dwSITFlags) else Result := E_NOTIMPL; end; function DwmSetIconicThumbnail(hWnd: HWND; hBmp: HBITMAP; dwSITFlags: DWORD): HRESULT; begin InitDwmApi; if Assigned(_DwmSetIconicThumbnail) then Result := _DwmSetIconicThumbnail(hWnd, hBmp, dwSITFlags) else Result := E_NOTIMPL; end; function DwmSetWindowAttribute(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; begin InitDwmApi; if Assigned(_DwmSetWindowAttribute) then Result := _DwmSetWindowAttribute(hwnd, dwAttribute, pvAttribute, cbAttribute) else Result := E_NOTIMPL; end; {-----------------------------------------------} function PrintWindow(hwnd: HWND; hdcBlt: HDC; nFlags: UINT): BOOL; begin if Assigned(_PrintWindow) then begin Result := _PrintWindow(hwnd, hdcBlt, nFlags); end else begin _PrintWindow := GetProcAddress(GetModuleHandle('user32.dll'), 'PrintWindow'); Result := Assigned(_PrintWindow) and _PrintWindow(hwnd, hdcBlt, nFlags); end; end; end. doublecmd-0.8.2/components/KASToolBar/kascomp.lpk0000664000175000017500000000440112144672601020742 0ustar alexxalexx doublecmd-0.8.2/components/doublecmd/0000775000175000017500000000000013244011205016620 5ustar alexxalexxdoublecmd-0.8.2/components/doublecmd/dcunicodeutils.pas0000664000175000017500000003612512756114647022377 0ustar alexxalexx{ Most of this code is based on similar functions from Lazarus LCLProc. } unit DCUnicodeUtils; {$mode objfpc}{$H+} interface uses Classes, SysUtils; {en Retrieves length in bytes of the next UTF-8 character. @param(P Pointer to the UTF-8 characters.) @param(aMaxBytes States how many bytes from P can be read.) @param(InvalidCharLen If an invalid UTF-8 character was found then InvalidCharLen has the number of bytes this character spans. If the character was valid InvalidCharLen is zero.) } function SafeUTF8NextCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer; {en Retrieves length in bytes of the previous UTF-8 character. It does not read from P, but rather from memory locations before P. @param(P Pointer to the UTF-8 characters.) @param(aMaxBytes States how many bytes from P *backwards* can be read. So, to safely read 3 bytes backwards ([p-1], [p-2], [p-3]) this parameter should be at least 3.) @param(InvalidCharLen If an invalid UTF-8 character was found then InvalidCharLen has the number of bytes this character spans. If the character was valid InvalidCharLen is zero.) } function SafeUTF8PrevCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer; function SafeUTF8NextCharStart(UTF8Str: PByte; Len: PtrInt): PByte; function SafeUTF8PrevCharEnd(UTF8Str: PByte; Len: PtrInt): PByte; {en Returns UTF-16 character length, which is either 1 or 2. @param(utf16char Any UTF-16 char or one of the surrogate pairs.) } function UTF16CharLen(utf16char: Word): Integer; {en Converts an UTF-16 surrogate pair into a unicode character. } function utf16PairToUnicode(u1, u2: Word): Cardinal; function Utf16LEToUtf8(const s: string): string; // UTF16-LE 2 or 4 byte little endian function Utf16BEToUtf8(const s: string): string; // UTF16-BE 2 or 4 byte big endian function Utf32LEToUtf8(const s: string): string; // UTF32-LE 4 byte little endian function Utf32BEToUtf8(const s: string): string; // UTF32-BE 4 byte big endian function Utf8ToUtf16LE(const s: string): string; // UTF16-LE 2 or 4 byte little endian function Utf8ToUtf16BE(const s: string): string; // UTF16-BE 2 or 4 byte big endian function UTF8ToUCS4(const UTF8Text: String): UCS4String; {en Replaces invalid UTF-8 characters with '?'. } function Utf8ReplaceBroken(const s: String): String; {en Replaces invalid UTF-8 characters with 0x1A (SUBSTITUTE). } procedure Utf8FixBroken(var S: String); procedure Utf16SwapEndian(var S: UnicodeString); implementation uses LazUTF8; const maxUTF8Len = 7; // really is 4, but this includes any invalid characters up to length 7 function SafeUTF8NextCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer; var BytesLen: Integer; i: Integer; begin if (p=nil) or (aMaxBytes = 0) then begin InvalidCharLen := 0; Result := 0; end else if p^<%10000000 then begin // regular single byte character InvalidCharLen := 0; Result := 1; end else if p^<%11000000 then begin // invalid single byte character InvalidCharLen := 1; Result := 1; end else begin // Read length of UTF-8 character in bytes. if ((p^ and %11100000) = %11000000) then BytesLen := 2 else if ((p^ and %11110000) = %11100000) then BytesLen := 3 else if ((p^ and %11111000) = %11110000) then BytesLen := 4 else if ((p^ and %11111100) = %11111000) then BytesLen := 5 else if ((p^ and %11111110) = %11111100) then BytesLen := 6 else if ((p^ and %11111111) = %11111110) then BytesLen := 7 else begin InvalidCharLen := 1; exit(1); end; // Check if the next bytes are from the middle of a character. for i := 1 to BytesLen - 1 do begin if (aMaxBytes < i) or ((p[i] and %11000000) <> %10000000) then begin InvalidCharLen := i; exit(1); end; end; InvalidCharLen := 0; Result := BytesLen; end; end; function SafeUTF8PrevCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer; var BytesLen: Integer; signature: Byte; begin if (p=nil) or (aMaxBytes = 0) then begin InvalidCharLen := 0; Result := 0; end else if p[-1]<%10000000 then begin // regular single byte character InvalidCharLen := 0; Result := 1; end else begin for BytesLen := 1 to maxUTF8Len do begin if (aMaxBytes < BytesLen) then begin InvalidCharLen := aMaxBytes; exit(1); end; // Move past all the bytes in the middle of a character. if (p[-BytesLen] and %11000000) <> %10000000 then break; if BytesLen = maxUTF8Len then begin InvalidCharLen := BytesLen; exit(1); end; end; if p[-BytesLen]<%11000000 then begin // invalid first byte of a character InvalidCharLen := BytesLen; Result := 1; end else begin signature := Byte($FF shl (7 - BytesLen)); if (p[-BytesLen] and signature) = Byte(signature shl 1) then begin // Correct first byte of a character. InvalidCharLen := 0; Result := BytesLen; end else begin // Invalid first byte of a character, or p is in the middle of a character. InvalidCharLen := BytesLen; Result := 1; end; end; end; end; function SafeUTF8NextCharStart(UTF8Str: PByte; Len: PtrInt): PByte; var CharLen: LongInt; InvalidCharLen: Integer; begin Result:=UTF8Str; if Result<>nil then begin while (Len>0) do begin CharLen := SafeUTF8NextCharLen(Result, Len, InvalidCharLen); if InvalidCharLen > 0 then begin dec(Len,InvalidCharLen); inc(Result,InvalidCharLen); end else if CharLen = 0 then exit(nil) else exit(Result); end; Result:=nil; end; end; function SafeUTF8PrevCharEnd(UTF8Str: PByte; Len: PtrInt): PByte; var CharLen: LongInt; InvalidCharLen: Integer; begin Result:=UTF8Str; if Result<>nil then begin while (Len>0) do begin CharLen := SafeUTF8PrevCharLen(Result, Len, InvalidCharLen); if InvalidCharLen > 0 then begin dec(Len,InvalidCharLen); dec(Result,InvalidCharLen); end else if CharLen = 0 then exit(nil) else exit(Result); // Result is the character beginning end; Result:=nil; end; end; function UTF16CharLen(utf16char: Word): Integer; inline; begin if (utf16char < $D800) or (utf16char > $DFFF) then Result := 1 else Result := 2; end; function utf16PairToUnicode(u1, u2: Word): Cardinal; begin if (u1 >= $D800) and (u1 <= $DBFF) then begin if (u2 >= $DC00) and (u2 <= $DFFF) then Result := (Cardinal(u1 - $D800) shl 10) + Cardinal(u2 - $DC00) + $10000 else Result := 0; end else Result := u1; end; function Utf16LEToUtf8(const s: string): string; var len: Integer; Src, Limit: PWord; Dest: PAnsiChar; u: Cardinal; begin if Length(s) < 2 then begin Result:=''; exit; end; Src:=PWord(Pointer(s)); Limit := PWord(Pointer(Src) + Length(s)); SetLength(Result, length(s) * 2); Dest:=PAnsiChar(Result); while Src + 1 <= Limit do begin len := UTF16CharLen(Src^); if len = 1 then u := LEtoN(Src^) else begin if Src + 2 <= Limit then u := utf16PairToUnicode(LEtoN(Src[0]), LEtoN(Src[1])) else break; end; inc(Src, len); if u<128 then begin Dest^:=chr(u); inc(Dest); end else begin inc(Dest,UnicodeToUTF8SkipErrors(u,Dest)); end; end; len:=PtrUInt(Dest)-PtrUInt(Result); Assert(len <= length(Result)); SetLength(Result,len); end; function Utf16BEToUtf8(const s: string): string; var len: Integer; Src, Limit: PWord; Dest: PAnsiChar; u: Cardinal; begin if Length(s) < 2 then begin Result:=''; exit; end; Src:=PWord(Pointer(s)); Limit := PWord(Pointer(Src) + Length(s)); SetLength(Result, length(s) * 2); Dest:=PAnsiChar(Result); while Src + 1 <= Limit do begin len := UTF16CharLen(Src^); if len = 1 then u := BEtoN(Src^) else begin if Src + 2 <= Limit then u := utf16PairToUnicode(BEtoN(Src[0]), BEtoN(Src[1])) else break; end; inc(Src, len); if u<128 then begin Dest^:=chr(u); inc(Dest); end else begin inc(Dest,UnicodeToUTF8SkipErrors(u,Dest)); end; end; len:=PtrUInt(Dest)-PtrUInt(Result); Assert(len <= length(Result)); SetLength(Result,len); end; function Utf32LEToUtf8(const s: string): string; var len: Integer; Src: PLongWord; Dest: PAnsiChar; i: Integer; c: LongWord; begin if Length(s) < 4 then begin Result:=''; exit; end; len:=length(s) div 4; SetLength(Result,len*4); Src:=PLongWord(Pointer(s)); Dest:=PAnsiChar(Result); for i:=1 to len do begin c:=LEtoN(Src^); inc(Src); if c<128 then begin Dest^:=chr(c); inc(Dest); end else begin inc(Dest,UnicodeToUTF8SkipErrors(c,Dest)); end; end; len:=PtrUInt(Dest)-PtrUInt(Result); Assert(len <= length(Result)); SetLength(Result,len); end; function Utf32BEToUtf8(const s: string): string; var len: Integer; Src: PLongWord; Dest: PAnsiChar; i: Integer; c: LongWord; begin if Length(s) < 4 then begin Result:=''; exit; end; len:=length(s) div 4; SetLength(Result,len*4); Src:=PLongWord(Pointer(s)); Dest:=PAnsiChar(Result); for i:=1 to len do begin c:=BEtoN(Src^); inc(Src); if c<128 then begin Dest^:=chr(c); inc(Dest); end else begin inc(Dest,UnicodeToUTF8SkipErrors(c,Dest)); end; end; len:=PtrUInt(Dest)-PtrUInt(Result); Assert(len <= length(Result)); SetLength(Result,len); end; function Utf8ToUtf16LE(const s: string): string; var L: SizeUInt; {$IF DEFINED(ENDIAN_BIG)} P: PWord; I: SizeInt; {$ENDIF} begin if Length(S) = 0 then begin Result := ''; Exit; end; // Wide chars of UTF-16 <= bytes of UTF-8 string SetLength(Result, Length(S) * SizeOf(WideChar)); if ConvertUTF8ToUTF16(PWideChar(PAnsiChar(Result)), Length(Result) + SizeOf(WideChar), PAnsiChar(S), Length(S), [toInvalidCharToSymbol], L) <> trNoError then Result := '' else begin SetLength(Result, (L - 1) * SizeOf(WideChar)); // Swap endian if needed {$IF DEFINED(ENDIAN_BIG)} P := PWord(PAnsiChar(Result)); for I := 0 to SizeInt(L) - 1 do begin P[I] := SwapEndian(P[I]); end; {$ENDIF} end; end; function Utf8ToUtf16BE(const s: string): string; var L: SizeUInt; {$IF DEFINED(ENDIAN_LITTLE)} P: PWord; I: SizeInt; {$ENDIF} begin if Length(S) = 0 then begin Result := ''; Exit; end; // Wide chars of UTF-16 <= bytes of UTF-8 string SetLength(Result, Length(S) * SizeOf(WideChar)); if ConvertUTF8ToUTF16(PWideChar(PAnsiChar(Result)), Length(Result) + SizeOf(WideChar), PAnsiChar(S), Length(S), [toInvalidCharToSymbol], L) <> trNoError then Result := '' else begin SetLength(Result, (L - 1) * SizeOf(WideChar)); // Swap endian if needed {$IF DEFINED(ENDIAN_LITTLE)} P := PWord(PAnsiChar(Result)); for I := 0 to SizeInt(L) - 1 do begin P[I] := SwapEndian(P[I]); end; {$ENDIF} end; end; function UTF8ToUCS4(const UTF8Text: String): UCS4String; var Len: PtrInt; Index: Integer; CharLen: Integer; SrcPos: PAnsiChar; begin Len:= Length(UTF8Text); SetLength(Result, Len); if Len = 0 then Exit; Index:= 0; SrcPos:= PAnsiChar(UTF8Text); while Len > 0 do begin Result[Index]:= UTF8CharacterToUnicode(SrcPos, CharLen); Inc(SrcPos, CharLen); Dec(Len, CharLen); Inc(Index); end; SetLength(Result, Index); end; function Utf8ReplaceBroken(const s: String): String; var Src, Dst, LastGoodPos: PByte; BytesLeft: Integer; InvalidCharLen: Integer; CharLen: Integer; begin if Length(s) = 0 then Exit(s); BytesLeft := Length(s); SetLength(Result, BytesLeft); // at most the same length Src := PByte(s); Dst := PByte(Result); LastGoodPos := Src; while BytesLeft > 0 do begin CharLen := SafeUTF8NextCharLen(Src, BytesLeft, InvalidCharLen); if InvalidCharLen > 0 then begin if LastGoodPos < Src then begin System.Move(LastGoodPos^, Dst^, Src - LastGoodPos); Inc(Dst, Src - LastGoodPos); end; Inc(Src, InvalidCharLen); Dec(BytesLeft, InvalidCharLen); LastGoodPos := Src; Dst^ := ord('?'); Inc(Dst); end else begin Inc(Src, CharLen); Dec(BytesLeft, CharLen); end; end; if LastGoodPos = PByte(s) then Result := s // All characters are good. else begin if LastGoodPos < Src then begin System.Move(LastGoodPos^, Dst^, Src - LastGoodPos); Inc(Dst, Src - LastGoodPos); end; SetLength(Result, Dst - PByte(Result)); end; end; procedure Utf8FixBroken(var S: String); var P: PAnsiChar; C, L: Integer; begin L:= Length(S); P:= Pointer(S); while (L > 0) do begin if Ord(P^) < %10000000 then begin // Regular single byte character C:= 1; end else if Ord(P^) < %11000000 then begin // Invalid character C:= 1; P^:= #26; end else if ((Ord(P^) and %11100000) = %11000000) then begin // Should be 2 byte character if (L > 1) and ((Ord(P[1]) and %11000000) = %10000000) then C:= 2 else begin // Invalid character C:= 1; P^:= #26; end; end else if ((Ord(P^) and %11110000) = %11100000) then begin // Should be 3 byte character if (L > 2) and ((Ord(P[1]) and %11000000) = %10000000) and ((Ord(P[2]) and %11000000) = %10000000) then C:= 3 else begin // Invalid character C:= 1; P^:= #26; end end else if ((Ord(P^) and %11111000) = %11110000) then begin // Should be 4 byte character if (L > 3) and ((Ord(P[1]) and %11000000) = %10000000) and ((Ord(P[2]) and %11000000) = %10000000) and ((Ord(P[3]) and %11000000) = %10000000) then C:= 4 else begin // Invalid character C:= 1; P^:= #26; end end else begin // Invalid character C:= 1; P^:= #26; end; Dec(L, C); Inc(P, C); end; end; procedure Utf16SwapEndian(var S: UnicodeString); var P: PWord; I, L: Integer; begin L:= Length(S); P:= PWord(PWideChar(S)); for I:= 0 to L - 1 do begin P[I]:= SwapEndian(P[I]); end; end; end. doublecmd-0.8.2/components/doublecmd/dcosutils.pas0000664000175000017500000012405613243630337021362 0ustar alexxalexx{ Double Commander ------------------------------------------------------------------------- This unit contains platform dependent functions dealing with operating system. Copyright (C) 2006-2017 Alexander Koblov (alexx2000@mail.ru) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } unit DCOSUtils; {$mode objfpc}{$H+} interface uses SysUtils, Classes, DynLibs, DCClassesUtf8, DCBasicTypes; const fmOpenSync = $10000; fmOpenDirect = $20000; fmOpenNoATime = $40000; type TFileMapRec = record FileHandle : System.THandle; FileSize : Int64; {$IFDEF MSWINDOWS} MappingHandle : System.THandle; {$ENDIF} MappedFile : Pointer; end; TCopyAttributesOption = (caoCopyAttributes, caoCopyTime, caoCopyOwnership, caoCopyPermissions, caoRemoveReadOnlyAttr); TCopyAttributesOptions = set of TCopyAttributesOption; const faInvalidAttributes: TFileAttrs = TFileAttrs(-1); CopyAttributesOptionCopyAll = [caoCopyAttributes, caoCopyTime, caoCopyOwnership]; {en Is file a directory @param(iAttr File attributes) @returns(@true if file is a directory, @false otherwise) } function FPS_ISDIR(iAttr: TFileAttrs) : Boolean; {en Is file a symbolic link @param(iAttr File attributes) @returns(@true if file is a symbolic link, @false otherwise) } function FPS_ISLNK(iAttr: TFileAttrs) : Boolean; {en Is file executable @param(sFileName File name) @returns(@true if file is executable, @false otherwise) } function FileIsExeLib(const sFileName : String) : Boolean; {en Copies a file attributes (attributes, date/time, owner & group, permissions). @param(sSrc String expression that specifies the name of the file to be copied) @param(sDst String expression that specifies the target file name) @param(bDropReadOnlyFlag Drop read only attribute if @true) @returns(The function returns @true if successful, @false otherwise) } function FileIsReadOnly(iAttr: TFileAttrs): Boolean; inline; {en Returns path to a temporary name. It ensures that returned path doesn't exist, i.e., there is no filesystem entry by that name. If it could not create a unique temporary name then it returns empty string. @param(PathPrefix This parameter is added at the beginning of each path that is tried. The directories in this path are not created if they don't exist. If it is empty then the system temporary directory is used. For example: If PathPrefix is '/tmp/myfile' then files '/tmp/myfileXXXXXX' are tried. The path '/tmp' must already exist.) } function GetTempName(PathPrefix: String): String; (* File mapping/unmapping routines *) {en Create memory map of a file @param(sFileName Name of file to mapping) @param(FileMapRec TFileMapRec structure) @returns(The function returns @true if successful, @false otherwise) } function MapFile(const sFileName : String; out FileMapRec : TFileMapRec) : Boolean; {en Unmap previously mapped file @param(FileMapRec TFileMapRec structure) } procedure UnMapFile(var FileMapRec : TFileMapRec); {en Convert from console to UTF8 encoding. } function ConsoleToUTF8(const Str: AnsiString): String; { File handling functions} function mbFileOpen(const FileName: String; Mode: LongWord): System.THandle; function mbFileCreate(const FileName: String): System.THandle; overload; inline; function mbFileCreate(const FileName: String; Mode: LongWord): System.THandle; overload; inline; function mbFileCreate(const FileName: String; Mode, Rights: LongWord): System.THandle; overload; function mbFileAge(const FileName: String): DCBasicTypes.TFileTime; function mbFileSame(const FirstName, SecondName: String): Boolean; // On success returns True. function mbFileGetTime(const FileName: String; var ModificationTime: DCBasicTypes.TFileTime; var CreationTime : DCBasicTypes.TFileTime; var LastAccessTime : DCBasicTypes.TFileTime): Boolean; // On success returns True. function mbFileSetTime(const FileName: String; ModificationTime: DCBasicTypes.TFileTime; CreationTime : DCBasicTypes.TFileTime = 0; LastAccessTime : DCBasicTypes.TFileTime = 0): Boolean; {en Checks if a given file exists - it can be a real file or a link to a file, but it can be opened and read from. Even if the result is @false, we can't be sure a file by that name can be created, because there may still exist a directory or link by that name. } function mbFileExists(const FileName: String): Boolean; function mbFileAccess(const FileName: String; Mode: Word): Boolean; function mbFileGetAttr(const FileName: String): TFileAttrs; overload; function mbFileSetAttr(const FileName: String; Attr: TFileAttrs) : LongInt; function mbFileGetAttr(const FileName: String; out Attr: TSearchRec): Boolean; overload; {en If any operation in Options is performed and does not succeed it is included in the result set. If all performed operations succeed the function returns empty set. For example for Options=[caoCopyTime, caoCopyOwnership] setting ownership doesn't succeed then the function returns [caoCopyOwnership]. } function mbFileCopyAttr(const sSrc, sDst: String; Options: TCopyAttributesOptions): TCopyAttributesOptions; // Returns True on success. function mbFileSetReadOnly(const FileName: String; ReadOnly: Boolean): Boolean; function mbDeleteFile(const FileName: String): Boolean; function mbRenameFile(const OldName: String; NewName: String): Boolean; function mbFileSize(const FileName: String): Int64; function FileFlush(Handle: System.THandle): Boolean; { Directory handling functions} function mbGetCurrentDir: String; function mbSetCurrentDir(const NewDir: String): Boolean; {en Checks if a given directory exists - it may be a real directory or a link to directory. Even if the result is @false, we can't be sure a directory by that name can be created, because there may still exist a file or link by that name. } function mbDirectoryExists(const Directory : String) : Boolean; function mbCreateDir(const NewDir: String): Boolean; function mbRemoveDir(const Dir: String): Boolean; {en Checks if any file system entry exists at given path. It can be file, directory, link, etc. (links are not followed). } function mbFileSystemEntryExists(const Path: String): Boolean; function mbCompareFileNames(const FileName1, FileName2: String): Boolean; function mbSameFile(const FileName1, FileName2: String): Boolean; { Other functions } function mbGetEnvironmentString(Index : Integer) : String; {en Expands environment-variable strings and replaces them with the values defined for the current user } function mbExpandEnvironmentStrings(const FileName: String): String; function mbSysErrorMessage: String; overload; inline; function mbSysErrorMessage(ErrorCode: Integer): String; overload; {en Get current module name } function mbGetModuleName(Address: Pointer = nil): String; function mbLoadLibrary(const Name: String): TLibHandle; function SafeGetProcAddress(Lib: TLibHandle; const ProcName: AnsiString): Pointer; {en Create a hard link to a file @param(Path Name of file) @param(LinkName Name of hard link) @returns(The function returns @true if successful, @false otherwise) } function CreateHardLink(const Path, LinkName: String) : Boolean; {en Create a symbolic link @param(Path Name of file) @param(LinkName Name of symbolic link) @returns(The function returns @true if successful, @false otherwise) } function CreateSymLink(const Path, LinkName: string) : Boolean; {en Read destination of symbolic link @param(LinkName Name of symbolic link) @returns(The file name/path the symbolic link name is pointing to. The path may be relative to link's location.) } function ReadSymLink(const LinkName : String) : String; implementation uses {$IF DEFINED(MSWINDOWS)} Windows, JwaWinNetWk, DCDateTimeUtils, DCWindows, DCNtfsLinks, {$ENDIF} {$IF DEFINED(UNIX)} BaseUnix, Unix, dl, DCUnix, {$ENDIF} DCConvertEncoding, DCStrUtils, LazUTF8; {$IFDEF UNIX} function SetModeReadOnly(mode: TMode; ReadOnly: Boolean): TMode; begin mode := mode and not (S_IWUSR or S_IWGRP or S_IWOTH); if ReadOnly = False then begin if (mode AND S_IRUSR) = S_IRUSR then mode := mode or S_IWUSR; if (mode AND S_IRGRP) = S_IRGRP then mode := mode or S_IWGRP; if (mode AND S_IROTH) = S_IROTH then mode := mode or S_IWOTH; end; Result := mode; end; {$ENDIF} {$IF DEFINED(MSWINDOWS)} const AccessModes: array[0..2] of DWORD = ( GENERIC_READ, GENERIC_WRITE, GENERIC_READ or GENERIC_WRITE); ShareModes: array[0..4] of DWORD = ( 0, 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE); OpenFlags: array[0..3] of DWORD = ( 0, FILE_FLAG_WRITE_THROUGH, FILE_FLAG_NO_BUFFERING, FILE_FLAG_WRITE_THROUGH or FILE_FLAG_NO_BUFFERING); var CurrentDirectory: String; {$ELSEIF DEFINED(UNIX)} const {$IF NOT DECLARED(O_SYNC)} O_SYNC = 0; {$ENDIF} {$IF NOT DECLARED(O_DIRECT)} O_DIRECT = 0; {$ENDIF} AccessModes: array[0..2] of cInt = ( O_RdOnly, O_WrOnly, O_RdWr); OpenFlags: array[0..3] of cInt = ( 0, O_SYNC, O_DIRECT, O_SYNC or O_DIRECT); {$ENDIF} (*Is Directory*) function FPS_ISDIR(iAttr: TFileAttrs) : Boolean; inline; {$IFDEF MSWINDOWS} begin Result := (iAttr and FILE_ATTRIBUTE_DIRECTORY <> 0); end; {$ELSE} begin Result := BaseUnix.FPS_ISDIR(iAttr); end; {$ENDIF} (*Is Link*) function FPS_ISLNK(iAttr: TFileAttrs) : Boolean; inline; {$IFDEF MSWINDOWS} begin Result := (iAttr and FILE_ATTRIBUTE_REPARSE_POINT <> 0); end; {$ELSE} begin Result := BaseUnix.FPS_ISLNK(iAttr); end; {$ENDIF} function FileIsExeLib(const sFileName : String) : Boolean; var fsExeLib : TFileStreamEx; {$IFDEF MSWINDOWS} Sign : Word; {$ELSE} Sign : DWord; {$ENDIF} begin Result := False; if mbFileExists(sFileName) and (mbFileSize(sFileName) >= SizeOf(Sign)) then try fsExeLib := TFileStreamEx.Create(sFileName, fmOpenRead or fmShareDenyNone); try {$IFDEF MSWINDOWS} Sign := fsExeLib.ReadWord; Result := (Sign = $5A4D); {$ELSE} Sign := fsExeLib.ReadDWord; Result := (Sign = $464C457F); {$ENDIF} finally fsExeLib.Free; end; except Result := False; end; end; function FileIsReadOnly(iAttr: TFileAttrs): Boolean; {$IFDEF MSWINDOWS} begin Result:= (iAttr and (faReadOnly or faHidden or faSysFile)) <> 0; end; {$ELSE} begin Result:= (((iAttr AND S_IRUSR) = S_IRUSR) and ((iAttr AND S_IWUSR) <> S_IWUSR)); end; {$ENDIF} function mbFileCopyAttr(const sSrc, sDst: String; Options: TCopyAttributesOptions): TCopyAttributesOptions; {$IFDEF MSWINDOWS} var Attr : TFileAttrs; ModificationTime, CreationTime, LastAccessTime: DCBasicTypes.TFileTime; begin Result := []; if caoCopyAttributes in Options then begin Attr := mbFileGetAttr(sSrc); if Attr <> faInvalidAttributes then begin if (caoRemoveReadOnlyAttr in Options) and ((Attr and faReadOnly) <> 0) then Attr := (Attr and not faReadOnly); if mbFileSetAttr(sDst, Attr) <> 0 then Include(Result, caoCopyAttributes); end else Include(Result, caoCopyAttributes); end; if caoCopyTime in Options then begin if not (mbFileGetTime(sSrc, ModificationTime, CreationTime, LastAccessTime) and mbFileSetTime(sDst, ModificationTime, CreationTime, LastAccessTime)) then Include(Result, caoCopyTime); end; if caoCopyPermissions in Options then begin if not CopyNtfsPermissions(sSrc, sDst) then begin Include(Result, caoCopyPermissions); end; end; end; {$ELSE} // *nix var StatInfo : BaseUnix.Stat; utb : BaseUnix.TUTimBuf; mode : TMode; begin if fpLStat(UTF8ToSys(sSrc), StatInfo) >= 0 then begin Result := []; if FPS_ISLNK(StatInfo.st_mode) then begin if caoCopyOwnership in Options then begin // Only group/owner can be set for links. if fpLChown(sDst, StatInfo.st_uid, StatInfo.st_gid) = -1 then begin Include(Result, caoCopyOwnership); end; end; end else begin if caoCopyTime in Options then begin utb.actime := time_t(StatInfo.st_atime); // last access time utb.modtime := time_t(StatInfo.st_mtime); // last modification time if fputime(UTF8ToSys(sDst), @utb) <> 0 then Include(Result, caoCopyTime); end; if caoCopyOwnership in Options then begin if fpChown(PChar(UTF8ToSys(sDst)), StatInfo.st_uid, StatInfo.st_gid) = -1 then begin Include(Result, caoCopyOwnership); end; end; if caoCopyAttributes in Options then begin mode := StatInfo.st_mode; if caoRemoveReadOnlyAttr in Options then mode := SetModeReadOnly(mode, False); if fpChmod(UTF8ToSys(sDst), mode) = -1 then begin Include(Result, caoCopyAttributes); end; end; end; end else Result := Options; end; {$ENDIF} function GetTempName(PathPrefix: String): String; const MaxTries = 100; var TryNumber: Integer = 0; begin if PathPrefix = '' then PathPrefix := GetTempDir; repeat Result := PathPrefix + IntToStr(System.Random(MaxInt)); // or use CreateGUID() Inc(TryNumber); if TryNumber = MaxTries then Exit(''); until not mbFileSystemEntryExists(Result); end; function MapFile(const sFileName : String; out FileMapRec : TFileMapRec) : Boolean; {$IFDEF MSWINDOWS} begin Result := False; with FileMapRec do begin MappedFile := nil; MappingHandle := 0; FileHandle := feInvalidHandle; FileSize := mbFileSize(sFileName); if FileSize = 0 then Exit; // Cannot map empty files FileHandle := mbFileOpen(sFileName, fmOpenRead); if FileHandle = feInvalidHandle then Exit; MappingHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); if MappingHandle <> 0 then begin MappedFile := MapViewOfFile(MappingHandle, FILE_MAP_READ, 0, 0, 0); if not Assigned(MappedFile) then begin UnMapFile(FileMapRec); Exit; end; end else begin UnMapFile(FileMapRec); Exit; end; end; Result := True; end; {$ELSE} var StatInfo: BaseUnix.Stat; begin Result:= False; with FileMapRec do begin MappedFile := nil; FileHandle:= mbFileOpen(sFileName, fmOpenRead); if FileHandle = feInvalidHandle then Exit; if fpfstat(FileHandle, StatInfo) <> 0 then begin UnMapFile(FileMapRec); Exit; end; FileSize := StatInfo.st_size; if FileSize = 0 then // Cannot map empty files begin UnMapFile(FileMapRec); Exit; end; MappedFile:= fpmmap(nil,FileSize,PROT_READ, MAP_PRIVATE{SHARED},FileHandle,0 ); if MappedFile = MAP_FAILED then begin MappedFile := nil; UnMapFile(FileMapRec); Exit; end; end; Result := True; end; {$ENDIF} procedure UnMapFile(var FileMapRec : TFileMapRec); {$IFDEF MSWINDOWS} begin with FileMapRec do begin if Assigned(MappedFile) then begin UnmapViewOfFile(MappedFile); MappedFile := nil; end; if MappingHandle <> 0 then begin CloseHandle(MappingHandle); MappingHandle := 0; end; if FileHandle <> feInvalidHandle then begin FileClose(FileHandle); FileHandle := feInvalidHandle; end; end; end; {$ELSE} begin with FileMapRec do begin if FileHandle <> feInvalidHandle then begin fpClose(FileHandle); FileHandle := feInvalidHandle; end; if Assigned(MappedFile) then begin fpmunmap(MappedFile,FileSize); MappedFile := nil; end; end; end; {$ENDIF} function ConsoleToUTF8(const Str: AnsiString): String; {$IFDEF MSWINDOWS} var Dst: PChar; {$ENDIF} begin Result:= Str; {$IFDEF MSWINDOWS} Dst:= AllocMem((Length(Result) + 1) * SizeOf(Char)); if OEMToChar(PChar(Result), Dst) then Result:= SysToUTF8(Dst); FreeMem(Dst); {$ENDIF} end; function mbFileOpen(const FileName: String; Mode: LongWord): System.THandle; {$IFDEF MSWINDOWS} const ft: TFileTime = ( dwLowDateTime: $FFFFFFFF; dwHighDateTime: $FFFFFFFF; ); begin Result:= CreateFileW(PWideChar(UTF16LongName(FileName)), AccessModes[Mode and 3] or ((Mode and fmOpenNoATime) shr 10), ShareModes[(Mode and $F0) shr 4], nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, OpenFlags[(Mode shr 16) and 3]); if (Mode and fmOpenNoATime <> 0) then begin if (Result <> feInvalidHandle) then SetFileTime(Result, nil, @ft, @ft) else if GetLastError = ERROR_ACCESS_DENIED then Result := mbFileOpen(FileName, Mode and not fmOpenNoATime); end; end; {$ELSE} begin repeat Result:= fpOpen(UTF8ToSys(FileName), AccessModes[Mode and 3] or OpenFlags[(Mode shr 16) and 3] or O_CLOEXEC); until (Result <> -1) or (fpgeterrno <> ESysEINTR); if Result <> feInvalidHandle then begin FileCloseOnExec(Result); Result:= FileLock(Result, Mode and $FF); end; end; {$ENDIF} function mbFileCreate(const FileName: String): System.THandle; begin Result:= mbFileCreate(FileName, fmShareDenyWrite); end; function mbFileCreate(const FileName: String; Mode: LongWord): System.THandle; begin Result:= mbFileCreate(FileName, Mode, 438); // 438 = 666 octal end; function mbFileCreate(const FileName: String; Mode, Rights: LongWord): System.THandle; {$IFDEF MSWINDOWS} begin Result:= CreateFileW(PWideChar(UTF16LongName(FileName)), GENERIC_READ or GENERIC_WRITE, ShareModes[(Mode and $F0) shr 4], nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, OpenFlags[(Mode shr 16) and 3]); end; {$ELSE} begin repeat Result:= fpOpen(UTF8ToSys(FileName), O_Creat or O_RdWr or O_Trunc or OpenFlags[(Mode shr 16) and 3] or O_CLOEXEC, Rights); until (Result <> -1) or (fpgeterrno <> ESysEINTR); if Result <> feInvalidHandle then begin FileCloseOnExec(Result); Result:= FileLock(Result, Mode and $FF); end; end; {$ENDIF} function mbFileAge(const FileName: String): DCBasicTypes.TFileTime; {$IFDEF MSWINDOWS} var Handle: System.THandle; FindData: TWin32FindDataW; begin Handle := FindFirstFileW(PWideChar(UTF16LongName(FileName)), FindData); if Handle <> INVALID_HANDLE_VALUE then begin Windows.FindClose(Handle); if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then Exit(DCBasicTypes.TWinFileTime(FindData.ftLastWriteTime)); end; Result:= DCBasicTypes.TFileTime(-1); end; {$ELSE} var Info: BaseUnix.Stat; begin Result:= DCBasicTypes.TFileTime(-1); if fpStat(UTF8ToSys(FileName), Info) >= 0 then {$PUSH}{$R-} Result := Info.st_mtime; {$POP} end; {$ENDIF} function mbFileSame(const FirstName, SecondName: String): Boolean; {$IFDEF MSWINDOWS} var Handle: System.THandle; lpFirstFileInfo, lpSecondFileInfo: TByHandleFileInformation; begin // Read first file info Handle:= CreateFileW(PWideChar(UTF16LongName(FirstName)), FILE_READ_ATTRIBUTES, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if Handle = INVALID_HANDLE_VALUE then Exit(False); Result:= GetFileInformationByHandle(Handle, lpFirstFileInfo); CloseHandle(Handle); if not Result then Exit; // Read second file info Handle:= CreateFileW(PWideChar(UTF16LongName(SecondName)), FILE_READ_ATTRIBUTES, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if Handle = INVALID_HANDLE_VALUE then Exit(False); Result:= GetFileInformationByHandle(Handle, lpSecondFileInfo); CloseHandle(Handle); if not Result then Exit; // Compare file info Result:= CompareByte(lpFirstFileInfo, lpSecondFileInfo, SizeOf(TByHandleFileInformation)) = 0; end; {$ELSE} var FirstStat, SecondStat: BaseUnix.Stat; begin // Read first file info if fpStat(UTF8ToSys(FirstName), FirstStat) < 0 then Exit(False); // Read second file info if fpStat(UTF8ToSys(SecondName), SecondStat) < 0 then Exit(False); // Compare file info Result:= (FirstStat.st_dev = SecondStat.st_dev) and (FirstStat.st_ino = SecondStat.st_ino); end; {$ENDIF} function mbFileGetTime(const FileName: String; var ModificationTime: DCBasicTypes.TFileTime; var CreationTime : DCBasicTypes.TFileTime; var LastAccessTime : DCBasicTypes.TFileTime): Boolean; {$IFDEF MSWINDOWS} var Handle: System.THandle; begin Handle := CreateFileW(PWideChar(UTF16LongName(FileName)), FILE_READ_ATTRIBUTES, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, // needed for opening directories 0); if Handle <> INVALID_HANDLE_VALUE then begin Result := Windows.GetFileTime(Handle, @CreationTime, @LastAccessTime, @ModificationTime); CloseHandle(Handle); end else Result := False; end; {$ELSE} var StatInfo : BaseUnix.Stat; begin Result := fpLStat(UTF8ToSys(FileName), StatInfo) >= 0; if Result then begin LastAccessTime := StatInfo.st_atime; ModificationTime := StatInfo.st_mtime; CreationTime := StatInfo.st_ctime; end; end; {$ENDIF} function mbFileSetTime(const FileName: String; ModificationTime: DCBasicTypes.TFileTime; CreationTime : DCBasicTypes.TFileTime = 0; LastAccessTime : DCBasicTypes.TFileTime = 0): Boolean; {$IFDEF MSWINDOWS} var Handle: System.THandle; PWinModificationTime: Windows.LPFILETIME = nil; PWinCreationTime: Windows.LPFILETIME = nil; PWinLastAccessTime: Windows.LPFILETIME = nil; begin Handle := CreateFileW(PWideChar(UTF16LongName(FileName)), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, // needed for opening directories 0); if Handle <> INVALID_HANDLE_VALUE then begin if ModificationTime <> 0 then begin PWinModificationTime := @ModificationTime; end; if CreationTime <> 0 then begin PWinCreationTime := @CreationTime; end; if LastAccessTime <> 0 then begin PWinLastAccessTime := @LastAccessTime; end; Result := Windows.SetFileTime(Handle, PWinCreationTime, PWinLastAccessTime, PWinModificationTime); CloseHandle(Handle); end else Result := False; end; {$ELSE} var t: TUTimBuf; CurrentModificationTime, CurrentCreationTime, CurrentLastAccessTime: DCBasicTypes.TFileTime; begin if mbFileGetTime(FileName,CurrentModificationTime, CurrentCreationTime, CurrentLastAccessTime) then begin if LastAccessTime<>0 then t.actime := time_t(LastAccessTime) else t.actime := time_t(CurrentLastAccessTime); if ModificationTime<>0 then t.modtime := time_t(ModificationTime) else t.modtime := time_t(CurrentModificationTime); Result := (fputime(UTF8ToSys(FileName), @t) <> -1); end else begin Result:=False; end; end; {$ENDIF} function mbFileExists(const FileName: String) : Boolean; {$IFDEF MSWINDOWS} var Attr: DWORD; begin Attr:= GetFileAttributesW(PWideChar(UTF16LongName(FileName))); if Attr <> DWORD(-1) then Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) = 0 else Result:=False; end; {$ELSE} var Info: BaseUnix.Stat; begin // Can use fpStat, because link to an existing filename can be opened as if it were a real file. if fpStat(UTF8ToSys(FileName), Info) >= 0 then Result:= fpS_ISREG(Info.st_mode) else Result:= False; end; {$ENDIF} function mbFileAccess(const FileName: String; Mode: Word): Boolean; {$IFDEF MSWINDOWS} const AccessMode: array[0..2] of DWORD = ( GENERIC_READ, GENERIC_WRITE, GENERIC_READ or GENERIC_WRITE); var hFile: System.THandle; dwDesiredAccess: DWORD; dwShareMode: DWORD = 0; begin dwDesiredAccess := AccessMode[Mode and 3]; if Mode = fmOpenRead then // If checking Read mode no sharing mode given Mode := Mode or fmShareDenyNone; dwShareMode := ShareModes[(Mode and $F0) shr 4]; hFile:= CreateFileW(PWideChar(UTF16LongName(FileName)), dwDesiredAccess, dwShareMode, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); Result := hFile <> INVALID_HANDLE_VALUE; if Result then FileClose(hFile); end; {$ELSE} const AccessMode: array[0..2] of LongInt = ( R_OK, W_OK, R_OK or W_OK); begin Result:= fpAccess(UTF8ToSys(FileName), AccessMode[Mode and 3]) = 0; end; {$ENDIF} {$IFOPT R+} {$DEFINE uOSUtilsRangeCheckOn} {$R-} {$ENDIF} function mbFileGetAttr(const FileName: String): TFileAttrs; {$IFDEF MSWINDOWS} begin Result := GetFileAttributesW(PWideChar(UTF16LongName(FileName))); end; {$ELSE} var Info: BaseUnix.Stat; begin if fpLStat(UTF8ToSys(FileName), @Info) >= 0 then Result:= Info.st_mode else Result:= faInvalidAttributes; end; {$ENDIF} function mbFileSetAttr(const FileName: String; Attr: TFileAttrs): LongInt; {$IFDEF MSWINDOWS} begin if SetFileAttributesW(PWideChar(UTF16LongName(FileName)), Attr) then Result:= 0 else Result:= GetLastError; end; {$ELSE} begin Result:= fpchmod(UTF8ToSys(FileName), Attr); end; {$ENDIF} function mbFileGetAttr(const FileName: String; out Attr: TSearchRec): Boolean; {$IFDEF MSWINDOWS} var FileInfo: Windows.TWin32FileAttributeData; begin Result:= GetFileAttributesExW(PWideChar(UTF16LongName(FileName)), GetFileExInfoStandard, @FileInfo); if Result then begin WinToDosTime(FileInfo.ftLastWriteTime, Attr.Time); Int64Rec(Attr.Size).Lo:= FileInfo.nFileSizeLow; Int64Rec(Attr.Size).Hi:= FileInfo.nFileSizeHigh; Attr.Attr:= FileInfo.dwFileAttributes; end; end; {$ELSE} var StatInfo: BaseUnix.Stat; begin Result:= fpLStat(UTF8ToSys(FileName), StatInfo) >= 0; if Result then begin Attr.Time:= StatInfo.st_mtime; Attr.Size:= StatInfo.st_size; Attr.Attr:= StatInfo.st_mode; end; end; {$ENDIF} {$IFDEF uOSUtilsRangeCheckOn} {$R+} {$UNDEF uOSUtilsRangeCheckOn} {$ENDIF} function mbFileSetReadOnly(const FileName: String; ReadOnly: Boolean): Boolean; {$IFDEF MSWINDOWS} var iAttr: DWORD; wFileName: UnicodeString; begin wFileName:= UTF16LongName(FileName); iAttr := GetFileAttributesW(PWideChar(wFileName)); if iAttr = DWORD(-1) then Exit(False); if ReadOnly then iAttr:= iAttr or faReadOnly else iAttr:= iAttr and not (faReadOnly or faHidden or faSysFile); Result:= SetFileAttributesW(PWideChar(wFileName), iAttr) = True; end; {$ELSE} var StatInfo: BaseUnix.Stat; mode: TMode; begin if fpStat(UTF8ToSys(FileName), StatInfo) <> 0 then Exit(False); mode := SetModeReadOnly(StatInfo.st_mode, ReadOnly); Result:= fpchmod(UTF8ToSys(FileName), mode) = 0; end; {$ENDIF} function mbDeleteFile(const FileName: String): Boolean; {$IFDEF MSWINDOWS} begin Result:= Windows.DeleteFileW(PWideChar(UTF16LongName(FileName))); if not Result then Result:= (GetLastError = ERROR_FILE_NOT_FOUND); end; {$ELSE} begin Result:= fpUnLink(UTF8ToSys(FileName)) = 0; if not Result then Result:= (fpgetErrNo = ESysENOENT); end; {$ENDIF} function mbRenameFile(const OldName: String; NewName: String): Boolean; {$IFDEF MSWINDOWS} var wOldName, wNewName: UnicodeString; begin wNewName:= UTF16LongName(NewName); wOldName:= UTF16LongName(OldName); Result:= MoveFileExW(PWChar(wOldName), PWChar(wNewName), MOVEFILE_REPLACE_EXISTING); end; {$ELSE} var tmpFileName: String; OldFileStat, NewFileStat: stat; begin if GetPathType(NewName) <> ptAbsolute then NewName := ExtractFilePath(OldName) + NewName; if OldName = NewName then Exit(True); if fpLstat(UTF8ToSys(OldName), OldFileStat) <> 0 then Exit(False); // Check if target file exists. if fpLstat(UTF8ToSys(NewName), NewFileStat) = 0 then begin // Check if source and target are the same files (same inode and same device). if (OldFileStat.st_ino = NewFileStat.st_ino) and (OldFileStat.st_dev = NewFileStat.st_dev) then begin // Check number of links. // If it is 1 then source and target names most probably differ only // by case on a case-insensitive filesystem. Direct rename() in such case // fails on Linux, so we use a temporary file name and rename in two stages. // If number of links is more than 1 then it's enough to simply unlink // the source file, since both files are technically identical. // (On Linux rename() returns success but doesn't do anything // if renaming a file to its hard link.) // We cannot use st_nlink for directories because it means "number of // subdirectories"; hard links to directories are not supported on Linux // or Windows anyway (on MacOSX they are). Therefore we always treat // directories as if they were a single link and rename them using temporary name. if (NewFileStat.st_nlink = 1) or BaseUnix.fpS_ISDIR(NewFileStat.st_mode) then begin tmpFileName := GetTempName(OldName); if FpRename(UTF8ToSys(OldName), UTF8ToSys(tmpFileName)) = 0 then begin if fpLstat(UTF8ToSys(NewName), NewFileStat) = 0 then begin // We have renamed the old file but the new file name still exists, // so this wasn't a single file on a case-insensitive filesystem // accessible by two names that differ by case. FpRename(UTF8ToSys(tmpFileName), UTF8ToSys(OldName)); // Restore old file. {$IFDEF DARWIN} // If it's a directory with multiple hard links then simply unlink the source. if BaseUnix.fpS_ISDIR(NewFileStat.st_mode) and (NewFileStat.st_nlink > 1) then Result := (fpUnLink(UTF8ToSys(OldName)) = 0) else {$ENDIF} Result := False; end else if FpRename(UTF8ToSys(tmpFileName), UTF8ToSys(NewName)) = 0 then begin Result := True; end else begin FpRename(UTF8ToSys(tmpFileName), UTF8ToSys(OldName)); // Restore old file. Result := False; end; end else Result := False; end else begin // Multiple links - simply unlink the source file. Result := (fpUnLink(UTF8ToSys(OldName)) = 0); end; Exit; end; end; Result := FpRename(UTF8ToSys(OldName), UTF8ToSys(NewName)) = 0; end; {$ENDIF} function mbFileSize(const FileName: String): Int64; {$IFDEF MSWINDOWS} var Handle: System.THandle; FindData: TWin32FindDataW; begin Result:= 0; Handle := FindFirstFileW(PWideChar(UTF16LongName(FileName)), FindData); if Handle <> INVALID_HANDLE_VALUE then begin Windows.FindClose(Handle); if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then begin Int64Rec(Result).Lo:= FindData.nFileSizeLow; Int64Rec(Result).Hi:= FindData.nFileSizeHigh; end; end; end; {$ELSE} var Info: BaseUnix.Stat; begin Result:= 0; if fpStat(UTF8ToSys(FileName), Info) >= 0 then Result:= Info.st_size; end; {$ENDIF} function FileFlush(Handle: System.THandle): Boolean; inline; {$IFDEF MSWINDOWS} begin Result:= FlushFileBuffers(Handle); end; {$ELSE} begin Result:= (fpfsync(Handle) = 0); end; {$ENDIF} function mbGetCurrentDir: String; {$IFDEF MSWINDOWS} var dwSize: DWORD; wsDir: UnicodeString; begin if Length(CurrentDirectory) > 0 then Result:= CurrentDirectory else begin dwSize:= GetCurrentDirectoryW(0, nil); if dwSize = 0 then Result:= EmptyStr else begin SetLength(wsDir, dwSize + 1); SetLength(wsDir, GetCurrentDirectoryW(dwSize, PWideChar(wsDir))); Result:= UTF16ToUTF8(wsDir); end; end; end; {$ELSE} begin GetDir(0, Result); Result := SysToUTF8(Result); end; {$ENDIF} function mbSetCurrentDir(const NewDir: String): Boolean; {$IFDEF MSWINDOWS} var Handle: THandle; wsNewDir: UnicodeString; FindData: TWin32FindDataW; NetResource: TNetResourceW; begin // Function WNetAddConnection2W works very slow // when the final character is a backslash ('\') wsNewDir:= UTF8Decode(ExcludeTrailingPathDelimiter(NewDir)); if Pos('\\', wsNewDir) = 1 then begin FillChar(NetResource, SizeOf(NetResource), #0); NetResource.dwType:= RESOURCETYPE_ANY; NetResource.lpRemoteName:= PWideChar(wsNewDir); WNetAddConnection2W(NetResource, nil, nil, CONNECT_INTERACTIVE); end; wsNewDir:= UTF16LongName(IncludeTrailingBackslash(NewDir)) + '*'; Handle:= FindFirstFileW(PWideChar(wsNewDir), FindData); Result:= (Handle <> INVALID_HANDLE_VALUE) or (GetLastError = ERROR_FILE_NOT_FOUND); if (Handle <> INVALID_HANDLE_VALUE) then FindClose(Handle); if Result then CurrentDirectory:= NewDir; end; {$ELSE} begin Result:= fpChDir(UTF8ToSys(NewDir)) = 0; end; {$ENDIF} function mbDirectoryExists(const Directory: String) : Boolean; {$IFDEF MSWINDOWS} var Attr: DWORD; begin Attr:= GetFileAttributesW(PWideChar(UTF16LongName(Directory))); if Attr <> DWORD(-1) then Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) > 0 else Result:= False; end; {$ELSE} var Info: BaseUnix.Stat; begin // We can use fpStat here instead of fpLstat, so that True is returned // when target is a directory or a link to an existing directory. // Note that same behaviour would be achieved by passing paths // that end with path delimiter to fpLstat. // Paths with links can be used the same way as if they were real directories. if fpStat(UTF8ToSys(Directory), Info) >= 0 then Result:= fpS_ISDIR(Info.st_mode) else Result:= False; end; {$ENDIF} function mbCreateDir(const NewDir: String): Boolean; {$IFDEF MSWINDOWS} begin Result:= CreateDirectoryW(PWideChar(UTF16LongName(NewDir)), nil); end; {$ELSE} begin Result:= fpMkDir(UTF8ToSys(NewDir), $1FF) = 0; // $1FF = &0777 end; {$ENDIF} function mbRemoveDir(const Dir: String): Boolean; {$IFDEF MSWINDOWS} begin Result:= RemoveDirectoryW(PWideChar(UTF16LongName(Dir))); if not Result then Result:= (GetLastError = ERROR_FILE_NOT_FOUND); end; {$ELSE} begin Result:= fpRmDir(UTF8ToSys(Dir)) = 0; if not Result then Result:= (fpgetErrNo = ESysENOENT); end; {$ENDIF} function mbFileSystemEntryExists(const Path: String): Boolean; begin Result := mbFileGetAttr(Path) <> faInvalidAttributes; end; function mbCompareFileNames(const FileName1, FileName2: String): Boolean; inline; {$IF DEFINED(WINDOWS) OR DEFINED(DARWIN)} begin Result:= (WideCompareText(UTF8Decode(FileName1), UTF8Decode(FileName2)) = 0); end; {$ELSE} begin Result:= (WideCompareStr(UTF8Decode(FileName1), UTF8Decode(FileName2)) = 0); end; {$ENDIF} function mbSameFile(const FileName1, FileName2: String): Boolean; {$IF DEFINED(MSWINDOWS)} var FileHandle1, FileHandle2: System.THandle; FileInfo1, FileInfo2: BY_HANDLE_FILE_INFORMATION; begin Result := mbCompareFileNames(FileName1, FileName2); if not Result then begin FileHandle1 := CreateFileW(PWideChar(UTF16LongName(FileName1)), FILE_READ_ATTRIBUTES, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, 0, 0); if FileHandle1 <> INVALID_HANDLE_VALUE then begin FileHandle2 := CreateFileW(PWideChar(UTF16LongName(FileName2)), FILE_READ_ATTRIBUTES, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, 0, 0); if FileHandle2 <> INVALID_HANDLE_VALUE then begin if GetFileInformationByHandle(FileHandle1, FileInfo1) and GetFileInformationByHandle(FileHandle2, FileInfo2) then begin // Check if both files have the same index on the same volume. // This check is valid only while both files are open. Result := (FileInfo1.dwVolumeSerialNumber = FileInfo2.dwVolumeSerialNumber) and (FileInfo1.nFileIndexHigh = FileInfo2.nFileIndexHigh) and (FileInfo1.nFileIndexLow = FileInfo2.nFileIndexLow); end; CloseHandle(FileHandle2); end; CloseHandle(FileHandle1); end end; end; {$ELSEIF DEFINED(UNIX)} var File1Stat, File2Stat: stat; begin Result := mbCompareFileNames(FileName1, FileName2) or ( (fpLstat(UTF8ToSys(FileName1), File1Stat) = 0) and (fpLstat(UTF8ToSys(FileName2), File2Stat) = 0) and (File1Stat.st_ino = File2Stat.st_ino) and (File1Stat.st_dev = File2Stat.st_dev) ); end; {$ENDIF} function mbGetEnvironmentString(Index: Integer): String; {$IFDEF MSWINDOWS} var hp, p: PWideChar; begin Result:= ''; p:= GetEnvironmentStringsW; hp:= p; if (hp <> nil) then begin while (hp^ <> #0) and (Index > 1) do begin Dec(Index); hp:= hp + lstrlenW(hp) + 1; end; if (hp^ <> #0) then Result:= UTF16ToUTF8(UnicodeString(hp)); end; FreeEnvironmentStringsW(p); end; {$ELSE} begin Result:= SysToUTF8(GetEnvironmentString(Index)); end; {$ENDIF} function mbExpandEnvironmentStrings(const FileName: String): String; {$IF DEFINED(MSWINDOWS)} var dwSize: DWORD; wsResult: UnicodeString; begin SetLength(wsResult, MaxSmallInt + 1); dwSize:= ExpandEnvironmentStringsW(PWideChar(UTF8Decode(FileName)), PWideChar(wsResult), MaxSmallInt); if (dwSize = 0) or (dwSize > MaxSmallInt) then Result:= FileName else begin SetLength(wsResult, dwSize - 1); Result:= UTF16ToUTF8(wsResult); end; end; {$ELSE} var Index: Integer = 1; EnvCnt, EqualPos: Integer; EnvVar, EnvName, EnvValue: String; begin Result:= FileName; EnvCnt:= GetEnvironmentVariableCount; while (Index <= EnvCnt) and (Pos('$', Result) > 0) do begin EnvVar:= mbGetEnvironmentString(Index); EqualPos:= Pos('=', EnvVar); if EqualPos = 0 then Continue; EnvName:= Copy(EnvVar, 1, EqualPos - 1); EnvValue:= Copy(EnvVar, EqualPos + 1, MaxInt); Result:= StringReplace(Result, '$' + EnvName, EnvValue, [rfReplaceAll, rfIgnoreCase]); Inc(Index); end; end; {$ENDIF} function mbSysErrorMessage: String; begin Result := mbSysErrorMessage(GetLastOSError); end; function mbSysErrorMessage(ErrorCode: Integer): String; begin Result := SysErrorMessage(ErrorCode); {$IF (FPC_FULLVERSION < 30004)} Result := CeSysToUtf8(Result); {$ENDIF} end; function mbGetModuleName(Address: Pointer): String; const Dummy: Boolean = False; {$IFDEF UNIX} var dlinfo: dl_info; begin if Address = nil then Address:= @Dummy; FillChar({%H-}dlinfo, SizeOf(dlinfo), #0); if dladdr(Address, @dlinfo) = 0 then Result:= EmptyStr else begin Result:= CeSysToUtf8(dlinfo.dli_fname); end; end; {$ELSE} var ModuleName: UnicodeString; lpBuffer: TMemoryBasicInformation; begin if Address = nil then Address:= @Dummy; if VirtualQuery(Address, @lpBuffer, SizeOf(lpBuffer)) <> SizeOf(lpBuffer) then Result:= EmptyStr else begin SetLength(ModuleName, MAX_PATH + 1); SetLength(ModuleName, GetModuleFileNameW({%H-}THandle(lpBuffer.AllocationBase), PWideChar(ModuleName), MAX_PATH)); Result:= UTF16ToUTF8(ModuleName); end; end; {$ENDIF} function mbLoadLibrary(const Name: String): TLibHandle; {$IFDEF MSWINDOWS} begin Result:= LoadLibraryW(PWideChar(UTF8Decode(Name))); end; {$ELSE} begin Result:= TLibHandle(dlopen(PChar(UTF8ToSys(Name)), RTLD_LAZY)); end; {$ENDIF} function SafeGetProcAddress(Lib: TLibHandle; const ProcName: AnsiString): Pointer; begin Result:= GetProcedureAddress(Lib, ProcName); if (Result = nil) then raise Exception.Create(ProcName); end; function CreateHardLink(const Path, LinkName: String) : Boolean; {$IFDEF MSWINDOWS} var wsPath, wsLinkName: UnicodeString; begin wsPath:= UTF16LongName(Path); wsLinkName:= UTF16LongName(LinkName); Result:= DCNtfsLinks.CreateHardlink(wsPath, wsLinkName); end; {$ELSE} begin Result := (fplink(PAnsiChar(CeUtf8ToSys(Path)),PAnsiChar(CeUtf8ToSys(LinkName)))=0); end; {$ENDIF} function CreateSymLink(const Path, LinkName: string) : Boolean; {$IFDEF MSWINDOWS} var wsPath, wsLinkName: UnicodeString; begin wsPath:= UTF8Decode(Path); wsLinkName:= UTF16LongName(LinkName); Result:= DCNtfsLinks.CreateSymlink(wsPath, wsLinkName); end; {$ELSE} begin Result := (fpsymlink(PAnsiChar(CeUtf8ToSys(Path)), PAnsiChar(CeUtf8ToSys(LinkName)))=0); end; {$ENDIF} function ReadSymLink(const LinkName : String) : String; {$IFDEF MSWINDOWS} var wsLinkName, wsTarget: UnicodeString; begin wsLinkName:= UTF16LongName(LinkName); if DCNtfsLinks.ReadSymLink(wsLinkName, wsTarget) then Result := UTF16ToUTF8(wsTarget) else Result := EmptyStr; end; {$ELSE} begin Result := SysToUTF8(fpReadlink(UTF8ToSys(LinkName))); end; {$ENDIF} end. doublecmd-0.8.2/components/doublecmd/doublecmd_common.lpk0000664000175000017500000000531312756114647022665 0ustar alexxalexx doublecmd-0.8.2/components/doublecmd/dcstrutils.pas0000664000175000017500000010321013102706541021531 0ustar alexxalexx{ Double Commander ------------------------------------------------------------------------- Useful functions dealing with strings. Copyright (C) 2006-2017 Alexander Koblov (alexx2000@mail.ru) Copyright (C) 2012 Przemyslaw Nagay (cobines@gmail.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . } unit DCStrUtils; {$mode objfpc}{$H+} interface uses Classes, SysUtils, DCBasicTypes,LazUtf8; type TPathType = (ptNone, ptRelative, ptAbsolute); {en Checks if StringToCheck contains any of the single characters in PossibleCharacters. Only ASCII can be searched. } function ContainsOneOf(StringToCheck: String; PossibleCharacters: String): Boolean; {en Convert known directory separators to the current directory separator. } function NormalizePathDelimiters(const Path: String): String; {en Get last directory name in path @returns(Last directory name in path) } function GetLastDir(Path : String) : String; {en Retrieves the root directory for a path. @param(sPath Absolute path to a directory or a file.) @returns(Root directory or an empty string if the path is not absolute.) } function GetRootDir(sPath : String) : String; {en Retrieves parent directory for a path (removes the last subdirectory in the path). @param(sPath Absolute or relative path to a directory or a file.) @returns(Parent directory or an empty string if the path does not have a parent directory.) } function GetParentDir(sPath : String) : String; {en Gets the deepest (longest) path that exist. } function GetDeepestExistingPath(const sPath : String) : String; function GetSplitFileName(var sFileName, sPath : String) : String; function MakeFileName(const sPath, sFileNameDef : String) : String; {en Split path into list of directories @param(DirName Path) @param(Dirs List of directories names) @returns(The function returns the number of directories found, or -1 if none were found.) } function GetDirs (DirName : String; var Dirs : TStringList) : Longint; {en Get absolute file name from relative file name @param(sPath Current path) @param(sRelativeFileName Relative file name) @returns(Absolute file name) } function GetAbsoluteFileName(const sPath, sRelativeFileName : String) : String; {en Checks if a path to a directory or file is absolute or relative. @returns(ptNone if a path is just a directory or file name (MyDir) ptRelative if a path is relative (MyDir/MySubDir) ptAbsolute if a path is absolute) (/root/MyDir) } function GetPathType(const sPath : String): TPathType; {en Get file name without path and extension @param(FileName File name) @returns(File name without path and extension) } function ExtractOnlyFileName(const FileName: string): string; {en Get file extension without the '.' at the front. } function ExtractOnlyFileExt(const FileName: string): string; {en Remove file extension with the '.' from file name. } function RemoveFileExt(const FileName: String): String; function RemoveInvalidCharsFromFileName(const FileName: String): String; function ContainsWildcards(const Path: String): Boolean; {en Expands an absolute file path by removing all relative references. Processes '/../' and '/./'. Example: /home/user/files/../somedirectory/./file.txt = /home/user/somedirectory/file.txt @param(Path path to expand.) } function ExpandAbsolutePath(const Path: String): String; function HasPathInvalidCharacters(Path: String): Boolean; {en Checks if a file or directory belongs in the specified path. Only strings are compared, no file-system checks are done. @param(sBasePath Absolute path where the path to check should be in.) @param(sPathToCheck Absolute path to file or directory to check.) @param(AllowSubDirs If @true, allows the sPathToCheck to point to a file or directory in some subdirectory of sBasePath. If @false, only allows the sPathToCheck to point directly to a file or directory in sBasePath.) @param(AllowSame If @true, returns @true if sBasePath = sPathToCheck. If @false, returns @false if sBasePath = sPathToCheck.) @return(@true if sPathToCheck points to a directory or file in sBasePath. @false otherwise.) Examples: IsInPath('/home', '/home/somedir/somefile', True, False) = True IsInPath('/home', '/home/somedir/somefile', False, False) = False IsInPath('/home', '/home/somedir/', False, False) = True IsInPath('/home', '/home', False, False) = False IsInPath('/home', '/home', False, True) = True } function IsInPath(sBasePath : String; sPathToCheck : String; AllowSubDirs : Boolean; AllowSame : Boolean) : Boolean; {en Changes a path to be relative to some parent directory. @param(sPrefix Absolute path that is a parent of sPath.) @param(sPath Path to change. Must be a subpath of sPrefix, otherwise no change is made.) Examples: ExtractDirLevel('/home', '/home/somedir/somefile') = '/somedir/somefile' } function ExtractDirLevel(const sPrefix, sPath: String): String; {en Adds a path delimiter at the beginning of the string, if it not exists. } function IncludeFrontPathDelimiter(s: String): String; {en Removes a path delimiter at the beginning of the string, if it exists. } function ExcludeFrontPathDelimiter(s: String): String; {en Removes a path delimiter at the ending of the string, if it exists. Doesn't remove path delimiter if it is the only character in the path (root dir), so it is safer to use than ExcludeTrailingPathDelimiter, especially on Unix. } function ExcludeBackPathDelimiter(const Path: String): String; {en Return position of character in string begun from start position @param(C character) @param(S String) @param(StartPos Start position) @returns(Position of character in string) } function CharPos(C: Char; const S: string; StartPos: Integer = 1): Integer; {en Return position of any of tag-characters in string T in string S begun from start position @param(T set of characters) @param(S String) @param(StartPos Start position) @param(SearchBackward set @True if need search backwards) @returns(Position of character in string) } function TagPos(T: string; const S: string; StartPos: Integer;SearchBackward: boolean=False): Integer; {en } function scopy(IndexBegin,IndexEnd:integer;str:string):string; {en Split file name on name and extension @param(sFileName File name) @param(n Name) @param(e Extension) } procedure DivFileName(const sFileName:String; out n,e:String); {en Split ';' separated path list to array @param(Path Path list to split) @returns(Path array) } function SplitPath(const Path: String): TDynamicStringArray; {en Split file mask on name mask and extension mask @param(DestMask File mask) @param(DestNameMask Name mask) @param(DestExtMask Extension mask) } procedure SplitFileMask(const DestMask: String; out DestNameMask: String; out DestExtMask: String); {en Apply name and extension mask to the file name @param(aFileName File name) @param(NameMask Name mask) @param(ExtMask Extension mask) } function ApplyRenameMask(aFileName: String; NameMask: String; ExtMask: String): String; {en Get count of character in string @param(Char Character) @param(S String) @returns(Count of character) } function NumCountChars(const Char: Char; const S: String): Integer; {en Remove last line ending in text @param(sText Text) @param(TextLineBreakStyle Text line break style) } function TrimRightLineEnding(const sText: String; TextLineBreakStyle: TTextLineBreakStyle): String; function mbCompareText(const s1, s2: String): PtrInt; function StrNewW(const mbString: String): PWideChar; procedure StrDisposeW(var pStr : PWideChar); function StrLCopyW(Dest, Source: PWideChar; MaxLen: SizeInt): PWideChar; function StrPCopyW(Dest: PWideChar; const Source: WideString): PWideChar; function StrPLCopyW(Dest: PWideChar; const Source: WideString; MaxLen: Cardinal): PWideChar; function RPos(const Substr : UnicodeString; const Source : UnicodeString) : Integer; overload; {en Checks if a string begins with another string. @returns(@true if StringToCheck begins with StringToMatch. StringToCheck may be longer than StringToMatch.) } function StrBegins(const StringToCheck, StringToMatch: String): Boolean; {en Checks if a string ends with another string. @returns(@true if StringToCheck ends with StringToMatch. StringToCheck may be longer than StringToMatch.) } function StrEnds(const StringToCheck, StringToMatch: String): Boolean; {en Adds a string to another string. If the source string is not empty adds a separator before adding the string. } procedure AddStrWithSep(var SourceString: String; const StringToAdd: String; const Separator: Char = ' '); procedure AddStrWithSep(var SourceString: String; const StringToAdd: String; const Separator: String); procedure ParseLineToList(sLine: String; ssItems: TStrings); {en Convert a number specified as an octal number to it's decimal value. @param(Value Octal number as string) @returns(Decimal number) } function OctToDec(Value: String): LongInt; {en Convert a number specified as an decimal number to it's octal value. @param(Value Decimal number) @returns(Octal number as string) } function DecToOct(Value: LongInt): String; procedure AddString(var anArray: TDynamicStringArray; const sToAdd: String); {en Splits a string into different parts delimited by the specified delimiter character. } function SplitString(const S: String; Delimiter: AnsiChar): TDynamicStringArray; {en Checks if the second array is the beginning of first. If BothWays is @true then also checks the other way around, if the first array is the beginning of second. For Array1=[1,2] Array2=[1,2] returns @true. For Array1=[1,2,...] Array2=[1,2] returns @true. For Array1=[1,3,...] Array2=[1,2] returns @false. If BothWays = True then also For Array1=[1] Array2=[1,2] returns @true. For Array1=[1] Array2=[2] returns @false. } function ArrBegins(const Array1, Array2: array of String; BothWays: Boolean): Boolean; function ArrayToString(const anArray: TDynamicStringArray; const Separator: Char = ' '): String; {en Compares length and contents of the arrays. If lengths differ or individual elements differ returns @false, otherwise @true. } function Compare(const Array1, Array2: array of String): Boolean; {en Copies open array to dynamic array. } function CopyArray(const anArray: array of String): TDynamicStringArray; function ContainsOneOf(const ArrayToSearch, StringsToSearch: array of String): Boolean; function Contains(const ArrayToSearch: array of String; const StringToSearch: String): Boolean; procedure DeleteString(var anArray: TDynamicStringArray; const Index: Integer); procedure DeleteString(var anArray: TDynamicStringArray; const sToDelete: String); function GetArrayFromStrings(Strings: TStrings): TDynamicStringArray; procedure SetStringsFromArray(Strings: TStrings; const anArray: TDynamicStringArray); {en Replaces old value of Key or adds a new Key=NewValue string to the array. } procedure SetValue(var anArray: TDynamicStringArray; Key, NewValue: String); procedure SetValue(var anArray: TDynamicStringArray; Key: String; NewValue: Boolean); function ShortcutsToText(const Shortcuts: TDynamicStringArray): String; function GetDateTimeInStrEZSortable(DateTime:TDateTime):string; function WrapTextSimple(const S: String; MaxCol: Integer): String; implementation uses DCOSUtils; function NormalizePathDelimiters(const Path: String): String; {$IFDEF UNIX} begin Result:= Path; end; {$ELSE} const AllowPathDelimiters : set of char = ['\','/']; var I : LongInt; begin Result:= Path; // If path is not URI if Pos('://', Result) = 0 then begin for I:= 1 to Length(Path) do if Path[I] in AllowPathDelimiters then Result[I]:= DirectorySeparator; end; end; {$ENDIF} function GetLastDir(Path : String) : String; begin Result:= ExtractFileName(ExcludeTrailingPathDelimiter(Path)); if Result = '' then Result:= ExtractFileDrive(Path); if Result = '' then Result:= PathDelim; end; function GetRootDir(sPath : String) : String; begin {$IF DEFINED(MSWINDOWS)} Result := ExtractFileDrive(sPath); if Result <> '' then Result := Result + PathDelim; {$ELSEIF DEFINED(UNIX)} Result := PathDelim; // Hardcoded {$ELSE} Result := ''; {$ENDIF} end; function GetParentDir(sPath : String) : String; var i : Integer; begin Result := ''; sPath := ExcludeTrailingPathDelimiter(sPath); // Start from one character before last. for i := length(sPath) - 1 downto 1 do if sPath[i] = DirectorySeparator then begin Result := Copy(sPath, 1, i); Break; end; end; function GetDeepestExistingPath(const sPath : String) : String; begin Result := sPath; while Result <> EmptyStr do begin if not mbDirectoryExists(Result) then Result := GetParentDir(Result) else Break; end; end; function GetSplitFileName(var sFileName, sPath : String) : String; begin if Pos(PathDelim, sFileName) <> 0 then begin Result := sFileName; sPath := ExtractFilePath(sFileName); sFileName := ExtractFileName(sFileName); end else Result := sPath + sFileName; end; function MakeFileName(const sPath, sFileNameDef : String) : String; begin Result:= ExtractFileName(ExcludeTrailingBackslash(sPath)); if Result = EmptyStr then Result:= sFileNameDef; end; function GetDirs (DirName : String; var Dirs : TStringList) : Longint; var I : Longint; len : Integer; sDir : String; begin I:= 1; Result:= -1; len := Length(DirName); while I <= len do begin if DirName[I]=PathDelim then begin Inc(Result); sDir := Copy(DirName, 1, len - (len - I + 1)); if dirs.IndexOf(sDir) < 0 then dirs.Add(sDir); end; Inc(I); end; if Result > -1 then inc(Result); end; function GetAbsoluteFileName(const sPath, sRelativeFileName : String) : String; begin case GetPathType(sRelativeFileName) of ptNone: Result := sPath + sRelativeFileName; ptRelative: Result := ExpandAbsolutePath(sPath + sRelativeFileName); ptAbsolute: Result := sRelativeFileName; end; end; function GetPathType(const sPath : String): TPathType; begin if sPath <> EmptyStr then begin {$IFDEF MSWINDOWS} { Absolute path in Windows } if { X:\... [Disk] ":" is reserved otherwise } ( Pos( DriveDelim, sPath ) > 0 ) or { \\... [UNC] \... [Root of current drive] } ( sPath[1] = PathDelim ) then {$ENDIF MSWINDOWS} {$IFDEF UNIX} { UNIX absolute paths start with a slash } if (sPath[1] = PathDelim) then {$ENDIF UNIX} Result := ptAbsolute else if ( Pos( PathDelim, sPath ) > 0 ) then Result := ptRelative else if (sPath = '..') then Result := ptRelative else Result := ptNone; end else Result := ptNone; end; function ExtractOnlyFileName(const FileName: string): string; var I, Index : LongInt; EndSep : Set of Char; begin // Find a dot index I := Length(FileName); EndSep:= AllowDirectorySeparators + AllowDriveSeparators + [ExtensionSeparator]; while (I > 0) and not (FileName[I] in EndSep) do Dec(I); if (I > 0) and (FileName[I] = ExtensionSeparator) then Index := I else Index := MaxInt; // Find file name index EndSep := EndSep - [ExtensionSeparator]; while (I > 0) and not (FileName[I] in EndSep) do Dec(I); Result := Copy(FileName, I + 1, Index - I - 1); end; function ExtractOnlyFileExt(const FileName: string): string; var I : LongInt; EndSep : Set of Char; begin I := Length(FileName); EndSep:= AllowDirectorySeparators + AllowDriveSeparators + [ExtensionSeparator]; while (I > 0) and not (FileName[I] in EndSep) do Dec(I); if (I > 0) and (FileName[I] = ExtensionSeparator) then Result := Copy(FileName, I + 1, MaxInt) else Result := ''; end; function RemoveFileExt(const FileName: String): String; var I : LongInt; EndSep : Set of Char; begin I := Length(FileName); EndSep:= AllowDirectorySeparators + AllowDriveSeparators + [ExtensionSeparator]; while (I > 0) and not (FileName[I] in EndSep) do Dec(I); if (I > 0) and (FileName[I] = ExtensionSeparator) then Result := Copy(FileName, 1, I - 1) else Result := FileName; end; function ContainsWildcards(const Path: String): Boolean; begin Result := ContainsOneOf(Path, '*?'); end; { RemoveInvalidCharsFromFileName } function RemoveInvalidCharsFromFileName(const FileName: String): String; const {$IFDEF MSWINDOWS} ForbiddenChars : set of char = ['<','>',':','"','/','\','|','?','*']; {$ELSE} ForbiddenChars : set of char = ['/']; {$ENDIF} var I : LongInt; begin Result:= ''; for I:= 1 to Length(FileName) do if not (FileName[I] in ForbiddenChars) then Result:=Result+FileName[I]; end; function ExpandAbsolutePath(const Path: String): String; var I, J: Integer; begin Result := Path; {First remove all references to '\.\'} I := Pos (DirectorySeparator + '.' + DirectorySeparator, Result); while I <> 0 do begin Delete (Result, I, 2); I := Pos (DirectorySeparator + '.' + DirectorySeparator, Result); end; if StrEnds(Result, DirectorySeparator + '.') then Delete (Result, Length(Result) - 1, 2); {Then remove all references to '\..\'} I := Pos (DirectorySeparator + '..', Result); while (I <> 0) do begin J := Pred (I); while (J > 0) and (Result [J] <> DirectorySeparator) do Dec (J); if (J = 0) then Delete (Result, I, 3) else Delete (Result, J, I - J + 3); I := Pos (DirectorySeparator + '..', Result); end; end; function HasPathInvalidCharacters(Path: String): Boolean; begin Result := ContainsOneOf(Path, '*?'); end; function IsInPath(sBasePath : String; sPathToCheck : String; AllowSubDirs : Boolean; AllowSame : Boolean) : Boolean; var BasePathLength, PathToCheckLength: Integer; DelimiterPos: Integer; begin if sBasePath = '' then Exit(False); sBasePath := IncludeTrailingPathDelimiter(sBasePath); BasePathLength := Length(sBasePath); PathToCheckLength := Length(sPathToCheck); if PathToCheckLength > BasePathLength then begin if CompareStr(Copy(sPathToCheck, 1, BasePathLength), sBasePath) = 0 then begin if AllowSubDirs then Result := True else begin // Additionally check if the remaining path is a relative path. // Look for a path delimiter in the middle of the filepath. sPathToCheck := Copy(sPathToCheck, 1 + BasePathLength, PathToCheckLength - BasePathLength); DelimiterPos := Pos(DirectorySeparator, sPathToCheck); // If no delimiter was found or it was found at then end (directories // may end with it), then the 'sPathToCheck' is in 'sBasePath'. Result := (DelimiterPos = 0) or (DelimiterPos = PathToCheckLength - BasePathLength); end; end else Result := False; end else Result := AllowSame and (((PathToCheckLength = BasePathLength) and (CompareStr(sPathToCheck, sBasePath) = 0)) or ((PathToCheckLength = BasePathLength - 1) and (CompareStr(Copy(sBasePath, 1, PathToCheckLength), sPathToCheck) = 0))); end; function ExtractDirLevel(const sPrefix, sPath: String): String; var PrefixLength: Integer; begin if IsInPath(sPrefix, sPath, True, True) then begin PrefixLength := Length(sPrefix); Result := Copy(sPath, 1 + PrefixLength, Length(sPath) - PrefixLength) end else Result := sPath; end; function IncludeFrontPathDelimiter(s: String): String; begin if (Length(s) > 0) and (s[1] = PathDelim) then Result:= s else Result:= PathDelim + s; end; function ExcludeFrontPathDelimiter(s: String): String; begin if (Length(s) > 0) and (s[1] = PathDelim) then Result := Copy(s, 2, Length(s) - 1) else Result := s; end; function ExcludeBackPathDelimiter(const Path: String): String; var L: Integer; begin L:= Length(Path); if (L > 1) and (Path[L] in AllowDirectorySeparators) then Result:= Copy(Path, 1, L - 1) else Result:= Path; end; procedure DivFileName(const sFileName:String; out n,e:String); var i:Integer; begin for i:= length(sFileName) downto 1 do if sFileName[i]='.' then begin // if i>1 then // hidden files?? e:=Copy(sFileName,i,Length(sFileName)-i+1); n:=Copy(sFileName,1,i-1); Exit; end; e:=''; n:=sFileName; end; function SplitPath(const Path: String): TDynamicStringArray; const cDelta = {$IF DEFINED(UNIX)}1{$ELSE}2{$ENDIF}; cDelimiter = {$IF DEFINED(UNIX)}'/'{$ELSE}':'{$ENDIF}; var L, F: Integer; S: Integer = 1; begin L:= Length(Path); for F:= 1 to L - cDelta do begin if (Path[F] = ';') and (Path[F + cDelta] = cDelimiter) then begin AddString(Result, Copy(Path, S, F - S)); S:= F + 1; end; end; if S <= L then begin AddString(Result, Copy(Path, S, L - S + 1)); end; end; procedure SplitFileMask(const DestMask: String; out DestNameMask: String; out DestExtMask: String); var iPos: LongInt; begin // Special case for mask that contains '*.*' ('*.*.old' for example) iPos:= Pos('*.*', DestMask); if (iPos = 0) then DivFileName(DestMask, DestNameMask, DestExtMask) else begin DestNameMask := Copy(DestMask, 1, iPos); DestExtMask := Copy(DestMask, iPos + 1, MaxInt); end; // Treat empty mask as '*.*'. if (DestNameMask = '') and (DestExtMask = '') then begin DestNameMask := '*'; DestExtMask := '.*'; end; end; function ApplyRenameMask(aFileName: String; NameMask: String; ExtMask: String): String; function ApplyMask(const TargetString: String; Mask: String): String; var i:Integer; begin Result:=''; for i:=1 to Length(Mask) do begin if Mask[i]= '?' then Result:=Result + TargetString[i] else if Mask[i]= '*' then Result:=Result + Copy(TargetString, i, Length(TargetString) - i + 1) else Result:=Result + Mask[i]; end; end; var sDstExt: String; sDstName: String; begin if ((NameMask = '*') and (ExtMask = '.*')) then Result := aFileName else begin DivFileName(aFileName, sDstName, sDstExt); sDstName := ApplyMask(sDstName, NameMask); sDstExt := ApplyMask(sDstExt, ExtMask); Result := sDstName; if sDstExt <> '.' then Result := Result + sDstExt; end; end; function CharPos(C: Char; const S: string; StartPos: Integer = 1): Integer; var sNewStr : String; begin if StartPos <> 1 then begin sNewStr := Copy(S, StartPos, Length(S) - StartPos + 1); Result := Pos(C, sNewStr); if Result <> 0 then Result := Result + StartPos - 1; end else Result := Pos(C, S); end; function TagPos(T: string; const S: string; StartPos: Integer; SearchBackward: boolean): Integer; // in future this function will moved to DCStrUtils var i,cnt:integer; ch:char; begin Result:=0; i:=StartPos; if i=0 then i:=1; cnt:=UTF8Length(S); if SearchBackward then begin while (i>0)do begin ch:=S[UTF8CharToByteIndex(PChar(S), length(S), i)]; if Pos(ch,T)=0 then dec(i) else break; end; end else while (i<=cnt)do begin ch:=S[UTF8CharToByteIndex(PChar(S), length(S), i)]; if Pos(ch,T)=0 then inc(i) else break; end; Result:=i; end; function scopy(IndexBegin,IndexEnd:integer;str:string):string; begin if (IndexBegin<=IndexEnd) then Result:=copy(str,IndexBegin,(IndexEnd-IndexBegin+1)) else Result:=''; end; function NumCountChars(const Char: char; const S: String): Integer; var I : Integer; begin Result := 0; if Length(S) > 0 then for I := 1 to Length(S) do if S[I] = Char then Inc(Result); end; function TrimRightLineEnding(const sText: String; TextLineBreakStyle: TTextLineBreakStyle): String; const TextLineBreakArray: array[TTextLineBreakStyle] of Integer = (1, 2, 1); var I, L: Integer; begin L:= Length(sText); I:= TextLineBreakArray[TextLineBreakStyle]; Result:= Copy(sText, 1, L - I); // Copy without last line ending end; function mbCompareText(const s1, s2: String): PtrInt; inline; begin // From 0.9.31 LazUtils can be used but this package does not exist in 0.9.30. // Result := LazUTF8.UTF8CompareText(s1, s2); Result := WideCompareText(UTF8Decode(s1), UTF8Decode(s2)); end; function StrNewW(const mbString: String): PWideChar; var wsString: WideString; iLength: PtrInt; begin Result:= nil; wsString:= UTF8Decode(mbString); iLength:= (Length(wsString) * SizeOf(WideChar)) + 1; Result:= GetMem(iLength); if Result <> nil then Move(PWideChar(wsString)^, Result^, iLength); end; procedure StrDisposeW(var pStr : PWideChar); begin FreeMem(pStr); pStr := nil; end; function StrLCopyW(Dest, Source: PWideChar; MaxLen: SizeInt): PWideChar; var I: SizeInt; begin Result := Dest; for I:= 0 to MaxLen - 1 do begin if Source^ = #0 then Break; Dest^ := Source^; Inc(Source); Inc(Dest); end; Dest^ := #0; end; function StrPCopyW(Dest: PWideChar; const Source: WideString): PWideChar; begin Result := StrLCopyW(Dest, PWideChar(Source), Length(Source)); end; function StrPLCopyW(Dest: PWideChar; const Source: WideString; MaxLen: Cardinal): PWideChar; begin Result := StrLCopyW(Dest, PWideChar(Source), MaxLen); end; function RPos(const Substr: UnicodeString; const Source: UnicodeString): Integer; var c : WideChar; pc, pc2 : PWideChar; MaxLen, llen : Integer; begin Result:= 0; llen:= Length(SubStr); maxlen:= Length(Source); if (llen > 0) and (maxlen > 0) and (llen <= maxlen) then begin pc:= @Source[maxlen]; pc2:= @Source[llen - 1]; c:= Substr[llen]; while pc >= pc2 do begin if (c = pc^) and (CompareByte(Substr[1], PByte(pc - llen + 1)^, llen * SizeOf(WideChar)) = 0) then begin Result:= PWideChar(pc - llen + 1) - PWideChar(@source[1]) + 1; Exit; end; Dec(pc); end; end; end; function StrBegins(const StringToCheck, StringToMatch: String): Boolean; begin Result := (Length(StringToCheck) >= Length(StringToMatch)) and (CompareChar(StringToCheck[1], StringToMatch[1], Length(StringToMatch)) = 0); end; function StrEnds(const StringToCheck, StringToMatch: String): Boolean; begin Result := (Length(StringToCheck) >= Length(StringToMatch)) and (CompareChar(StringToCheck[1 + Length(StringToCheck) - Length(StringToMatch)], StringToMatch[1], Length(StringToMatch)) = 0); end; procedure AddStrWithSep(var SourceString: String; const StringToAdd: String; const Separator: Char); begin if (Length(SourceString) > 0) and (Length(StringToAdd) > 0) then SourceString := SourceString + Separator; SourceString := SourceString + StringToAdd; end; procedure AddStrWithSep(var SourceString: String; const StringToAdd: String; const Separator: String); begin if (Length(SourceString) > 0) and (Length(StringToAdd) > 0) then SourceString := SourceString + Separator; SourceString := SourceString + StringToAdd; end; procedure ParseLineToList(sLine: String; ssItems: TStrings); var xPos: Integer; begin ssItems.Clear; while sLine <> '' do begin xPos:= Pos(';', sLine); if xPos > 0 then begin ssItems.Add(Copy(sLine, 1, xPos - 1)); Delete(sLine, 1, xPos); end else begin ssItems.Add(sLine); Exit; end; end; end; function ContainsOneOf(StringToCheck: String; PossibleCharacters: String): Boolean; var i, j: SizeInt; pc : PChar; begin pc := @StringToCheck[1]; for i := 1 to Length(StringToCheck) do begin for j := 1 to Length(PossibleCharacters) do if pc^ = PossibleCharacters[j] then Exit(True); Inc(pc); end; Result := False; end; function OctToDec(Value: String): LongInt; var I: Integer; begin Result:= 0; for I:= 1 to Length(Value) do Result:= Result * 8 + StrToInt(Copy(Value, I, 1)); end; function DecToOct(Value: LongInt): String; var iMod: Integer; begin Result := ''; while Value >= 8 do begin iMod:= Value mod 8; Value:= Value div 8; Result:= IntToStr(iMod) + Result; end; Result:= IntToStr(Value) + Result; end; procedure AddString(var anArray: TDynamicStringArray; const sToAdd: String); var Len: Integer; begin Len := Length(anArray); SetLength(anArray, Len + 1); anArray[Len] := sToAdd; end; function SplitString(const S: String; Delimiter: AnsiChar): TDynamicStringArray; var Start: Integer = 1; Len, Finish: Integer; begin Len:= Length(S); for Finish:= 1 to Len - 1 do begin if S[Finish] = Delimiter then begin AddString(Result, Copy(S, Start, Finish - Start)); Start:= Finish + 1; end; end; if Start <= Len then begin AddString(Result, Copy(S, Start, Len - Start + 1)); end; end; function ArrBegins(const Array1, Array2: array of String; BothWays: Boolean): Boolean; var Len1, Len2: Integer; i: Integer; begin Len1 := Length(Array1); Len2 := Length(Array2); if not BothWays and (Len1 < Len2) then Result := False else begin if Len1 > Len2 then Len1 := Len2; for i := 0 to Len1 - 1 do if Array1[i] <> Array2[i] then Exit(False); Result := True; end; end; function ArrayToString(const anArray: TDynamicStringArray; const Separator: Char): String; var i: Integer; begin Result := ''; for i := Low(anArray) to High(anArray) do AddStrWithSep(Result, anArray[i], Separator); end; function Compare(const Array1, Array2: array of String): Boolean; var Len1, Len2: Integer; i: Integer; begin Len1 := Length(Array1); Len2 := Length(Array2); if Len1 <> Len2 then Result := False else begin for i := 0 to Len1 - 1 do if Array1[i] <> Array2[i] then Exit(False); Result := True; end; end; function CopyArray(const anArray: array of String): TDynamicStringArray; var i: Integer; begin SetLength(Result, Length(anArray)); for i := Low(anArray) to High(anArray) do Result[i] := anArray[i]; end; function ContainsOneOf(const ArrayToSearch, StringsToSearch: array of String): Boolean; var i: Integer; begin for i := Low(StringsToSearch) to High(StringsToSearch) do if Contains(ArrayToSearch, StringsToSearch[i]) then Exit(True); Result := False; end; function Contains(const ArrayToSearch: array of String; const StringToSearch: String): Boolean; var i: Integer; begin for i := Low(ArrayToSearch) to High(ArrayToSearch) do if ArrayToSearch[i] = StringToSearch then Exit(True); Result := False; end; procedure DeleteString(var anArray: TDynamicStringArray; const Index: Integer); var Len: Integer; i: Integer; begin Len := Length(anArray); for i := Index + 1 to Len - 1 do anArray[i - 1] := anArray[i]; SetLength(anArray, Len - 1); end; procedure DeleteString(var anArray: TDynamicStringArray; const sToDelete: String); var i: Integer; begin for i := Low(anArray) to High(anArray) do if anArray[i] = sToDelete then begin DeleteString(anArray, i); Exit; end; end; function GetArrayFromStrings(Strings: TStrings): TDynamicStringArray; var LinesCount: Integer; i: Integer; begin LinesCount := Strings.Count; if LinesCount > 0 then begin if Strings[LinesCount-1] = '' then Dec(LinesCount); SetLength(Result, LinesCount); for i := 0 to LinesCount - 1 do Result[i] := Strings[i]; end; end; procedure SetStringsFromArray(Strings: TStrings; const anArray: TDynamicStringArray); var s: String; begin Strings.Clear; for s in anArray do Strings.Add(s); end; procedure SetValue(var anArray: TDynamicStringArray; Key, NewValue: String); var i: Integer; begin Key := Key + '='; for i := Low(anArray) to High(anArray) do if StrBegins(anArray[i], Key) then begin anArray[i] := Key + NewValue; Exit; end; AddString(anArray, Key + NewValue); end; procedure SetValue(var anArray: TDynamicStringArray; Key: String; NewValue: Boolean); begin if NewValue then SetValue(anArray, Key, 'true') else SetValue(anArray, Key, 'false'); end; function ShortcutsToText(const Shortcuts: TDynamicStringArray): String; begin Result := ArrayToString(Shortcuts, ' '); end; { GetDateTimeInStrEZSortable: Return the date and time in string format with YYYY-MM-DD@HH-MM-SS so it can be integrate in a filename. Also, because of the order of the terms, it make it useful when things are sorted BECAUSE it will also sort by date/time at the same time} function GetDateTimeInStrEZSortable(DateTime:TDateTime):string; var MyYear, MyMonth, MyDay, MyHour, MyMin, MySec, MyMilSec: word; begin DecodeDate(DateTime, MyYear, MyMonth, MyDay); DecodeTime(DateTime, MyHour, MyMin, MySec, MyMilSec); result:=Format('%d-%2.2d-%2.2d@%2.2d-%2.2d-%2.2d', [MyYear, MyMonth, MyDay, MyHour, MyMin, MySec]); end; function WrapTextSimple(const S: String; MaxCol: Integer): String; var Len, Index: Integer; begin Index:= 1; Result:= EmptyStr; Len:= UTF8Length(S); while (Len > 0) do begin Result:= Result + UTF8Copy(S, Index, MaxCol) + LineEnding; Inc(Index, MaxCol); Dec(Len, MaxCol); end; SetLength(Result, Length(Result) - Length(LineEnding)); end; end. doublecmd-0.8.2/components/doublecmd/dcconvertencoding.inc0000664000175000017500000004141312650700750023026 0ustar alexxalexx{ Do not edit this file! It is autogenerated from C program natspec.c } const charset_relation: array[0..253, 0..3] of String = ( ('C' , 'C' , 'CP1252' , 'IBM437' ), ('POSIX' , 'POSIX' , 'CP1252' , 'IBM437' ), ('aa' , 'aa_DJ' , 'CP1252' , 'IBM437' ), ('aa' , 'aa_ER' , 'CP1252' , 'IBM437' ), ('aa' , 'aa_ER@saaho' , 'CP1252' , 'IBM437' ), ('aa' , 'aa_ET' , 'CP1252' , 'IBM437' ), ('af' , 'af_ZA' , 'CP1252' , 'IBM850' ), ('am' , 'am_ET' , 'CP1252' , 'IBM437' ), ('an' , 'an_ES' , 'CP1252' , 'IBM437' ), ('ar' , 'ar_AE' , 'CP1256' , '' ), ('ar' , 'ar_BH' , 'CP1256' , '' ), ('ar' , 'ar_DZ' , 'CP1256' , '' ), ('ar' , 'ar_EG' , 'CP1256' , '' ), ('ar' , 'ar_IN' , 'CP1256' , '' ), ('ar' , 'ar_IQ' , 'CP1256' , '' ), ('ar' , 'ar_JO' , 'CP1256' , '' ), ('ar' , 'ar_KW' , 'CP1256' , '' ), ('ar' , 'ar_LB' , 'CP1256' , '' ), ('ar' , 'ar_LY' , 'CP1256' , '' ), ('ar' , 'ar_MA' , 'CP1256' , '' ), ('ar' , 'ar_OM' , 'CP1256' , '' ), ('ar' , 'ar_QA' , 'CP1256' , '' ), ('ar' , 'ar_SA' , 'CP1256' , '' ), ('ar' , 'ar_SD' , 'CP1256' , '' ), ('ar' , 'ar_SY' , 'CP1256' , '' ), ('ar' , 'ar_TN' , 'CP1256' , '' ), ('ar' , 'ar_YE' , 'CP1256' , '' ), ('as' , 'as_IN' , 'CP1252' , 'IBM437' ), ('ast' , 'ast_ES' , 'CP1252' , 'IBM437' ), ('az' , 'az_AZ' , 'CP1254' , 'IBM857' ), ('be' , 'be_BY' , 'CP1251' , 'IBM849' ), ('be' , 'be_BY@latin' , 'CP1251' , 'IBM849' ), ('ber' , 'ber_DZ' , 'CP1252' , 'IBM437' ), ('ber' , 'ber_MA' , 'CP1252' , 'IBM437' ), ('bg' , 'bg_BG' , 'CP1251' , 'IBM866' ), ('bn' , 'bn_BD' , 'CP1252' , 'IBM437' ), ('bn' , 'bn_IN' , 'CP1252' , 'IBM437' ), ('bo' , 'bo_CN' , 'CP1252' , 'IBM437' ), ('bo' , 'bo_IN' , 'CP1252' , 'IBM437' ), ('br' , 'br_FR' , 'CP1252' , 'IBM850' ), ('br' , 'br_FR@euro' , 'CP1252' , 'IBM850' ), ('bs' , 'bs_BA' , 'CP1252' , 'IBM437' ), ('byn' , 'byn_ER' , 'CP1252' , 'IBM437' ), ('ca' , 'ca_AD' , 'CP1252' , 'IBM850' ), ('ca' , 'ca_ES' , 'CP1252' , 'IBM850' ), ('ca' , 'ca_ES@euro' , 'CP1252' , 'IBM850' ), ('ca' , 'ca_FR' , 'CP1252' , 'IBM850' ), ('ca' , 'ca_IT' , 'CP1252' , 'IBM850' ), ('crh' , 'crh_UA' , 'CP1252' , 'IBM437' ), ('cs' , 'cs_CZ' , 'CP1250' , 'IBM852' ), ('csb' , 'csb_PL' , 'CP1252' , 'IBM437' ), ('cy' , 'cy_GB' , 'ISO885914' , 'IBM850' ), ('da' , 'da_DK' , 'CP1252' , 'IBM850' ), ('de' , 'de_AT' , 'CP1252' , 'IBM850' ), ('de' , 'de_AT@euro' , 'CP1252' , 'IBM850' ), ('de' , 'de_BE' , 'CP1252' , 'IBM850' ), ('de' , 'de_BE@euro' , 'CP1252' , 'IBM850' ), ('de' , 'de_CH' , 'CP1252' , 'IBM850' ), ('de' , 'de_DE' , 'CP1252' , 'IBM850' ), ('de' , 'de_DE@euro' , 'CP1252' , 'IBM850' ), ('de' , 'de_LU' , 'CP1252' , 'IBM850' ), ('de' , 'de_LU@euro' , 'CP1252' , 'IBM850' ), ('dz' , 'dz_BT' , 'CP1252' , 'IBM437' ), ('el' , 'el_CY' , 'CP1253' , '' ), ('el' , 'el_GR' , 'CP1253' , '' ), ('en' , 'en_AG' , 'CP1252' , 'IBM437' ), ('en' , 'en_AU' , 'CP1252' , 'IBM850' ), ('en' , 'en_BW' , 'CP1252' , 'IBM437' ), ('en' , 'en_CA' , 'CP1252' , 'IBM850' ), ('en' , 'en_DK' , 'CP1252' , 'IBM437' ), ('en' , 'en_GB' , 'CP1252' , 'IBM850' ), ('en' , 'en_HK' , 'CP1252' , 'IBM437' ), ('en' , 'en_IE' , 'CP1252' , 'IBM850' ), ('en' , 'en_IE@euro' , 'CP1252' , 'IBM850' ), ('en' , 'en_IN' , 'CP1252' , 'IBM437' ), ('en' , 'en_NG' , 'CP1252' , 'IBM437' ), ('en' , 'en_NZ' , 'CP1252' , 'IBM850' ), ('en' , 'en_PH' , 'CP1252' , 'IBM437' ), ('en' , 'en_SG' , 'CP1252' , 'IBM437' ), ('en' , 'en_US' , 'CP1252' , 'IBM437' ), ('en' , 'en_ZA' , 'CP1252' , 'IBM437' ), ('en' , 'en_ZW' , 'CP1252' , 'IBM437' ), ('es' , 'es_AR' , 'CP1252' , 'IBM850' ), ('es' , 'es_BO' , 'CP1252' , 'IBM850' ), ('es' , 'es_CL' , 'CP1252' , 'IBM850' ), ('es' , 'es_CO' , 'CP1252' , 'IBM850' ), ('es' , 'es_CR' , 'CP1252' , 'IBM850' ), ('es' , 'es_DO' , 'CP1252' , 'IBM850' ), ('es' , 'es_EC' , 'CP1252' , 'IBM850' ), ('es' , 'es_ES' , 'CP1252' , 'IBM850' ), ('es' , 'es_ES@euro' , 'CP1252' , 'IBM850' ), ('es' , 'es_GT' , 'CP1252' , 'IBM850' ), ('es' , 'es_HN' , 'CP1252' , 'IBM850' ), ('es' , 'es_MX' , 'CP1252' , 'IBM850' ), ('es' , 'es_NI' , 'CP1252' , 'IBM850' ), ('es' , 'es_PA' , 'CP1252' , 'IBM850' ), ('es' , 'es_PE' , 'CP1252' , 'IBM850' ), ('es' , 'es_PR' , 'CP1252' , 'IBM850' ), ('es' , 'es_PY' , 'CP1252' , 'IBM850' ), ('es' , 'es_SV' , 'CP1252' , 'IBM850' ), ('es' , 'es_US' , 'CP1252' , 'IBM850' ), ('es' , 'es_UY' , 'CP1252' , 'IBM850' ), ('es' , 'es_VE' , 'CP1252' , 'IBM850' ), ('et' , 'et_EE' , 'CP1257' , '' ), ('eu' , 'eu_ES' , 'CP1252' , 'IBM850' ), ('eu' , 'eu_ES@euro' , 'CP1252' , 'IBM850' ), ('fa' , 'fa_IR' , 'CP1256' , '' ), ('fi' , 'fi_FI' , 'CP1252' , 'IBM850' ), ('fi' , 'fi_FI@euro' , 'CP1252' , 'IBM850' ), ('fil' , 'fil_PH' , 'CP1252' , 'IBM437' ), ('fo' , 'fo_FO' , 'CP1252' , 'IBM850' ), ('fr' , 'fr_BE' , 'CP1252' , 'IBM850' ), ('fr' , 'fr_BE@euro' , 'CP1252' , 'IBM850' ), ('fr' , 'fr_CA' , 'CP1252' , 'IBM850' ), ('fr' , 'fr_CH' , 'CP1252' , 'IBM850' ), ('fr' , 'fr_FR' , 'CP1252' , 'IBM850' ), ('fr' , 'fr_FR@euro' , 'CP1252' , 'IBM850' ), ('fr' , 'fr_LU' , 'CP1252' , 'IBM850' ), ('fr' , 'fr_LU@euro' , 'CP1252' , 'IBM850' ), ('fur' , 'fur_IT' , 'CP1252' , 'IBM437' ), ('fy' , 'fy_DE' , 'CP1252' , 'IBM437' ), ('fy' , 'fy_NL' , 'CP1252' , 'IBM437' ), ('ga' , 'ga_IE' , 'CP1252' , 'IBM437' ), ('ga' , 'ga_IE@euro' , 'CP1252' , 'IBM437' ), ('gd' , 'gd_GB' , 'CP1252' , 'IBM850' ), ('gez' , 'gez_ER' , 'CP1252' , 'IBM437' ), ('gez' , 'gez_ER@abegede' , 'CP1252' , 'IBM437' ), ('gez' , 'gez_ET' , 'CP1252' , 'IBM437' ), ('gez' , 'gez_ET@abegede' , 'CP1252' , 'IBM437' ), ('gl' , 'gl_ES' , 'CP1252' , 'IBM850' ), ('gl' , 'gl_ES@euro' , 'CP1252' , 'IBM850' ), ('gv' , 'gv_GB' , 'CP1252' , 'IBM850' ), ('ha' , 'ha_NG' , 'CP1252' , 'IBM437' ), ('he' , 'he_IL' , 'CP1255' , 'IBM862' ), ('hne' , 'hne_IN' , 'CP1252' , 'IBM437' ), ('hr' , 'hr_HR' , 'CP1250' , 'IBM852' ), ('hsb' , 'hsb_DE' , 'CP1252' , 'IBM437' ), ('ht' , 'ht_HT' , 'CP1252' , 'IBM437' ), ('hu' , 'hu_HU' , 'CP1250' , 'IBM852' ), ('hy' , 'hy_AM' , 'CP1252' , 'IBM437' ), ('id' , 'id_ID' , 'CP1252' , 'IBM850' ), ('ig' , 'ig_NG' , 'CP1252' , 'IBM437' ), ('ik' , 'ik_CA' , 'CP1252' , 'IBM437' ), ('is' , 'is_IS' , 'CP1252' , 'IBM850' ), ('it' , 'it_CH' , 'CP1252' , 'IBM850' ), ('it' , 'it_IT' , 'CP1252' , 'IBM850' ), ('it' , 'it_IT@euro' , 'CP1252' , 'IBM850' ), ('iu' , 'iu_CA' , 'CP1252' , 'IBM437' ), ('iw' , 'iw_IL' , 'CP1252' , 'IBM437' ), ('ja' , 'ja_JP' , 'CP932' , 'CP932' ), ('kk' , 'kk_KZ' , 'CP1251' , 'IBM866' ), ('kl' , 'kl_GL' , 'CP1252' , 'IBM437' ), ('km' , 'km_KH' , 'CP1252' , 'IBM437' ), ('ko' , 'ko_KR' , 'CP949' , 'CP949' ), ('ks' , 'ks_IN' , 'CP1252' , 'IBM437' ), ('ks' , 'ks_IN@devanagari' , 'CP1252' , 'IBM437' ), ('ku' , 'ku_TR' , 'CP1252' , 'IBM437' ), ('kw' , 'kw_GB' , 'CP1252' , 'IBM850' ), ('ky' , 'ky_KG' , 'CP1251' , 'IBM866' ), ('lg' , 'lg_UG' , 'CP1252' , 'IBM437' ), ('li' , 'li_BE' , 'CP1252' , 'IBM437' ), ('li' , 'li_NL' , 'CP1252' , 'IBM437' ), ('lo' , 'lo_LA' , 'CP1252' , 'IBM437' ), ('lt' , 'lt_LT' , 'CP1257' , '' ), ('lv' , 'lv_LV' , 'CP1257' , '' ), ('mai' , 'mai_IN' , 'CP1252' , 'IBM437' ), ('mg' , 'mg_MG' , 'CP1252' , 'IBM437' ), ('mi' , 'mi_NZ' , 'CP1252' , 'IBM437' ), ('mk' , 'mk_MK' , 'CP1251' , 'IBM866' ), ('ml' , 'ml_IN' , 'CP1252' , 'IBM437' ), ('mn' , 'mn_MN' , 'CP1251' , 'IBM866' ), ('ms' , 'ms_MY' , 'CP1252' , 'IBM850' ), ('mt' , 'mt_MT' , 'CP1252' , 'IBM437' ), ('nan' , 'nan_TW@latin' , 'CP1252' , 'IBM437' ), ('nb' , 'nb_NO' , 'CP1252' , 'IBM850' ), ('nds' , 'nds_DE' , 'CP1252' , 'IBM437' ), ('nds' , 'nds_NL' , 'CP1252' , 'IBM437' ), ('ne' , 'ne_NP' , 'CP1252' , 'IBM437' ), ('nl' , 'nl_AW' , 'CP1252' , 'IBM850' ), ('nl' , 'nl_BE' , 'CP1252' , 'IBM850' ), ('nl' , 'nl_BE@euro' , 'CP1252' , 'IBM850' ), ('nl' , 'nl_NL' , 'CP1252' , 'IBM850' ), ('nl' , 'nl_NL@euro' , 'CP1252' , 'IBM850' ), ('nn' , 'nn_NO' , 'CP1252' , 'IBM850' ), ('no' , 'no_NO' , 'CP1252' , 'IBM437' ), ('nr' , 'nr_ZA' , 'CP1252' , 'IBM437' ), ('nso' , 'nso_ZA' , 'CP1252' , 'IBM437' ), ('oc' , 'oc_FR' , 'CP1252' , 'IBM437' ), ('om' , 'om_ET' , 'CP1252' , 'IBM437' ), ('om' , 'om_KE' , 'CP1252' , 'IBM437' ), ('or' , 'or_IN' , 'CP1252' , 'IBM437' ), ('pap' , 'pap_AN' , 'CP1252' , 'IBM437' ), ('pl' , 'pl_PL' , 'CP1250' , 'IBM852' ), ('pt' , 'pt_BR' , 'CP1252' , 'IBM850' ), ('pt' , 'pt_PT' , 'CP1252' , 'IBM850' ), ('pt' , 'pt_PT@euro' , 'CP1252' , 'IBM850' ), ('ro' , 'ro_RO' , 'CP1250' , 'IBM852' ), ('ru' , 'ru_RU' , 'CP1251' , 'IBM866' ), ('ru' , 'ru_UA' , 'CP1251' , 'IBM866' ), ('rw' , 'rw_RW' , 'CP1252' , 'IBM437' ), ('sc' , 'sc_IT' , 'CP1252' , 'IBM437' ), ('sd' , 'sd_IN' , 'CP1252' , 'IBM437' ), ('sd' , 'sd_IN@devanagari' , 'CP1252' , 'IBM437' ), ('se' , 'se_NO' , 'CP1252' , 'IBM437' ), ('shs' , 'shs_CA' , 'CP1252' , 'IBM437' ), ('si' , 'si_LK' , 'CP1252' , 'IBM437' ), ('sid' , 'sid_ET' , 'CP1252' , 'IBM437' ), ('sk' , 'sk_SK' , 'CP1250' , 'IBM852' ), ('sl' , 'sl_SI' , 'CP1250' , 'IBM852' ), ('so' , 'so_DJ' , 'CP1252' , 'IBM437' ), ('so' , 'so_ET' , 'CP1252' , 'IBM437' ), ('so' , 'so_KE' , 'CP1252' , 'IBM437' ), ('so' , 'so_SO' , 'CP1252' , 'IBM437' ), ('sq' , 'sq_AL' , 'CP1250' , 'IBM852' ), ('sr' , 'sr_ME' , 'CP1250' , 'IBM852' ), ('sr' , 'sr_RS' , 'CP1250' , 'IBM852' ), ('sr' , 'sr_RS@latin' , 'CP1250' , 'IBM852' ), ('ss' , 'ss_ZA' , 'CP1252' , 'IBM437' ), ('st' , 'st_ZA' , 'CP1252' , 'IBM437' ), ('sv' , 'sv_FI' , 'CP1252' , 'IBM850' ), ('sv' , 'sv_FI@euro' , 'CP1252' , 'IBM850' ), ('sv' , 'sv_SE' , 'CP1252' , 'IBM850' ), ('tg' , 'tg_TJ' , 'CP1252' , 'IBM437' ), ('th' , 'th_TH' , 'IBM874' , 'IBM874' ), ('ti' , 'ti_ER' , 'CP1252' , 'IBM437' ), ('ti' , 'ti_ET' , 'CP1252' , 'IBM437' ), ('tig' , 'tig_ER' , 'CP1252' , 'IBM437' ), ('tk' , 'tk_TM' , 'CP1252' , 'IBM437' ), ('tl' , 'tl_PH' , 'CP1252' , 'IBM437' ), ('tn' , 'tn_ZA' , 'CP1252' , 'IBM437' ), ('tr' , 'tr_CY' , 'CP1254' , 'IBM857' ), ('tr' , 'tr_TR' , 'CP1254' , 'IBM857' ), ('ts' , 'ts_ZA' , 'CP1252' , 'IBM437' ), ('tt' , 'tt_RU' , 'CP1251' , 'IBM866' ), ('tt' , 'tt_RU@iqtelif' , 'CP1251' , 'IBM866' ), ('ug' , 'ug_CN' , 'CP1252' , 'IBM437' ), ('uk' , 'uk_UA' , 'CP1251' , 'CP1125' ), ('ur' , 'ur_PK' , 'CP1256' , '' ), ('uz' , 'uz_UZ' , 'CP1251' , 'IBM866' ), ('uz' , 'uz_UZ@cyrillic' , 'CP1254' , 'IBM857' ), ('ve' , 've_ZA' , 'CP1252' , 'IBM437' ), ('vi' , 'vi_VN' , 'CP1258' , 'CP1258' ), ('wa' , 'wa_BE' , 'CP1252' , 'IBM850' ), ('wa' , 'wa_BE@euro' , 'CP1252' , 'IBM850' ), ('wo' , 'wo_SN' , 'CP1252' , 'IBM437' ), ('xh' , 'xh_ZA' , 'CP1252' , 'IBM437' ), ('yi' , 'yi_US' , 'CP1252' , 'IBM437' ), ('yo' , 'yo_NG' , 'CP1252' , 'IBM437' ), ('zh' , 'zh_CN' , 'CP936' , 'CP936' ), ('zh' , 'zh_HK' , 'BIG5' , 'BIG5' ), ('zh' , 'zh_SG' , 'CP936' , 'CP936' ), ('zh' , 'zh_TW' , 'BIG5' , 'BIG5' ), ('zu' , 'zu_ZA' , 'CP1252' , 'IBM437' ), ('POSIX' , 'POSIX' , 'CP1252' , 'IBM437' ) ); doublecmd-0.8.2/components/doublecmd/dclinuxmagic.inc0000664000175000017500000000506213243752341022001 0ustar alexxalexx{ /usr/include/linux/magic.h } const ADFS_SUPER_MAGIC = $adf5; AFFS_SUPER_MAGIC = $adff; AFS_SUPER_MAGIC = $5346414F; AUTOFS_SUPER_MAGIC = $0187; CODA_SUPER_MAGIC = $73757245; { some random number } CRAMFS_MAGIC = $28cd3d45; { magic number with the wrong endianess } CRAMFS_MAGIC_WEND = $453dcd28; DEBUGFS_MAGIC = $64626720; SECURITYFS_MAGIC = $73636673; SELINUX_MAGIC = $f97cff8c; { "SMAC" } SMACK_MAGIC = $43415d53; { some random number } RAMFS_MAGIC = $858458f6; TMPFS_MAGIC = $01021994; { some random number } HUGETLBFS_MAGIC = $958458f6; SQUASHFS_MAGIC = $73717368; ECRYPTFS_SUPER_MAGIC = $f15f; EFS_SUPER_MAGIC = $414A53; EXT2_SUPER_MAGIC = $EF53; EXT3_SUPER_MAGIC = $EF53; XENFS_SUPER_MAGIC = $abba1974; EXT4_SUPER_MAGIC = $EF53; BTRFS_SUPER_MAGIC = $9123683E; NILFS_SUPER_MAGIC = $3434; F2FS_SUPER_MAGIC = $F2F52010; HPFS_SUPER_MAGIC = $f995e849; ISOFS_SUPER_MAGIC = $9660; JFFS2_SUPER_MAGIC = $72b6; PSTOREFS_MAGIC = $6165676C; EFIVARFS_MAGIC = $de5e81e4; HOSTFS_SUPER_MAGIC = $00c0ffee; OVERLAYFS_SUPER_MAGIC = $794c7630; { minix v1 fs, 14 char names } MINIX_SUPER_MAGIC = $137F; { minix v1 fs, 30 char names } MINIX_SUPER_MAGIC2 = $138F; { minix v2 fs, 14 char names } MINIX2_SUPER_MAGIC = $2468; { minix v2 fs, 30 char names } MINIX2_SUPER_MAGIC2 = $2478; { minix v3 fs, 60 char names } MINIX3_SUPER_MAGIC = $4d5a; { MD } MSDOS_SUPER_MAGIC = $4d44; { Guess, what 0x564c is :-) } NCP_SUPER_MAGIC = $564c; NFS_SUPER_MAGIC = $6969; OCFS2_SUPER_MAGIC = $7461636f; OPENPROM_SUPER_MAGIC = $9fa1; { qnx4 fs detection } QNX4_SUPER_MAGIC = $002f; { qnx6 fs detection } QNX6_SUPER_MAGIC = $68191122; AFS_FS_MAGIC = $6B414653; { used by gcc } REISERFS_SUPER_MAGIC = $52654973; SMB_SUPER_MAGIC = $517B; CGROUP_SUPER_MAGIC = $27e0eb; CGROUP2_SUPER_MAGIC = $63677270; RDTGROUP_SUPER_MAGIC = $7655821; STACK_END_MAGIC = $57AC6E9D; TRACEFS_MAGIC = $74726163; V9FS_MAGIC = $01021997; BDEVFS_MAGIC = $62646576; DAXFS_MAGIC = $64646178; BINFMTFS_MAGIC = $42494e4d; DEVPTS_SUPER_MAGIC = $1cd1; FUTEXFS_SUPER_MAGIC = $BAD1DEA; PIPEFS_MAGIC = $50495045; PROC_SUPER_MAGIC = $9fa0; SOCKFS_MAGIC = $534F434B; SYSFS_MAGIC = $62656572; USBDEVICE_SUPER_MAGIC = $9fa2; MTD_INODE_FS_MAGIC = $11307854; ANON_INODE_FS_MAGIC = $09041934; BTRFS_TEST_MAGIC = $73727279; NSFS_MAGIC = $6e736673; BPF_FS_MAGIC = $cafe4a11; AAFS_MAGIC = $5a3c69f0; { Since UDF 2.01 is ISO 13346 based... } UDF_SUPER_MAGIC = $15013346; BALLOON_KVM_MAGIC = $13661366; ZSMALLOC_MAGIC = $58295829; doublecmd-0.8.2/components/doublecmd/doublecmd_common.pas0000664000175000017500000000053612756114647022664 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit doublecmd_common; interface uses DCClassesUtf8, DCOSUtils, DCStrUtils, DCBasicTypes, DCFileAttributes, DCConvertEncoding, DCDateTimeUtils, DCXmlConfig, DCProcessUtf8, DCUnicodeUtils; implementation end. doublecmd-0.8.2/components/doublecmd/dcxmlconfig.pas0000664000175000017500000006140313056767177021661 0ustar alexxalexx{ Double Commander ------------------------------------------------------------------------- Implementation of configuration file in XML. Based on XmlConf from fcl-xml package. Copyright (C) 2010 Przemyslaw Nagay (cobines@gmail.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } unit DCXmlConfig; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Laz2_DOM, Laz2_XMLRead, Laz2_XMLWrite; type // Define type aliases so we don't have to include DOM if we want to use config. TXmlNode = TDOMNode; TXmlPath = DOMString; { TXmlConfig } TXmlConfig = class private FFileName: String; FDoc: TXMLDocument; function GetRootNode: TXmlNode; procedure SplitPathToNodeAndAttr(const Path: DOMString; out NodePath: DOMString; out AttrName: DOMString); public constructor Create; virtual; constructor Create(const AFileName: String; AutoLoad: Boolean = False); virtual; destructor Destroy; override; procedure Clear; function AddNode(const RootNode: TDOMNode; const ValueName: DOMString): TDOMNode; procedure DeleteNode(const RootNode: TDOMNode; const Path: DOMString); procedure DeleteNode(const Node: TDOMNode); procedure ClearNode(const Node: TDOMNode); function FindNode(const RootNode: TDOMNode; const Path: DOMString; bCreate: Boolean = False): TDOMNode; function GetContent(const Node: TDOMNode): String; function IsEmpty: Boolean; procedure SetContent(const Node: TDOMNode; const AValue: String); // ------------------------------------------------------------------------ function GetAttr(const RootNode: TDOMNode; const Path: DOMString; const ADefault: String): String; function GetAttr(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Boolean): Boolean; function GetAttr(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Integer): Integer; function GetAttr(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Int64): Int64; function GetAttr(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Double): Double; function GetValue(const RootNode: TDOMNode; const Path: DOMString; const ADefault: String): String; function GetValue(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Boolean): Boolean; function GetValue(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Integer): Integer; function GetValue(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Int64): Int64; function GetValue(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Double): Double; // The Try... functions return True if the attribute/node was found and only then set AValue. function TryGetAttr(const RootNode: TDOMNode; const Path: DOMString; out AValue: String): Boolean; function TryGetAttr(const RootNode: TDOMNode; const Path: DOMString; out AValue: Boolean): Boolean; function TryGetAttr(const RootNode: TDOMNode; const Path: DOMString; out AValue: Integer): Boolean; function TryGetAttr(const RootNode: TDOMNode; const Path: DOMString; out AValue: Int64): Boolean; function TryGetAttr(const RootNode: TDOMNode; const Path: DOMString; out AValue: Double): Boolean; function TryGetValue(const RootNode: TDOMNode; const Path: DOMString; out AValue: String): Boolean; function TryGetValue(const RootNode: TDOMNode; const Path: DOMString; out AValue: Boolean): Boolean; function TryGetValue(const RootNode: TDOMNode; const Path: DOMString; out AValue: Integer): Boolean; function TryGetValue(const RootNode: TDOMNode; const Path: DOMString; out AValue: Int64): Boolean; function TryGetValue(const RootNode: TDOMNode; const Path: DOMString; out AValue: Double): Boolean; // ------------------------------------------------------------------------ // AddValue functions always add a new node. procedure AddValue(const RootNode: TDOMNode; const ValueName: DOMString; const AValue: String); procedure AddValue(const RootNode: TDOMNode; const ValueName: DOMString; const AValue: Boolean); procedure AddValue(const RootNode: TDOMNode; const ValueName: DOMString; const AValue: Integer); procedure AddValue(const RootNode: TDOMNode; const ValueName: DOMString; const AValue: Int64); procedure AddValue(const RootNode: TDOMNode; const ValueName: DOMString; const AValue: Double); procedure AddValueDef(const RootNode: TDOMNode; const ValueName: DOMString; const AValue, DefaultValue: String); procedure AddValueDef(const RootNode: TDOMNode; const ValueName: DOMString; const AValue, DefaultValue: Boolean); procedure AddValueDef(const RootNode: TDOMNode; const ValueName: DOMString; const AValue, DefaultValue: Integer); procedure AddValueDef(const RootNode: TDOMNode; const ValueName: DOMString; const AValue, DefaultValue: Int64); procedure AddValueDef(const RootNode: TDOMNode; const ValueName: DOMString; const AValue, DefaultValue: Double); // SetValue functions can only set values for unique paths. procedure SetAttr(const RootNode: TDOMNode; const Path: DOMString; const AValue: String); procedure SetAttr(const RootNode: TDOMNode; const Path: DOMString; const AValue: Boolean); procedure SetAttr(const RootNode: TDOMNode; const Path: DOMString; const AValue: Integer); procedure SetAttr(const RootNode: TDOMNode; const Path: DOMString; const AValue: Int64); procedure SetAttr(const RootNode: TDOMNode; const Path: DOMString; const AValue: Double); procedure SetValue(const RootNode: TDOMNode; const Path: DOMString; const AValue: String); procedure SetValue(const RootNode: TDOMNode; const Path: DOMString; const AValue: Boolean); procedure SetValue(const RootNode: TDOMNode; const Path: DOMString; const AValue: Integer); procedure SetValue(const RootNode: TDOMNode; const Path: DOMString; const AValue: Int64); procedure SetValue(const RootNode: TDOMNode; const Path: DOMString; const AValue: Double); // ------------------------------------------------------------------------ procedure GetFont(const aNode: TXmlNode; Path: TXmlPath; out Name: String; out Size: Integer; out Style, Quality: Integer; const DefName: String; const DefSize: Integer; const DefStyle, DefQuality: Integer); procedure SetFont(const aNode: TXmlNode; Path: TXmlPath; const Name: String; const Size: Integer; const Style, Quality: Integer); // ------------------------------------------------------------------------ procedure ReadFromFile(const AFilename: String); procedure ReadFromStream(AStream: TStream); procedure WriteToFile(const AFilename: String); procedure WriteToStream(AStream: TStream); function Load: Boolean; function LoadBypassingErrors: Boolean; function Save: Boolean; {en Get path of form "//...". } function GetPathFromNode(aNode: TDOMNode): String; property FileName: String read FFileName write FFileName; property RootNode: TXmlNode read GetRootNode; end; EXmlConfigEmpty = class(EFilerError); EXmlConfigNotFound = class(EFilerError); implementation uses LazLogger, DCOSUtils, DCClassesUtf8, URIParser; const BoolStrings: array[Boolean] of DOMString = ('False', 'True'); constructor TXmlConfig.Create; begin Clear; end; constructor TXmlConfig.Create(const AFileName: String; AutoLoad: Boolean); begin FFileName := AFileName; if not (AutoLoad and LoadBypassingErrors) then Clear; end; destructor TXmlConfig.Destroy; begin FreeAndNil(FDoc); inherited Destroy; end; procedure TXmlConfig.Clear; begin FreeAndNil(FDoc); FDoc := TXMLDocument.Create; FDoc.AppendChild(FDoc.CreateElement(ApplicationName)); end; function TXmlConfig.GetRootNode: TXmlNode; begin Result := FDoc.DocumentElement; end; // ------------------------------------------------------------------------ function TXmlConfig.GetAttr(const RootNode: TDOMNode; const Path: DOMString; const ADefault: String): String; begin if not TryGetAttr(RootNode, Path, Result) then Result := ADefault; end; function TXmlConfig.GetAttr(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Boolean): Boolean; begin if not TryGetAttr(RootNode, Path, Result) then Result := ADefault; end; function TXmlConfig.GetAttr(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Integer): Integer; begin if not TryGetAttr(RootNode, Path, Result) then Result := ADefault; end; function TXmlConfig.GetAttr(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Int64): Int64; begin if not TryGetAttr(RootNode, Path, Result) then Result := ADefault; end; function TXmlConfig.GetAttr(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Double): Double; begin if not TryGetAttr(RootNode, Path, Result) then Result := ADefault; end; function TXmlConfig.TryGetAttr(const RootNode: TDOMNode; const Path: DOMString; out AValue: String): Boolean; var Node: TDOMNode; Attr: TDOMAttr; NodePath, AttrName: DOMString; begin SplitPathToNodeAndAttr(Path, NodePath, AttrName); if NodePath <> EmptyStr then begin Node := FindNode(RootNode, NodePath, False); if not Assigned(Node) then Exit(False); end else Node := RootNode; Attr := TDOMElement(Node).GetAttributeNode(AttrName); Result := Assigned(Attr); if Result then AValue := Attr.Value; end; function TXmlConfig.TryGetAttr(const RootNode: TDOMNode; const Path: DOMString; out AValue: Boolean): Boolean; var sValue: String; begin Result := TryGetAttr(RootNode, Path, sValue); if Result then begin if SameText(sValue, 'TRUE') then AValue := True else if SameText(sValue, 'FALSE') then AValue := False else Result := False; // If other text then return not found. end; end; function TXmlConfig.TryGetAttr(const RootNode: TDOMNode; const Path: DOMString; out AValue: Integer): Boolean; var sValue: String; begin Result := TryGetAttr(RootNode, Path, sValue) and TryStrToInt(sValue, AValue); end; function TXmlConfig.TryGetAttr(const RootNode: TDOMNode; const Path: DOMString; out AValue: Int64): Boolean; var sValue: String; begin Result := TryGetAttr(RootNode, Path, sValue) and TryStrToInt64(sValue, AValue); end; function TXmlConfig.TryGetAttr(const RootNode: TDOMNode; const Path: DOMString; out AValue: Double): Boolean; var sValue: String; begin Result := TryGetAttr(RootNode, Path, sValue) and TryStrToFloat(sValue, AValue); end; function TXmlConfig.GetValue(const RootNode: TDOMNode; const Path: DOMString; const ADefault: String): String; var Node: TDOMNode; begin Node := FindNode(RootNode, Path, False); if Assigned(Node) then Result := Node.TextContent else Result := ADefault; end; function TXmlConfig.IsEmpty: Boolean; begin Result := RootNode.ChildNodes.Count = 0; end; function TXmlConfig.GetValue(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Boolean): Boolean; var sValue: String; begin sValue := GetValue(RootNode, Path, ''); if SameText(sValue, 'TRUE') then Result := True else if SameText(sValue, 'FALSE') then Result := False else Result := ADefault; end; function TXmlConfig.GetValue(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Integer): Integer; begin Result := StrToIntDef(GetValue(RootNode, Path, ''), ADefault); end; function TXmlConfig.GetValue(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Int64): Int64; begin Result := StrToInt64Def(GetValue(RootNode, Path, ''), ADefault); end; function TXmlConfig.GetValue(const RootNode: TDOMNode; const Path: DOMString; const ADefault: Double): Double; begin Result := StrToFloatDef(GetValue(RootNode, Path, ''), ADefault); end; function TXmlConfig.TryGetValue(const RootNode: TDOMNode; const Path: DOMString; out AValue: String): Boolean; var Node: TDOMNode; begin Node := FindNode(RootNode, Path, False); Result := Assigned(Node); if Result then AValue := Node.TextContent; end; function TXmlConfig.TryGetValue(const RootNode: TDOMNode; const Path: DOMString; out AValue: Boolean): Boolean; var sValue: String; begin Result := TryGetValue(RootNode, Path, sValue); if Result then begin if SameText(sValue, 'TRUE') then AValue := True else if SameText(sValue, 'FALSE') then AValue := False else Result := False; // If other text then return not found. end; end; function TXmlConfig.TryGetValue(const RootNode: TDOMNode; const Path: DOMString; out AValue: Integer): Boolean; var sValue: String; begin Result := TryGetValue(RootNode, Path, sValue) and TryStrToInt(sValue, AValue); end; function TXmlConfig.TryGetValue(const RootNode: TDOMNode; const Path: DOMString; out AValue: Int64): Boolean; var sValue: String; begin Result := TryGetValue(RootNode, Path, sValue) and TryStrToInt64(sValue, AValue); end; function TXmlConfig.TryGetValue(const RootNode: TDOMNode; const Path: DOMString; out AValue: Double): Boolean; var sValue: String; begin Result := TryGetValue(RootNode, Path, sValue) and TryStrToFloat(sValue, AValue); end; // ---------------------------------------------------------------------------- procedure TXmlConfig.AddValue(const RootNode: TDOMNode; const ValueName: DOMString; const AValue: String); var Node: TDOMNode; begin Node := RootNode.AppendChild(FDoc.CreateElement(ValueName)); Node.TextContent := AValue; end; procedure TXmlConfig.AddValueDef(const RootNode: TDOMNode; const ValueName: DOMString; const AValue, DefaultValue: Boolean); begin if AValue <> DefaultValue then AddValue(RootNode, ValueName, AValue); end; procedure TXmlConfig.AddValueDef(const RootNode: TDOMNode; const ValueName: DOMString; const AValue, DefaultValue: Double); begin if AValue <> DefaultValue then AddValue(RootNode, ValueName, AValue); end; procedure TXmlConfig.AddValueDef(const RootNode: TDOMNode; const ValueName: DOMString; const AValue, DefaultValue: Int64); begin if AValue <> DefaultValue then AddValue(RootNode, ValueName, AValue); end; procedure TXmlConfig.AddValueDef(const RootNode: TDOMNode; const ValueName: DOMString; const AValue, DefaultValue: Integer); begin if AValue <> DefaultValue then AddValue(RootNode, ValueName, AValue); end; procedure TXmlConfig.AddValueDef(const RootNode: TDOMNode; const ValueName: DOMString; const AValue, DefaultValue: String); begin if AValue <> DefaultValue then AddValue(RootNode, ValueName, AValue); end; procedure TXmlConfig.AddValue(const RootNode: TDOMNode; const ValueName: DOMString; const AValue: Boolean); begin AddValue(RootNode, ValueName, BoolStrings[AValue]); end; procedure TXmlConfig.AddValue(const RootNode: TDOMNode; const ValueName: DOMString; const AValue: Integer); begin AddValue(RootNode, ValueName, IntToStr(AValue)); end; procedure TXmlConfig.AddValue(const RootNode: TDOMNode; const ValueName: DOMString; const AValue: Int64); begin AddValue(RootNode, ValueName, IntToStr(AValue)); end; procedure TXmlConfig.AddValue(const RootNode: TDOMNode; const ValueName: DOMString; const AValue: Double); begin AddValue(RootNode, ValueName, FloatToStr(AValue)); end; procedure TXmlConfig.SetAttr(const RootNode: TDOMNode; const Path: DOMString; const AValue: String); var Node: TDOMNode; NodePath, AttrName: DOMString; begin SplitPathToNodeAndAttr(Path, NodePath, AttrName); if NodePath <> EmptyStr then begin Node := FindNode(RootNode, NodePath, True); TDOMElement(Node)[AttrName] := AValue; end else TDOMElement(RootNode)[AttrName] := AValue; end; procedure TXmlConfig.SetAttr(const RootNode: TDOMNode; const Path: DOMString; const AValue: Boolean); begin SetAttr(RootNode, Path, BoolStrings[AValue]); end; procedure TXmlConfig.SetAttr(const RootNode: TDOMNode; const Path: DOMString; const AValue: Integer); begin SetAttr(RootNode, Path, IntToStr(AValue)); end; procedure TXmlConfig.SetAttr(const RootNode: TDOMNode; const Path: DOMString; const AValue: Int64); begin SetAttr(RootNode, Path, IntToStr(AValue)); end; procedure TXmlConfig.SetAttr(const RootNode: TDOMNode; const Path: DOMString; const AValue: Double); begin SetAttr(RootNode, Path, FloatToStr(AValue)); end; procedure TXmlConfig.SetValue(const RootNode: TDOMNode; const Path: DOMString; const AValue: String); var Node: TDOMNode; begin Node := FindNode(RootNode, Path, True); Node.TextContent := AValue; end; procedure TXmlConfig.SetValue(const RootNode: TDOMNode; const Path: DOMString; const AValue: Boolean); begin SetValue(RootNode, Path, BoolStrings[AValue]); end; procedure TXmlConfig.SetValue(const RootNode: TDOMNode; const Path: DOMString; const AValue: Integer); begin SetValue(RootNode, Path, IntToStr(AValue)); end; procedure TXmlConfig.SetValue(const RootNode: TDOMNode; const Path: DOMString; const AValue: Int64); begin SetValue(RootNode, Path, IntToStr(AValue)); end; procedure TXmlConfig.SetValue(const RootNode: TDOMNode; const Path: DOMString; const AValue: Double); begin SetValue(RootNode, Path, FloatToStr(AValue)); end; // ---------------------------------------------------------------------------- procedure TXmlConfig.ReadFromFile(const AFilename: String); var FileStream: TStream; TmpDoc: TXMLDocument; begin FileStream := TFileStreamEx.Create(AFilename, fmOpenRead or fmShareDenyWrite); try if FileStream.Size = 0 then raise EXmlConfigEmpty.Create(''); ReadXMLFile(TmpDoc, FileStream, FilenameToURI(AFilename)); if TmpDoc.DocumentElement.NodeName <> ApplicationName then raise EXMLReadError.Create('Root element is not <' + ApplicationName + '>.'); FDoc.Free; FDoc := TmpDoc; finally FileStream.Free; end; end; procedure TXmlConfig.ReadFromStream(AStream: TStream); var TmpDoc: TXMLDocument; begin if AStream.Size = 0 then raise EXmlConfigEmpty.Create(''); ReadXMLFile(TmpDoc, AStream); FDoc.Free; FDoc := TmpDoc; end; procedure TXmlConfig.WriteToFile(const AFilename: String); var FileStream: TStream; begin FileStream := TFileStreamEx.Create(AFilename, fmCreate or fmShareDenyWrite); try WriteToStream(FileStream); finally FileStream.Free; end; end; procedure TXmlConfig.WriteToStream(AStream: TStream); var Position: Int64; MemoryStream: TMemoryStream; begin MemoryStream:= TMemoryStream.Create; try WriteXMLFile(FDoc, MemoryStream); Position:= AStream.Position; AStream.Size:= MemoryStream.Size; AStream.Position:= Position; MemoryStream.SaveToStream(AStream); finally MemoryStream.Free; end; end; function TXmlConfig.Load: Boolean; begin Result := False; if FFileName = '' then Exit; if not mbFileExists(FileName) then raise EXmlConfigNotFound.Create(''); if not mbFileAccess(FileName, fmOpenRead or fmShareDenyWrite) then raise EFOpenError.Create(SysErrorMessage(GetLastOSError)); ReadFromFile(FileName); Result := True; end; function TXmlConfig.LoadBypassingErrors: Boolean; var ErrMsg: String; begin try Result := Load; except on e: Exception do begin ErrMsg := 'Error loading configuration file ' + FileName; if e.Message <> EmptyStr then ErrMsg := ErrMsg + ': ' + e.Message; DebugLogger.DebugLn(ErrMsg); Result := False; end; end; end; function TXmlConfig.Save: Boolean; var bFileExists: Boolean; sTmpConfigFileName: String; begin Result := False; if FFileName = '' then Exit; bFileExists := mbFileExists(FileName); // Write to temporary file and if successfully written rename to proper name. if (not bFileExists) or mbFileAccess(FileName, fmOpenWrite or fmShareDenyWrite) then begin sTmpConfigFileName := GetTempName(FileName); try WriteToFile(sTmpConfigFileName); if bFileExists then begin mbFileCopyAttr(FileName, sTmpConfigFileName, [caoCopyOwnership, caoCopyPermissions]); end; if not mbRenameFile(sTmpConfigFileName, FileName) then begin mbDeleteFile(sTmpConfigFileName); DebugLogger.Debugln('Cannot save configuration file ', FileName); end else Result := True; except on e: EStreamError do begin mbDeleteFile(sTmpConfigFileName); DebugLogger.Debugln('Error saving configuration file ', FileName, ': ' + e.Message); end; end; end else begin DebugLogger.Debugln('Cannot save configuration file ', FileName, ' - check permissions'); end; end; procedure TXmlConfig.SplitPathToNodeAndAttr(const Path: DOMString; out NodePath: DOMString; out AttrName: DOMString); var AttrSepPos: Integer; begin // Last part of the path is the attr name. AttrSepPos := Length(Path); while (AttrSepPos > 0) and (Path[AttrSepPos] <> '/') do Dec(AttrSepPos); if (AttrSepPos = 0) or (AttrSepPos = Length(Path)) then begin NodePath := EmptyStr; AttrName := Path; end else begin NodePath := Copy(Path, 1, AttrSepPos - 1); AttrName := Copy(Path, AttrSepPos + 1, Length(Path) - AttrSepPos); end; end; function TXmlConfig.AddNode(const RootNode: TDOMNode; const ValueName: DOMString): TDOMNode; begin Result := RootNode.AppendChild(FDoc.CreateElement(ValueName)); end; procedure TXmlConfig.DeleteNode(const RootNode: TDOMNode; const Path: DOMString); begin DeleteNode(FindNode(RootNode, Path, False)); end; procedure TXmlConfig.DeleteNode(const Node: TDOMNode); begin if Assigned(Node) and Assigned(Node.ParentNode) then Node.ParentNode.DetachChild(Node); end; procedure TXmlConfig.ClearNode(const Node: TDOMNode); var Attr: TDOMAttr; begin while Assigned(Node.FirstChild) do Node.RemoveChild(Node.FirstChild); if Node.HasAttributes then begin Attr := TDOMAttr(Node.Attributes[0]); while Assigned(Attr) do begin TDOMElement(Node).RemoveAttributeNode(Attr); Attr := TDOMAttr(Attr.NextSibling); end; end; end; function TXmlConfig.FindNode(const RootNode: TDOMNode; const Path: DOMString; bCreate: Boolean = False): TDOMNode; var StartPos, EndPos: Integer; PathLen: Integer; Child: TDOMNode; function CompareDOMStrings(const s1, s2: DOMPChar; l1, l2: integer): integer; var i: integer; begin Result:=l1-l2; i:=0; while (i '/') do Inc(EndPos); Child := Result.FirstChild; while Assigned(Child) and not ((Child.NodeType = ELEMENT_NODE) and (0 = CompareDOMStrings(DOMPChar(Child.NodeName), @Path[StartPos], Length(Child.NodeName), EndPos-StartPos))) do Child := Child.NextSibling; if not Assigned(Child) and bCreate then begin Child := FDoc.CreateElementBuf(@Path[StartPos], EndPos-StartPos); Result.AppendChild(Child); end; Result := Child; StartPos := EndPos + 1; if StartPos > PathLen then Break; end; end; function TXmlConfig.GetContent(const Node: TDOMNode): String; begin Result := Node.TextContent; end; procedure TXmlConfig.SetContent(const Node: TDOMNode; const AValue: String); begin Node.TextContent := AValue; end; function TXmlConfig.GetPathFromNode(aNode: TDOMNode): String; begin Result := aNode.NodeName; aNode := aNode.ParentNode; while Assigned(aNode) and (aNode <> RootNode) do begin Result := aNode.NodeName + '/' + Result; aNode := aNode.ParentNode; end; end; procedure TXmlConfig.GetFont(const aNode: TXmlNode; Path: TXmlPath; out Name: String; out Size: Integer; out Style, Quality: Integer; const DefName: String; const DefSize: Integer; const DefStyle, DefQuality: Integer); begin if Path <> '' then Path := Path + '/'; Name := GetValue(aNode, Path + 'Name', DefName); Size := GetValue(aNode, Path + 'Size', DefSize); Style := GetValue(aNode, Path + 'Style', DefStyle); Quality := GetValue(aNode, Path + 'Quality', DefQuality); end; procedure TXmlConfig.SetFont(const aNode: TXmlNode; Path: TXmlPath; const Name: String; const Size: Integer; const Style, Quality: Integer); begin if Path <> '' then Path := Path + '/'; SetValue(aNode, Path + 'Name', Name); SetValue(aNode, Path + 'Size', Size); SetValue(aNode, Path + 'Style', Style); SetValue(aNode, Path + 'Quality', Quality); end; end. doublecmd-0.8.2/components/doublecmd/dcfileattributes.pas0000664000175000017500000003206113235433350022675 0ustar alexxalexx{ Double Commander ------------------------------------------------------------------------- Functions handling file attributes. Copyright (C) 2012 Przemysław Nagay (cobines@gmail.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } unit DCFileAttributes; {$mode objfpc}{$H+} interface uses Classes, SysUtils, DCBasicTypes; const // Windows attributes FILE_ATTRIBUTE_READONLY = $0001; FILE_ATTRIBUTE_HIDDEN = $0002; FILE_ATTRIBUTE_SYSTEM = $0004; FILE_ATTRIBUTE_DIRECTORY = $0010; FILE_ATTRIBUTE_ARCHIVE = $0020; FILE_ATTRIBUTE_NORMAL = $0080; FILE_ATTRIBUTE_TEMPORARY = $0100; FILE_ATTRIBUTE_SPARSE_FILE = $0200; FILE_ATTRIBUTE_REPARSE_POINT = $0400; FILE_ATTRIBUTE_COMPRESSED = $0800; FILE_ATTRIBUTE_OFFLINE = $1000; FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = $2000; FILE_ATTRIBUTE_ENCRYPTED = $4000; FILE_ATTRIBUTE_VIRTUAL = $20000; // Unix attributes { attributes mask } S_IFMT = $F000; { first-in/first-out (FIFO/pipe) } S_IFIFO = $1000; { character-special file (tty/console) } S_IFCHR = $2000; { directory } S_IFDIR = $4000; { blocking device (unused) } S_IFBLK = $6000; { regular } S_IFREG = $8000; { symbolic link (unused) } S_IFLNK = $A000; { Berkeley socket } S_IFSOCK = $C000; { mode_t possible values } S_IRUSR = %0100000000; { Read permission for owner } S_IWUSR = %0010000000; { Write permission for owner } S_IXUSR = %0001000000; { Exec permission for owner } S_IRGRP = %0000100000; { Read permission for group } S_IWGRP = %0000010000; { Write permission for group } S_IXGRP = %0000001000; { Exec permission for group } S_IROTH = %0000000100; { Read permission for world } S_IWOTH = %0000000010; { Write permission for world } S_IXOTH = %0000000001; { Exec permission for world } S_IRWXU = S_IRUSR or S_IWUSR or S_IXUSR; S_IRWXG = S_IRGRP or S_IWGRP or S_IXGRP; S_IRWXO = S_IROTH or S_IWOTH or S_IXOTH; S_IXUGO = S_IXUSR or S_IXGRP or S_IXOTH; { POSIX setuid(), setgid(), and sticky bit } S_ISUID = $0800; S_ISGID = $0400; S_ISVTX = $0200; // Generic attributes {$IF DEFINED(MSWINDOWS)} GENERIC_ATTRIBUTE_FILE = FILE_ATTRIBUTE_ARCHIVE; GENERIC_ATTRIBUTE_FOLDER = GENERIC_ATTRIBUTE_FILE or FILE_ATTRIBUTE_DIRECTORY; {$ELSEIF DEFINED(UNIX)} GENERIC_ATTRIBUTE_FILE = S_IRUSR or S_IWUSR or S_IRGRP or S_IROTH; GENERIC_ATTRIBUTE_FOLDER = GENERIC_ATTRIBUTE_FILE or S_IFDIR or S_IXUGO; {$ENDIF} function WinToUnixFileAttr(Attr: TFileAttrs): TFileAttrs; function UnixToWinFileAttr(Attr: TFileAttrs): TFileAttrs; function UnixToWcxFileAttr(Attr: TFileAttrs): TFileAttrs; function UnixToWinFileAttr(const FileName: String; Attr: TFileAttrs): TFileAttrs; function SingleStrToFileAttr(sAttr: String): TFileAttrs; function WinSingleStrToFileAttr(sAttr: String): TFileAttrs; function UnixSingleStrToFileAttr(sAttr: String): TFileAttrs; {en Convert file attributes from string to number @param(Attributes File attributes as string) @returns(File attributes as number) } function StrToFileAttr(sAttr: String): TFileAttrs; {en Convert file attributes to string in the format of "attr1+attr2+attr3+". @param(Attributes File attributes) @returns(File attributes as string) } function FileAttrToStr(Attr: TFileAttrs): String; {en Convert Windows file attributes from string to number @param(Attributes File attributes as string) @returns(File attributes as number) } function WinStrToFileAttr(sAttr: String): TFileAttrs; {en Convert Unix file attributes from string to number @param(Attributes File attributes as string) @returns(File attributes as number) } function UnixStrToFileAttr(sAttr: String): TFileAttrs; function FormatNtfsAttributes(iAttr: TFileAttrs): String; function FormatUnixAttributes(iAttr: TFileAttrs): String; implementation uses DCStrUtils; type TAttrStrToFileAttr = record Str: String; Attr: TFileAttrs; end; const WinAttrStrToFileAttr: array[0..9] of TAttrStrToFileAttr = ( (Str: 'r'; Attr: FILE_ATTRIBUTE_READONLY), (Str: 'h'; Attr: FILE_ATTRIBUTE_HIDDEN), (Str: 's'; Attr: FILE_ATTRIBUTE_SYSTEM), (Str: 'd'; Attr: FILE_ATTRIBUTE_DIRECTORY), (Str: 'a'; Attr: FILE_ATTRIBUTE_ARCHIVE), (Str: 't'; Attr: FILE_ATTRIBUTE_TEMPORARY), (Str: 'p'; Attr: FILE_ATTRIBUTE_SPARSE_FILE), (Str: 'l'; Attr: FILE_ATTRIBUTE_REPARSE_POINT), (Str: 'c'; Attr: FILE_ATTRIBUTE_COMPRESSED), (Str: 'e'; Attr: FILE_ATTRIBUTE_ENCRYPTED)); UnixAttrStrToFileAttr: array[0..18] of TAttrStrToFileAttr = ( // Permissions (Str: 'ur'; Attr: S_IRUSR), (Str: 'uw'; Attr: S_IWUSR), (Str: 'ux'; Attr: S_IXUSR), (Str: 'gr'; Attr: S_IRGRP), (Str: 'gw'; Attr: S_IWGRP), (Str: 'gx'; Attr: S_IXGRP), (Str: 'or'; Attr: S_IROTH), (Str: 'ow'; Attr: S_IWOTH), (Str: 'ox'; Attr: S_IXOTH), (Str: 'us'; Attr: S_ISUID), (Str: 'gs'; Attr: S_ISGID), (Str: 'sb'; Attr: S_ISVTX), // File types (Str: 'f'; Attr: S_IFIFO), (Str: 'c'; Attr: S_IFCHR), (Str: 'd'; Attr: S_IFDIR), (Str: 'b'; Attr: S_IFBLK), (Str: 'r'; Attr: S_IFREG), (Str: 'l'; Attr: S_IFLNK), (Str: 's'; Attr: S_IFSOCK)); function WinToUnixFileAttr(Attr: TFileAttrs): TFileAttrs; begin Result := S_IRUSR or S_IRGRP or S_IROTH; if (Attr and faReadOnly) = 0 then Result := Result or S_IWUSR; if (Attr and faDirectory) <> 0 then Result := Result or S_IFDIR or S_IXUGO else Result := Result or S_IFREG; end; function UnixToWinFileAttr(Attr: TFileAttrs): TFileAttrs; begin Result := 0; case (Attr and S_IFMT) of 0, S_IFREG: Result := faArchive; S_IFLNK: Result := Result or faSymLink; S_IFDIR: Result := Result or faDirectory; S_IFIFO, S_IFCHR, S_IFBLK, S_IFSOCK: Result := Result or faSysFile; end; if (Attr and S_IWUSR) = 0 then Result := Result or faReadOnly; end; function UnixToWcxFileAttr(Attr: TFileAttrs): TFileAttrs; begin {$IF DEFINED(MSWINDOWS)} Result := UnixToWinFileAttr(Attr); {$ELSEIF DEFINED(UNIX)} Result := Attr; {$ELSE} Result := 0; {$ENDIF} end; function UnixToWinFileAttr(const FileName: String; Attr: TFileAttrs): TFileAttrs; begin Result := UnixToWinFileAttr(Attr); if (Length(FileName) > 1) and (FileName[1] = '.') and (FileName[2] <> '.') then Result := Result or faHidden; end; function SingleStrToFileAttr(sAttr: String): TFileAttrs; begin {$IF DEFINED(MSWINDOWS)} Result := WinSingleStrToFileAttr(sAttr); {$ELSEIF DEFINED(UNIX)} Result := UnixSingleStrToFileAttr(sAttr); {$ENDIF} end; function WinSingleStrToFileAttr(sAttr: String): TFileAttrs; var i: Integer; begin for i := Low(WinAttrStrToFileAttr) to High(WinAttrStrToFileAttr) do begin if sAttr = WinAttrStrToFileAttr[i].Str then Exit(WinAttrStrToFileAttr[i].Attr); end; Result := 0; end; function UnixSingleStrToFileAttr(sAttr: String): TFileAttrs; var i: Integer; begin if Length(sAttr) > 0 then begin if sAttr[1] in ['0'..'7'] then begin // Octal representation. Exit(TFileAttrs(OctToDec(sAttr))); end else begin for i := Low(UnixAttrStrToFileAttr) to High(UnixAttrStrToFileAttr) do begin if sAttr = UnixAttrStrToFileAttr[i].Str then Exit(UnixAttrStrToFileAttr[i].Attr); end; end; end; Result := 0; end; function StrToFileAttr(sAttr: String): TFileAttrs; inline; begin {$IF DEFINED(MSWINDOWS)} Result := WinStrToFileAttr(sAttr); {$ELSEIF DEFINED(UNIX)} Result := UnixStrToFileAttr(sAttr); {$ENDIF} end; function FileAttrToStr(Attr: TFileAttrs): String; var i: Integer; begin Result := ''; {$IF DEFINED(MSWINDOWS)} for i := Low(WinAttrStrToFileAttr) to High(WinAttrStrToFileAttr) do begin if Attr and WinAttrStrToFileAttr[i].Attr <> 0 then Result := Result + WinAttrStrToFileAttr[i].Str + '+'; end; {$ELSEIF DEFINED(UNIX)} for i := Low(UnixAttrStrToFileAttr) to High(UnixAttrStrToFileAttr) do begin if Attr and UnixAttrStrToFileAttr[i].Attr <> 0 then Result := Result + UnixAttrStrToFileAttr[i].Str + '+'; end; {$ENDIF} end; function WinStrToFileAttr(sAttr: String): TFileAttrs; var I: LongInt; begin Result:= 0; sAttr:= LowerCase(sAttr); for I:= 1 to Length(sAttr) do case sAttr[I] of 'd': Result := Result or FILE_ATTRIBUTE_DIRECTORY; 'l': Result := Result or FILE_ATTRIBUTE_REPARSE_POINT; 'r': Result := Result or FILE_ATTRIBUTE_READONLY; 'a': Result := Result or FILE_ATTRIBUTE_ARCHIVE; 'h': Result := Result or FILE_ATTRIBUTE_HIDDEN; 's': Result := Result or FILE_ATTRIBUTE_SYSTEM; end; end; function UnixStrToFileAttr(sAttr: String): TFileAttrs; begin Result:= 0; if Length(sAttr) < 10 then Exit; if sAttr[1] = 'd' then Result:= Result or S_IFDIR; if sAttr[1] = 'l' then Result:= Result or S_IFLNK; if sAttr[1] = 's' then Result:= Result or S_IFSOCK; if sAttr[1] = 'f' then Result:= Result or S_IFIFO; if sAttr[1] = 'b' then Result:= Result or S_IFBLK; if sAttr[1] = 'c' then Result:= Result or S_IFCHR; if sAttr[2] = 'r' then Result:= Result or S_IRUSR; if sAttr[3] = 'w' then Result:= Result or S_IWUSR; if sAttr[4] = 'x' then Result:= Result or S_IXUSR; if sAttr[5] = 'r' then Result:= Result or S_IRGRP; if sAttr[6] = 'w' then Result:= Result or S_IWGRP; if sAttr[7] = 'x' then Result:= Result or S_IXGRP; if sAttr[8] = 'r' then Result:= Result or S_IROTH; if sAttr[9] = 'w' then Result:= Result or S_IWOTH; if sAttr[10] = 'x' then Result:= Result or S_IXOTH; if sAttr[4] = 'S' then Result:= Result or S_ISUID; if sAttr[7] = 'S' then Result:= Result or S_ISGID; if sAttr[10] = 'T' then Result:= Result or S_ISVTX; if sAttr[4] = 's' then Result:= Result or S_IXUSR or S_ISUID; if sAttr[7] = 's' then Result:= Result or S_IXGRP or S_ISGID; if sAttr[10] = 't' then Result:= Result or S_IXOTH or S_ISVTX; end; function FormatNtfsAttributes(iAttr: TFileAttrs): String; begin Result:= '--------'; if (iAttr and FILE_ATTRIBUTE_DIRECTORY ) <> 0 then Result[1] := 'd'; if (iAttr and FILE_ATTRIBUTE_REPARSE_POINT) <> 0 then Result[1] := 'l'; if (iAttr and FILE_ATTRIBUTE_READONLY ) <> 0 then Result[2] := 'r'; if (iAttr and FILE_ATTRIBUTE_ARCHIVE ) <> 0 then Result[3] := 'a'; if (iAttr and FILE_ATTRIBUTE_HIDDEN ) <> 0 then Result[4] := 'h'; if (iAttr and FILE_ATTRIBUTE_SYSTEM ) <> 0 then Result[5] := 's'; // These two are exclusive on NTFS. if (iAttr and FILE_ATTRIBUTE_COMPRESSED ) <> 0 then Result[6] := 'c'; if (iAttr and FILE_ATTRIBUTE_ENCRYPTED ) <> 0 then Result[6] := 'e'; if (iAttr and FILE_ATTRIBUTE_TEMPORARY ) <> 0 then Result[7] := 't'; if (iAttr and FILE_ATTRIBUTE_SPARSE_FILE ) <> 0 then Result[8] := 'p'; end; function FormatUnixAttributes(iAttr: TFileAttrs): String; begin Result:= '----------'; if ((iAttr and S_IFMT) = S_IFDIR) then Result[1] := 'd'; if ((iAttr and S_IFMT) = S_IFLNK) then Result[1] := 'l'; if ((iAttr and S_IFMT) = S_IFSOCK) then Result[1] := 's'; if ((iAttr and S_IFMT) = S_IFIFO) then Result[1] := 'f'; if ((iAttr and S_IFMT) = S_IFBLK) then Result[1] := 'b'; if ((iAttr and S_IFMT) = S_IFCHR) then Result[1] := 'c'; if ((iAttr and S_IRUSR) = S_IRUSR) then Result[2] := 'r'; if ((iAttr and S_IWUSR) = S_IWUSR) then Result[3] := 'w'; if ((iAttr and S_IXUSR) = S_IXUSR) then Result[4] := 'x'; if ((iAttr and S_IRGRP) = S_IRGRP) then Result[5] := 'r'; if ((iAttr and S_IWGRP) = S_IWGRP) then Result[6] := 'w'; if ((iAttr and S_IXGRP) = S_IXGRP) then Result[7] := 'x'; if ((iAttr and S_IROTH) = S_IROTH) then Result[8] := 'r'; if ((iAttr and S_IWOTH) = S_IWOTH) then Result[9] := 'w'; if ((iAttr and S_IXOTH) = S_IXOTH) then Result[10] := 'x'; if ((iAttr and S_ISUID) = S_ISUID) then begin if Result[4] = 'x' then Result[4] := 's' else Result[4] := 'S'; end; if ((iAttr and S_ISGID) = S_ISGID) then begin if Result[7] = 'x' then Result[7] := 's' else Result[7] := 'S'; end; if ((iAttr and S_ISVTX) = S_ISVTX) then begin if Result[10] = 'x' then Result[10] := 't' else Result[10] := 'T'; end; end; end. doublecmd-0.8.2/components/doublecmd/dcntfslinks.pas0000664000175000017500000003676713177323176021714 0ustar alexxalexx{ Double Commander ------------------------------------------------------------------------- This unit contains functions to work with hard and symbolic links on the NTFS file system. Copyright (C) 2012-2017 Alexander Koblov (alexx2000@mail.ru) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } unit DCNtfsLinks; {$mode delphi} interface uses Windows, SysUtils; const // CreateSymbolicLink flags SYMBOLIC_LINK_FLAG_FILE = 0; SYMBOLIC_LINK_FLAG_DIRECTORY = 1; // CreateFile flags FILE_FLAG_OPEN_REPARSE_POINT = $00200000; // DeviceIoControl control codes FSCTL_SET_REPARSE_POINT = $000900A4; FSCTL_GET_REPARSE_POINT = $000900A8; FSCTL_DELETE_REPARSE_POINT = $000900AC; const REPARSE_DATA_HEADER_SIZE = 8; MOUNT_POINT_HEADER_SIZE = 8; FILE_DOES_NOT_EXIST = DWORD(-1); wsLongFileNamePrefix = UnicodeString('\\?\'); wsNativeFileNamePrefix = UnicodeString('\??\'); type {$packrecords c} TSymbolicLinkReparseBuffer = record SubstituteNameOffset: USHORT; SubstituteNameLength: USHORT; PrintNameOffset: USHORT; PrintNameLength: USHORT; Flags: ULONG; PathBuffer: array[0..0] of WCHAR; end; TMountPointReparseBuffer = record SubstituteNameOffset: USHORT; SubstituteNameLength: USHORT; PrintNameOffset: USHORT; PrintNameLength: USHORT; PathBuffer: array[0..0] of WCHAR; end; TGenericReparseBuffer = record DataBuffer: array[0..0] of UCHAR; end; REPARSE_DATA_BUFFER = record ReparseTag: ULONG; ReparseDataLength: USHORT; Reserved: USHORT; case Integer of 0: (SymbolicLinkReparseBuffer: TSymbolicLinkReparseBuffer); 1: (MountPointReparseBuffer: TMountPointReparseBuffer); 2: (GenericReparseBuffer: TGenericReparseBuffer); end; TReparseDataBuffer = REPARSE_DATA_BUFFER; PReparseDataBuffer = ^REPARSE_DATA_BUFFER; {$packrecords default} {en Creates a symbolic link. This function is only supported on the NTFS file system. On Windows 2000/XP it works for directories only On Windows Vista/Seven it works for directories and files (for files it works only with Administrator rights) @param(AFileName The name of the existing file) @param(ALinkName The name of the symbolic link) @returns(The function returns @true if successful, @false otherwise) } function CreateSymLink(const ATargetName, ALinkName: UnicodeString): Boolean; {en Established a hard link beetwen an existing file and new file. This function is only supported on the NTFS file system, and only for files, not directories. @param(AFileName The name of the existing file) @param(ALinkName The name of the new hard link) @returns(The function returns @true if successful, @false otherwise) } function CreateHardLink(const AFileName, ALinkName: UnicodeString): Boolean; {en Reads a symbolic link target. This function is only supported on the NTFS file system. @param(aSymlinkFileName The name of the symbolic link) @param(aTargetFileName The name of the target file/directory) @returns(The function returns @true if successful, @false otherwise) } function ReadSymLink(const aSymlinkFileName: UnicodeString; out aTargetFileName: UnicodeString): Boolean; implementation const ERROR_DIRECTORY_NOT_SUPPORTED = 336; type TCreateSymbolicLinkW = function( pwcSymlinkFileName, pwcTargetFileName: PWideChar; dwFlags: DWORD): BOOL; stdcall; TCreateHardLinkW = function ( lpFileName, lpExistingFileName: LPCWSTR; lpSecurityAttributes: LPSECURITY_ATTRIBUTES): BOOL; stdcall; var HasNewApi: Boolean = False; MayCreateSymLink: Boolean = False; function _CreateHardLink_New(AFileName : UnicodeString; ALinkName: UnicodeString): Boolean; var hLib: THandle; CreateHardLinkW: TCreateHardLinkW; begin Result:= False; hLib:= GetModuleHandle('kernel32.dll'); if hLib = 0 then begin Assert(False, 'Can not load library "kernel32.dll"'); Exit; end; CreateHardLinkW:= TCreateHardLinkW(GetProcAddress(hLib, 'CreateHardLinkW')); if not Assigned(CreateHardLinkW) then begin Assert(False, 'Can not get function address for "CreateHardLinkW"'); Exit; end; Result:= CreateHardLinkW(PWideChar(ALinkName), PWideChar(AFileName), nil); end; function _CreateHardLink_Old(aExistingFileName, aFileName: UnicodeString): Boolean; var hFile: THandle; lpBuffer: TWin32StreamId; wcFileName: array[0..MAX_PATH] of WideChar; dwNumberOfBytesWritten: DWORD = 0; lpContext: LPVOID = nil; lpFilePart: LPWSTR = nil; begin Result:= GetFullPathNameW(PWideChar(aFileName), MAX_PATH, wcFileName, lpFilePart) > 0; if Result then begin hFile:= CreateFileW(PWideChar(aExistingFileName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, 0, 0); Result:= (hFile <> INVALID_HANDLE_VALUE); end; if Result then try ZeroMemory(@lpBuffer, SizeOf(TWin32StreamId)); with lpBuffer do begin dwStreamId:= BACKUP_LINK; Size.LowPart:= (Length(aFileName) + 1) * SizeOf(WideChar); end; // Write stream header Result:= BackupWrite(hFile, @lpBuffer, SizeOf(TWin32StreamId) - SizeOf(PWideChar), dwNumberOfBytesWritten, False, False, lpContext); if not Result then Exit; // Write file name buffer Result:= BackupWrite(hFile, @wcFileName, lpBuffer.Size.LowPart, dwNumberOfBytesWritten, False, False, lpContext); if not Result then Exit; // Finish write operation Result:= BackupWrite(hFile, nil, 0, dwNumberOfBytesWritten, True, False, lpContext); finally CloseHandle(hFile); end; end; function CreateHardLink(const AFileName, ALinkName: UnicodeString): Boolean; var dwAttributes: DWORD; begin dwAttributes := Windows.GetFileAttributesW(PWideChar(AFileName)); if dwAttributes = FILE_DOES_NOT_EXIST then Exit(False); if (dwAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then begin SetLastError(ERROR_DIRECTORY_NOT_SUPPORTED); Exit(False); end; dwAttributes := Windows.GetFileAttributesW(PWideChar(ALinkName)); if dwAttributes <> FILE_DOES_NOT_EXIST then begin SetLastError(ERROR_FILE_EXISTS); Exit(False); end; if HasNewApi then Result:= _CreateHardLink_New(AFileName, ALinkName) else Result:= _CreateHardLink_Old(AFileName, ALinkName) end; function _CreateSymLink_New(const ATargetFileName, ASymlinkFileName: UnicodeString; dwFlags: DWORD): boolean; var hLib: THandle; CreateSymbolicLinkW: TCreateSymbolicLinkW; begin Result:= False; hLib:= GetModuleHandle('kernel32.dll'); if hLib = 0 then begin Assert(False, 'Can not load library "kernel32.dll"'); Exit; end; CreateSymbolicLinkW:= TCreateSymbolicLinkW(GetProcAddress(hLib, 'CreateSymbolicLinkW')); if not Assigned(CreateSymbolicLinkW) then begin Assert(False, 'Can not get function address for "CreateSymbolicLinkW"'); Exit; end; Result:= CreateSymbolicLinkW(PWideChar(ASymlinkFileName), PWideChar(ATargetFileName), dwFlags); end; function _CreateSymLink_Old(aTargetFileName, aSymlinkFileName: UnicodeString): Boolean; var hDevice: THandle; lpInBuffer: PReparseDataBuffer; nInBufferSize, dwPathBufferSize: DWORD; wsNativeFileName: UnicodeString; lpBytesReturned: DWORD = 0; begin Result:= CreateDirectoryW(PWideChar(aSymlinkFileName), nil); if Result then try hDevice:= CreateFileW(PWideChar(aSymlinkFileName), GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OPEN_REPARSE_POINT, 0); if hDevice = INVALID_HANDLE_VALUE then Exit; if Pos(wsLongFileNamePrefix, aTargetFileName) <> 1 then wsNativeFileName:= wsNativeFileNamePrefix + aTargetFileName else begin wsNativeFileName:= wsNativeFileNamePrefix + Copy(aTargetFileName, 5, MaxInt); end; // File name length with trailing zero and zero for empty PrintName dwPathBufferSize:= Length(wsNativeFileName) * SizeOf(WideChar) + 4; nInBufferSize:= REPARSE_DATA_HEADER_SIZE + MOUNT_POINT_HEADER_SIZE + dwPathBufferSize; lpInBuffer:= GetMem(nInBufferSize); ZeroMemory(lpInBuffer, nInBufferSize); with lpInBuffer^, lpInBuffer^.MountPointReparseBuffer do begin ReparseTag:= IO_REPARSE_TAG_MOUNT_POINT; ReparseDataLength:= MOUNT_POINT_HEADER_SIZE + dwPathBufferSize; SubstituteNameLength:= Length(wsNativeFileName) * SizeOf(WideChar); PrintNameOffset:= SubstituteNameOffset + SubstituteNameLength + SizeOf(WideChar); CopyMemory(@PathBuffer[0], @wsNativeFileName[1], SubstituteNameLength); end; Result:= DeviceIoControl(hDevice, // handle to file or directory FSCTL_SET_REPARSE_POINT, // dwIoControlCode lpInBuffer, // input buffer nInBufferSize, // size of input buffer nil, // lpOutBuffer 0, // nOutBufferSize lpBytesReturned, // lpBytesReturned nil); // OVERLAPPED structure FreeMem(lpInBuffer); CloseHandle(hDevice); finally if not Result then RemoveDirectoryW(PWideChar(aSymlinkFileName)); end; end; function CreateSymLink(const ATargetName, ALinkName: UnicodeString): Boolean; var dwAttributes: DWORD; lpFilePart: LPWSTR = nil; AFileName, AFullPathName: UnicodeString; begin Result:= False; if (Length(ATargetName) > 1) and CharInSet(ATargetName[2], [':', '\']) then AFullPathName:= ATargetName else begin SetLength(AFullPathName, MaxSmallint); AFileName:= ExtractFilePath(ALinkName) + ATargetName; dwAttributes:= GetFullPathNameW(PWideChar(AFileName), MaxSmallint, PWideChar(AFullPathName), lpFilePart); if dwAttributes > 0 then SetLength(AFullPathName, dwAttributes) else begin AFullPathName:= ATargetName; end; end; dwAttributes:= Windows.GetFileAttributesW(PWideChar(AFullPathName)); if dwAttributes = FILE_DOES_NOT_EXIST then Exit; if HasNewApi = False then begin if (dwAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then Result:= _CreateSymLink_Old(AFullPathName, ALinkName) else SetLastError(ERROR_NOT_SUPPORTED); end else begin if (dwAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then Result:= _CreateSymLink_New(ATargetName, ALinkName, SYMBOLIC_LINK_FLAG_FILE) else begin if not MayCreateSymLink then Result:= _CreateSymLink_Old(AFullPathName, ALinkName) else begin Result:= _CreateSymLink_New(ATargetName, ALinkName, SYMBOLIC_LINK_FLAG_DIRECTORY); end; end; end; end; function ReadSymLink(const aSymlinkFileName: UnicodeString; out aTargetFileName: UnicodeString): Boolean; var hDevice: THandle; dwFileAttributes: DWORD; caOutBuffer: array[0..4095] of Byte; lpOutBuffer: TReparseDataBuffer absolute caOutBuffer; pwcTargetFileName: PWideChar; lpBytesReturned: DWORD = 0; dwFlagsAndAttributes: DWORD; begin dwFileAttributes:= GetFileAttributesW(PWideChar(aSymlinkFileName)); Result:= dwFileAttributes <> FILE_DOES_NOT_EXIST; if Result then begin if (dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then dwFlagsAndAttributes:= FILE_FLAG_OPEN_REPARSE_POINT else dwFlagsAndAttributes:= FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OPEN_REPARSE_POINT; // Open reparse point hDevice:= CreateFileW(PWideChar(aSymlinkFileName), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, dwFlagsAndAttributes, 0); Result:= hDevice <> INVALID_HANDLE_VALUE; if not Result then Exit; Result:= DeviceIoControl(hDevice, // handle to file or directory FSCTL_GET_REPARSE_POINT, // dwIoControlCode nil, // input buffer 0, // size of input buffer @caOutBuffer, // lpOutBuffer SizeOf(caOutBuffer), // nOutBufferSize lpBytesReturned, // lpBytesReturned nil); // OVERLAPPED structure CloseHandle(hDevice); if Result then begin case lpOutBuffer.ReparseTag of IO_REPARSE_TAG_SYMLINK: with lpOutBuffer.SymbolicLinkReparseBuffer do begin pwcTargetFileName:= @PathBuffer[0]; pwcTargetFileName:= pwcTargetFileName + SubstituteNameOffset div SizeOf(WideChar); SetLength(aTargetFileName, SubstituteNameLength div SizeOf(WideChar)); CopyMemory(PWideChar(aTargetFileName), pwcTargetFileName, SubstituteNameLength); end; IO_REPARSE_TAG_MOUNT_POINT: with lpOutBuffer.MountPointReparseBuffer do begin pwcTargetFileName:= @PathBuffer[0]; pwcTargetFileName:= pwcTargetFileName + SubstituteNameOffset div SizeOf(WideChar); SetLength(aTargetFileName, SubstituteNameLength div SizeOf(WideChar)); CopyMemory(PWideChar(aTargetFileName), pwcTargetFileName, SubstituteNameLength); end; end; if Pos(wsNativeFileNamePrefix, aTargetFileName) = 1 then Delete(aTargetFileName, 1, Length(wsNativeFileNamePrefix)); end; end; end; function MayCreateSymbolicLink: Boolean; const SE_CREATE_SYMBOLIC_LINK_NAME = 'SeCreateSymbolicLinkPrivilege'; var I: Integer; hProcess: HANDLE; dwLength: DWORD = 0; seCreateSymbolicLink: LUID = 0; TokenInformation: array [0..1023] of Byte; Privileges: TTokenPrivileges absolute TokenInformation; begin hProcess:= GetCurrentProcess(); if (OpenProcessToken(hProcess, TOKEN_READ, hProcess)) then try if (LookupPrivilegeValueW(nil, SE_CREATE_SYMBOLIC_LINK_NAME, seCreateSymbolicLink)) then begin if (GetTokenInformation(hProcess, TokenPrivileges, @Privileges, SizeOf(TokenInformation), dwLength)) then begin {$PUSH}{$R-} for I:= 0 to Int32(Privileges.PrivilegeCount) - 1 do begin if Privileges.Privileges[I].Luid = seCreateSymbolicLink then Exit(True); end; {$POP} end; end; finally CloseHandle(hProcess); end; Result:= False; end; initialization MayCreateSymLink:= MayCreateSymbolicLink; HasNewApi:= (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 6); end. doublecmd-0.8.2/components/doublecmd/dcclassesutf8.pas0000664000175000017500000001271113036642073022116 0ustar alexxalexx{ Double commander ------------------------------------------------------------------------- This module contains classes with UTF8 file names support. Copyright (C) 2008-2016 Alexander Koblov (alexx2000@mail.ru) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } unit DCClassesUtf8; {$mode objfpc}{$H+} interface uses Classes, RtlConsts, SysUtils, IniFiles; type { TFileStreamEx class } TFileStreamEx = class(THandleStream) private FHandle: THandle; FFileName: String; public constructor Create(const AFileName: String; Mode: LongWord); destructor Destroy; override; function Flush: Boolean; function Read(var Buffer; Count: LongInt): LongInt; override; property FileName: String read FFileName; end; { TStringListEx } TStringListEx = class(TStringList) public function IndexOfValue(const Value: String): Integer; procedure LoadFromFile(const FileName: String); override; procedure SaveToFile(const FileName: String); override; end; { TIniFileEx } TIniFileEx = class(TMemIniFile) private FReadOnly: Boolean; public constructor Create(const AFileName: String; Mode: Word); virtual; constructor Create(const AFileName: String; AEscapeLineFeeds : Boolean = False); override; procedure UpdateFile; override; public property ReadOnly: Boolean read FReadOnly; end; implementation uses DCOSUtils; { TFileStreamEx } constructor TFileStreamEx.Create(const AFileName: String; Mode: LongWord); begin if (Mode and fmCreate) <> 0 then begin FHandle:= mbFileCreate(AFileName, Mode); if FHandle = feInvalidHandle then raise EFCreateError.CreateFmt(SFCreateError, [AFileName]) else inherited Create(FHandle); end else begin FHandle:= mbFileOpen(AFileName, Mode); if FHandle = feInvalidHandle then raise EFOpenError.CreateFmt(SFOpenError, [AFilename]) else inherited Create(FHandle); end; FFileName:= AFileName; end; destructor TFileStreamEx.Destroy; begin inherited Destroy; // Close handle after destroying the base object, because it may use Handle in Destroy. if FHandle <> feInvalidHandle then FileClose(FHandle); end; function TFileStreamEx.Flush: Boolean; begin Result:= FileFlush(FHandle); end; function TFileStreamEx.Read(var Buffer; Count: LongInt): LongInt; begin Result:= FileRead(FHandle, Buffer, Count); if Result = -1 then raise EReadError.Create(mbSysErrorMessage(GetLastOSError)); end; { TStringListEx } function TStringListEx.IndexOfValue(const Value: String): Integer; var iStart: LongInt; sTemp: String; begin CheckSpecialChars; Result:= 0; while (Result < Count) do begin sTemp:= Strings[Result]; iStart:= Pos(NameValueSeparator, sTemp) + 1; if (iStart > 0) and (DoCompareText(Value, Copy(sTemp, iStart, MaxInt)) = 0) then Exit; Inc(result); end; Result:= -1; end; procedure TStringListEx.LoadFromFile(const FileName: String); var fsFileStream: TFileStreamEx; begin fsFileStream:= TFileStreamEx.Create(FileName, fmOpenRead or fmShareDenyNone); try LoadFromStream(fsFileStream); finally fsFileStream.Free; end; end; procedure TStringListEx.SaveToFile(const FileName: String); var fsFileStream: TFileStreamEx = nil; begin try if mbFileExists(FileName) then begin fsFileStream:= TFileStreamEx.Create(FileName, fmOpenWrite or fmShareDenyWrite); fsFileStream.Position:= 0; fsFileStream.Size:= 0; end else fsFileStream:= TFileStreamEx.Create(FileName, fmCreate); SaveToStream(fsFileStream); finally fsFileStream.Free; end; end; { TIniFileEx } constructor TIniFileEx.Create(const AFileName: String; Mode: Word); var slLines : TStringListEx; begin FReadOnly := ((Mode and $03) = fmOpenRead); inherited Create(EmptyStr); if ((Mode and $03) <> fmOpenWrite) then begin if mbFileExists(AFileName) then begin slLines := TStringListEx.Create; try slLines.LoadFromFile(AFileName); SetStrings(slLines); finally slLines.Free; end; end; end; Rename(AFileName, False); end; constructor TIniFileEx.Create(const AFileName: String; AEscapeLineFeeds: Boolean); var Mode: Word; begin if not mbFileExists(AFileName) then Mode := fmOpenWrite or fmShareDenyWrite else if mbFileAccess(AFileName, fmOpenReadWrite or fmShareDenyWrite) then Mode := fmOpenReadWrite or fmShareDenyWrite else begin Mode := fmOpenRead or fmShareDenyNone; end; Create(AFileName, Mode); end; procedure TIniFileEx.UpdateFile; var slLines: TStringListEx; begin if not FReadOnly then begin slLines := TStringListEx.Create; try GetStrings(slLines); slLines.SaveToFile(FileName); PBoolean(@Dirty)^:= False; finally slLines.Free; end; end; end; end. doublecmd-0.8.2/components/doublecmd/dcconvertencoding.pas0000664000175000017500000003143612650700750023044 0ustar alexxalexxunit DCConvertEncoding; {$mode objfpc}{$H+} {$IF DEFINED(DARWIN)} {$modeswitch objectivec1} {$ENDIF} interface uses Classes, SysUtils; {$IF NOT DECLARED(RawByteString)} type RawByteString = AnsiString; {$IFEND} var {en Convert from OEM to System encoding, if needed } CeOemToSys: function (const Source: String): RawByteString; CeSysToOem: function (const Source: String): RawByteString; {en Convert from OEM to UTF-8 encoding, if needed } CeOemToUtf8: function (const Source: String): RawByteString; CeUtf8ToOem: function (const Source: String): RawByteString; {en Convert from Ansi to System encoding, if needed } CeAnsiToSys: function (const Source: String): RawByteString; CeSysToAnsi: function (const Source: String): RawByteString; {en Convert from ANSI to UTF-8 encoding, if needed } CeAnsiToUtf8: function (const Source: String): RawByteString; CeUtf8ToAnsi: function (const Source: String): RawByteString; {en Convert from Utf8 to System encoding, if needed } CeUtf8ToSys: function (const Source: String): RawByteString; CeSysToUtf8: function (const Source: String): RawByteString; function CeRawToUtf8(const Source: String): RawByteString; {$IF DEFINED(MSWINDOWS)} function CeTryEncode(const aValue: UnicodeString; aCodePage: Cardinal; aAllowBestFit: Boolean; out aResult: AnsiString): Boolean; function CeTryDecode(const aValue: AnsiString; aCodePage: Cardinal; out aResult: UnicodeString): Boolean; {$ELSEIF DEFINED(UNIX)} var SystemEncodingUtf8: Boolean = False; SystemLanguage, SystemEncoding, SystemLocale: String; {$ENDIF} implementation uses {$IF DEFINED(UNIX)} iconvenc_dyn {$IF DEFINED(DARWIN)} , MacOSAll, CocoaAll {$ENDIF} {$ELSEIF DEFINED(MSWINDOWS)} Windows {$ENDIF} ; {$IF DEFINED(FPC_HAS_CPSTRING)} var FileSystemCodePage: TSystemCodePage; {$ENDIF} function UTF8CharacterStrictLength(P: PAnsiChar): integer; begin if p=nil then exit(0); if ord(p^)<%10000000 then begin // regular single byte character exit(1); end else if ord(p^)<%11000000 then begin // invalid single byte character exit(0); end else if ((ord(p^) and %11100000) = %11000000) then begin // should be 2 byte character if (ord(p[1]) and %11000000) = %10000000 then exit(2) else exit(0); end else if ((ord(p^) and %11110000) = %11100000) then begin // should be 3 byte character if ((ord(p[1]) and %11000000) = %10000000) and ((ord(p[2]) and %11000000) = %10000000) then exit(3) else exit(0); end else if ((ord(p^) and %11111000) = %11110000) then begin // should be 4 byte character if ((ord(p[1]) and %11000000) = %10000000) and ((ord(p[2]) and %11000000) = %10000000) and ((ord(p[3]) and %11000000) = %10000000) then exit(4) else exit(0); end else exit(0); end; function CeRawToUtf8(const Source: String): RawByteString; var P: PAnsiChar; I, L: LongInt; begin L:= Length(Source); // Try UTF-8 (this includes ASCII) P:= PAnsiChar(Source); repeat if Ord(P^) < 128 then begin // ASCII if (P^ = #0) and (P - PAnsiChar(Source) >= L) then begin Result:= Source; Exit; end; Inc(P); end else begin I:= UTF8CharacterStrictLength(P); if I = 0 then Break; Inc(P, I); end; until False; Result:= CeSysToUtf8(Source); end; function Dummy(const Source: String): RawByteString; begin Result:= Source; end; {$IF DEFINED(FPC_HAS_CPSTRING)} function Sys2UTF8(const Source: String): RawByteString; begin Result:= Source; SetCodePage(Result, FileSystemCodePage, False); SetCodePage(Result, CP_UTF8, True); // Prevent another codepage appear in the strings // we don't need codepage conversion magic in our code SetCodePage(Result, DefaultSystemCodePage, False); end; function UTF82Sys(const Source: String): RawByteString; begin Result:= Source; SetCodePage(Result, CP_UTF8, False); SetCodePage(Result, FileSystemCodePage, True); // Prevent another codepage appear in the strings // we don't need codepage conversion magic in our code SetCodePage(Result, DefaultSystemCodePage, False); end; {$ELSE} function Sys2UTF8(const Source: String): RawByteString; begin Result:= UTF8Encode(Source); end; function UTF82Sys(const Source: String): RawByteString; begin Result:= UTF8Decode(Source); end; {$ENDIF} {$IF DEFINED(MSWINDOWS)} function CeTryEncode(const aValue: UnicodeString; aCodePage: Cardinal; aAllowBestFit: Boolean; out aResult: AnsiString): Boolean; // Try to encode the given Unicode string as the requested codepage const WC_NO_BEST_FIT_CHARS = $00000400; Flags: array[Boolean] of DWORD = (WC_NO_BEST_FIT_CHARS, 0); var UsedDefault: BOOL; begin if not aAllowBestFit and not CheckWin32Version(4, 1) then Result := False else begin SetLength(aResult, WideCharToMultiByte(aCodePage, Flags[aAllowBestFit], PWideChar(aValue), Length(aValue), nil, 0, nil, @UsedDefault)); SetLength(aResult, WideCharToMultiByte(aCodePage, Flags[aAllowBestFit], PWideChar(aValue), Length(aValue), PAnsiChar(aResult), Length(aResult), nil, @UsedDefault)); Result := not UsedDefault; end; end; function CeTryDecode(const aValue: AnsiString; aCodePage: Cardinal; out aResult: UnicodeString): Boolean; begin SetLength(aResult, MultiByteToWideChar(aCodePage, MB_ERR_INVALID_CHARS, LPCSTR(aValue), Length(aValue), nil, 0) * SizeOf(UnicodeChar)); SetLength(aResult, MultiByteToWideChar(aCodePage, MB_ERR_INVALID_CHARS, LPCSTR(aValue), Length(aValue), PWideChar(aResult), Length(aResult))); Result := Length(aResult) > 0; end; function Oem2Utf8(const Source: String): RawByteString; var UnicodeResult: UnicodeString; begin if CeTryDecode(Source, CP_OEMCP, UnicodeResult) then Result:= UTF8Encode(UnicodeResult) else Result:= Source; end; function Utf82Oem(const Source: String): RawByteString; var AnsiResult: AnsiString; begin if CeTryEncode(UTF8Decode(Source), CP_OEMCP, False, AnsiResult) then Result:= AnsiResult else Result:= Source; end; function OEM2Ansi(const Source: String): RawByteString; var Dst: PAnsiChar; begin Result:= Source; Dst:= AllocMem((Length(Result) + 1) * SizeOf(AnsiChar)); if OEMToChar(PAnsiChar(Result), Dst) then Result:= StrPas(Dst); FreeMem(Dst); end; function Ansi2OEM(const Source: String): RawByteString; var Dst: PAnsiChar; begin Result := Source; Dst := AllocMem((Length(Result) + 1) * SizeOf(AnsiChar)); if CharToOEM(PAnsiChar(Result), Dst) then Result := StrPas(Dst); FreeMem(Dst); end; procedure Initialize; begin CeOemToSys:= @OEM2Ansi; CeSysToOem:= @Ansi2OEM; CeOemToUtf8:= @Oem2Utf8; CeUtf8ToOem:= @Utf82Oem; CeAnsiToSys:= @Dummy; CeSysToAnsi:= @Dummy; CeAnsiToUtf8:= @Sys2UTF8; CeUtf8ToAnsi:= @UTF82Sys; CeSysToUtf8:= @Sys2UTF8; CeUtf8ToSys:= @UTF82Sys; end; {$ELSEIF DEFINED(UNIX)} {$I dcconvertencoding.inc} const EncodingUTF8 = 'UTF-8'; // UTF-8 Encoding var EncodingOEM, // OEM Encoding EncodingANSI: String; // ANSI Encoding function GetSystemEncoding: Boolean; {$IF DEFINED(DARWIN)} var Country: String; CurrentLocale: NSLocale; LanguageCFRef: CFStringRef = nil; LanguageCFArray: CFArrayRef = nil; begin // System encoding SystemEncoding:= EncodingUTF8; // Get system language LanguageCFArray:= CFLocaleCopyPreferredLanguages; try Result:= CFArrayGetCount(LanguageCFArray) > 0; if Result then begin LanguageCFRef:= CFArrayGetValueAtIndex(LanguageCFArray, 0); SetLength(SystemLanguage, MAX_PATH); Result:= CFStringGetCString(LanguageCFRef, PAnsiChar(SystemLanguage), MAX_PATH, kCFStringEncodingUTF8 ); end; finally CFRelease(LanguageCFArray); end; if Result then begin // Crop to terminating zero SystemLanguage:= PAnsiChar(SystemLanguage); // Get system country CurrentLocale:= NSLocale.currentLocale(); Country:= NSString(CurrentLocale.objectForKey(NSLocaleCountryCode)).UTF8String; // Combine system locale if (Length(SystemLanguage) > 0) and (Length(Country) > 0) then begin SystemLocale:= SystemLanguage + '_' + Country; end; end; end; {$ELSE} var I: Integer; Lang: String; begin Result:= True; Lang:= SysUtils.GetEnvironmentVariable('LC_ALL'); if Length(Lang) = 0 then begin Lang:= SysUtils.GetEnvironmentVariable('LC_MESSAGES'); if Length(Lang) = 0 then begin Lang:= SysUtils.GetEnvironmentVariable('LANG'); if Length(Lang) = 0 then Exit(False); end; end; I:= Pos('_', Lang); if (I = 0) then SystemLanguage:= Lang else begin SystemLanguage:= Copy(Lang, 1, I - 1); end; I:= System.Pos('.', Lang); if (I > 0) then begin SystemLocale:= Copy(Lang, 1, I - 1); SystemEncoding:= Copy(Lang, I + 1, Length(Lang) - I); end else begin SystemLocale:= Lang; SystemEncoding:= EncodingUTF8; end; end; {$ENDIF} {$IF DEFINED(DARWIN)} function InitIconv(var Error: String): Boolean; begin Error:= EmptyStr; Result:= TryLoadLib('libiconv.dylib', Error); IconvLibFound:= IconvLibFound or Result; end; {$ENDIF} function FindEncoding: Boolean; var Index: Integer; begin // Try to find by language and country for Index:= Low(charset_relation) to High(charset_relation) do begin if CompareStr(charset_relation[Index, 1], SystemLocale) = 0 then begin EncodingANSI:= charset_relation[Index, 2]; EncodingOEM:= charset_relation[Index, 3]; Exit(True); end; end; // Try to find by language only for Index:= Low(charset_relation) to High(charset_relation) do begin if CompareStr(charset_relation[Index, 0], SystemLanguage) = 0 then begin EncodingANSI:= charset_relation[Index, 2]; EncodingOEM:= charset_relation[Index, 3]; Exit(True); end; end; Result:= False; end; function Oem2Utf8(const Source: String): RawByteString; begin Result:= Source; Iconvert(Source, String(Result), EncodingOEM, EncodingUTF8); end; function Utf82Oem(const Source: String): RawByteString; begin Result:= Source; Iconvert(Source, String(Result), EncodingUTF8, EncodingOEM); end; function OEM2Sys(const Source: String): RawByteString; begin Result:= Source; Iconvert(Source, String(Result), EncodingOEM, SystemEncoding); end; function Sys2OEM(const Source: String): RawByteString; begin Result:= Source; Iconvert(Source, String(Result), SystemEncoding, EncodingOEM); end; function Ansi2Sys(const Source: String): RawByteString; begin Result:= Source; Iconvert(Source, String(Result), EncodingANSI, SystemEncoding); end; function Sys2Ansi(const Source: String): RawByteString; begin Result:= Source; Iconvert(Source, String(Result), SystemEncoding, EncodingANSI); end; function Ansi2Utf8(const Source: String): RawByteString; begin Result:= Source; Iconvert(Source, String(Result), EncodingANSI, EncodingUTF8); end; function Utf82Ansi(const Source: String): RawByteString; begin Result:= Source; Iconvert(Source, String(Result), EncodingUTF8, EncodingANSI); end; procedure Initialize; var Error: String = ''; begin CeOemToSys:= @Dummy; CeSysToOem:= @Dummy; CeOemToUtf8:= @Dummy; CeUtf8ToOem:= @Dummy; CeAnsiToSys:= @Dummy; CeSysToAnsi:= @Dummy; CeUtf8ToSys:= @Dummy; CeSysToUtf8:= @Dummy; CeAnsiToUtf8:= @Dummy; CeUtf8ToAnsi:= @Dummy; // Try to get system encoding and initialize Iconv library if not (GetSystemEncoding and InitIconv(Error)) then WriteLn(Error) else begin SystemEncodingUtf8:= (SysUtils.CompareText(SystemEncoding, 'UTF-8') = 0) or (SysUtils.CompareText(SystemEncoding, 'UTF8') = 0); if FindEncoding then begin if (Length(EncodingOEM) > 0) then begin CeOemToSys:= @OEM2Sys; CeSysToOem:= @Sys2OEM; CeOemToUtf8:= @Oem2Utf8; CeUtf8ToOem:= @Utf82Oem; end; if (Length(EncodingANSI) > 0) then begin CeAnsiToSys:= @Ansi2Sys; CeSysToAnsi:= @Sys2Ansi; CeAnsiToUtf8:= @Ansi2Utf8; CeUtf8ToAnsi:= @Utf82Ansi; end; end; if not SystemEncodingUtf8 then begin CeUtf8ToSys:= @UTF82Sys; CeSysToUtf8:= @Sys2UTF8; end; end; end; {$ELSE} procedure Initialize; begin CeOemToSys:= @Dummy; CeSysToOem:= @Dummy; CeOemToUtf8:= @Dummy; CeUtf8ToOem:= @Dummy; CeAnsiToSys:= @Dummy; CeSysToAnsi:= @Dummy; CeUtf8ToSys:= @Dummy; CeSysToUtf8:= @Dummy; CeAnsiToUtf8:= @Dummy; CeUtf8ToAnsi:= @Dummy; end; {$ENDIF} initialization {$IF DEFINED(FPC_HAS_CPSTRING)} FileSystemCodePage:= WideStringManager.GetStandardCodePageProc(scpFileSystemSingleByte); {$ENDIF} Initialize; end. doublecmd-0.8.2/components/doublecmd/dcunix.pas0000664000175000017500000000752513243752341020644 0ustar alexxalexx{ Double commander ------------------------------------------------------------------------- This unit contains Unix specific functions Copyright (C) 2015-2018 Alexander Koblov (alexx2000@mail.ru) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA } unit DCUnix; {$mode objfpc}{$H+} interface uses InitC, BaseUnix; const {$IF DEFINED(LINUX)} FD_CLOEXEC = 1; O_CLOEXEC = &02000000; {$ELSEIF DEFINED(FREEBSD)} O_CLOEXEC = &04000000; {$ELSEIF DEFINED(NETBSD)} O_CLOEXEC = $00400000; {$ELSE} O_CLOEXEC = 0; {$ENDIF} {$IF DEFINED(LINUX)} {$I dclinuxmagic.inc} {$ENDIF} {en Set the close-on-exec flag to all } procedure FileCloseOnExecAll; {en Set the close-on-exec (FD_CLOEXEC) flag } procedure FileCloseOnExec(Handle: System.THandle); inline; {en Change owner and group of a file (does not follow symbolic links) @param(path Full path to file) @param(owner User ID) @param(group Group ID) @returns(On success, zero is returned. On error, -1 is returned, and errno is set appropriately) } function fpLChown(path : String; owner : TUid; group : TGid): cInt; function FileLock(Handle: System.THandle; Mode: cInt): System.THandle; implementation uses SysUtils, Unix, DCConvertEncoding; {$IF DEFINED(BSD)} type rlim_t = Int64; {$ENDIF} const {$IF DEFINED(LINUX)} _SC_OPEN_MAX = 4; RLIM_INFINITY = rlim_t(-1); {$ELSEIF DEFINED(BSD)} _SC_OPEN_MAX = 5; RLIM_INFINITY = rlim_t(High(QWord) shr 1); {$ENDIF} function sysconf(name: cint): clong; cdecl; external clib; function lchown(path : PChar; owner : TUid; group : TGid): cInt; cdecl; external clib name 'lchown'; procedure FileCloseOnExecAll; var fd: cint; p: TRLimit; fd_max: rlim_t = RLIM_INFINITY; begin if (FpGetRLimit(RLIMIT_NOFILE, @p) = 0) and (p.rlim_cur <> RLIM_INFINITY) then fd_max:= p.rlim_cur else begin {$IF DECLARED(_SC_OPEN_MAX)} fd_max:= sysconf(_SC_OPEN_MAX); {$ENDIF} end; if fd_max = RLIM_INFINITY then fd_max:= High(Byte); for fd:= 3 to cint(fd_max) do FileCloseOnExec(fd); end; procedure FileCloseOnExec(Handle: System.THandle); begin {$IF DECLARED(FD_CLOEXEC)} FpFcntl(Handle, F_SETFD, FpFcntl(Handle, F_GETFD) or FD_CLOEXEC); {$ENDIF} end; function fpLChown(path: String; owner: TUid; group: TGid): cInt; begin Result := lchown(PAnsiChar(CeUtf8ToSys(path)), owner, group); if Result = -1 then fpseterrno(fpgetCerrno); end; function FileLock(Handle: System.THandle; Mode: cInt): System.THandle; var lockop: cint; lockres: cint; lockerr: cint; begin Result:= Handle; case (Mode and $F0) of fmShareCompat, fmShareExclusive: lockop:= LOCK_EX or LOCK_NB; fmShareDenyWrite: lockop:= LOCK_SH or LOCK_NB; else Exit; end; repeat lockres:= fpFlock(Handle, lockop); until (lockres = 0) or (fpgeterrno <> ESysEIntr); lockerr:= fpgeterrno; { Only return an error if locks are working and the file was already locked. Not if locks are simply unsupported (e.g., on Angstrom Linux you always get ESysNOLCK in the default configuration) } if (lockres <> 0) and ((lockerr = ESysEAGAIN) or (lockerr = ESysEDEADLK)) then begin Result:= -1; FileClose(Handle); end; end; end. doublecmd-0.8.2/components/doublecmd/dcprocessutf8.pas0000664000175000017500000002203413043055670022135 0ustar alexxalexx{ Based on process.inc from the Free Component Library (FCL) Copyright (c) 1999-2008 by the Free Pascal development team See the file COPYING.FPC, included in this distribution, for details about the copyright. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. } unit DCProcessUtf8; {$mode objfpc}{$H+} interface uses Classes, SysUtils {$IF DEFINED(MSWINDOWS)} , Process, Windows, Pipes {$ELSEIF DEFINED(UNIX)} , UTF8Process, DCUnix {$ENDIF} ; type { TProcessUtf8 } {$IF DEFINED(UNIX)} TProcessUtf8 = class(UTF8Process.TProcessUTF8) private procedure DoForkEvent(Sender : TObject); public constructor Create(AOwner : TComponent); override; end; {$ELSEIF DEFINED(MSWINDOWS)} TProcessUtf8 = class(TProcess) public procedure Execute; override; end; {$ENDIF} implementation {$IF DEFINED(UNIX)} { TProcessUtf8 } procedure TProcessUtf8.DoForkEvent(Sender: TObject); begin FileCloseOnExecAll; end; constructor TProcessUtf8.Create(AOwner: TComponent); begin inherited Create(AOwner); {$IF (FPC_FULLVERSION >= 30000)} OnForkEvent:= @DoForkEvent; {$ELSE} OnForkEvent:= @FileCloseOnExecAll; {$ENDIF} end; {$ELSEIF DEFINED(MSWINDOWS)} {$WARN SYMBOL_DEPRECATED OFF} {$IF FPC_FULLVERSION < 30000} type TStartupInfoW = TStartupInfo; {$ENDIF} resourcestring SNoCommandLine = 'Cannot execute empty command-line'; SErrCannotExecute = 'Failed to execute %s : %d'; const PriorityConstants: array [TProcessPriority] of Cardinal = (HIGH_PRIORITY_CLASS, IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS); function GetStartupFlags(P: TProcess): Cardinal; begin with P do begin Result := 0; if poUsePipes in Options then Result := Result or Startf_UseStdHandles; if suoUseShowWindow in StartupOptions then Result := Result or startf_USESHOWWINDOW; if suoUSESIZE in StartupOptions then Result := Result or startf_usesize; if suoUsePosition in StartupOptions then Result := Result or startf_USEPOSITION; if suoUSECOUNTCHARS in StartupOptions then Result := Result or startf_usecountchars; if suoUsefIllAttribute in StartupOptions then Result := Result or startf_USEFILLATTRIBUTE; end; end; function GetCreationFlags(P: TProcess): Cardinal; begin with P do begin Result := 0; if poNoConsole in Options then Result := Result or Detached_Process; if poNewConsole in Options then Result := Result or Create_new_console; if poNewProcessGroup in Options then Result := Result or CREATE_NEW_PROCESS_GROUP; if poRunSuspended in Options then Result := Result or Create_Suspended; if poDebugProcess in Options then Result := Result or DEBUG_PROCESS; if poDebugOnlyThisProcess in Options then Result := Result or DEBUG_ONLY_THIS_PROCESS; if poDefaultErrorMode in Options then Result := Result or CREATE_DEFAULT_ERROR_MODE; Result := Result or PriorityConstants[Priority]; end; end; function StringsToPWideChars(List: TStrings): Pointer; var I: Integer; EnvBlock: WideString; begin EnvBlock := ''; for I := 0 to List.Count - 1 do EnvBlock := EnvBlock + UTF8Decode(List[I]) + #0; EnvBlock := EnvBlock + #0; GetMem(Result, Length(EnvBlock) * SizeOf(Widechar)); CopyMemory(Result, @EnvBlock[1], Length(EnvBlock) * SizeOf(Widechar)); end; procedure InitProcessAttributes(P: TProcess; var PA: TSecurityAttributes); begin FillChar(PA, SizeOf(PA), 0); PA.nLength := SizeOf(PA); end; procedure InitThreadAttributes(P: TProcess; var TA: TSecurityAttributes); begin FillChar(TA, SizeOf(TA), 0); TA.nLength := SizeOf(TA); end; procedure InitStartupInfo(P: TProcess; var SI: TStartupInfoW); const SWC: array [TShowWindowOptions] of Cardinal = (0, SW_HIDE, SW_Maximize, SW_Minimize, SW_Restore, SW_Show, SW_ShowDefault, SW_ShowMaximized, SW_ShowMinimized, SW_showMinNOActive, SW_ShowNA, SW_ShowNoActivate, SW_ShowNormal); begin FillChar(SI, SizeOf(SI), 0); with SI do begin dwFlags := GetStartupFlags(P); if P.ShowWindow <> swoNone then dwFlags := dwFlags or Startf_UseShowWindow else dwFlags := dwFlags and not Startf_UseShowWindow; wShowWindow := SWC[P.ShowWindow]; if (poUsePipes in P.Options) then begin dwFlags := dwFlags or Startf_UseStdHandles; end; if P.FillAttribute <> 0 then begin dwFlags := dwFlags or Startf_UseFillAttribute; dwFillAttribute := P.FillAttribute; end; dwXCountChars := P.WindowColumns; dwYCountChars := P.WindowRows; dwYsize := P.WindowHeight; dwXsize := P.WindowWidth; dwy := P.WindowTop; dwX := P.WindowLeft; end; end; { The handles that are to be passed to the child process must be inheritable. On the other hand, only non-inheritable handles allow the sending of EOF when the write-end is closed. This function is used to duplicate the child process's ends of the handles into inheritable ones, leaving the parent-side handles non-inheritable. } function DuplicateHandleFP(var Handle: THandle): Boolean; var oldHandle: THandle; begin oldHandle := Handle; Result := DuplicateHandle(GetCurrentProcess(), oldHandle, GetCurrentProcess(), @Handle, 0, True, DUPLICATE_SAME_ACCESS); if Result then Result := CloseHandle(oldHandle); end; procedure CreatePipes(var HI, HO, HE: THandle; var SI: TStartupInfoW; CE: Boolean; APipeBufferSize: Cardinal); begin CreatePipeHandles(SI.hStdInput, HI, APipeBufferSize); DuplicateHandleFP(SI.hStdInput); CreatePipeHandles(HO, Si.hStdOutput, APipeBufferSize); DuplicateHandleFP(Si.hStdOutput); if CE then begin CreatePipeHandles(HE, SI.hStdError, APipeBufferSize); DuplicateHandleFP(SI.hStdError); end else begin SI.hStdError := SI.hStdOutput; HE := HO; end; end; function MaybeQuote(const S: String): String; begin if (Pos(' ', S) <> 0) then Result := '"' + S + '"' else Result := S; end; function MaybeQuoteIfNotQuoted(const S: String): String; begin if (Pos(' ', S) <> 0) and (pos('"', S) = 0) then Result := '"' + S + '"' else Result := S; end; { TProcessUtf8 } procedure TProcessUtf8.Execute; var I: Integer; PName, PDir, PCommandLine: PWideChar; FEnv: Pointer; FCreationFlags: Cardinal; FProcessAttributes: TSecurityAttributes; FThreadAttributes: TSecurityAttributes; FProcessInformation: TProcessInformation; FStartupInfo: TStartupInfoW; HI, HO, HE: THandle; Cmd: String; begin InheritHandles := True; PName := nil; PCommandLine := nil; PDir := nil; if (ApplicationName = '') and (CommandLine = '') and (Executable = '') then raise EProcess.Create(SNoCommandline); if (ApplicationName <> '') then begin PName := PWideChar(UTF8Decode(ApplicationName)); PCommandLine := PWideChar(UTF8Decode(CommandLine)); end else if (CommandLine <> '') then PCommandLine := PWideChar(UTF8Decode(CommandLine)) else if (Executable <> '') then begin Cmd := MaybeQuoteIfNotQuoted(Executable); for I := 0 to Parameters.Count - 1 do Cmd := Cmd + ' ' + MaybeQuoteIfNotQuoted(Parameters[I]); PCommandLine := PWideChar(UTF8Decode(Cmd)); end; if CurrentDirectory <> '' then PDir := PWideChar(UTF8Decode(CurrentDirectory)); if Environment.Count <> 0 then FEnv := StringsToPWideChars(Environment) else FEnv := nil; try FCreationFlags := GetCreationFlags(Self); InitProcessAttributes(Self, FProcessAttributes); InitThreadAttributes(Self, FThreadAttributes); InitStartupInfo(Self, FStartUpInfo); if poUsePipes in Options then CreatePipes(HI, HO, HE, FStartupInfo, not (poStdErrToOutPut in Options), PipeBufferSize); try if not CreateProcessW(PName, PCommandLine, @FProcessAttributes, @FThreadAttributes, InheritHandles, FCreationFlags, FEnv, PDir, FStartupInfo, FProcessInformation) then raise EProcess.CreateFmt(SErrCannotExecute, [CommandLine, GetLastError]); PHandle(@ProcessHandle)^ := FProcessInformation.hProcess; PHandle(@ThreadHandle)^ := FProcessInformation.hThread; PInteger(@ProcessID)^ := FProcessINformation.dwProcessID; finally if poUsePipes in Options then begin FileClose(FStartupInfo.hStdInput); FileClose(FStartupInfo.hStdOutput); if not (poStdErrToOutPut in Options) then FileClose(FStartupInfo.hStdError); CreateStreams(HI, HO, HE); end; end; FRunning := True; finally if FEnv <> nil then FreeMem(FEnv); end; if not (csDesigning in ComponentState) and // This would hang the IDE ! (poWaitOnExit in Options) and not (poRunSuspended in Options) then WaitOnExit; end; {$ENDIF} end. doublecmd-0.8.2/components/doublecmd/dcdatetimeutils.pas0000664000175000017500000004451013211003140022506 0ustar alexxalexx{ Double Commander ------------------------------------------------------------------------- Date and time functions. Copyright (C) 2009-2012 Przemysław Nagay (cobines@gmail.com) Copyright (C) 2017 Alexander Koblov (alexx2000@mail.ru) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } unit DCDateTimeUtils; {$mode objfpc}{$H+} interface uses Classes, SysUtils, DCBasicTypes {$IF DEFINED(MSWINDOWS)} , Windows {$ELSEIF DEFINED(UNIX)} , unixutil {$ENDIF} ; function FileTimeToDateTime(FileTime : DCBasicTypes.TFileTime) : TDateTime; function DateTimeToFileTime(DateTime : TDateTime) : DCBasicTypes.TFileTime; {en Converts system specific UTC time to local time. } function FileTimeToLocalFileTime(const FileTime: DCBasicTypes.TFileTime; out LocalFileTime: DCBasicTypes.TFileTime): LongBool; {en Converts system specific local time to UTC time. } function LocalFileTimeToFileTime(const LocalFileTime: DCBasicTypes.TFileTime; out FileTime: DCBasicTypes.TFileTime): LongBool; {en Converts Windows UTC file time to Windows local file time. @param(lpFileTime TWinFileTime structure containing the UTC-based file time) @param(lpLocalFileTime TWinFileTime structure to receive the converted local file time) @returns(The function returns @true if successful, @false otherwise) } function WinFileTimeToLocalFileTime(const FileTime: TWinFileTime; out LocalFileTime: TWinFileTime): LongBool; {en Converts Windows local file time to Windows UTC file time. @param(lpLocalFileTime TWinFileTime structure that specifies the local file time) @param(lpFileTime TWinFileTime structure to receive the converted UTC-based file time) @returns(The function returns @true if successful, @false otherwise) } function WinLocalFileTimeToFileTime(const LocalFileTime: TWinFileTime; out FileTime: TWinFileTime): LongBool; {en Converts Windows UTC file time to a file time in TDateTime format. @param(ft TWinFileTime structure containing the UTC-based file time) @returns(File time in TDateTime format) } function WinFileTimeToDateTime(ft : TWinFileTime) : TDateTime; {en Converts a file time in TDateTime format to Windows UTC file time. @param(dt File time in TDateTime format) @returns(Windows UTC-based file time) } function DateTimeToWinFileTime(dt : TDateTime) : TWinFileTime; function DosFileTimeToDateTime(const DosTime: TDosFileTime): TDateTime; function DateTimeToDosFileTime(const DateTime: TDateTime): TDosFileTime; {$IFDEF MSWINDOWS} function WinFileTimeToDateTime(ft : Windows.FILETIME) : TDateTime; inline; overload; function WinToDosTime(const WinTime: Windows.FILETIME; var DosTime: TDosFileTime): LongBool; overload; function DosToWinTime(const DosTime: TDosFileTime; var WinTime: Windows.FILETIME): LongBool; overload; function WinToDosTime(const WinTime: TWinFileTime; var DosTime: TDosFileTime): LongBool; function DosToWinTime(const DosTime: TDosFileTime; var WinTime: TWinFileTime): LongBool; {$ENDIF} function UnixFileTimeToDateTime(UnixTime: TUnixFileTime) : TDateTime; function DateTimeToUnixFileTime(DateTime: TDateTime) : TUnixFileTime; function UnixFileTimeToDosTime(UnixTime: TUnixFileTime): TDosFileTime; function UnixFileTimeToWinTime(UnixTime: TUnixFileTime): TWinFileTime; function WinFileTimeToUnixTime(WinTime: TWinFileTime) : TUnixFileTime; function UnixFileTimeToWcxTime(UnixTime: TUnixFileTime): LongInt; function GetTimeZoneBias: LongInt; {en Converts a month short name to month number. @param(ShortMonthName Month short name) @param(Default Default month number) @returns(Month number) } function MonthToNumberDef(const ShortMonthName: String; Default: Word): Word; {en Converts a year short record to year long record if need (10 -> 2010). @param(Year Year short record) @returns(Year long record) } function YearShortToLong(Year: Word): Word; function TwelveToTwentyFour(Hour: Word; Modifier: AnsiString): Word; function FileTimeCompare(SourceTime, TargetTime: TDateTime; NtfsShift: Boolean): Integer; type EDateOutOfRange = class(EConvertError) private FDateTime: TDateTime; public constructor Create(ADateTime: TDateTime); property DateTime: TDateTime read FDateTime; end; implementation uses DateUtils; const { Short names of months. } ShortMonthNames: TMonthNameArray = ('Jan','Feb','Mar','Apr','May','Jun', 'Jul','Aug','Sep','Oct','Nov','Dec'); SecsPerHour = SecsPerMin * MinsPerHour; {$IF DEFINED(MSWINDOWS)} var WinTimeZoneBias: LongInt; {$ENDIF} function AdjustUnixFileTime(const FileTime: DCBasicTypes.TFileTime; out AdjustedFileTime: DCBasicTypes.TFileTime; AdjustValue: Int64): Boolean; begin if AdjustValue < 0 then begin if FileTime < DCBasicTypes.TFileTime(-AdjustValue) then begin AdjustedFileTime := 0; Result := False; end else begin AdjustedFileTime := FileTime - DCBasicTypes.TFileTime(-AdjustValue); Result := True; end; end else begin if High(FileTime) - FileTime < DCBasicTypes.TFileTime(AdjustValue) then begin AdjustedFileTime := High(FileTime); Result := False; end else begin AdjustedFileTime := FileTime + DCBasicTypes.TFileTime(AdjustValue); Result := True; end; end; end; function AdjustWinFileTime(const FileTime: TWinFileTime; out AdjustedFileTime: TWinFileTime; AdjustValue: Int64): Boolean; begin if AdjustValue < 0 then begin if FileTime < DCBasicTypes.TWinFileTime(-AdjustValue) then begin AdjustedFileTime := 0; Result := False; end else begin AdjustedFileTime := FileTime - DCBasicTypes.TWinFileTime(-AdjustValue); Result := True; end; end else begin if High(FileTime) - FileTime < DCBasicTypes.TWinFileTime(AdjustValue) then begin AdjustedFileTime := High(FileTime); Result := False; end else begin AdjustedFileTime := FileTime + DCBasicTypes.TWinFileTime(AdjustValue); Result := True; end; end; end; function FileTimeToDateTime(FileTime : DCBasicTypes.TFileTime) : TDateTime; {$IF DEFINED(MSWINDOWS)} begin Result := WinFileTimeToDateTime(FileTime); end; {$ELSEIF DEFINED(UNIX)} var Hrs, Mins, Secs : Word; TodaysSecs : DCBasicTypes.TFileTime; begin FileTimeToLocalFileTime(FileTime, FileTime); TodaysSecs := FileTime mod SecsPerDay; Hrs := Word(TodaysSecs div SecsPerHour); TodaysSecs := TodaysSecs - (Hrs * SecsPerHour); Mins := Word(TodaysSecs div SecsPerMin); Secs := Word(TodaysSecs - (Mins * SecsPerMin)); Result := UnixEpoch + // Epoch start + (FileTime div SecsPerDay) + // Number of days + EncodeTime(Hrs, Mins, Secs, 0); // Time end; {$ELSE} begin Result := 0; end; {$ENDIF} function DateTimeToFileTime(DateTime : TDateTime) : DCBasicTypes.TFileTime; {$IF DEFINED(MSWINDOWS)} begin Result := DateTimeToWinFileTime(DateTime); end; {$ELSEIF DEFINED(UNIX)} var Hrs, Mins, Secs, MSecs : Word; Dt, Tm : TDateTime; BigTime: QWord; begin Dt := Trunc(DateTime); Tm := DateTime - Dt; if Dt < UnixEpoch then raise EDateOutOfRange.Create(DateTime) else {$PUSH}{$Q-} BigTime := Trunc(Dt - UnixEpoch) * SecsPerDay; {$POP} DecodeTime(Tm, Hrs, Mins, Secs, MSecs); {$PUSH}{$Q-} BigTime := BigTime + QWord(Hrs * SecsPerHour) + QWord(Mins * SecsPerMin) + Secs; {$POP} {$IFDEF cpu32} if BigTime > High(DCBasicTypes.TFileTime) then raise EDateOutOfRange.Create(DateTime) else {$ENDIF} LocalFileTimeToFileTime(BigTime, Result); end; {$ELSE} begin Result := 0; end; {$ENDIF} function FileTimeToLocalFileTime(const FileTime: DCBasicTypes.TFileTime; out LocalFileTime: DCBasicTypes.TFileTime): LongBool; {$IFDEF MSWINDOWS} begin Result := Windows.FileTimeToLocalFileTime(@Windows.FILETIME(FileTime), @Windows.FILETIME(LocalFileTime)); end; {$ELSE} begin Result := AdjustUnixFileTime(FileTime, LocalFileTime, Tzseconds); end; {$ENDIF} function LocalFileTimeToFileTime(const LocalFileTime: DCBasicTypes.TFileTime; out FileTime: DCBasicTypes.TFileTime): LongBool; {$IFDEF MSWINDOWS} begin Result := Windows.LocalFileTimeToFileTime(@Windows.FILETIME(LocalFileTime), @Windows.FILETIME(FileTime)); end; {$ELSE} begin Result := AdjustUnixFileTime(LocalFileTime, FileTime, -Tzseconds); end; {$ENDIF} function WinFileTimeToLocalFileTime(const FileTime: TWinFileTime; out LocalFileTime: TWinFileTime): LongBool; {$IFDEF MSWINDOWS} begin Result := Windows.FileTimeToLocalFileTime(@Windows.FILETIME(FileTime), @Windows.FILETIME(LocalFileTime)); end; {$ELSE} begin Result := AdjustWinFileTime(FileTime, LocalFileTime, 10000000 * Int64(TZSeconds)); end; {$ENDIF} function WinLocalFileTimeToFileTime(const LocalFileTime: TWinFileTime; out FileTime: TWinFileTime): LongBool; {$IFDEF MSWINDOWS} begin Result := Windows.LocalFileTimeToFileTime(@Windows.FILETIME(LocalFileTime), @Windows.FILETIME(FileTime)); end; {$ELSE} begin Result := AdjustWinFileTime(LocalFileTime, FileTime, -10000000 * Int64(TZSeconds)); end; {$ENDIF} function WinFileTimeToDateTime(ft : TWinFileTime) : TDateTime; begin WinFileTimeToLocalFileTime(ft,ft); Result := (ft / 864000000000.0) - 109205.0; end; function DateTimeToWinFileTime(dt : TDateTime) : TWinFileTime; begin Result := Round((Extended(dt) + 109205.0) * 864000000000.0); WinLocalFileTimeToFileTime(Result, Result); end; function DosFileTimeToDateTime(const DosTime: TDosFileTime): TDateTime; var Yr, Mo, Dy : Word; Hr, Mn, S : Word; FileDate, FileTime : Word; begin FileDate := LongRec(DosTime).Hi; FileTime := LongRec(DosTime).Lo; Yr := FileDate shr 9 + 1980; Mo := FileDate shr 5 and 15; if Mo < 1 then Mo := 1; if Mo > 12 then Mo := 12; Dy := FileDate and 31; if Dy < 1 then Dy := 1; if Dy > DaysInAMonth(Yr, Mo) then Dy := DaysInAMonth(Yr, Mo); Hr := FileTime shr 11; if Hr > 23 then Hr := 23; Mn := FileTime shr 5 and 63; if Mn > 59 then Mn := 59; S := FileTime and 31 shl 1; if S > 59 then S := 59; Result := ComposeDateTime(EncodeDate(Yr, Mo, Dy), EncodeTime(Hr, Mn, S, 0)); end; function DateTimeToDosFileTime(const DateTime: TDateTime): TDosFileTime; var Yr, Mo, Dy : Word; Hr, Mn, S, MS: Word; begin DecodeDate(DateTime, Yr, Mo, Dy); if (Yr < 1980) or (Yr > 2107) then // outside DOS file date year range Yr := 1980; DecodeTime(DateTime, Hr, Mn, S, MS); LongRec(Result).Lo := (S shr 1) or (Mn shl 5) or (Hr shl 11); LongRec(Result).Hi := Dy or (Mo shl 5) or (Word(Yr - 1980) shl 9); end; {$IFDEF MSWINDOWS} function WinFileTimeToDateTime(ft : Windows.FILETIME) : TDateTime; begin Result := WinFileTimeToDateTime(TWinFileTime(ft)); end; function WinToDosTime(const WinTime: Windows.FILETIME; var DosTime: TDosFileTime): LongBool; var lft : Windows.TFILETIME; begin Result:= Windows.FileTimeToLocalFileTime(@Windows.FILETIME(WinTime), @lft) and Windows.FileTimeToDosDateTime(@lft, @LongRec(Dostime).Hi, @LongRec(DosTime).Lo); end; function DosToWinTime(const DosTime: TDosFileTime; var WinTime: Windows.FILETIME): LongBool; var lft : Windows.TFILETIME; begin Result := Windows.DosDateTimeToFileTime(LongRec(DosTime).Hi, LongRec(DosTime).Lo, @lft) and Windows.LocalFileTimeToFileTime(@lft, @Windows.FILETIME(WinTime)); end; function WinToDosTime(const WinTime: TWinFileTime; var DosTime: TDosFileTime): LongBool; var lft : Windows.TFILETIME; begin Result:= Windows.FileTimeToLocalFileTime(@Windows.FILETIME(WinTime), @lft) and Windows.FileTimeToDosDateTime(@lft, @LongRec(Dostime).Hi, @LongRec(DosTime).Lo); end; function DosToWinTime(const DosTime: TDosFileTime; var WinTime: TWinFileTime): LongBool; var lft : Windows.TFILETIME; begin Result := Windows.DosDateTimeToFileTime(LongRec(DosTime).Hi, LongRec(DosTime).Lo, @lft) and Windows.LocalFileTimeToFileTime(@lft, @Windows.FILETIME(WinTime)); end; {$ENDIF} function UnixFileTimeToDateTime(UnixTime: TUnixFileTime) : TDateTime; var Hrs, Mins, Secs : Word; TodaysSecs : LongInt; {$IFDEF MSWINDOWS} LocalWinFileTime, WinFileTime: TWinFileTime; {$ENDIF} {$IFDEF UNIX} LocalUnixTime: TUnixFileTime; {$ENDIF} begin {$IFDEF UNIX} if FileTimeToLocalFileTime(UnixTime, LocalUnixTime) then UnixTime := LocalUnixTime; {$ENDIF} TodaysSecs := UnixTime mod SecsPerDay; Hrs := TodaysSecs div SecsPerHour; TodaysSecs := TodaysSecs - (Hrs * SecsPerHour); Mins := TodaysSecs div SecsPerMin; Secs := TodaysSecs - (Mins * SecsPerMin); Result := UnixDateDelta + (UnixTime div SecsPerDay) + EncodeTime(Hrs, Mins, Secs, 0); {$IFDEF MSWINDOWS} // Convert universal to local TDateTime. WinFileTime := DateTimeToWinFileTime(Result); if FileTimeToLocalFileTime(WinFileTime, LocalWinFileTime) then WinFileTime := LocalWinFileTime; Result := WinFileTimeToDateTime(WinFileTime); {$ENDIF} end; function DateTimeToUnixFileTime(DateTime : TDateTime): TUnixFileTime; var Hrs, Mins, Secs, MSecs : Word; Dt, Tm : TDateTime; {$IFDEF MSWINDOWS} LocalWinFileTime, WinFileTime: TWinFileTime; {$ENDIF} {$IFDEF UNIX} UnixTime: TUnixFileTime; {$ENDIF} begin {$IFDEF MSWINDOWS} // Convert local to universal TDateTime. LocalWinFileTime := DateTimeToWinFileTime(DateTime); if LocalFileTimeToFileTime(LocalWinFileTime, WinFileTime) then LocalWinFileTime := WinFileTime; DateTime := WinFileTimeToDateTime(LocalWinFileTime); {$ENDIF} Dt := Trunc(DateTime); Tm := DateTime - Dt; if Dt < UnixDateDelta then Result := 0 else Result := Trunc(Dt - UnixDateDelta) * SecsPerDay; DecodeTime(Tm, Hrs, Mins, Secs, MSecs); Result := Result + (Hrs * SecsPerHour) + (Mins * SecsPerMin) + Secs; {$IFDEF UNIX} if LocalFileTimeToFileTime(Result, UnixTime) then Result := UnixTime; {$ENDIF} end; function UnixFileTimeToDosTime(UnixTime: TUnixFileTime): TDosFileTime; begin Result := DateTimeToDosFileTime(UnixFileTimeToDateTime(UnixTime)); end; function UnixFileTimeToWinTime(UnixTime: TUnixFileTime): TWinFileTime; var WinFileTime: TWinFileTime; begin WinFileTime := $019DB1DED53E8000; // Unix epoch start if not AdjustWinFileTime(WinFileTime, Result, 10000000 * Int64(UnixTime)) then Result := WinFileTime; end; function WinFileTimeToUnixTime(WinTime: TWinFileTime): TUnixFileTime; begin Result:= TUnixFileTime((WinTime - $019DB1DED53E8000) div 10000000); end; function UnixFileTimeToWcxTime(UnixTime: TUnixFileTime): LongInt; begin {$IF DEFINED(MSWINDOWS)} Result := UnixFileTimeToDosTime(UnixTime); {$ELSEIF DEFINED(UNIX)} {$PUSH}{$R-} Result := UnixTime; {$POP} {$ELSE} Result := 0; {$ENDIF} end; function GetTimeZoneBias: LongInt; begin {$IF DEFINED(MSWINDOWS)} Result := WinTimeZoneBias; {$ELSEIF DEFINED(UNIX)} Result := -Tzseconds div 60; {$ELSE} Result := 0; {$ENDIF} end; function MonthToNumberDef(const ShortMonthName: String; Default: Word): Word; var I: Word; begin Result:= Default; if ShortMonthName = EmptyStr then Exit; for I:= 1 to 12 do if SameText(ShortMonthName, ShortMonthNames[I]) then Exit(I); end; function YearShortToLong(Year: Word): Word; begin Result:= Year; if (Year < 100) then begin if (Year < 80) then Result:= Year + 2000 else Result:= Year + 1900; end; end; function TwelveToTwentyFour(Hour: Word; Modifier: AnsiString): Word; begin if Modifier = EmptyStr then Exit(Hour); case LowerCase(Modifier[1]) of 'a': begin if (Hour = 12) then Result:= 0; end; 'p': begin if (Hour < 12) then Result:= Hour + 12; end; end; end; function FileTimeCompare(SourceTime, TargetTime: TDateTime; NtfsShift: Boolean): Integer; const TimeDiff = 3100 / MSecsPerDay; NtfsDiff:TDateTime = (1/HoursPerDay); var FileTimeDiff, NtfsTimeDiff: TDateTime; begin FileTimeDiff:= SourceTime - TargetTime; if NtfsShift then begin NtfsTimeDiff:= FileTimeDiff - NtfsDiff; if (NtfsTimeDiff > -TimeDiff) and (NtfsTimeDiff < TimeDiff) then Exit(0); NtfsTimeDiff:= FileTimeDiff + NtfsDiff; if (NtfsTimeDiff > -TimeDiff) and (NtfsTimeDiff < TimeDiff) then Exit(0); end; if (FileTimeDiff > -TimeDiff) and (FileTimeDiff < TimeDiff) then Result:= 0 else if FileTimeDiff > 0 then Result:= +1 else if FileTimeDiff < 0 then Result:= -1; end; { EDateOutOfRange } constructor EDateOutOfRange.Create(ADateTime: TDateTime); begin inherited Create(EmptyStr); FDateTime := ADateTime; end; {$IF DEFINED(MSWINDOWS)} procedure InitTimeZoneBias; var TZInfo: TTimeZoneInformation; begin case GetTimeZoneInformation(@TZInfo) of TIME_ZONE_ID_UNKNOWN: WinTimeZoneBias := TZInfo.Bias; TIME_ZONE_ID_STANDARD: WinTimeZoneBias := TZInfo.Bias + TZInfo.StandardBias; TIME_ZONE_ID_DAYLIGHT: WinTimeZoneBias := TZInfo.Bias + TZInfo.DaylightBias; else WinTimeZoneBias := 0; end; end; initialization InitTimeZoneBias; {$ENDIF} end. doublecmd-0.8.2/components/doublecmd/dcbasictypes.pas0000664000175000017500000000305212262250007022006 0ustar alexxalexx{ Double commander ------------------------------------------------------------------------- Definitions of basic types. Copyright (C) 2012 Przemyslaw Nagay (cobines@gmail.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } unit DCBasicTypes; interface type TDynamicStringArray = array of String; TCharSet = set of Char; TFileAttrs = Cardinal; // file attributes type regardless of system TWinFileTime = QWord; // NTFS time (UTC) (2 x DWORD) TDosFileTime = LongInt; // MS-DOS time (local) {$IFDEF MSWINDOWS} TFileTime = TWinFileTime; {$ELSE} // Unix time (UTC). // Unix defines time_t as signed integer, // but we define it as unsigned because sign is not needed. {$IFDEF cpu64} TFileTime = QWord; {$ELSE} TFileTime = DWord; {$ENDIF} {$ENDIF} TUnixFileTime = TFileTime; PFileTime = ^TFileTime; PWinFileTime = ^TWinFileTime; implementation end. doublecmd-0.8.2/components/doublecmd/dcwindows.pas0000664000175000017500000001164112755661604021355 0ustar alexxalexx{ Double commander ------------------------------------------------------------------------- This unit contains Windows specific functions Copyright (C) 2015 Alexander Koblov (alexx2000@mail.ru) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA } unit DCWindows; {$mode objfpc}{$H+} interface uses Windows; {en Converts file name in UTF-8 encoding to file name with UTF-16 encoding with extended-length path prefix } function UTF16LongName(const FileName: String): UnicodeString; {en Enable a privilege @param(hToken Access token handle) @param(lpszPrivilege Name of privilege to enable) @returns(The function returns @true if successful, @false otherwise) } function EnablePrivilege(hToken: HANDLE; lpszPrivilege: LPCTSTR): Boolean; {en Copy permissions specific to the NTFS file system, like read and write permissions, and the file owner } function CopyNtfsPermissions(const Source, Target: String): Boolean; implementation uses JwaAclApi, JwaWinNT, JwaAccCtrl, JwaWinBase, JwaWinType; function UTF16LongName(const FileName: String): UnicodeString; var Temp: PWideChar; begin if Pos('\\', FileName) = 0 then Result := '\\?\' + UTF8Decode(FileName) else begin Result := '\\?\UNC\' + UTF8Decode(Copy(FileName, 3, MaxInt)); end; Temp := Pointer(Result) + 4; while Temp^ <> #0 do begin if Temp^ = '/' then Temp^:= '\'; Inc(Temp); end; if ((Temp - 1)^ = DriveSeparator) then Result:= Result + '\'; end; function EnablePrivilege(hToken: HANDLE; lpszPrivilege: LPCTSTR): Boolean; var tp: TTokenPrivileges; luid: TLuid = (LowPart: 0; HighPart: 0); begin if (not LookupPrivilegeValue(nil, lpszPrivilege, luid)) then Exit(False); tp.PrivilegeCount:= 1; tp.Privileges[0].Luid:= luid; tp.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED; // Enable privilege in the specified access token if (not AdjustTokenPrivileges(hToken, False, @tp, SizeOf(TTokenPrivileges), nil, nil)) then Exit(False); // Not all privileges or groups referenced are assigned to the caller Result:= not (GetLastError() = ERROR_NOT_ALL_ASSIGNED); end; function CopyNtfsPermissions(const Source, Target: String): Boolean; const DisabledPrivilege: Boolean = True; var Dacl, Sacl: PACL; lpdwRevision: DWORD = 0; ProcessToken: HANDLE = 0; SidOwner, SidGroup: PSID; SecDescPtr: PSECURITY_DESCRIPTOR = nil; SecDescCtl: SECURITY_DESCRIPTOR_CONTROL = 0; SecurityInfo: SECURITY_INFORMATION = DACL_SECURITY_INFORMATION or SACL_SECURITY_INFORMATION or OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION; begin if DisabledPrivilege then begin DisabledPrivilege:= False; Result:= OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, ProcessToken); if not Result then Exit(False) else begin EnablePrivilege(ProcessToken, SE_BACKUP_NAME); EnablePrivilege(ProcessToken, SE_RESTORE_NAME); EnablePrivilege(ProcessToken, SE_SECURITY_NAME); CloseHandle(ProcessToken); end; end; Result:= GetNamedSecurityInfoW(PWideChar(UTF8Decode(Source)), SE_FILE_OBJECT, SecurityInfo, @SidOwner, @SidGroup, @Dacl, @Sacl, SecDescPtr) = ERROR_SUCCESS; if Result then begin if GetSecurityDescriptorControl(SecDescPtr, SecDescCtl, lpdwRevision) then begin // Need to copy DACL inheritance if (SecDescCtl and SE_DACL_PROTECTED <> 0) then SecurityInfo:= SecurityInfo or PROTECTED_DACL_SECURITY_INFORMATION else begin SecurityInfo:= SecurityInfo or UNPROTECTED_DACL_SECURITY_INFORMATION; end; // Need to copy SACL inheritance if (SecDescCtl and SE_SACL_PROTECTED <> 0) then SecurityInfo:= SecurityInfo or PROTECTED_SACL_SECURITY_INFORMATION else begin SecurityInfo:= SecurityInfo or UNPROTECTED_SACL_SECURITY_INFORMATION; end; Result:= SetNamedSecurityInfoW(PWideChar(UTF8Decode(Target)), SE_FILE_OBJECT, SecurityInfo, SidOwner, SidGroup, Dacl, Sacl) = ERROR_SUCCESS; end; {$PUSH}{$HINTS OFF}{$WARNINGS OFF} LocalFree(HLOCAL(SecDescPtr)); {$POP} end; end; end. doublecmd-0.8.2/components/build.sh0000775000175000017500000000170013054266654016341 0ustar alexxalexx#!/bin/sh set -e # Compiling components # Do not execute this script directly. # This script is called from ../build.sh. # Get processor architecture if [ -z $CPU_TARGET ] ; then export CPU_TARGET=$(fpc -iTP) fi # Generate PIC code if [ "$CPU_TARGET" != "arm" ] ; then if [ -f /etc/fpc.cfg ] ; then cp /etc/fpc.cfg ./ echo "-fPIC" >> fpc.cfg export PPC_CONFIG_PATH=$(pwd) fi fi # Build components basedir=$(pwd) cd components $lazbuild chsdet/chsdet.lpk $DC_ARCH $lazbuild CmdLine/cmdbox.lpk $DC_ARCH $lazbuild multithreadprocs/multithreadprocslaz.lpk $DC_ARCH $lazbuild dcpcrypt/dcpcrypt.lpk $DC_ARCH $lazbuild doublecmd/doublecmd_common.lpk $DC_ARCH $lazbuild KASToolBar/kascomp.lpk $DC_ARCH $lazbuild viewer/viewerpackage.lpk $DC_ARCH $lazbuild gifanim/pkg_gifanim.lpk $DC_ARCH $lazbuild synunihighlighter/synuni.lpk $DC_ARCH cd $basedir # Remove temporary file if [ -f fpc.cfg ] ; then rm -f fpc.cfg export PPC_CONFIG_PATH= fi doublecmd-0.8.2/components/build.bat0000664000175000017500000000106713054266654016500 0ustar alexxalexx@echo off rem Compiling components rem Do not execute this script directly. rem This script is called from ..\build.bat. pushd components lazbuild chsdet\chsdet.lpk %DC_ARCH% lazbuild CmdLine\cmdbox.lpk %DC_ARCH% lazbuild multithreadprocs\multithreadprocslaz.lpk %DC_ARCH% lazbuild dcpcrypt\dcpcrypt.lpk %DC_ARCH% lazbuild doublecmd\doublecmd_common.lpk %DC_ARCH% lazbuild KASToolBar\kascomp.lpk %DC_ARCH% lazbuild viewer\viewerpackage.lpk %DC_ARCH% lazbuild gifanim\pkg_gifanim.lpk %DC_ARCH% lazbuild synunihighlighter\synuni.lpk %DC_ARCH% popd doublecmd-0.8.2/components/lclextensions/0000775000175000017500000000000013244011205017554 5ustar alexxalexxdoublecmd-0.8.2/components/lclextensions/delphicompat.pas0000664000175000017500000001071012014201074022730 0ustar alexxalexxunit DelphiCompat; { Delphi Compatibility Unit Copyright (C) 2007 Luiz Amrico Pereira Cmara pascalive@bol.com.br This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version with the following modification: As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules,and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. } {$mode objfpc}{$H+} {.$define DEBUG_DELPHICOMPAT} interface uses LMessages, Types, LCLType, Classes; const //Messages WM_GETDLGCODE = LM_GETDLGCODE; WM_ERASEBKGND = LM_ERASEBKGND; WM_VSCROLL = LM_VSCROLL; WM_HSCROLL = LM_HSCROLL; WM_CHAR = LM_CHAR; WM_KEYDOWN = LM_KEYDOWN; WM_KEYUP = LM_KEYUP; WM_KILLFOCUS = LM_KILLFOCUS; WM_SIZE = LM_SIZE; WM_LBUTTONDBLCLK = LM_LBUTTONDBLCLK; WM_LBUTTONDOWN = LM_LBUTTONDOWN; type //TWM* types TMessage = TLMessage; TWMHScroll = TLMHScroll; TWMVScroll = TLMVScroll; TWMChar = TLMChar; TWMKeyDown = TLMKeyDown; TWMKeyUp = TLMKeyUp; TWMKillFocus = TLMKillFocus; TWMSize = TLMSize; TWMLButtonDblClk = TLMLButtonDblClk; TWMMeasureItem = TLMMeasureItem; TWMDrawItem = TLMDrawItems; function BeginDeferWindowPos(nNumWindows: LongInt):THandle; function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Rop: DWORD): Boolean; function CopyImage(hImage: THandle; uType:LongWord; cxDesired, cyDesired: LongInt; fuFlags:LongWord):THandle; function DeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter:THandle; x, y, cx, cy:longint; uFlags:LongWord):THandle; function EndDeferWindowPos(hWinPosInfo:THandle):Boolean; function GdiFlush: Boolean; function GetACP:LongWord; function GetBkColor(DC:HDC):COLORREF; function GetDCEx(hWnd:HWND; hrgnClip:HRGN; flags:DWORD):HDC; function GetKeyboardLayout(dwLayout:DWORD):THandle; function GetKeyboardState(lpKeyState:PBYTE):BOOLEAN; function GetLocaleInfo(Locale, LCType:LongWord; lpLCData:PChar; cchData:longint):longint; function GetRandomRgn(DC: HDC; Rgn: HRGN; iNum: Integer): Integer; stdcall; function GetTextAlign(hDC:HDC): LongWord; function GetTextExtentExPoint(DC: HDC; Str: PChar; Count, MaxWidth: Integer; MaxCount, PartialWidths: PInteger; var Size: TSize): BOOL; function GetTextExtentPoint32W(DC: HDC; Str: PWideChar; Count: Integer; out Size: TSize): Boolean; function GetWindowDC(hWnd:HWND):HDC; function ImageList_DragShowNolock(fShow: Boolean): Boolean; function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints; cPoints: UINT): Integer; function MultiByteToWideChar(CodePage, dwFlags:DWORD; lpMultiByteStr:PChar; cchMultiByte:longint; lpWideCharStr:PWideChar;cchWideChar:longint):longint; function OffsetRgn(hrgn:HRGN; nxOffset, nYOffset:longint):longint; function ScrollDC(DC:HDC; dx:longint; dy:longint; var lprcScroll:TRECT; var lprcClip:TRECT;hrgnUpdate:HRGN; lprcUpdate:PRECT):Boolean; function SetBrushOrgEx(DC:HDC; nXOrg, nYOrg:longint; lppt:PPOINT):Boolean; function ToAscii(uVirtKey, uScanCode:LongWord; lpKeyState: PByte; lpChar: PWord; uFlags:LongWord): LongInt; implementation uses {$i uses.inc} LCLProc, Controls {$ifdef DEBUG_DELPHICOMPAT} ,multiloglcl, filechannel {$endif} ; {$ifdef DEBUG_DELPHICOMPAT} const //Logger classes lcInfo = 0; lcStack = 1; var Logger: TLCLLogger; {$endif} {$i delphicompat.inc} end. doublecmd-0.8.2/components/lclextensions/include/0000775000175000017500000000000013244011205021177 5ustar alexxalexxdoublecmd-0.8.2/components/lclextensions/include/gtk/0000775000175000017500000000000013244011205021764 5ustar alexxalexxdoublecmd-0.8.2/components/lclextensions/include/gtk/delphicompat.inc0000664000175000017500000001027412014201074025133 0ustar alexxalexx { This file is part of Delphi Compatibility Unit Copyright (C) 2007 Luiz Américo Pereira Câmara pascalive@bol.com.br This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version with the following modification: As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules,and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. } {$define HAS_GETBKCOLOR} {$define HAS_GETTEXTEXTENTEXPOINT} {$define HAS_DRAWFRAMECONTROL} {$i ../generic/stubs.inc} {$i ../generic/independentfunctions.inc} {$i ../generic/unicodefunctions.inc} function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Rop: DWORD): Boolean; begin Result := GTKWidgetSet.StretchCopyArea(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height, 0, XSrc, YSrc, Rop); end; function DrawFrameControl(DC: HDC; const Rect: TRect; uType, uState: LongWord): Boolean; begin Result := LCLIntf.DrawFrameControl(DC, Rect, uType, uState); end; function GetBkColor(DC:HDC):COLORREF; begin if GTKWidgetSet.IsValidDC(DC) then Result := TGtkDeviceContext(DC).CurrentBackColor.ColorRef else Result := CLR_INVALID; end; function GetTextExtentExPoint(DC: HDC; Str: PChar; Count, MaxWidth: Integer; MaxCount, PartialWidths: ObjPas.PInteger; var Size: TSize): BOOL; var lbearing, rbearing, width, ascent,descent: LongInt; UseFont : PGDKFont; IsDBCSFont: Boolean; NewCount,Accumulator,i: Integer; begin //based in lcl code Result := GTKWidgetSet.IsValidDC(DC); if Result then with TGtkDeviceContext(DC) do begin if (CurrentFont = nil) or (CurrentFont^.GDIFontObject = nil) then begin UseFont := GTKWidgetSet.GetDefaultGtkFont(false); end else begin UseFont := CurrentFont^.GDIFontObject; end; If UseFont = nil then DebugLn('WARNING: [TGtkWidgetSet.GetTextExtentPoint] Missing font') else begin descent:=0; { UpdateDCTextMetric(TDeviceContext(DC)); IsDBCSFont:=TDeviceContext(DC).DCTextMetric.IsDoubleByteChar; if IsDBCSFont then begin NewCount:=Count*2; if FExtUTF8OutCacheSize nil then begin Accumulator:=0; for i:= 0 to Count - 1 do begin Inc(Accumulator,gdk_char_width(UseFont,(Str+i)^)); PartialWidths[i]:=Accumulator; end; end; end; end; end; doublecmd-0.8.2/components/lclextensions/include/gtk/lclext.inc0000664000175000017500000000047512014201074023757 0ustar alexxalexx function DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean; begin //todo: see if is possible todo it faster Result := GTKWidgetSet.StretchCopyArea(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height, Mask, XSrc, YSrc, SRCCOPY); end; doublecmd-0.8.2/components/lclextensions/include/gtk/uses.inc0000664000175000017500000000010612014201074023432 0ustar alexxalexx LCLIntf, Graphics, gtkdef, gdk, GTKProc, GtkInt, glib, gtk, Math, doublecmd-0.8.2/components/lclextensions/include/gtk/uses_lclext.inc0000664000175000017500000000001712014201074025006 0ustar alexxalexxuses GtkInt; doublecmd-0.8.2/components/lclextensions/include/qt/0000775000175000017500000000000013244011205021623 5ustar alexxalexxdoublecmd-0.8.2/components/lclextensions/include/qt/delphicompat.inc0000664000175000017500000000367512014201074025001 0ustar alexxalexx { Qt Interface Initial implementation by Zeljan Rikalo } {$define HAS_GETBKCOLOR} {$define HAS_GETTEXTEXTENTEXPOINT} {$define HAS_GETTEXTALIGN} {$define HAS_GETWINDOWDC} {$define HAS_OFFSETRGN} {$define HAS_SETBRUSHORGEX} {$i ../generic/stubs.inc} {$i ../generic/independentfunctions.inc} {$i ../generic/unicodefunctions.inc} function GetBkColor(DC:HDC):COLORREF; var Color: PQColor; begin if QtWidgetSet.IsValidDC(DC) then begin Color := TQtDeviceContext(DC).BackgroundBrush.getColor; TQColorToColorRef(Color^, Result); end else Result := CLR_INVALID; end; function GetTextExtentExPoint(DC: HDC; Str: PChar; Count, MaxWidth: Integer; MaxCount, PartialWidths: PInteger; var Size: TSize): BOOL; begin Result := QtWidgetSet.GetTextExtentExPoint(DC, Str, Count, MaxWidth, MaxCount, PartialWidths, Size); end; function GetTextAlign(hDC:HDC): LongWord; var QtDC: TQtDeviceContext; QtFontMetrics: QFontMetricsH; QtFont: QFontH; begin Result := 0; if not QtWidgetSet.IsValidDC(hdC) then Exit; QtDC := TQtDeviceContext(hDC); QtFont := QtDC.vFont.FHandle; QtFontMetrics := QFontMetrics_create(QtFont); try {TODO: FIXME we should save somehow text flags into QtDC cause we don't have any function which returns current flags !} finally QFontMetrics_destroy(QtFontMetrics); end; end; function GetWindowDC(hWnd:HWND): HDC; begin Result := LCLIntf.GetDC(hWnd); end; function OffsetRgn(hrgn:HRGN; nxOffset, nYOffset:longint):longint; var Region: TQtRegion; begin Region := TQtRegion(hrgn); QRegion_translate(Region.FHandle, nxOffset, nYOffset); Result := Region.GetRegionType; end; function SetBrushOrgEx(DC:HDC; nXOrg, nYOrg:longint; lppt:PPOINT):Boolean; var QtDC: TQtDeviceContext; begin Result := False; if not QtWidgetSet.IsValidDC(DC) then Exit; QtDC := TQtDeviceContext(DC); if lppt <> nil then QtDC.getBrushOrigin(lppt); QtDC.setBrushOrigin(nXorg, nYOrg); Result := True; end; doublecmd-0.8.2/components/lclextensions/include/qt/lclext.inc0000664000175000017500000000044712014201074023615 0ustar alexxalexxfunction DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean; begin //todo: see if is possible todo it faster Result := StretchMaskBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height, Mask, 0, 0, SRCCOPY); end; doublecmd-0.8.2/components/lclextensions/include/qt/uses.inc0000664000175000017500000000011412014201074023270 0ustar alexxalexx InterfaceBase, LCLIntf, Graphics, qt4, qtint, qtobjects, qtwidgets, Math, doublecmd-0.8.2/components/lclextensions/include/qt/uses_lclext.inc0000664000175000017500000000001712014201074024645 0ustar alexxalexxuses LclIntf;doublecmd-0.8.2/components/lclextensions/include/gtk2/0000775000175000017500000000000013244011205022046 5ustar alexxalexxdoublecmd-0.8.2/components/lclextensions/include/gtk2/delphicompat.inc0000664000175000017500000000634612203745772025244 0ustar alexxalexx{ This file is part of Delphi Compatibility Unit Copyright (C) 2007 Luiz Américo Pereira Câmara pascalive@bol.com.br This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version with the following modification: As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules,and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. } {$MACRO ON} {$define HAS_GETBKCOLOR} {$define HAS_GETTEXTEXTENTEXPOINT} {$i ../generic/stubs.inc} {$i ../generic/independentfunctions.inc} {$i ../generic/unicodefunctions.inc} procedure pango_extents_to_pixels (ink_rect: PPangoRectangle; logical_rect: PPangoRectangle); cdecl; external 'libpango-1.0.so.0'; function GetBkColor(DC:HDC):COLORREF; begin if GTK2WidgetSet.IsValidDC(DC) then Result := TGtkDeviceContext(DC).CurrentBackColor.ColorRef else Result := CLR_INVALID; end; function GetTextExtentExPoint(DC: HDC; Str: PChar; Count, MaxWidth: Integer; MaxCount, PartialWidths: PInteger; var Size: TSize): BOOL; var layout: PPangoLayout; i: Integer; Rect: TPangoRectangle; iter : PPangoLayoutIter; begin Result := GTK2WidgetSet.IsValidDC(DC); if Result then with TGtk2DeviceContext(DC) do begin if (CurrentFont = nil) or (CurrentFont^.GDIFontObject = nil) then layout := GTK2WidgetSet.GetDefaultGtkFont(false) else layout := CurrentFont^.GDIFontObject; pango_layout_set_text(layout, Str, Count); if PartialWidths = nil then pango_layout_get_pixel_size (layout, @Size.cx, @Size.cy) else begin i := 0; Size.cx := 0; Size.cy := 0; iter := pango_layout_get_iter(layout); repeat pango_layout_iter_get_char_extents(iter,@Rect); pango_extents_to_pixels(nil,@Rect); inc(Size.cx, Rect.Width); PartialWidths[i] := Size.cx; if Size.cy < Rect.Height then Size.cy := Rect.Height; inc(i); until not pango_layout_iter_next_char(iter); pango_layout_iter_free(iter); end; end; end; doublecmd-0.8.2/components/lclextensions/include/gtk2/lclext.inc0000664000175000017500000000047412014201074024040 0ustar alexxalexxfunction DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean; begin //todo: see if is possible todo it faster Result := GTK2WidgetSet.StretchCopyArea(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height, Mask, XSrc, YSrc, SRCCOPY); end; doublecmd-0.8.2/components/lclextensions/include/gtk2/uses.inc0000664000175000017500000000007712014201074023523 0ustar alexxalexx LCLIntf, Graphics, Gtk2Def, Gtk2Proc, Gtk2Int, pango, math, doublecmd-0.8.2/components/lclextensions/include/gtk2/uses_lclext.inc0000664000175000017500000000002012014201074025062 0ustar alexxalexxuses Gtk2Int; doublecmd-0.8.2/components/lclextensions/include/win32/0000775000175000017500000000000013244011205022141 5ustar alexxalexxdoublecmd-0.8.2/components/lclextensions/include/win32/delphicompat.inc0000664000175000017500000001275512014201074025316 0ustar alexxalexx { This file is part of Delphi Compatibility Unit Copyright (C) 2007 Luiz Américo Pereira Câmara pascalive@bol.com.br This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version with the following modification: As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules,and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. } function BeginDeferWindowPos(nNumWindows: longint): THandle; begin Result:=Windows.BeginDeferWindowPos(nNumWindows); end; function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Rop: DWORD): Boolean; begin Result := Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Rop); end; function CopyImage(hImage: THANDLE; uType: LongWord; cxDesired, cyDesired: LongInt; fuFlags: LongWord): THandle; begin Result := Windows.CopyImage(hImage,uType,cxDesired,cyDesired,fuFlags); end; function CreatePatternBrush(hbmp: HBITMAP): HBRUSH; begin Result := Windows.CreatePatternBrush(hbmp); end; function DeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter: THandle; x, y, cx, cy: longint; uFlags: LongWord): THandle; begin Result := Windows.DeferWindowPos(hWinPosInfo,hWnd,hWndInsertAfter,x,y,cx,cy,uFlags); end; function DrawFrameControl(DC: HDC; const Rect: TRect; uType, uState: LongWord): Boolean; begin Result := Windows.DrawFrameControl(DC,Rect,uType,uState); end; function EndDeferWindowPos(hWinPosInfo: THandle): Boolean; begin Result:=Windows.EndDeferWindowPos(hWinPosInfo); end; function GdiFlush: Boolean; begin Result := Windows.GdiFlush; end; function GetACP: LongWord; begin Result := Windows.GetACP; end; function GetBkColor(DC: HDC): LCLType.COLORREF; begin Result := Windows.GetBkColor(DC); end; function GetDCEx(hWnd: HWND; hrgnClip: HRGN; flags: DWORD): HDC; begin Result := Windows.GetDCEx(hWnd,hrgnClip,flags); end; function GetKeyboardLayout(dwLayout: DWORD): THandle; begin Result := Windows.GetKeyboardLayout(dwLayout); end; function GetKeyboardState(lpKeyState: PBYTE): BOOLEAN; begin Result := Windows.GetKeyboardState(lpKeyState); end; function GetLocaleInfo(Locale, LCType: LongWord; lpLCData: PChar; cchData: longint): longint; begin Result := Windows.GetLocaleInfo(Locale,LCType,lpLCData,cchData); end; function GetRandomRgn(DC: HDC; Rgn: HRGN; iNum: Integer): Integer; stdcall; external 'GDI32.DLL'; function GetTextAlign(hDC: HDC): LongWord; begin Result := Windows.GetTextAlign(hDC); end; function GetTextExtentExPoint(DC: LCLType.HDC; Str: PChar; Count, MaxWidth: Integer; MaxCount, PartialWidths: ObjPas.PInteger; var Size: TSize): BOOL; begin Result := Windows.GetTextExtentExPoint(DC, Str, Count, MaxWidth, MaxCount, PartialWidths, Size); end; function GetTextExtentPoint32W(DC: HDC; Str: PWideChar; Count: Integer; out Size: TSize): Boolean; begin Result := Windows.GetTextExtentPointW(DC, Str, Count, Size); end; function GetWindowDC(hWnd: HWND): HDC; begin Result := Windows.GetWindowDC(hWnd); end; function ImageList_DragShowNolock(fShow: Boolean): Boolean; begin Result := CommCtrl.ImageList_DragShowNolock(fShow); end; function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints; cPoints: UINT ): Integer; begin Result:=Windows.MapWindowPoints(hWndFrom,hWndTo,lpPoints,cPoints); end; function MultiByteToWideChar(CodePage, dwFlags: DWORD; lpMultiByteStr: PChar; cchMultiByte: longint; lpWideCharStr: PWideChar; cchWideChar: longint ): longint; begin Result := Windows.MultiByteToWideChar(CodePage,dwFlags,lpMultiByteStr,cchMultiByte,lpWideCharStr,cchWideChar); end; function OffsetRgn(hrgn: HRGN; nxOffset, nYOffset: longint): longint; begin Result := Windows.OffsetRgn(hrgn,nxOffset,nYOffset); end; function SetBrushOrgEx(DC: LCLType.HDC; nXOrg, nYOrg: longint; lppt: Types.PPoint): Boolean; begin Result := Windows.SetBrushOrgEx(DC,nXOrg,nYOrg,lppt); end; function ScrollDC(DC: LCLType.HDC; dx: longint; dy: longint; var lprcScroll: Types.TRect; var lprcClip: Types.TRect; hrgnUpdate: LCLType.HRGN; lprcUpdate: Types.PRect): Boolean; begin Result := Windows.ScrollDC(DC, dx, dy, lprcScroll, lprcClip, hrgnUpdate, lprcUpdate); end; function ToAscii(uVirtKey, uScanCode: LongWord; lpKeyState: PBYTE; lpChar: PWORD; uFlags: LongWord): longint; begin Result := Windows.ToAscii(uVirtKey,uScanCode,lpKeyState,lpChar,uFlags); end; doublecmd-0.8.2/components/lclextensions/include/win32/lclext.inc0000664000175000017500000000200712014201074024125 0ustar alexxalexxfunction DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean; var MaskDC: HDC; MaskObj: HGDIOBJ; PrevTextColor, PrevBkColor: COLORREF; begin //this is a stripped version of LCL.StretchMaskBlt if Mask <> 0 then begin MaskDC := Windows.CreateCompatibleDC(DestDC); MaskObj := Windows.SelectObject(MaskDC, Mask); PrevTextColor := Windows.SetTextColor(DestDC, $00000000); PrevBkColor := Windows.SetBkColor(DestDC, $00FFFFFF); Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, SRCINVERT); Windows.BitBlt(DestDC, X, Y, Width, Height, MaskDC, XSrc, YSrc, SRCAND); Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, SRCINVERT); Windows.SetTextColor(DestDC, PrevTextColor); Windows.SetBkColor(DestDC, PrevBkColor); Windows.SelectObject(MaskDC, MaskObj); Windows.DeleteDC(MaskDC); end else Result := Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, SRCCOPY); end; doublecmd-0.8.2/components/lclextensions/include/win32/uses.inc0000664000175000017500000000004212014201074023606 0ustar alexxalexx Windows, win32proc, CommCtrl, doublecmd-0.8.2/components/lclextensions/include/win32/uses_lclext.inc0000664000175000017500000000002412014201074025161 0ustar alexxalexx uses Windows; doublecmd-0.8.2/components/lclextensions/include/carbon/0000775000175000017500000000000013244011205022443 5ustar alexxalexxdoublecmd-0.8.2/components/lclextensions/include/carbon/delphicompat.inc0000664000175000017500000000071011751527542025626 0ustar alexxalexx { Carbon Interface Dummy implementation. Not tested. Waiting for someone with a Mac to implement it } { Only a few functions are necessary to compile VirtualTreeView: } {.$define HAS_GETTEXTEXTENTEXPOINT} {.$define HAS_GETTEXTALIGN} {.$define HAS_GETWINDOWDC} {.$define HAS_OFFSETRGN} {.$define HAS_SETBRUSHORGEX} {$i ../generic/stubs.inc} {$i ../generic/independentfunctions.inc} {$i ../generic/unicodefunctions.inc} doublecmd-0.8.2/components/lclextensions/include/carbon/lclext.inc0000664000175000017500000000044712014201074024435 0ustar alexxalexxfunction DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean; begin //todo: see if is possible todo it faster Result := StretchMaskBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height, Mask, 0, 0, SRCCOPY); end; doublecmd-0.8.2/components/lclextensions/include/carbon/uses.inc0000664000175000017500000000010212014201074024105 0ustar alexxalexx InterfaceBase, LCLIntf, Graphics, CarbonInt, CarbonCanvas, Math,doublecmd-0.8.2/components/lclextensions/include/carbon/uses_lclext.inc0000664000175000017500000000001712014201074025465 0ustar alexxalexxuses LclIntf;doublecmd-0.8.2/components/lclextensions/include/generic/0000775000175000017500000000000013244011205022613 5ustar alexxalexxdoublecmd-0.8.2/components/lclextensions/include/generic/independentfunctions.inc0000664000175000017500000000157112014201074027537 0ustar alexxalexx function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints; cPoints: UINT): Integer; var i: Integer; XOffset, YOffset: SmallInt; FromPoint, ToPoint: TPoint; begin FromPoint := Point(0, 0); ToPoint := Point(0, 0); if hWndFrom <> 0 then ClientToScreen(hWndFrom, FromPoint); if hWndTo <> 0 then ClientToScreen(hWndTo, ToPoint); XOffset := (FromPoint.X - ToPoint.X); YOffset := (FromPoint.Y - ToPoint.Y); for i := 0 to cPoints - 1 do begin PPoint(@lpPoints)[i].x := XOffset + PPoint(@lpPoints)[i].x; PPoint(@lpPoints)[i].y := YOffset + PPoint(@lpPoints)[i].y; end; Result := MakeLong(XOffset, YOffset); end; {$ifndef HAS_BITBLT} function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Rop: DWORD): Boolean; begin Result := LCLIntf.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Rop); end; {$endif} doublecmd-0.8.2/components/lclextensions/include/generic/unicodefunctions.inc0000664000175000017500000000202212014201074026660 0ustar alexxalexx { GetUTF8ByteCount returns the number of bytes necessary to hold the requested number of characters (count). Not necessarily the number of characters is equal to the widestring length but here we assume it to skip the extra overhead } //todo do a function that convert the str and the count at one pass function GetUTF8ByteCount(const UTF8Str: UTF8String; WideCount: Integer): Integer; var CharCount, CharLen, StrLen: Integer; P: PChar; begin Result := 0; CharCount := 0; P := PChar(UTF8Str); StrLen := Length(UTF8Str); WideCount := Min(WideCount, StrLen); while (CharCount < WideCount) do begin CharLen := UTF8CharacterLength(P); Inc(P, CharLen); Inc(Result, CharLen); Inc(CharCount); end; Result := Min(Result, StrLen); end; function GetTextExtentPoint32W(DC: HDC; Str: PWideChar; Count: Integer; out Size: TSize): Boolean; var TempStr: UTF8String; begin TempStr := UTF8Encode(WideString(Str)); Result := GetTextExtentPoint(DC, PChar(TempStr), GetUTF8ByteCount(TempStr, Count), Size); end; doublecmd-0.8.2/components/lclextensions/include/generic/stubs.inc0000664000175000017500000001036012140233030024442 0ustar alexxalexx function BeginDeferWindowPos(nNumWindows:longint):THandle; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; function CopyImage(hImage:THANDLE; uType:LongWord; cxDesired, cyDesired: LongInt; fuFlags:LongWord):THandle; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; function DeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter:THandle; x, y, cx, cy:longint; uFlags:LongWord):THandle; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; function EndDeferWindowPos(hWinPosInfo:THandle):Boolean; begin Result := False; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; function GdiFlush: Boolean; begin Result := False; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; function GetACP:LongWord; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; {$ifndef HAS_GETBKCOLOR} function GetBkColor(DC:HDC):COLORREF; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; {$endif} function GetDCEx(hWnd:HWND; hrgnClip:HRGN; flags:DWORD):HDC; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; function GetKeyboardLayout(dwLayout:DWORD):THandle; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; function GetKeyboardState(lpKeyState: System.PByte):BOOLEAN; begin Result := False; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; function GetLocaleInfo(Locale, LCType:LongWord; lpLCData:PChar; cchData:longint):longint; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; function GetRandomRgn(DC: HDC; Rgn: HRGN; iNum: Integer): Integer; stdcall; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; {$ifndef HAS_GETTEXTEXTENTEXPOINT} function GetTextExtentExPoint(DC: HDC; Str: PChar; Count, MaxWidth: Integer; MaxCount, PartialWidths: PInteger; var Size: TSize): BOOL; begin Result := LCLIntf.GetTextExtentExPoint(DC, Str, Count, MaxWidth, MaxCount, PartialWidths, Size); end; {$endif} {$ifndef HAS_GETTEXTALIGN} function GetTextAlign(hDC:HDC): LongWord; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; {$endif} {$ifndef HAS_GETWINDOWDC} function GetWindowDC(hWnd:HWND):HDC; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; {$endif} function ImageList_DragShowNolock(fShow: Boolean): Boolean; begin Result := False; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; function MultiByteToWideChar(CodePage, dwFlags:DWORD; lpMultiByteStr:PChar; cchMultiByte:longint; lpWideCharStr:PWideChar;cchWideChar:longint):longint; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; {$ifndef HAS_OFFSETRGN} function OffsetRgn(hrgn:HRGN; nxOffset, nYOffset:longint):longint; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; {$endif} function ScrollDC(DC:HDC; dx:longint; dy:longint; var lprcScroll:TRECT; var lprcClip:TRECT;hrgnUpdate:HRGN; lprcUpdate:PRECT):Boolean; begin Result := False; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; {$ifndef HAS_SETBRUSHORGEX} function SetBrushOrgEx(DC:HDC; nXOrg, nYOrg:longint; lppt:PPOINT):Boolean; begin Result := False; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; {$endif} function ToAscii(uVirtKey, uScanCode:LongWord; lpKeyState: System.PByte; lpChar: System.PWord; uFlags:LongWord):longint; begin Result := 0; {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif} end; doublecmd-0.8.2/components/lclextensions/readme.txt0000664000175000017500000000016712014201074021555 0ustar alexxalexxlclextensions v0.4 http://code.google.com/p/luipack/ Some modifications done so that it only compiles VirtualTreeView.doublecmd-0.8.2/components/lclextensions/oleutils.pas0000664000175000017500000001062312014201074022122 0ustar alexxalexxunit oleutils; { OLE helper functions Copyright (C) 2007 Luiz Amrico Pereira Cmara pascalive@bol.com.br This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version with the following modification: As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules,and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. } //todo: add error handling {$mode objfpc}{$H+} interface {$ifdef Windows} uses Windows, Classes, SysUtils, ActiveX; type { TOLEStream } TOLEStream = class (TStream) private FSrcStream: IStream; procedure InternalSetSize(NewSize: LARGE_INTEGER); public constructor Create(const Stream: IStream); function Read(var Buffer; Count: Integer): Integer; override; function Seek(Offset: Integer; Origin: Word): Integer; overload; override; procedure SetSize(const NewSize: Int64); override; procedure SetSize(NewSize: Longint); override; function Write(const Buffer; Count: Integer): Integer; override; end; {$endif} implementation {$ifdef Windows} function ErrorString(Error: HRESULT): String; begin case Error of E_PENDING: Result:='E_PENDING'; S_FALSE: Result:='S_FALSE'; STG_E_MEDIUMFULL: Result:='STG_E_MEDIUMFULL'; STG_E_ACCESSDENIED: Result:= 'STG_E_ACCESSDENIED'; STG_E_CANTSAVE: Result:='STG_E_CANTSAVE'; STG_E_INVALIDPOINTER: Result:='STG_E_INVALIDPOINTER'; STG_E_REVERTED: Result:='STG_E_REVERTED'; STG_E_WRITEFAULT: Result:='STG_E_WRITEFAULT'; STG_E_INVALIDFUNCTION: Result:='STG_E_INVALIDFUNCTION'; else Result:='Unknow error'; end; end; { TOLEStream } constructor TOLEStream.Create(const Stream: IStream); begin inherited Create; FSrcStream:=Stream; end; function TOLEStream.Read(var Buffer; Count: Integer): Integer; var Res: HRESULT; begin Res:=FSrcStream.Read(@Buffer, Count, @Result); if Res <> S_OK then Raise Exception.Create('TOLEStream - Error while reading: '+ErrorString(Res)); end; function TOLEStream.Seek(Offset: Integer; Origin: Word): Integer; var liResult, liOffset : LARGE_INTEGER; Res: HRESULT; begin //soFrom* constants are equal to STREAM_SEEK_* constants. Assume it here liOffset.LowPart:=Offset; liOffset.HighPart:=0; Res:=FSrcStream.Seek(Int64(liOffset), Origin, Int64(liResult)); Result:=liResult.LowPart; if Res <> S_OK then Raise Exception.Create('TOLEStream - Error while seeking: '+ErrorString(Res)); end; procedure TOLEStream.SetSize(NewSize: Longint); var liSize: LARGE_INTEGER; begin liSize.LowPart:=NewSize; liSize.HighPart:=0; InternalSetSize(liSize); end; procedure TOLEStream.SetSize(const NewSize: Int64); var liSize: LARGE_INTEGER; begin liSize.QuadPart:=NewSize; InternalSetSize(liSize); end; procedure TOLEStream.InternalSetSize(NewSize: LARGE_INTEGER); var Res:HRESULT; begin Res:=FSrcStream.SetSize(Int64(NewSize)); if Res <> S_OK then Raise Exception.Create('TOLEStream - Error while setting size: '+ErrorString(Res)); end; function TOLEStream.Write(const Buffer; Count: Integer): Integer; var Res: HRESULT; begin Res:=FSrcStream.Write(@Buffer,Count,@Result); if Res <> S_OK then Raise Exception.Create('TOLEStream - Error while writing: '+ErrorString(Res)); end; {$endif} end. doublecmd-0.8.2/components/lclextensions/lclext.pas0000664000175000017500000000350712014201074021560 0ustar alexxalexxunit LclExt; { LCL Extension Unit Copyright (C) 2007 Luiz Américo Pereira Câmara pascalive@bol.com.br This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version with the following modification: As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules,and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. } {$mode objfpc}{$H+} interface uses Classes, SysUtils, LCLType, Graphics; function DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean; implementation {$i uses_lclext.inc} {$i lclext.inc} end. doublecmd-0.8.2/components/lclextensions/lclextensions_package_doublecmd.lpk0000664000175000017500000000350411751527542026672 0ustar alexxalexx doublecmd-0.8.2/components/lclextensions/lclextensions_package_doublecmd.pas0000664000175000017500000000056512014201074026651 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit lclextensions_package_doublecmd; interface uses DelphiCompat, oleutils, LclExt, LazarusPackageIntf; implementation procedure Register; begin end; initialization RegisterPackage('lclextensions_package_doublecmd', @Register); end. doublecmd-0.8.2/components/chsdet/0000775000175000017500000000000013244011205016134 5ustar alexxalexxdoublecmd-0.8.2/components/chsdet/Licence.txt0000664000175000017500000005750512014201074020252 0ustar alexxalexx GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS doublecmd-0.8.2/components/chsdet/dcu/0000775000175000017500000000000013244011205016707 5ustar alexxalexxdoublecmd-0.8.2/components/chsdet/chsdet.pas0000664000175000017500000000114212677725617020145 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit chsdet; interface uses Big5Freq, CharDistribution, chsdIntf, CustomDetector, EUCKRFreq, EUCSampler, EUCTWFreq, GB2312Freq, JISFreq, JpCntx, MBUnicodeMultiProber, MultiModelProber, nsCodingStateMachine, nsCore, nsEscCharsetProber, nsGroupProber, nsHebrewProber, nsLatin1Prober, nsMBCSMultiProber, nsPkg, nsSBCharSetProber, nsSBCSGroupProber, nsUniversalDetector, LangBulgarianModel, LangCyrillicModel, LangGreekModel, LangHebrewModel; implementation end. doublecmd-0.8.2/components/chsdet/chsd_dll_intf.pas0000664000175000017500000000610412014201074021435 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: chsd_dll_intf.pas,v 1.4 2009/07/12 15:13:56 ya_nick Exp $ unit chsd_dll_intf; interface const NS_OK = 0; NS_ERROR_OUT_OF_MEMORY = $8007000e; type rCharsetInfo = record Name: pChar; CodePage: integer; Language: pChar; end; prCharsetInfo = ^rCharsetInfo; rAboutHolder = record MajorVersionNr: Cardinal; MinorVersionNr: Cardinal; BuildVersionNr: Cardinal; About: pChar; end; eBOMKind =( BOM_Not_Found, BOM_UCS4_BE, // 00 00 FE FF UCS-4, big-endian machine (1234 order) BOM_UCS4_LE, // FF FE 00 00 UCS-4, little-endian machine (4321 order) BOM_UCS4_2143, // 00 00 FF FE UCS-4, unusual octet order (2143) BOM_UCS4_3412, // FE FF 00 00 UCS-4, unusual octet order (3412) BOM_UTF16_BE, // FE FF ## ## UTF-16, big-endian BOM_UTF16_LE, // FF FE ## ## UTF-16, little-endian BOM_UTF8 // EF BB BF UTF-8 ); const CharsetDetectorLibrary = 'chsdet.dll'; procedure csd_Reset; stdcall; external CharsetDetectorLibrary; function csd_HandleData(aBuf: PChar; aLen: integer): integer; stdcall; external CharsetDetectorLibrary; function csd_Done: Boolean; stdcall; external CharsetDetectorLibrary; procedure csd_DataEnd; stdcall; external CharsetDetectorLibrary; function csd_GetDetectedCharset: rCharsetInfo; stdcall; external CharsetDetectorLibrary; procedure csd_GetKnownCharsets(var KnownCharsets: pChar); stdcall; external CharsetDetectorLibrary; procedure csd_GetAbout(var About: rAboutHolder); stdcall; external CharsetDetectorLibrary; function csd_GetDetectedBOM: eBOMKind; stdcall; external CharsetDetectorLibrary; procedure csd_DisableCharsetCP(CodePage: integer); stdcall; external CharsetDetectorLibrary; implementation end. doublecmd-0.8.2/components/chsdet/chsdet.lpk0000664000175000017500000001545112144672601020137 0ustar alexxalexx doublecmd-0.8.2/components/chsdet/ReadMe.txt0000664000175000017500000001374712014201074020045 0ustar alexxalexx-----------Summary Charset Detector - as the name says - is a stand alone executable module for automatic charset detection of a given text. It can be useful for internationalisation support in multilingual applications such as web-script editors or Unicode editors. Given input buffer will be analysed to guess used encoding. The result can be used as control parameter for charset conversation procedure. Charset Detector can be compiled (and hopefully used) for MS Windows (as dll - dynamic link library) or Linux. Based on Mozilla's i18n component - http://www.mozilla.org/projects/intl/. -----------State Version 0.2.6 stable. The latest version can be found at http://chsdet.sourceforge.net. -----------Requirements Charset Detector doesn't need any external components. -----------Output As result you will get guessed charset as MS Windows Code Page id and charset name. -----------Licence Charset Detector is open source project and distributed under Lesser GPL. See the GNU Lesser General Public License for more details - http://www.opensource.org/licenses/lgpl-license.php -----------Supported charsets +-----------+---------------------------+------------------------+ | Code pade | Name | Note | +-----------+---------------------------+------------------------+ | 0 | ASCII | Pseudo code page. | | 855 | IBM855 | | | 866 | IBM866 | | | 932 | Shift_JIS | | | 950 | Big5 | | | 1200 | UTF-16LE | | | 1201 | UTF-16BE | | | 1251 | windows-1251 | | | 1252 | windows-1252 | | | 1253 | windows-1253 | | | 1255 | windows-1255 | | | 10007 | x-mac-cyrillic | | | 12000 | X-ISO-10646-UCS-4-2143 | | | 12000 | UTF-32LE | MS Windows hasn't CP.| | | | Try to use USC-4. | | 12001 | X-ISO-10646-UCS-4-3412 | | | 12001 | UTF-32BE | MS Windows hasn't CP.| | | | Try to use USC-4. | | 20866 | KOI8-R | | | 28595 | ISO-8859-5 | | | 28595 | ISO-8859-5 | | | 28597 | ISO-8859-7 | | | 28598 | ISO-8859-8 | | | 50222 | ISO-2022-JP | | | 50225 | ISO-2022-KR | | | 50227 | ISO-2022-CN | | | 51932 | EUC-JP | | | 51936 | x-euc-tw | | | 51949 | EUC-KR | | | 52936 | HZ-GB-2312 | | | 54936 | GB18030 | | | 65001 | UTF-8 | | +-----------+---------------------------+------------------------+ -----------Types Return values NS_OK = 0; NS_ERROR_OUT_OF_MEMORY = $8007000e; Returned types rCharsetInfo = record Name: pChar; // charset GNU canonical name CodePage: integer; // MS Windows CodePage id Language: pChar; // end; rAboutHolder = record MajorVersionNr: Cardinal; // Library's Major Version # MinorVersionNr: Cardinal; // Library's Minor Version # BuildVersionNr: Cardinal; // Library's Build/Release Version # About: pChar; // Copyleft information; end; -----------Exported functions procedure chsd_Reset; stdcall; Reset Charset Detector state. Prepare to new analyse. function chsd_HandleData(aBuf: PChar; aLen: integer): integer; stdcall; Analyse given buffer. Parameters aBuf - pointer to buffer with text. sLen - buffer length; Return value NS_ERROR_OUT_OF_MEMORY - failure. Unable to create internal objects. NS_OK - success. Note Function can be called more that one time to continue guessing. Charset Detector remember last state until chsd_Reset called. function chsd_Done: Boolean; stdcall; Return value TRUE - Charset Detector is sure about text encoding. FALSE - Overwise. Note If input buffer is smaller then 1K Charset Detector returns anyway FALSE. procedure chsd_DataEnd; stdcall; Signalise data end. If Charset Detector hasn't sure result (Done = FALSE) the best guessed encoding will be set as result. function chsd_GetDetectedCharset: rCharsetInfo; stdcall; Returns guessed charset. procedure chsd_GetKnownCharsets(var KnownCharsets: pChar); Fills the parameter with all supported charsets in form "CodePage - Name LineFeed". procedure chsd_GetAbout(var About: rAboutHolder); stdcall; Fills the parameter with version and copyleft information. -----------Sample The definition file "chsd_dll_intf.pas" can be found in the same direcory. Bellow is small usage sample. // WS: WideString; // Wide string which can be used in Unicode controls. // Get encoding of some buffer chsd_Reset; chsd_HandleData(aBuf, aLen); if not chsd_Done then chsd_DataEnd; ChSInfo := chsd_GetDetectedCharset(); // convert buffer to WideString OutputLength := MultiByteToWideChar(ChSInfo.CodePage, 0, aBuf, aLen, nil, 0); SetLength(WS, OutputLength); MultiByteToWideChar(ChSInfo.CodePage, 0, aBuf, aLen, PWideChar(WS), OutputLength); // If you using Unicode SynEdit SynEdit.Lines.Text := WS; Nikolaj Yakowlew 2006-2008 doublecmd-0.8.2/components/chsdet/src/0000775000175000017500000000000013244011205016723 5ustar alexxalexxdoublecmd-0.8.2/components/chsdet/src/EUCTWFreq.pas0000664000175000017500000010627212014201074021144 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: EUCTWFreq.pas,v 1.2 2007/05/20 15:46:04 ya_nick Exp $ unit EUCTWFreq; // EUCTW frequency table // Converted from big5 work // by Taiwan's Mandarin Promotion Council // (****************************************************************************** * 128 --> 0.42261 * 256 --> 0.57851 * 512 --> 0.74851 * 1024 --> 0.89384 * 2048 --> 0.97583 * * Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 * Random Distribution Ration = 512/(5401-512)=0.105 * * Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR *****************************************************************************) interface uses nsCore; const EUCTW_TYPICAL_DISTRIBUTION_RATIO: float = 0.75; //Char to FreqOrder table , EUCTW_TABLE_SIZE = 8102-2742+16; EUCTWCharToFreqOrder: array [0..EUCTW_TABLE_SIZE-1] of PRInt16 = ( 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, // 2742 3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, // 2758 1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, // 2774 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, // 2790 3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, // 2806 4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, // 2822 7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, // 2838 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, // 2854 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, // 2870 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, // 2886 2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, // 2902 1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, // 2918 3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, // 2934 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, // 2950 1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, // 2966 3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, // 2982 2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, // 2998 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, // 3014 3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, // 3030 1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, // 3046 7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, // 3062 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, // 3078 7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, // 3094 1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, // 3110 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, // 3126 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, // 3142 3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, // 3158 3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, // 3174 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, // 3190 2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, // 3206 2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, // 3222 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, // 3238 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, // 3254 3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, // 3270 1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, // 3286 1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, // 3302 1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, // 3318 2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, // 3334 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, // 3350 4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, // 3366 1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, // 3382 7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, // 3398 2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, // 3414 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, // 3430 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, // 3446 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, // 3462 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, // 3478 7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, // 3494 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, // 3510 1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, // 3526 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, // 3542 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, // 3558 7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, // 3574 1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, // 3590 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, // 3606 3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, // 3622 4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, // 3638 3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, // 3654 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, // 3670 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, // 3686 1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, // 3702 4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, // 3718 3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, // 3734 3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, // 3750 2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, // 3766 7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, // 3782 3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, // 3798 7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, // 3814 1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, // 3830 2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, // 3846 1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, // 3862 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, // 3878 1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, // 3894 4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, // 3910 3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, // 3926 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, // 3942 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, // 3958 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, // 3974 2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, // 3990 7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, // 4006 1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, // 4022 2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, // 4038 1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, // 4054 1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, // 4070 7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, // 4086 7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, // 4102 7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, // 4118 3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, // 4134 4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, // 4150 1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, // 4166 7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, // 4182 2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, // 4198 7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, // 4214 3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, // 4230 3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, // 4246 7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, // 4262 2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, // 4278 7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, // 4294 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, // 4310 4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, // 4326 2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, // 4342 7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, // 4358 3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, // 4374 2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, // 4390 2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, // 4406 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, // 4422 2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, // 4438 1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, // 4454 1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, // 4470 2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, // 4486 1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, // 4502 7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, // 4518 7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, // 4534 2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, // 4550 4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, // 4566 1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, // 4582 7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, // 4598 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, // 4614 4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, // 4630 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, // 4646 2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, // 4662 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, // 4678 1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, // 4694 1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, // 4710 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, // 4726 3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, // 4742 3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, // 4758 1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, // 4774 3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, // 4790 7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, // 4806 7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, // 4822 1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, // 4838 2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, // 4854 1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, // 4870 3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, // 4886 2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, // 4902 3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, // 4918 2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, // 4934 4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, // 4950 4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, // 4966 3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, // 4982 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, // 4998 3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, // 5014 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, // 5030 3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, // 5046 3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, // 5062 3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, // 5078 1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, // 5094 7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, // 5110 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, // 5126 7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, // 5142 1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, // 5158 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, // 5174 4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, // 5190 3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, // 5206 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, // 5222 2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, // 5238 2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, // 5254 3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, // 5270 1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, // 5286 4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, // 5302 2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, // 5318 1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, // 5334 1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, // 5350 2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, // 5366 3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, // 5382 1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, // 5398 7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, // 5414 1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, // 5430 4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, // 5446 1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, // 5462 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, // 5478 1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, // 5494 3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, // 5510 3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, // 5526 2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, // 5542 1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, // 5558 4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, // 5574 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, // 5590 7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, // 5606 2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, // 5622 3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, // 5638 4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, // 5654 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, // 5670 7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, // 5686 7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, // 5702 1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, // 5718 4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, // 5734 3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, // 5750 2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, // 5766 3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, // 5782 3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, // 5798 2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, // 5814 1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, // 5830 4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, // 5846 3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, // 5862 3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, // 5878 2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, // 5894 4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, // 5910 7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, // 5926 3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, // 5942 2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, // 5958 3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, // 5974 1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, // 5990 2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, // 6006 3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, // 6022 4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, // 6038 2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, // 6054 2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, // 6070 7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, // 6086 1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, // 6102 2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, // 6118 1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, // 6134 3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, // 6150 4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, // 6166 2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, // 6182 3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, // 6198 3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, // 6214 2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, // 6230 4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, // 6246 2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, // 6262 3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, // 6278 4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, // 6294 7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, // 6310 3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, // 6326 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, // 6342 1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, // 6358 4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, // 6374 1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, // 6390 4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, // 6406 7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, // 6422 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, // 6438 7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, // 6454 2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, // 6470 1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, // 6486 1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, // 6502 3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, // 6518 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, // 6534 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, // 6550 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, // 6566 3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, // 6582 2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, // 6598 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, // 6614 7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, // 6630 1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, // 6646 3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, // 6662 7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, // 6678 1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, // 6694 7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, // 6710 4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, // 6726 1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, // 6742 2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, // 6758 2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, // 6774 4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, // 6790 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, // 6806 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, // 6822 3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, // 6838 3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, // 6854 1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, // 6870 2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, // 6886 7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, // 6902 1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, // 6918 1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, // 6934 3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, // 6950 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, // 6966 1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, // 6982 4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, // 6998 7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, // 7014 2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, // 7030 3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, // 7046 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, // 7062 1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, // 7078 2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, // 7094 2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, // 7110 7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, // 7126 7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, // 7142 7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, // 7158 2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, // 7174 2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, // 7190 1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, // 7206 4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, // 7222 3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, // 7238 3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, // 7254 4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, // 7270 4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, // 7286 2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, // 7302 2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, // 7318 7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, // 7334 4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, // 7350 7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, // 7366 2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, // 7382 1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, // 7398 3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, // 7414 4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, // 7430 2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, // 7446 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, // 7462 2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, // 7478 1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, // 7494 2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, // 7510 2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, // 7526 4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, // 7542 7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, // 7558 1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, // 7574 3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, // 7590 7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, // 7606 1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, // 7622 8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, // 7638 2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, // 7654 8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, // 7670 2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, // 7686 2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, // 7702 8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, // 7718 8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, // 7734 8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, // 7750 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, // 7766 8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, // 7782 4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, // 7798 3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, // 7814 8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, // 7830 1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, // 7846 8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, // 7862 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, // 7878 1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, // 7894 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, // 7910 4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, // 7926 1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, // 7942 4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, // 7958 1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, // 7974 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, // 7990 3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, // 8006 4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, // 8022 8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, // 8038 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, // 8054 3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, // 8070 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, // 8086 2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118 // 8102 (*************************************************************************************** *Everything below is of no interest for detection purpose * *************************************************************************************** 2515,1613,4582,8119,3312,3866,2516,8120,4058,8121,1637,4059,2466,4583,3867,8122, // 8118 2493,3016,3734,8123,8124,2192,8125,8126,2162,8127,8128,8129,8130,8131,8132,8133, // 8134 8134,8135,8136,8137,8138,8139,8140,8141,8142,8143,8144,8145,8146,8147,8148,8149, // 8150 8150,8151,8152,8153,8154,8155,8156,8157,8158,8159,8160,8161,8162,8163,8164,8165, // 8166 8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181, // 8182 8182,8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197, // 8198 8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,8213, // 8214 8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229, // 8230 8230,8231,8232,8233,8234,8235,8236,8237,8238,8239,8240,8241,8242,8243,8244,8245, // 8246 8246,8247,8248,8249,8250,8251,8252,8253,8254,8255,8256,8257,8258,8259,8260,8261, // 8262 8262,8263,8264,8265,8266,8267,8268,8269,8270,8271,8272,8273,8274,8275,8276,8277, // 8278 8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,8290,8291,8292,8293, // 8294 8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,8308,8309, // 8310 8310,8311,8312,8313,8314,8315,8316,8317,8318,8319,8320,8321,8322,8323,8324,8325, // 8326 8326,8327,8328,8329,8330,8331,8332,8333,8334,8335,8336,8337,8338,8339,8340,8341, // 8342 8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356,8357, // 8358 8358,8359,8360,8361,8362,8363,8364,8365,8366,8367,8368,8369,8370,8371,8372,8373, // 8374 8374,8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389, // 8390 8390,8391,8392,8393,8394,8395,8396,8397,8398,8399,8400,8401,8402,8403,8404,8405, // 8406 8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421, // 8422 8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434,8435,8436,8437, // 8438 8438,8439,8440,8441,8442,8443,8444,8445,8446,8447,8448,8449,8450,8451,8452,8453, // 8454 8454,8455,8456,8457,8458,8459,8460,8461,8462,8463,8464,8465,8466,8467,8468,8469, // 8470 8470,8471,8472,8473,8474,8475,8476,8477,8478,8479,8480,8481,8482,8483,8484,8485, // 8486 8486,8487,8488,8489,8490,8491,8492,8493,8494,8495,8496,8497,8498,8499,8500,8501, // 8502 8502,8503,8504,8505,8506,8507,8508,8509,8510,8511,8512,8513,8514,8515,8516,8517, // 8518 8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8533, // 8534 8534,8535,8536,8537,8538,8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8549, // 8550 8550,8551,8552,8553,8554,8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,8565, // 8566 8566,8567,8568,8569,8570,8571,8572,8573,8574,8575,8576,8577,8578,8579,8580,8581, // 8582 8582,8583,8584,8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597, // 8598 8598,8599,8600,8601,8602,8603,8604,8605,8606,8607,8608,8609,8610,8611,8612,8613, // 8614 8614,8615,8616,8617,8618,8619,8620,8621,8622,8623,8624,8625,8626,8627,8628,8629, // 8630 8630,8631,8632,8633,8634,8635,8636,8637,8638,8639,8640,8641,8642,8643,8644,8645, // 8646 8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,8657,8658,8659,8660,8661, // 8662 8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672,8673,8674,8675,8676,8677, // 8678 8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,8690,8691,8692,8693, // 8694 8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,8705,8706,8707,8708,8709, // 8710 8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,8720,8721,8722,8723,8724,8725, // 8726 8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,8736,8737,8738,8739,8740,8741, // 8742 //13973 ****************************************************************************************) ); implementation end. doublecmd-0.8.2/components/chsdet/src/Big5Freq.pas0000664000175000017500000024436212014201074021046 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: Big5Freq.pas,v 1.2 2007/05/20 15:46:02 ya_nick Exp $ unit Big5Freq; // Big5 frequency table // by Taiwan's Mandarin Promotion Council // (****************************************************************************** * 128 --> 0.42261 * 256 --> 0.57851 * 512 --> 0.74851 * 1024 --> 0.89384 * 2048 --> 0.97583 * * Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 * Random Distribution Ration = 512/(5401-512)=0.105 * * Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR *****************************************************************************) interface uses nsCore; const BIG5_TYPICAL_DISTRIBUTION_RATIO: float = 0.75; //Char to FreqOrder table , BIG5_TABLE_SIZE = 5376; Big5CharToFreqOrder: array [0..BIG5_TABLE_SIZE-1] of PRInt16 = ( 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, // 16 3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, // 32 1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, // 48 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, // 64 3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, // 80 4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, // 96 5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, // 112 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, // 128 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, // 144 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, // 160 2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, // 176 1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, // 192 3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, // 208 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, // 224 1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, // 240 3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, // 256 2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, // 272 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, // 288 3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, // 304 1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, // 320 5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, // 336 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, // 352 5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, // 368 1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, // 384 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, // 400 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, // 416 3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, // 432 3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, // 448 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, // 464 2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, // 480 2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, // 496 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, // 512 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, // 528 3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, // 544 1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, // 560 1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, // 576 1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, // 592 2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, // 608 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, // 624 4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, // 640 1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, // 656 5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, // 672 2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, // 688 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, // 704 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, // 720 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, // 736 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, // 752 5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, // 768 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, // 784 1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, // 800 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, // 816 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, // 832 5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, // 848 1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, // 864 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, // 880 3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, // 896 4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, // 912 3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, // 928 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, // 944 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, // 960 1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, // 976 4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, // 992 3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, // 1008 3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, // 1024 2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, // 1040 5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, // 1056 3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, // 1072 5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, // 1088 1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, // 1104 2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, // 1120 1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, // 1136 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, // 1152 1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, // 1168 4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, // 1184 3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, // 1200 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, // 1216 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, // 1232 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, // 1248 2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, // 1264 5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, // 1280 1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, // 1296 2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, // 1312 1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, // 1328 1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, // 1344 5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, // 1360 5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, // 1376 5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, // 1392 3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, // 1408 4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, // 1424 4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, // 1440 2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, // 1456 5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, // 1472 3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, // 1488 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, // 1504 5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, // 1520 5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, // 1536 1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, // 1552 2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, // 1568 3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, // 1584 4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, // 1600 5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, // 1616 3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, // 1632 4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, // 1648 1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, // 1664 1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, // 1680 4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, // 1696 1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, // 1712 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, // 1728 1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, // 1744 1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, // 1760 3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, // 1776 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, // 1792 5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, // 1808 2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, // 1824 1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, // 1840 1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, // 1856 5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, // 1872 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, // 1888 4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, // 1904 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, // 1920 2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, // 1936 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, // 1952 1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, // 1968 1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, // 1984 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, // 2000 4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, // 2016 4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, // 2032 1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, // 2048 3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, // 2064 5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, // 2080 5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, // 2096 1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, // 2112 2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, // 2128 1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, // 2144 3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, // 2160 2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, // 2176 3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, // 2192 2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, // 2208 4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, // 2224 4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, // 2240 3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, // 2256 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, // 2272 3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, // 2288 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, // 2304 3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, // 2320 4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, // 2336 3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, // 2352 1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, // 2368 5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, // 2384 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, // 2400 5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, // 2416 1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, // 2432 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, // 2448 4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, // 2464 4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, // 2480 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, // 2496 2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, // 2512 2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, // 2528 3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, // 2544 1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, // 2560 4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, // 2576 2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, // 2592 1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, // 2608 1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, // 2624 2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, // 2640 3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, // 2656 1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, // 2672 5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, // 2688 1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, // 2704 4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, // 2720 1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, // 2736 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, // 2752 1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, // 2768 4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, // 2784 4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, // 2800 2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, // 2816 1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, // 2832 4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, // 2848 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, // 2864 5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, // 2880 2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, // 2896 3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, // 2912 4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, // 2928 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, // 2944 5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, // 2960 5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, // 2976 1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, // 2992 4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, // 3008 4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, // 3024 2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, // 3040 3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, // 3056 3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, // 3072 2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, // 3088 1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, // 3104 4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, // 3120 3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, // 3136 3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, // 3152 2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, // 3168 4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, // 3184 5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, // 3200 3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, // 3216 2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, // 3232 3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, // 3248 1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, // 3264 2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, // 3280 3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, // 3296 4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, // 3312 2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, // 3328 2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, // 3344 5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, // 3360 1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, // 3376 2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, // 3392 1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, // 3408 3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, // 3424 4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, // 3440 2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, // 3456 3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, // 3472 3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, // 3488 2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, // 3504 4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, // 3520 2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, // 3536 3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, // 3552 4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, // 3568 5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, // 3584 3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, // 3600 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, // 3616 1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, // 3632 4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, // 3648 1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, // 3664 4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, // 3680 5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, // 3696 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, // 3712 5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, // 3728 5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, // 3744 2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, // 3760 3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, // 3776 2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, // 3792 2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, // 3808 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, // 3824 1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, // 3840 4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, // 3856 3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, // 3872 3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, // 3888 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, // 3904 2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, // 3920 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, // 3936 2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, // 3952 4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, // 3968 1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, // 3984 4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, // 4000 1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, // 4016 3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, // 4032 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, // 4048 3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, // 4064 5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, // 4080 5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, // 4096 3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, // 4112 3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, // 4128 1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, // 4144 2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, // 4160 5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, // 4176 1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, // 4192 1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, // 4208 3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, // 4224 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, // 4240 1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, // 4256 4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, // 4272 5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, // 4288 2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, // 4304 3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, // 4320 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, // 4336 1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, // 4352 2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, // 4368 2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, // 4384 5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, // 4400 5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, // 4416 5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, // 4432 2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, // 4448 2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, // 4464 1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, // 4480 4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, // 4496 3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, // 4512 3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, // 4528 4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, // 4544 4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, // 4560 2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, // 4576 2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, // 4592 5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, // 4608 4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, // 4624 5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, // 4640 4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, // 4656 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, // 4672 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, // 4688 1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, // 4704 3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, // 4720 4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, // 4736 1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, // 4752 5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, // 4768 2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, // 4784 2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, // 4800 3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, // 4816 5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, // 4832 1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, // 4848 3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, // 4864 5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, // 4880 1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, // 4896 5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, // 4912 2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, // 4928 3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, // 4944 2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, // 4960 3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, // 4976 3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, // 4992 3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, // 5008 4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, // 5024 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, // 5040 2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, // 5056 4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, // 5072 3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, // 5088 5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, // 5104 1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, // 5120 5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, // 5136 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, // 5152 1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, // 5168 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, // 5184 4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, // 5200 1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, // 5216 4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, // 5232 1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, // 5248 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, // 5264 3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, // 5280 4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, // 5296 5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, // 5312 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, // 5328 3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, // 5344 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, // 5360 2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798 // 5376 //last 512 (*************************************************************************************** *Everything below is of no interest for detection purpose * *************************************************************************************** 2522,1613,4812,5799,3345,3945,2523,5800,4162,5801,1637,4163,2471,4813,3946,5802, // 5392 2500,3034,3800,5803,5804,2195,4814,5805,2163,5806,5807,5808,5809,5810,5811,5812, // 5408 5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828, // 5424 5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844, // 5440 5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,5859,5860, // 5456 5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,5875,5876, // 5472 5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,5889,5890,5891,5892, // 5488 5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905,5906,5907,5908, // 5504 5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920,5921,5922,5923,5924, // 5520 5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5938,5939,5940, // 5536 5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952,5953,5954,5955,5956, // 5552 5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968,5969,5970,5971,5972, // 5568 5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984,5985,5986,5987,5988, // 5584 5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004, // 5600 6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020, // 5616 6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036, // 5632 6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052, // 5648 6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068, // 5664 6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084, // 5680 6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100, // 5696 6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116, // 5712 6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,6132, // 5728 6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,6145,6146,6147,6148, // 5744 6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163,6164, // 5760 6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179,6180, // 5776 6181,6182,6183,6184,6185,6186,6187,6188,6189,6190,6191,6192,6193,6194,6195,6196, // 5792 6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212, // 5808 6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,3670,6224,6225,6226,6227, // 5824 6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243, // 5840 6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259, // 5856 6260,6261,6262,6263,6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275, // 5872 6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,4815,6286,6287,6288,6289,6290, // 5888 6291,6292,4816,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305, // 5904 6306,6307,6308,6309,6310,6311,4817,4818,6312,6313,6314,6315,6316,6317,6318,4819, // 5920 6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334, // 5936 6335,6336,6337,4820,6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349, // 5952 6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365, // 5968 6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381, // 5984 6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397, // 6000 6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,3441,6411,6412, // 6016 6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,4440,6426,6427, // 6032 6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443, // 6048 6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,4821,6455,6456,6457,6458, // 6064 6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,6474, // 6080 6475,6476,6477,3947,3948,6478,6479,6480,6481,3272,4441,6482,6483,6484,6485,4442, // 6096 6486,6487,6488,6489,6490,6491,6492,6493,6494,6495,6496,4822,6497,6498,6499,6500, // 6112 6501,6502,6503,6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516, // 6128 6517,6518,6519,6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532, // 6144 6533,6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548, // 6160 6549,6550,6551,6552,6553,6554,6555,6556,2784,6557,4823,6558,6559,6560,6561,6562, // 6176 6563,6564,6565,6566,6567,6568,6569,3949,6570,6571,6572,4824,6573,6574,6575,6576, // 6192 6577,6578,6579,6580,6581,6582,6583,4825,6584,6585,6586,3950,2785,6587,6588,6589, // 6208 6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605, // 6224 6606,6607,6608,6609,6610,6611,6612,4826,6613,6614,6615,4827,6616,6617,6618,6619, // 6240 6620,6621,6622,6623,6624,6625,4164,6626,6627,6628,6629,6630,6631,6632,6633,6634, // 6256 3547,6635,4828,6636,6637,6638,6639,6640,6641,6642,3951,2984,6643,6644,6645,6646, // 6272 6647,6648,6649,4165,6650,4829,6651,6652,4830,6653,6654,6655,6656,6657,6658,6659, // 6288 6660,6661,6662,4831,6663,6664,6665,6666,6667,6668,6669,6670,6671,4166,6672,4832, // 6304 3952,6673,6674,6675,6676,4833,6677,6678,6679,4167,6680,6681,6682,3198,6683,6684, // 6320 6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,4834,6698,6699, // 6336 6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,6715, // 6352 6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731, // 6368 6732,6733,6734,4443,6735,6736,6737,6738,6739,6740,6741,6742,6743,6744,6745,4444, // 6384 6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761, // 6400 6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777, // 6416 6778,6779,6780,6781,4168,6782,6783,3442,6784,6785,6786,6787,6788,6789,6790,6791, // 6432 4169,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806, // 6448 6807,6808,6809,6810,6811,4835,6812,6813,6814,4445,6815,6816,4446,6817,6818,6819, // 6464 6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833,6834,6835, // 6480 3548,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,4836,6847,6848,6849, // 6496 6850,6851,6852,6853,6854,3953,6855,6856,6857,6858,6859,6860,6861,6862,6863,6864, // 6512 6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,3199,6878,6879, // 6528 6880,6881,6882,4447,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,6894, // 6544 6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,4170,6905,6906,6907,6908,6909, // 6560 6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923,6924,6925, // 6576 6926,6927,4837,6928,6929,6930,6931,6932,6933,6934,6935,6936,3346,6937,6938,4838, // 6592 6939,6940,6941,4448,6942,6943,6944,6945,6946,4449,6947,6948,6949,6950,6951,6952, // 6608 6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968, // 6624 6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,6984, // 6640 6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,3671,6995,6996,6997,6998,4839, // 6656 6999,7000,7001,7002,3549,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013, // 6672 7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,7029, // 6688 7030,4840,7031,7032,7033,7034,7035,7036,7037,7038,4841,7039,7040,7041,7042,7043, // 6704 7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059, // 6720 7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,2985,7071,7072,7073,7074, // 6736 7075,7076,7077,7078,7079,7080,4842,7081,7082,7083,7084,7085,7086,7087,7088,7089, // 6752 7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105, // 6768 7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,4450,7119,7120, // 6784 7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136, // 6800 7137,7138,7139,7140,7141,7142,7143,4843,7144,7145,7146,7147,7148,7149,7150,7151, // 6816 7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167, // 6832 7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183, // 6848 7184,7185,7186,7187,7188,4171,4172,7189,7190,7191,7192,7193,7194,7195,7196,7197, // 6864 7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213, // 6880 7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229, // 6896 7230,7231,7232,7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245, // 6912 7246,7247,7248,7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261, // 6928 7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277, // 6944 7278,7279,7280,7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293, // 6960 7294,7295,7296,4844,7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308, // 6976 7309,7310,7311,7312,7313,7314,7315,7316,4451,7317,7318,7319,7320,7321,7322,7323, // 6992 7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339, // 7008 7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,4173,7354, // 7024 7355,4845,7356,7357,7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369, // 7040 7370,7371,7372,7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385, // 7056 7386,7387,7388,4846,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400, // 7072 7401,7402,7403,7404,7405,3672,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415, // 7088 7416,7417,7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431, // 7104 7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447, // 7120 7448,7449,7450,7451,7452,7453,4452,7454,3200,7455,7456,7457,7458,7459,7460,7461, // 7136 7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,4847,7475,7476, // 7152 7477,3133,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491, // 7168 7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,3347,7503,7504,7505,7506, // 7184 7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,4848, // 7200 7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537, // 7216 7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,3801,4849,7550,7551, // 7232 7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567, // 7248 7568,7569,3035,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582, // 7264 7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598, // 7280 7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614, // 7296 7615,7616,4850,7617,7618,3802,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628, // 7312 7629,7630,7631,7632,4851,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643, // 7328 7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659, // 7344 7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,7670,4453,7671,7672,7673,7674, // 7360 7675,7676,7677,7678,7679,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690, // 7376 7691,7692,7693,7694,7695,7696,7697,3443,7698,7699,7700,7701,7702,4454,7703,7704, // 7392 7705,7706,7707,7708,7709,7710,7711,7712,7713,2472,7714,7715,7716,7717,7718,7719, // 7408 7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,3954,7732,7733,7734, // 7424 7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750, // 7440 3134,7751,7752,4852,7753,7754,7755,4853,7756,7757,7758,7759,7760,4174,7761,7762, // 7456 7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778, // 7472 7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794, // 7488 7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,4854,7806,7807,7808,7809, // 7504 7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825, // 7520 4855,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840, // 7536 7841,7842,7843,7844,7845,7846,7847,3955,7848,7849,7850,7851,7852,7853,7854,7855, // 7552 7856,7857,7858,7859,7860,3444,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870, // 7568 7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886, // 7584 7887,7888,7889,7890,7891,4175,7892,7893,7894,7895,7896,4856,4857,7897,7898,7899, // 7600 7900,2598,7901,7902,7903,7904,7905,7906,7907,7908,4455,7909,7910,7911,7912,7913, // 7616 7914,3201,7915,7916,7917,7918,7919,7920,7921,4858,7922,7923,7924,7925,7926,7927, // 7632 7928,7929,7930,7931,7932,7933,7934,7935,7936,7937,7938,7939,7940,7941,7942,7943, // 7648 7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7958,7959, // 7664 7960,7961,7962,7963,7964,7965,7966,7967,7968,7969,7970,7971,7972,7973,7974,7975, // 7680 7976,7977,7978,7979,7980,7981,4859,7982,7983,7984,7985,7986,7987,7988,7989,7990, // 7696 7991,7992,7993,7994,7995,7996,4860,7997,7998,7999,8000,8001,8002,8003,8004,8005, // 7712 8006,8007,8008,8009,8010,8011,8012,8013,8014,8015,8016,4176,8017,8018,8019,8020, // 7728 8021,8022,8023,4861,8024,8025,8026,8027,8028,8029,8030,8031,8032,8033,8034,8035, // 7744 8036,4862,4456,8037,8038,8039,8040,4863,8041,8042,8043,8044,8045,8046,8047,8048, // 7760 8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063,8064, // 7776 8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080, // 7792 8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096, // 7808 8097,8098,8099,4864,4177,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110, // 7824 8111,8112,8113,8114,8115,8116,8117,8118,8119,8120,4178,8121,8122,8123,8124,8125, // 7840 8126,8127,8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141, // 7856 8142,8143,8144,8145,4865,4866,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155, // 7872 8156,8157,8158,8159,8160,8161,8162,8163,8164,8165,4179,8166,8167,8168,8169,8170, // 7888 8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181,4457,8182,8183,8184,8185, // 7904 8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201, // 7920 8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,8213,8214,8215,8216,8217, // 7936 8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229,8230,8231,8232,8233, // 7952 8234,8235,8236,8237,8238,8239,8240,8241,8242,8243,8244,8245,8246,8247,8248,8249, // 7968 8250,8251,8252,8253,8254,8255,8256,3445,8257,8258,8259,8260,8261,8262,4458,8263, // 7984 8264,8265,8266,8267,8268,8269,8270,8271,8272,4459,8273,8274,8275,8276,3550,8277, // 8000 8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,4460,8290,8291,8292, // 8016 8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,4867, // 8032 8308,8309,8310,8311,8312,3551,8313,8314,8315,8316,8317,8318,8319,8320,8321,8322, // 8048 8323,8324,8325,8326,4868,8327,8328,8329,8330,8331,8332,8333,8334,8335,8336,8337, // 8064 8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353, // 8080 8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,4869,4461,8364,8365,8366,8367, // 8096 8368,8369,8370,4870,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382, // 8112 8383,8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398, // 8128 8399,8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,4871,8411,8412,8413, // 8144 8414,8415,8416,8417,8418,8419,8420,8421,8422,4462,8423,8424,8425,8426,8427,8428, // 8160 8429,8430,8431,8432,8433,2986,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443, // 8176 8444,8445,8446,8447,8448,8449,8450,8451,8452,8453,8454,8455,8456,8457,8458,8459, // 8192 8460,8461,8462,8463,8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475, // 8208 8476,8477,8478,4180,8479,8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490, // 8224 8491,8492,8493,8494,8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506, // 8240 8507,8508,8509,8510,8511,8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522, // 8256 8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538, // 8272 8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554, // 8288 8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,4872,8565,8566,8567,8568,8569, // 8304 8570,8571,8572,8573,4873,8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584, // 8320 8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599,8600, // 8336 8601,8602,8603,8604,8605,3803,8606,8607,8608,8609,8610,8611,8612,8613,4874,3804, // 8352 8614,8615,8616,8617,8618,8619,8620,8621,3956,8622,8623,8624,8625,8626,8627,8628, // 8368 8629,8630,8631,8632,8633,8634,8635,8636,8637,8638,2865,8639,8640,8641,8642,8643, // 8384 8644,8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,4463,8657,8658, // 8400 8659,4875,4876,8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672, // 8416 8673,8674,8675,8676,8677,8678,8679,8680,8681,4464,8682,8683,8684,8685,8686,8687, // 8432 8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703, // 8448 8704,8705,8706,8707,8708,8709,2261,8710,8711,8712,8713,8714,8715,8716,8717,8718, // 8464 8719,8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,4181, // 8480 8734,8735,8736,8737,8738,8739,8740,8741,8742,8743,8744,8745,8746,8747,8748,8749, // 8496 8750,8751,8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,4877,8764, // 8512 8765,8766,8767,8768,8769,8770,8771,8772,8773,8774,8775,8776,8777,8778,8779,8780, // 8528 8781,8782,8783,8784,8785,8786,8787,8788,4878,8789,4879,8790,8791,8792,4880,8793, // 8544 8794,8795,8796,8797,8798,8799,8800,8801,4881,8802,8803,8804,8805,8806,8807,8808, // 8560 8809,8810,8811,8812,8813,8814,8815,3957,8816,8817,8818,8819,8820,8821,8822,8823, // 8576 8824,8825,8826,8827,8828,8829,8830,8831,8832,8833,8834,8835,8836,8837,8838,8839, // 8592 8840,8841,8842,8843,8844,8845,8846,8847,4882,8848,8849,8850,8851,8852,8853,8854, // 8608 8855,8856,8857,8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,8868,8869,8870, // 8624 8871,8872,8873,8874,8875,8876,8877,8878,8879,8880,8881,8882,8883,8884,3202,8885, // 8640 8886,8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898,8899,8900,8901, // 8656 8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,8915,8916,8917, // 8672 8918,8919,8920,8921,8922,8923,8924,4465,8925,8926,8927,8928,8929,8930,8931,8932, // 8688 4883,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,2214,8944,8945,8946, // 8704 8947,8948,8949,8950,8951,8952,8953,8954,8955,8956,8957,8958,8959,8960,8961,8962, // 8720 8963,8964,8965,4884,8966,8967,8968,8969,8970,8971,8972,8973,8974,8975,8976,8977, // 8736 8978,8979,8980,8981,8982,8983,8984,8985,8986,8987,8988,8989,8990,8991,8992,4885, // 8752 8993,8994,8995,8996,8997,8998,8999,9000,9001,9002,9003,9004,9005,9006,9007,9008, // 8768 9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,4182,9022,9023, // 8784 9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037,9038,9039, // 8800 9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050,9051,9052,9053,9054,9055, // 8816 9056,9057,9058,9059,9060,9061,9062,9063,4886,9064,9065,9066,9067,9068,9069,4887, // 8832 9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,9080,9081,9082,9083,9084,9085, // 8848 9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9101, // 8864 9102,9103,9104,9105,9106,9107,9108,9109,9110,9111,9112,9113,9114,9115,9116,9117, // 8880 9118,9119,9120,9121,9122,9123,9124,9125,9126,9127,9128,9129,9130,9131,9132,9133, // 8896 9134,9135,9136,9137,9138,9139,9140,9141,3958,9142,9143,9144,9145,9146,9147,9148, // 8912 9149,9150,9151,4888,9152,9153,9154,9155,9156,9157,9158,9159,9160,9161,9162,9163, // 8928 9164,9165,9166,9167,9168,9169,9170,9171,9172,9173,9174,9175,4889,9176,9177,9178, // 8944 9179,9180,9181,9182,9183,9184,9185,9186,9187,9188,9189,9190,9191,9192,9193,9194, // 8960 9195,9196,9197,9198,9199,9200,9201,9202,9203,4890,9204,9205,9206,9207,9208,9209, // 8976 9210,9211,9212,9213,9214,9215,9216,9217,9218,9219,9220,9221,9222,4466,9223,9224, // 8992 9225,9226,9227,9228,9229,9230,9231,9232,9233,9234,9235,9236,9237,9238,9239,9240, // 9008 9241,9242,9243,9244,9245,4891,9246,9247,9248,9249,9250,9251,9252,9253,9254,9255, // 9024 9256,9257,4892,9258,9259,9260,9261,4893,4894,9262,9263,9264,9265,9266,9267,9268, // 9040 9269,9270,9271,9272,9273,4467,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283, // 9056 9284,9285,3673,9286,9287,9288,9289,9290,9291,9292,9293,9294,9295,9296,9297,9298, // 9072 9299,9300,9301,9302,9303,9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314, // 9088 9315,9316,9317,9318,9319,9320,9321,9322,4895,9323,9324,9325,9326,9327,9328,9329, // 9104 9330,9331,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345, // 9120 9346,9347,4468,9348,9349,9350,9351,9352,9353,9354,9355,9356,9357,9358,9359,9360, // 9136 9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9372,9373,4896,9374,4469, // 9152 9375,9376,9377,9378,9379,4897,9380,9381,9382,9383,9384,9385,9386,9387,9388,9389, // 9168 9390,9391,9392,9393,9394,9395,9396,9397,9398,9399,9400,9401,9402,9403,9404,9405, // 9184 9406,4470,9407,2751,9408,9409,3674,3552,9410,9411,9412,9413,9414,9415,9416,9417, // 9200 9418,9419,9420,9421,4898,9422,9423,9424,9425,9426,9427,9428,9429,3959,9430,9431, // 9216 9432,9433,9434,9435,9436,4471,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446, // 9232 9447,9448,9449,9450,3348,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,9461, // 9248 9462,9463,9464,9465,9466,9467,9468,9469,9470,9471,9472,4899,9473,9474,9475,9476, // 9264 9477,4900,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,3349,9489,9490, // 9280 9491,9492,9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506, // 9296 9507,9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,4901,9521, // 9312 9522,9523,9524,9525,9526,4902,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536, // 9328 9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,9548,9549,9550,9551,9552, // 9344 9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568, // 9360 9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584, // 9376 3805,9585,9586,9587,9588,9589,9590,9591,9592,9593,9594,9595,9596,9597,9598,9599, // 9392 9600,9601,9602,4903,9603,9604,9605,9606,9607,4904,9608,9609,9610,9611,9612,9613, // 9408 9614,4905,9615,9616,9617,9618,9619,9620,9621,9622,9623,9624,9625,9626,9627,9628, // 9424 9629,9630,9631,9632,4906,9633,9634,9635,9636,9637,9638,9639,9640,9641,9642,9643, // 9440 4907,9644,9645,9646,9647,9648,9649,9650,9651,9652,9653,9654,9655,9656,9657,9658, // 9456 9659,9660,9661,9662,9663,9664,9665,9666,9667,9668,9669,9670,9671,9672,4183,9673, // 9472 9674,9675,9676,9677,4908,9678,9679,9680,9681,4909,9682,9683,9684,9685,9686,9687, // 9488 9688,9689,9690,4910,9691,9692,9693,3675,9694,9695,9696,2945,9697,9698,9699,9700, // 9504 9701,9702,9703,9704,9705,4911,9706,9707,9708,9709,9710,9711,9712,9713,9714,9715, // 9520 9716,9717,9718,9719,9720,9721,9722,9723,9724,9725,9726,9727,9728,9729,9730,9731, // 9536 9732,9733,9734,9735,4912,9736,9737,9738,9739,9740,4913,9741,9742,9743,9744,9745, // 9552 9746,9747,9748,9749,9750,9751,9752,9753,9754,9755,9756,9757,9758,4914,9759,9760, // 9568 9761,9762,9763,9764,9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776, // 9584 9777,9778,9779,9780,9781,9782,4915,9783,9784,9785,9786,9787,9788,9789,9790,9791, // 9600 9792,9793,4916,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806, // 9616 9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,9818,9819,9820,9821,9822, // 9632 9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,9836,9837,9838, // 9648 9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854, // 9664 9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,4917,9869, // 9680 9870,9871,9872,9873,9874,9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885, // 9696 9886,9887,9888,9889,9890,9891,9892,4472,9893,9894,9895,9896,9897,3806,9898,9899, // 9712 9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,4918, // 9728 9915,9916,9917,4919,9918,9919,9920,9921,4184,9922,9923,9924,9925,9926,9927,9928, // 9744 9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944, // 9760 9945,9946,4920,9947,9948,9949,9950,9951,9952,9953,9954,9955,4185,9956,9957,9958, // 9776 9959,9960,9961,9962,9963,9964,9965,4921,9966,9967,9968,4473,9969,9970,9971,9972, // 9792 9973,9974,9975,9976,9977,4474,9978,9979,9980,9981,9982,9983,9984,9985,9986,9987, // 9808 9988,9989,9990,9991,9992,9993,9994,9995,9996,9997,9998,9999,10000,10001,10002,10003, // 9824 10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,10014,10015,10016,10017,10018,10019, // 9840 10020,10021,4922,10022,4923,10023,10024,10025,10026,10027,10028,10029,10030,10031,10032,10033, // 9856 10034,10035,10036,10037,10038,10039,10040,10041,10042,10043,10044,10045,10046,10047,10048,4924, // 9872 10049,10050,10051,10052,10053,10054,10055,10056,10057,10058,10059,10060,10061,10062,10063,10064, // 9888 10065,10066,10067,10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,10080, // 9904 10081,10082,10083,10084,10085,10086,10087,4475,10088,10089,10090,10091,10092,10093,10094,10095, // 9920 10096,10097,4476,10098,10099,10100,10101,10102,10103,10104,10105,10106,10107,10108,10109,10110, // 9936 10111,2174,10112,10113,10114,10115,10116,10117,10118,10119,10120,10121,10122,10123,10124,10125, // 9952 10126,10127,10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,10140,3807, // 9968 4186,4925,10141,10142,10143,10144,10145,10146,10147,4477,4187,10148,10149,10150,10151,10152, // 9984 10153,4188,10154,10155,10156,10157,10158,10159,10160,10161,4926,10162,10163,10164,10165,10166, //10000 10167,10168,10169,10170,10171,10172,10173,10174,10175,10176,10177,10178,10179,10180,10181,10182, //10016 10183,10184,10185,10186,10187,10188,10189,10190,10191,10192,3203,10193,10194,10195,10196,10197, //10032 10198,10199,10200,4478,10201,10202,10203,10204,4479,10205,10206,10207,10208,10209,10210,10211, //10048 10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,10226,10227, //10064 10228,10229,10230,10231,10232,10233,10234,4927,10235,10236,10237,10238,10239,10240,10241,10242, //10080 10243,10244,10245,10246,10247,10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258, //10096 10259,10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,10272,10273,4480, //10112 4928,4929,10274,10275,10276,10277,10278,10279,10280,10281,10282,10283,10284,10285,10286,10287, //10128 10288,10289,10290,10291,10292,10293,10294,10295,10296,10297,10298,10299,10300,10301,10302,10303, //10144 10304,10305,10306,10307,10308,10309,10310,10311,10312,10313,10314,10315,10316,10317,10318,10319, //10160 10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333,10334,4930, //10176 10335,10336,10337,10338,10339,10340,10341,10342,4931,10343,10344,10345,10346,10347,10348,10349, //10192 10350,10351,10352,10353,10354,10355,3088,10356,2786,10357,10358,10359,10360,4189,10361,10362, //10208 10363,10364,10365,10366,10367,10368,10369,10370,10371,10372,10373,10374,10375,4932,10376,10377, //10224 10378,10379,10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,10392,4933, //10240 10393,10394,10395,4934,10396,10397,10398,10399,10400,10401,10402,10403,10404,10405,10406,10407, //10256 10408,10409,10410,10411,10412,3446,10413,10414,10415,10416,10417,10418,10419,10420,10421,10422, //10272 10423,4935,10424,10425,10426,10427,10428,10429,10430,4936,10431,10432,10433,10434,10435,10436, //10288 10437,10438,10439,10440,10441,10442,10443,4937,10444,10445,10446,10447,4481,10448,10449,10450, //10304 10451,10452,10453,10454,10455,10456,10457,10458,10459,10460,10461,10462,10463,10464,10465,10466, //10320 10467,10468,10469,10470,10471,10472,10473,10474,10475,10476,10477,10478,10479,10480,10481,10482, //10336 10483,10484,10485,10486,10487,10488,10489,10490,10491,10492,10493,10494,10495,10496,10497,10498, //10352 10499,10500,10501,10502,10503,10504,10505,4938,10506,10507,10508,10509,10510,2552,10511,10512, //10368 10513,10514,10515,10516,3447,10517,10518,10519,10520,10521,10522,10523,10524,10525,10526,10527, //10384 10528,10529,10530,10531,10532,10533,10534,10535,10536,10537,10538,10539,10540,10541,10542,10543, //10400 4482,10544,4939,10545,10546,10547,10548,10549,10550,10551,10552,10553,10554,10555,10556,10557, //10416 10558,10559,10560,10561,10562,10563,10564,10565,10566,10567,3676,4483,10568,10569,10570,10571, //10432 10572,3448,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584,10585,10586, //10448 10587,10588,10589,10590,10591,10592,10593,10594,10595,10596,10597,10598,10599,10600,10601,10602, //10464 10603,10604,10605,10606,10607,10608,10609,10610,10611,10612,10613,10614,10615,10616,10617,10618, //10480 10619,10620,10621,10622,10623,10624,10625,10626,10627,4484,10628,10629,10630,10631,10632,4940, //10496 10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,10644,10645,10646,10647,10648, //10512 10649,10650,10651,10652,10653,10654,10655,10656,4941,10657,10658,10659,2599,10660,10661,10662, //10528 10663,10664,10665,10666,3089,10667,10668,10669,10670,10671,10672,10673,10674,10675,10676,10677, //10544 10678,10679,10680,4942,10681,10682,10683,10684,10685,10686,10687,10688,10689,10690,10691,10692, //10560 10693,10694,10695,10696,10697,4485,10698,10699,10700,10701,10702,10703,10704,4943,10705,3677, //10576 10706,10707,10708,10709,10710,10711,10712,4944,10713,10714,10715,10716,10717,10718,10719,10720, //10592 10721,10722,10723,10724,10725,10726,10727,10728,4945,10729,10730,10731,10732,10733,10734,10735, //10608 10736,10737,10738,10739,10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751, //10624 10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,4946,10762,10763,10764,10765,10766, //10640 10767,4947,4948,10768,10769,10770,10771,10772,10773,10774,10775,10776,10777,10778,10779,10780, //10656 10781,10782,10783,10784,10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796, //10672 10797,10798,10799,10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,10811,10812, //10688 10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,10824,10825,10826,10827,10828, //10704 10829,10830,10831,10832,10833,10834,10835,10836,10837,10838,10839,10840,10841,10842,10843,10844, //10720 10845,10846,10847,10848,10849,10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,10860, //10736 10861,10862,10863,10864,10865,10866,10867,10868,10869,10870,10871,10872,10873,10874,10875,10876, //10752 10877,10878,4486,10879,10880,10881,10882,10883,10884,10885,4949,10886,10887,10888,10889,10890, //10768 10891,10892,10893,10894,10895,10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906, //10784 10907,10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,4487,10920,10921, //10800 10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,10932,4950,10933,10934,10935,10936, //10816 10937,10938,10939,10940,10941,10942,10943,10944,10945,10946,10947,10948,10949,4488,10950,10951, //10832 10952,10953,10954,10955,10956,10957,10958,10959,4190,10960,10961,10962,10963,10964,10965,10966, //10848 10967,10968,10969,10970,10971,10972,10973,10974,10975,10976,10977,10978,10979,10980,10981,10982, //10864 10983,10984,10985,10986,10987,10988,10989,10990,10991,10992,10993,10994,10995,10996,10997,10998, //10880 10999,11000,11001,11002,11003,11004,11005,11006,3960,11007,11008,11009,11010,11011,11012,11013, //10896 11014,11015,11016,11017,11018,11019,11020,11021,11022,11023,11024,11025,11026,11027,11028,11029, //10912 11030,11031,11032,4951,11033,11034,11035,11036,11037,11038,11039,11040,11041,11042,11043,11044, //10928 11045,11046,11047,4489,11048,11049,11050,11051,4952,11052,11053,11054,11055,11056,11057,11058, //10944 4953,11059,11060,11061,11062,11063,11064,11065,11066,11067,11068,11069,11070,11071,4954,11072, //10960 11073,11074,11075,11076,11077,11078,11079,11080,11081,11082,11083,11084,11085,11086,11087,11088, //10976 11089,11090,11091,11092,11093,11094,11095,11096,11097,11098,11099,11100,11101,11102,11103,11104, //10992 11105,11106,11107,11108,11109,11110,11111,11112,11113,11114,11115,3808,11116,11117,11118,11119, //11008 11120,11121,11122,11123,11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,4955, //11024 11135,11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,11148,11149,11150, //11040 11151,11152,11153,11154,11155,11156,11157,11158,11159,11160,11161,4956,11162,11163,11164,11165, //11056 11166,11167,11168,11169,11170,11171,11172,11173,11174,11175,11176,11177,11178,11179,11180,4957, //11072 11181,11182,11183,11184,11185,11186,4958,11187,11188,11189,11190,11191,11192,11193,11194,11195, //11088 11196,11197,11198,11199,11200,3678,11201,11202,11203,11204,11205,11206,4191,11207,11208,11209, //11104 11210,11211,11212,11213,11214,11215,11216,11217,11218,11219,11220,11221,11222,11223,11224,11225, //11120 11226,11227,11228,11229,11230,11231,11232,11233,11234,11235,11236,11237,11238,11239,11240,11241, //11136 11242,11243,11244,11245,11246,11247,11248,11249,11250,11251,4959,11252,11253,11254,11255,11256, //11152 11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,11268,11269,11270,11271,11272, //11168 11273,11274,11275,11276,11277,11278,11279,11280,11281,11282,11283,11284,11285,11286,11287,11288, //11184 11289,11290,11291,11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304, //11200 11305,11306,11307,11308,11309,11310,11311,11312,11313,11314,3679,11315,11316,11317,11318,4490, //11216 11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,11329,11330,11331,11332,11333,11334, //11232 11335,11336,11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,4960,11348,11349, //11248 11350,11351,11352,11353,11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365, //11264 11366,11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,3961,4961,11378,11379, //11280 11380,11381,11382,11383,11384,11385,11386,11387,11388,11389,11390,11391,11392,11393,11394,11395, //11296 11396,11397,4192,11398,11399,11400,11401,11402,11403,11404,11405,11406,11407,11408,11409,11410, //11312 11411,4962,11412,11413,11414,11415,11416,11417,11418,11419,11420,11421,11422,11423,11424,11425, //11328 11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441, //11344 11442,11443,11444,11445,11446,11447,11448,11449,11450,11451,11452,11453,11454,11455,11456,11457, //11360 11458,11459,11460,11461,11462,11463,11464,11465,11466,11467,11468,11469,4963,11470,11471,4491, //11376 11472,11473,11474,11475,4964,11476,11477,11478,11479,11480,11481,11482,11483,11484,11485,11486, //11392 11487,11488,11489,11490,11491,11492,4965,11493,11494,11495,11496,11497,11498,11499,11500,11501, //11408 11502,11503,11504,11505,11506,11507,11508,11509,11510,11511,11512,11513,11514,11515,11516,11517, //11424 11518,11519,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,3962,11530,11531,11532, //11440 11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545,11546,11547,11548, //11456 11549,11550,11551,11552,11553,11554,11555,11556,11557,11558,11559,11560,11561,11562,11563,11564, //11472 4193,4194,11565,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578, //11488 11579,11580,11581,11582,11583,11584,11585,11586,11587,11588,11589,11590,11591,4966,4195,11592, //11504 11593,11594,11595,11596,11597,11598,11599,11600,11601,11602,11603,11604,3090,11605,11606,11607, //11520 11608,11609,11610,4967,11611,11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622, //11536 11623,11624,11625,11626,11627,11628,11629,11630,11631,11632,11633,11634,11635,11636,11637,11638, //11552 11639,11640,11641,11642,11643,11644,11645,11646,11647,11648,11649,11650,11651,11652,11653,11654, //11568 11655,11656,11657,11658,11659,11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670, //11584 11671,11672,11673,11674,4968,11675,11676,11677,11678,11679,11680,11681,11682,11683,11684,11685, //11600 11686,11687,11688,11689,11690,11691,11692,11693,3809,11694,11695,11696,11697,11698,11699,11700, //11616 11701,11702,11703,11704,11705,11706,11707,11708,11709,11710,11711,11712,11713,11714,11715,11716, //11632 11717,11718,3553,11719,11720,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,4969, //11648 11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,4492,11741,11742,11743,11744,11745, //11664 11746,11747,11748,11749,11750,11751,11752,4970,11753,11754,11755,11756,11757,11758,11759,11760, //11680 11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,11771,11772,11773,11774,11775,11776, //11696 11777,11778,11779,11780,11781,11782,11783,11784,11785,11786,11787,11788,11789,11790,4971,11791, //11712 11792,11793,11794,11795,11796,11797,4972,11798,11799,11800,11801,11802,11803,11804,11805,11806, //11728 11807,11808,11809,11810,4973,11811,11812,11813,11814,11815,11816,11817,11818,11819,11820,11821, //11744 11822,11823,11824,11825,11826,11827,11828,11829,11830,11831,11832,11833,11834,3680,3810,11835, //11760 11836,4974,11837,11838,11839,11840,11841,11842,11843,11844,11845,11846,11847,11848,11849,11850, //11776 11851,11852,11853,11854,11855,11856,11857,11858,11859,11860,11861,11862,11863,11864,11865,11866, //11792 11867,11868,11869,11870,11871,11872,11873,11874,11875,11876,11877,11878,11879,11880,11881,11882, //11808 11883,11884,4493,11885,11886,11887,11888,11889,11890,11891,11892,11893,11894,11895,11896,11897, //11824 11898,11899,11900,11901,11902,11903,11904,11905,11906,11907,11908,11909,11910,11911,11912,11913, //11840 11914,11915,4975,11916,11917,11918,11919,11920,11921,11922,11923,11924,11925,11926,11927,11928, //11856 11929,11930,11931,11932,11933,11934,11935,11936,11937,11938,11939,11940,11941,11942,11943,11944, //11872 11945,11946,11947,11948,11949,4976,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959, //11888 11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971,11972,11973,11974,11975, //11904 11976,11977,11978,11979,11980,11981,11982,11983,11984,11985,11986,11987,4196,11988,11989,11990, //11920 11991,11992,4977,11993,11994,11995,11996,11997,11998,11999,12000,12001,12002,12003,12004,12005, //11936 12006,12007,12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019,12020,12021, //11952 12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,12032,12033,12034,12035,12036,12037, //11968 12038,12039,12040,12041,12042,12043,12044,12045,12046,12047,12048,12049,12050,12051,12052,12053, //11984 12054,12055,12056,12057,12058,12059,12060,12061,4978,12062,12063,12064,12065,12066,12067,12068, //12000 12069,12070,12071,12072,12073,12074,12075,12076,12077,12078,12079,12080,12081,12082,12083,12084, //12016 12085,12086,12087,12088,12089,12090,12091,12092,12093,12094,12095,12096,12097,12098,12099,12100, //12032 12101,12102,12103,12104,12105,12106,12107,12108,12109,12110,12111,12112,12113,12114,12115,12116, //12048 12117,12118,12119,12120,12121,12122,12123,4979,12124,12125,12126,12127,12128,4197,12129,12130, //12064 12131,12132,12133,12134,12135,12136,12137,12138,12139,12140,12141,12142,12143,12144,12145,12146, //12080 12147,12148,12149,12150,12151,12152,12153,12154,4980,12155,12156,12157,12158,12159,12160,4494, //12096 12161,12162,12163,12164,3811,12165,12166,12167,12168,12169,4495,12170,12171,4496,12172,12173, //12112 12174,12175,12176,3812,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,12188, //12128 12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199,12200,12201,12202,12203,12204, //12144 12205,12206,12207,12208,12209,12210,12211,12212,12213,12214,12215,12216,12217,12218,12219,12220, //12160 12221,4981,12222,12223,12224,12225,12226,12227,12228,12229,12230,12231,12232,12233,12234,12235, //12176 4982,12236,12237,12238,12239,12240,12241,12242,12243,12244,12245,4983,12246,12247,12248,12249, //12192 4984,12250,12251,12252,12253,12254,12255,12256,12257,12258,12259,12260,12261,12262,12263,12264, //12208 4985,12265,4497,12266,12267,12268,12269,12270,12271,12272,12273,12274,12275,12276,12277,12278, //12224 12279,12280,12281,12282,12283,12284,12285,12286,12287,4986,12288,12289,12290,12291,12292,12293, //12240 12294,12295,12296,2473,12297,12298,12299,12300,12301,12302,12303,12304,12305,12306,12307,12308, //12256 12309,12310,12311,12312,12313,12314,12315,12316,12317,12318,12319,3963,12320,12321,12322,12323, //12272 12324,12325,12326,12327,12328,12329,12330,12331,12332,4987,12333,12334,12335,12336,12337,12338, //12288 12339,12340,12341,12342,12343,12344,12345,12346,12347,12348,12349,12350,12351,12352,12353,12354, //12304 12355,12356,12357,12358,12359,3964,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369, //12320 12370,3965,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384, //12336 12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400, //12352 12401,12402,12403,12404,12405,12406,12407,12408,4988,12409,12410,12411,12412,12413,12414,12415, //12368 12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431, //12384 12432,12433,12434,12435,12436,12437,12438,3554,12439,12440,12441,12442,12443,12444,12445,12446, //12400 12447,12448,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462, //12416 12463,12464,4989,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477, //12432 12478,12479,12480,4990,12481,12482,12483,12484,12485,12486,12487,12488,12489,4498,12490,12491, //12448 12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507, //12464 12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523, //12480 12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,12536,12537,12538,12539, //12496 12540,12541,12542,12543,12544,12545,12546,12547,12548,12549,12550,12551,4991,12552,12553,12554, //12512 12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570, //12528 12571,12572,12573,12574,12575,12576,12577,12578,3036,12579,12580,12581,12582,12583,3966,12584, //12544 12585,12586,12587,12588,12589,12590,12591,12592,12593,12594,12595,12596,12597,12598,12599,12600, //12560 12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616, //12576 12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,12632, //12592 12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,4499,12647, //12608 12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,12659,12660,12661,12662,12663, //12624 12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679, //12640 12680,12681,12682,12683,12684,12685,12686,12687,12688,12689,12690,12691,12692,12693,12694,12695, //12656 12696,12697,12698,4992,12699,12700,12701,12702,12703,12704,12705,12706,12707,12708,12709,12710, //12672 12711,12712,12713,12714,12715,12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726, //12688 12727,12728,12729,12730,12731,12732,12733,12734,12735,12736,12737,12738,12739,12740,12741,12742, //12704 12743,12744,12745,12746,12747,12748,12749,12750,12751,12752,12753,12754,12755,12756,12757,12758, //12720 12759,12760,12761,12762,12763,12764,12765,12766,12767,12768,12769,12770,12771,12772,12773,12774, //12736 12775,12776,12777,12778,4993,2175,12779,12780,12781,12782,12783,12784,12785,12786,4500,12787, //12752 12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,12800,12801,12802,12803, //12768 12804,12805,12806,12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819, //12784 12820,12821,12822,12823,12824,12825,12826,4198,3967,12827,12828,12829,12830,12831,12832,12833, //12800 12834,12835,12836,12837,12838,12839,12840,12841,12842,12843,12844,12845,12846,12847,12848,12849, //12816 12850,12851,12852,12853,12854,12855,12856,12857,12858,12859,12860,12861,4199,12862,12863,12864, //12832 12865,12866,12867,12868,12869,12870,12871,12872,12873,12874,12875,12876,12877,12878,12879,12880, //12848 12881,12882,12883,12884,12885,12886,12887,4501,12888,12889,12890,12891,12892,12893,12894,12895, //12864 12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,12911, //12880 12912,4994,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,12924,12925,12926, //12896 12927,12928,12929,12930,12931,12932,12933,12934,12935,12936,12937,12938,12939,12940,12941,12942, //12912 12943,12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,12956,1772,12957, //12928 12958,12959,12960,12961,12962,12963,12964,12965,12966,12967,12968,12969,12970,12971,12972,12973, //12944 12974,12975,12976,12977,12978,12979,12980,12981,12982,12983,12984,12985,12986,12987,12988,12989, //12960 12990,12991,12992,12993,12994,12995,12996,12997,4502,12998,4503,12999,13000,13001,13002,13003, //12976 4504,13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,13016,13017,13018, //12992 13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,3449,13030,13031,13032,13033, //13008 13034,13035,13036,13037,13038,13039,13040,13041,13042,13043,13044,13045,13046,13047,13048,13049, //13024 13050,13051,13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,13064,13065, //13040 13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,13076,13077,13078,13079,13080,13081, //13056 13082,13083,13084,13085,13086,13087,13088,13089,13090,13091,13092,13093,13094,13095,13096,13097, //13072 13098,13099,13100,13101,13102,13103,13104,13105,13106,13107,13108,13109,13110,13111,13112,13113, //13088 13114,13115,13116,13117,13118,3968,13119,4995,13120,13121,13122,13123,13124,13125,13126,13127, //13104 4505,13128,13129,13130,13131,13132,13133,13134,4996,4506,13135,13136,13137,13138,13139,4997, //13120 13140,13141,13142,13143,13144,13145,13146,13147,13148,13149,13150,13151,13152,13153,13154,13155, //13136 13156,13157,13158,13159,4998,13160,13161,13162,13163,13164,13165,13166,13167,13168,13169,13170, //13152 13171,13172,13173,13174,13175,13176,4999,13177,13178,13179,13180,13181,13182,13183,13184,13185, //13168 13186,13187,13188,13189,13190,13191,13192,13193,13194,13195,13196,13197,13198,13199,13200,13201, //13184 13202,13203,13204,13205,13206,5000,13207,13208,13209,13210,13211,13212,13213,13214,13215,13216, //13200 13217,13218,13219,13220,13221,13222,13223,13224,13225,13226,13227,4200,5001,13228,13229,13230, //13216 13231,13232,13233,13234,13235,13236,13237,13238,13239,13240,3969,13241,13242,13243,13244,3970, //13232 13245,13246,13247,13248,13249,13250,13251,13252,13253,13254,13255,13256,13257,13258,13259,13260, //13248 13261,13262,13263,13264,13265,13266,13267,13268,3450,13269,13270,13271,13272,13273,13274,13275, //13264 13276,5002,13277,13278,13279,13280,13281,13282,13283,13284,13285,13286,13287,13288,13289,13290, //13280 13291,13292,13293,13294,13295,13296,13297,13298,13299,13300,13301,13302,3813,13303,13304,13305, //13296 13306,13307,13308,13309,13310,13311,13312,13313,13314,13315,13316,13317,13318,13319,13320,13321, //13312 13322,13323,13324,13325,13326,13327,13328,4507,13329,13330,13331,13332,13333,13334,13335,13336, //13328 13337,13338,13339,13340,13341,5003,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351, //13344 13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,13364,13365,13366,13367, //13360 5004,13368,13369,13370,13371,13372,13373,13374,13375,13376,13377,13378,13379,13380,13381,13382, //13376 13383,13384,13385,13386,13387,13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398, //13392 13399,13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,13412,13413,13414, //13408 13415,13416,13417,13418,13419,13420,13421,13422,13423,13424,13425,13426,13427,13428,13429,13430, //13424 13431,13432,4508,13433,13434,13435,4201,13436,13437,13438,13439,13440,13441,13442,13443,13444, //13440 13445,13446,13447,13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,5005,13458,13459, //13456 13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,4509,13471,13472,13473,13474, //13472 13475,13476,13477,13478,13479,13480,13481,13482,13483,13484,13485,13486,13487,13488,13489,13490, //13488 13491,13492,13493,13494,13495,13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506, //13504 13507,13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,13520,13521,13522, //13520 13523,13524,13525,13526,13527,13528,13529,13530,13531,13532,13533,13534,13535,13536,13537,13538, //13536 13539,13540,13541,13542,13543,13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554, //13552 13555,13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,13568,13569,13570, //13568 13571,13572,13573,13574,13575,13576,13577,13578,13579,13580,13581,13582,13583,13584,13585,13586, //13584 13587,13588,13589,13590,13591,13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602, //13600 13603,13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,13616,13617,13618, //13616 13619,13620,13621,13622,13623,13624,13625,13626,13627,13628,13629,13630,13631,13632,13633,13634, //13632 13635,13636,13637,13638,13639,13640,13641,13642,5006,13643,13644,13645,13646,13647,13648,13649, //13648 13650,13651,5007,13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,13664, //13664 13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,13676,13677,13678,13679,13680, //13680 13681,13682,13683,13684,13685,13686,13687,13688,13689,13690,13691,13692,13693,13694,13695,13696, //13696 13697,13698,13699,13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,13712, //13712 13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,13724,13725,13726,13727,13728, //13728 13729,13730,13731,13732,13733,13734,13735,13736,13737,13738,13739,13740,13741,13742,13743,13744, //13744 13745,13746,13747,13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,13760, //13760 13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,13772,13773,13774,3273,13775, //13776 13776,13777,13778,13779,13780,13781,13782,13783,13784,13785,13786,13787,13788,13789,13790,13791, //13792 13792,13793,13794,13795,13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807, //13808 13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,13820,13821,13822,13823, //13824 13824,13825,13826,13827,13828,13829,13830,13831,13832,13833,13834,13835,13836,13837,13838,13839, //13840 13840,13841,13842,13843,13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855, //13856 13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,13868,13869,13870,13871, //13872 13872,13873,13874,13875,13876,13877,13878,13879,13880,13881,13882,13883,13884,13885,13886,13887, //13888 13888,13889,13890,13891,13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903, //13904 13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,13916,13917,13918,13919, //13920 13920,13921,13922,13923,13924,13925,13926,13927,13928,13929,13930,13931,13932,13933,13934,13935, //13936 13936,13937,13938,13939,13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951, //13952 13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966,13967, //13968 13968,13969,13970,13971,13972, //13973 ****************************************************************************************) ); implementation end. doublecmd-0.8.2/components/chsdet/src/nsEscCharsetProber.pas0000664000175000017500000000444712014201074023177 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsEscCharsetProber.pas,v 1.3 2007/05/26 13:09:38 ya_nick Exp $ unit nsEscCharsetProber; interface uses nsCore, MultiModelProber; type TnsEscCharSetProber = class (TMultiModelProber) public constructor Create; override; function GetConfidence: float; override; end; implementation uses nsCodingStateMachine, CustomDetector; {$I '.\mbclass\ISO2022KRLangModel.inc'} {$I '.\mbclass\ISO2022JPLangModel.inc'} {$I '.\mbclass\ISO2022CNLangModel.inc'} {$I '.\mbclass\HZLangModel.inc'} { TnsEscCharSetProber } const NUM_OF_ESC_CHARSETS = 4; constructor TnsEscCharSetProber.Create; begin inherited; AddCharsetModel(HZSMModel); AddCharsetModel(ISO2022CNSMModel); AddCharsetModel(ISO2022JPSMModel); AddCharsetModel(ISO2022KRSMModel); Reset; end; function TnsEscCharSetProber.GetConfidence: float; begin case mState of psFoundIt: Result := SURE_YES; psNotMe: Result := SURE_NO; psDetecting: Result := (SURE_YES + SURE_NO) / 2; else Result := 1.1 * SURE_NO; end; end; end. doublecmd-0.8.2/components/chsdet/src/JpCntx.pas0000664000175000017500000005245512014201074020650 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: JpCntx.pas,v 1.2 2007/05/20 15:46:05 ya_nick Exp $ unit JpCntx; interface uses nsCore; const NUM_OF_CATEGORY = 6; type TJapaneseContextAnalysis = class (TObject) private (*category counters, each interger counts sequence in its category*) mRelSample: array [0..Pred(NUM_OF_CATEGORY)] of PRUint32; (*total sequence received*) mTotalRel: PRUint32; (*The order of previous char*) mLastCharOrder: integer; (*if last byte in current buffer is not the last byte of a character, we*) (*need to know how many byte to skip in next buffer.*) mNeedToSkipCharNum: integer; (*If this flag is set to PR_TRUE, detection is done and conclusion has been made*) mDone: Boolean; function GetOrder(str: PChar; charLen: pPRUint32): PRInt32; overload; virtual; abstract; function GetOrder(str: PChar): PRInt32; overload; virtual; abstract; public constructor Create; destructor Destroy; override; procedure Reset; procedure HandleData(const aBuf: PChar; aLen: integer); procedure HandleOneChar(aStr: PChar; aCharLen: integer); function GotEnoughData: Boolean; function GetConfidence: float; end; TSJISContextAnalysis = class (TJapaneseContextAnalysis) public function GetOrder(str: PChar; charLen: pPRUint32): PRInt32; overload; override; function GetOrder(str: PChar): PRInt32; overload; override; end; TEUCJPContextAnalysis = class (TJapaneseContextAnalysis) public function GetOrder(str: PChar; charLen: pPRUint32): PRInt32; overload; override; (*We only interested in Hiragana, so first byte is '\244'*) function GetOrder(str: PChar): PRInt32; overload; override; end; implementation const ENOUGH_REL_THRESHOLD = 100; MAX_REL_THRESHOLD = 1000; MINIMUM_DATA_THRESHOLD = 4; DONT_KNOW: float = -1; (*hiragana frequency category table*) //This is hiragana 2-char sequence table, the number in each cell represents its frequency category jp2CharContext: array [0..82, 0..82] of byte = ( ( 0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), ( 2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), ( 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), ( 0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), ( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), ( 0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), ( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), ( 0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), ( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), ( 0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), ( 1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), ( 0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), ( 0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), ( 0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), ( 0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), ( 0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), ( 2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), ( 0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), ( 0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), ( 0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), ( 2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), ( 0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), ( 1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), ( 0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), ( 0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), ( 0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), ( 0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), ( 0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), ( 0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), ( 0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), ( 0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), ( 0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), ( 0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), ( 0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), ( 0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), ( 1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), ( 0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), ( 0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), ( 0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), ( 0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), ( 0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), ( 2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), ( 0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), ( 0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), ( 0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), ( 0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), ( 0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), ( 0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), ( 0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), ( 0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), ( 0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), ( 0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), ( 0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), ( 0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), ( 0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), ( 0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), ( 0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), ( 0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), ( 0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), ( 0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), ( 0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), ( 2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), ( 0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), ( 0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), ( 0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), ( 0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), ( 1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), ( 0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), ( 0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), ( 0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), ( 0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), ( 0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), ( 0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), ( 0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), ( 0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), ( 1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), ( 0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), ( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), ( 0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), ( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), ( 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), ( 0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), ( 0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1) ); constructor TJapaneseContextAnalysis.Create; begin inherited Create; Reset; end; destructor TJapaneseContextAnalysis.Destroy; begin inherited; end; procedure TJapaneseContextAnalysis.HandleOneChar(aStr: PChar; aCharLen: integer); var order: PRInt32; (*if we received enough data, stop here *) begin if mTotalRel > MAX_REL_THRESHOLD then mDone:= TRUE; if mDone then exit; (*Only 2-bytes characters are of our interest*) if (aCharLen=2) then order := GetOrder(aStr) else order := -1; if (order <> -1) and (mLastCharOrder <> -1) then begin inc(mTotalRel); inc(mRelSample[jp2CharContext[mLastCharOrder][order]]); (*count this sequence to its category counter*) end; mLastCharOrder:= order; end; function TJapaneseContextAnalysis.GotEnoughData: Boolean; begin Result := mTotalRel > ENOUGH_REL_THRESHOLD; end; function TJapaneseContextAnalysis.GetConfidence: float; begin (*This is just one way to calculate confidence. It works well for me.*) if mTotalRel > MINIMUM_DATA_THRESHOLD then Result := (mTotalRel - mRelSample[0]) div mTotalRel else Result := DONT_KNOW; end; procedure TJapaneseContextAnalysis.HandleData(const aBuf: PChar; aLen: integer); var charLen: PRUint32; order: PRInt32; i: integer; begin if mDone then exit; (*The buffer we got is byte oriented, and a character may span in more than one*) (*buffers. In case the last one or two byte in last buffer is not complete, we *) (*record how many byte needed to complete that character and skip these bytes here.*) (*We can choose to record those bytes as well and analyse the character once it *) (*is complete, but since a character will not make much difference, by simply skipping*) (*this character will simply our logic and improve performance.*) i := mNeedToSkipCharNum; while i < integer(aLen) do begin order := GetOrder(aBuf+i, @charLen); i := i + integer(charLen); if i > integer(aLen) then begin mNeedToSkipCharNum := i - aLen; mLastCharOrder := -1; end else begin if (order <> -1) and (mLastCharOrder <> -1) then begin inc(mTotalRel); if mTotalRel > MAX_REL_THRESHOLD then begin mDone:= TRUE; break; {<= !!!b possible in "switch" - then remove this line} end; inc(mRelSample[jp2CharContext[mLastCharOrder][order]]); end; mLastCharOrder:= order; end; end; end; procedure TJapaneseContextAnalysis.Reset; var i: integer; begin mTotalRel := 0; for i := 0 to Pred(NUM_OF_CATEGORY) do mRelSample[i] := 0; mNeedToSkipCharNum := 0; mLastCharOrder := -1; mDone := FALSE; end; { TSJISContextAnalysis } function TSJISContextAnalysis.GetOrder(str: PChar; charLen: pPRUint32): PRInt32; begin (*find out current char's byte length*) if (byte(str^) >= $81) and (byte(str^) <= $9f) or (byte(str^) >= $e0) and (byte(str^) <= $fc) then charLen^:=2 else charLen^:=1; (*return its order if it is hiragana*) if (str^ = #$82) and (byte((str+1)^) >= $9f) and (byte((str+1)^) <= $f1) then Result := byte((str+1)^) - $9f else Result:= -1; end; function TSJISContextAnalysis.GetOrder(str: PChar): PRInt32; begin (*We only interested in Hiragana, so first byte is '\202'*) if (str[0]=#$82) and (byte(str[1]) >= $9f) and (byte(str[1]) <= $f1) then Result := byte(str[1]) - $9f else Result := -1; end; { TEUCJPContextAnalysis } function TEUCJPContextAnalysis.GetOrder(str: PChar; charLen: pPRUint32): PRInt32; begin (*find out current char's byte length*) if (byte(str^) = $8e) or (byte(str^) >= $a1) and (byte(str^) <= $fe) then charLen^ := 2 else if byte(str^) = $8f then charLen^ := 3 else charLen^ := 1; (*return its order if it is hiragana*) if (byte(str^) = $a4) and (byte((str+1)^) >= $a1) and (byte((str+1)^) <= $f3) then Result := byte((str+1)^) - $a1 else Result:= -1; end; function TEUCJPContextAnalysis.GetOrder(str: PChar): PRInt32; begin if (str[0]=#$A4) and (byte(str[1]) >= $a1) and (byte(str[1]) <= $f3) then Result := byte(str[1]) - $a1 else Result := -1; end; end. doublecmd-0.8.2/components/chsdet/src/sbseq/0000775000175000017500000000000013244011205020040 5ustar alexxalexxdoublecmd-0.8.2/components/chsdet/src/sbseq/LangHebrewModel.pas0000664000175000017500000002670712014201074023557 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: LangHebrewModel.pas,v 1.1 2007/05/20 15:46:20 ya_nick Exp $ unit LangHebrewModel; interface uses nsCore, nsSBCharSetProber; (**************************************************************** 255: Control characters that usually does not exist in any text 254: Carriage/Return 253: symbol (punctuation) that does not belong to word 252: 0 - 9 *****************************************************************) //Windows-1255 language model //Character Mapping Table: const win1255_CharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253, 69, 91, 79, 80, 92, 89, 97, 90, 68,111,112, 82, 73, 95, 85, //40 78,121, 86, 71, 67,102,107, 84,114,103,115,253,253,253,253,253, //50 253, 50, 74, 60, 61, 42, 76, 70, 64, 53,105, 93, 56, 65, 54, 49, //60 66,110, 51, 43, 44, 63, 81, 77, 98, 75,108,253,253,253,253,253, //70 124,202,203,204,205, 40, 58,206,207,208,209,210,211,212,213,214, 215, 83, 52, 47, 46, 72, 32, 94,216,113,217,109,218,219,220,221, 34,116,222,118,100,223,224,117,119,104,125,225,226, 87, 99,227, 106,122,123,228, 55,229,230,101,231,232,120,233, 48, 39, 57,234, 30, 59, 41, 88, 33, 37, 36, 31, 29, 35,235, 62, 28,236,126,237, 238, 38, 45,239,240,241,242,243,127,244,245,246,247,248,249,250, 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23, 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5,251,252,128, 96,253 ); //Model Table: //total sequences: 100% //first 512 sequences: 98.4004% //first 1024 sequences: 1.5981% //rest sequences: 0.087% //negative sequences: 0.0015% HebrewLangModel: array [0..Pred(32*128)] of byte = ( 0,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,1,2,0,1,0,0, 3,0,3,1,0,0,1,3,2,0,1,1,2,0,2,2,2,1,1,1,1,2,1,1,1,2,0,0,2,2,0,1, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2, 1,2,1,2,1,2,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2, 1,2,1,3,1,1,0,0,2,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,1,2,2,1,3, 1,2,1,1,2,2,0,0,2,2,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,2, 1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,3,2,2,2,1,2,2,2,2, 1,2,1,1,2,2,0,1,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,0,2,2,2,2,2, 0,2,0,2,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,0,2,2,2, 0,2,1,2,2,2,0,0,2,1,0,0,0,0,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,2,3,2,2,2, 1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0, 3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,2,0,2, 0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,2,2,3,2,1,2,1,1,1, 0,1,1,1,1,1,3,0,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, 3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,0,0, 0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2, 0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,3,3,3,2,3,3,3,2,1,2,3,3,2,3,3,3,3,2,3,2,1,2,0,2,1,2, 0,2,0,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0, 3,3,3,3,3,3,3,3,3,2,3,3,3,1,2,2,3,3,2,3,2,3,2,2,3,1,2,2,0,2,2,2, 0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,1,3,2,2,2, 0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,1,2,2,0,2,2,2,2, 0,2,0,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,3,2,3,3,2,3,3,2,2,1,2,2,2,2,2,2, 0,2,1,2,1,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,2,3,2,3,3,2,3,3,3,3,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,1, 0,2,0,1,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,3,3,3,2,1,2,3,3,3,3,3,3,3,2,3,2,3,2,1,2,3,0,2,1,2,2, 0,2,1,1,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,2,0, 3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,1,3,1,2,2,2,1,2,3,3,1,2,1,2,2,2,2, 0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,0,2,3,3,3,1,3,3,3,1,2,2,2,2,1,1,2,2,2,2,2,2, 0,2,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, 3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,2,1,2,3,2,3,2,2,2,2,1,2,1,1,1,2,2, 0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, 3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0, 1,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,2,3,3,2,3,1,2,2,2,2,3,2,3,1,1,2,2,1,2,2,1,1,0,2,2,2,2, 0,1,0,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, 3,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0, 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,0,1,0,1,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, 3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,2,2,1,1,1,1,1,1,1,1,2,1,1,0,3,3,3, 0,3,0,2,2,2,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, 2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,2,0,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0, 0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,3,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,0,2,1,0, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, 0,3,1,1,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,0,1,1,1,1,0, 0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,2,1,1,1,1,2,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, 0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0, 2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,1,1,1,0,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,0,1,0,1, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,1,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,2,1,1,0,1,0,1, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,1,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2, 0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, 3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,2,0,1,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0, 0,1,1,1,2,1,2,2,2,0,2,0,2,0,1,1,2,1,1,1,1,2,1,0,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0,1,0,0,0,0,0,1,0,1,2,2,0,1,0,0,1,1,2,2,1,2,0,2,0,0,0,1,2,0,1, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,2,0,2,1,2,0,2,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,1,2,2,0,0,1,0,0,0,1,0,0,1, 1,1,2,1,0,1,1,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,2,1, 0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,1,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1, 2,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,1,2,1,1,2,0,1,0,0,0,1,1,0,1, 1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,0,0,2,1,1,2,0,2,0,0,0,1,1,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,2,2,1,2,1,1,0,1,0,0,0,1,1,0,1, 2,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,2,1,1,1,0,2,1,1,0,0,0,2,1,0,1, 1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,0,2,1,1,0,1,0,0,0,1,1,0,1, 2,2,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,0,1,2,1,0,2,0,0,0,1,1,0,1, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0, 0,1,0,0,2,0,2,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,1, 1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,2,1,1,1,1,1,0,1,0,0,0,0,1,0,1, 0,1,1,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,1,0,0 ); Win1255Model: SequenceModel = ( charToOrderMap: @win1255_CharToOrderMap; precedenceMatrix: @HebrewLangModel; mTypicalPositiveRatio: 0.984004; keepEnglishLetter: FALSE; CharsetID: WINDOWS_1255_CHARSET; ); implementation end. doublecmd-0.8.2/components/chsdet/src/sbseq/LangCyrillicModel.pas0000664000175000017500000004345412014201074024113 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: LangCyrillicModel.pas,v 1.1 2007/05/20 15:46:17 ya_nick Exp $ unit LangCyrillicModel; interface uses nsCore, nsSBCharSetProber; (*KOI8-R language model*) const KOI8R_CharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, //80 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, //90 223,224,225, 68,226,227,228,229,230,231,232,233,234,235,236,237, //a0 238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253, //b0 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, //c0 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, //d0 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, //e0 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70 //f0 ); win1251_CharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, 239,240,241,242,243,244,245,246, 68,247,248,249,250,251,252,253, 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16 ); latin5_CharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, 239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255 ); macCyrillic_CharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, 239,240,241,242,243,244,245,246,247,248,249,250,251,252, 68, 16, 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27,255 ); IBM855_CharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 191,192,193,194, 68,195,196,197,198,199,200,201,202,203,204,205, 206,207,208,209,210,211,212,213,214,215,216,217, 27, 59, 54, 70, 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46,218,219, 220,221,222,223,224, 26, 55, 4, 42,225,226,227,228, 23, 60,229, 230,231,232,233,234,235, 11, 36,236,237,238,239,240,241,242,243, 8, 49, 12, 38, 5, 31, 1, 34, 15,244,245,246,247, 35, 16,248, 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61,249, 250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50,251,252,255 ); IBM866_CharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, 239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255 ); //Model Table: //total sequences: 100% //first 512 sequences: 97.6601% //first 1024 sequences: 2.3389% //rest sequences: 0.1237% //negative sequences: 0.0009% RussianLangModel: array [0..Pred(32*128)] of byte = ( 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,1,3,3,3,2,3,2,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,2,2,2,2,2,0,0,2, 3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,2,3,2,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,2,2,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,2,3,3,1,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, 0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, 0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,2,2,2,3,1,3,3,1,3,3,3,3,2,2,3,0,2,2,2,3,3,2,1,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,2,3,3,3,2,1,2,2,0,1,2,2,2,2,2,2,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,0,2,2,3,3,2,1,2,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,2,3,3,1,2,3,2,2,3,2,3,3,3,3,2,2,3,0,3,2,2,3,1,1,1,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,2,2,2,0,3,3,3,2,2,2,2,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,2,3,2,2,0,1,3,2,1,2,2,1,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,2,1,1,3,0,1,1,1,1,2,1,1,0,2,2,2,1,2,0,1,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,2,3,3,2,2,2,2,1,3,2,3,2,3,2,1,2,2,0,1,1,2,1,2,1,2,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,2,2,2,2,0,2,2,2,2,3,1,1,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, 3,2,3,2,2,3,3,3,3,3,3,3,3,3,1,3,2,0,0,3,3,3,3,2,3,3,3,3,2,3,2,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,3,3,3,3,3,2,2,3,3,0,2,1,0,3,2,3,2,3,0,0,1,2,0,0,1,0,1,2,1,1,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,0,3,0,2,3,3,3,3,2,3,3,3,3,1,2,2,0,0,2,3,2,2,2,3,2,3,2,2,3,0,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,2,3,0,2,3,2,3,0,1,2,3,3,2,0,2,3,0,0,2,3,2,2,0,1,3,1,3,2,2,1,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,1,3,0,2,3,3,3,3,3,3,3,3,2,1,3,2,0,0,2,2,3,3,3,2,3,3,0,2,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,0,0,1,1,1,1,1,2,0,0,1,1,1,1,0,1,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,0,3,2,3,3,2,3,2,0,2,1,0,1,1,0,1,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,2,3,3,3,2,2,2,2,3,1,3,2,3,1,1,2,1,0,2,2,2,2,1,3,1,0, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, 2,2,3,3,3,3,3,1,2,2,1,3,1,0,3,0,0,3,0,0,0,1,1,0,1,2,1,0,0,0,0,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,2,2,1,1,3,3,3,2,2,1,2,2,3,1,1,2,0,0,2,2,1,3,0,0,2,1,1,2,1,1,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,2,3,3,3,3,1,2,2,2,1,2,1,3,3,1,1,2,1,2,1,2,2,0,2,0,0,1,1,0,1,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,3,3,3,3,3,2,1,3,2,2,3,2,0,3,2,0,3,0,1,0,1,1,0,0,1,1,1,1,0,1,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,2,3,3,3,2,2,2,3,3,1,2,1,2,1,0,1,0,1,1,0,1,0,0,2,1,1,1,0,1,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, 3,1,1,2,1,2,3,3,2,2,1,2,2,3,0,2,1,0,0,2,2,3,2,1,2,2,2,2,2,3,1,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,1,1,0,1,1,2,2,1,1,3,0,0,1,3,1,1,1,0,0,0,1,0,1,1,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,1,3,3,3,2,0,0,0,2,1,0,1,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,0,1,0,0,2,3,2,2,2,1,2,2,2,1,2,1,0,0,1,1,1,0,2,0,1,1,1,0,0,1,1, 1,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, 2,3,3,3,3,0,0,0,0,1,0,0,0,0,3,0,1,2,1,0,0,0,0,0,0,0,1,1,0,0,1,1, 1,0,1,0,1,2,0,0,1,1,2,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0, 2,2,3,2,2,2,3,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,0,1,1,1,0,2,1, 1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0, 3,3,3,2,2,2,2,3,2,2,1,1,2,2,2,2,1,1,3,1,2,1,2,0,0,1,1,0,1,0,2,1, 1,1,1,1,1,2,1,0,1,1,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,0, 2,0,0,1,0,3,2,2,2,2,1,2,1,2,1,2,0,0,0,2,1,2,2,1,1,2,2,0,1,1,0,2, 1,1,1,1,1,0,1,1,1,2,1,1,1,2,1,0,1,2,1,1,1,1,0,1,1,1,0,0,1,0,0,1, 1,3,2,2,2,1,1,1,2,3,0,0,0,0,2,0,2,2,1,0,0,0,0,0,0,1,0,0,0,0,1,1, 1,0,1,1,0,1,0,1,1,0,1,1,0,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, 2,3,2,3,2,1,2,2,2,2,1,0,0,0,2,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,1, 1,1,2,1,0,2,0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0, 3,0,0,1,0,2,2,2,3,2,2,2,2,2,2,2,0,0,0,2,1,2,1,1,1,2,2,0,0,0,1,2, 1,1,1,1,1,0,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1, 2,3,2,3,3,2,0,1,1,1,0,0,1,0,2,0,1,1,3,1,0,0,0,0,0,0,0,1,0,0,2,1, 1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0, 2,3,3,3,3,1,2,2,2,2,0,1,1,0,2,1,1,1,2,1,0,1,1,0,0,1,0,1,0,0,2,0, 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,3,3,3,2,0,0,1,1,2,2,1,0,0,2,0,1,1,3,0,0,1,0,0,0,0,0,1,0,1,2,1, 1,1,2,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0, 1,3,2,3,2,1,0,0,2,2,2,0,1,0,2,0,1,1,1,0,1,0,0,0,3,0,1,1,0,0,2,1, 1,1,1,0,1,1,0,0,0,0,1,1,0,1,0,0,2,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0, 3,1,2,1,1,2,2,2,2,2,2,1,2,2,1,1,0,0,0,2,2,2,0,0,0,1,2,1,0,1,0,1, 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1, 3,0,0,0,0,2,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1,0,1, 1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1, 1,3,3,2,2,0,0,0,2,2,0,0,0,1,2,0,1,1,2,0,0,0,0,0,0,0,0,1,0,0,2,1, 0,1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0, 2,3,2,3,2,0,0,0,0,1,1,0,0,0,2,0,2,0,2,0,0,0,0,0,1,0,0,1,0,0,1,1, 1,1,2,0,1,2,1,0,1,1,2,1,1,1,1,1,2,1,1,0,1,0,0,1,1,1,1,1,0,1,1,0, 1,3,2,2,2,1,0,0,2,2,1,0,1,2,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1, 0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,1,0,2,3,1,2,2,2,2,2,2,1,1,0,0,0,1,0,1,0,2,1,1,1,0,0,0,0,1, 1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 2,0,2,0,0,1,0,3,2,1,2,1,2,2,0,1,0,0,0,2,1,0,0,2,1,1,1,1,0,2,0,2, 2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1, 1,2,2,2,2,1,0,0,1,0,0,0,0,0,2,0,1,1,1,1,0,0,0,0,1,0,1,2,0,0,2,0, 1,0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0, 2,1,2,2,2,0,3,0,1,1,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0, 1,2,2,3,2,2,0,0,1,1,2,0,1,2,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1, 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, 2,2,1,1,2,1,2,2,2,2,2,1,2,2,0,1,0,0,0,1,2,2,2,1,2,1,1,1,1,1,2,1, 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,0,1, 1,2,2,2,2,0,1,0,2,2,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0, 0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, 0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,2,2,2,2,0,0,0,2,2,2,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1, 0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,2,2,2,2,0,0,0,0,1,0,0,1,1,2,0,0,0,0,1,0,1,0,0,1,0,0,2,0,0,0,1, 0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, 1,2,2,2,1,1,2,0,2,1,1,1,1,0,2,2,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1, 0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, 1,0,2,1,2,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, 0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, 1,0,0,0,0,2,0,1,2,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1, 0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, 2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0, 0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 ); Koi8rModel: SequenceModel = ( charToOrderMap: @KOI8R_CharToOrderMap; precedenceMatrix: @RussianLangModel; mTypicalPositiveRatio: 0.976601; keepEnglishLetter: FALSE; CharsetID: KOI8_R_CHARSET; ); Win1251Model: SequenceModel = ( charToOrderMap: @win1251_CharToOrderMap; precedenceMatrix: @RussianLangModel; mTypicalPositiveRatio: 0.976601; keepEnglishLetter: FALSE; CharsetID: WINDOWS_1251_CHARSET; ); Latin5Model: SequenceModel = ( charToOrderMap: @latin5_CharToOrderMap; precedenceMatrix: @RussianLangModel; mTypicalPositiveRatio: 0.976601; keepEnglishLetter: FALSE; CharsetID: ISO_8859_5_CHARSET; ); MacCyrillicModel: SequenceModel = ( charToOrderMap: @macCyrillic_CharToOrderMap; precedenceMatrix: @RussianLangModel; mTypicalPositiveRatio: 0.976601; keepEnglishLetter: FALSE; CharsetID: X_MAC_CYRILLIC_CHARSET; ); Ibm866Model: SequenceModel = ( charToOrderMap: @IBM866_CharToOrderMap; precedenceMatrix: @RussianLangModel; mTypicalPositiveRatio: 0.976601; keepEnglishLetter: FALSE; CharsetID: IBM866_CHARSET; ); Ibm855Model: SequenceModel = ( charToOrderMap: @IBM855_CharToOrderMap; precedenceMatrix: @RussianLangModel; mTypicalPositiveRatio: 0.976601; keepEnglishLetter: FALSE; CharsetID: IBM855_CHARSET; ); implementation end. doublecmd-0.8.2/components/chsdet/src/sbseq/LangBulgarianModel.pas0000664000175000017500000003201312014201074024232 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: LangBulgarianModel.pas,v 1.1 2007/05/20 15:46:17 ya_nick Exp $ unit LangBulgarianModel; interface uses nsCore, nsSBCharSetProber; (**************************************************************** 255: Control characters that usually does not exist in any text 254: Carriage/Return 253: symbol (punctuation) that does not belong to word 252: 0 - 9 *****************************************************************) //Character Mapping Table: //this talbe is modified base on win1251BulgarianCharToOrderMap, so //only number <64 is sure valid const Latin5_BulgarianCharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, //40 110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, //50 253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, //60 116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, //70 194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, //80 210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225, //90 81,226,227,228,229,230,105,231,232,233,234,235,236, 45,237,238, //a0 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, //b0 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,239, 67,240, 60, 56, //c0 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, //d0 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,241, 42, 16, //e0 62,242,243,244, 58,245, 98,246,247,248,249,250,251, 91,252,253 //f0 ); win1251BulgarianCharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, //40 110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, //50 253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, //60 116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, //70 206,207,208,209,210,211,212,213,120,214,215,216,217,218,219,220, //80 221, 78, 64, 83,121, 98,117,105,222,223,224,225,226,227,228,229, //90 88,230,231,232,233,122, 89,106,234,235,236,237,238, 45,239,240, //a0 73, 80,118,114,241,242,243,244,245, 62, 58,246,247,248,249,250, //b0 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, //c0 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,251, 67,252, 60, 56, //d0 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, //e0 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,253, 42, 16 //f0 ); //Model Table: //total sequences: 100% //first 512 sequences: 96.9392% //first 1024 sequences:3.0618% //rest sequences: 0.2992% //negative sequences: 0.0020% BulgarianLangModel: array [0..Pred(32*128)] of byte = ( 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,2,2,1,2,2, 3,1,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,0,1, 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,0,3,1,0, 0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,1,3,3,3,3,2,2,2,1,1,2,0,1,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,3,3,2,3,2,2,3,3,1,1,2,3,3,2,3,3,3,3,2,1,2,0,2,0,3,0,0, 0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,3,3,1,3,3,3,3,3,2,3,2,3,3,3,3,3,2,3,3,1,3,0,3,0,2,0,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,3,3,3,1,3,3,2,3,3,3,1,3,3,2,3,2,2,2,0,0,2,0,2,0,2,0,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,3,3,1,2,2,3,2,1,1,2,0,2,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,3,3,2,3,3,1,2,3,2,2,2,3,3,3,3,3,2,2,3,1,2,0,2,1,2,0,0, 0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,1,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,2,2,3,1,2,0,1,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,3,3,3,3,3,3,1,1,1,2,2,1,3,1,3,2,2,3,0,0,1,0,1,0,1,0,0, 0,0,0,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,2,2,3,2,2,3,1,2,1,1,1,2,3,1,3,1,2,2,0,1,1,1,1,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,1,3,2,2,3,3,1,2,3,1,1,3,3,3,3,1,2,2,1,1,1,0,2,0,2,0,1, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,2,2,3,3,3,2,2,1,1,2,0,2,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, 3,0,1,2,1,3,3,2,3,3,3,3,3,2,3,2,1,0,3,1,2,1,2,1,2,3,2,1,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,1,3,3,2,3,3,2,2,2,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,3,3,3,3,0,3,3,3,3,3,2,1,1,2,1,3,3,0,3,1,1,1,1,3,2,0,1,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, 3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,1,1,3,1,3,3,2,3,2,2,2,3,0,2,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,2,3,3,2,2,3,2,1,1,1,1,1,3,1,3,1,1,0,0,0,1,0,0,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,2,3,2,0,3,2,0,3,0,2,0,0,2,1,3,1,0,0,1,0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,2,1,1,1,1,2,1,1,2,1,1,1,2,2,1,2,1,1,1,0,1,1,0,1,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,2,1,3,1,1,2,1,3,2,1,1,0,1,2,3,2,1,1,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,3,3,3,3,2,2,1,0,1,0,0,1,0,0,0,2,1,0,3,0,0,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,2,3,2,3,3,1,3,2,1,1,1,2,1,1,2,1,3,0,1,0,0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,1,1,2,2,3,3,2,3,2,2,2,3,1,2,2,1,1,2,1,1,2,2,0,1,1,0,1,0,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,2,1,3,1,0,2,2,1,3,2,1,0,0,2,0,2,0,1,0,0,0,0,0,0,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, 3,3,3,3,3,3,1,2,0,2,3,1,2,3,2,0,1,3,1,2,1,1,1,0,0,1,0,0,2,2,2,3, 2,2,2,2,1,2,1,1,2,2,1,1,2,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,1, 3,3,3,3,3,2,1,2,2,1,2,0,2,0,1,0,1,2,1,2,1,1,0,0,0,1,0,1,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, 3,3,2,3,3,1,1,3,1,0,3,2,1,0,0,0,1,2,0,2,0,1,0,0,0,1,0,1,2,1,2,2, 1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,2,1,1,1,0,0,0,0,0,1,1,0,0, 3,1,0,1,0,2,3,2,2,2,3,2,2,2,2,2,1,0,2,1,2,1,1,1,0,1,2,1,2,2,2,1, 1,1,2,2,2,2,1,2,1,1,0,1,2,1,2,2,2,1,1,1,0,1,1,1,1,2,0,1,0,0,0,0, 2,3,2,3,3,0,0,2,1,0,2,1,0,0,0,0,2,3,0,2,0,0,0,0,0,1,0,0,2,0,1,2, 2,1,2,1,2,2,1,1,1,2,1,1,1,0,1,2,2,1,1,1,1,1,0,1,1,1,0,0,1,2,0,0, 3,3,2,2,3,0,2,3,1,1,2,0,0,0,1,0,0,2,0,2,0,0,0,1,0,1,0,1,2,0,2,2, 1,1,1,1,2,1,0,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0, 2,3,2,3,3,0,0,3,0,1,1,0,1,0,0,0,2,2,1,2,0,0,0,0,0,0,0,0,2,0,1,2, 2,2,1,1,1,1,1,2,2,2,1,0,2,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0, 3,3,3,3,2,2,2,2,2,0,2,1,1,1,1,2,1,2,1,1,0,2,0,1,0,1,0,0,2,0,1,2, 1,1,1,1,1,1,1,2,2,1,1,0,2,0,1,0,2,0,0,1,1,1,0,0,2,0,0,0,1,1,0,0, 2,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,0,0,0,1,2,0,1,2, 2,2,2,1,1,2,1,1,2,2,2,1,2,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,0, 2,3,3,3,3,0,2,2,0,2,1,0,0,0,1,1,1,2,0,2,0,0,0,3,0,0,0,0,2,0,2,2, 1,1,1,2,1,2,1,1,2,2,2,1,2,0,1,1,1,0,1,1,1,1,0,2,1,0,0,0,1,1,0,0, 2,3,3,3,3,0,2,1,0,0,2,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,0,0,2,0,1,2, 1,1,1,2,1,1,1,1,2,2,2,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,1,0,0, 3,3,2,2,3,0,1,0,1,0,0,0,0,0,0,0,1,1,0,3,0,0,0,0,0,0,0,0,1,0,2,2, 1,1,1,1,1,2,1,1,2,2,1,2,2,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0, 3,1,0,1,0,2,2,2,2,3,2,1,1,1,2,3,0,0,1,0,2,1,1,0,1,1,1,1,2,1,1,1, 1,2,2,1,2,1,2,2,1,1,0,1,2,1,2,2,1,1,1,0,0,1,1,1,2,1,0,1,0,0,0,0, 2,1,0,1,0,3,1,2,2,2,2,1,2,2,1,1,1,0,2,1,2,2,1,1,2,1,1,0,2,1,1,1, 1,2,2,2,2,2,2,2,1,2,0,1,1,0,2,1,1,1,1,1,0,0,1,1,1,1,0,1,0,0,0,0, 2,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,3,2,2,1,1,1,1,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,3,2,0,1,2,0,1,2,1,1,0,1,0,1,2,1,2,0,0,0,1,1,0,0,0,1,0,0,2, 1,1,0,0,1,1,0,1,1,1,1,0,2,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0, 2,0,0,0,0,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,1, 1,2,2,2,2,1,1,2,1,2,1,1,1,0,2,1,2,1,1,1,0,2,1,1,1,1,0,1,0,0,0,0, 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, 1,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,3,2,0,0,0,0,1,0,0,0,0,0,0,1,1,0,2,0,0,0,0,0,0,0,0,1,0,1,2, 1,1,1,1,1,1,0,0,2,2,2,2,2,0,1,1,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1, 2,3,1,2,1,0,1,1,0,2,2,2,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,2, 1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0, 2,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,2,2, 1,1,1,1,1,0,0,1,2,1,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, 1,2,2,2,2,0,0,2,0,1,1,0,0,0,1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,1,1, 0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, 1,2,2,3,2,0,0,1,0,0,1,0,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,0,0,2, 1,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, 2,1,2,2,2,1,2,1,2,2,1,1,2,1,1,1,0,1,1,1,1,2,0,1,0,1,1,1,1,0,1,1, 1,1,2,1,1,1,1,1,1,0,0,1,2,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0, 1,0,0,1,3,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,1,0,0,1,0,2,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,1, 0,2,0,1,0,0,1,1,2,0,1,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, 1,2,2,2,2,0,1,1,0,2,1,0,1,1,1,0,0,1,0,2,0,1,0,0,0,0,0,0,0,0,0,1, 0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, 0,1,0,1,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, 2,0,1,0,0,1,2,1,1,1,1,1,1,2,2,1,0,0,1,0,1,0,0,0,0,1,1,1,1,0,0,0, 1,1,2,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,1,2,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, 1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,2,0,0,2,0,1,0,0,1,0,0,1, 1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, 1,1,1,1,1,1,1,2,0,0,0,0,0,0,2,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 ); Latin5BulgarianModel: SequenceModel = ( charToOrderMap: @Latin5_BulgarianCharToOrderMap; precedenceMatrix: @BulgarianLangModel; mTypicalPositiveRatio: 0.969392; keepEnglishLetter: FALSE; CharsetID: ISO_8859_5_CHARSET; ); Win1251BulgarianModel: SequenceModel = ( charToOrderMap: @win1251BulgarianCharToOrderMap; precedenceMatrix: @BulgarianLangModel; mTypicalPositiveRatio: 0.969392; keepEnglishLetter: FALSE; CharsetID: WINDOWS_BULGARIAN_CHARSET; ); implementation end. doublecmd-0.8.2/components/chsdet/src/sbseq/LangGreekModel.pas0000664000175000017500000003161312014201074023370 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: LangGreekModel.pas,v 1.1 2007/05/20 15:46:17 ya_nick Exp $ unit LangGreekModel; interface uses nsCore, nsSBCharSetProber; (**************************************************************** 255: Control characters that usually does not exist in any text 254: Carriage/Return 253: symbol (punctuation) that does not belong to word 252: 0 - 9 *****************************************************************) const //Character Mapping Table: Latin7_CharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, //40 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, //50 253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, //60 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, //70 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //80 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //90 +253,233, 90,253,253,253,253,253,253,253,253,253,253, 74,253,253, //a0 253,253,253,253,247,248, 61, 36, 46, 71, 73,253, 54,253,108,123, //b0 110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, //c0 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, //d0 124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, //e0 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253 //f0 ); win1253_CharToOrderMap: array [0..255] of byte = ( 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, //40 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, //50 253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, //60 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, //70 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //80 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //90 +253,233, 61,253,253,253,253,253,253,253,253,253,253, 74,253,253, //a0 253,253,253,253,247,253,253, 36, 46, 71, 73,253, 54,253,108,123, //b0 110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, //c0 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, //d0 124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, //e0 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253 //f0 ); //Model Table: //total sequences: 100% //first 512 sequences: 98.2851% //first 1024 sequences:1.7001% //rest sequences: 0.0359% //negative sequences: 0.0148% GreekLangModel: array [0..Pred(32*128)] of byte = ( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,2,2,3,3,3,3,3,3,3,3,1,3,3,3,0,2,2,3,3,0,3,0,3,2,0,3,3,3,0, 3,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,3,0,3,3,0,3,2,3,3,0,3,2,3,3,3,0,0,3,0,3,0,3,3,2,0,0,0, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, 0,2,3,2,2,3,3,3,3,3,3,3,3,0,3,3,3,3,0,2,3,3,0,3,3,3,3,2,3,3,3,0, 2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,2,1,3,3,3,3,2,3,3,2,3,3,2,0, 0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,2,3,3,0, 2,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, 0,3,3,3,3,3,2,3,0,0,0,0,3,3,0,3,1,3,3,3,0,3,3,0,3,3,3,3,0,0,0,0, 2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,3,0,3,0,3,3,3,3,3,0,3,2,2,2,3,0,2,3,3,3,3,3,2,3,3,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,3,3,2,2,2,3,3,3,3,0,3,1,3,3,3,3,2,3,3,3,3,3,3,3,2,2,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,3,2,0,3,0,0,0,3,3,2,3,3,3,3,3,0,0,3,2,3,0,2,3,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,0,3,3,3,3,0,0,3,3,0,2,3,0,3,0,3,3,3,0,0,3,0,3,0,2,2,3,3,0,0, 0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,3,2,0,3,2,3,3,3,3,0,3,3,3,3,3,0,3,3,2,3,2,3,3,2,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,2,3,2,3,3,3,3,3,3,0,2,3,2,3,2,2,2,3,2,3,3,2,3,0,2,2,2,3,0, 2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,0,0,0,3,3,3,2,3,3,0,0,3,0,3,0,0,0,3,2,0,3,0,3,0,0,2,0,2,0, 0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,0,0,0,3,3,0,3,3,3,0,0,1,2,3,0, 3,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,3,2,0,0,3,2,2,3,3,0,3,3,3,3,3,2,1,3,0,3,2,3,3,2,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,3,0,2,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,3,0,3,2,3,0,0,3,3,3,0, 3,0,0,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,0,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,2,0,3,2,3,0,0,3,2,3,0, 2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,1,2,2,3,3,3,3,3,3,0,2,3,0,3,0,0,0,3,3,0,3,0,2,0,0,2,3,1,0, 2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,0,3,3,3,3,0,3,0,3,3,2,3,0,3,3,3,3,3,3,0,3,3,3,0,2,3,0,0,3,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,0,3,3,3,0,0,3,0,0,0,3,3,0,3,0,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,0,0,0,3,3,3,3,3,3,0,0,3,0,2,0,0,0,3,3,0,3,0,3,0,0,2,0,2,0, 0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,3,3,0,3,0,2,0,3,2,0,3,2,3,2,3,0,0,3,2,3,2,3,3,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,0,0,2,3,3,3,3,3,0,0,0,3,0,2,1,0,0,3,2,2,2,0,3,0,0,2,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,0,3,3,3,2,0,3,0,3,0,3,3,0,2,1,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,2,3,3,3,0,3,3,3,3,3,3,0,2,3,0,3,0,0,0,2,1,0,2,2,3,0,0,2,2,2,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,0,0,2,3,3,3,2,3,0,0,1,3,0,2,0,0,0,0,3,0,1,0,2,0,0,1,1,1,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,3,1,0,3,0,0,0,3,2,0,3,2,3,3,3,0,0,3,0,3,2,2,2,1,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,0,3,3,3,0,0,3,0,0,0,0,2,0,2,3,3,2,2,2,2,3,0,2,0,2,2,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,2,0,0,0,0,0,0,2,3,0,2,0,2,3,2,0,0,3,0,3,0,3,1,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,3,2,3,3,2,2,3,0,2,0,3,0,0,0,2,0,0,0,0,1,2,0,2,0,2,0, 0,2,0,2,0,2,2,0,0,1,0,2,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,1,0,0,0,0, 0,2,0,3,3,2,0,0,0,0,0,0,1,3,0,2,0,2,2,2,0,0,2,0,3,0,0,2,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,0,2,3,2,0,2,2,0,2,0,2,2,0,2,0,2,2,2,0,0,0,0,0,0,2,3,0,0,0,2, 0,1,2,0,0,0,0,2,2,0,0,0,2,1,0,2,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0, 0,0,2,1,0,2,3,2,2,3,2,3,2,0,0,3,3,3,0,0,3,2,0,0,0,1,1,0,2,0,2,2, 0,2,0,2,0,2,2,0,0,2,0,2,2,2,0,2,2,2,2,0,0,2,0,0,0,2,0,1,0,0,0,0, 0,3,0,3,3,2,2,0,3,0,0,0,2,2,0,2,2,2,1,2,0,0,1,2,2,0,0,3,0,0,0,2, 0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,2,2,0,1,0,0,2,0,0,0,2,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,2,3,3,2,2,0,0,0,2,0,2,3,3,0,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,2, 0,2,2,0,0,2,2,2,2,1,0,0,2,2,0,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0, 0,2,0,3,2,3,0,0,0,3,0,0,2,2,0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,2, 0,0,2,2,0,0,2,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,2,0,0,3,2,0,2,2,2,2,2,0,0,0,2,0,0,0,0,2,0,1,0,0,2,0,1,0,0,0, 0,2,2,2,0,2,2,0,1,2,0,2,2,2,0,2,2,2,2,1,2,2,0,0,2,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, 0,2,0,2,0,2,2,0,0,0,0,1,2,1,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,3,2,3,0,0,2,0,0,0,2,2,0,2,0,0,0,1,0,0,2,0,2,0,2,2,0,0,0,0, 0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0, 0,2,2,3,2,2,0,0,0,0,0,0,1,3,0,2,0,2,2,0,0,0,1,0,2,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,2,0,2,0,3,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 0,0,2,0,0,0,0,1,1,0,0,2,1,2,0,2,2,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0, 0,3,0,2,2,2,0,0,2,0,0,0,2,0,0,0,2,3,0,2,0,0,0,0,0,0,2,2,0,0,0,2, 0,1,2,0,0,0,1,2,2,1,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,2,1,2,0,2,2,0,2,0,0,2,0,0,0,0,1,2,1,0,2,1,0,0,0,0,0,0,0,0,0,0, 0,0,2,0,0,0,3,1,2,2,0,2,0,0,0,0,2,0,0,0,2,0,0,3,0,0,0,0,2,2,2,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,2,1,0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,2, 0,2,2,0,0,2,2,2,2,2,0,1,2,0,0,0,2,2,0,1,0,2,0,0,2,2,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,2, 0,1,2,0,0,0,0,2,2,1,0,1,0,1,0,2,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0, 0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,1,0,0,0,0,0,0,2, 0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0, 0,2,2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,1, 0,0,2,0,0,0,0,1,2,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0, 0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,0,0,0,2, 0,0,1,0,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, 0,3,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,2, 0,0,2,0,0,0,0,2,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,2,0,2,2,1,0,0,0,0,0,0,2,0,0,2,0,2,2,2,0,0,0,0,0,0,2,0,0,0,0,2, 0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0, 0,0,3,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0, 0,2,2,2,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1, 0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, 0,2,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,2,0,0,0, 0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,2,0,2,0,0,0, 0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ); Latin7Model: SequenceModel = ( charToOrderMap: @Latin7_CharToOrderMap; precedenceMatrix: @GreekLangModel; mTypicalPositiveRatio: 0.982851; keepEnglishLetter: FALSE; CharsetID: ISO_8859_7_CHARSET; ); Win1253Model: SequenceModel = ( charToOrderMap: @win1253_CharToOrderMap; precedenceMatrix: @GreekLangModel; mTypicalPositiveRatio: 0.982851; keepEnglishLetter: FALSE; CharsetID: WINDOWS_1253_CHARSET; ); implementation end. doublecmd-0.8.2/components/chsdet/src/nsCodingStateMachine.pas0000664000175000017500000000710512014201074023464 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsCodingStateMachine.pas,v 1.3 2007/05/26 13:09:38 ya_nick Exp $ unit nsCodingStateMachine; {$R-} interface uses nsCore; type nsSMState = ( eStart = 0, eError = 1, eItsMe = 2 ); (*state machine model*) type SMModel = record classTable: Pointer; //nsPkgInt; classFactor: PRUint32; stateTable: Pointer; //nsPkgInt; charLenTable: Pointer; // pByteArray; // array of byte; // pPRUint32; CharsetID: eInternalCharsetID; end; pSMModel = ^SMModel; type TnsCodingStateMachine = class (TObject) protected mCurrentState: nsSMState; mCurrentCharLen: PRUint32; mCurrentBytePos: PRUint32; mModel: SMModel; public Enabled: Boolean; constructor Create(sm: SMModel); destructor Destroy; override; function NextState(c: char): nsSMState; function GetCurrentCharLen: PRUint32; procedure Reset; function GetCharsetID: eInternalCharsetID; property LangModel: SMModel read mModel; end; implementation { TnsCodingStateMachine } constructor TnsCodingStateMachine.Create(sm: SMModel); begin mCurrentState:= eStart; mModel := sm; Enabled := true; end; destructor TnsCodingStateMachine.Destroy; begin mModel.classTable := nil; mModel.stateTable := nil; mModel.charLenTable := nil; inherited; end; function TnsCodingStateMachine.NextState(c: char): nsSMState; var byteCls: PRUint32; begin if not Enabled then begin Result := eError; exit; end; (*for each byte we get its class , if it is first byte, we also get byte length*) byteCls := pByteArray(mModel.classTable)[integer(c)]; if mCurrentState = eStart then begin mCurrentBytePos := 0; mCurrentCharLen := pByteArray(mModel.charLenTable)[byteCls]; end; (*from byte's class and stateTable, we get its next state*) mCurrentState := nsSMState(pByteArray(mModel.stateTable)[cardinal(mCurrentState) * mModel.classFactor + byteCls]); inc(mCurrentBytePos); //if mCurrentBytePos > mCurrentCharLen then // mCurrentState := eError; Result:= mCurrentState; end; function TnsCodingStateMachine.GetCurrentCharLen: PRUint32; begin Result:= mCurrentCharLen; end; procedure TnsCodingStateMachine.Reset; begin mCurrentState:= eStart; end; function TnsCodingStateMachine.GetCharsetID: eInternalCharsetID; begin Result:= mModel.CharsetID; end; end. doublecmd-0.8.2/components/chsdet/src/CustomDetector.pas0000664000175000017500000000277412014201074022405 0ustar alexxalexxunit CustomDetector; interface uses {$I dbg.inc} nscore; type TCustomDetector = class(TObject) protected mState: eProbingState; mEnabled: Boolean; // procedure Init; virtual; abstract; procedure SetEnabled(NewValue: Boolean); virtual; function GetEnabled: Boolean; virtual; public constructor Create; virtual; function GetDetectedCharset: eInternalCharsetID; virtual; abstract; function HandleData(aBuf: PChar; aLen: integer): eProbingState; virtual; function GetState: eProbingState; virtual; function GetConfidence: float; virtual; abstract; procedure Reset; virtual; {$ifdef DEBUG_chardet} procedure DumpStatus(Dump: string); virtual; {$endif} property Enabled: Boolean read GetEnabled write SetEnabled; end; implementation { TCustomDetector } constructor TCustomDetector.Create; begin mEnabled := true; end; function TCustomDetector.GetEnabled: Boolean; begin Result := mEnabled; end; procedure TCustomDetector.SetEnabled(NewValue: Boolean); begin mEnabled := NewValue; end; function TCustomDetector.GetState: eProbingState; begin Result := mState; end; function TCustomDetector.HandleData(aBuf: PChar; aLen: integer): eProbingState; begin if not mEnabled then begin mState := psNotMe; end; Result := mState; end; procedure TCustomDetector.Reset; begin mState := psDetecting; end; {$ifdef DEBUG_chardet} procedure TCustomDetector.DumpStatus(Dump: string); begin addDump(Dump); end; {$endif} end. doublecmd-0.8.2/components/chsdet/src/EUCSampler.pas0000664000175000017500000001002112014201074021361 0ustar alexxalexxunit EUCSampler; interface const FreqSize = 94; type rEUCStatistics = record mFirstByteFreq: array[0..Pred(FreqSize)] of Double; mFirstByteStdDev, mFirstByteMean, mFirstByteWeight: Double; mSecoundByteFreq: array [0..Pred(FreqSize)] of Double; mSecoundByteStdDev, mSecoundByteMean, mSecoundByteWeight: Double; end; prEUCStatistics = ^rEUCStatistics; type TEUCSampler = class (TObject) private mTotal, mThreshold, mState: integer; mFirstByteCnt: array [0..Pred(FreqSize)] of integer; mSecondByteCnt: array [0..Pred(FreqSize)] of integer; mFirstByteFreq: array [0..Pred(FreqSize)] of double; mSecondByteFreq: array [0..Pred(FreqSize)] of double; public constructor Create; destructor Destroy; override; function Sample(aIn: pChar; aLen: integer): Boolean; function GetSomeData: Boolean; function EnoughData: Boolean; procedure CalFreq; function GetScore(const aFirstByteFreq: array of Double; aFirstByteWeight: Double; const aSecondByteFreq: array of Double; aSecondByteWeight: Double): double; overload; virtual; function GetScore(const array1, array2: array of Double): double; overload; virtual; procedure Reset; end; implementation { TEUCSampler } procedure TEUCSampler.CalFreq; var i: integer; begin for i := 0 to Pred(FreqSize) do begin mFirstByteFreq[i] := mFirstByteCnt[i] / mTotal; mSecondByteFreq[i] := mSecondByteCnt[i] / mTotal; end; end; constructor TEUCSampler.Create; begin inherited; Reset; end; destructor TEUCSampler.Destroy; begin inherited; end; function TEUCSampler.EnoughData: Boolean; begin Result := mTotal > mThreshold; end; function TEUCSampler.GetScore(const aFirstByteFreq: array of Double; aFirstByteWeight: Double; const aSecondByteFreq: array of Double; aSecondByteWeight: Double): double; begin Result := aFirstByteWeight * GetScore(aFirstByteFreq, mFirstByteFreq) + aSecondByteWeight * GetScore(aSecondByteFreq, mSecondByteFreq); end; function TEUCSampler.GetScore(const array1, array2: array of Double): double; var s, sum: Double; i: integer; begin sum := 0.0; for i := 0 to Pred(FreqSize) do begin s := array1[i] - array2[i]; sum := sum + s * s; end; Result := sqrt(sum) / (FreqSize*1.0); end; function TEUCSampler.GetSomeData: Boolean; begin Result := mTotal > 1; end; procedure TEUCSampler.Reset; var i: integer; begin mTotal := 0; mThreshold := 200; mState := 0; for i := 0 to Pred(FreqSize) do begin mFirstByteCnt[i] := 0; mSecondByteCnt[i] := 0; end; end; function TEUCSampler.Sample(aIn: pChar; aLen: integer): Boolean; const MAX_LENGTH: integer = MaxInt;// $80000000; var i: integer; p: pChar; begin if (mState = 1) then begin Result := FALSE; exit; end; p := aIn; if (aLen + mTotal > MAX_LENGTH) then aLen := MAX_LENGTH - mTotal; i := 0; while (i < aLen) and (mState <> 1) do begin case mState of 0: if (byte(p^) and $0080) > 0 then begin if (byte(p^) = $00ff) or ( byte(p^) < $00a1) then mState := 1 else begin Inc(mTotal); Inc(mFirstByteCnt[byte(p^) - $00a1]); mState := 2; end; end; 1: begin end; 2: if ( byte(p^) and $0080) > 0 then begin if(byte(p^) = $00ff) or (byte(p^) < $00a1) then mState := 1 else begin Inc(mTotal); Inc(mSecondByteCnt[byte(p^) - $00a1]); mState := 0; end; end else mState := 1; else mState := 1; end; Inc(i); Inc(p); end; Result := ( mState <> 1 ); end; end. doublecmd-0.8.2/components/chsdet/src/nsGroupProber.pas0000664000175000017500000001410612014201074022240 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsGroupProber.pas,v 1.2 2007/05/26 13:09:38 ya_nick Exp $ unit nsGroupProber; interface uses {$I dbg.inc} nsCore, CustomDetector; type TnsGroupProber = class(TCustomDetector) protected mNumOfProbers: integer; mProbers: array of TCustomDetector; mIsActive: array of Boolean; mBestGuess: integer; mActiveNum: integer; mProberStates: array of eProbingState; public constructor Create; override; destructor Destroy; override; procedure Reset; override; function HandleData(aBuf: PChar; aLen: integer): eProbingState; override; function GetDetectedCharset: eInternalCharsetID; override; function GetConfidence: float; override; function EnableCharset(Charset: eInternalCharsetID; NewValue: Boolean): Boolean; {$ifdef DEBUG_chardet} procedure DumpStatus(Dump: string); override; {$endif} end; implementation uses SysUtils {$ifdef DEBUG_chardet} ,TypInfo {$endif} ; { TnsGroupProber } constructor TnsGroupProber.Create; begin inherited Create; Self.Reset; end; destructor TnsGroupProber.Destroy; var i: integer; begin for i := 0 to Pred(mNumOfProbers) do if mProbers[i] <> nil then mProbers[i].Free; SetLength(mProbers, 0); SetLength(mProberStates, 0); SetLength(mIsActive, 0); inherited; end; function TnsGroupProber.GetDetectedCharset: eInternalCharsetID; begin (*if we have no answer yet*) if mBestGuess = -1 then begin GetConfidence; (*no charset seems positive*) if mBestGuess = -1 then mBestGuess:= 0; (*we will use default.*) end; Result := mProbers[mBestGuess].GetDetectedCharset; end; function TnsGroupProber.HandleData(aBuf: PChar; aLen: integer): eProbingState; var i: integer; begin {$IFDEF DEBUG_chardet} AddDump('Group Prober - HandleData - start'); {$endif} for i:=0 to Pred(mNumOfProbers) do begin if (mProberStates[i] = psNotMe) or (mProberStates[i] = psFoundIt) then continue; mProberStates[i] := mProbers[i].HandleData(aBuf, aLen); if mProberStates[i] = psFoundIt then begin mBestGuess := i; mState := psFoundIt; break; end else if mProberStates[i] = psNotMe then begin mIsActive[i] := FALSE; dec(mActiveNum); if mActiveNum <= 0 then begin mState := psNotMe; break; end; end; end; Result := mState; {$IFDEF DEBUG_chardet} DumpStatus('Group Prober - HandleData - exit'); {$endif} end; procedure TnsGroupProber.Reset; var i: integer; begin mActiveNum := 0; for i := 0 to Pred(mNumOfProbers) do begin if mProbers[i] <> nil then begin mProbers[i].Reset; mIsActive[i] := mProbers[i].Enabled; if mProbers[i].Enabled then begin mProberStates[i] := psDetecting; inc(mActiveNum); end else mProberStates[i] := psNotMe; end else mIsActive[i] := FALSE; end; mBestGuess := -1; mEnabled := (mActiveNum > 0); if mEnabled then mState := psDetecting else mState := psNotMe; end; function TnsGroupProber.GetConfidence: float; var i: integer; bestConf: float; cf: float; begin bestConf := 0.0; case mState of psFoundIt: begin Result := SURE_YES; (*sure yes*) exit; end; psNotMe: begin Result := SURE_NO; (*sure no*) exit; end; else for i := 0 to Pred(mNumOfProbers) do begin if not mIsActive[i] then continue; cf := mProbers[i].GetConfidence; if bestConf < cf then begin bestConf := cf; mBestGuess := i; end; end; end;{case} {$IFDEF DEBUG_chardet} DumpStatus('Group Prober - GetConfidience'); {$endif} Result := bestConf; end; function TnsGroupProber.EnableCharset(Charset: eInternalCharsetID; NewValue: Boolean): Boolean; var i: integer; begin for i := 0 to Pred(mNumOfProbers) do if mProbers[i].GetDetectedCharset = Charset then begin Result := true; mProbers[i].Enabled := NewValue; exit; end; Result := false; end; {$ifdef DEBUG_chardet} procedure TnsGroupProber.DumpStatus(Dump: string); var i: integer; begin inherited DumpStatus(Dump); inherited DumpStatus(Format('%30s - %5s - %5s', ['Prober', 'Active', 'Conf'])); for i := 0 to Pred(mNumOfProbers) do inherited DumpStatus(Format('%30s - %5s - %1.5f', [GetEnumName(TypeInfo(eInternalCharsetID), integer(mProbers[i].GetDetectedCharset)), BoolToStr(mIsActive[i], True), mProbers[i].GetConfidence])); end; {$endif} end. doublecmd-0.8.2/components/chsdet/src/nsMBCSMultiProber.pas0000664000175000017500000002153713023052076022720 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsMBCSMultiProber.pas,v 1.2 2007/05/26 13:09:38 ya_nick Exp $ unit nsMBCSMultiProber; interface uses {$I dbg.inc} nsCore, MultiModelProber, JpCntx, CharDistribution; type TnsMBCSMultiProber = class (TMultiModelProber) private mDistributionAnalysis: array of TCharDistributionAnalysis; mContextAnalysis: array of TJapaneseContextAnalysis; mBestGuess: integer; function RunStatAnalyse(aBuf: PChar; aLen: integer): eProbingState; function GetConfidenceFor(index: integer): double; reintroduce; public constructor Create; reintroduce; destructor Destroy; override; function HandleData(aBuf: PChar; aLen: integer): eProbingState; override; function GetConfidence: double; override; procedure Reset; override; {$ifdef DEBUG_chardet} procedure DumpStatus(Dump: string); override; {$endif} end; implementation uses SysUtils, nsCodingStateMachine {$ifdef DEBUG_chardet} ,TypInfo {$endif} ; {$I '.\mbclass\SJISLangModel.inc'} {$I '.\mbclass\EUCJPLangModel.inc'} {$I '.\mbclass\GB18030LangModel.inc'} {$I '.\mbclass\EUCKRLangModel.inc'} {$I '.\mbclass\Big5LangModel.inc'} {$I '.\mbclass\EUCTWLangModel.inc'} { TnsMBCSMultiProber } const NUM_OF_PROBERS = 6; constructor TnsMBCSMultiProber.Create; begin inherited Create; SetLength(mDistributionAnalysis, NUM_OF_PROBERS); SetLength(mContextAnalysis, NUM_OF_PROBERS); AddCharsetModel(SJISLangModel); mDistributionAnalysis[0] := TSJISDistributionAnalysis.Create; mContextAnalysis[0] := TSJISContextAnalysis.Create; AddCharsetModel(EUCJPLangModel); mDistributionAnalysis[1] := TEUCKRDistributionAnalysis.Create; mContextAnalysis[1] := nil; AddCharsetModel(GB18030LangModel); mDistributionAnalysis[2] := TGB2312DistributionAnalysis.Create; mContextAnalysis[2] := nil; AddCharsetModel(EUCKRLangModel); mDistributionAnalysis[3] := TEUCKRDistributionAnalysis.Create; mContextAnalysis[3] := nil; AddCharsetModel(Big5LangModel); mDistributionAnalysis[4] := TBig5DistributionAnalysis.Create; mContextAnalysis[4] := nil; AddCharsetModel(EUCTWLangModel); mDistributionAnalysis[5] := TEUCTWDistributionAnalysis.Create; mContextAnalysis[5] := nil; end; destructor TnsMBCSMultiProber.Destroy; var i: integer; begin inherited; for i := 0 to Pred(mCharsetsCount) do begin if mDistributionAnalysis[i] <> nil then mDistributionAnalysis[i].Free; if mContextAnalysis[i] <> nil then mContextAnalysis[i].Free; end; SetLength(mDistributionAnalysis, 0); SetLength(mContextAnalysis, 0); end; {$ifdef DEBUG_chardet} procedure TnsMBCSMultiProber.DumpStatus(Dump: string); var i: integer; begin AddDump(Dump + ' Current state ' + GetEnumName(TypeInfo(eProbingState), integer(mState))); AddDump(Format('%30s - %10s - %5s', ['Prober', 'State', 'Conf'])); for i := 0 to Pred(mCharsetsCount) do AddDump(Format('%30s - %10s - %1.5f', [GetEnumName(TypeInfo(eInternalCharsetID), integer(mCodingSM[i].GetCharsetID)), GetEnumName(TypeInfo(eProbingState), integer(mSMState[i])), GetConfidenceFor(i) ])); end; {$endif} function TnsMBCSMultiProber.HandleData(aBuf: PChar; aLen: integer): eProbingState; var i: integer; (*do filtering to reduce load to probers*) highbyteBuf: PChar; hptr: PChar; keepNext: Boolean; begin keepNext := TRUE; (*assume previous is not ascii, it will do no harm except add some noise*) highbyteBuf := AllocMem(aLen); try hptr:= highbyteBuf; if hptr = nil then begin Result := mState; exit; end; for i:=0 to Pred(aLen) do begin if (Byte(aBuf[i]) > $80) then begin hptr^ := aBuf[i]; inc(hptr); keepNext:= TRUE; end else begin (*if previous is highbyte, keep this even it is a ASCII*) if keepNext = TRUE then begin hptr^ := aBuf[i]; inc(hptr); keepNext:= FALSE; end; end; end; {$IFDEF DEBUG_chardet} AddDump('MultiByte - HandleData - start'); {$endif} inherited HandleData(highbyteBuf, hptr - highbyteBuf); {$IFDEF DEBUG_chardet} AddDump('MultiByte - HandleData - end'); {$endif} finally FreeMem(highbyteBuf, aLen); end; // if we have more when one candidat then // try statisic analyse if (mState <> psFoundIt) or (mState <> psNotMe) then RunStatAnalyse(aBuf, aLen); Result := mState; end; function TnsMBCSMultiProber.RunStatAnalyse(aBuf: PChar; aLen: integer): eProbingState; var i, c: integer; codingState: nsSMState; charLen: byte; mLastChar: array [0..1] of Char; begin {$IFDEF DEBUG_chardet} AddDump('MultiByte - Stat Analyse - start'); {$endif} for i := 0 to Pred(mCharsetsCount) do begin if (mSMState[i] = psFoundIt) or (mSMState[i] = psNotMe) then continue; if mDistributionAnalysis[i] = nil then continue; for c := 0 to Pred(aLen) do begin codingState := mCodingSM[i].NextState(aBuf[c]); if codingState = eStart then begin charLen := mCodingSM[i].GetCurrentCharLen; if c = 0 then begin mLastChar[1] := aBuf[0]; if mContextAnalysis[i] <> nil then mContextAnalysis[i].HandleOneChar(mLastChar,charLen); mDistributionAnalysis[i].HandleOneChar(mLastChar,charLen); end else begin if mContextAnalysis[i] <> nil then mContextAnalysis[i].HandleOneChar(aBuf+c-1,charLen); mDistributionAnalysis[i].HandleOneChar(aBuf+c-1,charLen); end; end; if (mContextAnalysis[i] <> nil) then if mContextAnalysis[i].GotEnoughData and (GetConfidenceFor(i) > SHORTCUT_THRESHOLD) then begin mState := psFoundIt; mDetectedCharset := mCodingSM[i].GetCharsetID; break; end; end; end; {$IFDEF DEBUG_chardet} AddDump('MultiByte - Stat Analyse - EXIT'); {$endif} Result := mState; end; function TnsMBCSMultiProber.GetConfidenceFor(index: integer): double; var contxtCf: double; distribCf: double; begin if mContextAnalysis[index] <> nil then contxtCf := mContextAnalysis[index].GetConfidence else contxtCf := -1; distribCf := mDistributionAnalysis[index].GetConfidence; if contxtCf > distribCf then Result := contxtCf else Result := distribCf; end; function TnsMBCSMultiProber.GetConfidence: double; var i: integer; conf, bestConf: double; begin mBestGuess := -1; bestConf := SURE_NO; for i := 0 to Pred(mCharsetsCount) do begin if (mSMState[i] = psFoundIt) or (mSMState[i] = psNotMe) then continue; if mDistributionAnalysis[i] = nil then continue; conf := GetConfidenceFor(i); if conf > bestConf then begin mBestGuess := i; bestConf := conf; end; end; Result := bestConf; if mBestGuess > -1 then mDetectedCharset := mCodingSM[mBestGuess].GetCharsetID else mDetectedCharset := UNKNOWN_CHARSET; end; procedure TnsMBCSMultiProber.Reset; var i: integer; begin inherited Reset; for i := 0 to Pred(mCharsetsCount) do begin if mDistributionAnalysis[i] <> nil then mDistributionAnalysis[i].Reset; if mContextAnalysis[i] <> nil then mContextAnalysis[i].Reset; end; end; end. doublecmd-0.8.2/components/chsdet/src/nsUniversalDetector.pas0000664000175000017500000002756512014201074023451 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsUniversalDetector.pas,v 1.5 2008/06/22 09:04:20 ya_nick Exp $ unit nsUniversalDetector; interface uses {$I dbg.inc} nsCore, CustomDetector; const NUM_OF_CHARSET_PROBERS = 4; type nsInputState = ( ePureAscii = 0, eEscAscii = 1, eHighbyte = 2 ) ; TnsUniversalDetector = class (TObject) protected mInputState: nsInputState; mDone: Boolean; mStart: Boolean; mGotData: Boolean; mLastChar: Char; mDetectedCharset: eInternalCharsetID; mCharSetProbers: array [0..Pred(NUM_OF_CHARSET_PROBERS)] of TCustomDetector; mEscCharSetProber: TCustomDetector; mDetectedBOM: eBOMKind; procedure Report(aCharsetID: eInternalCharsetID); function CheckBOM(aBuf: pChar; aLen: integer): integer; function GetCharsetID(CodePage: integer): eInternalCharsetID; procedure DoEnableCharset(Charset: eInternalCharsetID; SetEnabledTo: Boolean); public constructor Create; destructor Destroy; override; procedure Reset; function HandleData(aBuf: PChar; aLen: integer): nsResult; procedure DataEnd; function GetDetectedCharsetInfo: nsCore.rCharsetInfo; function GetKnownCharset(out KnownCharsets: pChar): integer; procedure GetAbout(out About: rAboutHolder); procedure DisableCharset(CodePage: integer); property Done: Boolean read mDone; property BOMDetected: eBOMKind read mDetectedBOM; end; implementation uses SysUtils, nsGroupProber, nsMBCSMultiProber, nsSBCSGroupProber, nsEscCharsetProber, nsLatin1Prober, MBUnicodeMultiProber; const MINIMUM_THRESHOLD: float = 0.20; AboutInfo: rAboutHolder = ( MajorVersionNr: 0; MinorVersionNr: 2; BuildVersionNr: 6; About: 'Charset Detector Library. Copyright (C) 2006 - 2008, Nick Yakowlew. http://chsdet.sourceforge.net'; ); { TnsUniversalDetector } constructor TnsUniversalDetector.Create; begin inherited Create; mCharSetProbers[0] := TnsMBCSMultiProber.Create; mCharSetProbers[1] := TnsSBCSGroupProber.Create; mCharSetProbers[2] := TnsLatin1Prober.Create; mCharSetProbers[3] := TMBUnicodeMultiProber.Create; mEscCharSetProber := TnsEscCharSetProber.Create; Reset; end; destructor TnsUniversalDetector.Destroy; var i: integer; begin for i := 0 to Pred(NUM_OF_CHARSET_PROBERS) do mCharSetProbers[i].Free; mEscCharSetProber.Free; inherited; end; procedure TnsUniversalDetector.DataEnd; var proberConfidence: float; maxProberConfidence: float; maxProber: PRInt32; i: integer; begin if not mGotData then (* we haven't got any data yet, return immediately *) (* caller program sometimes call DataEnd before anything has been sent to detector*) exit; if mDetectedCharset <> UNKNOWN_CHARSET then begin mDone := TRUE; Report(mDetectedCharset); exit; end; case mInputState of eHighbyte: begin maxProberConfidence := 0.0; maxProber := 0; for i := 0 to Pred(NUM_OF_CHARSET_PROBERS) do begin proberConfidence := mCharSetProbers[i].GetConfidence; if proberConfidence > maxProberConfidence then begin maxProberConfidence := proberConfidence; maxProber := i; end; end; (*do not report anything because we are not confident of it, that's in fact a negative answer*) if maxProberConfidence > MINIMUM_THRESHOLD then Report(mCharSetProbers[maxProber].GetDetectedCharset); end; eEscAscii: begin mDetectedCharset := mEscCharSetProber.GetDetectedCharset; end; else begin mDetectedCharset := PURE_ASCII_CHARSET; end; end;{case} {$ifdef DEBUG_chardet} AddDump('Universal detector - DataEnd'); {$endif} end; function TnsUniversalDetector.HandleData(aBuf: PChar; aLen: integer): nsResult; var i: integer; st: eProbingState; // startAt: integer; //newBuf: pChar; //BufPtr: pChar; //b: integer; //tmpBOM: eBOMKind; begin // startAt := 0; if mDone then begin Result := NS_OK; exit; end; if aLen > 0 then mGotData := TRUE; (*If the data starts with BOM, we know it is Unicode*) if mStart then begin mStart := FALSE; // startAt := CheckBOM(aBuf, aLen); CheckBOM(aBuf, aLen); // case mDetectedBOM of // BOM_UCS4_BE: mDetectedCharset := UCS4_BE_CHARSET; // BOM_UCS4_LE: mDetectedCharset := UCS4_LE_CHARSET; // BOM_UTF16_BE: mDetectedCharset := UTF16_BE_CHARSET; // BOM_UTF16_LE: mDetectedCharset := UTF16_LE_CHARSET; // BOM_UTF8: mDetectedCharset := UTF8_CHARSET; // // BOM_UCS4_2143: mDetectedCharset := UCS4_BE_CHARSET; // BOM_UCS4_3412: mDetectedCharset := UCS4_LE_CHARSET; // end; // TODO - some stuppid ASCII text can starts with BOM. What to do? if mDetectedCharset <> UNKNOWN_CHARSET then begin // mDone := TRUE; // Result := NS_OK; // exit; end; end; {if mStart} for i := 0 to Pred(aLen) do (*other than 0xa0, if every othe character is ascii, the page is ascii*) if (aBuf[i] > #$80) and (aBuf[i] <> #$A0) then begin (*Since many Ascii only page contains NBSP *) (*we got a non-ascii byte (high-byte)*) if mInputState <> eHighbyte then begin (*adjust state*) mInputState := eHighbyte; end; end else begin (*ok, just pure ascii so *) if (mInputState = ePureAscii) and ((aBuf[i] = #$1B) or (aBuf[i] = '{') and (mLastChar = '~')) then (*found escape character or HZ "~{"*) mInputState := eEscAscii; mLastChar := aBuf[i]; end; case mInputState of eEscAscii: begin {$ifdef DEBUG_chardet} AddDump('Universal detector - Escape Detector started'); {$endif} st := mEscCharSetProber.HandleData(aBuf,aLen); if st = psFoundIt then begin mDone := TRUE; mDetectedCharset := mEscCharSetProber.GetDetectedCharset; end; end; eHighbyte: begin {$ifdef DEBUG_chardet} AddDump('Universal detector - HighByte Detector started'); {$endif} for i := 0 to Pred(NUM_OF_CHARSET_PROBERS) do begin //newBuf := AllocMem(aLen+StartAt); //BufPtr := newBuf; //try //tmpBOM := BOM_Not_Found; //if mDetectedBOM = BOM_Not_Found then //begin ////case mCharSetProbers[i].GetDetectedCharset of //// UTF16_BE_CHARSET: tmpBOM := BOM_UCS4_BE; //// UTF16_LE_CHARSET: tmpBOM := BOM_UCS4_LE; //// else //// tmpBOM := BOM_Not_Found; ////end; //tmpBOM := BOM_UTF16_BE; //end; //for b:=0 to integer(KnownBOM[tmpBOM][0])-1 do //begin //BufPtr^ := KnownBOM[tmpBOM][b+1]; //inc(BufPtr); //end; // //for b:=0 to aLen do //begin //BufPtr^ := aBuf[b]; //inc(BufPtr); //end; st := mCharSetProbers[i].HandleData(aBuf,aLen); // st := mCharSetProbers[i].HandleData(newBuf,aLen+startAt); if st = psFoundIt then begin mDone:= TRUE; mDetectedCharset := mCharSetProbers[i].GetDetectedCharset; // Result := NS_OK; break; end; //finally //FreeMem(newBuf, aLen); //end; end; end; else (*pure ascii*) begin (*do nothing here*) end; end;{case} Result := NS_OK; end; procedure TnsUniversalDetector.Report(aCharsetID: eInternalCharsetID); begin if (aCharsetID <> UNKNOWN_CHARSET) and (mDetectedCharset = UNKNOWN_CHARSET) then mDetectedCharset := aCharsetID; end; procedure TnsUniversalDetector.Reset; var i: integer; begin mDone := FALSE; mStart := TRUE; mDetectedCharset := UNKNOWN_CHARSET; mGotData := FALSE; mInputState := ePureAscii; mLastChar := #0; (*illegal value as signal*) mEscCharSetProber.Reset; for i := 0 to Pred(NUM_OF_CHARSET_PROBERS) do mCharSetProbers[i].Reset; mDetectedBOM := BOM_Not_Found; end; function TnsUniversalDetector.GetDetectedCharsetInfo: nsCore.rCharsetInfo; begin Result := KNOWN_CHARSETS[mDetectedCharset]; end; function TnsUniversalDetector.GetKnownCharset(out KnownCharsets: pChar): integer; var s: ANSIstring; i: integer; begin s := ''; for i := integer(low(KNOWN_CHARSETS)) to integer(High(KNOWN_CHARSETS)) do s := s + #10 + KNOWN_CHARSETS[eInternalCharsetID(i)].Name + ' - ' + inttostr(KNOWN_CHARSETS[eInternalCharsetID(i)].CodePage); KnownCharsets := pChar(s); Result := Length(s); end; procedure TnsUniversalDetector.GetAbout(out About: rAboutHolder); begin About := AboutInfo; end; function TnsUniversalDetector.CheckBOM(aBuf: pChar; aLen: integer): integer; function BOMLength(BOM: eBOMKind): integer; begin Result := integer(KnownBOM[BOM, 0]); end; var i, b: integer; Same: Boolean; begin Result := 0; for i := integer(low(KnownBOM))+1 to integer(high(KnownBOM)) do if aLen > BOMLength(eBOMKind(i)) then begin Same := true; for b := 0 to BOMLength(eBOMKind(i)) - 1 do if (aBuf[b] <> KnownBOM[eBOMKind(i), b+1]) then begin Same := false; break; end; if Same then begin mDetectedBOM := eBOMKind(i); Result := BOMLength(mDetectedBOM); exit; end; end; end; procedure TnsUniversalDetector.DisableCharset(CodePage: integer); begin DoEnableCharset(GetCharsetID(CodePage), false); end; function TnsUniversalDetector.GetCharsetID(CodePage: integer): eInternalCharsetID; var i: integer; begin for i := integer(low(KNOWN_CHARSETS))+1 to integer(high(KNOWN_CHARSETS)) do if (KNOWN_CHARSETS[eInternalCharsetID(i)].CodePage = CodePage) then begin Result := eInternalCharsetID(i); exit; end; Result := UNKNOWN_CHARSET; end; procedure TnsUniversalDetector.DoEnableCharset(Charset: eInternalCharsetID; SetEnabledTo: Boolean); var i: integer; begin if Charset = UNKNOWN_CHARSET then exit; for i := 0 to Pred(NUM_OF_CHARSET_PROBERS) do begin if (mCharSetProbers[i] is TnsGroupProber) then begin if TnsGroupProber(mCharSetProbers[i]).EnableCharset(Charset, SetEnabledTo) then exit; end; if (mCharSetProbers[i] is TnsEscCharSetProber) then begin TnsEscCharSetProber(mCharSetProbers[i]).Enabled := SetEnabledTo; end; if (mCharSetProbers[i] is TCustomDetector) then begin if TCustomDetector(mCharSetProbers[i]).GetDetectedCharset = Charset then TCustomDetector(mCharSetProbers[i]).Enabled := SetEnabledTo; end; end; end; end. doublecmd-0.8.2/components/chsdet/src/nsPkg.pas0000664000175000017500000000525412014201074020517 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsPkg.pas,v 1.2 2007/05/20 15:46:11 ya_nick Exp $ unit nsPkg; interface uses nsCore; type nsIdxSft = ( eIdxSft4bits = 3 // NOT used // eIdxSft8bits = 2, // eIdxSft16bits = 1 ); nsSftMsk = ( eSftMsk4bits = 7 // NOT used // eSftMsk8bits = 3, // eSftMsk16bits = 1 ); nsBitSft = ( eBitSft4bits = 2 // NOT used // eBitSft8bits = 3, // eBitSft16bits = 4 ); nsUnitMsk = ( eUnitMsk4bits = $0000000F // NOT used // eUnitMsk8bits = $000000FF, // eUnitMsk16bits = $0000FFFF ); nsPkgInt = record idxsft: nsIdxSft; sftmsk: nsSftMsk; bitsft: nsBitSft; unitmsk: nsUnitMsk; data: pPRUint32; end; pnsPkgInt = ^nsPkgInt; function PCK4BITS(a, b, c, d, e, f, g, h: integer): integer; function GETFROMPCK(i: integer; c: pnsPkgInt): integer; implementation function PCK16BITS(a: integer; b: integer): integer; begin Result:= ((b shl 16) or a); end; function PCK8BITS(a, b, c, d: integer): integer; begin Result:= PCK16BITS(((b shl 8) or a), ((d shl 8) or c)); end; function PCK4BITS(a, b, c, d, e, f, g, h: integer): integer; begin Result:= PCK8BITS(((b shl 4) or a), ((d shl 4) or c), ((f shl 4) or e), ((h shl 4) or g)); end; function GETFROMPCK(i: integer; c: pnsPkgInt): integer; begin Result:= (((aPRUint32(c^.data)[i shr integer(c^.idxsft)]) shr (i and integer(c^.sftmsk) shl integer(c^.bitsft))) and integer(c^.unitmsk)); end; end. doublecmd-0.8.2/components/chsdet/src/chsdIntf.pas0000664000175000017500000000564512014201074021203 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: chsdIntf.pas,v 1.4 2008/06/22 09:04:20 ya_nick Exp $ unit chsdIntf; interface uses nsCore; procedure csd_Reset; stdcall; function csd_HandleData(aBuf: PChar; aLen: integer): integer; stdcall; function csd_Done: boolean; stdcall; procedure csd_DataEnd; stdcall; function csd_GetDetectedCharset: rCharsetInfo; stdcall; function csd_GetKnownCharsets(var KnownCharsets: pChar): integer; stdcall; procedure csd_GetAbout(var About: rAboutHolder); stdcall; function csd_GetDetectedBOM: eBOMKind; stdcall; procedure csd_DisableCharsetCP(CodePage: integer); stdcall; implementation uses nsUniversalDetector; var Detector: TnsUniversalDetector = nil; procedure csd_Reset; stdcall; begin Detector.Reset; end; function csd_HandleData(aBuf: PChar; aLen: integer): integer; stdcall; begin Result := Detector.HandleData(aBuf, aLen); end; function csd_Done: boolean; stdcall; begin Result := Detector.Done; end; procedure csd_DataEnd; stdcall; begin Detector.DataEnd; end; function csd_GetDetectedCharset: rCharsetInfo; stdcall; begin Result := Detector.GetDetectedCharsetInfo; end; function csd_GetKnownCharsets(var KnownCharsets: pChar): integer; stdcall; begin Result := Detector.GetKnownCharset(KnownCharsets); end; procedure csd_GetAbout(var About: rAboutHolder); stdcall; begin Detector.GetAbout(About); end; function csd_GetDetectedBOM: eBOMKind; stdcall; begin Result := Detector.BOMDetected; end; procedure csd_DisableCharsetCP(CodePage: integer); stdcall; begin Detector.DisableCharset(CodePage); end; initialization Detector := TnsUniversalDetector.Create; finalization if Detector <> nil then Detector.Free; end. doublecmd-0.8.2/components/chsdet/src/EUCKRFreq.pas0000664000175000017500000013316512014201074021127 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: EUCKRFreq.pas,v 1.2 2007/05/20 15:46:03 ya_nick Exp $ unit EUCKRFreq; interface //Sampling from about 20M text materials include literature and computer technology (****************************************************************************** * 128 --> 0.79 * 256 --> 0.92 * 512 --> 0.986 * 1024 --> 0.99944 * 2048 --> 0.99999 * * Ideal Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 * Random Distribution Ration = 512 / (2350-512) = 0.279. * * Typical Distribution Ratio *****************************************************************************) uses nsCore; const EUCKR_TYPICAL_DISTRIBUTION_RATIO: float = 6.0; EUCKR_TABLE_SIZE = 2352; //Char to FreqOrder table , EUCKRCharToFreqOrder: array [0..EUCKR_TABLE_SIZE-1] of PRInt16 = ( 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, 1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, 1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, 1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, 1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, 1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, 1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, 1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, 1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, 1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, 1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, 1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, 1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, 1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, 1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, 1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, 1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, 1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, 1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, 1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, 1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, 1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, 1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, 1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, 1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, 1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, 1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, 1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, 1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, 2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, 2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, 2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, 2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, 2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, 1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, 2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, 1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, 2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, 2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, 1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, 2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, 2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, 2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, 1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, 2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, 2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, 2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, 2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, 2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, 2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, 1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, 2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, 2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, 2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, 2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, 2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, 1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, 1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, 2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, 1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, 2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, 1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, 2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, 2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, 2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, 2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, 2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, 1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, 1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, 2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, 1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, 2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, 2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, 1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, 2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, 1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, 2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, 1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, 2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, 2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, 1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, 1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, 2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, 2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, 2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, 2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, 2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, 2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, 1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, 2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, 2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, 2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, 2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, 2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, 2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, 1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, 2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642 //512, 256 (*************************************************************************************** *Everything below is of no interest for detection purpose * *************************************************************************************** 2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658, 2659,2660,2661,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674, 2675,2676,2677,2678,2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690, 2691,2692,2693,2694,2695,2696,2697,2698,2699,1542, 880,2700,2701,2702,2703,2704, 2705,2706,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720, 2721,2722,2723,2724,2725,1543,2726,2727,2728,2729,2730,2731,2732,1544,2733,2734, 2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750, 2751,2752,2753,2754,1545,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765, 2766,1546,2767,1547,2768,2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779, 2780,2781,2782,2783,2784,2785,2786,1548,2787,2788,2789,1109,2790,2791,2792,2793, 2794,2795,2796,2797,2798,2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809, 2810,2811,2812,1329,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824, 2825,2826,2827,2828,2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840, 2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856, 1549,2857,2858,2859,2860,1550,2861,2862,1551,2863,2864,2865,2866,2867,2868,2869, 2870,2871,2872,2873,2874,1110,1330,2875,2876,2877,2878,2879,2880,2881,2882,2883, 2884,2885,2886,2887,2888,2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899, 2900,2901,2902,2903,2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915, 2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,1331, 2931,2932,2933,2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,1552,2944,2945, 2946,2947,2948,2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961, 2962,2963,2964,1252,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976, 2977,2978,2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992, 2993,2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008, 3009,3010,3011,3012,1553,3013,3014,3015,3016,3017,1554,3018,1332,3019,3020,3021, 3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037, 3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,1555,3051,3052, 3053,1556,1557,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066, 3067,1558,3068,3069,3070,3071,3072,3073,3074,3075,3076,1559,3077,3078,3079,3080, 3081,3082,3083,1253,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095, 3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,1152,3109,3110, 3111,3112,3113,1560,3114,3115,3116,3117,1111,3118,3119,3120,3121,3122,3123,3124, 3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140, 3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156, 3157,3158,3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172, 3173,3174,3175,3176,1333,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187, 3188,3189,1561,3190,3191,1334,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201, 3202,3203,3204,3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217, 3218,3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233, 3234,1562,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248, 3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,3264, 3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,1563,3278,3279, 3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,3294,3295, 3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311, 3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,3325,3326,3327, 3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,3339,3340,3341,3342,3343, 3344,3345,3346,3347,3348,3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359, 3360,3361,3362,3363,3364,1335,3365,3366,3367,3368,3369,3370,3371,3372,3373,3374, 3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387,1336,3388,3389, 3390,3391,3392,3393,3394,3395,3396,3397,3398,3399,3400,3401,3402,3403,3404,3405, 3406,3407,3408,3409,3410,3411,3412,3413,3414,1337,3415,3416,3417,3418,3419,1338, 3420,3421,3422,1564,1565,3423,3424,3425,3426,3427,3428,3429,3430,3431,1254,3432, 3433,3434,1339,3435,3436,3437,3438,3439,1566,3440,3441,3442,3443,3444,3445,3446, 3447,3448,3449,3450,3451,3452,3453,3454,1255,3455,3456,3457,3458,3459,1567,1191, 3460,1568,1569,3461,3462,3463,1570,3464,3465,3466,3467,3468,1571,3469,3470,3471, 3472,3473,1572,3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486, 1340,3487,3488,3489,3490,3491,3492,1021,3493,3494,3495,3496,3497,3498,1573,3499, 1341,3500,3501,3502,3503,3504,3505,3506,3507,3508,3509,3510,3511,1342,3512,3513, 3514,3515,3516,1574,1343,3517,3518,3519,1575,3520,1576,3521,3522,3523,3524,3525, 3526,3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541, 3542,3543,3544,3545,3546,3547,3548,3549,3550,3551,3552,3553,3554,3555,3556,3557, 3558,3559,3560,3561,3562,3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573, 3574,3575,3576,3577,3578,3579,3580,1577,3581,3582,1578,3583,3584,3585,3586,3587, 3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603, 3604,1579,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618, 3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,1580,3630,3631,1581,3632, 3633,3634,3635,3636,3637,3638,3639,3640,3641,3642,3643,3644,3645,3646,3647,3648, 3649,3650,3651,3652,3653,3654,3655,3656,1582,3657,3658,3659,3660,3661,3662,3663, 3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679, 3680,3681,3682,3683,3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695, 3696,3697,3698,3699,3700,1192,3701,3702,3703,3704,1256,3705,3706,3707,3708,1583, 1257,3709,3710,3711,3712,3713,3714,3715,3716,1584,3717,3718,3719,3720,3721,3722, 3723,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,3738, 3739,3740,3741,3742,3743,3744,3745,1344,3746,3747,3748,3749,3750,3751,3752,3753, 3754,3755,3756,1585,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,1586,3767, 3768,3769,3770,3771,3772,3773,3774,3775,3776,3777,3778,1345,3779,3780,3781,3782, 3783,3784,3785,3786,3787,3788,3789,3790,3791,3792,3793,3794,3795,1346,1587,3796, 3797,1588,3798,3799,3800,3801,3802,3803,3804,3805,3806,1347,3807,3808,3809,3810, 3811,1589,3812,3813,3814,3815,3816,3817,3818,3819,3820,3821,1590,3822,3823,1591, 1348,3824,3825,3826,3827,3828,3829,3830,1592,3831,3832,1593,3833,3834,3835,3836, 3837,3838,3839,3840,3841,3842,3843,3844,1349,3845,3846,3847,3848,3849,3850,3851, 3852,3853,3854,3855,3856,3857,3858,1594,3859,3860,3861,3862,3863,3864,3865,3866, 3867,3868,3869,1595,3870,3871,3872,3873,1596,3874,3875,3876,3877,3878,3879,3880, 3881,3882,3883,3884,3885,3886,1597,3887,3888,3889,3890,3891,3892,3893,3894,3895, 1598,3896,3897,3898,1599,1600,3899,1350,3900,1351,3901,3902,1352,3903,3904,3905, 3906,3907,3908,3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921, 3922,3923,3924,1258,3925,3926,3927,3928,3929,3930,3931,1193,3932,1601,3933,3934, 3935,3936,3937,3938,3939,3940,3941,3942,3943,1602,3944,3945,3946,3947,3948,1603, 3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964, 3965,1604,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,3976,3977,1353,3978, 3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,1354,3992,3993, 3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009, 4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,1355,4024, 4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040, 1605,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055, 4056,4057,4058,4059,4060,1606,4061,4062,4063,4064,1607,4065,4066,4067,4068,4069, 4070,4071,4072,4073,4074,4075,4076,1194,4077,4078,1608,4079,4080,4081,4082,4083, 4084,4085,4086,4087,1609,4088,4089,4090,4091,4092,4093,4094,4095,4096,4097,4098, 4099,4100,4101,4102,4103,4104,4105,4106,4107,4108,1259,4109,4110,4111,4112,4113, 4114,4115,4116,4117,4118,4119,4120,4121,4122,4123,4124,1195,4125,4126,4127,1610, 4128,4129,4130,4131,4132,4133,4134,4135,4136,4137,1356,4138,4139,4140,4141,4142, 4143,4144,1611,4145,4146,4147,4148,4149,4150,4151,4152,4153,4154,4155,4156,4157, 4158,4159,4160,4161,4162,4163,4164,4165,4166,4167,4168,4169,4170,4171,4172,4173, 4174,4175,4176,4177,4178,4179,4180,4181,4182,4183,4184,4185,4186,4187,4188,4189, 4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205, 4206,4207,4208,4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,1612,4220, 4221,4222,4223,4224,4225,4226,4227,1357,4228,1613,4229,4230,4231,4232,4233,4234, 4235,4236,4237,4238,4239,4240,4241,4242,4243,1614,4244,4245,4246,4247,4248,4249, 4250,4251,4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265, 4266,4267,4268,4269,4270,1196,1358,4271,4272,4273,4274,4275,4276,4277,4278,4279, 4280,4281,4282,4283,4284,4285,4286,4287,1615,4288,4289,4290,4291,4292,4293,4294, 4295,4296,4297,4298,4299,4300,4301,4302,4303,4304,4305,4306,4307,4308,4309,4310, 4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326, 4327,4328,4329,4330,4331,4332,4333,4334,1616,4335,4336,4337,4338,4339,4340,4341, 4342,4343,4344,4345,4346,4347,4348,4349,4350,4351,4352,4353,4354,4355,4356,4357, 4358,4359,4360,1617,4361,4362,4363,4364,4365,1618,4366,4367,4368,4369,4370,4371, 4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387, 4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403, 4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,1619,4417,4418, 4419,4420,4421,4422,4423,4424,4425,1112,4426,4427,4428,4429,4430,1620,4431,4432, 4433,4434,4435,4436,4437,4438,4439,4440,4441,4442,1260,1261,4443,4444,4445,4446, 4447,4448,4449,4450,4451,4452,4453,4454,4455,1359,4456,4457,4458,4459,4460,4461, 4462,4463,4464,4465,1621,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476, 4477,4478,4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,1055,4490,4491, 4492,4493,4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507, 4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,1622,4519,4520,4521,1623, 4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,1360,4536, 4537,4538,4539,4540,4541,4542,4543, 975,4544,4545,4546,4547,4548,4549,4550,4551, 4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567, 4568,4569,4570,4571,1624,4572,4573,4574,4575,4576,1625,4577,4578,4579,4580,4581, 4582,4583,4584,1626,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,1627, 4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611, 4612,4613,4614,4615,1628,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626, 4627,4628,4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642, 4643,4644,4645,4646,4647,4648,4649,1361,4650,4651,4652,4653,4654,4655,4656,4657, 4658,4659,4660,4661,1362,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672, 4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,1629,4683,4684,4685,4686,4687, 1630,4688,4689,4690,4691,1153,4692,4693,4694,1113,4695,4696,4697,4698,4699,4700, 4701,4702,4703,4704,4705,4706,4707,4708,4709,4710,4711,1197,4712,4713,4714,4715, 4716,4717,4718,4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731, 4732,4733,4734,4735,1631,4736,1632,4737,4738,4739,4740,4741,4742,4743,4744,1633, 4745,4746,4747,4748,4749,1262,4750,4751,4752,4753,4754,1363,4755,4756,4757,4758, 4759,4760,4761,4762,4763,4764,4765,4766,4767,4768,1634,4769,4770,4771,4772,4773, 4774,4775,4776,4777,4778,1635,4779,4780,4781,4782,4783,4784,4785,4786,4787,4788, 4789,1636,4790,4791,4792,4793,4794,4795,4796,4797,4798,4799,4800,4801,4802,4803, 4804,4805,4806,1637,4807,4808,4809,1638,4810,4811,4812,4813,4814,4815,4816,4817, 4818,1639,4819,4820,4821,4822,4823,4824,4825,4826,4827,4828,4829,4830,4831,4832, 4833,1077,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847, 4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863, 4864,4865,4866,4867,4868,4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879, 4880,4881,4882,4883,1640,4884,4885,1641,4886,4887,4888,4889,4890,4891,4892,4893, 4894,4895,4896,4897,4898,4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909, 4910,4911,1642,4912,4913,4914,1364,4915,4916,4917,4918,4919,4920,4921,4922,4923, 4924,4925,4926,4927,4928,4929,4930,4931,1643,4932,4933,4934,4935,4936,4937,4938, 4939,4940,4941,4942,4943,4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954, 4955,4956,4957,4958,4959,4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970, 4971,4972,4973,4974,4975,4976,4977,4978,4979,4980,1644,4981,4982,4983,4984,1645, 4985,4986,1646,4987,4988,4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999, 5000,5001,5002,5003,5004,5005,1647,5006,1648,5007,5008,5009,5010,5011,5012,1078, 5013,5014,5015,5016,5017,5018,5019,5020,5021,5022,5023,5024,5025,5026,5027,5028, 1365,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,1649,5040,5041,5042, 5043,5044,5045,1366,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,1650,5056, 5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,5070,5071,5072, 5073,5074,5075,5076,5077,1651,5078,5079,5080,5081,5082,5083,5084,5085,5086,5087, 5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102,5103, 5104,5105,5106,5107,5108,5109,5110,1652,5111,5112,5113,5114,5115,5116,5117,5118, 1367,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,1653,5130,5131,5132, 5133,5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148, 5149,1368,5150,1654,5151,1369,5152,5153,5154,5155,5156,5157,5158,5159,5160,5161, 5162,5163,5164,5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,5176,5177, 5178,1370,5179,5180,5181,5182,5183,5184,5185,5186,5187,5188,5189,5190,5191,5192, 5193,5194,5195,5196,5197,5198,1655,5199,5200,5201,5202,1656,5203,5204,5205,5206, 1371,5207,1372,5208,5209,5210,5211,1373,5212,5213,1374,5214,5215,5216,5217,5218, 5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234, 5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,5245,5246,5247,1657,5248,5249, 5250,5251,1658,1263,5252,5253,5254,5255,5256,1375,5257,5258,5259,5260,5261,5262, 5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278, 5279,5280,5281,5282,5283,1659,5284,5285,5286,5287,5288,5289,5290,5291,5292,5293, 5294,5295,5296,5297,5298,5299,5300,1660,5301,5302,5303,5304,5305,5306,5307,5308, 5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,1376,5322,5323, 5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,1198,5334,5335,5336,5337,5338, 5339,5340,5341,5342,5343,1661,5344,5345,5346,5347,5348,5349,5350,5351,5352,5353, 5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369, 5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385, 5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,5397,5398,1264,5399,5400, 5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,5411,5412,1662,5413,5414,5415, 5416,1663,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430, 5431,5432,5433,5434,5435,5436,5437,5438,1664,5439,5440,5441,5442,5443,5444,5445, 5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461, 5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477, 5478,1154,5479,5480,5481,5482,5483,5484,5485,1665,5486,5487,5488,5489,5490,5491, 5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504,5505,5506,5507, 5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523, 5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539, 5540,5541,5542,5543,5544,5545,5546,5547,5548,1377,5549,5550,5551,5552,5553,5554, 5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570, 1114,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585, 5586,5587,5588,5589,5590,5591,5592,1378,5593,5594,5595,5596,5597,5598,5599,5600, 5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,1379,5615, 5616,5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631, 5632,5633,5634,1380,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646, 5647,5648,5649,1381,1056,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660, 1666,5661,5662,5663,5664,5665,5666,5667,5668,1667,5669,1668,5670,5671,5672,5673, 5674,5675,5676,5677,5678,1155,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688, 5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,1669,5699,5700,5701,5702,5703, 5704,5705,1670,5706,5707,5708,5709,5710,1671,5711,5712,5713,5714,1382,5715,5716, 5717,5718,5719,5720,5721,5722,5723,5724,5725,1672,5726,5727,1673,1674,5728,5729, 5730,5731,5732,5733,5734,5735,5736,1675,5737,5738,5739,5740,5741,5742,5743,5744, 1676,5745,5746,5747,5748,5749,5750,5751,1383,5752,5753,5754,5755,5756,5757,5758, 5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,1677,5769,5770,5771,5772,5773, 1678,5774,5775,5776, 998,5777,5778,5779,5780,5781,5782,5783,5784,5785,1384,5786, 5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798,5799,5800,1679,5801, 5802,5803,1115,1116,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,5814,5815, 5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,5829,5830,5831, 5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844,5845,5846,5847, 5848,5849,5850,5851,5852,5853,5854,5855,1680,5856,5857,5858,5859,5860,5861,5862, 5863,5864,1681,5865,5866,5867,1682,5868,5869,5870,5871,5872,5873,5874,5875,5876, 5877,5878,5879,1683,5880,1684,5881,5882,5883,5884,1685,5885,5886,5887,5888,5889, 5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905, 5906,5907,1686,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, 5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,1687, 5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951, 5952,1688,1689,5953,1199,5954,5955,5956,5957,5958,5959,5960,5961,1690,5962,5963, 5964,5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979, 5980,5981,1385,5982,1386,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993, 5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009, 6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025, 6026,6027,1265,6028,6029,1691,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039, 6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055, 6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,6069,6070,6071, 6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,1692,6085,6086, 6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100,6101,6102, 6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116,6117,6118, 6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,1693,6132,6133, 6134,6135,6136,1694,6137,6138,6139,6140,6141,1695,6142,6143,6144,6145,6146,6147, 6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163, 6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179, 6180,6181,6182,6183,6184,6185,1696,6186,6187,6188,6189,6190,6191,6192,6193,6194, 6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210, 6211,6212,6213,6214,6215,6216,6217,6218,6219,1697,6220,6221,6222,6223,6224,6225, 6226,6227,6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241, 6242,6243,6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,1698,6254,6255,6256, 6257,6258,6259,6260,6261,6262,6263,1200,6264,6265,6266,6267,6268,6269,6270,6271, //1024 6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,6286,6287, 6288,6289,6290,6291,6292,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,1699, 6303,6304,1700,6305,6306,6307,6308,6309,6310,6311,6312,6313,6314,6315,6316,6317, 6318,6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333, 6334,6335,6336,6337,6338,6339,1701,6340,6341,6342,6343,6344,1387,6345,6346,6347, 6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363, 6364,6365,6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379, 6380,6381,6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395, 6396,6397,6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411, 6412,6413,1702,6414,6415,6416,6417,6418,6419,6420,6421,6422,1703,6423,6424,6425, 6426,6427,6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,1704,6439,6440, 6441,6442,6443,6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456, 6457,6458,6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472, 6473,6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488, 6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,1266, 6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518,6519, 6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,6534,6535, 6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,6549,6550,6551, 1705,1706,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565, 6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,6580,6581, 6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597, 6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,6609,6610,6611,6612,6613, 6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,6624,6625,6626,6627,6628,6629, 6630,6631,6632,6633,6634,6635,6636,6637,1388,6638,6639,6640,6641,6642,6643,6644, 1707,6645,6646,6647,6648,6649,6650,6651,6652,6653,6654,6655,6656,6657,6658,6659, 6660,6661,6662,6663,1708,6664,6665,6666,6667,6668,6669,6670,6671,6672,6673,6674, 1201,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689, 6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705, 6706,6707,6708,6709,6710,6711,6712,6713,6714,6715,6716,6717,6718,6719,6720,6721, 6722,6723,6724,6725,1389,6726,6727,6728,6729,6730,6731,6732,6733,6734,6735,6736, 1390,1709,6737,6738,6739,6740,6741,6742,1710,6743,6744,6745,6746,1391,6747,6748, 6749,6750,6751,6752,6753,6754,6755,6756,6757,1392,6758,6759,6760,6761,6762,6763, 6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777,6778,6779, 6780,1202,6781,6782,6783,6784,6785,6786,6787,6788,6789,6790,6791,6792,6793,6794, 6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,1711, 6810,6811,6812,6813,6814,6815,6816,6817,6818,6819,6820,6821,6822,6823,6824,6825, 6826,6827,6828,6829,6830,6831,6832,6833,6834,6835,6836,1393,6837,6838,6839,6840, 6841,6842,6843,6844,6845,6846,6847,6848,6849,6850,6851,6852,6853,6854,6855,6856, 6857,6858,6859,6860,6861,6862,6863,6864,6865,6866,6867,6868,6869,6870,6871,6872, 6873,6874,6875,6876,6877,6878,6879,6880,6881,6882,6883,6884,6885,6886,6887,6888, 6889,6890,6891,6892,6893,6894,6895,6896,6897,6898,6899,6900,6901,6902,1712,6903, 6904,6905,6906,6907,6908,6909,6910,1713,6911,6912,6913,6914,6915,6916,6917,6918, 6919,6920,6921,6922,6923,6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934, 6935,6936,6937,6938,6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950, 6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966, 6967,6968,6969,6970,6971,6972,6973,6974,1714,6975,6976,6977,6978,6979,6980,6981, 6982,6983,6984,6985,6986,6987,6988,1394,6989,6990,6991,6992,6993,6994,6995,6996, 6997,6998,6999,7000,1715,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011, 7012,7013,7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027, 7028,1716,7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042, 7043,7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058, 7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,7074, 7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089,7090, 7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105,7106, 7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122, 7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136,7137,7138, 7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154, 7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167,7168,7169,7170, 7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186, 7187,7188,7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202, 7203,7204,7205,7206,7207,1395,7208,7209,7210,7211,7212,7213,1717,7214,7215,7216, 7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229,7230,7231,7232, 7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245,7246,7247,7248, 7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261,7262,7263,7264, 7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280, 7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,7296, 7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308,7309,7310,7311,7312, 7313,1718,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327, 7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,7343, 7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357,7358,7359, 7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372,7373,7374,7375, 7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391, 7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402,7403,7404,7405,7406,7407, 7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,7418,7419,7420,7421,7422,7423, 7424,7425,7426,7427,7428,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439, 7440,7441,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455, 7456,7457,7458,7459,7460,7461,7462,7463,7464,7465,7466,7467,7468,7469,7470,7471, 7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487, 7488,7489,7490,7491,7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503, 7504,7505,7506,7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519, 7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535, 7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551, 7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567, 7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,7583, 7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598,7599, 7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614,7615, 7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631, 7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643,7644,7645,7646,7647, 7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659,7660,7661,7662,7663, 7664,7665,7666,7667,7668,7669,7670,7671,7672,7673,7674,7675,7676,7677,7678,7679, 7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695, 7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711, 7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727, 7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743, 7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759, 7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775, 7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791, 7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807, 7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823, 7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839, 7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855, 7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871, 7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887, 7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903, 7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919, 7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935, 7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951, 7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967, 7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983, 7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999, 8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015, 8016,8017,8018,8019,8020,8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031, 8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047, 8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063, 8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079, 8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095, 8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111, 8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127, 8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143, 8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159, 8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175, 8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191, 8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207, 8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223, 8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239, 8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255, 8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271, 8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,8285,8286,8287, 8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303, 8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,8315,8316,8317,8318,8319, 8320,8321,8322,8323,8324,8325,8326,8327,8328,8329,8330,8331,8332,8333,8334,8335, 8336,8337,8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351, 8352,8353,8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,8364,8365,8366,8367, 8368,8369,8370,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382,8383, 8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398,8399, 8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415, 8416,8417,8418,8419,8420,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431, 8432,8433,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443,8444,8445,8446,8447, 8448,8449,8450,8451,8452,8453,8454,8455,8456,8457,8458,8459,8460,8461,8462,8463, 8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479, 8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,8495, 8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,8510,8511, 8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527, 8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,8540,8541,8542,8543, 8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557,8558,8559, 8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,8570,8571,8572,8573,8574,8575, 8576,8577,8578,8579,8580,8581,8582,8583,8584,8585,8586,8587,8588,8589,8590,8591, 8592,8593,8594,8595,8596,8597,8598,8599,8600,8601,8602,8603,8604,8605,8606,8607, 8608,8609,8610,8611,8612,8613,8614,8615,8616,8617,8618,8619,8620,8621,8622,8623, 8624,8625,8626,8627,8628,8629,8630,8631,8632,8633,8634,8635,8636,8637,8638,8639, 8640,8641,8642,8643,8644,8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655, 8656,8657,8658,8659,8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671, 8672,8673,8674,8675,8676,8677,8678,8679,8680,8681,8682,8683,8684,8685,8686,8687, 8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703, 8704,8705,8706,8707,8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719, 8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734,8735, 8736,8737,8738,8739,8740,8741 ****************************************************************************************) ); implementation end. doublecmd-0.8.2/components/chsdet/src/chsdet.dof0000664000175000017500000001662111670731366020717 0ustar alexxalexx[FileVersion] Version=6.0 [Compiler] A=8 B=0 C=1 D=1 E=0 F=0 G=1 H=1 I=1 J=1 K=0 L=1 M=0 N=1 O=1 P=1 Q=0 R=0 S=0 T=0 U=1 V=1 W=0 X=1 Y=2 Z=1 ShowHints=1 ShowWarnings=1 UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; [Linker] MapFile=0 OutputObjs=0 ConsoleApp=1 DebugInfo=0 RemoteSymbols=0 MinStackSize=16384 MaxStackSize=1048576 ImageBase=4194304 ExeDescription= [Directories] OutputDir=..\ UnitOutputDir=..\dcu PackageDLLOutputDir= PackageDCPOutputDir= SearchPath=.\mbclass;.\sbseq;.\stat Packages=VCL50;VCLX50;VCLSMP50;QRPT50;VCLDB50;VCLIE50;INETDB50;INET50;NMFAST50;dclocx50;dclaxserver50;DJCL50;JVAPPFRMD5R;JVCORED5R;JVBANDSD5R;JVDLGSD5R;JVCMPD5R;JVCRYPTD5R;JVCTRLSD5R;JVCUSTOMD5R;JVDOCKINGD5R;JVDOTNETCTRLSD5R;JVEDID5R;JVGLOBUSD5R;JVHMID5R;JVINSPECTORD5R;JVINTERPRETERD5R;JVJANSD5R;JVMANAGEDTHREADSD5R;JVMMD5R;JVNETD5R;JVSTDCTRLSD5R;JVPAGECOMPSD5R;JVPLUGIND5R;JVPRINTPREVIEWD5R;JVSYSTEMD5R;JVTIMEFRAMEWORKD5R;JVUIBD5R;JVVALIDATORSD5R;JVWIZARDD5R;JVXPCTRLSD5R;vcl Conditionals= DebugSourceDirs= UsePackages=0 [Parameters] RunParams= HostApplication= Launcher= UseLauncher=0 DebugCWD= [Language] ActiveLang= ProjectLang=$00000407 [Version Info] IncludeVerInfo=1 AutoIncBuild=0 MajorVer=0 MinorVer=2 Release=6 Build=2 Debug=0 PreRelease=0 Special=0 Private=0 DLL=1 Locale=2057 CodePage=1252 [Version Info Keys] CompanyName= FileDescription=Charset detector FileVersion=0.2.6.2 InternalName= LegalCopyright=Nick Yakowlew, ya_nick@users.sourceforge.net LegalTrademarks= OriginalFilename=chsdet.dll ProductName=Charset detector ProductVersion=0.2 Comments=LGPL Licence [Excluded Packages] E:\Data\Yan\Delphi\log4delphi\bin\log4delphi_D6.bpl=Log4Delphi 0.5 c:\program files\borland\delphi6\Bin\DCLNMF60.bpl=NetMasters Fastnet Tools C:\PROGRAM FILES\BORLAND\DELPHI6\PROJECTS\BPL\TBX_D6.BPL=Toolbar2000 -- TBX Extensions (Alex Denisov) C:\PROGRAM FILES\BORLAND\DELPHI6\PROJECTS\BPL\TB2K_D6.BPL=Toolbar2000 Components (Jordan Russell) C:\PROGRAM FILES\BORLAND\DELPHI6\PROJECTS\BPL\TBXDSGN_D6.BPL=Toolbar2000 -- TBX Extensions Design Package (Alex Denisov) C:\PROGRAM FILES\BORLAND\DELPHI6\PROJECTS\BPL\TB2KDSGN_D6.BPL=Toolbar2000 Design Package (Jordan Russell) c:\program files\borland\delphi6\Projects\Bpl\IEDcomp.bpl=Internet EDiting components C:\PROGRAM FILES\BORLAND\DELPHI6\PROJECTS\BPL\TNTUNICODEVCL_D60.BPL=Tnt Unicode Controls c:\program files\borland\delphi6\Projects\Bpl\SmpltCP.bpl=(untitled) c:\program files\borland\delphi6\Projects\Bpl\devFileMonitorPkg.bpl=(untitled) c:\program files\borland\delphi6\Bin\dclsoap60.bpl=Borland SOAP Components c:\program files\borland\delphi6\Projects\Bpl\SpTBXLibDsgn_d6.bpl=Toolbar2000 -- SpTBXLib Design Package c:\program files\borland\delphi6\Projects\Bpl\LSFindReplaceDialogW_6.bpl=LS Find/Replace Dialog for Wide Strings c:\program files\borland\delphi6\Projects\Bpl\Unicode6.bpl=Unicode components c:\program files\borland\delphi6\Projects\Bpl\credit.bpl=(untitled) c:\program files\borland\delphi6\Projects\Bpl\pActivePorts.bpl=LGM ActivePorts Component c:\program files\borland\delphi6\Projects\Bpl\USE.bpl=Unicode Syntax Edit control C:\Program Files\Borland\Delphi6\Projects\Bpl\JvAppFrmD6D.bpl=JVCL Application and Form Components C:\PROGRAM FILES\BORLAND\DELPHI6\PROJECTS\BPL\JVCORED6D.BPL=JVCL Core Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvCmpD6D.bpl=JVCL Non-Visual Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvCryptD6D.bpl=JVCL Encryption and Compression Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvCtrlsD6D.bpl=JVCL Visual Controls C:\Program Files\Borland\Delphi6\Projects\Bpl\JvCustomD6D.bpl=JVCL Custom Controls C:\Program Files\Borland\Delphi6\Projects\Bpl\JvDlgsD6D.bpl=JVCL Dialog Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvDockingD6D.bpl=JVCL Docking Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvGlobusD6D.bpl=JVCL Globus Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvHMID6D.bpl=JVCL HMI Controls design time unit C:\Program Files\Borland\Delphi6\Projects\Bpl\JvJansD6D.bpl=JVCL Jans Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvManagedThreadsD6D.bpl=JVCL Managed Threads C:\Program Files\Borland\Delphi6\Projects\Bpl\JvMMD6D.bpl=JVCL Multimedia and Image Components C:\PROGRAM FILES\BORLAND\DELPHI6\PROJECTS\BPL\JVSTDCTRLSD6D.BPL=JVCL Standard Controls C:\Program Files\Borland\Delphi6\Projects\Bpl\JvPageCompsD6D.bpl=JVCL Page Style Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvPluginD6D.bpl=JVCL Plugin Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvSystemD6D.bpl=JVCL System Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvTimeFrameworkD6D.bpl=JVCL Time Framework C:\Program Files\Borland\Delphi6\Projects\Bpl\JvValidatorsD6D.bpl=JVCL Validators and Error Provider Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvXPCtrlsD6D.bpl=JVCL XP Controls C:\Program Files\Borland\Delphi6\Projects\Bpl\JvBandsD6D.bpl=JVCL Band Objects C:\Program Files\Borland\Delphi6\Projects\Bpl\JvBDED6D.bpl=JVCL BDE Components C:\PROGRAM FILES\BORLAND\DELPHI6\PROJECTS\BPL\JVDBD6D.BPL=JVCL Database Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvDotNetCtrlsD6D.bpl=JVCL DotNet Controls C:\Program Files\Borland\Delphi6\Projects\Bpl\JvEDID6D.bpl=JVCL EDI Components Designtime Package C:\Program Files\Borland\Delphi6\Projects\Bpl\JvInspectorD6D.bpl=JVCL Inspector Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvInterpreterD6D.bpl=JVCL Interpreter Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvNetD6D.bpl=JVCL Network Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvPrintPreviewD6D.bpl=JVCL Print Preview Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvUIBD6D.bpl=JVCL Unified Interbase Components C:\Program Files\Borland\Delphi6\Projects\Bpl\JvWizardD6D.bpl=JVCL Wizard Design Time Package c:\program files\borland\delphi6\Projects\Bpl\components.bpl=Components for tsWebEditor c:\program files\borland\delphi6\Projects\Bpl\CoolTrayIcon_D6plus.bpl=CoolTrayIcon and Friends C:\PROGRAM FILES\BORLAND\DELPHI6\BIN\DCLBDE60.BPL=Borland BDE DB Components C:\PROGRAM FILES\BORLAND\DELPHI6\BIN\DBX60.BPL=Borland SQL Explorer UI Package c:\program files\borland\delphi6\Projects\Bpl\ClassBrowsing.bpl=ClassBrowsing components c:\program files\borland\delphi6\Bin\dclqrt60.bpl=QuickReport Components c:\program files\borland\delphi6\Bin\dclcds60.bpl=Borland Base Cached ClientDataset Component C:\PROGRAM FILES\BORLAND\DELPHI6\BIN\DCLMID60.BPL=Borland MyBase DataAccess Components c:\program files\borland\delphi6\Bin\dclbdecds60.bpl=Borland Local BDE ClientDataset Components c:\program files\borland\delphi6\Bin\dcltee60.bpl=TeeChart Components c:\program files\borland\delphi6\Bin\dcltqr60.bpl=TeeChart for QuickReport Components c:\program files\borland\delphi6\Bin\dclib60.bpl=InterBase Data Access Components c:\program files\borland\delphi6\Bin\dcldbxcds60.bpl=Borland Local DBX ClientDataset Components c:\program files\borland\delphi6\Bin\DBWEBXPRT.BPL=Borland Web Wizard Package c:\program files\borland\delphi6\Projects\Bpl\prgInternet6.bpl=Progsan Internet Components c:\program files\borland\delphi6\Projects\Bpl\Comps_D6.bpl=(untitled) c:\program files\borland\delphi6\Projects\Bpl\SynEdit_D6.bpl=SynEdit component suite c:\program files\borland\delphi6\Projects\Bpl\DevCpp.bpl=Dev-c++ components doublecmd-0.8.2/components/chsdet/src/nsLatin1Prober.pas0000664000175000017500000001537112014201074022301 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsLatin1Prober.pas,v 1.3 2007/05/26 13:09:38 ya_nick Exp $ unit nsLatin1Prober; interface uses nsCore, CustomDetector; type TnsLatin1Prober = class(TCustomDetector) private mLastCharClass: Char; mFreqCounter: array of PRUint32; public constructor Create; override; destructor Destroy; override; function HandleData(aBuf: PChar; aLen: integer): eProbingState; override; function GetDetectedCharset: eInternalCharsetID; override; procedure Reset; override; function GetConfidence: float; override; {$ifdef DEBUG_chardet} procedure DumpStatus; override; {$endif} end; implementation uses SysUtils; const FREQ_CAT_NUM = 4; UDF = 0; (* undefined*) OTH = 1; (*other*) ASC = 2; (* ascii capital letter*) ASS = 3; (* ascii small letter*) ACV = 4; (* accent capital vowel*) ACO = 5; (* accent capital other*) ASV = 6; (* accent small vowel*) ASO = 7; (* accent small other*) CLASS_NUM = 8; (* total classes*) Latin1_CharToClass: array [0..255] of byte = ( OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 00 - 07 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 08 - 0F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 10 - 17 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 18 - 1F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 20 - 27 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 28 - 2F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 30 - 37 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 38 - 3F OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 40 - 47 ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 48 - 4F ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 50 - 57 ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, // 58 - 5F OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 60 - 67 ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 68 - 6F ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 70 - 77 ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, // 78 - 7F OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, // 80 - 87 OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, // 88 - 8F UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 90 - 97 OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, // 98 - 9F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // A0 - A7 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // A8 - AF OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // B0 - B7 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // B8 - BF ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, // C0 - C7 ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, // C8 - CF ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, // D0 - D7 ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, // D8 - DF ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, // E0 - E7 ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, // E8 - EF ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, // F0 - F7 ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO // F8 - FF ); (* 0 : illegal 1 : very unlikely 2 : normal 3 : very likely *) Latin1ClassModel: array [0..63] of byte = ( (* UDF OTH ASC ASS ACV ACO ASV ASO *) (*UDF*) 0, 0, 0, 0, 0, 0, 0, 0, (*OTH*) 0, 3, 3, 3, 3, 3, 3, 3, (*ASC*) 0, 3, 3, 3, 3, 3, 3, 3, (*ASS*) 0, 3, 3, 3, 1, 1, 3, 3, (*ACV*) 0, 3, 3, 3, 1, 2, 1, 2, (*ACO*) 0, 3, 3, 3, 3, 3, 3, 3, (*ASV*) 0, 3, 1, 3, 1, 1, 1, 3, (*ASO*) 0, 3, 1, 3, 1, 1, 3, 3 ); { TnsLatin1Prober } constructor TnsLatin1Prober.Create; begin inherited Create; SetLength(mFreqCounter, FREQ_CAT_NUM); Reset; end; destructor TnsLatin1Prober.Destroy; begin SetLength(mFreqCounter, 0); inherited; end; {$ifdef DEBUG_chardet} procedure TnsLatin1Prober.DumpStatus; begin printf(' Latin1Prober: %1.3f [%s]r'#13#10'',GetConfidence,GetCharSetName); end; {$endif} function TnsLatin1Prober.GetDetectedCharset: eInternalCharsetID; begin Result := WINDOWS_1252_CHARSET; end; function TnsLatin1Prober.GetConfidence: float; var confidence: float; total: cardinal; i: integer; begin if mState = psNotMe then begin Result := SURE_NO; exit; end; total := 0; for i := 0 to Pred(FREQ_CAT_NUM) do total := total + mFreqCounter[i]; if total = 0 then confidence := 0.0 else begin confidence := mFreqCounter[3] * 1.0 / total; confidence := confidence - (mFreqCounter[1] * 20.0 /total); end; if confidence < 0.0 then confidence := 0.0; confidence := confidence * (0.50); (* lower the confidence of latin1 so that other more accurate detector *) (* can take priority.*) Result := confidence; end; function TnsLatin1Prober.HandleData(aBuf: PChar; aLen: integer): eProbingState; var newBuf1: PChar; newLen1: integer; charClass: char; freq: byte; i: integer; begin Result := inherited HandleData(aBuf, aLen); if Result = psNotMe then exit; newBuf1 := nil; newLen1 := 0; newBuf1 := AllocMem(aLen); try if not FilterWithEnglishLetters(aBuf,aLen,newBuf1,newLen1) then begin newBuf1 := aBuf; newLen1 := aLen; end; for i := 0 to Pred(newLen1) do begin charClass := char(Latin1_CharToClass[integer(newBuf1[i])]); freq := Latin1ClassModel[byte(mLastCharClass) * CLASS_NUM + byte(charClass)]; if freq = 0 then begin mState:= psNotMe; break; end; inc(mFreqCounter[freq]); mLastCharClass := charClass; end; finally FreeMem(newBuf1, aLen); end; Result := mState; end; procedure TnsLatin1Prober.Reset; var i: integer; begin mState := psDetecting; mLastCharClass := Char(OTH); for i := 0 to Pred(FREQ_CAT_NUM) do mFreqCounter[i] := 0; end; end. doublecmd-0.8.2/components/chsdet/src/MultiModelProber.pas0000664000175000017500000001331412014201074022656 0ustar alexxalexxunit MultiModelProber; interface uses {$I dbg.inc} nsCore, CustomDetector, nsCodingStateMachine; type TMultiModelProber = class (TCustomDetector) private protected mDetectedCharset: eInternalCharsetID; mActiveSM: integer; mCharsetsCount: integer; mSMState: array of eProbingState; mCodingSM: array of TnsCodingStateMachine; procedure AddCharsetModel(Model: SMModel); public constructor Create; override; destructor Destroy; override; function HandleData(aBuf: PChar; aLen: integer): eProbingState; override; function GetDetectedCharset: eInternalCharsetID; override; procedure Reset; override; function EnableCharset(Charset: eInternalCharsetID; NewValue: Boolean): Boolean; {$ifdef DEBUG_chardet} procedure DumpStatus(Dump: string); override; {$endif} function GetConfidence: float; override; end; implementation {$ifdef DEBUG_chardet} uses SysUtils, TypInfo; {$endif} { TMultiModelProber } constructor TMultiModelProber.Create; begin inherited; mCharsetsCount := 0; end; destructor TMultiModelProber.Destroy; var i: integer; begin for i := 0 to Pred(mCharsetsCount) do begin mCodingSM[i].Free; mCodingSM[i] := nil; end; SetLength(mCodingSM, 0); inherited; end; procedure TMultiModelProber.AddCharsetModel(Model: SMModel); begin inc(mCharsetsCount); SetLength(mCodingSM, mCharsetsCount); SetLength(mSMState, mCharsetsCount); mCodingSM[Pred(mCharsetsCount)] := TnsCodingStateMachine.Create(Model); mSMState[Pred(mCharsetsCount)] := psDetecting; Reset; end; function TMultiModelProber.GetDetectedCharset: eInternalCharsetID; begin Result := mDetectedCharset; end; function TMultiModelProber.HandleData(aBuf: PChar; aLen: integer): eProbingState; var codingState: nsSMState; j: integer; i: integer; begin {$IFDEF DEBUG_chardet} AddDump('Multi Model - HandleData - start'); {$endif} Result := mState; for i := 0 to Pred(aLen) do begin // if mState = psDetecting then // break; for j := mCharsetsCount - 1 downto 0 do begin // skip disabled if (not mCodingSM[j].Enabled) or (mSMState[j] = psNotMe) then continue; (*byte is feed to all active state machine *) codingState := mCodingSM[j].NextState(aBuf[i]); if codingState = eError then begin (*got negative answer for this state machine, make it inactive*) mSMState[j] := psNotMe; dec(mActiveSM); if mActiveSM = 0 then begin mState:= psNotMe; Result:= mState; {$IFDEF DEBUG_chardet} DumpStatus('Multi Model - HandleData - NOT ME!'); {$endif} exit; end; end else if codingState = eItsMe then begin {$IFDEF DEBUG_chardet} DumpStatus('Multi Model - HandleData - FOUND IT!'); {$endif} mSMState[j] := psFoundIt; mState := psFoundIt; mDetectedCharset := mCodingSM[j].GetCharsetID; Result:= mState; exit; end; end; // if codingState = eError end; if mActiveSM = 1 then begin for i := 0 to Pred(mCharsetsCount) do if (mSMState[i] <> psNotMe) then begin // TODO - set confidience ? or.... // signalised that it's not sure if GetConfidence > SURE_NO then begin mSMState[i] := psFoundIt; mState := psFoundIt; mDetectedCharset := mCodingSM[i].GetCharsetID; break; end; end; end else Result := mState; {$IFDEF DEBUG_chardet} DumpStatus('Multi Model - HandleData - EXIT.'); {$endif} end; procedure TMultiModelProber.Reset; var i: integer; begin mState:= psDetecting; for i := 0 to Pred(mCharsetsCount) do begin mCodingSM[i].Reset; if mCodingSM[i].Enabled then mSMState[i] := psDetecting else mSMState[i] := psNotMe; end; mActiveSM := mCharsetsCount; mDetectedCharset := UNKNOWN_CHARSET; end; function TMultiModelProber.EnableCharset(Charset: eInternalCharsetID; NewValue: Boolean): Boolean; var i: integer; begin for i := 0 to Pred(mCharsetsCount) do if mCodingSM[i].GetCharsetID = Charset then begin Result := true; mCodingSM[i].Enabled := NewValue; exit; end; Result := false; end; function TMultiModelProber.GetConfidence: float; var i: integer; begin Result := SURE_NO; case mState of psNotMe: begin Result := SURE_NO; mDetectedCharset := UNKNOWN_CHARSET; end; else for i := 0 to Pred(mCharsetsCount) do if (mSMState[i] = psFoundIt) or ((mSMState[i] = psDetecting) and (mActiveSM = 1)) then begin Result := SURE_YES; mDetectedCharset := mCodingSM[i].GetCharsetID; break; end; end;{case} end; {$ifdef DEBUG_chardet} procedure TMultiModelProber.DumpStatus(Dump: string); var i: integer; begin inherited DumpStatus(Dump + ' Current state ' + GetEnumName(TypeInfo(eProbingState), integer(mState))); inherited DumpStatus(Format('%30s - %5s', ['Prober', 'State' ])); for i := 0 to Pred(mCharsetsCount) do inherited DumpStatus(Format('%30s - %5s', [GetEnumName(TypeInfo(eInternalCharsetID), integer(mCodingSM[i].GetCharsetID)), GetEnumName(TypeInfo(eProbingState), integer(mSMState[i])) ])); end; {$endif} end. doublecmd-0.8.2/components/chsdet/src/Dump.pas0000664000175000017500000000057412014201074020342 0ustar alexxalexxunit Dump; interface const nl = #13#10; var DumpStr: string; procedure AddDump(Dump: string); procedure ShowDump; implementation uses // Windows; UNIT1; procedure AddDump(Dump: string); begin UNIT1.Form1.Memo1.Lines.Add(Dump); // DumpStr := DumpStr + Dump + nl; end; procedure ShowDump; begin // OutputDebugString(pChar(DumpStr)); // DumpStr := ''; end; end. doublecmd-0.8.2/components/chsdet/src/nsHebrewProber.pas0000664000175000017500000003543012014201074022363 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsHebrewProber.pas,v 1.3 2007/05/26 13:09:38 ya_nick Exp $ unit nsHebrewProber; interface uses nsCore, CustomDetector; (* This prober doesn't actually recognize a language or a charset.*) (* It is a helper prober for the use of the Hebrew model probers*) type TnsHebrewProber = class(TCustomDetector) protected mFinalCharLogicalScore: PRInt32; mFinalCharVisualScore: PRInt32; (* The two last characters seen in the previous buffer.*) mPrev: char; mBeforePrev: char; (* These probers are owned by the group prober.*) mLogicalProb: TCustomDetector; mVisualProb: TCustomDetector; public constructor Create; override; destructor Destroy; override; function HandleData(aBuf: PChar; aLen: integer): eProbingState; override; function GetDetectedCharset: eInternalCharsetID; override; procedure Reset; override; function GetState: eProbingState; override; procedure SetModelProbers(logicalPrb: TCustomDetector; visualPrb: TCustomDetector); {$ifdef DEBUG_chardet} procedure DumpStatus; override; {$endif} function isFinal(c: char): Boolean; function isNonFinal(c: char): Boolean; function GetConfidence: float; override; end; implementation (* windows-1255 / ISO-8859-8 code points of interest*) const FINAL_KAF = (#$ea); NORMAL_KAF = (#$eb); FINAL_MEM = (#$ed); NORMAL_MEM = (#$ee); FINAL_NUN = (#$ef); NORMAL_NUN = (#$f0); FINAL_PE = (#$f3); NORMAL_PE = (#$f4); FINAL_TSADI = (#$f5); // YaN - Not used // NORMAL_TSADI = (#$f6); (* Minimum Visual vs Logical final letter score difference.*) (* If the difference is below this, don't rely solely on the final letter score distance.*) MIN_FINAL_CHAR_DISTANCE = (5); (* Minimum Visual vs Logical model score difference.*) (* If the difference is below this, don't rely at all on the model score distance.*) MIN_MODEL_DISTANCE = (0.01); var VISUAL_HEBREW_CHARSET, LOGICAL_HEBREW_CHARSET: eInternalCharsetID; { TnsHebrewProber } constructor TnsHebrewProber.Create; begin inherited Create; mLogicalProb := nil; mVisualProb := nil; VISUAL_HEBREW_CHARSET := ISO_8859_8_CHARSET; LOGICAL_HEBREW_CHARSET := WINDOWS_1255_CHARSET; Reset; end; destructor TnsHebrewProber.Destroy; begin inherited; end; {$ifdef DEBUG_chardet} procedure TnsHebrewProber.DumpStatus; begin printf(' HEB: %d - %d [Logical-Visual score]r'#13#10'',mFinalCharLogicalScore,mFinalCharVisualScore); end; {$endif} (* Make the decision: is it Logical or Visual?*) function TnsHebrewProber.GetDetectedCharset: eInternalCharsetID; var finalsub: PRInt32; modelsub: float; begin (* If the final letter score distance is dominant enough, rely on it.*) finalsub := mFinalCharLogicalScore-mFinalCharVisualScore; if finalsub >= MIN_FINAL_CHAR_DISTANCE then begin Result := LOGICAL_HEBREW_CHARSET; exit; end; if finalsub <= -(MIN_FINAL_CHAR_DISTANCE) then begin Result:= VISUAL_HEBREW_CHARSET; exit; end; (* It's not dominant enough, try to rely on the model scores instead.*) modelsub := mLogicalProb.GetConfidence - mVisualProb.GetConfidence; if modelsub > MIN_MODEL_DISTANCE then begin Result := LOGICAL_HEBREW_CHARSET; exit; end; if modelsub < -(MIN_MODEL_DISTANCE) then begin Result := VISUAL_HEBREW_CHARSET; exit; end; (* Still no good, back to final letter distance, maybe it'll save the day.*) if finalsub < 0 then begin Result := VISUAL_HEBREW_CHARSET; exit; end; (* (finalsub > 0 - Logical) or (don't know what to do) default to Logical.*) Result:= LOGICAL_HEBREW_CHARSET; end; function TnsHebrewProber.GetConfidence: float; begin Result := 0.0; end; function TnsHebrewProber.GetState: eProbingState; begin (* Remain active as long as any of the model probers are active.*) if (mLogicalProb.GetState = psNotMe) and (mVisualProb.GetState = psNotMe) then begin Result := psNotMe; exit; end; Result := psDetecting; end; function TnsHebrewProber.HandleData(aBuf: PChar; aLen: integer): eProbingState; (* * Final letter analysis for logical-visual decision. * Look for evidence that the received buffer is either logical Hebrew or * visual Hebrew. * The following cases are checked: * 1) A word longer than 1 letter, ending with a final letter. This is an * indication that the text is laid out "naturally" since the final letter * really appears at the end. +1 for logical score. * 2) A word longer than 1 letter, ending with a Non-Final letter. In normal * Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, should not end with * the Non-Final form of that letter. Exceptions to this rule are mentioned * above in isNonFinal(). This is an indication that the text is laid out * backwards. +1 for visual score * 3) A word longer than 1 letter, starting with a final letter. Final letters * should not appear at the beginning of a word. This is an indication that * the text is laid out backwards. +1 for visual score. * * The visual score and logical score are accumulated throughout the text and * are finally checked against each other in GetCharSetName(). * No checking for final letters in the middle of words is done since that case * is not an indication for either Logical or Visual text. * * The input buffer should not contain any white spaces that are not (' ') * or any low-ascii punctuation marks. *) var curPtr: PChar; endPtr: PChar; cur: char; begin (* check prober enabled*) inherited HandleData(aBuf, aLen); (* Both model probers say it's not them. No reason to continue.*) if GetState = psNotMe then begin Result:= psNotMe; exit; end; endPtr := aBuf + aLen; curPtr := aBuf; while curPtr < endPtr do begin cur := curPtr^; if cur = ' ' then begin (* We stand on a space - a word just ended*) if mBeforePrev <> ' ' then begin (* *(curPtr-2) was not a space so prev is not a 1 letter word*) if isFinal(mPrev) then inc(mFinalCharLogicalScore) else (* case (1) [-2:not space][-1:final letter][cur:space]*) if isNonFinal(mPrev) then inc(mFinalCharVisualScore); (* case (2) [-2:not space][-1:Non-Final letter][cur:space]*) end; end else begin (* Not standing on a space*) if (mBeforePrev = ' ') and isFinal(mPrev) and (cur <> ' ') then inc(mFinalCharVisualScore); (* case (3) [-2:space][-1:final letter][cur:not space]*) end; mBeforePrev := mPrev; mPrev := cur; inc(curPtr); end; (* Forever detecting, till the end or until both model probers return psNotMe (handled above).*) Result := psDetecting; end; function TnsHebrewProber.isFinal(c: char): Boolean; begin Result := ((c=FINAL_KAF))or((c=FINAL_MEM))or((c=FINAL_NUN))or((c=FINAL_PE))or((c=FINAL_TSADI)); end; function TnsHebrewProber.isNonFinal(c: char): Boolean; begin Result:= ((c=NORMAL_KAF))or((c=NORMAL_MEM))or((c=NORMAL_NUN))or((c=NORMAL_PE)); (* The normal Tsadi is not a good Non-Final letter due to words like *) (* 'lechotet' (to chat) containing an apostrophe after the tsadi. This *) (* apostrophe is converted to a space in FilterWithoutEnglishLetters causing *) (* the Non-Final tsadi to appear at an end of a word even though this is not *) (* the case in the original text.*) (* The letters Pe and Kaf rarely display a related behavior of not being a *) (* good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' for *) (* example legally end with a Non-Final Pe or Kaf. However, the benefit of *) (* these letters as Non-Final letters outweighs the damage since these words *) (* are quite rare.*) end; procedure TnsHebrewProber.Reset; begin mFinalCharLogicalScore := 0; mFinalCharVisualScore := 0; mPrev := ' '; mBeforePrev := ' '; (* mPrev and mBeforePrev are initialized to space in order to simulate a word *) (* delimiter at the beginning of the data*) end; procedure TnsHebrewProber.SetModelProbers(logicalPrb, visualPrb: TCustomDetector); begin mLogicalProb := logicalPrb; mVisualProb := visualPrb; end; (** * ** General ideas of the Hebrew charset recognition ** * * Four main charsets exist in Hebrew: * "ISO-8859-8" - Visual Hebrew * "windows-1255" - Logical Hebrew * "ISO-8859-8-I" - Logical Hebrew * "x-mac-hebrew" - ?? Logical Hebrew ?? * * Both "ISO" charsets use a completely identical set of code points, whereas * "windows-1255" and "x-mac-hebrew" are two different proper supersets of * these code points. windows-1255 defines additional characters in the range * 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific * diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. * x-mac-hebrew defines similar additional code points but with a different * mapping. * * As as an average Hebrew text with no diacritics is concerned, all four * charsets are identical with respect to code points. Meaning that for the * main Hebrew alphabet, all four map the same values to all 27 Hebrew letters * (including final letters). * * The dominant difference between these charsets is their directionality. * "Visual" directionality means that the text is ordered as if the renderer is * not aware of a BIDI rendering algorithm. The renderer sees the text and * draws it from left to right. The text itself when ordered naturally is read * backwards. A buffer of Visual Hebrew generally looks like so: * "[last word of first line spelled backwards] [whole line ordered backwards * and spelled backwards] [first word of first line spelled backwards] * [end of line] [last word of second line] ... etc' " * adding punctuation marks, numbers and English text to visual text is * naturally also "visual" and from left to right. * * "Logical" directionality means the text is ordered "naturally" according to * the order it is read. It is the responsibility of the renderer to display * the text from right to left. A BIDI algorithm is used to place general * punctuation marks, numbers and English text in the text. * * Texts in x-mac-hebrew are almost impossible to find on the Internet. From * what little evidence I could find, it seems that its general directionality * is Logical. * * To sum up all of the above, the Hebrew probing mechanism knows about two * charsets: * Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are * backwards while line order is natural. For charset recognition purposes * the line order is unimportant (In fact, for this implementation, even * word order is unimportant). * Logical Hebrew - "windows-1255" - normal, naturally ordered text. * * "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be * specifically identified. * "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew * that contain special punctuation marks or diacritics is displayed with * some unconverted characters showing as question marks. This problem might * be corrected using another model prober for x-mac-hebrew. Due to the fact * that x-mac-hebrew texts are so rare, writing another model prober isn't * worth the effort and performance hit. * * *** The Prober *** * * The prober is divided between two nsSBCharSetProbers and an nsHebrewProber, * all of which are managed, created, fed data, inquired and deleted by the * nsSBCSGroupProber. The two nsSBCharSetProbers identify that the text is in * fact some kind of Hebrew, Logical or Visual. The final decision about which * one is it is made by the nsHebrewProber by combining final-letter scores * with the scores of the two nsSBCharSetProbers to produce a final answer. * * The nsSBCSGroupProber is responsible for stripping the original text of HTML * tags, English characters, numbers, low-ASCII punctuation characters, spaces * and new lines. It reduces any sequence of such characters to a single space. * The buffer fed to each prober in the SBCS group prober is pure text in * high-ASCII. * The two nsSBCharSetProbers (model probers) share the same language model: * Win1255Model. * The first nsSBCharSetProber uses the model normally as any other * nsSBCharSetProber does, to recognize windows-1255, upon which this model was * built. The second nsSBCharSetProber is told to make the pair-of-letter * lookup in the language model backwards. This in practice exactly simulates * a visual Hebrew model using the windows-1255 logical Hebrew model. * * The nsHebrewProber is not using any language model. All it does is look for * final-letter evidence suggesting the text is either logical Hebrew or visual * Hebrew. Disjointed from the model probers, the results of the nsHebrewProber * alone are meaningless. nsHebrewProber always returns 0.00 as confidence * since it never identifies a charset by itself. Instead, the pointer to the * nsHebrewProber is passed to the model probers as a helper "Name Prober". * When the Group prober receives a positive identification from any prober, * it asks for the name of the charset identified. If the prober queried is a * Hebrew model prober, the model prober forwards the call to the * nsHebrewProber to make the final decision. In the nsHebrewProber, the * decision is made according to the final-letters scores maintained and Both * model probers scores. The answer is returned in the form of the name of the * charset identified, either "windows-1255" or "ISO-8859-8". * *) end. doublecmd-0.8.2/components/chsdet/src/mbclass/0000775000175000017500000000000013244011205020347 5ustar alexxalexxdoublecmd-0.8.2/components/chsdet/src/mbclass/EUCTWLangModel.inc0000664000175000017500000000473512014201074023524 0ustar alexxalexxconst EUCTWCharLenTable: array [0..6] of Byte = (0, 0, 1, 2, 2, 2, 3); //PCK4BITS(0,2,2,2,2,2,2,2, // 00 - 07 EUCTW_cls: array [0..255] of Byte = ( 2,2,2,2,2,2,2,2, // 00 - 07 2,2,2,2,2,2,0,0, // 08 - 0f 2,2,2,2,2,2,2,2, // 10 - 17 2,2,2,0,2,2,2,2, // 18 - 1f 2,2,2,2,2,2,2,2, // 20 - 27 2,2,2,2,2,2,2,2, // 28 - 2f 2,2,2,2,2,2,2,2, // 30 - 37 2,2,2,2,2,2,2,2, // 38 - 3f 2,2,2,2,2,2,2,2, // 40 - 47 2,2,2,2,2,2,2,2, // 48 - 4f 2,2,2,2,2,2,2,2, // 50 - 57 2,2,2,2,2,2,2,2, // 58 - 5f 2,2,2,2,2,2,2,2, // 60 - 67 2,2,2,2,2,2,2,2, // 68 - 6f 2,2,2,2,2,2,2,2, // 70 - 77 2,2,2,2,2,2,2,2, // 78 - 7f 0,0,0,0,0,0,0,0, // 80 - 87 0,0,0,0,0,0,6,0, // 88 - 8f 0,0,0,0,0,0,0,0, // 90 - 97 0,0,0,0,0,0,0,0, // 98 - 9f 0,3,4,4,4,4,4,4, // a0 - a7 5,5,1,1,1,1,1,1, // a8 - af 1,1,1,1,1,1,1,1, // b0 - b7 1,1,1,1,1,1,1,1, // b8 - bf 1,1,3,1,3,3,3,3, // c0 - c7 3,3,3,3,3,3,3,3, // c8 - cf 3,3,3,3,3,3,3,3, // d0 - d7 3,3,3,3,3,3,3,3, // d8 - df 3,3,3,3,3,3,3,3, // e0 - e7 3,3,3,3,3,3,3,3, // e8 - ef 3,3,3,3,3,3,3,3, // f0 - f7 3,3,3,3,3,3,3,0 // f8 - ff ); EUCTW_st: array [0..47] of Byte = ( Byte(eError),Byte(eError),Byte(eStart), 3, 3, 3, 4,Byte(eError),//00-07 Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eItsMe),//08-0f Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eError),Byte(eStart),Byte(eError),//10-17 Byte(eStart),Byte(eStart),Byte(eStart),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),//18-1f 5,Byte(eError),Byte(eError),Byte(eError),Byte(eStart),Byte(eError),Byte(eStart),Byte(eStart),//20-27 Byte(eStart),Byte(eError),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart) //28-2f ); EUCTWLangModel: SMModel = ( classTable: @EUCTW_cls; classFactor: 7; stateTable: @EUCTW_st; charLenTable: @EUCTWCharLenTable; CharsetID: X_EUC_TW_CHARSET; ); // EUCTWLangModel: SMModel = ( // classTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @EUCTW_cls; // ); // classFactor: 7; // stateTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @EUCTW_st; // ); // charLenTable: @EUCTWCharLenTable; // CharsetID: X_EUC_TW_CHARSET; // ); doublecmd-0.8.2/components/chsdet/src/mbclass/ISO2022KRLangModel.inc0000664000175000017500000000372612014201074024031 0ustar alexxalexxconst ISO2022KRCharLenTable: array [0..5] of PRUint32 = (0, 0, 0, 0, 0, 0); ISO2022KR_cls: array [Char] of Byte = ( 2,0,0,0,0,0,0,0, // 00 - 07 0,0,0,0,0,0,0,0, // 08 - 0f 0,0,0,0,0,0,0,0, // 10 - 17 0,0,0,1,0,0,0,0, // 18 - 1f 0,0,0,0,3,0,0,0, // 20 - 27 0,4,0,0,0,0,0,0, // 28 - 2f 0,0,0,0,0,0,0,0, // 30 - 37 0,0,0,0,0,0,0,0, // 38 - 3f 0,0,0,5,0,0,0,0, // 40 - 47 0,0,0,0,0,0,0,0, // 48 - 4f 0,0,0,0,0,0,0,0, // 50 - 57 0,0,0,0,0,0,0,0, // 58 - 5f 0,0,0,0,0,0,0,0, // 60 - 67 0,0,0,0,0,0,0,0, // 68 - 6f 0,0,0,0,0,0,0,0, // 70 - 77 0,0,0,0,0,0,0,0, // 78 - 7f 2,2,2,2,2,2,2,2, // 80 - 87 2,2,2,2,2,2,2,2, // 88 - 8f 2,2,2,2,2,2,2,2, // 90 - 97 2,2,2,2,2,2,2,2, // 98 - 9f 2,2,2,2,2,2,2,2, // a0 - a7 2,2,2,2,2,2,2,2, // a8 - af 2,2,2,2,2,2,2,2, // b0 - b7 2,2,2,2,2,2,2,2, // b8 - bf 2,2,2,2,2,2,2,2, // c0 - c7 2,2,2,2,2,2,2,2, // c8 - cf 2,2,2,2,2,2,2,2, // d0 - d7 2,2,2,2,2,2,2,2, // d8 - df 2,2,2,2,2,2,2,2, // e0 - e7 2,2,2,2,2,2,2,2, // e8 - ef 2,2,2,2,2,2,2,2, // f0 - f7 2,2,2,2,2,2,2,2 // f8 - ff ); ISO2022KR_st: array [0..39] of Byte = ( Byte(eStart), 3,Byte(eError),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eError),Byte(eError),//00-07 Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),//08-0f Byte(eItsMe),Byte(eItsMe),Byte(eError),Byte(eError),Byte(eError), 4,Byte(eError),Byte(eError),//10-17 Byte(eError),Byte(eError),Byte(eError),Byte(eError), 5,Byte(eError),Byte(eError),Byte(eError),//18-1f Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart) //20-27 ); ISO2022KRSMModel: SMModel = ( classTable: @ISO2022KR_cls; classFactor: 6; stateTable: @ISO2022KR_st; charLenTable: @ISO2022KRCharLenTable; CharsetID: ISO_2022_KR_CHARSET; ); doublecmd-0.8.2/components/chsdet/src/mbclass/EUCKRLangModel.inc0000664000175000017500000000402612014201074023477 0ustar alexxalexxconst EUCKRCharLenTable: array [0..3] of byte = (0, 1, 2, 0); //PCK4BITS(0,1,1,1,1,1,1,1, // 00 - 07 EUCKR_cls: array [0..255] of byte = ( 1,1,1,1,1,1,1,1, // 00 - 07 1,1,1,1,1,1,0,0, // 08 - 0f 1,1,1,1,1,1,1,1, // 10 - 17 1,1,1,0,1,1,1,1, // 18 - 1f 1,1,1,1,1,1,1,1, // 20 - 27 1,1,1,1,1,1,1,1, // 28 - 2f 1,1,1,1,1,1,1,1, // 30 - 37 1,1,1,1,1,1,1,1, // 38 - 3f 1,1,1,1,1,1,1,1, // 40 - 47 1,1,1,1,1,1,1,1, // 48 - 4f 1,1,1,1,1,1,1,1, // 50 - 57 1,1,1,1,1,1,1,1, // 58 - 5f 1,1,1,1,1,1,1,1, // 60 - 67 1,1,1,1,1,1,1,1, // 68 - 6f 1,1,1,1,1,1,1,1, // 70 - 77 1,1,1,1,1,1,1,1, // 78 - 7f 0,0,0,0,0,0,0,0, // 80 - 87 0,0,0,0,0,0,0,0, // 88 - 8f 0,0,0,0,0,0,0,0, // 90 - 97 0,0,0,0,0,0,0,0, // 98 - 9f 0,2,2,2,2,2,2,2, // a0 - a7 2,2,2,2,2,3,3,3, // a8 - af 2,2,2,2,2,2,2,2, // b0 - b7 2,2,2,2,2,2,2,2, // b8 - bf 2,2,2,2,2,2,2,2, // c0 - c7 2,3,2,2,2,2,2,2, // c8 - cf 2,2,2,2,2,2,2,2, // d0 - d7 2,2,2,2,2,2,2,2, // d8 - df 2,2,2,2,2,2,2,2, // e0 - e7 2,2,2,2,2,2,2,2, // e8 - ef 2,2,2,2,2,2,2,2, // f0 - f7 2,2,2,2,2,2,2,0 // f8 - ff ); EUCKR_st: array [0..15] of byte = ( byte(eError),byte(eStart), 3,byte(eError),byte(eError),byte(eError),byte(eError),byte(eError), //00-07 byte(eItsMe),byte(eItsMe),byte(eItsMe),byte(eItsMe),byte(eError),byte(eError),byte(eStart),byte(eStart) //08-0f ); EUCKRLangModel: SMModel =( classTable: @EUCKR_cls; classFactor: 4; stateTable: @EUCKR_st; charLenTable: @EUCKRCharLenTable; CharsetID: EUC_KR_CHARSET; ); // EUCKRLangModel: SMModel =( // classTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @EUCKR_cls; // ); // classFactor: 4; // stateTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @EUCKR_st; // ); // charLenTable: @EUCKRCharLenTable; // CharsetID: EUC_KR_CHARSET; // ); doublecmd-0.8.2/components/chsdet/src/mbclass/Big5LangModel.inc0000664000175000017500000000421712014201074023416 0ustar alexxalexxconst Big5CharLenTable: array [0..4] of Byte = (0, 1, 1, 2, 0); BIG5_cls: array [0..255] of Byte = ( 1,1,1,1,1,1,1,1, // 00 - 07 //allow 0x00 as legal value 1,1,1,1,1,1,0,0, // 08 - 0f 1,1,1,1,1,1,1,1, // 10 - 17 1,1,1,0,1,1,1,1, // 18 - 1f 1,1,1,1,1,1,1,1, // 20 - 27 1,1,1,1,1,1,1,1, // 28 - 2f 1,1,1,1,1,1,1,1, // 30 - 37 1,1,1,1,1,1,1,1, // 38 - 3f 2,2,2,2,2,2,2,2, // 40 - 47 2,2,2,2,2,2,2,2, // 48 - 4f 2,2,2,2,2,2,2,2, // 50 - 57 2,2,2,2,2,2,2,2, // 58 - 5f 2,2,2,2,2,2,2,2, // 60 - 67 2,2,2,2,2,2,2,2, // 68 - 6f 2,2,2,2,2,2,2,2, // 70 - 77 2,2,2,2,2,2,2,1, // 78 - 7f 4,4,4,4,4,4,4,4, // 80 - 87 4,4,4,4,4,4,4,4, // 88 - 8f 4,4,4,4,4,4,4,4, // 90 - 97 4,4,4,4,4,4,4,4, // 98 - 9f 4,3,3,3,3,3,3,3, // a0 - a7 3,3,3,3,3,3,3,3, // a8 - af 3,3,3,3,3,3,3,3, // b0 - b7 3,3,3,3,3,3,3,3, // b8 - bf 3,3,3,3,3,3,3,3, // c0 - c7 3,3,3,3,3,3,3,3, // c8 - cf 3,3,3,3,3,3,3,3, // d0 - d7 3,3,3,3,3,3,3,3, // d8 - df 3,3,3,3,3,3,3,3, // e0 - e7 3,3,3,3,3,3,3,3, // e8 - ef 3,3,3,3,3,3,3,3, // f0 - f7 3,3,3,3,3,3,3,0 // f8 - ff ); BIG5_st: array [0..23] of Byte = ( Byte(eError),Byte(eStart),Byte(eStart), 3,Byte(eError),Byte(eError),Byte(eError),Byte(eError),//00-07 Byte(eError),Byte(eError),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eError),//08-0f Byte(eError),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart) //10-17 ); Big5LangModel: SMModel = ( classTable: @BIG5_cls; classFactor: 5; stateTable: @BIG5_st; charLenTable: @Big5CharLenTable; CharsetID: BIG5_CHARSET; ); // Big5LangModel: SMModel = ( // classTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @BIG5_cls; // ); // classFactor: 5; // stateTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @BIG5_st; // ); // charLenTable: @Big5CharLenTable; // CharsetID: BIG5_CHARSET; // ); doublecmd-0.8.2/components/chsdet/src/mbclass/SJISLangModel.inc0000664000175000017500000000443412014201074023401 0ustar alexxalexxconst SJIS_cls: array [0..255] of byte = ( 1,1,1,1,1,1,1,1, // 00 - 07 1,1,1,1,1,1,0,0, // 08 - 0f 1,1,1,1,1,1,1,1, // 10 - 17 1,1,1,0,1,1,1,1, // 18 - 1f 1,1,1,1,1,1,1,1, // 20 - 27 1,1,1,1,1,1,1,1, // 28 - 2f 1,1,1,1,1,1,1,1, // 30 - 37 1,1,1,1,1,1,1,1, // 38 - 3f 2,2,2,2,2,2,2,2, // 40 - 47 2,2,2,2,2,2,2,2, // 48 - 4f 2,2,2,2,2,2,2,2, // 50 - 57 2,2,2,2,2,2,2,2, // 58 - 5f 2,2,2,2,2,2,2,2, // 60 - 67 2,2,2,2,2,2,2,2, // 68 - 6f 2,2,2,2,2,2,2,2, // 70 - 77 2,2,2,2,2,2,2,1, // 78 - 7f 3,3,3,3,3,3,3,3, // 80 - 87 3,3,3,3,3,3,3,3, // 88 - 8f 3,3,3,3,3,3,3,3, // 90 - 97 3,3,3,3,3,3,3,3, // 98 - 9f //0xa0 is illegal in sjis encoding, but some pages does //contain such byte. We need to be more error forgiven. 2,2,2,2,2,2,2,2, // a0 - a7 2,2,2,2,2,2,2,2, // a8 - af 2,2,2,2,2,2,2,2, // b0 - b7 2,2,2,2,2,2,2,2, // b8 - bf 2,2,2,2,2,2,2,2, // c0 - c7 2,2,2,2,2,2,2,2, // c8 - cf 2,2,2,2,2,2,2,2, // d0 - d7 2,2,2,2,2,2,2,2, // d8 - df 3,3,3,3,3,3,3,3, // e0 - e7 3,3,3,3,3,4,4,4, // e8 - ef 4,4,4,4,4,4,4,4, // f0 - f7 4,4,4,4,4,0,0,0 // f8 - ff ); SJIS_st: array [0..23] of byte = ( byte(eError),byte(eStart),byte(eStart), 3,byte(eError),byte(eError),byte(eError),byte(eError),//00-07 byte(eError),byte(eError),byte(eError),byte(eError),byte(eItsMe),byte(eItsMe),byte(eItsMe),byte(eItsMe),//08-0f byte(eItsMe),byte(eItsMe),byte(eError),byte(eError),byte(eStart),byte(eStart),byte(eStart),byte(eStart) //10-17 ); SJISCharLenTable: array [0..5] of byte = (0, 1, 1, 2, 0, 0); SJISLangModel: SMModel = ( classTable: @SJIS_cls; classFactor: 6; stateTable: @SJIS_st; charLenTable: @SJISCharLenTable; CharsetID: SHIFT_JIS_CHARSET; ); // SJISLangModel: SMModel = ( // classTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @SJIS_cls; // ); // classFactor: 6; // stateTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @SJIS_st; // ); // charLenTable: @SJISCharLenTable; // CharsetID: SHIFT_JIS_CHARSET; // ); doublecmd-0.8.2/components/chsdet/src/mbclass/EUCJPLangModel.inc0000664000175000017500000000453312014201074023477 0ustar alexxalexxconst EUCJPCharLenTable: array [0..5] of byte = (2, 2, 2, 3, 1, 0); //PCK4BITS(5,4,4,4,4,4,4,4), // 00 - 07 EUCJP_cls: array [0..255] of byte = ( 4,4,4,4,4,4,4,4, // 00 - 07 4,4,4,4,4,4,5,5, // 08 - 0f 4,4,4,4,4,4,4,4, // 10 - 17 4,4,4,5,4,4,4,4, // 18 - 1f 4,4,4,4,4,4,4,4, // 20 - 27 4,4,4,4,4,4,4,4, // 28 - 2f 4,4,4,4,4,4,4,4, // 30 - 37 4,4,4,4,4,4,4,4, // 38 - 3f 4,4,4,4,4,4,4,4, // 40 - 47 4,4,4,4,4,4,4,4, // 48 - 4f 4,4,4,4,4,4,4,4, // 50 - 57 4,4,4,4,4,4,4,4, // 58 - 5f 4,4,4,4,4,4,4,4, // 60 - 67 4,4,4,4,4,4,4,4, // 68 - 6f 4,4,4,4,4,4,4,4, // 70 - 77 4,4,4,4,4,4,4,4, // 78 - 7f 5,5,5,5,5,5,5,5, // 80 - 87 5,5,5,5,5,5,1,3, // 88 - 8f 5,5,5,5,5,5,5,5, // 90 - 97 5,5,5,5,5,5,5,5, // 98 - 9f 5,2,2,2,2,2,2,2, // a0 - a7 2,2,2,2,2,2,2,2, // a8 - af 2,2,2,2,2,2,2,2, // b0 - b7 2,2,2,2,2,2,2,2, // b8 - bf 2,2,2,2,2,2,2,2, // c0 - c7 2,2,2,2,2,2,2,2, // c8 - cf 2,2,2,2,2,2,2,2, // d0 - d7 2,2,2,2,2,2,2,2, // d8 - df 0,0,0,0,0,0,0,0, // e0 - e7 0,0,0,0,0,0,0,0, // e8 - ef 0,0,0,0,0,0,0,0, // f0 - f7 0,0,0,0,0,0,0,5 // f8 - ff ); EUCJP_st: array [0..39] of byte = ( 3, 4, 3, 5,byte(eStart),byte(eError),byte(eError),byte(eError),//00-07 byte(eError),byte(eError),byte(eError),byte(eError),byte(eItsMe),byte(eItsMe),byte(eItsMe),byte(eItsMe),//08-0f byte(eItsMe),byte(eItsMe),byte(eStart),byte(eError),byte(eStart),byte(eError),byte(eError),byte(eError),//10-17 byte(eError),byte(eError),byte(eStart),byte(eError),byte(eError),byte(eError), 3,byte(eError),//18-1f 3,byte(eError),byte(eError),byte(eError),byte(eStart),byte(eStart),byte(eStart),byte(eStart) //20-27 ); EUCJPLangModel: SMModel = ( classTable: @EUCJP_cls; classFactor: 6; stateTable: @EUCJP_st; charLenTable: @EUCJPCharLenTable; CharsetID: EUC_JP_CHARSET; ); // EUCJPLangModel: SMModel = ( // classTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @EUCJP_cls; // ); // classFactor: 6; // stateTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @EUCJP_st; // ); // charLenTable: @EUCJPCharLenTable; // CharsetID: EUC_JP_CHARSET; // ); doublecmd-0.8.2/components/chsdet/src/mbclass/ISO2022CNLangModel.inc0000664000175000017500000000446012014201074024011 0ustar alexxalexxconst ISO2022CNCharLenTable: array [0..8] of PRUint32 = (0, 0, 0, 0, 0, 0, 0, 0, 0); ISO2022CN_cls: array [Char] of Byte = ( 2,0,0,0,0,0,0,0, // 00 - 07 0,0,0,0,0,0,0,0, // 08 - 0f 0,0,0,0,0,0,0,0, // 10 - 17 0,0,0,1,0,0,0,0, // 18 - 1f 0,0,0,0,0,0,0,0, // 20 - 27 0,3,0,0,0,0,0,0, // 28 - 2f 0,0,0,0,0,0,0,0, // 30 - 37 0,0,0,0,0,0,0,0, // 38 - 3f 0,0,0,4,0,0,0,0, // 40 - 47 0,0,0,0,0,0,0,0, // 48 - 4f 0,0,0,0,0,0,0,0, // 50 - 57 0,0,0,0,0,0,0,0, // 58 - 5f 0,0,0,0,0,0,0,0, // 60 - 67 0,0,0,0,0,0,0,0, // 68 - 6f 0,0,0,0,0,0,0,0, // 70 - 77 0,0,0,0,0,0,0,0, // 78 - 7f 2,2,2,2,2,2,2,2, // 80 - 87 2,2,2,2,2,2,2,2, // 88 - 8f 2,2,2,2,2,2,2,2, // 90 - 97 2,2,2,2,2,2,2,2, // 98 - 9f 2,2,2,2,2,2,2,2, // a0 - a7 2,2,2,2,2,2,2,2, // a8 - af 2,2,2,2,2,2,2,2, // b0 - b7 2,2,2,2,2,2,2,2, // b8 - bf 2,2,2,2,2,2,2,2, // c0 - c7 2,2,2,2,2,2,2,2, // c8 - cf 2,2,2,2,2,2,2,2, // d0 - d7 2,2,2,2,2,2,2,2, // d8 - df 2,2,2,2,2,2,2,2, // e0 - e7 2,2,2,2,2,2,2,2, // e8 - ef 2,2,2,2,2,2,2,2, // f0 - f7 2,2,2,2,2,2,2,2 // f8 - ff ); ISO2022CN_st: array [0..63] of Byte = ( Byte(eStart), 3,Byte(eError),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),//00-07 Byte(eStart),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),//08-0f Byte(eError),Byte(eError),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),//10-17 Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eError),Byte(eError),Byte(eError), 4,Byte(eError),//18-1f Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eError),Byte(eError),Byte(eError),Byte(eError),//20-27 5, 6,Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),//28-2f Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eError),Byte(eError),Byte(eError),Byte(eError),//30-37 Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eError),Byte(eStart) //38-3f ); ISO2022CNSMModel: SMModel = ( classTable: @ISO2022CN_cls; classFactor: 9; stateTable: @ISO2022CN_st; charLenTable: @ISO2022CNCharLenTable; CharsetID: ISO_2022_CN_CHARSET; );doublecmd-0.8.2/components/chsdet/src/mbclass/GB18030LangModel.inc0000664000175000017500000000471012014201074023512 0ustar alexxalexxconst GB18030CharLenTable: array [0..6] of byte = (0, 1, 1, 1, 1, 1, 2); GB18030_cls: array [0..255] of Byte = ( 1,1,1,1,1,1,1,1, // 00 - 07 1,1,1,1,1,1,0,0, // 08 - 0f 1,1,1,1,1,1,1,1, // 10 - 17 1,1,1,0,1,1,1,1, // 18 - 1f 1,1,1,1,1,1,1,1, // 20 - 27 1,1,1,1,1,1,1,1, // 28 - 2f 3,3,3,3,3,3,3,3, // 30 - 37 3,3,1,1,1,1,1,1, // 38 - 3f 2,2,2,2,2,2,2,2, // 40 - 47 2,2,2,2,2,2,2,2, // 48 - 4f 2,2,2,2,2,2,2,2, // 50 - 57 2,2,2,2,2,2,2,2, // 58 - 5f 2,2,2,2,2,2,2,2, // 60 - 67 2,2,2,2,2,2,2,2, // 68 - 6f 2,2,2,2,2,2,2,2, // 70 - 77 2,2,2,2,2,2,2,4, // 78 - 7f 5,6,6,6,6,6,6,6, // 80 - 87 6,6,6,6,6,6,6,6, // 88 - 8f 6,6,6,6,6,6,6,6, // 90 - 97 6,6,6,6,6,6,6,6, // 98 - 9f 6,6,6,6,6,6,6,6, // a0 - a7 6,6,6,6,6,6,6,6, // a8 - af 6,6,6,6,6,6,6,6, // b0 - b7 6,6,6,6,6,6,6,6, // b8 - bf 6,6,6,6,6,6,6,6, // c0 - c7 6,6,6,6,6,6,6,6, // c8 - cf 6,6,6,6,6,6,6,6, // d0 - d7 6,6,6,6,6,6,6,6, // d8 - df 6,6,6,6,6,6,6,6, // e0 - e7 6,6,6,6,6,6,6,6, // e8 - ef 6,6,6,6,6,6,6,6, // f0 - f7 6,6,6,6,6,6,6,0 // f8 - ff ); GB18030_st: array [0..47] of byte = ( byte(eError),byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart), 3,byte(eError),//00-07 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eItsMe),byte(eItsMe),//08-0f byte(eItsMe),byte(eItsMe),byte(eItsMe),byte(eItsMe),byte(eItsMe),byte(eError),byte(eError),byte(eStart),//10-17 4,byte(eError),byte(eStart),byte(eStart),byte(eError),byte(eError),byte(eError),byte(eError),//18-1f byte(eError),byte(eError), 5,byte(eError),byte(eError),byte(eError),byte(eItsMe),byte(eError),//20-27 byte(eError),byte(eError),byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart) //28-2f ); GB18030LangModel: SMModel = ( classTable: @GB18030_cls; classFactor: 7; stateTable: @GB18030_st; charLenTable: @GB18030CharLenTable; CharsetID: GB18030_CHARSET; ); // GB18030LangModel: SMModel = ( // classTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @GB18030_cls; // ); // classFactor: 7; // stateTable: ( // idxsft: eIdxSft4bits; // sftmsk: eSftMsk4bits; // bitsft: eBitSft4bits; // unitmsk: eUnitMsk4bits; // data: @GB18030_st; // ); // charLenTable: @GB18030CharLenTable; // CharsetID: GB18030_CHARSET; // ); doublecmd-0.8.2/components/chsdet/src/mbclass/UTF8LangModel.inc0000664000175000017500000001015412014201074023353 0ustar alexxalexxconst UTF8_cls: array [0..255] of byte = ( 1,1,1,1,1,1,1,1, // 00 - 07 //allow 0x00 as a legal value 1,1,1,1,1,1,0,0, // 08 - 0f 1,1,1,1,1,1,1,1, // 10 - 17 1,1,1,0,1,1,1,1, // 18 - 1f 1,1,1,1,1,1,1,1, // 20 - 27 1,1,1,1,1,1,1,1, // 28 - 2f 1,1,1,1,1,1,1,1, // 30 - 37 1,1,1,1,1,1,1,1, // 38 - 3f 1,1,1,1,1,1,1,1, // 40 - 47 1,1,1,1,1,1,1,1, // 48 - 4f 1,1,1,1,1,1,1,1, // 50 - 57 1,1,1,1,1,1,1,1, // 58 - 5f 1,1,1,1,1,1,1,1, // 60 - 67 1,1,1,1,1,1,1,1, // 68 - 6f 1,1,1,1,1,1,1,1, // 70 - 77 1,1,1,1,1,1,1,1, // 78 - 7f 2,2,2,2,3,3,3,3, // 80 - 87 4,4,4,4,4,4,4,4, // 88 - 8f 4,4,4,4,4,4,4,4, // 90 - 97 4,4,4,4,4,4,4,4, // 98 - 9f 5,5,5,5,5,5,5,5, // a0 - a7 5,5,5,5,5,5,5,5, // a8 - af 5,5,5,5,5,5,5,5, // b0 - b7 5,5,5,5,5,5,5,5, // b8 - bf 0,0,6,6,6,6,6,6, // c0 - c7 6,6,6,6,6,6,6,6, // c8 - cf 6,6,6,6,6,6,6,6, // d0 - d7 6,6,6,6,6,6,6,6, // d8 - df 7,8,8,8,8,8,8,8, // e0 - e7 8,8,8,8,8,9,8,8, // e8 - ef 10,11,11,11,11,11,11,11, // f0 - f7 12,13,13,13,14,15,0,0 // f8 - ff ); UTF8CharLenTable: array [0..15] of byte = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6 ); UTF8_st: array [0..207] of byte = ( byte(eError),byte(eStart),byte(eError),byte(eError),byte(eError),byte(eError), 12, 10,//00-07 9, 11, 8, 7, 6, 5, 4, 3,//08-0f byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//10-17 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//18-1f byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart),//20-27 byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eStart),//28-2f byte(eError),byte(eError), 5, 5, 5, 5,byte(eError),byte(eError),//30-37 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//38-3f byte(eError),byte(eError),byte(eError), 5, 5, 5,byte(eError),byte(eError),//40-47 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//48-4f byte(eError),byte(eError), 7, 7, 7, 7,byte(eError),byte(eError),//50-57 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//58-5f byte(eError),byte(eError),byte(eError),byte(eError), 7, 7,byte(eError),byte(eError),//60-67 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//68-6f byte(eError),byte(eError), 9, 9, 9, 9,byte(eError),byte(eError),//70-77 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//78-7f byte(eError),byte(eError),byte(eError),byte(eError),byte(eError), 9,byte(eError),byte(eError),//80-87 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//88-8f byte(eError),byte(eError), 12, 12, 12, 12,byte(eError),byte(eError),//90-97 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//98-9f byte(eError),byte(eError),byte(eError),byte(eError),byte(eError), 12,byte(eError),byte(eError),//a0-a7 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//a8-af byte(eError),byte(eError), 12, 12, 12,byte(eError),byte(eError),byte(eError),//b0-b7 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),//b8-bf byte(eError),byte(eError),byte(eStart),byte(eStart),byte(eStart),byte(eStart),byte(eError),byte(eError),//c0-c7 byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError),byte(eError) //c8-cf ); UTF8LangModel: SMModel = ( classTable: @UTF8_cls; classFactor: 16; stateTable: @UTF8_st; charLenTable: @UTF8CharLenTable; CharsetID: UTF8_CHARSET; ); doublecmd-0.8.2/components/chsdet/src/mbclass/UCS2BELangModel.inc0000664000175000017500000000410712014201074023551 0ustar alexxalexxconst UCS2BECharLenTable: array [0..5] of Byte = (2, 2, 2, 2, 2, 2); UCS2BE_cls: array [Char] of Byte = ( 0,0,0,0,0,0,0,0, // 00 - 07 //allow 0x00 as a legal value 0,0,1,0,0,2,0,0, // 08 - 0f 0,0,0,0,0,0,0,0, // 10 - 17 0,0,0,3,0,0,0,0, // 18 - 1f 0,0,0,0,0,0,0,0, // 20 - 27 0,3,3,3,3,3,0,0, // 28 - 2f 0,0,0,0,0,0,0,0, // 30 - 37 0,0,0,0,0,0,0,0, // 38 - 3f 0,0,0,0,0,0,0,0, // 40 - 47 0,0,0,0,0,0,0,0, // 48 - 4f 0,0,0,0,0,0,0,0, // 50 - 57 0,0,0,0,0,0,0,0, // 58 - 5f 0,0,0,0,0,0,0,0, // 60 - 67 0,0,0,0,0,0,0,0, // 68 - 6f 0,0,0,0,0,0,0,0, // 70 - 77 0,0,0,0,0,0,0,0, // 78 - 7f 0,0,0,0,0,0,0,0, // 80 - 87 0,0,0,0,0,0,0,0, // 88 - 8f 0,0,0,0,0,0,0,0, // 90 - 97 0,0,0,0,0,0,0,0, // 98 - 9f 0,0,0,0,0,0,0,0, // a0 - a7 0,0,0,0,0,0,0,0, // a8 - af 0,0,0,0,0,0,0,0, // b0 - b7 0,0,0,0,0,0,0,0, // b8 - bf 0,0,0,0,0,0,0,0, // c0 - c7 0,0,0,0,0,0,0,0, // c8 - cf 0,0,0,0,0,0,0,0, // d0 - d7 0,0,0,0,0,0,0,0, // d8 - df 0,0,0,0,0,0,0,0, // e0 - e7 0,0,0,0,0,0,0,0, // e8 - ef 0,0,0,0,0,0,0,0, // f0 - f7 0,0,0,0,0,0,4,5 // f8 - ff ); UCS2BE_st: array [0..55] of Byte = ( 5, 7, 7,integer(eError), 4, 3,integer(eError),integer(eError),//00-07 integer(eError),integer(eError),integer(eError),integer(eError),integer(eItsMe),integer(eItsMe),integer(eItsMe),integer(eItsMe),//08-0f integer(eItsMe),integer(eItsMe), 6, 6, 6, 6,integer(eError),integer(eError),//10-17 6, 6, 6, 6, 6,integer(eItsMe), 6, 6,//18-1f 6, 6, 6, 6, 5, 7, 7,integer(eError),//20-27 5, 8, 6, 6,integer(eError), 6, 6, 6,//28-2f 6, 6, 6, 6,integer(eError),integer(eError),integer(eStart),integer(eStart) //30-37 ); UCS2BELangModel: SMModel = ( classTable: @UCS2BE_cls; classFactor: 6; stateTable: @UCS2BE_st; charLenTable: @UCS2BECharLenTable; CharsetID: UTF16_BE_CHARSET; );doublecmd-0.8.2/components/chsdet/src/mbclass/UCS2LELangModel.inc0000664000175000017500000000402412014201074023561 0ustar alexxalexxconst UCS2LECharLenTable: array [0..5] of PRUint32 = (2, 2, 2, 2, 2, 2); UCS2LE_cls: array [Char] of Byte = ( 0,0,0,0,0,0,0,0, // 00 - 07 //allow 0x00 as a legal value 0,0,1,0,0,2,0,0, // 08 - 0f 0,0,0,0,0,0,0,0, // 10 - 17 0,0,0,3,0,0,0,0, // 18 - 1f 0,0,0,0,0,0,0,0, // 20 - 27 0,3,3,3,3,3,0,0, // 28 - 2f 0,0,0,0,0,0,0,0, // 30 - 37 0,0,0,0,0,0,0,0, // 38 - 3f 0,0,0,0,0,0,0,0, // 40 - 47 0,0,0,0,0,0,0,0, // 48 - 4f 0,0,0,0,0,0,0,0, // 50 - 57 0,0,0,0,0,0,0,0, // 58 - 5f 0,0,0,0,0,0,0,0, // 60 - 67 0,0,0,0,0,0,0,0, // 68 - 6f 0,0,0,0,0,0,0,0, // 70 - 77 0,0,0,0,0,0,0,0, // 78 - 7f 0,0,0,0,0,0,0,0, // 80 - 87 0,0,0,0,0,0,0,0, // 88 - 8f 0,0,0,0,0,0,0,0, // 90 - 97 0,0,0,0,0,0,0,0, // 98 - 9f 0,0,0,0,0,0,0,0, // a0 - a7 0,0,0,0,0,0,0,0, // a8 - af 0,0,0,0,0,0,0,0, // b0 - b7 0,0,0,0,0,0,0,0, // b8 - bf 0,0,0,0,0,0,0,0, // c0 - c7 0,0,0,0,0,0,0,0, // c8 - cf 0,0,0,0,0,0,0,0, // d0 - d7 0,0,0,0,0,0,0,0, // d8 - df 0,0,0,0,0,0,0,0, // e0 - e7 0,0,0,0,0,0,0,0, // e8 - ef 0,0,0,0,0,0,0,0, // f0 - f7 0,0,0,0,0,0,4,5 // f8 - ff ); UCS2LE_st: array [0..55] of Byte = ( 6, 6, 7, 6, 4, 3,integer(eError),integer(eError),//00-07 integer(eError),integer(eError),integer(eError),integer(eError),integer(eItsMe),integer(eItsMe),integer(eItsMe),integer(eItsMe),//08-0f integer(eItsMe),integer(eItsMe), 5, 5, 5,integer(eError),integer(eItsMe),integer(eError),//10-17 5, 5, 5,integer(eError), 5,integer(eError), 6, 6,//18-1f 7, 6, 8, 8, 5, 5, 5,integer(eError),//20-27 5, 5, 5,integer(eError),integer(eError),integer(eError), 5, 5,//28-2f 5, 5, 5,integer(eError), 5,integer(eError),integer(eStart),integer(eStart) //30-37 ); UCS2LELangModel: SMModel = ( classTable: @UCS2LE_cls; classFactor: 6; stateTable: @UCS2LE_st; charLenTable: @UCS2LECharLenTable; CharsetID: UTF16_LE_CHARSET; ); doublecmd-0.8.2/components/chsdet/src/mbclass/ISO2022JPLangModel.inc0000664000175000017500000000464312014201074024025 0ustar alexxalexxconst ISO2022JPCharLenTable: array [0..7] of PRUint32 = (0, 0, 0, 0, 0, 0, 0, 0); ISO2022JP_cls: array [Char] of Byte = ( 2,0,0,0,0,0,0,0, // 00 - 07 0,0,0,0,0,0,2,2, // 08 - 0f 0,0,0,0,0,0,0,0, // 10 - 17 0,0,0,1,0,0,0,0, // 18 - 1f 0,0,0,0,7,0,0,0, // 20 - 27 3,0,0,0,0,0,0,0, // 28 - 2f 0,0,0,0,0,0,0,0, // 30 - 37 0,0,0,0,0,0,0,0, // 38 - 3f 6,0,4,0,8,0,0,0, // 40 - 47 0,9,5,0,0,0,0,0, // 48 - 4f 0,0,0,0,0,0,0,0, // 50 - 57 0,0,0,0,0,0,0,0, // 58 - 5f 0,0,0,0,0,0,0,0, // 60 - 67 0,0,0,0,0,0,0,0, // 68 - 6f 0,0,0,0,0,0,0,0, // 70 - 77 0,0,0,0,0,0,0,0, // 78 - 7f 2,2,2,2,2,2,2,2, // 80 - 87 2,2,2,2,2,2,2,2, // 88 - 8f 2,2,2,2,2,2,2,2, // 90 - 97 2,2,2,2,2,2,2,2, // 98 - 9f 2,2,2,2,2,2,2,2, // a0 - a7 2,2,2,2,2,2,2,2, // a8 - af 2,2,2,2,2,2,2,2, // b0 - b7 2,2,2,2,2,2,2,2, // b8 - bf 2,2,2,2,2,2,2,2, // c0 - c7 2,2,2,2,2,2,2,2, // c8 - cf 2,2,2,2,2,2,2,2, // d0 - d7 2,2,2,2,2,2,2,2, // d8 - df 2,2,2,2,2,2,2,2, // e0 - e7 2,2,2,2,2,2,2,2, // e8 - ef 2,2,2,2,2,2,2,2, // f0 - f7 2,2,2,2,2,2,2,2 // f8 - ff ); ISO2022JP_st: array [0..71] of Byte = ( Byte(eStart), 3,Byte(eError),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),//00-07 Byte(eStart),Byte(eStart),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),//08-0f Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),//10-17 Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eError),Byte(eError),//18-1f Byte(eError), 5,Byte(eError),Byte(eError),Byte(eError), 4,Byte(eError),Byte(eError),//20-27 Byte(eError),Byte(eError),Byte(eError), 6,Byte(eItsMe),Byte(eError),Byte(eItsMe),Byte(eError),//28-2f Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eItsMe),//30-37 Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eError),Byte(eError),Byte(eError),Byte(eError),//38-3f Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eError),Byte(eStart),Byte(eStart)//40-47 ); ISO2022JPSMModel: SMModel = ( classTable: @ISO2022JP_cls; classFactor: 10; stateTable: @ISO2022JP_st; charLenTable: @ISO2022JPCharLenTable; CharsetID: ISO_2022_JP_CHARSET; ); doublecmd-0.8.2/components/chsdet/src/mbclass/HZLangModel.inc0000664000175000017500000000367012014201074023153 0ustar alexxalexxconst HZCharLenTable: array [0..5] of PRUint32 = (0, 0, 0, 0, 0, 0); HZ_cls: array [0..255] of Byte = ( 1,0,0,0,0,0,0,0, // 00 - 07 0,0,0,0,0,0,0,0, // 08 - 0f 0,0,0,0,0,0,0,0, // 10 - 17 0,0,0,1,0,0,0,0, // 18 - 1f 0,0,0,0,0,0,0,0, // 20 - 27 0,0,0,0,0,0,0,0, // 28 - 2f 0,0,0,0,0,0,0,0, // 30 - 37 0,0,0,0,0,0,0,0, // 38 - 3f 0,0,0,0,0,0,0,0, // 40 - 47 0,0,0,0,0,0,0,0, // 48 - 4f 0,0,0,0,0,0,0,0, // 50 - 57 0,0,0,0,0,0,0,0, // 58 - 5f 0,0,0,0,0,0,0,0, // 60 - 67 0,0,0,0,0,0,0,0, // 68 - 6f 0,0,0,0,0,0,0,0, // 70 - 77 0,0,0,4,0,5,2,0, // 78 - 7f 1,1,1,1,1,1,1,1, // 80 - 87 1,1,1,1,1,1,1,1, // 88 - 8f 1,1,1,1,1,1,1,1, // 90 - 97 1,1,1,1,1,1,1,1, // 98 - 9f 1,1,1,1,1,1,1,1, // a0 - a7 1,1,1,1,1,1,1,1, // a8 - af 1,1,1,1,1,1,1,1, // b0 - b7 1,1,1,1,1,1,1,1, // b8 - bf 1,1,1,1,1,1,1,1, // c0 - c7 1,1,1,1,1,1,1,1, // c8 - cf 1,1,1,1,1,1,1,1, // d0 - d7 1,1,1,1,1,1,1,1, // d8 - df 1,1,1,1,1,1,1,1, // e0 - e7 1,1,1,1,1,1,1,1, // e8 - ef 1,1,1,1,1,1,1,1, // f0 - f7 1,1,1,1,1,1,1,1 // f8 - ff ); HZ_st: array [0..47] of Byte = ( Byte(eStart),Byte(eError), 3,Byte(eStart),Byte(eStart),Byte(eStart),Byte(eError),Byte(eError),//00-07 Byte(eError),Byte(eError),Byte(eError),Byte(eError),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),Byte(eItsMe),//08-0f Byte(eItsMe),Byte(eItsMe),Byte(eError),Byte(eError),Byte(eStart),Byte(eStart), 4,Byte(eError),//10-17 5,Byte(eError), 6,Byte(eError), 5, 5, 4,Byte(eError),//18-1f 4,Byte(eError), 4, 4, 4,Byte(eError), 4,Byte(eError),//20-27 4,Byte(eItsMe),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart),Byte(eStart)//28-2f ); HZSMModel: SMModel = ( classTable: @HZ_cls; classFactor: 6; stateTable: @HZ_st; charLenTable: @HZCharLenTable; CharsetID: HZ_GB_2312_CHARSET; );doublecmd-0.8.2/components/chsdet/src/nsSBCharSetProber.pas0000664000175000017500000001622012014201074022721 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsSBCharSetProber.pas,v 1.3 2007/05/26 13:09:38 ya_nick Exp $ unit nsSBCharSetProber; interface uses {$I dbg.inc} nsCore, CustomDetector; const NUMBER_OF_SEQ_CAT = 4; type SequenceModel = record charToOrderMap: PChar; (* [256] table use to find a char's order*) precedenceMatrix: PChar; (* [SAMPLE_SIZE][SAMPLE_SIZE]; table to find a 2-char sequence's frequency*) mTypicalPositiveRatio: float; (* = freqSeqs / totalSeqs *) keepEnglishLetter: Boolean; (* says if this script contains English characters (not implemented)*) CharsetID: eInternalCharsetID; end; TnsSingleByteCharSetProber = class(TCustomDetector) protected mModel: SequenceModel; mReversed: Boolean; (* TRUE if we need to reverse every pair in the model lookup*) mLastOrder: byte; (*char order of last character*) mTotalSeqs: PRUint32; mSeqCounters: array [0..Pred(NUMBER_OF_SEQ_CAT)] of PRUint32; mTotalChar: PRUint32; (*characters that fall in our sampling range*) mFreqChar: PRUint32; (* Optional auxiliary prober for name decision. created and destroyed by the GroupProber*) mNameProber: TCustomDetector; public constructor Create(model: SequenceModel; reversed: Boolean = FALSE; nameProber: TCustomDetector = nil); reintroduce; destructor Destroy; override; function GetDetectedCharset: eInternalCharsetID; override; function HandleData(aBuf: PChar; aLen: integer): eProbingState; override; procedure Reset; override; function GetConfidence: float; override; (* This feature is not implemented yet. any current language model*) (* contain this parameter as PR_FALSE. No one is looking at this*) (* parameter or calling this method.*) (* Moreover, the nsSBCSGroupProber which calls the HandleData of this*) (* prober has a hard-coded call to FilterWithoutEnglishLetters which gets rid*) (* of the English letters.*) function KeepEnglishLetters: Boolean; virtual; (* (not implemented)*) end; implementation {$ifdef DEBUG_chardet} uses TypInfo, SysUtils; {$endif} const SAMPLE_SIZE: byte = 64; SB_ENOUGH_REL_THRESHOLD = 1024; POSITIVE_SHORTCUT_THRESHOLD = SHORTCUT_THRESHOLD; NEGATIVE_SHORTCUT_THRESHOLD = 1 - POSITIVE_SHORTCUT_THRESHOLD; SYMBOL_CAT_ORDER: byte = 250; POSITIVE_CAT = (NUMBER_OF_SEQ_CAT-1); (*#define NEGATIVE_APPROACH 1*) {$ifdef NEGATIVE_APPROACH} NEGATIVE_CAT = 0; {$endif} { TnsSingleByteCharSetProber } constructor TnsSingleByteCharSetProber.Create(model: SequenceModel; reversed: Boolean = FALSE; nameProber: TCustomDetector = nil); begin inherited Create; mModel := model; mReversed := reversed; mNameProber := nameProber; Reset; end; destructor TnsSingleByteCharSetProber.Destroy; begin inherited; end; function TnsSingleByteCharSetProber.GetDetectedCharset: eInternalCharsetID; begin if mNameProber = nil then begin Result := mModel.CharsetID; exit; end; Result := mNameProber.GetDetectedCharset; end; (*#define NEGATIVE_APPROACH 1*) function TnsSingleByteCharSetProber.GetConfidence: float; var r: float; begin {$ifdef NEGATIVE_APPROACH} if mTotalSeqs > 0 then if mTotalSeqs > mSeqCounters[NEGATIVE_CAT] * 10 then begin Result := (mTotalSeqs-mSeqCounters[NEGATIVE_CAT] * 10) / mTotalSeqs * mFreqChar / mTotalChar; exit; end; Result := SURE_NO; {$else} (*POSITIVE_APPROACH*) if mTotalSeqs > 0 then begin r := (1.0) * mSeqCounters[POSITIVE_CAT] / mTotalSeqs / mModel.mTypicalPositiveRatio; r := r * mFreqChar / mTotalChar; if r >= 1.0 then r := SURE_YES; Result := r; exit; end; Result := SURE_NO; {$endif} end; function TnsSingleByteCharSetProber.HandleData(aBuf: PChar; aLen: integer): eProbingState; var order: byte; i: integer; cf: float; begin Result := inherited HandleData(aBuf, aLen); if Result = psNotMe then exit; // TODO - move here call to FilterWithoutEnglishLetters from nsSBCSGroupProber.pas // if not mModel.keepEnglishLetter then ... for i := 0 to Pred(aLen) do begin order := byte(mModel.charToOrderMap[byte(aBuf[i])]); if order < SYMBOL_CAT_ORDER then inc(mTotalChar); if order < SAMPLE_SIZE then begin inc(mFreqChar); if mLastOrder < SAMPLE_SIZE then begin inc(mTotalSeqs); {$ifdef DEBUG_chardet} //if ((mLastOrder * SAMPLE_SIZE + order) >= 4096) then AddDump(Format('oredr %4d for byte %4d last order %4d'+#10#13+ 'array index %4d array high %8d'+#10#13+ 'LangModel %s', [order,byte(aBuf[i]),mLastOrder, (mLastOrder * SAMPLE_SIZE + order),4096, getEnumName(TypeInfo(eInternalCharsetID), integer(mModel.CharsetID))])); {$endif} if not mReversed then inc(mSeqCounters[cardinal(mModel.precedenceMatrix[mLastOrder * SAMPLE_SIZE + order])]) else inc(mSeqCounters[cardinal(mModel.precedenceMatrix[order * SAMPLE_SIZE + mLastOrder])]); (* reverse the order of the letters in the lookup*) end; end; mLastOrder:= order; end; if mState = psDetecting then if mTotalSeqs > SB_ENOUGH_REL_THRESHOLD then begin cf := GetConfidence; if cf > POSITIVE_SHORTCUT_THRESHOLD then mState:= psFoundIt else if cf < NEGATIVE_SHORTCUT_THRESHOLD then mState:= psNotMe; end; Result := mState; end; function TnsSingleByteCharSetProber.KeepEnglishLetters: Boolean; begin Result := mModel.keepEnglishLetter; end; procedure TnsSingleByteCharSetProber.Reset; var i: integer; begin if mEnabled then mState := psDetecting else mState := psNotMe; mLastOrder := 255; for i := 0 to Pred(NUMBER_OF_SEQ_CAT) do mSeqCounters[i] := 0; mTotalSeqs := 0; mTotalChar := 0; mFreqChar := 0; end; end. doublecmd-0.8.2/components/chsdet/src/GB2312Freq.pas0000664000175000017500000010761112014201074021053 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: GB2312Freq.pas,v 1.2 2007/05/20 15:46:04 ya_nick Exp $ unit GB2312Freq; //GB2312 most frequently used character table //Char to FreqOrder table , from hz6763 (****************************************************************************** * 512 --> 0.79 -- 0.79 * 1024 --> 0.92 -- 0.13 * 2048 --> 0.98 -- 0.06 * 6768 --> 1.00 -- 0.02 * * Idea Distribution Ratio = 0.79135/(1-0.79135) = 3.79 * Random Distribution Ration = 512 / (3755 - 512) = 0.157 * * Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR *****************************************************************************) interface uses nsCore; const GB2312_TYPICAL_DISTRIBUTION_RATIO: float = 0.9; GB2312_TABLE_SIZE = 3760; GB2312CharToFreqOrder: array [0..GB2312_TABLE_SIZE-1] of PRInt16 = ( 1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, 2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, 2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, 1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, 1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, 1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, 2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, 3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, 1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, 2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, 2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, 1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, 3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, 1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, 2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, 1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, 3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, 1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, 2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, 1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, 3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, 3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, 3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, 1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, 3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, 2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, 1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, 1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, 4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, 3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, 3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, 1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, 2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, 1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, 1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, 3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, 3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, 4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, 3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, 1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, 1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, 4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, 3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, 1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, 1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, 2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, 3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, 4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, 3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, 2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, 2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, 2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, 2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, 3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, 2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, 2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, 1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, 2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, 1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, 1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, 1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, 2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, 3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, 2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, 2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, 2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, 3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, 1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, 1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, 2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, 1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, 3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, 1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, 1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, 3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, 2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, 1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, 4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, 1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, 1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, 3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, 1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, 1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, 1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, 1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, 3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, 4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, 3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, 2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, 2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, 1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, 3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, 2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, 1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, 1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, 2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, 2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, 3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, 4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, 3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, 3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, 2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, 1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, 3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, 4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, 2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, 1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, 1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, 1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, 3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, 1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, 1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, 2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, 2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, 2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, 1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, 1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, 2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, 1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, 1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, 2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, 2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, 3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, 1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, 4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, 3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, 1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, 3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, 1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, 4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, 1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, 2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, 1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, 1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, 3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, 2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, 1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, 1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, 1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, 3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, 2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, 3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, 3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, 3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, 2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, 2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, 1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, 1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, 3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, 3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, 1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, 1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, 3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, 2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, 2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, 1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, 3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, 4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, 1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, 2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, 3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, 3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, 1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, 2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, 1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, 1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, 1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, 1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, 1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, 1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483 //last 512 (*************************************************************************************** *Everything below is of no interest for detection purpose * *************************************************************************************** 5508,6484,3900,3414,3974,4441,4024,3537,4037,5628,5099,3633,6485,3148,6486,3636, 5509,3257,5510,5973,5445,5872,4941,4403,3174,4627,5873,6276,2286,4230,5446,5874, 5122,6102,6103,4162,5447,5123,5323,4849,6277,3980,3851,5066,4246,5774,5067,6278, 3001,2807,5695,3346,5775,5974,5158,5448,6487,5975,5976,5776,3598,6279,5696,4806, 4211,4154,6280,6488,6489,6490,6281,4212,5037,3374,4171,6491,4562,4807,4722,4827, 5977,6104,4532,4079,5159,5324,5160,4404,3858,5359,5875,3975,4288,4610,3486,4512, 5325,3893,5360,6282,6283,5560,2522,4231,5978,5186,5449,2569,3878,6284,5401,3578, 4415,6285,4656,5124,5979,2506,4247,4449,3219,3417,4334,4969,4329,6492,4576,4828, 4172,4416,4829,5402,6286,3927,3852,5361,4369,4830,4477,4867,5876,4173,6493,6105, 4657,6287,6106,5877,5450,6494,4155,4868,5451,3700,5629,4384,6288,6289,5878,3189, 4881,6107,6290,6495,4513,6496,4692,4515,4723,5100,3356,6497,6291,3810,4080,5561, 3570,4430,5980,6498,4355,5697,6499,4724,6108,6109,3764,4050,5038,5879,4093,3226, 6292,5068,5217,4693,3342,5630,3504,4831,4377,4466,4309,5698,4431,5777,6293,5778, 4272,3706,6110,5326,3752,4676,5327,4273,5403,4767,5631,6500,5699,5880,3475,5039, 6294,5562,5125,4348,4301,4482,4068,5126,4593,5700,3380,3462,5981,5563,3824,5404, 4970,5511,3825,4738,6295,6501,5452,4516,6111,5881,5564,6502,6296,5982,6503,4213, 4163,3454,6504,6112,4009,4450,6113,4658,6297,6114,3035,6505,6115,3995,4904,4739, 4563,4942,4110,5040,3661,3928,5362,3674,6506,5292,3612,4791,5565,4149,5983,5328, 5259,5021,4725,4577,4564,4517,4364,6298,5405,4578,5260,4594,4156,4157,5453,3592, 3491,6507,5127,5512,4709,4922,5984,5701,4726,4289,6508,4015,6116,5128,4628,3424, 4241,5779,6299,4905,6509,6510,5454,5702,5780,6300,4365,4923,3971,6511,5161,3270, 3158,5985,4100, 867,5129,5703,6117,5363,3695,3301,5513,4467,6118,6512,5455,4232, 4242,4629,6513,3959,4478,6514,5514,5329,5986,4850,5162,5566,3846,4694,6119,5456, 4869,5781,3779,6301,5704,5987,5515,4710,6302,5882,6120,4392,5364,5705,6515,6121, 6516,6517,3736,5988,5457,5989,4695,2457,5883,4551,5782,6303,6304,6305,5130,4971, 6122,5163,6123,4870,3263,5365,3150,4871,6518,6306,5783,5069,5706,3513,3498,4409, 5330,5632,5366,5458,5459,3991,5990,4502,3324,5991,5784,3696,4518,5633,4119,6519, 4630,5634,4417,5707,4832,5992,3418,6124,5993,5567,4768,5218,6520,4595,3458,5367, 6125,5635,6126,4202,6521,4740,4924,6307,3981,4069,4385,6308,3883,2675,4051,3834, 4302,4483,5568,5994,4972,4101,5368,6309,5164,5884,3922,6127,6522,6523,5261,5460, 5187,4164,5219,3538,5516,4111,3524,5995,6310,6311,5369,3181,3386,2484,5188,3464, 5569,3627,5708,6524,5406,5165,4677,4492,6312,4872,4851,5885,4468,5996,6313,5709, 5710,6128,2470,5886,6314,5293,4882,5785,3325,5461,5101,6129,5711,5786,6525,4906, 6526,6527,4418,5887,5712,4808,2907,3701,5713,5888,6528,3765,5636,5331,6529,6530, 3593,5889,3637,4943,3692,5714,5787,4925,6315,6130,5462,4405,6131,6132,6316,5262, 6531,6532,5715,3859,5716,5070,4696,5102,3929,5788,3987,4792,5997,6533,6534,3920, 4809,5000,5998,6535,2974,5370,6317,5189,5263,5717,3826,6536,3953,5001,4883,3190, 5463,5890,4973,5999,4741,6133,6134,3607,5570,6000,4711,3362,3630,4552,5041,6318, 6001,2950,2953,5637,4646,5371,4944,6002,2044,4120,3429,6319,6537,5103,4833,6538, 6539,4884,4647,3884,6003,6004,4758,3835,5220,5789,4565,5407,6540,6135,5294,4697, 4852,6320,6321,3206,4907,6541,6322,4945,6542,6136,6543,6323,6005,4631,3519,6544, 5891,6545,5464,3784,5221,6546,5571,4659,6547,6324,6137,5190,6548,3853,6549,4016, 4834,3954,6138,5332,3827,4017,3210,3546,4469,5408,5718,3505,4648,5790,5131,5638, 5791,5465,4727,4318,6325,6326,5792,4553,4010,4698,3439,4974,3638,4335,3085,6006, 5104,5042,5166,5892,5572,6327,4356,4519,5222,5573,5333,5793,5043,6550,5639,5071, 4503,6328,6139,6551,6140,3914,3901,5372,6007,5640,4728,4793,3976,3836,4885,6552, 4127,6553,4451,4102,5002,6554,3686,5105,6555,5191,5072,5295,4611,5794,5296,6556, 5893,5264,5894,4975,5466,5265,4699,4976,4370,4056,3492,5044,4886,6557,5795,4432, 4769,4357,5467,3940,4660,4290,6141,4484,4770,4661,3992,6329,4025,4662,5022,4632, 4835,4070,5297,4663,4596,5574,5132,5409,5895,6142,4504,5192,4664,5796,5896,3885, 5575,5797,5023,4810,5798,3732,5223,4712,5298,4084,5334,5468,6143,4052,4053,4336, 4977,4794,6558,5335,4908,5576,5224,4233,5024,4128,5469,5225,4873,6008,5045,4729, 4742,4633,3675,4597,6559,5897,5133,5577,5003,5641,5719,6330,6560,3017,2382,3854, 4406,4811,6331,4393,3964,4946,6561,2420,3722,6562,4926,4378,3247,1736,4442,6332, 5134,6333,5226,3996,2918,5470,4319,4003,4598,4743,4744,4485,3785,3902,5167,5004, 5373,4394,5898,6144,4874,1793,3997,6334,4085,4214,5106,5642,4909,5799,6009,4419, 4189,3330,5899,4165,4420,5299,5720,5227,3347,6145,4081,6335,2876,3930,6146,3293, 3786,3910,3998,5900,5300,5578,2840,6563,5901,5579,6147,3531,5374,6564,6565,5580, 4759,5375,6566,6148,3559,5643,6336,6010,5517,6337,6338,5721,5902,3873,6011,6339, 6567,5518,3868,3649,5722,6568,4771,4947,6569,6149,4812,6570,2853,5471,6340,6341, 5644,4795,6342,6012,5723,6343,5724,6013,4349,6344,3160,6150,5193,4599,4514,4493, 5168,4320,6345,4927,3666,4745,5169,5903,5005,4928,6346,5725,6014,4730,4203,5046, 4948,3395,5170,6015,4150,6016,5726,5519,6347,5047,3550,6151,6348,4197,4310,5904, 6571,5581,2965,6152,4978,3960,4291,5135,6572,5301,5727,4129,4026,5905,4853,5728, 5472,6153,6349,4533,2700,4505,5336,4678,3583,5073,2994,4486,3043,4554,5520,6350, 6017,5800,4487,6351,3931,4103,5376,6352,4011,4321,4311,4190,5136,6018,3988,3233, 4350,5906,5645,4198,6573,5107,3432,4191,3435,5582,6574,4139,5410,6353,5411,3944, 5583,5074,3198,6575,6354,4358,6576,5302,4600,5584,5194,5412,6577,6578,5585,5413, 5303,4248,5414,3879,4433,6579,4479,5025,4854,5415,6355,4760,4772,3683,2978,4700, 3797,4452,3965,3932,3721,4910,5801,6580,5195,3551,5907,3221,3471,3029,6019,3999, 5908,5909,5266,5267,3444,3023,3828,3170,4796,5646,4979,4259,6356,5647,5337,3694, 6357,5648,5338,4520,4322,5802,3031,3759,4071,6020,5586,4836,4386,5048,6581,3571, 4679,4174,4949,6154,4813,3787,3402,3822,3958,3215,3552,5268,4387,3933,4950,4359, 6021,5910,5075,3579,6358,4234,4566,5521,6359,3613,5049,6022,5911,3375,3702,3178, 4911,5339,4521,6582,6583,4395,3087,3811,5377,6023,6360,6155,4027,5171,5649,4421, 4249,2804,6584,2270,6585,4000,4235,3045,6156,5137,5729,4140,4312,3886,6361,4330, 6157,4215,6158,3500,3676,4929,4331,3713,4930,5912,4265,3776,3368,5587,4470,4855, 3038,4980,3631,6159,6160,4132,4680,6161,6362,3923,4379,5588,4255,6586,4121,6587, 6363,4649,6364,3288,4773,4774,6162,6024,6365,3543,6588,4274,3107,3737,5050,5803, 4797,4522,5589,5051,5730,3714,4887,5378,4001,4523,6163,5026,5522,4701,4175,2791, 3760,6589,5473,4224,4133,3847,4814,4815,4775,3259,5416,6590,2738,6164,6025,5304, 3733,5076,5650,4816,5590,6591,6165,6592,3934,5269,6593,3396,5340,6594,5804,3445, 3602,4042,4488,5731,5732,3525,5591,4601,5196,6166,6026,5172,3642,4612,3202,4506, 4798,6366,3818,5108,4303,5138,5139,4776,3332,4304,2915,3415,4434,5077,5109,4856, 2879,5305,4817,6595,5913,3104,3144,3903,4634,5341,3133,5110,5651,5805,6167,4057, 5592,2945,4371,5593,6596,3474,4182,6367,6597,6168,4507,4279,6598,2822,6599,4777, 4713,5594,3829,6169,3887,5417,6170,3653,5474,6368,4216,2971,5228,3790,4579,6369, 5733,6600,6601,4951,4746,4555,6602,5418,5475,6027,3400,4665,5806,6171,4799,6028, 5052,6172,3343,4800,4747,5006,6370,4556,4217,5476,4396,5229,5379,5477,3839,5914, 5652,5807,4714,3068,4635,5808,6173,5342,4192,5078,5419,5523,5734,6174,4557,6175, 4602,6371,6176,6603,5809,6372,5735,4260,3869,5111,5230,6029,5112,6177,3126,4681, 5524,5915,2706,3563,4748,3130,6178,4018,5525,6604,6605,5478,4012,4837,6606,4534, 4193,5810,4857,3615,5479,6030,4082,3697,3539,4086,5270,3662,4508,4931,5916,4912, 5811,5027,3888,6607,4397,3527,3302,3798,2775,2921,2637,3966,4122,4388,4028,4054, 1633,4858,5079,3024,5007,3982,3412,5736,6608,3426,3236,5595,3030,6179,3427,3336, 3279,3110,6373,3874,3039,5080,5917,5140,4489,3119,6374,5812,3405,4494,6031,4666, 4141,6180,4166,6032,5813,4981,6609,5081,4422,4982,4112,3915,5653,3296,3983,6375, 4266,4410,5654,6610,6181,3436,5082,6611,5380,6033,3819,5596,4535,5231,5306,5113, 6612,4952,5918,4275,3113,6613,6376,6182,6183,5814,3073,4731,4838,5008,3831,6614, 4888,3090,3848,4280,5526,5232,3014,5655,5009,5737,5420,5527,6615,5815,5343,5173, 5381,4818,6616,3151,4953,6617,5738,2796,3204,4360,2989,4281,5739,5174,5421,5197, 3132,5141,3849,5142,5528,5083,3799,3904,4839,5480,2880,4495,3448,6377,6184,5271, 5919,3771,3193,6034,6035,5920,5010,6036,5597,6037,6378,6038,3106,5422,6618,5423, 5424,4142,6619,4889,5084,4890,4313,5740,6620,3437,5175,5307,5816,4199,5198,5529, 5817,5199,5656,4913,5028,5344,3850,6185,2955,5272,5011,5818,4567,4580,5029,5921, 3616,5233,6621,6622,6186,4176,6039,6379,6380,3352,5200,5273,2908,5598,5234,3837, 5308,6623,6624,5819,4496,4323,5309,5201,6625,6626,4983,3194,3838,4167,5530,5922, 5274,6381,6382,3860,3861,5599,3333,4292,4509,6383,3553,5481,5820,5531,4778,6187, 3955,3956,4324,4389,4218,3945,4325,3397,2681,5923,4779,5085,4019,5482,4891,5382, 5383,6040,4682,3425,5275,4094,6627,5310,3015,5483,5657,4398,5924,3168,4819,6628, 5925,6629,5532,4932,4613,6041,6630,4636,6384,4780,4204,5658,4423,5821,3989,4683, 5822,6385,4954,6631,5345,6188,5425,5012,5384,3894,6386,4490,4104,6632,5741,5053, 6633,5823,5926,5659,5660,5927,6634,5235,5742,5824,4840,4933,4820,6387,4859,5928, 4955,6388,4143,3584,5825,5346,5013,6635,5661,6389,5014,5484,5743,4337,5176,5662, 6390,2836,6391,3268,6392,6636,6042,5236,6637,4158,6638,5744,5663,4471,5347,3663, 4123,5143,4293,3895,6639,6640,5311,5929,5826,3800,6189,6393,6190,5664,5348,3554, 3594,4749,4603,6641,5385,4801,6043,5827,4183,6642,5312,5426,4761,6394,5665,6191, 4715,2669,6643,6644,5533,3185,5427,5086,5930,5931,5386,6192,6044,6645,4781,4013, 5745,4282,4435,5534,4390,4267,6045,5746,4984,6046,2743,6193,3501,4087,5485,5932, 5428,4184,4095,5747,4061,5054,3058,3862,5933,5600,6646,5144,3618,6395,3131,5055, 5313,6396,4650,4956,3855,6194,3896,5202,4985,4029,4225,6195,6647,5828,5486,5829, 3589,3002,6648,6397,4782,5276,6649,6196,6650,4105,3803,4043,5237,5830,6398,4096, 3643,6399,3528,6651,4453,3315,4637,6652,3984,6197,5535,3182,3339,6653,3096,2660, 6400,6654,3449,5934,4250,4236,6047,6401,5831,6655,5487,3753,4062,5832,6198,6199, 6656,3766,6657,3403,4667,6048,6658,4338,2897,5833,3880,2797,3780,4326,6659,5748, 5015,6660,5387,4351,5601,4411,6661,3654,4424,5935,4339,4072,5277,4568,5536,6402, 6662,5238,6663,5349,5203,6200,5204,6201,5145,4536,5016,5056,4762,5834,4399,4957, 6202,6403,5666,5749,6664,4340,6665,5936,5177,5667,6666,6667,3459,4668,6404,6668, 6669,4543,6203,6670,4276,6405,4480,5537,6671,4614,5205,5668,6672,3348,2193,4763, 6406,6204,5937,5602,4177,5669,3419,6673,4020,6205,4443,4569,5388,3715,3639,6407, 6049,4058,6206,6674,5938,4544,6050,4185,4294,4841,4651,4615,5488,6207,6408,6051, 5178,3241,3509,5835,6208,4958,5836,4341,5489,5278,6209,2823,5538,5350,5206,5429, 6675,4638,4875,4073,3516,4684,4914,4860,5939,5603,5389,6052,5057,3237,5490,3791, 6676,6409,6677,4821,4915,4106,5351,5058,4243,5539,4244,5604,4842,4916,5239,3028, 3716,5837,5114,5605,5390,5940,5430,6210,4332,6678,5540,4732,3667,3840,6053,4305, 3408,5670,5541,6410,2744,5240,5750,6679,3234,5606,6680,5607,5671,3608,4283,4159, 4400,5352,4783,6681,6411,6682,4491,4802,6211,6412,5941,6413,6414,5542,5751,6683, 4669,3734,5942,6684,6415,5943,5059,3328,4670,4144,4268,6685,6686,6687,6688,4372, 3603,6689,5944,5491,4373,3440,6416,5543,4784,4822,5608,3792,4616,5838,5672,3514, 5391,6417,4892,6690,4639,6691,6054,5673,5839,6055,6692,6056,5392,6212,4038,5544, 5674,4497,6057,6693,5840,4284,5675,4021,4545,5609,6418,4454,6419,6213,4113,4472, 5314,3738,5087,5279,4074,5610,4959,4063,3179,4750,6058,6420,6214,3476,4498,4716, 5431,4960,4685,6215,5241,6694,6421,6216,6695,5841,5945,6422,3748,5946,5179,3905, 5752,5545,5947,4374,6217,4455,6423,4412,6218,4803,5353,6696,3832,5280,6219,4327, 4702,6220,6221,6059,4652,5432,6424,3749,4751,6425,5753,4986,5393,4917,5948,5030, 5754,4861,4733,6426,4703,6697,6222,4671,5949,4546,4961,5180,6223,5031,3316,5281, 6698,4862,4295,4934,5207,3644,6427,5842,5950,6428,6429,4570,5843,5282,6430,6224, 5088,3239,6060,6699,5844,5755,6061,6431,2701,5546,6432,5115,5676,4039,3993,3327, 4752,4425,5315,6433,3941,6434,5677,4617,4604,3074,4581,6225,5433,6435,6226,6062, 4823,5756,5116,6227,3717,5678,4717,5845,6436,5679,5846,6063,5847,6064,3977,3354, 6437,3863,5117,6228,5547,5394,4499,4524,6229,4605,6230,4306,4500,6700,5951,6065, 3693,5952,5089,4366,4918,6701,6231,5548,6232,6702,6438,4704,5434,6703,6704,5953, 4168,6705,5680,3420,6706,5242,4407,6066,3812,5757,5090,5954,4672,4525,3481,5681, 4618,5395,5354,5316,5955,6439,4962,6707,4526,6440,3465,4673,6067,6441,5682,6708, 5435,5492,5758,5683,4619,4571,4674,4804,4893,4686,5493,4753,6233,6068,4269,6442, 6234,5032,4705,5146,5243,5208,5848,6235,6443,4963,5033,4640,4226,6236,5849,3387, 6444,6445,4436,4437,5850,4843,5494,4785,4894,6709,4361,6710,5091,5956,3331,6237, 4987,5549,6069,6711,4342,3517,4473,5317,6070,6712,6071,4706,6446,5017,5355,6713, 6714,4988,5436,6447,4734,5759,6715,4735,4547,4456,4754,6448,5851,6449,6450,3547, 5852,5318,6451,6452,5092,4205,6716,6238,4620,4219,5611,6239,6072,4481,5760,5957, 5958,4059,6240,6453,4227,4537,6241,5761,4030,4186,5244,5209,3761,4457,4876,3337, 5495,5181,6242,5959,5319,5612,5684,5853,3493,5854,6073,4169,5613,5147,4895,6074, 5210,6717,5182,6718,3830,6243,2798,3841,6075,6244,5855,5614,3604,4606,5496,5685, 5118,5356,6719,6454,5960,5357,5961,6720,4145,3935,4621,5119,5962,4261,6721,6455, 4786,5963,4375,4582,6245,6246,6247,6076,5437,4877,5856,3376,4380,6248,4160,6722, 5148,6456,5211,6457,6723,4718,6458,6724,6249,5358,4044,3297,6459,6250,5857,5615, 5497,5245,6460,5498,6725,6251,6252,5550,3793,5499,2959,5396,6461,6462,4572,5093, 5500,5964,3806,4146,6463,4426,5762,5858,6077,6253,4755,3967,4220,5965,6254,4989, 5501,6464,4352,6726,6078,4764,2290,5246,3906,5438,5283,3767,4964,2861,5763,5094, 6255,6256,4622,5616,5859,5860,4707,6727,4285,4708,4824,5617,6257,5551,4787,5212, 4965,4935,4687,6465,6728,6466,5686,6079,3494,4413,2995,5247,5966,5618,6729,5967, 5764,5765,5687,5502,6730,6731,6080,5397,6467,4990,6258,6732,4538,5060,5619,6733, 4719,5688,5439,5018,5149,5284,5503,6734,6081,4607,6259,5120,3645,5861,4583,6260, 4584,4675,5620,4098,5440,6261,4863,2379,3306,4585,5552,5689,4586,5285,6735,4864, 6736,5286,6082,6737,4623,3010,4788,4381,4558,5621,4587,4896,3698,3161,5248,4353, 4045,6262,3754,5183,4588,6738,6263,6739,6740,5622,3936,6741,6468,6742,6264,5095, 6469,4991,5968,6743,4992,6744,6083,4897,6745,4256,5766,4307,3108,3968,4444,5287, 3889,4343,6084,4510,6085,4559,6086,4898,5969,6746,5623,5061,4919,5249,5250,5504, 5441,6265,5320,4878,3242,5862,5251,3428,6087,6747,4237,5624,5442,6266,5553,4539, 6748,2585,3533,5398,4262,6088,5150,4736,4438,6089,6267,5505,4966,6749,6268,6750, 6269,5288,5554,3650,6090,6091,4624,6092,5690,6751,5863,4270,5691,4277,5555,5864, 6752,5692,4720,4865,6470,5151,4688,4825,6753,3094,6754,6471,3235,4653,6755,5213, 5399,6756,3201,4589,5865,4967,6472,5866,6473,5019,3016,6757,5321,4756,3957,4573, 6093,4993,5767,4721,6474,6758,5625,6759,4458,6475,6270,6760,5556,4994,5214,5252, 6271,3875,5768,6094,5034,5506,4376,5769,6761,2120,6476,5253,5770,6762,5771,5970, 3990,5971,5557,5558,5772,6477,6095,2787,4641,5972,5121,6096,6097,6272,6763,3703, 5867,5507,6273,4206,6274,4789,6098,6764,3619,3646,3833,3804,2394,3788,4936,3978, 4866,4899,6099,6100,5559,6478,6765,3599,5868,6101,5869,5870,6275,6766,4527,6767, *******************************************************************************) ); implementation end. doublecmd-0.8.2/components/chsdet/src/stat/0000775000175000017500000000000013244011205017676 5ustar alexxalexxdoublecmd-0.8.2/components/chsdet/src/stat/EUCKRStatistics.inc0000664000175000017500000001207112014201074023315 0ustar alexxalexxconst EUCKRStat: rEUCStatistics = ( mFirstByteFreq: ( 0.000000, // FreqH[a1] 0.000000, // FreqH[a2] 0.000000, // FreqH[a3] 0.000000, // FreqH[a4] 0.000000, // FreqH[a5] 0.000000, // FreqH[a6] 0.000000, // FreqH[a7] 0.000412, // FreqH[a8] 0.000000, // FreqH[a9] 0.000000, // FreqH[aa] 0.000000, // FreqH[ab] 0.000000, // FreqH[ac] 0.000000, // FreqH[ad] 0.000000, // FreqH[ae] 0.000000, // FreqH[af] 0.057502, // FreqH[b0] 0.033182, // FreqH[b1] 0.002267, // FreqH[b2] 0.016076, // FreqH[b3] 0.014633, // FreqH[b4] 0.032976, // FreqH[b5] 0.004122, // FreqH[b6] 0.011336, // FreqH[b7] 0.058533, // FreqH[b8] 0.024526, // FreqH[b9] 0.025969, // FreqH[ba] 0.054411, // FreqH[bb] 0.019580, // FreqH[bc] 0.063273, // FreqH[bd] 0.113974, // FreqH[be] 0.029885, // FreqH[bf] 0.150041, // FreqH[c0] 0.059151, // FreqH[c1] 0.002679, // FreqH[c2] 0.009893, // FreqH[c3] 0.014839, // FreqH[c4] 0.026381, // FreqH[c5] 0.015045, // FreqH[c6] 0.069456, // FreqH[c7] 0.089860, // FreqH[c8] 0.000000, // FreqH[c9] 0.000000, // FreqH[ca] 0.000000, // FreqH[cb] 0.000000, // FreqH[cc] 0.000000, // FreqH[cd] 0.000000, // FreqH[ce] 0.000000, // FreqH[cf] 0.000000, // FreqH[d0] 0.000000, // FreqH[d1] 0.000000, // FreqH[d2] 0.000000, // FreqH[d3] 0.000000, // FreqH[d4] 0.000000, // FreqH[d5] 0.000000, // FreqH[d6] 0.000000, // FreqH[d7] 0.000000, // FreqH[d8] 0.000000, // FreqH[d9] 0.000000, // FreqH[da] 0.000000, // FreqH[db] 0.000000, // FreqH[dc] 0.000000, // FreqH[dd] 0.000000, // FreqH[de] 0.000000, // FreqH[df] 0.000000, // FreqH[e0] 0.000000, // FreqH[e1] 0.000000, // FreqH[e2] 0.000000, // FreqH[e3] 0.000000, // FreqH[e4] 0.000000, // FreqH[e5] 0.000000, // FreqH[e6] 0.000000, // FreqH[e7] 0.000000, // FreqH[e8] 0.000000, // FreqH[e9] 0.000000, // FreqH[ea] 0.000000, // FreqH[eb] 0.000000, // FreqH[ec] 0.000000, // FreqH[ed] 0.000000, // FreqH[ee] 0.000000, // FreqH[ef] 0.000000, // FreqH[f0] 0.000000, // FreqH[f1] 0.000000, // FreqH[f2] 0.000000, // FreqH[f3] 0.000000, // FreqH[f4] 0.000000, // FreqH[f5] 0.000000, // FreqH[f6] 0.000000, // FreqH[f7] 0.000000, // FreqH[f8] 0.000000, // FreqH[f9] 0.000000, // FreqH[fa] 0.000000, // FreqH[fb] 0.000000, // FreqH[fc] 0.000000, // FreqH[fd] 0.000000 // FreqH[fe] ); mFirstByteStdDev: 0.025593; // Lead Byte StdDev mFirstByteMean: 0.010638; // Lead Byte Mean mFirstByteWeight: 0.647437; // Lead Byte Weight mSecoundByteFreq: ( 0.016694, // FreqL[a1] 0.000000, // FreqL[a2] 0.012778, // FreqL[a3] 0.030091, // FreqL[a4] 0.002679, // FreqL[a5] 0.006595, // FreqL[a6] 0.001855, // FreqL[a7] 0.000824, // FreqL[a8] 0.005977, // FreqL[a9] 0.004740, // FreqL[aa] 0.003092, // FreqL[ab] 0.000824, // FreqL[ac] 0.019580, // FreqL[ad] 0.037304, // FreqL[ae] 0.008244, // FreqL[af] 0.014633, // FreqL[b0] 0.001031, // FreqL[b1] 0.000000, // FreqL[b2] 0.003298, // FreqL[b3] 0.002061, // FreqL[b4] 0.006183, // FreqL[b5] 0.005977, // FreqL[b6] 0.000824, // FreqL[b7] 0.021847, // FreqL[b8] 0.014839, // FreqL[b9] 0.052968, // FreqL[ba] 0.017312, // FreqL[bb] 0.007626, // FreqL[bc] 0.000412, // FreqL[bd] 0.000824, // FreqL[be] 0.011129, // FreqL[bf] 0.000000, // FreqL[c0] 0.000412, // FreqL[c1] 0.001649, // FreqL[c2] 0.005977, // FreqL[c3] 0.065746, // FreqL[c4] 0.020198, // FreqL[c5] 0.021434, // FreqL[c6] 0.014633, // FreqL[c7] 0.004122, // FreqL[c8] 0.001649, // FreqL[c9] 0.000824, // FreqL[ca] 0.000824, // FreqL[cb] 0.051937, // FreqL[cc] 0.019580, // FreqL[cd] 0.023289, // FreqL[ce] 0.026381, // FreqL[cf] 0.040396, // FreqL[d0] 0.009068, // FreqL[d1] 0.001443, // FreqL[d2] 0.003710, // FreqL[d3] 0.007420, // FreqL[d4] 0.001443, // FreqL[d5] 0.013190, // FreqL[d6] 0.002885, // FreqL[d7] 0.000412, // FreqL[d8] 0.003298, // FreqL[d9] 0.025969, // FreqL[da] 0.000412, // FreqL[db] 0.000412, // FreqL[dc] 0.006183, // FreqL[dd] 0.003298, // FreqL[de] 0.066983, // FreqL[df] 0.002679, // FreqL[e0] 0.002267, // FreqL[e1] 0.011129, // FreqL[e2] 0.000412, // FreqL[e3] 0.010099, // FreqL[e4] 0.015251, // FreqL[e5] 0.007626, // FreqL[e6] 0.043899, // FreqL[e7] 0.003710, // FreqL[e8] 0.002679, // FreqL[e9] 0.001443, // FreqL[ea] 0.010923, // FreqL[eb] 0.002885, // FreqL[ec] 0.009068, // FreqL[ed] 0.019992, // FreqL[ee] 0.000412, // FreqL[ef] 0.008450, // FreqL[f0] 0.005153, // FreqL[f1] 0.000000, // FreqL[f2] 0.010099, // FreqL[f3] 0.000000, // FreqL[f4] 0.001649, // FreqL[f5] 0.012160, // FreqL[f6] 0.011542, // FreqL[f7] 0.006595, // FreqL[f8] 0.001855, // FreqL[f9] 0.010923, // FreqL[fa] 0.000412, // FreqL[fb] 0.023702, // FreqL[fc] 0.003710, // FreqL[fd] 0.001855 // FreqL[fe] ); mSecoundByteStdDev: 0.013937; // Trail Byte StdDev mSecoundByteMean: 0.010638; // Trail Byte Mean mSecoundByteWeight: 0.352563 // Trial Byte Weight ); doublecmd-0.8.2/components/chsdet/src/stat/Big5Statistics.inc0000664000175000017500000001207012014201074023231 0ustar alexxalexxconst Big5Stat: rEUCStatistics = ( mFirstByteFreq: ( 0.000000, // FreqH[a1] 0.000000, // FreqH[a2] 0.000000, // FreqH[a3] 0.114427, // FreqH[a4] 0.061058, // FreqH[a5] 0.075598, // FreqH[a6] 0.048386, // FreqH[a7] 0.063966, // FreqH[a8] 0.027094, // FreqH[a9] 0.095787, // FreqH[aa] 0.029525, // FreqH[ab] 0.031331, // FreqH[ac] 0.036915, // FreqH[ad] 0.021805, // FreqH[ae] 0.019349, // FreqH[af] 0.037496, // FreqH[b0] 0.018068, // FreqH[b1] 0.012760, // FreqH[b2] 0.030053, // FreqH[b3] 0.017339, // FreqH[b4] 0.016731, // FreqH[b5] 0.019501, // FreqH[b6] 0.011240, // FreqH[b7] 0.032973, // FreqH[b8] 0.016658, // FreqH[b9] 0.015872, // FreqH[ba] 0.021458, // FreqH[bb] 0.012378, // FreqH[bc] 0.017003, // FreqH[bd] 0.020802, // FreqH[be] 0.012454, // FreqH[bf] 0.009239, // FreqH[c0] 0.012829, // FreqH[c1] 0.007922, // FreqH[c2] 0.010079, // FreqH[c3] 0.009815, // FreqH[c4] 0.010104, // FreqH[c5] 0.000000, // FreqH[c6] 0.000000, // FreqH[c7] 0.000000, // FreqH[c8] 0.000053, // FreqH[c9] 0.000035, // FreqH[ca] 0.000105, // FreqH[cb] 0.000031, // FreqH[cc] 0.000088, // FreqH[cd] 0.000027, // FreqH[ce] 0.000027, // FreqH[cf] 0.000026, // FreqH[d0] 0.000035, // FreqH[d1] 0.000024, // FreqH[d2] 0.000034, // FreqH[d3] 0.000375, // FreqH[d4] 0.000025, // FreqH[d5] 0.000028, // FreqH[d6] 0.000020, // FreqH[d7] 0.000024, // FreqH[d8] 0.000028, // FreqH[d9] 0.000031, // FreqH[da] 0.000059, // FreqH[db] 0.000040, // FreqH[dc] 0.000030, // FreqH[dd] 0.000079, // FreqH[de] 0.000037, // FreqH[df] 0.000040, // FreqH[e0] 0.000023, // FreqH[e1] 0.000030, // FreqH[e2] 0.000027, // FreqH[e3] 0.000064, // FreqH[e4] 0.000020, // FreqH[e5] 0.000027, // FreqH[e6] 0.000025, // FreqH[e7] 0.000074, // FreqH[e8] 0.000019, // FreqH[e9] 0.000023, // FreqH[ea] 0.000021, // FreqH[eb] 0.000018, // FreqH[ec] 0.000017, // FreqH[ed] 0.000035, // FreqH[ee] 0.000021, // FreqH[ef] 0.000019, // FreqH[f0] 0.000025, // FreqH[f1] 0.000017, // FreqH[f2] 0.000037, // FreqH[f3] 0.000018, // FreqH[f4] 0.000018, // FreqH[f5] 0.000019, // FreqH[f6] 0.000022, // FreqH[f7] 0.000033, // FreqH[f8] 0.000032, // FreqH[f9] 0.000000, // FreqH[fa] 0.000000, // FreqH[fb] 0.000000, // FreqH[fc] 0.000000, // FreqH[fd] 0.000000 // FreqH[fe] ); mFirstByteStdDev: 0.020606; // Lead Byte StdDev mFirstByteMean: 0.010638; // Lead Byte Mean mFirstByteWeight: 0.675261; // Lead Byte Weight mSecoundByteFreq: ( 0.020256, // FreqL[a1] 0.003293, // FreqL[a2] 0.045811, // FreqL[a3] 0.016650, // FreqL[a4] 0.007066, // FreqL[a5] 0.004146, // FreqL[a6] 0.009229, // FreqL[a7] 0.007333, // FreqL[a8] 0.003296, // FreqL[a9] 0.005239, // FreqL[aa] 0.008282, // FreqL[ab] 0.003791, // FreqL[ac] 0.006116, // FreqL[ad] 0.003536, // FreqL[ae] 0.004024, // FreqL[af] 0.016654, // FreqL[b0] 0.009334, // FreqL[b1] 0.005429, // FreqL[b2] 0.033392, // FreqL[b3] 0.006121, // FreqL[b4] 0.008983, // FreqL[b5] 0.002801, // FreqL[b6] 0.004221, // FreqL[b7] 0.010357, // FreqL[b8] 0.014695, // FreqL[b9] 0.077937, // FreqL[ba] 0.006314, // FreqL[bb] 0.004020, // FreqL[bc] 0.007331, // FreqL[bd] 0.007150, // FreqL[be] 0.005341, // FreqL[bf] 0.009195, // FreqL[c0] 0.005350, // FreqL[c1] 0.005698, // FreqL[c2] 0.004472, // FreqL[c3] 0.007242, // FreqL[c4] 0.004039, // FreqL[c5] 0.011154, // FreqL[c6] 0.016184, // FreqL[c7] 0.004741, // FreqL[c8] 0.012814, // FreqL[c9] 0.007679, // FreqL[ca] 0.008045, // FreqL[cb] 0.016631, // FreqL[cc] 0.009451, // FreqL[cd] 0.016487, // FreqL[ce] 0.007287, // FreqL[cf] 0.012688, // FreqL[d0] 0.017421, // FreqL[d1] 0.013205, // FreqL[d2] 0.031480, // FreqL[d3] 0.003404, // FreqL[d4] 0.009149, // FreqL[d5] 0.008921, // FreqL[d6] 0.007514, // FreqL[d7] 0.008683, // FreqL[d8] 0.008203, // FreqL[d9] 0.031403, // FreqL[da] 0.011733, // FreqL[db] 0.015617, // FreqL[dc] 0.015306, // FreqL[dd] 0.004004, // FreqL[de] 0.010899, // FreqL[df] 0.009961, // FreqL[e0] 0.008388, // FreqL[e1] 0.010920, // FreqL[e2] 0.003925, // FreqL[e3] 0.008585, // FreqL[e4] 0.009108, // FreqL[e5] 0.015546, // FreqL[e6] 0.004659, // FreqL[e7] 0.006934, // FreqL[e8] 0.007023, // FreqL[e9] 0.020252, // FreqL[ea] 0.005387, // FreqL[eb] 0.024704, // FreqL[ec] 0.006963, // FreqL[ed] 0.002625, // FreqL[ee] 0.009512, // FreqL[ef] 0.002971, // FreqL[f0] 0.008233, // FreqL[f1] 0.010000, // FreqL[f2] 0.011973, // FreqL[f3] 0.010553, // FreqL[f4] 0.005945, // FreqL[f5] 0.006349, // FreqL[f6] 0.009401, // FreqL[f7] 0.008577, // FreqL[f8] 0.008186, // FreqL[f9] 0.008159, // FreqL[fa] 0.005033, // FreqL[fb] 0.008714, // FreqL[fc] 0.010614, // FreqL[fd] 0.006554 // FreqL[fe] ); mSecoundByteStdDev: 0.009909; // Trail Byte StdDev mSecoundByteMean: 0.010638; // Trail Byte Mean mSecoundByteWeight: 0.324739 // Trial Byte Weight ); doublecmd-0.8.2/components/chsdet/src/stat/EUCTWStatistics.inc0000664000175000017500000001207112014201074023333 0ustar alexxalexxconst EUCKTWtat: rEUCStatistics = ( mFirstByteFreq: ( 0.000000, // FreqH[a1] 0.000000, // FreqH[a2] 0.000000, // FreqH[a3] 0.000000, // FreqH[a4] 0.000000, // FreqH[a5] 0.000000, // FreqH[a6] 0.000000, // FreqH[a7] 0.000000, // FreqH[a8] 0.000000, // FreqH[a9] 0.000000, // FreqH[aa] 0.000000, // FreqH[ab] 0.000000, // FreqH[ac] 0.000000, // FreqH[ad] 0.000000, // FreqH[ae] 0.000000, // FreqH[af] 0.000000, // FreqH[b0] 0.000000, // FreqH[b1] 0.000000, // FreqH[b2] 0.000000, // FreqH[b3] 0.000000, // FreqH[b4] 0.000000, // FreqH[b5] 0.000000, // FreqH[b6] 0.000000, // FreqH[b7] 0.000000, // FreqH[b8] 0.000000, // FreqH[b9] 0.000000, // FreqH[ba] 0.000000, // FreqH[bb] 0.000000, // FreqH[bc] 0.000000, // FreqH[bd] 0.000000, // FreqH[be] 0.000000, // FreqH[bf] 0.000000, // FreqH[c0] 0.000000, // FreqH[c1] 0.000000, // FreqH[c2] 0.000000, // FreqH[c3] 0.119286, // FreqH[c4] 0.052233, // FreqH[c5] 0.044126, // FreqH[c6] 0.052494, // FreqH[c7] 0.045906, // FreqH[c8] 0.019038, // FreqH[c9] 0.032465, // FreqH[ca] 0.026252, // FreqH[cb] 0.025502, // FreqH[cc] 0.015963, // FreqH[cd] 0.052493, // FreqH[ce] 0.019256, // FreqH[cf] 0.015137, // FreqH[d0] 0.031782, // FreqH[d1] 0.017370, // FreqH[d2] 0.018494, // FreqH[d3] 0.015575, // FreqH[d4] 0.016621, // FreqH[d5] 0.007444, // FreqH[d6] 0.011642, // FreqH[d7] 0.013916, // FreqH[d8] 0.019159, // FreqH[d9] 0.016445, // FreqH[da] 0.007851, // FreqH[db] 0.011079, // FreqH[dc] 0.022842, // FreqH[dd] 0.015513, // FreqH[de] 0.010033, // FreqH[df] 0.009950, // FreqH[e0] 0.010347, // FreqH[e1] 0.013103, // FreqH[e2] 0.015371, // FreqH[e3] 0.012502, // FreqH[e4] 0.007436, // FreqH[e5] 0.018253, // FreqH[e6] 0.014134, // FreqH[e7] 0.008907, // FreqH[e8] 0.005411, // FreqH[e9] 0.009570, // FreqH[ea] 0.013598, // FreqH[eb] 0.006092, // FreqH[ec] 0.007409, // FreqH[ed] 0.008432, // FreqH[ee] 0.005816, // FreqH[ef] 0.009349, // FreqH[f0] 0.005472, // FreqH[f1] 0.007170, // FreqH[f2] 0.007420, // FreqH[f3] 0.003681, // FreqH[f4] 0.007523, // FreqH[f5] 0.004610, // FreqH[f6] 0.006154, // FreqH[f7] 0.003348, // FreqH[f8] 0.005074, // FreqH[f9] 0.005922, // FreqH[fa] 0.005254, // FreqH[fb] 0.004682, // FreqH[fc] 0.002093, // FreqH[fd] 0.000000 // FreqH[fe] ); mFirstByteStdDev: 0.016681; // Lead Byte StdDev mFirstByteMean: 0.010638; // Lead Byte Mean mFirstByteWeight: 0.715599; // Lead Byte Weight mSecoundByteFreq: ( 0.028933, // FreqL[a1] 0.011371, // FreqL[a2] 0.011053, // FreqL[a3] 0.007232, // FreqL[a4] 0.010192, // FreqL[a5] 0.004093, // FreqL[a6] 0.015043, // FreqL[a7] 0.011752, // FreqL[a8] 0.022387, // FreqL[a9] 0.008410, // FreqL[aa] 0.012448, // FreqL[ab] 0.007473, // FreqL[ac] 0.003594, // FreqL[ad] 0.007139, // FreqL[ae] 0.018912, // FreqL[af] 0.006083, // FreqL[b0] 0.003302, // FreqL[b1] 0.010215, // FreqL[b2] 0.008791, // FreqL[b3] 0.024236, // FreqL[b4] 0.014107, // FreqL[b5] 0.014108, // FreqL[b6] 0.010303, // FreqL[b7] 0.009728, // FreqL[b8] 0.007877, // FreqL[b9] 0.009719, // FreqL[ba] 0.007952, // FreqL[bb] 0.021028, // FreqL[bc] 0.005764, // FreqL[bd] 0.009341, // FreqL[be] 0.006591, // FreqL[bf] 0.012517, // FreqL[c0] 0.005921, // FreqL[c1] 0.008982, // FreqL[c2] 0.008771, // FreqL[c3] 0.012802, // FreqL[c4] 0.005926, // FreqL[c5] 0.008342, // FreqL[c6] 0.003086, // FreqL[c7] 0.006843, // FreqL[c8] 0.007576, // FreqL[c9] 0.004734, // FreqL[ca] 0.016404, // FreqL[cb] 0.008803, // FreqL[cc] 0.008071, // FreqL[cd] 0.005349, // FreqL[ce] 0.008566, // FreqL[cf] 0.010840, // FreqL[d0] 0.015401, // FreqL[d1] 0.031904, // FreqL[d2] 0.008670, // FreqL[d3] 0.011479, // FreqL[d4] 0.010936, // FreqL[d5] 0.007617, // FreqL[d6] 0.008995, // FreqL[d7] 0.008114, // FreqL[d8] 0.008658, // FreqL[d9] 0.005934, // FreqL[da] 0.010452, // FreqL[db] 0.009142, // FreqL[dc] 0.004519, // FreqL[dd] 0.008339, // FreqL[de] 0.007476, // FreqL[df] 0.007027, // FreqL[e0] 0.006025, // FreqL[e1] 0.021804, // FreqL[e2] 0.024248, // FreqL[e3] 0.015895, // FreqL[e4] 0.003768, // FreqL[e5] 0.010171, // FreqL[e6] 0.010007, // FreqL[e7] 0.010178, // FreqL[e8] 0.008316, // FreqL[e9] 0.006832, // FreqL[ea] 0.006364, // FreqL[eb] 0.009141, // FreqL[ec] 0.009148, // FreqL[ed] 0.012081, // FreqL[ee] 0.011914, // FreqL[ef] 0.004464, // FreqL[f0] 0.014257, // FreqL[f1] 0.006907, // FreqL[f2] 0.011292, // FreqL[f3] 0.018622, // FreqL[f4] 0.008149, // FreqL[f5] 0.004636, // FreqL[f6] 0.006612, // FreqL[f7] 0.013478, // FreqL[f8] 0.012614, // FreqL[f9] 0.005186, // FreqL[fa] 0.048285, // FreqL[fb] 0.006816, // FreqL[fc] 0.006743, // FreqL[fd] 0.008671 // FreqL[fe] ); mSecoundByteStdDev: 0.006630; // Trail Byte StdDev mSecoundByteMean: 0.010638; // Trail Byte Mean mSecoundByteWeight: 0.284401 // Trial Byte Weight ); doublecmd-0.8.2/components/chsdet/src/stat/GB2312Statistics.inc0000664000175000017500000001207212014201074023245 0ustar alexxalexxconst GB2312Stat: rEUCStatistics = ( mFirstByteFreq: ( 0.011628, // FreqH[a1] 0.000000, // FreqH[a2] 0.000000, // FreqH[a3] 0.000000, // FreqH[a4] 0.000000, // FreqH[a5] 0.000000, // FreqH[a6] 0.000000, // FreqH[a7] 0.000000, // FreqH[a8] 0.000000, // FreqH[a9] 0.000000, // FreqH[aa] 0.000000, // FreqH[ab] 0.000000, // FreqH[ac] 0.000000, // FreqH[ad] 0.000000, // FreqH[ae] 0.000000, // FreqH[af] 0.011628, // FreqH[b0] 0.012403, // FreqH[b1] 0.009302, // FreqH[b2] 0.003876, // FreqH[b3] 0.017829, // FreqH[b4] 0.037209, // FreqH[b5] 0.008527, // FreqH[b6] 0.010078, // FreqH[b7] 0.019380, // FreqH[b8] 0.054264, // FreqH[b9] 0.010078, // FreqH[ba] 0.041085, // FreqH[bb] 0.020930, // FreqH[bc] 0.018605, // FreqH[bd] 0.010078, // FreqH[be] 0.013178, // FreqH[bf] 0.016279, // FreqH[c0] 0.006202, // FreqH[c1] 0.009302, // FreqH[c2] 0.017054, // FreqH[c3] 0.011628, // FreqH[c4] 0.008527, // FreqH[c5] 0.004651, // FreqH[c6] 0.006202, // FreqH[c7] 0.017829, // FreqH[c8] 0.024806, // FreqH[c9] 0.020155, // FreqH[ca] 0.013953, // FreqH[cb] 0.032558, // FreqH[cc] 0.035659, // FreqH[cd] 0.068217, // FreqH[ce] 0.010853, // FreqH[cf] 0.036434, // FreqH[d0] 0.117054, // FreqH[d1] 0.027907, // FreqH[d2] 0.100775, // FreqH[d3] 0.010078, // FreqH[d4] 0.017829, // FreqH[d5] 0.062016, // FreqH[d6] 0.012403, // FreqH[d7] 0.000000, // FreqH[d8] 0.000000, // FreqH[d9] 0.000000, // FreqH[da] 0.000000, // FreqH[db] 0.000000, // FreqH[dc] 0.000000, // FreqH[dd] 0.000000, // FreqH[de] 0.000000, // FreqH[df] 0.000000, // FreqH[e0] 0.000000, // FreqH[e1] 0.000000, // FreqH[e2] 0.000000, // FreqH[e3] 0.000000, // FreqH[e4] 0.000000, // FreqH[e5] 0.000000, // FreqH[e6] 0.000000, // FreqH[e7] 0.000000, // FreqH[e8] 0.000000, // FreqH[e9] 0.001550, // FreqH[ea] 0.000000, // FreqH[eb] 0.000000, // FreqH[ec] 0.000000, // FreqH[ed] 0.000000, // FreqH[ee] 0.000000, // FreqH[ef] 0.000000, // FreqH[f0] 0.000000, // FreqH[f1] 0.000000, // FreqH[f2] 0.000000, // FreqH[f3] 0.000000, // FreqH[f4] 0.000000, // FreqH[f5] 0.000000, // FreqH[f6] 0.000000, // FreqH[f7] 0.000000, // FreqH[f8] 0.000000, // FreqH[f9] 0.000000, // FreqH[fa] 0.000000, // FreqH[fb] 0.000000, // FreqH[fc] 0.000000, // FreqH[fd] 0.000000 // FreqH[fe] ); mFirstByteStdDev: 0.020081; // Lead Byte StdDev mFirstByteMean: 0.010638; // Lead Byte Mean mFirstByteWeight: 0.586533; // Lead Byte Weight mSecoundByteFreq: ( 0.006202, // FreqL[a1] 0.031008, // FreqL[a2] 0.005426, // FreqL[a3] 0.003101, // FreqL[a4] 0.001550, // FreqL[a5] 0.003101, // FreqL[a6] 0.082171, // FreqL[a7] 0.014729, // FreqL[a8] 0.006977, // FreqL[a9] 0.001550, // FreqL[aa] 0.013953, // FreqL[ab] 0.000000, // FreqL[ac] 0.013953, // FreqL[ad] 0.010078, // FreqL[ae] 0.008527, // FreqL[af] 0.006977, // FreqL[b0] 0.004651, // FreqL[b1] 0.003101, // FreqL[b2] 0.003101, // FreqL[b3] 0.003101, // FreqL[b4] 0.008527, // FreqL[b5] 0.003101, // FreqL[b6] 0.005426, // FreqL[b7] 0.005426, // FreqL[b8] 0.005426, // FreqL[b9] 0.003101, // FreqL[ba] 0.001550, // FreqL[bb] 0.006202, // FreqL[bc] 0.014729, // FreqL[bd] 0.010853, // FreqL[be] 0.000000, // FreqL[bf] 0.011628, // FreqL[c0] 0.000000, // FreqL[c1] 0.031783, // FreqL[c2] 0.013953, // FreqL[c3] 0.030233, // FreqL[c4] 0.039535, // FreqL[c5] 0.008527, // FreqL[c6] 0.015504, // FreqL[c7] 0.000000, // FreqL[c8] 0.003101, // FreqL[c9] 0.008527, // FreqL[ca] 0.016279, // FreqL[cb] 0.005426, // FreqL[cc] 0.001550, // FreqL[cd] 0.013953, // FreqL[ce] 0.013953, // FreqL[cf] 0.044961, // FreqL[d0] 0.003101, // FreqL[d1] 0.004651, // FreqL[d2] 0.006977, // FreqL[d3] 0.001550, // FreqL[d4] 0.005426, // FreqL[d5] 0.012403, // FreqL[d6] 0.001550, // FreqL[d7] 0.015504, // FreqL[d8] 0.000000, // FreqL[d9] 0.006202, // FreqL[da] 0.001550, // FreqL[db] 0.000000, // FreqL[dc] 0.007752, // FreqL[dd] 0.006977, // FreqL[de] 0.001550, // FreqL[df] 0.009302, // FreqL[e0] 0.011628, // FreqL[e1] 0.004651, // FreqL[e2] 0.010853, // FreqL[e3] 0.012403, // FreqL[e4] 0.017829, // FreqL[e5] 0.005426, // FreqL[e6] 0.024806, // FreqL[e7] 0.000000, // FreqL[e8] 0.006202, // FreqL[e9] 0.000000, // FreqL[ea] 0.082171, // FreqL[eb] 0.015504, // FreqL[ec] 0.004651, // FreqL[ed] 0.000000, // FreqL[ee] 0.006977, // FreqL[ef] 0.004651, // FreqL[f0] 0.000000, // FreqL[f1] 0.008527, // FreqL[f2] 0.012403, // FreqL[f3] 0.004651, // FreqL[f4] 0.003876, // FreqL[f5] 0.003101, // FreqL[f6] 0.022481, // FreqL[f7] 0.024031, // FreqL[f8] 0.001550, // FreqL[f9] 0.047287, // FreqL[fa] 0.009302, // FreqL[fb] 0.001550, // FreqL[fc] 0.005426, // FreqL[fd] 0.017054 // FreqL[fe] ); mSecoundByteStdDev: 0.014156; // Trail Byte StdDev mSecoundByteMean: 0.010638; // Trail Byte Mean mSecoundByteWeight: 0.413467 // Trial Byte Weight ); doublecmd-0.8.2/components/chsdet/src/stat/EUCJPStatistics.inc0000664000175000017500000001207112014201074023312 0ustar alexxalexxconst EUCJPStat: rEUCStatistics = ( mFirstByteFreq: ( 0.364808, // FreqH[a1] 0.000000, // FreqH[a2] 0.000000, // FreqH[a3] 0.145325, // FreqH[a4] 0.304891, // FreqH[a5] 0.000000, // FreqH[a6] 0.000000, // FreqH[a7] 0.000000, // FreqH[a8] 0.000000, // FreqH[a9] 0.000000, // FreqH[aa] 0.000000, // FreqH[ab] 0.000000, // FreqH[ac] 0.000000, // FreqH[ad] 0.000000, // FreqH[ae] 0.000000, // FreqH[af] 0.001835, // FreqH[b0] 0.010771, // FreqH[b1] 0.006462, // FreqH[b2] 0.001157, // FreqH[b3] 0.002114, // FreqH[b4] 0.003231, // FreqH[b5] 0.001356, // FreqH[b6] 0.007420, // FreqH[b7] 0.004189, // FreqH[b8] 0.003231, // FreqH[b9] 0.003032, // FreqH[ba] 0.033190, // FreqH[bb] 0.006303, // FreqH[bc] 0.006064, // FreqH[bd] 0.009973, // FreqH[be] 0.002354, // FreqH[bf] 0.003670, // FreqH[c0] 0.009135, // FreqH[c1] 0.001675, // FreqH[c2] 0.002792, // FreqH[c3] 0.002194, // FreqH[c4] 0.014720, // FreqH[c5] 0.011928, // FreqH[c6] 0.000878, // FreqH[c7] 0.013124, // FreqH[c8] 0.001077, // FreqH[c9] 0.009295, // FreqH[ca] 0.003471, // FreqH[cb] 0.002872, // FreqH[cc] 0.002433, // FreqH[cd] 0.000957, // FreqH[ce] 0.001636, // FreqH[cf] 0.000000, // FreqH[d0] 0.000000, // FreqH[d1] 0.000000, // FreqH[d2] 0.000000, // FreqH[d3] 0.000000, // FreqH[d4] 0.000000, // FreqH[d5] 0.000000, // FreqH[d6] 0.000000, // FreqH[d7] 0.000000, // FreqH[d8] 0.000000, // FreqH[d9] 0.000000, // FreqH[da] 0.000000, // FreqH[db] 0.000000, // FreqH[dc] 0.000000, // FreqH[dd] 0.000080, // FreqH[de] 0.000279, // FreqH[df] 0.000000, // FreqH[e0] 0.000000, // FreqH[e1] 0.000000, // FreqH[e2] 0.000000, // FreqH[e3] 0.000000, // FreqH[e4] 0.000000, // FreqH[e5] 0.000000, // FreqH[e6] 0.000000, // FreqH[e7] 0.000000, // FreqH[e8] 0.000000, // FreqH[e9] 0.000000, // FreqH[ea] 0.000000, // FreqH[eb] 0.000000, // FreqH[ec] 0.000000, // FreqH[ed] 0.000000, // FreqH[ee] 0.000000, // FreqH[ef] 0.000000, // FreqH[f0] 0.000000, // FreqH[f1] 0.000000, // FreqH[f2] 0.000000, // FreqH[f3] 0.000000, // FreqH[f4] 0.000000, // FreqH[f5] 0.000000, // FreqH[f6] 0.000000, // FreqH[f7] 0.000000, // FreqH[f8] 0.000000, // FreqH[f9] 0.000000, // FreqH[fa] 0.000000, // FreqH[fb] 0.000000, // FreqH[fc] 0.000080, // FreqH[fd] 0.000000 // FreqH[fe] ); mFirstByteStdDev: 0.050407; // Lead Byte StdDev mFirstByteMean: 0.010638; // Lead Byte Mean mFirstByteWeight: 0.640871; // Lead Byte Weight mSecoundByteFreq: ( 0.002473, // FreqL[a1] 0.039134, // FreqL[a2] 0.152745, // FreqL[a3] 0.009694, // FreqL[a4] 0.000359, // FreqL[a5] 0.022180, // FreqL[a6] 0.000758, // FreqL[a7] 0.004308, // FreqL[a8] 0.000160, // FreqL[a9] 0.002513, // FreqL[aa] 0.003072, // FreqL[ab] 0.001316, // FreqL[ac] 0.003830, // FreqL[ad] 0.001037, // FreqL[ae] 0.003590, // FreqL[af] 0.000957, // FreqL[b0] 0.000160, // FreqL[b1] 0.000239, // FreqL[b2] 0.006462, // FreqL[b3] 0.001596, // FreqL[b4] 0.031554, // FreqL[b5] 0.001316, // FreqL[b6] 0.002194, // FreqL[b7] 0.016555, // FreqL[b8] 0.003271, // FreqL[b9] 0.000678, // FreqL[ba] 0.000598, // FreqL[bb] 0.206438, // FreqL[bc] 0.000718, // FreqL[bd] 0.001077, // FreqL[be] 0.003710, // FreqL[bf] 0.001356, // FreqL[c0] 0.001356, // FreqL[c1] 0.000439, // FreqL[c2] 0.004388, // FreqL[c3] 0.005704, // FreqL[c4] 0.000878, // FreqL[c5] 0.010172, // FreqL[c6] 0.007061, // FreqL[c7] 0.014680, // FreqL[c8] 0.000638, // FreqL[c9] 0.025730, // FreqL[ca] 0.002792, // FreqL[cb] 0.000718, // FreqL[cc] 0.001795, // FreqL[cd] 0.091551, // FreqL[ce] 0.000758, // FreqL[cf] 0.003909, // FreqL[d0] 0.000558, // FreqL[d1] 0.031195, // FreqL[d2] 0.007061, // FreqL[d3] 0.001316, // FreqL[d4] 0.022579, // FreqL[d5] 0.006981, // FreqL[d6] 0.007260, // FreqL[d7] 0.001117, // FreqL[d8] 0.000239, // FreqL[d9] 0.012127, // FreqL[da] 0.000878, // FreqL[db] 0.003790, // FreqL[dc] 0.001077, // FreqL[dd] 0.000758, // FreqL[de] 0.002114, // FreqL[df] 0.002234, // FreqL[e0] 0.000678, // FreqL[e1] 0.002992, // FreqL[e2] 0.003311, // FreqL[e3] 0.023416, // FreqL[e4] 0.001237, // FreqL[e5] 0.002753, // FreqL[e6] 0.005146, // FreqL[e7] 0.002194, // FreqL[e8] 0.007021, // FreqL[e9] 0.008497, // FreqL[ea] 0.013763, // FreqL[eb] 0.011768, // FreqL[ec] 0.006303, // FreqL[ed] 0.001915, // FreqL[ee] 0.000638, // FreqL[ef] 0.008776, // FreqL[f0] 0.000918, // FreqL[f1] 0.003431, // FreqL[f2] 0.057603, // FreqL[f3] 0.000439, // FreqL[f4] 0.000439, // FreqL[f5] 0.000758, // FreqL[f6] 0.002872, // FreqL[f7] 0.001675, // FreqL[f8] 0.011050, // FreqL[f9] 0.000000, // FreqL[fa] 0.000279, // FreqL[fb] 0.012127, // FreqL[fc] 0.000718, // FreqL[fd] 0.007380 // FreqL[fe] ); mSecoundByteStdDev: 0.028247; // Trail Byte StdDev mSecoundByteMean: 0.010638; // Trail Byte Mean mSecoundByteWeight: 0.359129 // Trial Byte Weight ); doublecmd-0.8.2/components/chsdet/src/chsdet.lpi0000664000175000017500000001224311670731366020727 0ustar alexxalexx doublecmd-0.8.2/components/chsdet/src/chsdet.dpr0000664000175000017500000000303312014201074020702 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: chsdet.dpr,v 1.3 2007/05/26 13:07:21 ya_nick Exp $ library chsdet; uses chsdIntf in 'chsdIntf.pas'; exports csd_Reset, csd_HandleData, csd_Done, csd_DataEnd, csd_GetDetectedCharset, csd_GetKnownCharsets, csd_GetAbout; {$R *.res} begin end. doublecmd-0.8.2/components/chsdet/src/chsdet.lpr0000664000175000017500000000341312014201074020714 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: chsdet.lpr,v 1.1 2009/03/20 17:40:22 ya_nick Exp $ library chsdet; uses chsdIntf in 'chsdIntf.pas', LangBulgarianModel in 'sbseq/LangBulgarianModel.pas', LangCyrillicModel in 'sbseq/LangCyrillicModel.pas', LangGreekModel in 'sbseq/LangGreekModel.pas', LangHebrewModel in 'sbseq/LangHebrewModel.pas' ; exports csd_Reset, csd_HandleData, csd_Done, csd_DataEnd, csd_GetDetectedCharset, csd_GetKnownCharsets, csd_GetAbout; {.chsdet$R *.res} {.chsdet$R chsdet.res} begin end. doublecmd-0.8.2/components/chsdet/src/nsSBCSGroupProber.pas0000664000175000017500000001230212014201074022707 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsSBCSGroupProber.pas,v 1.3 2007/05/26 13:09:38 ya_nick Exp $ unit nsSBCSGroupProber; interface uses nsCore, nsGroupProber; type TnsSBCSGroupProber = class(TnsGroupProber) public constructor Create; reintroduce; function HandleData(aBuf: PChar; aLen: integer): eProbingState; override; // {$ifdef DEBUG_chardet} // procedure DumpStatus; override; // {$endif} end; implementation uses SysUtils, nsHebrewProber, nsSBCharSetProber, LangCyrillicModel, LangGreekModel, LangBulgarianModel, LangHebrewModel; { TnsSBCSGroupProber } const NUM_OF_PROBERS = 13; constructor TnsSBCSGroupProber.Create; var hebprober: TnsHebrewProber; i: integer; begin mNumOfProbers := NUM_OF_PROBERS; SetLength(mProbers, NUM_OF_PROBERS); SetLength(mIsActive, NUM_OF_PROBERS); SetLength(mProberStates, NUM_OF_PROBERS); mProbers[0] := TnsSingleByteCharSetProber.Create(Win1251Model); mProbers[1] := TnsSingleByteCharSetProber.Create(Koi8rModel); mProbers[2] := TnsSingleByteCharSetProber.Create(Latin5Model); mProbers[3] := TnsSingleByteCharSetProber.Create(MacCyrillicModel); mProbers[4] := TnsSingleByteCharSetProber.Create(Ibm866Model); mProbers[5] := TnsSingleByteCharSetProber.Create(Ibm855Model); mProbers[6] := TnsSingleByteCharSetProber.Create(Latin7Model); mProbers[7] := TnsSingleByteCharSetProber.Create(Win1253Model); mProbers[8] := TnsSingleByteCharSetProber.Create(Latin5BulgarianModel); mProbers[9] := TnsSingleByteCharSetProber.Create(Win1251BulgarianModel); hebprober := TnsHebrewProber.Create; // Notice: Any change in these indexes - 10,11,12 must be reflected // in the code below as well. mProbers[10]:= hebprober; mProbers[11]:= TnsSingleByteCharSetProber.Create(Win1255Model,FALSE,hebprober);(* Logical Hebrew*) mProbers[12]:= TnsSingleByteCharSetProber.Create(Win1255Model,TRUE,hebprober); (* Visual Hebrew*) (* Tell the Hebrew prober about the logical and visual probers*) if (mProbers[10]<>nil)and(mProbers[11]<>nil)and(mProbers[12]<>nil) then (* all are not null*) hebprober.SetModelProbers(mProbers[11],mProbers[12]) else (* One or more is null. avoid any Hebrew probing, null them all*) for i := 10 to 12 do begin mProbers[i].Free; mProbers[i] := nil; end; inherited Create; (* disable latin2 before latin1 is available, otherwise all latin1 *) (* will be detected as latin2 because of their similarity.*) // mProbers[10] = new nsSingleByteCharSetProber(&Latin2HungarianModel); // mProbers[11] = new nsSingleByteCharSetProber(&Win1250HungarianModel); end; function TnsSBCSGroupProber.HandleData(aBuf: PChar; aLen: integer): eProbingState; var newBuf1: PChar; newLen1: integer; begin newBuf1 := AllocMem(aLen); newLen1 := 0; (*apply filter to original buffer, and we got new buffer back*) (*depend on what script it is, we will feed them the new buffer *) (*we got after applying proper filter*) (*this is done without any consideration to KeepEnglishLetters*) (*of each prober since as of now, there are no probers here which*) (*recognize languages with English characters.*) Result := mState; try if (not FilterWithoutEnglishLetters(aBuf,aLen,newBuf1,newLen1)) or (newLen1 = 0) then exit; (* Nothing to see here, move on.*) inherited HandleData(newBuf1, newLen1); finally FreeMem(newBuf1, aLen); end; Result:= mState; end; {$ifdef DEBUG_chardet} procedure TnsSBCSGroupProber.DumpStatus; var i: integer; cf: float; i: integer; begin cf := GetConfidence; printf(' SBCS Group Prober --------begin status r'#13#10''); for i := 0 to Pred(NUM_OF_SBCS_PROBERS) do begin if 0 = mIsActive[i] then printf(' inactive: [%s] (i.e. confidence is too low).r'#13#10'',mProbers[i].GetCharSetName) else mProbers[i].DumpStatus; end; printf(' SBCS Group found best match [%s] confidence %f.r'#13#10'',mProbers[mBestGuess].GetCharSetName,cf); end; {$endif} end. doublecmd-0.8.2/components/chsdet/src/nsCore.pas0000664000175000017500000002714112014201074020665 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: nsCore.pas,v 1.4 2008/06/22 09:04:20 ya_nick Exp $ unit nsCore; interface type PRInt16 = smallint; PRUint16 = word; PRInt32 = integer; PRUint32 = cardinal; pByteArray = array of Byte; pPRUint32 = ^PRUint32; aPRUint32 = array of PRUint32; pPRint16 = ^PRint16; aPRint16 = array of PRint16; const SURE_YES: double = 0.99; SURE_NO: double = 0.01; const ENOUGH_DATA_THRESHOLD: cardinal = 1024; SHORTCUT_THRESHOLD = 0.95; type eProbingState = ( psDetecting = 0, //We are still detecting, no sure answer yet, but caller can ask for confidence. psFoundIt = 1, //That's a positive answer psNotMe = 2 //Negative answer ); type nsResult = PRUint32; const NS_OK = 0; NS_ERROR_OUT_OF_MEMORY = $8007000e; type float = double; rAboutHolder = record MajorVersionNr: Cardinal; MinorVersionNr: Cardinal; BuildVersionNr: Cardinal; About: pChar; end; eBOMKind = ( BOM_Not_Found, BOM_UCS4_BE, // 00 00 FE FF UCS-4, big-endian machine (1234 order) BOM_UCS4_LE, // FF FE 00 00 UCS-4, little-endian machine (4321 order) BOM_UCS4_2143, // 00 00 FF FE UCS-4, unusual octet order (2143) BOM_UCS4_3412, // FE FF 00 00 UCS-4, unusual octet order (3412) BOM_UTF16_BE, // FE FF ## ## UTF-16, big-endian BOM_UTF16_LE, // FF FE ## ## UTF-16, little-endian BOM_UTF8 // EF BB BF UTF-8 ); const KnownBOM: array [eBOMKind] of array [0..4] of Char = ( // first element = byte count (#$00, #$00, #$00, #$00, #$00), (#$04, #$00, #$00, #$FE, #$FF), (#$04, #$FF, #$FE, #$00, #$00), (#$04, #$00, #$00, #$FF, #$FE), (#$04, #$FE, #$FF, #$00, #$00), (#$02, #$FE, #$FF, #$00, #$00), (#$02, #$FF, #$FE, #$00, #$00), (#$03, #$EF, #$BB, #$BF, #$00) ); // "extended" charset info type rCharsetInfo = record Name: pChar; CodePage: integer; Language: pChar; end; eInternalCharsetID = ( UNKNOWN_CHARSET = 000, PURE_ASCII_CHARSET = 001, UTF8_CHARSET = 002, UCS4_BE_CHARSET = 003, UTF16_BE_CHARSET = 004, UTF32_BE_CHARSET = 005, UCS4_LE_CHARSET = 006, UTF32_LE_CHARSET = 007, UTF16_LE_CHARSET = 008, LATIN5_BULGARIAN_CHARSET = 009, WINDOWS_BULGARIAN_CHARSET = 010, KOI8_R_CHARSET = 011, WINDOWS_1251_CHARSET = 012, ISO_8859_5_CHARSET = 013, X_MAC_CYRILLIC_CHARSET = 014, IBM866_CHARSET = 015, IBM855_CHARSET = 016, ISO_8859_7_CHARSET = 017, WINDOWS_1253_CHARSET = 018, ISO_8859_8_CHARSET = 019, WINDOWS_1255_CHARSET = 020, BIG5_CHARSET = 021, ISO_2022_CN_CHARSET = 022, ISO_2022_JP_CHARSET = 023, ISO_2022_KR_CHARSET = 024, EUC_JP_CHARSET = 025, EUC_KR_CHARSET = 026, X_EUC_TW_CHARSET = 027, SHIFT_JIS_CHARSET = 028, GB18030_CHARSET = 029, HZ_GB_2312_CHARSET = 030, WINDOWS_1252_CHARSET = 031 ); const KNOWN_CHARSETS: array [eInternalCharsetID] of rCharsetInfo = ( // UNKNOWN_CHARSET ( Name: 'Unknown'; CodePage: -1; Language: 'Unknown' ), // PURE_ASCII_CHARSET ( Name: 'ASCII'; CodePage: 0; Language: 'ASCII' ), // UTF8_CHARSET ( Name: 'UTF-8'; CodePage: 65001; Language: 'Unicode' ), // UCS4_BE_CHARSET ( Name: 'X-ISO-10646-UCS-4-3412'; CodePage: 12001; Language: 'Unicode' ), // UTF16_BE_CHARSET ( Name: 'UTF-16BE'; CodePage: 1201; Language: 'Unicode' ), // UTF32_BE_CHARSET ( Name: 'UTF-32BE'; CodePage: 12001; Language: 'Unicode' ), // UCS4_LE_CHARSET ( Name: 'X-ISO-10646-UCS-4-2143'; CodePage: 12000; Language: 'Unicode' ), // UTF32_LE_CHARSET ( Name: 'UTF-32LE'; CodePage: 12000; Language: 'Unicode' ), // UTF16_LE_CHARSET ( Name: 'UTF-16LE'; CodePage: 1200; Language: 'Unicode' ), // LATIN5_BULGARIAN_CHARSET ( Name: 'ISO-8859-5'; CodePage: 28595; Language: 'Bulgarian' ), // WINDOWS_BULGARIAN_CHARSET ( Name: 'windows-1251'; CodePage: 1251; Language: 'Bulgarian' ), // KOI8_R_CHARSET ( Name: 'KOI8-R'; CodePage: 20866; Language: 'russian' ), // WINDOWS_1251_CHARSET ( Name: 'windows-1251'; CodePage: 1251; Language: 'russian' ), // ISO_8859_5_CHARSET ( Name: 'ISO-8859-5'; CodePage: 28595; Language: 'russian' ), // X_MAC_CYRILLIC_CHARSET ( Name: 'x-mac-cyrillic'; CodePage: 10007; Language: 'russian' ), // IBM866_CHARSET ( Name: 'IBM866'; CodePage: 866; Language: 'russian' ), // IBM855_CHARSET ( Name: 'IBM855'; CodePage: 855; Language: 'russian' ), // ISO_8859_7_CHARSET ( Name: 'ISO-8859-7'; CodePage: 28597; Language: 'greek' ), // WINDOWS_1253_CHARSET ( Name: 'windows-1253'; CodePage: 1253; Language: 'greek' ), // ISO_8859_8_CHARSET ( Name: 'ISO-8859-8'; CodePage: 28598; Language: 'hebrew' ), // WINDOWS_1255_CHARSET ( Name: 'windows-1255'; CodePage: 1255; Language: 'hebrew' ), // BIG5_CHARSET ( Name: 'Big5'; CodePage: 950; Language: 'ch' ), // ISO_2022_CN_CHARSET ( Name: 'ISO-2022-CN'; CodePage: 50227; Language: 'ch'; ), // ISO_2022_JP_CHARSET ( Name: 'ISO-2022-JP'; CodePage: 50222; Language: 'japanese'; ), // ISO_2022_KR_CHARSET ( Name: 'ISO-2022-KR'; CodePage: 50225; Language: 'kr'; ), // EUC_JP_CHARSET ( Name: 'EUC-JP'; CodePage: 51932; Language: 'japanese'; ), // EUC_KR_CHARSET ( Name: 'EUC-KR'; CodePage: 51949; Language: 'kr'; ), // X_EUC_TW_CHARSET ( Name: 'x-euc-tw'; CodePage: 51936; Language: 'ch'; ), // SHIFT_JIS_CHARSET ( Name: 'Shift_JIS'; CodePage: 932; Language: 'japanese'; ), // GB18030_CHARSET ( Name: 'GB18030'; CodePage: 54936; Language: 'ch'; ), // HZ_GB_2312_CHARSET ( Name: 'HZ-GB-2312'; CodePage: 52936; Language: 'ch'; ), // WINDOWS_1252_CHARSET ( Name: 'windows-1252'; CodePage: 1252; Language: 'eu'; ) ); (* Helper functions used in the Latin1 and Group probers.*) (* both functions Allocate a new buffer for newBuf. This buffer should be *) (* freed by the caller using PR_FREEIF.*) (* Both functions return PR_FALSE in case of memory allocation failure.*) function FilterWithoutEnglishLetters(aBuf: PChar; aLen: integer; var newBuf: PChar; var newLen: integer): Boolean; function FilterWithEnglishLetters(aBuf: PChar; aLen: integer; var newBuf: PChar; var newLen: integer): Boolean; implementation function FilterWithEnglishLetters(aBuf: PChar; aLen: integer; var newBuf: PChar; var newLen: integer): Boolean; var newptr: pChar; prevPtr: pChar; curPtr: pChar; isInTag: Boolean; begin //do filtering to reduce load to probers isInTag := FALSE; newLen := 0; newptr := newBuf; if (newptr = nil) then begin Result := FALSE; exit; end; prevPtr := aBuf; curPtr := prevPtr; while (curPtr < aBuf+aLen) do begin if (curPtr^ = '>') then isInTag := FALSE else if (curPtr^ = '<') then isInTag := TRUE; if ((curPtr^ < #$80) and ((curPtr^ < 'A') or ((curPtr^ > 'Z') and (curPtr^ < 'a')) or (curPtr^ > 'z')) ) then begin if ((curPtr > prevPtr) and (not isInTag)) then // Current segment contains more than just a symbol // and it is not inside a tag, keep it. begin while (prevPtr < curPtr) do begin newptr^ := prevPtr^; inc(newptr); inc(prevPtr); end; inc(prevPtr); newptr^ := ' '; inc(newptr); end else prevPtr := curPtr+1; end; inc(curPtr); end; // If the current segment contains more than just a symbol // and it is not inside a tag then keep it. if ( not isInTag) then while (prevPtr < curPtr) do begin newptr^ := prevPtr^; inc(newptr); inc(prevPtr); end; newLen := newptr - newBuf; Result := TRUE; end; function FilterWithoutEnglishLetters(aBuf: PChar; aLen: integer; var newBuf: PChar; var newLen: integer): Boolean; var newPtr: pChar; prevPtr: pChar; curPtr: pChar; meetMSB: Boolean; begin (*This filter applies to all scripts which do not use English characters*) Result := FALSE; newLen := 0; meetMSB:= FALSE; if newBuf = nil then exit; newPtr := newBuf; curPtr := aBuf; prevPtr := curPtr; while curPtr < aBuf+aLen do begin if curPtr^ > #$80 then meetMSB := TRUE else if ((curPtr^ < 'A') or ((curPtr^ > 'Z') and (curPtr^ < 'a')) or (curPtr^ > 'z')) then begin //current char is a symbol, most likely a punctuation. we treat it as segment delimiter if (meetMSB and (curPtr > prevPtr)) then //this segment contains more than single symbol, and it has upper ASCII, we need to keep it begin while (prevPtr < curPtr) do begin newptr^ := prevPtr^; inc(newptr); inc(prevPtr); end; inc(prevPtr); newptr^ := ' '; inc(newptr); meetMSB := FALSE; end else //ignore current segment. (either because it is just a symbol or just an English word) prevPtr := curPtr+1; end; inc(curPtr); end; if (meetMSB and (curPtr > prevPtr)) then while (prevPtr < curPtr) do begin newptr^ := prevPtr^; inc(newptr); inc(prevPtr); end; newLen := newptr - newBuf; Result := TRUE; end; end. doublecmd-0.8.2/components/chsdet/src/JISFreq.pas0000664000175000017500000013667012014201074020707 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: JISFreq.pas,v 1.2 2007/05/20 15:46:04 ya_nick Exp $ unit JISFreq; //Sampling from about 20M text materials include literature and computer technology // Japanese frequency table, applied to both S-JIS and EUC-JP //They are sorted in order. (****************************************************************************** * 128 --> 0.77094 * 256 --> 0.85710 * 512 --> 0.92635 * 1024 --> 0.97130 * 2048 --> 0.99431 * * Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 * Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 * * Typical Distribution Ratio, 25% of IDR *****************************************************************************) interface uses nsCore; const JIS_TYPICAL_DISTRIBUTION_RATIO: double = 3.0; //Char to FreqOrder table , JIS_TABLE_SIZE = 4368; JISCharToFreqOrder: array [0..JIS_TABLE_SIZE-1] of PRInt16 = ( 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, // 16 3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, // 32 1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, // 48 2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, // 64 2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, // 80 5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, // 96 1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, // 112 5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, // 128 5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, // 144 5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, // 160 5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, // 176 5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, // 192 5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, // 208 1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, // 224 1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, // 240 1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, // 256 2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, // 272 3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, // 288 3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, // 304 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, // 320 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, // 336 1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, // 352 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, // 368 5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, // 384 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, // 400 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, // 416 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, // 432 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, // 448 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, // 464 5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, // 480 5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, // 496 5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, // 512 4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, // 528 5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, // 544 5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, // 560 5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, // 576 5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, // 592 5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, // 608 5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, // 624 5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, // 640 5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, // 656 5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, // 672 3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, // 688 5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, // 704 5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, // 720 5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, // 736 5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, // 752 5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, // 768 5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, // 784 5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, // 800 5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, // 816 5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, // 832 5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, // 848 5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, // 864 5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, // 880 5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, // 896 5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, // 912 5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, // 928 5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, // 944 5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, // 960 5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, // 976 5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, // 992 5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, // 1008 5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, // 1024 5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, // 1040 5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, // 1056 5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, // 1072 5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, // 1088 5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, // 1104 5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, // 1120 5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, // 1136 5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, // 1152 5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, // 1168 5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, // 1184 5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, // 1200 5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, // 1216 5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, // 1232 5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, // 1248 5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, // 1264 5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, // 1280 5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, // 1296 6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, // 1312 6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, // 1328 6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, // 1344 6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, // 1360 6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, // 1376 6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, // 1392 6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, // 1408 6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, // 1424 4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, // 1440 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, // 1456 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, // 1472 1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, // 1488 1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, // 1504 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, // 1520 3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, // 1536 3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, // 1552 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, // 1568 3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, // 1584 3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, // 1600 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, // 1616 2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, // 1632 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, // 1648 3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, // 1664 1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, // 1680 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, // 1696 1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, // 1712 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, // 1728 2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, // 1744 2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, // 1760 2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, // 1776 2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, // 1792 1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, // 1808 1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, // 1824 1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, // 1840 1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, // 1856 2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, // 1872 1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, // 1888 2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, // 1904 1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, // 1920 1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, // 1936 1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, // 1952 1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, // 1968 1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, // 1984 1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, // 2000 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, // 2016 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, // 2032 1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, // 2048 2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, // 2064 2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, // 2080 2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, // 2096 3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, // 2112 3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, // 2128 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, // 2144 3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, // 2160 1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, // 2176 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, // 2192 2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, // 2208 1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, // 2224 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, // 2240 3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, // 2256 4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, // 2272 2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, // 2288 1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, // 2304 2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, // 2320 1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, // 2336 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, // 2352 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, // 2368 1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, // 2384 2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, // 2400 2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, // 2416 2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, // 2432 3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, // 2448 1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, // 2464 2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, // 2480 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, // 2496 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, // 2512 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, // 2528 1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, // 2544 2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, // 2560 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, // 2576 1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, // 2592 1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, // 2608 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, // 2624 1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, // 2640 1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, // 2656 1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, // 2672 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, // 2688 2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, // 2704 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, // 2720 2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, // 2736 3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, // 2752 2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, // 2768 1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, // 2784 6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, // 2800 1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, // 2816 2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, // 2832 1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, // 2848 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, // 2864 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, // 2880 3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, // 2896 3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, // 2912 1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, // 2928 1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, // 2944 1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, // 2960 1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, // 2976 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, // 2992 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, // 3008 2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, // 3024 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, // 3040 3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, // 3056 2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, // 3072 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, // 3088 1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, // 3104 2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, // 3120 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, // 3136 1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, // 3152 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, // 3168 4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, // 3184 2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, // 3200 1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, // 3216 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, // 3232 1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, // 3248 2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, // 3264 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, // 3280 6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, // 3296 1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, // 3312 1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, // 3328 2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, // 3344 3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, // 3360 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, // 3376 3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, // 3392 1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, // 3408 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, // 3424 1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, // 3440 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, // 3456 3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, // 3472 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, // 3488 2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, // 3504 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, // 3520 4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, // 3536 2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, // 3552 1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, // 3568 1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, // 3584 1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, // 3600 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, // 3616 1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, // 3632 3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, // 3648 1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, // 3664 3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, // 3680 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, // 3696 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, // 3712 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, // 3728 2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, // 3744 1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, // 3760 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, // 3776 1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, // 3792 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, // 3808 1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, // 3824 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, // 3840 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, // 3856 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, // 3872 1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, // 3888 1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, // 3904 2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, // 3920 4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, // 3936 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, // 3952 1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, // 3968 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, // 3984 1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, // 4000 3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, // 4016 1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, // 4032 2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, // 4048 2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, // 4064 1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, // 4080 1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, // 4096 2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, // 4112 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, // 4128 2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, // 4144 1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, // 4160 1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, // 4176 1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, // 4192 1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, // 4208 3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, // 4224 2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, // 4240 2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, // 4256 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, // 4272 3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, // 4288 3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, // 4304 1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, // 4320 2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, // 4336 1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, // 4352 2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137 // 4368 //last 512 (*************************************************************************************** *Everything below is of no interest for detection purpose * *************************************************************************************** 2138,2122,3730,2888,1995,1820,1044,6190,6191,6192,6193,6194,6195,6196,6197,6198, // 4384 6199,6200,6201,6202,6203,6204,6205,4670,6206,6207,6208,6209,6210,6211,6212,6213, // 4400 6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229, // 4416 6230,6231,6232,6233,6234,6235,6236,6237,3187,6238,6239,3969,6240,6241,6242,6243, // 4432 6244,4671,6245,6246,4672,6247,6248,4133,6249,6250,4364,6251,2923,2556,2613,4673, // 4448 4365,3970,6252,6253,6254,6255,4674,6256,6257,6258,2768,2353,4366,4675,4676,3188, // 4464 4367,3463,6259,4134,4677,4678,6260,2267,6261,3842,3332,4368,3543,6262,6263,6264, // 4480 3013,1954,1928,4135,4679,6265,6266,2478,3091,6267,4680,4369,6268,6269,1699,6270, // 4496 3544,4136,4681,6271,4137,6272,4370,2804,6273,6274,2593,3971,3972,4682,6275,2236, // 4512 4683,6276,6277,4684,6278,6279,4138,3973,4685,6280,6281,3258,6282,6283,6284,6285, // 4528 3974,4686,2841,3975,6286,6287,3545,6288,6289,4139,4687,4140,6290,4141,6291,4142, // 4544 6292,6293,3333,6294,6295,6296,4371,6297,3399,6298,6299,4372,3976,6300,6301,6302, // 4560 4373,6303,6304,3843,3731,6305,4688,4374,6306,6307,3259,2294,6308,3732,2530,4143, // 4576 6309,4689,6310,6311,6312,3048,6313,6314,4690,3733,2237,6315,6316,2282,3334,6317, // 4592 6318,3844,6319,6320,4691,6321,3400,4692,6322,4693,6323,3049,6324,4375,6325,3977, // 4608 6326,6327,6328,3546,6329,4694,3335,6330,4695,4696,6331,6332,6333,6334,4376,3978, // 4624 6335,4697,3979,4144,6336,3980,4698,6337,6338,6339,6340,6341,4699,4700,4701,6342, // 4640 6343,4702,6344,6345,4703,6346,6347,4704,6348,4705,4706,3135,6349,4707,6350,4708, // 4656 6351,4377,6352,4709,3734,4145,6353,2506,4710,3189,6354,3050,4711,3981,6355,3547, // 4672 3014,4146,4378,3735,2651,3845,3260,3136,2224,1986,6356,3401,6357,4712,2594,3627, // 4688 3137,2573,3736,3982,4713,3628,4714,4715,2682,3629,4716,6358,3630,4379,3631,6359, // 4704 6360,6361,3983,6362,6363,6364,6365,4147,3846,4717,6366,6367,3737,2842,6368,4718, // 4720 2628,6369,3261,6370,2386,6371,6372,3738,3984,4719,3464,4720,3402,6373,2924,3336, // 4736 4148,2866,6374,2805,3262,4380,2704,2069,2531,3138,2806,2984,6375,2769,6376,4721, // 4752 4722,3403,6377,6378,3548,6379,6380,2705,3092,1979,4149,2629,3337,2889,6381,3338, // 4768 4150,2557,3339,4381,6382,3190,3263,3739,6383,4151,4723,4152,2558,2574,3404,3191, // 4784 6384,6385,4153,6386,4724,4382,6387,6388,4383,6389,6390,4154,6391,4725,3985,6392, // 4800 3847,4155,6393,6394,6395,6396,6397,3465,6398,4384,6399,6400,6401,6402,6403,6404, // 4816 4156,6405,6406,6407,6408,2123,6409,6410,2326,3192,4726,6411,6412,6413,6414,4385, // 4832 4157,6415,6416,4158,6417,3093,3848,6418,3986,6419,6420,3849,6421,6422,6423,4159, // 4848 6424,6425,4160,6426,3740,6427,6428,6429,6430,3987,6431,4727,6432,2238,6433,6434, // 4864 4386,3988,6435,6436,3632,6437,6438,2843,6439,6440,6441,6442,3633,6443,2958,6444, // 4880 6445,3466,6446,2364,4387,3850,6447,4388,2959,3340,6448,3851,6449,4728,6450,6451, // 4896 3264,4729,6452,3193,6453,4389,4390,2706,3341,4730,6454,3139,6455,3194,6456,3051, // 4912 2124,3852,1602,4391,4161,3853,1158,3854,4162,3989,4392,3990,4731,4732,4393,2040, // 4928 4163,4394,3265,6457,2807,3467,3855,6458,6459,6460,3991,3468,4733,4734,6461,3140, // 4944 2960,6462,4735,6463,6464,6465,6466,4736,4737,4738,4739,6467,6468,4164,2403,3856, // 4960 6469,6470,2770,2844,6471,4740,6472,6473,6474,6475,6476,6477,6478,3195,6479,4741, // 4976 4395,6480,2867,6481,4742,2808,6482,2493,4165,6483,6484,6485,6486,2295,4743,6487, // 4992 6488,6489,3634,6490,6491,6492,6493,6494,6495,6496,2985,4744,6497,6498,4745,6499, // 5008 6500,2925,3141,4166,6501,6502,4746,6503,6504,4747,6505,6506,6507,2890,6508,6509, // 5024 6510,6511,6512,6513,6514,6515,6516,6517,6518,6519,3469,4167,6520,6521,6522,4748, // 5040 4396,3741,4397,4749,4398,3342,2125,4750,6523,4751,4752,4753,3052,6524,2961,4168, // 5056 6525,4754,6526,4755,4399,2926,4169,6527,3857,6528,4400,4170,6529,4171,6530,6531, // 5072 2595,6532,6533,6534,6535,3635,6536,6537,6538,6539,6540,6541,6542,4756,6543,6544, // 5088 6545,6546,6547,6548,4401,6549,6550,6551,6552,4402,3405,4757,4403,6553,6554,6555, // 5104 4172,3742,6556,6557,6558,3992,3636,6559,6560,3053,2726,6561,3549,4173,3054,4404, // 5120 6562,6563,3993,4405,3266,3550,2809,4406,6564,6565,6566,4758,4759,6567,3743,6568, // 5136 4760,3744,4761,3470,6569,6570,6571,4407,6572,3745,4174,6573,4175,2810,4176,3196, // 5152 4762,6574,4177,6575,6576,2494,2891,3551,6577,6578,3471,6579,4408,6580,3015,3197, // 5168 6581,3343,2532,3994,3858,6582,3094,3406,4409,6583,2892,4178,4763,4410,3016,4411, // 5184 6584,3995,3142,3017,2683,6585,4179,6586,6587,4764,4412,6588,6589,4413,6590,2986, // 5200 6591,2962,3552,6592,2963,3472,6593,6594,4180,4765,6595,6596,2225,3267,4414,6597, // 5216 3407,3637,4766,6598,6599,3198,6600,4415,6601,3859,3199,6602,3473,4767,2811,4416, // 5232 1856,3268,3200,2575,3996,3997,3201,4417,6603,3095,2927,6604,3143,6605,2268,6606, // 5248 3998,3860,3096,2771,6607,6608,3638,2495,4768,6609,3861,6610,3269,2745,4769,4181, // 5264 3553,6611,2845,3270,6612,6613,6614,3862,6615,6616,4770,4771,6617,3474,3999,4418, // 5280 4419,6618,3639,3344,6619,4772,4182,6620,2126,6621,6622,6623,4420,4773,6624,3018, // 5296 6625,4774,3554,6626,4183,2025,3746,6627,4184,2707,6628,4421,4422,3097,1775,4185, // 5312 3555,6629,6630,2868,6631,6632,4423,6633,6634,4424,2414,2533,2928,6635,4186,2387, // 5328 6636,4775,6637,4187,6638,1891,4425,3202,3203,6639,6640,4776,6641,3345,6642,6643, // 5344 3640,6644,3475,3346,3641,4000,6645,3144,6646,3098,2812,4188,3642,3204,6647,3863, // 5360 3476,6648,3864,6649,4426,4001,6650,6651,6652,2576,6653,4189,4777,6654,6655,6656, // 5376 2846,6657,3477,3205,4002,6658,4003,6659,3347,2252,6660,6661,6662,4778,6663,6664, // 5392 6665,6666,6667,6668,6669,4779,4780,2048,6670,3478,3099,6671,3556,3747,4004,6672, // 5408 6673,6674,3145,4005,3748,6675,6676,6677,6678,6679,3408,6680,6681,6682,6683,3206, // 5424 3207,6684,6685,4781,4427,6686,4782,4783,4784,6687,6688,6689,4190,6690,6691,3479, // 5440 6692,2746,6693,4428,6694,6695,6696,6697,6698,6699,4785,6700,6701,3208,2727,6702, // 5456 3146,6703,6704,3409,2196,6705,4429,6706,6707,6708,2534,1996,6709,6710,6711,2747, // 5472 6712,6713,6714,4786,3643,6715,4430,4431,6716,3557,6717,4432,4433,6718,6719,6720, // 5488 6721,3749,6722,4006,4787,6723,6724,3644,4788,4434,6725,6726,4789,2772,6727,6728, // 5504 6729,6730,6731,2708,3865,2813,4435,6732,6733,4790,4791,3480,6734,6735,6736,6737, // 5520 4436,3348,6738,3410,4007,6739,6740,4008,6741,6742,4792,3411,4191,6743,6744,6745, // 5536 6746,6747,3866,6748,3750,6749,6750,6751,6752,6753,6754,6755,3867,6756,4009,6757, // 5552 4793,4794,6758,2814,2987,6759,6760,6761,4437,6762,6763,6764,6765,3645,6766,6767, // 5568 3481,4192,6768,3751,6769,6770,2174,6771,3868,3752,6772,6773,6774,4193,4795,4438, // 5584 3558,4796,4439,6775,4797,6776,6777,4798,6778,4799,3559,4800,6779,6780,6781,3482, // 5600 6782,2893,6783,6784,4194,4801,4010,6785,6786,4440,6787,4011,6788,6789,6790,6791, // 5616 6792,6793,4802,6794,6795,6796,4012,6797,6798,6799,6800,3349,4803,3483,6801,4804, // 5632 4195,6802,4013,6803,6804,4196,6805,4014,4015,6806,2847,3271,2848,6807,3484,6808, // 5648 6809,6810,4441,6811,4442,4197,4443,3272,4805,6812,3412,4016,1579,6813,6814,4017, // 5664 6815,3869,6816,2964,6817,4806,6818,6819,4018,3646,6820,6821,4807,4019,4020,6822, // 5680 6823,3560,6824,6825,4021,4444,6826,4198,6827,6828,4445,6829,6830,4199,4808,6831, // 5696 6832,6833,3870,3019,2458,6834,3753,3413,3350,6835,4809,3871,4810,3561,4446,6836, // 5712 6837,4447,4811,4812,6838,2459,4448,6839,4449,6840,6841,4022,3872,6842,4813,4814, // 5728 6843,6844,4815,4200,4201,4202,6845,4023,6846,6847,4450,3562,3873,6848,6849,4816, // 5744 4817,6850,4451,4818,2139,6851,3563,6852,6853,3351,6854,6855,3352,4024,2709,3414, // 5760 4203,4452,6856,4204,6857,6858,3874,3875,6859,6860,4819,6861,6862,6863,6864,4453, // 5776 3647,6865,6866,4820,6867,6868,6869,6870,4454,6871,2869,6872,6873,4821,6874,3754, // 5792 6875,4822,4205,6876,6877,6878,3648,4206,4455,6879,4823,6880,4824,3876,6881,3055, // 5808 4207,6882,3415,6883,6884,6885,4208,4209,6886,4210,3353,6887,3354,3564,3209,3485, // 5824 2652,6888,2728,6889,3210,3755,6890,4025,4456,6891,4825,6892,6893,6894,6895,4211, // 5840 6896,6897,6898,4826,6899,6900,4212,6901,4827,6902,2773,3565,6903,4828,6904,6905, // 5856 6906,6907,3649,3650,6908,2849,3566,6909,3567,3100,6910,6911,6912,6913,6914,6915, // 5872 4026,6916,3355,4829,3056,4457,3756,6917,3651,6918,4213,3652,2870,6919,4458,6920, // 5888 2438,6921,6922,3757,2774,4830,6923,3356,4831,4832,6924,4833,4459,3653,2507,6925, // 5904 4834,2535,6926,6927,3273,4027,3147,6928,3568,6929,6930,6931,4460,6932,3877,4461, // 5920 2729,3654,6933,6934,6935,6936,2175,4835,2630,4214,4028,4462,4836,4215,6937,3148, // 5936 4216,4463,4837,4838,4217,6938,6939,2850,4839,6940,4464,6941,6942,6943,4840,6944, // 5952 4218,3274,4465,6945,6946,2710,6947,4841,4466,6948,6949,2894,6950,6951,4842,6952, // 5968 4219,3057,2871,6953,6954,6955,6956,4467,6957,2711,6958,6959,6960,3275,3101,4843, // 5984 6961,3357,3569,6962,4844,6963,6964,4468,4845,3570,6965,3102,4846,3758,6966,4847, // 6000 3878,4848,4849,4029,6967,2929,3879,4850,4851,6968,6969,1733,6970,4220,6971,6972, // 6016 6973,6974,6975,6976,4852,6977,6978,6979,6980,6981,6982,3759,6983,6984,6985,3486, // 6032 3487,6986,3488,3416,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,4853, // 6048 6998,6999,4030,7000,7001,3211,7002,7003,4221,7004,7005,3571,4031,7006,3572,7007, // 6064 2614,4854,2577,7008,7009,2965,3655,3656,4855,2775,3489,3880,4222,4856,3881,4032, // 6080 3882,3657,2730,3490,4857,7010,3149,7011,4469,4858,2496,3491,4859,2283,7012,7013, // 6096 7014,2365,4860,4470,7015,7016,3760,7017,7018,4223,1917,7019,7020,7021,4471,7022, // 6112 2776,4472,7023,7024,7025,7026,4033,7027,3573,4224,4861,4034,4862,7028,7029,1929, // 6128 3883,4035,7030,4473,3058,7031,2536,3761,3884,7032,4036,7033,2966,2895,1968,4474, // 6144 3276,4225,3417,3492,4226,2105,7034,7035,1754,2596,3762,4227,4863,4475,3763,4864, // 6160 3764,2615,2777,3103,3765,3658,3418,4865,2296,3766,2815,7036,7037,7038,3574,2872, // 6176 3277,4476,7039,4037,4477,7040,7041,4038,7042,7043,7044,7045,7046,7047,2537,7048, // 6192 7049,7050,7051,7052,7053,7054,4478,7055,7056,3767,3659,4228,3575,7057,7058,4229, // 6208 7059,7060,7061,3660,7062,3212,7063,3885,4039,2460,7064,7065,7066,7067,7068,7069, // 6224 7070,7071,7072,7073,7074,4866,3768,4867,7075,7076,7077,7078,4868,3358,3278,2653, // 6240 7079,7080,4479,3886,7081,7082,4869,7083,7084,7085,7086,7087,7088,2538,7089,7090, // 6256 7091,4040,3150,3769,4870,4041,2896,3359,4230,2930,7092,3279,7093,2967,4480,3213, // 6272 4481,3661,7094,7095,7096,7097,7098,7099,7100,7101,7102,2461,3770,7103,7104,4231, // 6288 3151,7105,7106,7107,4042,3662,7108,7109,4871,3663,4872,4043,3059,7110,7111,7112, // 6304 3493,2988,7113,4873,7114,7115,7116,3771,4874,7117,7118,4232,4875,7119,3576,2336, // 6320 4876,7120,4233,3419,4044,4877,4878,4482,4483,4879,4484,4234,7121,3772,4880,1045, // 6336 3280,3664,4881,4882,7122,7123,7124,7125,4883,7126,2778,7127,4485,4486,7128,4884, // 6352 3214,3887,7129,7130,3215,7131,4885,4045,7132,7133,4046,7134,7135,7136,7137,7138, // 6368 7139,7140,7141,7142,7143,4235,7144,4886,7145,7146,7147,4887,7148,7149,7150,4487, // 6384 4047,4488,7151,7152,4888,4048,2989,3888,7153,3665,7154,4049,7155,7156,7157,7158, // 6400 7159,7160,2931,4889,4890,4489,7161,2631,3889,4236,2779,7162,7163,4891,7164,3060, // 6416 7165,1672,4892,7166,4893,4237,3281,4894,7167,7168,3666,7169,3494,7170,7171,4050, // 6432 7172,7173,3104,3360,3420,4490,4051,2684,4052,7174,4053,7175,7176,7177,2253,4054, // 6448 7178,7179,4895,7180,3152,3890,3153,4491,3216,7181,7182,7183,2968,4238,4492,4055, // 6464 7184,2990,7185,2479,7186,7187,4493,7188,7189,7190,7191,7192,4896,7193,4897,2969, // 6480 4494,4898,7194,3495,7195,7196,4899,4495,7197,3105,2731,7198,4900,7199,7200,7201, // 6496 4056,7202,3361,7203,7204,4496,4901,4902,7205,4497,7206,7207,2315,4903,7208,4904, // 6512 7209,4905,2851,7210,7211,3577,7212,3578,4906,7213,4057,3667,4907,7214,4058,2354, // 6528 3891,2376,3217,3773,7215,7216,7217,7218,7219,4498,7220,4908,3282,2685,7221,3496, // 6544 4909,2632,3154,4910,7222,2337,7223,4911,7224,7225,7226,4912,4913,3283,4239,4499, // 6560 7227,2816,7228,7229,7230,7231,7232,7233,7234,4914,4500,4501,7235,7236,7237,2686, // 6576 7238,4915,7239,2897,4502,7240,4503,7241,2516,7242,4504,3362,3218,7243,7244,7245, // 6592 4916,7246,7247,4505,3363,7248,7249,7250,7251,3774,4506,7252,7253,4917,7254,7255, // 6608 3284,2991,4918,4919,3219,3892,4920,3106,3497,4921,7256,7257,7258,4922,7259,4923, // 6624 3364,4507,4508,4059,7260,4240,3498,7261,7262,4924,7263,2992,3893,4060,3220,7264, // 6640 7265,7266,7267,7268,7269,4509,3775,7270,2817,7271,4061,4925,4510,3776,7272,4241, // 6656 4511,3285,7273,7274,3499,7275,7276,7277,4062,4512,4926,7278,3107,3894,7279,7280, // 6672 4927,7281,4513,7282,7283,3668,7284,7285,4242,4514,4243,7286,2058,4515,4928,4929, // 6688 4516,7287,3286,4244,7288,4517,7289,7290,7291,3669,7292,7293,4930,4931,4932,2355, // 6704 4933,7294,2633,4518,7295,4245,7296,7297,4519,7298,7299,4520,4521,4934,7300,4246, // 6720 4522,7301,7302,7303,3579,7304,4247,4935,7305,4936,7306,7307,7308,7309,3777,7310, // 6736 4523,7311,7312,7313,4248,3580,7314,4524,3778,4249,7315,3581,7316,3287,7317,3221, // 6752 7318,4937,7319,7320,7321,7322,7323,7324,4938,4939,7325,4525,7326,7327,7328,4063, // 6768 7329,7330,4940,7331,7332,4941,7333,4526,7334,3500,2780,1741,4942,2026,1742,7335, // 6784 7336,3582,4527,2388,7337,7338,7339,4528,7340,4250,4943,7341,7342,7343,4944,7344, // 6800 7345,7346,3020,7347,4945,7348,7349,7350,7351,3895,7352,3896,4064,3897,7353,7354, // 6816 7355,4251,7356,7357,3898,7358,3779,7359,3780,3288,7360,7361,4529,7362,4946,4530, // 6832 2027,7363,3899,4531,4947,3222,3583,7364,4948,7365,7366,7367,7368,4949,3501,4950, // 6848 3781,4951,4532,7369,2517,4952,4252,4953,3155,7370,4954,4955,4253,2518,4533,7371, // 6864 7372,2712,4254,7373,7374,7375,3670,4956,3671,7376,2389,3502,4065,7377,2338,7378, // 6880 7379,7380,7381,3061,7382,4957,7383,7384,7385,7386,4958,4534,7387,7388,2993,7389, // 6896 3062,7390,4959,7391,7392,7393,4960,3108,4961,7394,4535,7395,4962,3421,4536,7396, // 6912 4963,7397,4964,1857,7398,4965,7399,7400,2176,3584,4966,7401,7402,3422,4537,3900, // 6928 3585,7403,3782,7404,2852,7405,7406,7407,4538,3783,2654,3423,4967,4539,7408,3784, // 6944 3586,2853,4540,4541,7409,3901,7410,3902,7411,7412,3785,3109,2327,3903,7413,7414, // 6960 2970,4066,2932,7415,7416,7417,3904,3672,3424,7418,4542,4543,4544,7419,4968,7420, // 6976 7421,4255,7422,7423,7424,7425,7426,4067,7427,3673,3365,4545,7428,3110,2559,3674, // 6992 7429,7430,3156,7431,7432,3503,7433,3425,4546,7434,3063,2873,7435,3223,4969,4547, // 7008 4548,2898,4256,4068,7436,4069,3587,3786,2933,3787,4257,4970,4971,3788,7437,4972, // 7024 3064,7438,4549,7439,7440,7441,7442,7443,4973,3905,7444,2874,7445,7446,7447,7448, // 7040 3021,7449,4550,3906,3588,4974,7450,7451,3789,3675,7452,2578,7453,4070,7454,7455, // 7056 7456,4258,3676,7457,4975,7458,4976,4259,3790,3504,2634,4977,3677,4551,4260,7459, // 7072 7460,7461,7462,3907,4261,4978,7463,7464,7465,7466,4979,4980,7467,7468,2213,4262, // 7088 7469,7470,7471,3678,4981,7472,2439,7473,4263,3224,3289,7474,3908,2415,4982,7475, // 7104 4264,7476,4983,2655,7477,7478,2732,4552,2854,2875,7479,7480,4265,7481,4553,4984, // 7120 7482,7483,4266,7484,3679,3366,3680,2818,2781,2782,3367,3589,4554,3065,7485,4071, // 7136 2899,7486,7487,3157,2462,4072,4555,4073,4985,4986,3111,4267,2687,3368,4556,4074, // 7152 3791,4268,7488,3909,2783,7489,2656,1962,3158,4557,4987,1963,3159,3160,7490,3112, // 7168 4988,4989,3022,4990,4991,3792,2855,7491,7492,2971,4558,7493,7494,4992,7495,7496, // 7184 7497,7498,4993,7499,3426,4559,4994,7500,3681,4560,4269,4270,3910,7501,4075,4995, // 7200 4271,7502,7503,4076,7504,4996,7505,3225,4997,4272,4077,2819,3023,7506,7507,2733, // 7216 4561,7508,4562,7509,3369,3793,7510,3590,2508,7511,7512,4273,3113,2994,2616,7513, // 7232 7514,7515,7516,7517,7518,2820,3911,4078,2748,7519,7520,4563,4998,7521,7522,7523, // 7248 7524,4999,4274,7525,4564,3682,2239,4079,4565,7526,7527,7528,7529,5000,7530,7531, // 7264 5001,4275,3794,7532,7533,7534,3066,5002,4566,3161,7535,7536,4080,7537,3162,7538, // 7280 7539,4567,7540,7541,7542,7543,7544,7545,5003,7546,4568,7547,7548,7549,7550,7551, // 7296 7552,7553,7554,7555,7556,5004,7557,7558,7559,5005,7560,3795,7561,4569,7562,7563, // 7312 7564,2821,3796,4276,4277,4081,7565,2876,7566,5006,7567,7568,2900,7569,3797,3912, // 7328 7570,7571,7572,4278,7573,7574,7575,5007,7576,7577,5008,7578,7579,4279,2934,7580, // 7344 7581,5009,7582,4570,7583,4280,7584,7585,7586,4571,4572,3913,7587,4573,3505,7588, // 7360 5010,7589,7590,7591,7592,3798,4574,7593,7594,5011,7595,4281,7596,7597,7598,4282, // 7376 5012,7599,7600,5013,3163,7601,5014,7602,3914,7603,7604,2734,4575,4576,4577,7605, // 7392 7606,7607,7608,7609,3506,5015,4578,7610,4082,7611,2822,2901,2579,3683,3024,4579, // 7408 3507,7612,4580,7613,3226,3799,5016,7614,7615,7616,7617,7618,7619,7620,2995,3290, // 7424 7621,4083,7622,5017,7623,7624,7625,7626,7627,4581,3915,7628,3291,7629,5018,7630, // 7440 7631,7632,7633,4084,7634,7635,3427,3800,7636,7637,4582,7638,5019,4583,5020,7639, // 7456 3916,7640,3801,5021,4584,4283,7641,7642,3428,3591,2269,7643,2617,7644,4585,3592, // 7472 7645,4586,2902,7646,7647,3227,5022,7648,4587,7649,4284,7650,7651,7652,4588,2284, // 7488 7653,5023,7654,7655,7656,4589,5024,3802,7657,7658,5025,3508,4590,7659,7660,7661, // 7504 1969,5026,7662,7663,3684,1821,2688,7664,2028,2509,4285,7665,2823,1841,7666,2689, // 7520 3114,7667,3917,4085,2160,5027,5028,2972,7668,5029,7669,7670,7671,3593,4086,7672, // 7536 4591,4087,5030,3803,7673,7674,7675,7676,7677,7678,7679,4286,2366,4592,4593,3067, // 7552 2328,7680,7681,4594,3594,3918,2029,4287,7682,5031,3919,3370,4288,4595,2856,7683, // 7568 3509,7684,7685,5032,5033,7686,7687,3804,2784,7688,7689,7690,7691,3371,7692,7693, // 7584 2877,5034,7694,7695,3920,4289,4088,7696,7697,7698,5035,7699,5036,4290,5037,5038, // 7600 5039,7700,7701,7702,5040,5041,3228,7703,1760,7704,5042,3229,4596,2106,4089,7705, // 7616 4597,2824,5043,2107,3372,7706,4291,4090,5044,7707,4091,7708,5045,3025,3805,4598, // 7632 4292,4293,4294,3373,7709,4599,7710,5046,7711,7712,5047,5048,3806,7713,7714,7715, // 7648 5049,7716,7717,7718,7719,4600,5050,7720,7721,7722,5051,7723,4295,3429,7724,7725, // 7664 7726,7727,3921,7728,3292,5052,4092,7729,7730,7731,7732,7733,7734,7735,5053,5054, // 7680 7736,7737,7738,7739,3922,3685,7740,7741,7742,7743,2635,5055,7744,5056,4601,7745, // 7696 7746,2560,7747,7748,7749,7750,3923,7751,7752,7753,7754,7755,4296,2903,7756,7757, // 7712 7758,7759,7760,3924,7761,5057,4297,7762,7763,5058,4298,7764,4093,7765,7766,5059, // 7728 3925,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,3595,7777,4299,5060,4094, // 7744 7778,3293,5061,7779,7780,4300,7781,7782,4602,7783,3596,7784,7785,3430,2367,7786, // 7760 3164,5062,5063,4301,7787,7788,4095,5064,5065,7789,3374,3115,7790,7791,7792,7793, // 7776 7794,7795,7796,3597,4603,7797,7798,3686,3116,3807,5066,7799,7800,5067,7801,7802, // 7792 4604,4302,5068,4303,4096,7803,7804,3294,7805,7806,5069,4605,2690,7807,3026,7808, // 7808 7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824, // 7824 7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840, // 7840 7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856, // 7856 7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872, // 7872 7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888, // 7888 7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904, // 7904 7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920, // 7920 7921,7922,7923,7924,3926,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935, // 7936 7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951, // 7952 7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967, // 7968 7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983, // 7984 7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999, // 8000 8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015, // 8016 8016,8017,8018,8019,8020,8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031, // 8032 8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047, // 8048 8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063, // 8064 8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079, // 8080 8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095, // 8096 8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111, // 8112 8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127, // 8128 8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143, // 8144 8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159, // 8160 8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175, // 8176 8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191, // 8192 8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207, // 8208 8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223, // 8224 8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239, // 8240 8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255, // 8256 8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271, // 8272 ****************************************************************************************) ); implementation end. doublecmd-0.8.2/components/chsdet/src/dbg.inc0000664000175000017500000000015012014201074020145 0ustar alexxalexx{.$DEFINE DEBUG_chardet} // Uncomment this for debug dump.*) {$ifdef DEBUG_chardet} Dump, {$endif} doublecmd-0.8.2/components/chsdet/src/CharDistribution.pas0000664000175000017500000002353412014201074022713 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: CharDistribution.pas,v 1.3 2007/05/26 13:09:38 ya_nick Exp $ unit CharDistribution; {$R-} interface uses nsCore; type TCharDistributionAnalysis = class (TObject) protected //mDone: PRBool; (*If this flag is set to PR_TRUE, detection is done and conclusion has been made*) // YaN: nice idea. Unfortunately is not implemented :(( mFreqChars: PRUint32; (*The number of characters whose frequency order is less than 512*) mTotalChars: PRUint32; (*Total character encounted.*) mCharToFreqOrder: pPRInt16; (*Mapping table to get frequency order from char order (get from GetOrder())*) mTableSize: PRUint32; (*Size of above table*) mTypicalDistributionRatio: double;(*This is a constant value varies from language to language, it is used in calculating confidence. See my paper for further detail.*) //we do not handle character base on its original encoding string, but //convert this encoding string to a number, here called order. //This allow multiple encoding of a language to share one frequency table function GetOrder(str: PChar): PRInt32; virtual; abstract; (*feed a block of data and do distribution analysis*) // function HandleData(const aBuf: PChar; aLen: PRUint32): eProbingState; virtual; abstract; public destructor Destroy; override; (*This function is for future extension. Caller can use this function to control analyser's behavior*) // procedure SetOpion(); virtual; abstract; (*return confidence base on existing data*) function GetConfidence: float; virtual; (*Reset analyser, clear any state *) procedure Reset; virtual; (*It is not necessary to receive all data to draw conclusion. For charset detection, certain amount of data is enough*) function GotEnoughData: Boolean; (*Feed a character with known length*) procedure HandleOneChar(aStr: PChar; aCharLen: PRUint32); virtual; end; TEUCTWDistributionAnalysis = class (TCharDistributionAnalysis) (*for euc-TW encoding, we are interested *) (* first byte range: 0xc4 -- 0xfe*) (* second byte range: 0xa1 -- 0xfe*) (*no validation needed here. State machine has done that*) protected function GetOrder(str: PChar): PRInt32; override; public constructor Create; reintroduce; end; TEUCKRDistributionAnalysis = class (TCharDistributionAnalysis) (*for euc-KR encoding, we are interested *) (* first byte range: 0xb0 -- 0xfe*) (* second byte range: 0xa1 -- 0xfe*) (*no validation needed here. State machine has done that*) protected function GetOrder(str: PChar): PRInt32; override; public constructor Create; reintroduce; end; TGB2312DistributionAnalysis = class (TCharDistributionAnalysis) (*for GB2312 encoding, we are interested *) (* first byte range: 0xb0 -- 0xfe*) (* second byte range: 0xa1 -- 0xfe*) (*no validation needed here. State machine has done that*) protected function GetOrder(str: PChar): PRInt32; override; public constructor Create; reintroduce; end; TBig5DistributionAnalysis = class (TCharDistributionAnalysis) (*for big5 encoding, we are interested *) (* first byte range: 0xa4 -- 0xfe*) (* second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe*) (*no validation needed here. State machine has done that*) protected function GetOrder(str: PChar): PRInt32; override; public constructor Create; reintroduce; end; TSJISDistributionAnalysis = class (TCharDistributionAnalysis) (*for sjis encoding, we are interested *) (* first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe*) (* second byte range: 0x40 -- 0x7e, 0x81 -- oxfe*) (*no validation needed here. State machine has done that*) protected function GetOrder(str: PChar): PRInt32; override; public constructor Create; reintroduce; end; TEUCJPDistributionAnalysis = class (TCharDistributionAnalysis) (*for euc-JP encoding, we are interested *) (* first byte range: 0xa0 -- 0xfe*) (* second byte range: 0xa1 -- 0xfe*) (*no validation needed here. State machine has done that*) protected function GetOrder(str: PChar): PRInt32; override; public constructor Create; reintroduce; end; implementation uses JISFreq, Big5Freq, EUCKRFreq, EUCTWFreq, GB2312Freq; destructor TCharDistributionAnalysis.Destroy; begin mCharToFreqOrder := nil; inherited; end; procedure TCharDistributionAnalysis.HandleOneChar(aStr: PChar; aCharLen: PRUint32); var order: integer; begin (*we only care about 2-bytes character in our distribution analysis*) if (aCharLen=2) then order := GetOrder(aStr) else order := -1; if order >= 0 then begin inc(mTotalChars); (*order is valid*) if order < integer(mTableSize) then begin if 512 > aPRint16(mCharToFreqOrder)[order] then inc(mFreqChars); end; end; end; function TCharDistributionAnalysis.GetConfidence: float; var r: float; begin (*if we didn't receive any character in our consideration range, return negative answer*) if mTotalChars <= 0 then begin Result := SURE_NO; exit; end; if mTotalChars <> mFreqChars then begin r := mFreqChars / ((mTotalChars - mFreqChars) * mTypicalDistributionRatio); if r < SURE_YES then begin Result := r; exit; end; end; (*normalize confidence, (we don't want to be 100% sure)*) Result := SURE_YES; end; procedure TCharDistributionAnalysis.Reset; begin mTotalChars := 0; mFreqChars := 0; end; function TCharDistributionAnalysis.GotEnoughData: Boolean; begin Result := (mTotalChars > ENOUGH_DATA_THRESHOLD); end; constructor TEUCTWDistributionAnalysis.Create; begin inherited Create; mCharToFreqOrder := @EUCTWCharToFreqOrder; mTableSize := EUCTW_TABLE_SIZE; mTypicalDistributionRatio := EUCTW_TYPICAL_DISTRIBUTION_RATIO; end; function TEUCTWDistributionAnalysis.GetOrder(str: PChar): PRInt32; begin if byte(str^) >= $c4 then Result := 94 * (byte(str[0]) - $c4) + byte(str[1]) - byte($a1) else Result := -1; end; constructor TEUCKRDistributionAnalysis.Create; begin inherited Create; mCharToFreqOrder := @EUCKRCharToFreqOrder; mTableSize := EUCKR_TABLE_SIZE; mTypicalDistributionRatio := EUCKR_TYPICAL_DISTRIBUTION_RATIO; end; function TEUCKRDistributionAnalysis.GetOrder(str: PChar): PRInt32; begin if byte(str^) >= $b0 then Result := 94 * (byte(str[0]) - $b0) + byte(str[1]) - $a1 else Result := -1; end; constructor TGB2312DistributionAnalysis.Create; begin inherited; mCharToFreqOrder := @GB2312CharToFreqOrder; mTableSize := GB2312_TABLE_SIZE; mTypicalDistributionRatio := GB2312_TYPICAL_DISTRIBUTION_RATIO; end; function TGB2312DistributionAnalysis.GetOrder(str: PChar): PRInt32; begin if (byte(str[0]) >= $b0) and (byte(str[1]) >= $a1) then Result := 94 * (byte(str[0]) - $b0) + byte(str[1]) - $a1 else Result := -1; end; constructor TBig5DistributionAnalysis.Create; begin inherited; mCharToFreqOrder := @Big5CharToFreqOrder; mTableSize := BIG5_TABLE_SIZE; mTypicalDistributionRatio := BIG5_TYPICAL_DISTRIBUTION_RATIO; end; function TBig5DistributionAnalysis.GetOrder(str: PChar): PRInt32; begin if byte(str[0]) >= $a4 then begin if byte(str[1]) >= $a1 then Result := 157 * (byte(str[0]) - $a4) + byte(str[1]) - $a1 + 63 else Result := 157 * (byte(str[0]) - $a4) + byte(str[1]) - $40; end else Result:= -1; end; constructor TSJISDistributionAnalysis.Create; begin inherited Create; mCharToFreqOrder := @JISCharToFreqOrder; mTableSize := JIS_TABLE_SIZE; mTypicalDistributionRatio := JIS_TYPICAL_DISTRIBUTION_RATIO; end; function TSJISDistributionAnalysis.GetOrder(str: PChar): PRInt32; var order: PRInt32; begin if (byte(str[0]) >= $81) and (byte(str[0]) <= $9f) then order := 188 * (byte(str[0]) - $81) else if (byte(str[0]) >= $e0) and (byte(str[0]) <= $ef) then order := 188 * (byte(str[0]) - $e0 + 31) else begin Result:= -1; exit; end; order := order + (byte((str+1)^) - $40); if byte(str[1]) > $7f then dec(order); Result := order; end; constructor TEUCJPDistributionAnalysis.Create; begin inherited Create; mCharToFreqOrder := @JISCharToFreqOrder; mTableSize := JIS_TABLE_SIZE; mTypicalDistributionRatio := JIS_TYPICAL_DISTRIBUTION_RATIO; end; function TEUCJPDistributionAnalysis.GetOrder(str: PChar): PRInt32; begin if byte(str[0]) >= $a0 then Result := 94 * (byte(str[0]) - $a1) + byte(str[1]) - $a1 else Result:= -1; end; end. doublecmd-0.8.2/components/chsdet/src/MBUnicodeMultiProber.pas0000664000175000017500000000765413023052076023444 0ustar alexxalexx// +----------------------------------------------------------------------+ // | chsdet - Charset Detector Library | // +----------------------------------------------------------------------+ // | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net | // +----------------------------------------------------------------------+ // | Based on Mozilla sources http://www.mozilla.org/projects/intl/ | // +----------------------------------------------------------------------+ // | This library is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | // | the Free Software Foundation; either version 2 of the License, or | // | (at your option) any later version. | // | This library is distributed in the hope that it will be useful | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | // | See the GNU Lesser General Public License for more details. | // | http://www.opensource.org/licenses/lgpl-license.php | // +----------------------------------------------------------------------+ // // $Id: MBUnicodeMultiProber.pas,v 1.2 2007/05/26 13:09:38 ya_nick Exp $ unit MBUnicodeMultiProber; interface uses {$I dbg.inc} nsCore, MultiModelProber; type TMBUnicodeMultiProber = class (TMultiModelProber) public constructor Create; reintroduce; destructor Destroy; override; function HandleData(aBuf: PChar; aLen: integer): eProbingState; override; // function GetConfidence: double; override; end; implementation uses SysUtils, nsCodingStateMachine; {$I '.\mbclass\UTF8LangModel.inc'} {$I '.\mbclass\UCS2BELangModel.inc'} {$I '.\mbclass\UCS2LELangModel.inc'} { TMBUnicodeMultiProber } const NUM_OF_PROBERS = 3; ONE_CHAR_PROB: float = 0.50; {$ifdef DEBUG_chardet} {$endif} constructor TMBUnicodeMultiProber.Create; begin inherited Create; AddCharsetModel(UTF8LangModel); AddCharsetModel(UCS2BELangModel); AddCharsetModel(UCS2LELangModel); end; destructor TMBUnicodeMultiProber.Destroy; begin inherited; end; function TMBUnicodeMultiProber.HandleData(aBuf: PChar; aLen: integer): eProbingState; var i: integer; (*do filtering to reduce load to probers*) highbyteBuf: PChar; hptr: PChar; keepNext: Boolean; begin keepNext := TRUE; (*assume previous is not ascii, it will do no harm except add some noise*) highbyteBuf := AllocMem(aLen); try hptr:= highbyteBuf; if hptr = nil then begin Result := mState; exit; end; for i:=0 to Pred(aLen) do begin if (Byte(aBuf[i]) > $80) then begin hptr^ := aBuf[i]; inc(hptr); keepNext:= TRUE; end else begin (*if previous is highbyte, keep this even it is a ASCII*) if keepNext = TRUE then begin hptr^ := aBuf[i]; inc(hptr); keepNext:= FALSE; end; end; end; // inherited HandleData(highbyteBuf, hptr - highbyteBuf); inherited HandleData(aBuf, aLen); finally FreeMem(highbyteBuf, aLen); end; Result := mState; end; //function TMBUnicodeMultiProber.GetConfidence: double; //var // i: integer; // conf, // bestConf: double; //begin // mBestGuess := -1; // bestConf := SURE_NO; // for i := 0 to Pred(mCharsetsCount) do // begin // if (mSMState[i] = psFoundIt) or // (mSMState[i] = psNotMe) then // continue; // // if conf > bestConf then // begin // mBestGuess := i; // bestConf := conf; // end; // end; // Result := bestConf; // if mBestGuess > 0 then // mDetectedCharset := mCodingSM[mBestGuess].GetCharsetID // else // mDetectedCharset := UNKNOWN_CHARSET; //end; end. doublecmd-0.8.2/components/multithreadprocs/0000775000175000017500000000000013244011205020253 5ustar alexxalexxdoublecmd-0.8.2/components/multithreadprocs/multithreadprocslaz.pas0000664000175000017500000000055412677725617025120 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit MultiThreadProcsLaz; interface uses MTProcs, MTPUtils, MTPCPU, LazarusPackageIntf; implementation procedure Register; begin end; initialization RegisterPackage('MultiThreadProcsLaz', @Register); end. doublecmd-0.8.2/components/multithreadprocs/examples/0000775000175000017500000000000013244011205022071 5ustar alexxalexxdoublecmd-0.8.2/components/multithreadprocs/examples/testmtp1.lpi0000664000175000017500000000255312573027524024404 0ustar alexxalexx doublecmd-0.8.2/components/multithreadprocs/examples/simplemtp1.lpr0000664000175000017500000000071712573027524024727 0ustar alexxalexxprogram SimpleMTP1; {$mode objfpc}{$H+} uses {$IFDEF UNIX} cthreads, cmem, {$ENDIF} MTProcs; // a simple parallel procedure procedure DoSomethingParallel(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); var i: Integer; begin writeln(Index); for i:=1 to Index*1000000 do ; // do some work end; begin ProcThreadPool.DoParallel(@DoSomethingParallel,1,5,nil); // address, startindex, endindex, optional data end. doublecmd-0.8.2/components/multithreadprocs/examples/recursivemtp1.lpi0000664000175000017500000000276312573027524025437 0ustar alexxalexx </General> <VersionInfo> <ProjectVersion Value=""/> </VersionInfo> <PublishOptions> <Version Value="2"/> <IgnoreBinaries Value="False"/> <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> </PublishOptions> <RunParams> <local> <FormatVersion Value="1"/> <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> </local> </RunParams> <RequiredPackages Count="1"> <Item1> <PackageName Value="MultiThreadProcsLaz"/> <MinVersion Valid="True"/> <DefaultFilename Value="../multithreadprocslaz.lpk"/> </Item1> </RequiredPackages> <Units Count="1"> <Unit0> <Filename Value="recursivemtp1.lpr"/> <IsPartOfProject Value="True"/> <UnitName Value="RecursiveMTP1"/> </Unit0> </Units> </ProjectOptions> <CompilerOptions> <Version Value="8"/> <Other> <CompilerPath Value="$(CompPath)"/> </Other> </CompilerOptions> </CONFIG> �������������doublecmd-0.8.2/components/multithreadprocs/examples/simplemtp1.lpi���������������������������������0000664�0001750�0001750�00000003006�12573027524�024710� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0"?> <CONFIG> <ProjectOptions> <PathDelim Value="/"/> <Version Value="7"/> <General> <Flags> <LRSInOutputDirectory Value="False"/> </Flags> <SessionStorage Value="InProjectDir"/> <MainUnit Value="0"/> <TargetFileExt Value=""/> <Title Value="simplemtp1"/> </General> <VersionInfo> <ProjectVersion Value=""/> </VersionInfo> <PublishOptions> <Version Value="2"/> <IgnoreBinaries Value="False"/> <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> </PublishOptions> <RunParams> <local> <FormatVersion Value="1"/> <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> </local> </RunParams> <RequiredPackages Count="1"> <Item1> <PackageName Value="MultiThreadProcsLaz"/> <MinVersion Valid="True"/> <DefaultFilename Value="../multithreadprocslaz.lpk"/> </Item1> </RequiredPackages> <Units Count="1"> <Unit0> <Filename Value="simplemtp1.lpr"/> <IsPartOfProject Value="True"/> <UnitName Value="SimpleMTP1"/> </Unit0> </Units> </ProjectOptions> <CompilerOptions> <Version Value="8"/> <Other> <CompilerPath Value="$(CompPath)"/> </Other> </CompilerOptions> </CONFIG> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/multithreadprocs/examples/recursivemtp1.lpr������������������������������0000664�0001750�0001750�00000002265�12573027524�025445� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������program RecursiveMTP1; {$mode objfpc}{$H+} uses {$IFDEF UNIX} cthreads, cmem, {$ENDIF} MTProcs; type TArrayOfInteger = array of integer; var Items: TArrayOfInteger; type TFindMaximumParallelData = record Items: TArrayOfInteger; Left, Middle, Right: integer; LeftMaxIndex, RightMaxIndex: integer; end; PFindMaximumParallelData = ^TFindMaximumParallelData; procedure FindMaximumParallel(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); var Params: PFindMaximumParallelData absolute Data; LeftParams, RightParams: TFindMaximumParallelData; begin if Params^.Left+1000>Params^.Right then begin // compute the maximum of the few remaining items Params^.LeftMaxIndex:=Params^.Items[Params^.Left]; for i:=Params^.Left+1 to Params^.Right do if Params^.Items[i]>Params^.LeftMaxIndex then end else begin end; end; function FindMaximumIndex(Items: TArrayOfInteger): integer; begin end; begin SetLength(Items,10000000); for i:=0 to length(Items)-1 do Items[i]:=Random(1000); ProcThreadPool.DoParallel(@DoSomethingParallel,1,5,nil); // address, startindex, endindex, optional data end. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/multithreadprocs/examples/parallelloop1.lpr������������������������������0000664�0001750�0001750�00000006360�12573027524�025403� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ Example for a parallel loop with MTProcs. Copyright (C) 2009 Mattias Gaertner mattias@freepascal.org This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version with the following modification: As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules,and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. } program ParallelLoop1; {$mode objfpc}{$H+} uses {$IFDEF UNIX} cthreads, cmem, {$ENDIF} Classes, SysUtils, MTProcs; type TFindBestData = record List: TList; Value: Pointer; BlockCount: integer; Results: array of integer; end; PFindBestData = ^TFindBestData; procedure FindBestParallel(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); var i: integer; begin with PFindBestData(Data)^ do begin Results[Index]:=-1; i:=Index; while i<List.Count-1 do begin if List[i]=Value then // hier wuerde die teure Vergleichsoperation stehen Results[Index]:=i; inc(i,BlockCount); end; end; end; function FindBest(aList: TList; aValue: Pointer): integer; var Index: integer; Data: TFindBestData; begin with Data do begin List:=aList; Value:=aValue; BlockCount:=ProcThreadPool.MaxThreadCount; SetLength(Results,BlockCount); ProcThreadPool.DoParallel(@FindBestParallel,0,BlockCount-1,@Data); // Ergebnisse zusammenfassen Result:=-1; for Index:=0 to BlockCount-1 do if Results[Index]>=0 then Result:=Results[Index]; end; end; function FindBest1(List: TList; Value: Pointer): integer; var i: integer; begin Result:=-1; i:=0; while i<List.Count do begin if List[i]=Value then // hier wuerde die teure Vergleichsoperation stehen Result:=i; inc(i); end; end; var List: TList; i: Integer; begin List:=TList.Create; for i:=0 to 100000000 do List.Add(Pointer(i)); i:=FindBest(List,Pointer(9999)); //i:=FindBest1(List,Pointer(9999)); writeln('i=',i); end. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/multithreadprocs/examples/testmtp1.lpr�����������������������������������0000664�0001750�0001750�00000025102�12573027524�024410� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������program TestMTP1; {$mode objfpc}{$H+} uses {$IFDEF UNIX} cthreads, cmem, {$ENDIF} Math, SysUtils, Classes, MTProcs, MTPUtils, MultiThreadProcsLaz; type { TTestItem } TTestItem = class private FIndex: int64; public property Index: int64 read FIndex; constructor Create(NewIndex: int64); end; { TTests } TTests = class public procedure Work(Seconds: integer); // RTLeventSetEvent, RTLeventWaitFor procedure TestRTLevent_Set_WaitFor; // single thread test procedure TestSingleThread; procedure MTPLoop_TestSingleThread(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); // two threads test: run once procedure TestTwoThreads1; procedure MTPLoop_TestTwoThreads1(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); // 0 runs two seconds, // 1 runs a second then waits for 0 then runs a second // 2 runs a second then waits for 1 // 3 waits for 0 // 4 waits for 1 // 5 waits for 2 procedure TestMTPWaitForIndex; procedure MTPLoop_TestMTPWaitForIndex(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); // two threads test: various run times procedure TestMTPTwoThreads2; procedure MTPLoop_TestTwoThreads2(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); // test exception in starter thread procedure TestMTPExceptionInStarterThread; procedure MTPLoop_TestExceptionInStarterThread(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); // test exception in helper thread procedure TestMTPExceptionInHelperThread; procedure MTPLoop_TestExceptionInHelperThread(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); // test parallel sort procedure TestMTPSort; procedure MTPLoop_TestDoubleMTPSort(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); end; { TTestItem } constructor TTestItem.Create(NewIndex: int64); begin FIndex:=NewIndex; end; { TTests } procedure TTests.Work(Seconds: integer); var Start: TDateTime; begin Start:=Now; while (Now-Start)*86400<Seconds do if GetCurrentDir='' then ; end; procedure TTests.TestRTLevent_Set_WaitFor; var e: PRTLEvent; begin e:=RTLEventCreate; RTLeventSetEvent(e); RTLeventWaitFor(e); RTLeventdestroy(e); end; procedure TTests.TestSingleThread; begin ProcThreadPool.DoParallel(@MTPLoop_TestSingleThread,1,3,nil,1); end; procedure TTests.MTPLoop_TestSingleThread(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); begin writeln('TTests.MTPLoop_TestSingleThread Index=',Index); end; procedure TTests.TestTwoThreads1; begin WriteLn('TTests.TestTwoThreads1 START'); ProcThreadPool.DoParallel(@MTPLoop_TestTwoThreads1,1,2,nil,2); WriteLn('TTests.TestTwoThreads1 END'); end; procedure TTests.MTPLoop_TestTwoThreads1(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); var i: Integer; begin for i:=1 to 3 do begin WriteLn('TTests.MTPLoop_TestTwoThreads1 Index=',Index,' ',i); Work(1); end; end; procedure TTests.TestMTPWaitForIndex; var IndexStates: PInteger; begin ProcThreadPool.MaxThreadCount:=8; IndexStates:=nil; GetMem(IndexStates,SizeOf(Integer)*10); FillByte(IndexStates^,SizeOf(Integer)*10,0); WriteLn('TTests.TestMTPWaitForIndex START'); ProcThreadPool.DoParallel(@MTPLoop_TestMTPWaitForIndex,0,5,IndexStates); FreeMem(IndexStates); WriteLn('TTests.TestMTPWaitForIndex END'); end; procedure TTests.MTPLoop_TestMTPWaitForIndex(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); // 0 runs two seconds, // 1 runs a second then waits for 0 then runs a second // 2 runs a second then waits for 1 // 3 waits for 0 // 4 waits for 1 // 5 waits for 2 procedure WaitFor(OtherIndex: PtrInt); begin WriteLn('TTests.MTPLoop_TestMTPWaitForIndex Index='+IntToStr(Index)+' waiting for '+IntToStr(OtherIndex)+' ...'); Item.WaitForIndex(OtherIndex); WriteLn('TTests.MTPLoop_TestMTPWaitForIndex Index='+IntToStr(Index)+' waited for '+IntToStr(OtherIndex)+'. working ...'); if PInteger(Data)[OtherIndex]<>2 then begin WriteLn('TTests.MTPLoop_TestMTPWaitForIndex Index='+IntToStr(Index)+' ERROR: waited for '+IntToStr(OtherIndex)+' failed: OtherState='+IntToStr(PInteger(Data)[OtherIndex])); end; end; begin WriteLn('TTests.MTPLoop_TestMTPWaitForIndex Index='+IntToStr(Index)+' START'); if PInteger(Data)[Index]<>0 then begin WriteLn('TTests.MTPLoop_TestMTPWaitForIndex Index='+IntToStr(Index)+' ERROR: IndexState='+IntToStr(PInteger(Data)[Index])); end; PInteger(Data)[Index]:=1; case Index of 0: Work(2); 1:begin Work(1); WaitFor(0); Work(1); end; 2:begin Work(1); WaitFor(1); end; 3:begin WaitFor(0); end; 4:begin WaitFor(1); end; 5:begin WaitFor(2); end; end; WriteLn('TTests.MTPLoop_TestMTPWaitForIndex Index='+IntToStr(Index)+' END'); PInteger(Data)[Index]:=2; end; procedure TTests.TestMTPTwoThreads2; begin WriteLn('TTests.TestMTPTwoThreads1 START'); ProcThreadPool.DoParallel(@MTPLoop_TestTwoThreads2,1,6,nil,2); WriteLn('TTests.TestMTPTwoThreads1 END'); end; procedure TTests.MTPLoop_TestTwoThreads2(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); var i: Integer; begin for i:=1 to (Index mod 3)+1 do begin WriteLn('TTests.MTPLoop_TestTwoThreads1 Index=',Index,' i=',i,' ID=',PtrUint(GetThreadID)); Work(1); end; end; type TMyException = class(Exception); procedure TTests.TestMTPExceptionInStarterThread; var IndexStates: PInteger; begin WriteLn('TTests.TestMTPExceptionInStarterThread START'); ProcThreadPool.MaxThreadCount:=8; IndexStates:=nil; GetMem(IndexStates,SizeOf(Integer)*10); FillByte(IndexStates^,SizeOf(Integer)*10,0); try ProcThreadPool.DoParallel(@MTPLoop_TestExceptionInStarterThread,1,3,IndexStates,2); except on E: Exception do begin WriteLn('TTests.TestMTPExceptionInHelperThread E.ClassName=',E.ClassName,' E.Message=',E.Message); end; end; FreeMem(IndexStates); WriteLn('TTests.TestMTPExceptionInStarterThread END'); end; procedure TTests.MTPLoop_TestExceptionInStarterThread(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); begin WriteLn('TTests.MTPLoop_TestExceptionInStarterThread START Index='+IntToStr(Index)); if PInteger(Data)[Index]<>0 then WriteLn('TTests.MTPLoop_TestExceptionInStarterThread Index='+IntToStr(Index)+' ERROR: IndexState='+IntToStr(PInteger(Data)[Index])); PInteger(Data)[Index]:=1; case Index of 1: begin // Main Thread Work(1); WriteLn('TTests.MTPLoop_TestExceptionInStarterThread raising exception in Index='+IntToStr(Index)+' ...'); raise Exception.Create('Exception in starter thread'); end; else Work(Index); end; PInteger(Data)[Index]:=2; WriteLn('TTests.MTPLoop_TestExceptionInStarterThread END Index='+IntToStr(Index)); end; procedure TTests.TestMTPExceptionInHelperThread; var IndexStates: PInteger; begin WriteLn('TTests.TestMTPExceptionInHelperThread START'); ProcThreadPool.MaxThreadCount:=8; IndexStates:=nil; GetMem(IndexStates,SizeOf(Integer)*10); FillByte(IndexStates^,SizeOf(Integer)*10,0); try ProcThreadPool.DoParallel(@MTPLoop_TestExceptionInHelperThread,1,3,IndexStates,2); except on E: Exception do begin WriteLn('TTests.TestMTPExceptionInHelperThread E.ClassName=',E.ClassName,' E.Message=',E.Message); end; end; FreeMem(IndexStates); WriteLn('TTests.TestMTPExceptionInHelperThread END'); end; procedure TTests.MTPLoop_TestExceptionInHelperThread(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); begin WriteLn('TTests.MTPLoop_TestExceptionInHelperThread START Index='+IntToStr(Index)); if PInteger(Data)[Index]<>0 then WriteLn('TTests.MTPLoop_TestExceptionInHelperThread Index='+IntToStr(Index)+' ERROR: IndexState='+IntToStr(PInteger(Data)[Index])); PInteger(Data)[Index]:=1; case Index of 2: begin // Helper Thread 2 Work(1); WriteLn('TTests.MTPLoop_TestExceptionInHelperThread raising exception in Index='+IntToStr(Index)+' ...'); raise TMyException.Create('Exception in helper thread'); end; else Work(Index+1); end; PInteger(Data)[Index]:=2; WriteLn('TTests.MTPLoop_TestExceptionInHelperThread END Index='+IntToStr(Index)); end; function CompareTestItems(Data1, Data2: Pointer): integer; begin if TTestItem(Data1).Index>TTestItem(Data2).Index then Result:=1 else if TTestItem(Data1).Index<TTestItem(Data2).Index then Result:=-1 else Result:=0; end; procedure TTests.TestMTPSort; var OuterLoop: Integer; InnerLoop: Integer; begin OuterLoop:=1; InnerLoop:=0; if Paramcount=1 then begin InnerLoop:=StrToInt(ParamStr(1)); end else if Paramcount=2 then begin OuterLoop:=StrToInt(ParamStr(1)); InnerLoop:=StrToInt(ParamStr(2)); end; writeln('TTests.TestMTPSort Running ',OuterLoop,'x',InnerLoop); ProcThreadPool.DoParallel(@MTPLoop_TestDoubleMTPSort,1,OuterLoop,@InnerLoop); end; procedure TTests.MTPLoop_TestDoubleMTPSort(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); var i: Integer; List: TFPList; t: double; begin // create an unsorted list of values List:=TFPList.Create; for i:=1 to 10000000 do List.Add(TTestItem.Create(Random(99999999999))); //QuickSort(List,0,List.Count-1,@AnsiCompareText); t:=Now; ParallelSortFPList(List,@CompareTestItems,PInteger(Data)^); t:=Now-t; writeln('TTests.TestMTPSort ',t*86400); // check sleep(1); for i:=0 to List.Count-2 do if CompareTestItems(List[i],List[i+1])>0 then raise Exception.Create('not sorted'); for i:=0 to List.Count-1 do TObject(List[i]).Free; List.Free; end; var Tests: TTests; begin writeln('threads=',ProcThreadPool.MaxThreadCount); ProcThreadPool.MaxThreadCount:=8; Tests:=TTests.Create; //Tests.Test1; //Tests.Test2; //Tests.TestTwoThreads2; //Tests.TestRTLevent_Set_WaitFor; //Tests.TestMTPWaitForIndex; //Tests.TestMTPExceptionInStarterThread; Tests.TestMTPExceptionInHelperThread; //Tests.TestMTPSort; Tests.Free; end. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/multithreadprocs/examples/parallelloop1.lpi������������������������������0000664�0001750�0001750�00000002763�12573027524�025375� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0"?> <CONFIG> <ProjectOptions> <Version Value="7"/> <General> <Flags> <LRSInOutputDirectory Value="False"/> </Flags> <SessionStorage Value="InProjectDir"/> <MainUnit Value="0"/> <TargetFileExt Value=""/> <Title Value="parallelloop1"/> </General> <VersionInfo> <ProjectVersion Value=""/> </VersionInfo> <PublishOptions> <Version Value="2"/> <IgnoreBinaries Value="False"/> <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> </PublishOptions> <RunParams> <local> <FormatVersion Value="1"/> <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> </local> </RunParams> <RequiredPackages Count="1"> <Item1> <PackageName Value="MultiThreadProcsLaz"/> <MinVersion Valid="True"/> <DefaultFilename Value="../multithreadprocslaz.lpk"/> </Item1> </RequiredPackages> <Units Count="1"> <Unit0> <Filename Value="parallelloop1.lpr"/> <IsPartOfProject Value="True"/> <UnitName Value="ParallelLoop1"/> </Unit0> </Units> </ProjectOptions> <CompilerOptions> <Version Value="8"/> <Other> <CompilerPath Value="$(CompPath)"/> </Other> </CompilerOptions> </CONFIG> �������������doublecmd-0.8.2/components/multithreadprocs/Readme.txt����������������������������������������������0000664�0001750�0001750�00000000110�12573027524�022220� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Official page: http://wiki.lazarus.freepascal.org/Parallel_procedures ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/multithreadprocs/mtpcpu.pas����������������������������������������������0000664�0001750�0001750�00000005152�12573027524�022312� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ System depending code for light weight threads. This file is part of the Free Pascal run time library. Copyright (C) 2008 Mattias Gaertner mattias@freepascal.org See the file COPYING.FPC, included in this distribution, for details about the copyright. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **********************************************************************} unit MTPCPU; {$mode objfpc}{$H+} {$inline on} interface {$IF defined(windows)} uses Windows; {$ELSEIF defined(freebsd) or defined(darwin)} uses ctypes, sysctl; {$ELSEIF defined(linux)} {$linklib c} uses ctypes; {$ENDIF} function GetSystemThreadCount: integer; procedure CallLocalProc(AProc, Frame: Pointer; Param1: PtrInt; Param2, Param3: Pointer); inline; implementation {$IFDEF Linux} const _SC_NPROCESSORS_ONLN = 83; function sysconf(i: cint): clong; cdecl; external name 'sysconf'; {$ENDIF} function GetSystemThreadCount: integer; // returns a good default for the number of threads on this system {$IF defined(windows)} //returns total number of processors available to system including logical hyperthreaded processors var i: Integer; ProcessAffinityMask, SystemAffinityMask: DWORD_PTR; Mask: DWORD; SystemInfo: SYSTEM_INFO; begin if GetProcessAffinityMask(GetCurrentProcess, ProcessAffinityMask, SystemAffinityMask) then begin Result := 0; for i := 0 to 31 do begin Mask := DWord(1) shl i; if (ProcessAffinityMask and Mask)<>0 then inc(Result); end; end else begin //can't get the affinity mask so we just report the total number of processors GetSystemInfo(SystemInfo); Result := SystemInfo.dwNumberOfProcessors; end; end; {$ELSEIF defined(UNTESTEDsolaris)} begin t = sysconf(_SC_NPROC_ONLN); end; {$ELSEIF defined(freebsd) or defined(darwin)} var mib: array[0..1] of cint; len: cint; t: cint; begin mib[0] := CTL_HW; mib[1] := HW_NCPU; len := sizeof(t); fpsysctl(pchar(@mib), 2, @t, @len, Nil, 0); Result:=t; end; {$ELSEIF defined(linux)} begin Result:=sysconf(_SC_NPROCESSORS_ONLN); end; {$ELSE} begin Result:=1; end; {$ENDIF} procedure CallLocalProc(AProc, Frame: Pointer; Param1: PtrInt; Param2, Param3: Pointer); inline; type PointerLocal = procedure(_EBP: Pointer; Param1: PtrInt; Param2, Param3: Pointer); begin PointerLocal(AProc)(Frame, Param1, Param2, Param3); end; end. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/multithreadprocs/mtprocs.pas���������������������������������������������0000664�0001750�0001750�00000064133�12573027524�022475� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ Unit for light weight threads. This file is part of the Free Pascal run time library. Copyright (C) 2008 Mattias Gaertner mattias@freepascal.org See the file COPYING.FPC, included in this distribution, for details about the copyright. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **********************************************************************} { Abstract: Light weight threads. This unit provides methods to easily run a procedure/method with several threads at once. } unit MTProcs; {$mode objfpc}{$H+} {$inline on} interface uses Classes, SysUtils, MTPCPU; type TProcThreadGroup = class; TProcThreadPool = class; TProcThread = class; { TMultiThreadProcItem } TMTPThreadState = ( mtptsNone, mtptsActive, mtptsWaitingForIndex, mtptsWaitingFailed, mtptsInactive, mtptsTerminated ); TMultiThreadProcItem = class private FGroup: TProcThreadGroup; FIndex: PtrInt; FThread: TProcThread; FWaitingForIndexEnd: PtrInt; FWaitingForIndexStart: PtrInt; fWaitForPool: PRTLEvent; FState: TMTPThreadState; public destructor Destroy; override; function WaitForIndexRange(StartIndex, EndIndex: PtrInt): boolean; function WaitForIndex(Index: PtrInt): boolean; inline; procedure CalcBlock(Index, BlockSize, LoopLength: PtrInt; out BlockStart, BlockEnd: PtrInt); inline; property Index: PtrInt read FIndex; property Group: TProcThreadGroup read FGroup; property WaitingForIndexStart: PtrInt read FWaitingForIndexStart; property WaitingForIndexEnd: PtrInt read FWaitingForIndexEnd; property Thread: TProcThread read FThread; end; { TProcThread } TMTPThreadList = ( mtptlPool, mtptlGroup ); TProcThread = class(TThread) private FItem: TMultiThreadProcItem; FNext, FPrev: array[TMTPThreadList] of TProcThread; procedure AddToList(var First: TProcThread; ListType: TMTPThreadList); inline; procedure RemoveFromList(var First: TProcThread; ListType: TMTPThreadList); inline; procedure Terminating(aPool: TProcThreadPool; E: Exception); public constructor Create; destructor Destroy; override; procedure Execute; override; property Item: TMultiThreadProcItem read FItem; end; TMTMethod = procedure(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem) of object; TMTProcedure = procedure(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); { TProcThreadGroup Each task creates a new group of threads. A group can either need more threads or it has finished and waits for its threads to end. The thread that created the group is not in the list FFirstThread. } TMTPGroupState = ( mtpgsNone, mtpgsNeedThreads, // the groups waiting for more threads to help mtpgsFinishing, // the groups waiting for its threads to finish mtpgsException // there was an exception => close asap ); TProcThreadGroup = class private FEndIndex: PtrInt; FException: Exception; FFirstRunningIndex: PtrInt; FFirstThread: TProcThread; FLastRunningIndex: PtrInt; FMaxThreads: PtrInt; FNext, FPrev: TProcThreadGroup; FPool: TProcThreadPool; FStarterItem: TMultiThreadProcItem; FStartIndex: PtrInt; FState: TMTPGroupState; FTaskData: Pointer; FTaskFrame: Pointer; FTaskMethod: TMTMethod; FTaskProcedure: TMTProcedure; FThreadCount: PtrInt; procedure AddToList(var First: TProcThreadGroup; ListType: TMTPGroupState); inline; procedure RemoveFromList(var First: TProcThreadGroup); inline; function NeedMoreThreads: boolean; inline; procedure IncreaseLastRunningIndex(Item: TMultiThreadProcItem); procedure AddThread(AThread: TProcThread); procedure RemoveThread(AThread: TProcThread); inline; procedure Run(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); inline; procedure IndexComplete(Index: PtrInt); procedure WakeThreadsWaitingForIndex; function HasFinishedIndex(aStartIndex, aEndIndex: PtrInt): boolean; procedure EnterExceptionState(E: Exception); public constructor Create; destructor Destroy; override; property Pool: TProcThreadPool read FPool; property StartIndex: PtrInt read FStartIndex; property EndIndex: PtrInt read FEndIndex; property FirstRunningIndex: PtrInt read FFirstRunningIndex; // first started property LastRunningIndex: PtrInt read FLastRunningIndex; // last started property TaskData: Pointer read FTaskData; property TaskMethod: TMTMethod read FTaskMethod; property TaskProcedure: TMTProcedure read FTaskProcedure; property TaskFrame: Pointer read FTaskFrame; property MaxThreads: PtrInt read FMaxThreads; property StarterItem: TMultiThreadProcItem read FStarterItem; end; { TLightWeightThreadPool Group 0 are the inactive threads } { TProcThreadPool } TProcThreadPool = class private FMaxThreadCount: PtrInt; FThreadCount: PtrInt; FFirstInactiveThread: TProcThread; FFirstActiveThread: TProcThread; FFirstTerminatedThread: TProcThread; FFirstGroupNeedThreads: TProcThreadGroup; FFirstGroupFinishing: TProcThreadGroup; FCritSection: TRTLCriticalSection; FDestroying: boolean; procedure SetMaxThreadCount(const AValue: PtrInt); procedure CleanTerminatedThreads; procedure DoParallelIntern(const AMethod: TMTMethod; const AProc: TMTProcedure; const AFrame: Pointer; StartIndex, EndIndex: PtrInt; Data: Pointer = nil; MaxThreads: PtrInt = 0); public // for debugging only: the critical section is public: procedure EnterPoolCriticalSection; inline; procedure LeavePoolCriticalSection; inline; public constructor Create; destructor Destroy; override; procedure DoParallel(const AMethod: TMTMethod; StartIndex, EndIndex: PtrInt; Data: Pointer = nil; MaxThreads: PtrInt = 0); inline; procedure DoParallel(const AProc: TMTProcedure; StartIndex, EndIndex: PtrInt; Data: Pointer = nil; MaxThreads: PtrInt = 0); inline; // experimental procedure DoParallelLocalProc(const LocalProc: Pointer; StartIndex, EndIndex: PtrInt; Data: Pointer = nil; MaxThreads: PtrInt = 0); // do not make this inline! // utility functions for loops: procedure CalcBlockSize(LoopLength: PtrInt; out BlockCount, BlockSize: PtrInt; MinBlockSize: PtrInt = 0); inline; public property MaxThreadCount: PtrInt read FMaxThreadCount write SetMaxThreadCount; property ThreadCount: PtrInt read FThreadCount; end; var ProcThreadPool: TProcThreadPool = nil; threadvar CurrentThread: TThread; // TProcThread sets this, you can set this for your own TThreads descendants implementation { TMultiThreadProcItem } destructor TMultiThreadProcItem.Destroy; begin if fWaitForPool<>nil then begin RTLeventdestroy(fWaitForPool); fWaitForPool:=nil; end; inherited Destroy; end; function TMultiThreadProcItem.WaitForIndexRange( StartIndex, EndIndex: PtrInt): boolean; var aPool: TProcThreadPool; begin //WriteLn('TLightWeightThreadItem.WaitForIndexRange START Index='+IntToStr(Index)+' StartIndex='+IntToStr(StartIndex)+' EndIndex='+IntToStr(EndIndex)); if (EndIndex>=Index) then exit(false); if EndIndex<StartIndex then exit(true); if Group=nil then exit(true); // a single threaded group has no group object // multi threaded group aPool:=Group.Pool; if aPool.FDestroying then exit(false); // no more wait allowed aPool.EnterPoolCriticalSection; try if Group.FState=mtpgsException then begin //WriteLn('TLightWeightThreadItem.WaitForIndexRange Index='+IntToStr(Index)+', Group closing because of error'); exit(false); end; if Group.HasFinishedIndex(StartIndex,EndIndex) then begin //WriteLn('TLightWeightThreadItem.WaitForIndexRange Index='+IntToStr(Index)+', range already finished'); exit(true); end; FState:=mtptsWaitingForIndex; FWaitingForIndexStart:=StartIndex; FWaitingForIndexEnd:=EndIndex; if fWaitForPool=nil then fWaitForPool:=RTLEventCreate; RTLeventResetEvent(fWaitForPool); finally aPool.LeavePoolCriticalSection; end; //WriteLn('TLightWeightThreadItem.WaitForIndexRange '+IntToStr(Index)+' waiting ... '); RTLeventWaitFor(fWaitForPool); Result:=FState=mtptsActive; FState:=mtptsActive; //WriteLn('TLightWeightThreadItem.WaitForIndexRange END '+IntToStr(Index)); end; function TMultiThreadProcItem.WaitForIndex(Index: PtrInt): boolean; inline; begin Result:=WaitForIndexRange(Index,Index); end; procedure TMultiThreadProcItem.CalcBlock(Index, BlockSize, LoopLength: PtrInt; out BlockStart, BlockEnd: PtrInt); begin BlockStart:=BlockSize*Index; BlockEnd:=BlockStart+BlockSize; if LoopLength<BlockEnd then BlockEnd:=LoopLength; dec(BlockEnd); end; { TProcThread } procedure TProcThread.AddToList(var First: TProcThread; ListType: TMTPThreadList); begin FNext[ListType]:=First; if FNext[ListType]<>nil then FNext[ListType].FPrev[ListType]:=Self; First:=Self; end; procedure TProcThread.RemoveFromList(var First: TProcThread; ListType: TMTPThreadList); begin if First=Self then First:=FNext[ListType]; if FNext[ListType]<>nil then FNext[ListType].FPrev[ListType]:=FPrev[ListType]; if FPrev[ListType]<>nil then FPrev[ListType].FNext[ListType]:=FNext[ListType]; FNext[ListType]:=nil; FPrev[ListType]:=nil; end; procedure TProcThread.Terminating(aPool: TProcThreadPool; E: Exception); begin aPool.EnterPoolCriticalSection; try // remove from group if Item.FGroup<>nil then begin // an exception occured Item.FGroup.EnterExceptionState(E); Item.FGroup.RemoveThread(Self); Item.FGroup:=nil; end; // move to pool's terminated threads case Item.FState of mtptsActive: RemoveFromList(aPool.FFirstActiveThread,mtptlPool); mtptsInactive: RemoveFromList(aPool.FFirstInactiveThread,mtptlPool); end; AddToList(aPool.FFirstTerminatedThread,mtptlPool); Item.FState:=mtptsTerminated; finally aPool.LeavePoolCriticalSection; end; end; constructor TProcThread.Create; begin inherited Create(true); fItem:=TMultiThreadProcItem.Create; fItem.fWaitForPool:=RTLEventCreate; fItem.FThread:=Self; end; destructor TProcThread.Destroy; begin FreeAndNil(FItem); inherited Destroy; end; procedure TProcThread.Execute; var aPool: TProcThreadPool; Group: TProcThreadGroup; ok: Boolean; E: Exception; begin MTProcs.CurrentThread:=Self; aPool:=Item.Group.Pool; ok:=false; try repeat // work Group:=Item.Group; Group.Run(Item.Index,Group.TaskData,Item); aPool.EnterPoolCriticalSection; try Group.IndexComplete(Item.Index); // find next work if Group.LastRunningIndex<Group.EndIndex then begin // next index of group Group.IncreaseLastRunningIndex(Item); end else begin // remove from group RemoveFromList(Group.FFirstThread,mtptlGroup); dec(Group.FThreadCount); Item.FGroup:=nil; Group:=nil; if aPool.FFirstGroupNeedThreads<>nil then begin // add to new group aPool.FFirstGroupNeedThreads.AddThread(Self); Group:=Item.Group; end else begin // mark inactive RemoveFromList(aPool.FFirstActiveThread,mtptlPool); AddToList(aPool.FFirstInactiveThread,mtptlPool); Item.FState:=mtptsInactive; RTLeventResetEvent(Item.fWaitForPool); end; end; finally aPool.LeavePoolCriticalSection; end; // wait for new work if Item.FState=mtptsInactive then RTLeventWaitFor(Item.fWaitForPool); until Item.Group=nil; ok:=true; except // stop the exception and store it E:=Exception(AcquireExceptionObject); Terminating(aPool,E); end; if ok then Terminating(aPool,nil); end; { TProcThreadGroup } procedure TProcThreadGroup.AddToList(var First: TProcThreadGroup; ListType: TMTPGroupState); begin FNext:=First; if FNext<>nil then FNext.FPrev:=Self; First:=Self; FState:=ListType; end; procedure TProcThreadGroup.RemoveFromList( var First: TProcThreadGroup); begin if First=Self then First:=FNext; if FNext<>nil then FNext.FPrev:=FPrev; if FPrev<>nil then FPrev.FNext:=FNext; FNext:=nil; FPrev:=nil; FState:=mtpgsNone; end; function TProcThreadGroup.NeedMoreThreads: boolean; begin Result:=(FLastRunningIndex<FEndIndex) and (FThreadCount<FMaxThreads) and (FState<>mtpgsException); end; procedure TProcThreadGroup.IncreaseLastRunningIndex(Item: TMultiThreadProcItem); begin inc(FLastRunningIndex); Item.FIndex:=FLastRunningIndex; if NeedMoreThreads then exit; if FState=mtpgsNeedThreads then begin RemoveFromList(Pool.FFirstGroupNeedThreads); AddToList(Pool.FFirstGroupFinishing,mtpgsFinishing); end; end; procedure TProcThreadGroup.AddThread(AThread: TProcThread); begin AThread.Item.FGroup:=Self; AThread.AddToList(FFirstThread,mtptlGroup); inc(FThreadCount); IncreaseLastRunningIndex(AThread.Item); end; procedure TProcThreadGroup.RemoveThread(AThread: TProcThread); begin AThread.RemoveFromList(FFirstThread,mtptlGroup); dec(FThreadCount); end; procedure TProcThreadGroup.Run(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); inline; begin if Assigned(FTaskFrame) then begin CallLocalProc(FTaskProcedure,FTaskFrame,Index,Data,Item) end else begin if Assigned(FTaskProcedure) then FTaskProcedure(Index,Data,Item) else FTaskMethod(Index,Data,Item) end; end; procedure TProcThreadGroup.IndexComplete(Index: PtrInt); var AThread: TProcThread; NewFirstRunningThread: PtrInt; begin // update FirstRunningIndex NewFirstRunningThread:=FStarterItem.Index; AThread:=FFirstThread; while AThread<>nil do begin if (NewFirstRunningThread>aThread.Item.Index) and (aThread.Item.Index<>Index) then NewFirstRunningThread:=aThread.Item.Index; aThread:=aThread.FNext[mtptlGroup]; end; FFirstRunningIndex:=NewFirstRunningThread; // wake up threads (Note: do this even if FFirstRunningIndex has not changed) WakeThreadsWaitingForIndex; end; procedure TProcThreadGroup.WakeThreadsWaitingForIndex; var aThread: TProcThread; begin if FState<>mtpgsException then begin // wake up waiting threads aThread:=FFirstThread; while aThread<>nil do begin if (aThread.Item.FState=mtptsWaitingForIndex) and HasFinishedIndex(aThread.Item.WaitingForIndexStart, aThread.Item.WaitingForIndexEnd) then begin // wake up the thread aThread.Item.FState:=mtptsActive; RTLeventSetEvent(aThread.Item.fWaitForPool); end; aThread:=aThread.FNext[mtptlGroup]; end; if (FStarterItem.FState=mtptsWaitingForIndex) and HasFinishedIndex(FStarterItem.WaitingForIndexStart,FStarterItem.WaitingForIndexEnd) then begin // wake up the starter thread of this group FStarterItem.FState:=mtptsActive; RTLeventSetEvent(FStarterItem.fWaitForPool); end; end else begin // end group: wake up waiting threads aThread:=FFirstThread; while aThread<>nil do begin if (aThread.Item.FState=mtptsWaitingForIndex) then begin // end group: wake up the thread aThread.Item.FState:=mtptsWaitingFailed; RTLeventSetEvent(aThread.Item.fWaitForPool); end; aThread:=aThread.FNext[mtptlGroup]; end; if (FStarterItem.FState=mtptsWaitingForIndex) then begin // end group: wake up the starter thread of this group FStarterItem.FState:=mtptsWaitingFailed; RTLeventSetEvent(FStarterItem.fWaitForPool); end; end; end; function TProcThreadGroup.HasFinishedIndex( aStartIndex, aEndIndex: PtrInt): boolean; var AThread: TProcThread; begin // test the finished range if FFirstRunningIndex>aEndIndex then exit(true); // test the unfinished range if FLastRunningIndex<aEndIndex then exit(false); // test the active range AThread:=FFirstThread; while AThread<>nil do begin if (AThread.Item.Index>=aStartIndex) and (AThread.Item.Index<=aEndIndex) then exit(false); AThread:=AThread.FNext[mtptlGroup]; end; if (FStarterItem.Index>=aStartIndex) and (FStarterItem.Index<=aEndIndex) then exit(false); Result:=true; end; procedure TProcThreadGroup.EnterExceptionState(E: Exception); begin if FState=mtpgsException then exit; case FState of mtpgsFinishing: RemoveFromList(Pool.FFirstGroupFinishing); mtpgsNeedThreads: RemoveFromList(Pool.FFirstGroupNeedThreads); end; FState:=mtpgsException; FException:=E; WakeThreadsWaitingForIndex; end; constructor TProcThreadGroup.Create; begin FStarterItem:=TMultiThreadProcItem.Create; FStarterItem.FGroup:=Self; end; destructor TProcThreadGroup.Destroy; begin FreeAndNil(FStarterItem); inherited Destroy; end; { TProcThreadPool } procedure TProcThreadPool.SetMaxThreadCount(const AValue: PtrInt); begin if FMaxThreadCount=AValue then exit; if AValue<1 then raise Exception.Create('TLightWeightThreadPool.SetMaxThreadCount'); FMaxThreadCount:=AValue; end; procedure TProcThreadPool.CleanTerminatedThreads; var AThread: TProcThread; begin while FFirstTerminatedThread<>nil do begin AThread:=FFirstTerminatedThread; AThread.RemoveFromList(FFirstTerminatedThread,mtptlPool); AThread.Free; end; end; constructor TProcThreadPool.Create; begin FMaxThreadCount:=GetSystemThreadCount; if FMaxThreadCount<1 then FMaxThreadCount:=1; InitCriticalSection(FCritSection); end; destructor TProcThreadPool.Destroy; procedure WakeWaitingStarterItems(Group: TProcThreadGroup); begin while Group<>nil do begin if Group.StarterItem.FState=mtptsWaitingForIndex then begin Group.StarterItem.FState:=mtptsWaitingFailed; RTLeventSetEvent(Group.StarterItem.fWaitForPool); end; Group:=Group.FNext; end; end; var AThread: TProcThread; begin FDestroying:=true; // wake up all waiting threads EnterPoolCriticalSection; try AThread:=FFirstActiveThread; while AThread<>nil do begin if aThread.Item.FState=mtptsWaitingForIndex then begin aThread.Item.FState:=mtptsWaitingFailed; RTLeventSetEvent(AThread.Item.fWaitForPool); end; AThread:=AThread.FNext[mtptlPool]; end; WakeWaitingStarterItems(FFirstGroupNeedThreads); WakeWaitingStarterItems(FFirstGroupFinishing); finally LeavePoolCriticalSection; end; // wait for all active threads to become inactive while FFirstActiveThread<>nil do Sleep(10); // wake up all inactive threads (without new work they will terminate) EnterPoolCriticalSection; try AThread:=FFirstInactiveThread; while AThread<>nil do begin RTLeventSetEvent(AThread.Item.fWaitForPool); AThread:=AThread.FNext[mtptlPool]; end; finally LeavePoolCriticalSection; end; // wait for all threads to terminate while FFirstInactiveThread<>nil do Sleep(10); // free threads CleanTerminatedThreads; DoneCriticalsection(FCritSection); inherited Destroy; end; procedure TProcThreadPool.EnterPoolCriticalSection; begin EnterCriticalsection(FCritSection); end; procedure TProcThreadPool.LeavePoolCriticalSection; begin LeaveCriticalsection(FCritSection); end; procedure TProcThreadPool.DoParallel(const AMethod: TMTMethod; StartIndex, EndIndex: PtrInt; Data: Pointer; MaxThreads: PtrInt); begin if not Assigned(AMethod) then exit; DoParallelIntern(AMethod,nil,nil,StartIndex,EndIndex,Data,MaxThreads); end; procedure TProcThreadPool.DoParallel(const AProc: TMTProcedure; StartIndex, EndIndex: PtrInt; Data: Pointer; MaxThreads: PtrInt); begin if not Assigned(AProc) then exit; DoParallelIntern(nil,AProc,nil,StartIndex,EndIndex,Data,MaxThreads); end; procedure TProcThreadPool.DoParallelLocalProc(const LocalProc: Pointer; StartIndex, EndIndex: PtrInt; Data: Pointer; MaxThreads: PtrInt); var Frame: Pointer; begin if not Assigned(LocalProc) then exit; Frame:=get_caller_frame(get_frame); DoParallelIntern(nil,TMTProcedure(LocalProc),Frame,StartIndex,EndIndex, Data,MaxThreads); end; procedure TProcThreadPool.CalcBlockSize(LoopLength: PtrInt; out BlockCount, BlockSize: PtrInt; MinBlockSize: PtrInt); begin if LoopLength<=0 then begin BlockCount:=0; BlockSize:=1; exit; end; // split work into equally sized blocks BlockCount:=ProcThreadPool.MaxThreadCount; BlockSize:=(LoopLength div BlockCount); if (BlockSize<MinBlockSize) then BlockSize:=MinBlockSize; BlockCount:=((LoopLength-1) div BlockSize)+1; end; procedure TProcThreadPool.DoParallelIntern(const AMethod: TMTMethod; const AProc: TMTProcedure; const AFrame: Pointer; StartIndex, EndIndex: PtrInt; Data: Pointer; MaxThreads: PtrInt); var Group: TProcThreadGroup; Index: PtrInt; AThread: TProcThread; NewThread: Boolean; Item: TMultiThreadProcItem; HelperThreadException: Exception; begin if (StartIndex>EndIndex) then exit; // nothing to do if FDestroying then raise Exception.Create('Pool destroyed'); if (MaxThreads>MaxThreadCount) or (MaxThreads<=0) then MaxThreads:=MaxThreadCount; if (StartIndex=EndIndex) or (MaxThreads<=1) then begin // single threaded Item:=TMultiThreadProcItem.Create; try for Index:=StartIndex to EndIndex do begin Item.FIndex:=Index; if Assigned(AFrame) then begin CallLocalProc(AProc,AFrame,Index,Data,Item) end else begin if Assigned(AProc) then AProc(Index,Data,Item) else AMethod(Index,Data,Item) end; end; finally Item.Free; end; exit; end; // create a new group Group:=TProcThreadGroup.Create; Group.FPool:=Self; Group.FTaskData:=Data; Group.FTaskMethod:=AMethod; Group.FTaskProcedure:=AProc; Group.FTaskFrame:=AFrame; Group.FStartIndex:=StartIndex; Group.FEndIndex:=EndIndex; Group.FFirstRunningIndex:=StartIndex; Group.FLastRunningIndex:=StartIndex; Group.FMaxThreads:=MaxThreads; Group.FThreadCount:=1; Group.FStarterItem.FState:=mtptsActive; Group.FStarterItem.FIndex:=StartIndex; HelperThreadException:=nil; try // start threads EnterPoolCriticalSection; try Group.AddToList(FFirstGroupNeedThreads,mtpgsNeedThreads); while Group.NeedMoreThreads do begin AThread:=FFirstInactiveThread; NewThread:=false; if AThread<>nil then begin AThread.RemoveFromList(FFirstInactiveThread,mtptlPool); end else if FThreadCount<FMaxThreadCount then begin AThread:=TProcThread.Create; if Assigned(AThread.FatalException) then raise AThread.FatalException; NewThread:=true; inc(FThreadCount); end else begin break; end; // add to Group Group.AddThread(AThread); // start thread AThread.AddToList(FFirstActiveThread,mtptlPool); AThread.Item.FState:=mtptsActive; if NewThread then {$IF defined(VER2_4_2) or defined(VER2_4_3)} AThread.Resume {$ELSE} AThread.Start {$ENDIF} else RTLeventSetEvent(AThread.Item.fWaitForPool); end; finally LeavePoolCriticalSection; end; // run until no more Index left Index:=StartIndex; repeat Group.FStarterItem.FIndex:=Index; Group.Run(Index,Data,Group.FStarterItem); EnterPoolCriticalSection; try Group.IndexComplete(Index); if (Group.FLastRunningIndex<Group.EndIndex) and (Group.FState<>mtpgsException) then begin inc(Group.FLastRunningIndex); Index:=Group.FLastRunningIndex; end else begin Index:=StartIndex; end; finally LeavePoolCriticalSection; end; until Index=StartIndex; finally // wait for Group to finish if Group.FFirstThread<>nil then begin EnterPoolCriticalSection; try Group.FStarterItem.FState:=mtptsInactive; Group.FStarterItem.fIndex:=EndIndex;// needed for Group.HasFinishedIndex // wake threads waiting for starter thread to finish if Group.FStarterItem.FState<>mtptsInactive then Group.EnterExceptionState(nil) else Group.WakeThreadsWaitingForIndex; finally LeavePoolCriticalSection; end; // waiting with exponential spin lock Index:=0; while Group.FFirstThread<>nil do begin sleep(Index); Index:=Index*2+1; if Index>30 then Index:=30; end; end; // remove group from pool EnterPoolCriticalSection; try case Group.FState of mtpgsNeedThreads: Group.RemoveFromList(FFirstGroupNeedThreads); mtpgsFinishing: Group.RemoveFromList(FFirstGroupFinishing); end; finally LeavePoolCriticalSection; end; HelperThreadException:=Group.FException; Group.Free; // free terminated threads (terminated, because of exceptions) CleanTerminatedThreads; end; // if the exception occured in a helper thread raise it now if HelperThreadException<>nil then raise HelperThreadException; end; initialization ProcThreadPool:=TProcThreadPool.Create; CurrentThread:=nil; finalization ProcThreadPool.Free; ProcThreadPool:=nil; end. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/multithreadprocs/multithreadprocslaz.lpk���������������������������������0000664�0001750�0001750�00000002766�12573027524�025115� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0"?> <CONFIG> <Package Version="4"> <Name Value="MultiThreadProcsLaz"/> <Author Value="Mattias Gaertner mattias@freepascal.org"/> <CompilerOptions> <Version Value="10"/> <SearchPaths> <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> </SearchPaths> <Other> <CompilerMessages> <UseMsgFile Value="True"/> </CompilerMessages> <CompilerPath Value="$(CompPath)"/> </Other> </CompilerOptions> <Description Value="Running procedures and methods parallel via a thread pool."/> <License Value="modified LGPL2"/> <Version Major="1" Minor="2" Release="1"/> <Files Count="3"> <Item1> <Filename Value="mtprocs.pas"/> <UnitName Value="MTProcs"/> </Item1> <Item2> <Filename Value="mtputils.pas"/> <UnitName Value="MTPUtils"/> </Item2> <Item3> <Filename Value="mtpcpu.pas"/> <UnitName Value="MTPCPU"/> </Item3> </Files> <Type Value="RunAndDesignTime"/> <RequiredPkgs Count="1"> <Item1> <PackageName Value="FCL"/> <MinVersion Major="1" Valid="True"/> </Item1> </RequiredPkgs> <UsageOptions> <CustomOptions Value="-dUseCThreads"/> <UnitPath Value="$(PkgOutDir)"/> </UsageOptions> <PublishOptions> <Version Value="2"/> <IgnoreBinaries Value="False"/> </PublishOptions> </Package> </CONFIG> ����������doublecmd-0.8.2/components/multithreadprocs/mtputils.pas��������������������������������������������0000664�0001750�0001750�00000014116�12573027524�022663� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ Utilities using light weight threads. This file is part of the Free Pascal run time library. Copyright (C) 2008 Mattias Gaertner mattias@freepascal.org See the file COPYING.FPC, included in this distribution, for details about the copyright. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **********************************************************************} { Abstract: Utility functions using mtprocs. For example a parallel sort. } unit MTPUtils; {$mode objfpc}{$H+} interface uses Classes, SysUtils, MTProcs; type TSortPartEvent = procedure(aList: PPointer; aCount: PtrInt); { TParallelSortPointerList } TParallelSortPointerList = class protected fBlockSize: PtrInt; fBlockCntPowOf2Offset: PtrInt; FMergeBuffer: PPointer; procedure MTPSort(Index: PtrInt; {%H-}Data: Pointer; Item: TMultiThreadProcItem); public List: PPointer; Count: PtrInt; Compare: TListSortCompare; BlockCnt: PtrInt; OnSortPart: TSortPartEvent; constructor Create(aList: PPointer; aCount: PtrInt; const aCompare: TListSortCompare; MaxThreadCount: integer = 0); procedure Sort; end; { Sort a list in parallel using merge sort. You must provide a compare function. You can provide your own sort function for the blocks which are sorted in a single thread, for example a normal quicksort. } procedure ParallelSortFPList(List: TFPList; const Compare: TListSortCompare; MaxThreadCount: integer = 0; const OnSortPart: TSortPartEvent = nil); implementation procedure ParallelSortFPList(List: TFPList; const Compare: TListSortCompare; MaxThreadCount: integer; const OnSortPart: TSortPartEvent); var Sorter: TParallelSortPointerList; begin if List.Count<=1 then exit; Sorter:=TParallelSortPointerList.Create(@List.List[0],List.Count,Compare, MaxThreadCount); try Sorter.OnSortPart:=OnSortPart; Sorter.Sort; finally Sorter.Free; end; end; { TParallelSortPointerList } procedure TParallelSortPointerList.MTPSort(Index: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); procedure MergeSort(L, M, R: PtrInt; Recursive: boolean); var Src1: PtrInt; Src2: PtrInt; Dest1: PtrInt; begin if R-L<=1 then begin // sort lists of 1 and 2 items directly if L<R then begin if Compare(List[L],List[R])>0 then begin FMergeBuffer[L]:=List[L]; List[L]:=List[R]; List[R]:=FMergeBuffer[L]; end; end; exit; end; // sort recursively if Recursive then begin MergeSort(L,(L+M) div 2,M-1,true); MergeSort(M,(M+R+1) div 2,R,true); end; // merge both blocks Src1:=L; Src2:=M; Dest1:=L; repeat if (Src1<M) and ((Src2>R) or (Compare(List[Src1],List[Src2])<=0)) then begin FMergeBuffer[Dest1]:=List[Src1]; inc(Dest1); inc(Src1); end else if (Src2<=R) then begin FMergeBuffer[Dest1]:=List[Src2]; inc(Dest1); inc(Src2); end else break; until false; // write the mergebuffer back Src1:=L; Dest1:=l; while Src1<=R do begin List[Dest1]:=FMergeBuffer[Src1]; inc(Src1); inc(Dest1); end; end; var L, M, R: PtrInt; i: integer; NormIndex: Integer; Range: integer; MergeIndex: Integer; begin L:=fBlockSize*Index; R:=L+fBlockSize-1; if R>=Count then R:=Count-1; // last block //WriteLn('TParallelSortPointerList.LWTSort Index=',Index,' sort block: ',L,' ',(L+R+1) div 2,' ',R); if Assigned(OnSortPart) then OnSortPart(@List[L],R-L+1) else MergeSort(L,(L+R+1) div 2,R,true); // merge // 0 1 2 3 4 5 6 7 // \/ \/ \/ \/ // \/ \/ // \/ // For example: BlockCnt = 5 => Index in 0..4 // fBlockCntPowOf2Offset = 3 (=8-5) // NormIndex = Index + 3 => NormIndex in 3..7 NormIndex:=Index+fBlockCntPowOf2Offset; i:=0; repeat Range:=1 shl i; if NormIndex and Range=0 then break; // merge left and right block(s) MergeIndex:=NormIndex-Range-fBlockCntPowOf2Offset; if (MergeIndex+Range-1>=0) then begin // wait until left blocks have finished //WriteLn('TParallelSortPointerList.LWTSort Index=',Index,' wait for block ',MergeIndex); if (MergeIndex>=0) and (not Item.WaitForIndex(MergeIndex)) then exit; // compute left and right block bounds M:=L; L:=(MergeIndex-Range+1)*fBlockSize; if L<0 then L:=0; //WriteLn('TParallelSortPointerList.LWTSort Index=',Index,' merge blocks ',L,' ',M,' ',R); MergeSort(L,M,R,false); end; inc(i); until false; //WriteLn('TParallelSortPointerList.LWTSort END Index='+IntToStr(Index)); end; constructor TParallelSortPointerList.Create(aList: PPointer; aCount: PtrInt; const aCompare: TListSortCompare; MaxThreadCount: integer); begin List:=aList; Count:=aCount; Compare:=aCompare; BlockCnt:=Count div 100; // at least 100 items per thread if BlockCnt>ProcThreadPool.MaxThreadCount then BlockCnt:=ProcThreadPool.MaxThreadCount; if (MaxThreadCount>0) and (BlockCnt>MaxThreadCount) then BlockCnt:=MaxThreadCount; if BlockCnt<1 then BlockCnt:=1; end; procedure TParallelSortPointerList.Sort; begin if (Count<=1) then exit; fBlockSize:=(Count+BlockCnt-1) div BlockCnt; fBlockCntPowOf2Offset:=1; while fBlockCntPowOf2Offset<BlockCnt do fBlockCntPowOf2Offset:=fBlockCntPowOf2Offset*2; fBlockCntPowOf2Offset:=fBlockCntPowOf2Offset-BlockCnt; //WriteLn('TParallelSortPointerList.Sort BlockCnt=',BlockCnt,' fBlockSize=',fBlockSize,' fBlockCntPowOf2Offset=',fBlockCntPowOf2Offset); GetMem(FMergeBuffer,SizeOf(Pointer)*Count); try ProcThreadPool.DoParallel(@MTPSort,0,BlockCnt-1); finally FreeMem(FMergeBuffer); FMergeBuffer:=nil; end; end; end. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/����������������������������������������������������������������0000775�0001750�0001750�00000000000�13244011205�016512� 5����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/dcp.pas���������������������������������������������������������0000664�0001750�0001750�00000000772�12014201074�017772� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ This file was automatically created by Lazarus. do not edit! This source is only used to compile and install the package. } unit dcp; interface uses DCPbase64, DCPblockciphers, DCPconst, DCPcrypt2, DCPblowfish, DCPcast128, DCPcast256, DCPdes, DCPgost, DCPice, DCPidea, DCPmars, DCPmisty1, DCPrc2, DCPrc4, DCPrc5, DCPrc6, DCPrijndael, DCPserpent, DCPtea, DCPtwofish, DCPhaval, DCPmd4, DCPmd5, DCPripemd128, DCPripemd160, DCPsha1, DCPsha256, DCPsha512, DCPtiger; implementation end. ������doublecmd-0.8.2/components/dcpcrypt/CHANGELOG.txt���������������������������������������������������0000664�0001750�0001750�00000001415�12014201074�020542� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Change in v2.0.4.1 by Graeme Geldenhuys (2010) * Version number bumped to v2.0.4.1 * More fixes for 64-bit support * Removed a lot of compiler warnings - tested with FPC 2.4.1 Change in v2.0.4 by Graeme Geldenhuys (2009) * Version number bumped to v2.0.4 * Split the Lazarus package into two separate packages - one is runtime only package and GUI toolkit independent. - one is Lazarus design-time only package which installs components in component palette. * Updated code to be compilable with FPC 2.4.0-rc1 * Updated code to be compilable with 64-bit FPC 2.4.0-rc1. - Tested under 32-bit & 64-bit Linux on x86 systems. Changes since DCPCrypt v2 Beta 3: * Ported DCPCrypt to Lazarus by Barko in 2006 -=-=-=-=-=-=-=-=-=-=-=-=-=-=- ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/Ciphers/��������������������������������������������������������0000775�0001750�0001750�00000000000�13244011205�020107� 5����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/Ciphers/DCPrijndael.inc�����������������������������������������0000664�0001750�0001750�00000177367�13157542637�022773� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������const MAXBC= 8; MAXKC= 8; S: array[0..255] of byte= ( 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22); T1: array[0..255,0..3] of byte= ( ($c6,$63,$63,$a5), ($f8,$7c,$7c,$84), ($ee,$77,$77,$99), ($f6,$7b,$7b,$8d), ($ff,$f2,$f2,$0d), ($d6,$6b,$6b,$bd), ($de,$6f,$6f,$b1), ($91,$c5,$c5,$54), ($60,$30,$30,$50), ($02,$01,$01,$03), ($ce,$67,$67,$a9), ($56,$2b,$2b,$7d), ($e7,$fe,$fe,$19), ($b5,$d7,$d7,$62), ($4d,$ab,$ab,$e6), ($ec,$76,$76,$9a), ($8f,$ca,$ca,$45), ($1f,$82,$82,$9d), ($89,$c9,$c9,$40), ($fa,$7d,$7d,$87), ($ef,$fa,$fa,$15), ($b2,$59,$59,$eb), ($8e,$47,$47,$c9), ($fb,$f0,$f0,$0b), ($41,$ad,$ad,$ec), ($b3,$d4,$d4,$67), ($5f,$a2,$a2,$fd), ($45,$af,$af,$ea), ($23,$9c,$9c,$bf), ($53,$a4,$a4,$f7), ($e4,$72,$72,$96), ($9b,$c0,$c0,$5b), ($75,$b7,$b7,$c2), ($e1,$fd,$fd,$1c), ($3d,$93,$93,$ae), ($4c,$26,$26,$6a), ($6c,$36,$36,$5a), ($7e,$3f,$3f,$41), ($f5,$f7,$f7,$02), ($83,$cc,$cc,$4f), ($68,$34,$34,$5c), ($51,$a5,$a5,$f4), ($d1,$e5,$e5,$34), ($f9,$f1,$f1,$08), ($e2,$71,$71,$93), ($ab,$d8,$d8,$73), ($62,$31,$31,$53), ($2a,$15,$15,$3f), ($08,$04,$04,$0c), ($95,$c7,$c7,$52), ($46,$23,$23,$65), ($9d,$c3,$c3,$5e), ($30,$18,$18,$28), ($37,$96,$96,$a1), ($0a,$05,$05,$0f), ($2f,$9a,$9a,$b5), ($0e,$07,$07,$09), ($24,$12,$12,$36), ($1b,$80,$80,$9b), ($df,$e2,$e2,$3d), ($cd,$eb,$eb,$26), ($4e,$27,$27,$69), ($7f,$b2,$b2,$cd), ($ea,$75,$75,$9f), ($12,$09,$09,$1b), ($1d,$83,$83,$9e), ($58,$2c,$2c,$74), ($34,$1a,$1a,$2e), ($36,$1b,$1b,$2d), ($dc,$6e,$6e,$b2), ($b4,$5a,$5a,$ee), ($5b,$a0,$a0,$fb), ($a4,$52,$52,$f6), ($76,$3b,$3b,$4d), ($b7,$d6,$d6,$61), ($7d,$b3,$b3,$ce), ($52,$29,$29,$7b), ($dd,$e3,$e3,$3e), ($5e,$2f,$2f,$71), ($13,$84,$84,$97), ($a6,$53,$53,$f5), ($b9,$d1,$d1,$68), ($00,$00,$00,$00), ($c1,$ed,$ed,$2c), ($40,$20,$20,$60), ($e3,$fc,$fc,$1f), ($79,$b1,$b1,$c8), ($b6,$5b,$5b,$ed), ($d4,$6a,$6a,$be), ($8d,$cb,$cb,$46), ($67,$be,$be,$d9), ($72,$39,$39,$4b), ($94,$4a,$4a,$de), ($98,$4c,$4c,$d4), ($b0,$58,$58,$e8), ($85,$cf,$cf,$4a), ($bb,$d0,$d0,$6b), ($c5,$ef,$ef,$2a), ($4f,$aa,$aa,$e5), ($ed,$fb,$fb,$16), ($86,$43,$43,$c5), ($9a,$4d,$4d,$d7), ($66,$33,$33,$55), ($11,$85,$85,$94), ($8a,$45,$45,$cf), ($e9,$f9,$f9,$10), ($04,$02,$02,$06), ($fe,$7f,$7f,$81), ($a0,$50,$50,$f0), ($78,$3c,$3c,$44), ($25,$9f,$9f,$ba), ($4b,$a8,$a8,$e3), ($a2,$51,$51,$f3), ($5d,$a3,$a3,$fe), ($80,$40,$40,$c0), ($05,$8f,$8f,$8a), ($3f,$92,$92,$ad), ($21,$9d,$9d,$bc), ($70,$38,$38,$48), ($f1,$f5,$f5,$04), ($63,$bc,$bc,$df), ($77,$b6,$b6,$c1), ($af,$da,$da,$75), ($42,$21,$21,$63), ($20,$10,$10,$30), ($e5,$ff,$ff,$1a), ($fd,$f3,$f3,$0e), ($bf,$d2,$d2,$6d), ($81,$cd,$cd,$4c), ($18,$0c,$0c,$14), ($26,$13,$13,$35), ($c3,$ec,$ec,$2f), ($be,$5f,$5f,$e1), ($35,$97,$97,$a2), ($88,$44,$44,$cc), ($2e,$17,$17,$39), ($93,$c4,$c4,$57), ($55,$a7,$a7,$f2), ($fc,$7e,$7e,$82), ($7a,$3d,$3d,$47), ($c8,$64,$64,$ac), ($ba,$5d,$5d,$e7), ($32,$19,$19,$2b), ($e6,$73,$73,$95), ($c0,$60,$60,$a0), ($19,$81,$81,$98), ($9e,$4f,$4f,$d1), ($a3,$dc,$dc,$7f), ($44,$22,$22,$66), ($54,$2a,$2a,$7e), ($3b,$90,$90,$ab), ($0b,$88,$88,$83), ($8c,$46,$46,$ca), ($c7,$ee,$ee,$29), ($6b,$b8,$b8,$d3), ($28,$14,$14,$3c), ($a7,$de,$de,$79), ($bc,$5e,$5e,$e2), ($16,$0b,$0b,$1d), ($ad,$db,$db,$76), ($db,$e0,$e0,$3b), ($64,$32,$32,$56), ($74,$3a,$3a,$4e), ($14,$0a,$0a,$1e), ($92,$49,$49,$db), ($0c,$06,$06,$0a), ($48,$24,$24,$6c), ($b8,$5c,$5c,$e4), ($9f,$c2,$c2,$5d), ($bd,$d3,$d3,$6e), ($43,$ac,$ac,$ef), ($c4,$62,$62,$a6), ($39,$91,$91,$a8), ($31,$95,$95,$a4), ($d3,$e4,$e4,$37), ($f2,$79,$79,$8b), ($d5,$e7,$e7,$32), ($8b,$c8,$c8,$43), ($6e,$37,$37,$59), ($da,$6d,$6d,$b7), ($01,$8d,$8d,$8c), ($b1,$d5,$d5,$64), ($9c,$4e,$4e,$d2), ($49,$a9,$a9,$e0), ($d8,$6c,$6c,$b4), ($ac,$56,$56,$fa), ($f3,$f4,$f4,$07), ($cf,$ea,$ea,$25), ($ca,$65,$65,$af), ($f4,$7a,$7a,$8e), ($47,$ae,$ae,$e9), ($10,$08,$08,$18), ($6f,$ba,$ba,$d5), ($f0,$78,$78,$88), ($4a,$25,$25,$6f), ($5c,$2e,$2e,$72), ($38,$1c,$1c,$24), ($57,$a6,$a6,$f1), ($73,$b4,$b4,$c7), ($97,$c6,$c6,$51), ($cb,$e8,$e8,$23), ($a1,$dd,$dd,$7c), ($e8,$74,$74,$9c), ($3e,$1f,$1f,$21), ($96,$4b,$4b,$dd), ($61,$bd,$bd,$dc), ($0d,$8b,$8b,$86), ($0f,$8a,$8a,$85), ($e0,$70,$70,$90), ($7c,$3e,$3e,$42), ($71,$b5,$b5,$c4), ($cc,$66,$66,$aa), ($90,$48,$48,$d8), ($06,$03,$03,$05), ($f7,$f6,$f6,$01), ($1c,$0e,$0e,$12), ($c2,$61,$61,$a3), ($6a,$35,$35,$5f), ($ae,$57,$57,$f9), ($69,$b9,$b9,$d0), ($17,$86,$86,$91), ($99,$c1,$c1,$58), ($3a,$1d,$1d,$27), ($27,$9e,$9e,$b9), ($d9,$e1,$e1,$38), ($eb,$f8,$f8,$13), ($2b,$98,$98,$b3), ($22,$11,$11,$33), ($d2,$69,$69,$bb), ($a9,$d9,$d9,$70), ($07,$8e,$8e,$89), ($33,$94,$94,$a7), ($2d,$9b,$9b,$b6), ($3c,$1e,$1e,$22), ($15,$87,$87,$92), ($c9,$e9,$e9,$20), ($87,$ce,$ce,$49), ($aa,$55,$55,$ff), ($50,$28,$28,$78), ($a5,$df,$df,$7a), ($03,$8c,$8c,$8f), ($59,$a1,$a1,$f8), ($09,$89,$89,$80), ($1a,$0d,$0d,$17), ($65,$bf,$bf,$da), ($d7,$e6,$e6,$31), ($84,$42,$42,$c6), ($d0,$68,$68,$b8), ($82,$41,$41,$c3), ($29,$99,$99,$b0), ($5a,$2d,$2d,$77), ($1e,$0f,$0f,$11), ($7b,$b0,$b0,$cb), ($a8,$54,$54,$fc), ($6d,$bb,$bb,$d6), ($2c,$16,$16,$3a)); T2: array[0..255,0..3] of byte= ( ($a5,$c6,$63,$63), ($84,$f8,$7c,$7c), ($99,$ee,$77,$77), ($8d,$f6,$7b,$7b), ($0d,$ff,$f2,$f2), ($bd,$d6,$6b,$6b), ($b1,$de,$6f,$6f), ($54,$91,$c5,$c5), ($50,$60,$30,$30), ($03,$02,$01,$01), ($a9,$ce,$67,$67), ($7d,$56,$2b,$2b), ($19,$e7,$fe,$fe), ($62,$b5,$d7,$d7), ($e6,$4d,$ab,$ab), ($9a,$ec,$76,$76), ($45,$8f,$ca,$ca), ($9d,$1f,$82,$82), ($40,$89,$c9,$c9), ($87,$fa,$7d,$7d), ($15,$ef,$fa,$fa), ($eb,$b2,$59,$59), ($c9,$8e,$47,$47), ($0b,$fb,$f0,$f0), ($ec,$41,$ad,$ad), ($67,$b3,$d4,$d4), ($fd,$5f,$a2,$a2), ($ea,$45,$af,$af), ($bf,$23,$9c,$9c), ($f7,$53,$a4,$a4), ($96,$e4,$72,$72), ($5b,$9b,$c0,$c0), ($c2,$75,$b7,$b7), ($1c,$e1,$fd,$fd), ($ae,$3d,$93,$93), ($6a,$4c,$26,$26), ($5a,$6c,$36,$36), ($41,$7e,$3f,$3f), ($02,$f5,$f7,$f7), ($4f,$83,$cc,$cc), ($5c,$68,$34,$34), ($f4,$51,$a5,$a5), ($34,$d1,$e5,$e5), ($08,$f9,$f1,$f1), ($93,$e2,$71,$71), ($73,$ab,$d8,$d8), ($53,$62,$31,$31), ($3f,$2a,$15,$15), ($0c,$08,$04,$04), ($52,$95,$c7,$c7), ($65,$46,$23,$23), ($5e,$9d,$c3,$c3), ($28,$30,$18,$18), ($a1,$37,$96,$96), ($0f,$0a,$05,$05), ($b5,$2f,$9a,$9a), ($09,$0e,$07,$07), ($36,$24,$12,$12), ($9b,$1b,$80,$80), ($3d,$df,$e2,$e2), ($26,$cd,$eb,$eb), ($69,$4e,$27,$27), ($cd,$7f,$b2,$b2), ($9f,$ea,$75,$75), ($1b,$12,$09,$09), ($9e,$1d,$83,$83), ($74,$58,$2c,$2c), ($2e,$34,$1a,$1a), ($2d,$36,$1b,$1b), ($b2,$dc,$6e,$6e), ($ee,$b4,$5a,$5a), ($fb,$5b,$a0,$a0), ($f6,$a4,$52,$52), ($4d,$76,$3b,$3b), ($61,$b7,$d6,$d6), ($ce,$7d,$b3,$b3), ($7b,$52,$29,$29), ($3e,$dd,$e3,$e3), ($71,$5e,$2f,$2f), ($97,$13,$84,$84), ($f5,$a6,$53,$53), ($68,$b9,$d1,$d1), ($00,$00,$00,$00), ($2c,$c1,$ed,$ed), ($60,$40,$20,$20), ($1f,$e3,$fc,$fc), ($c8,$79,$b1,$b1), ($ed,$b6,$5b,$5b), ($be,$d4,$6a,$6a), ($46,$8d,$cb,$cb), ($d9,$67,$be,$be), ($4b,$72,$39,$39), ($de,$94,$4a,$4a), ($d4,$98,$4c,$4c), ($e8,$b0,$58,$58), ($4a,$85,$cf,$cf), ($6b,$bb,$d0,$d0), ($2a,$c5,$ef,$ef), ($e5,$4f,$aa,$aa), ($16,$ed,$fb,$fb), ($c5,$86,$43,$43), ($d7,$9a,$4d,$4d), ($55,$66,$33,$33), ($94,$11,$85,$85), ($cf,$8a,$45,$45), ($10,$e9,$f9,$f9), ($06,$04,$02,$02), ($81,$fe,$7f,$7f), ($f0,$a0,$50,$50), ($44,$78,$3c,$3c), ($ba,$25,$9f,$9f), ($e3,$4b,$a8,$a8), ($f3,$a2,$51,$51), ($fe,$5d,$a3,$a3), ($c0,$80,$40,$40), ($8a,$05,$8f,$8f), ($ad,$3f,$92,$92), ($bc,$21,$9d,$9d), ($48,$70,$38,$38), ($04,$f1,$f5,$f5), ($df,$63,$bc,$bc), ($c1,$77,$b6,$b6), ($75,$af,$da,$da), ($63,$42,$21,$21), ($30,$20,$10,$10), ($1a,$e5,$ff,$ff), ($0e,$fd,$f3,$f3), ($6d,$bf,$d2,$d2), ($4c,$81,$cd,$cd), ($14,$18,$0c,$0c), ($35,$26,$13,$13), ($2f,$c3,$ec,$ec), ($e1,$be,$5f,$5f), ($a2,$35,$97,$97), ($cc,$88,$44,$44), ($39,$2e,$17,$17), ($57,$93,$c4,$c4), ($f2,$55,$a7,$a7), ($82,$fc,$7e,$7e), ($47,$7a,$3d,$3d), ($ac,$c8,$64,$64), ($e7,$ba,$5d,$5d), ($2b,$32,$19,$19), ($95,$e6,$73,$73), ($a0,$c0,$60,$60), ($98,$19,$81,$81), ($d1,$9e,$4f,$4f), ($7f,$a3,$dc,$dc), ($66,$44,$22,$22), ($7e,$54,$2a,$2a), ($ab,$3b,$90,$90), ($83,$0b,$88,$88), ($ca,$8c,$46,$46), ($29,$c7,$ee,$ee), ($d3,$6b,$b8,$b8), ($3c,$28,$14,$14), ($79,$a7,$de,$de), ($e2,$bc,$5e,$5e), ($1d,$16,$0b,$0b), ($76,$ad,$db,$db), ($3b,$db,$e0,$e0), ($56,$64,$32,$32), ($4e,$74,$3a,$3a), ($1e,$14,$0a,$0a), ($db,$92,$49,$49), ($0a,$0c,$06,$06), ($6c,$48,$24,$24), ($e4,$b8,$5c,$5c), ($5d,$9f,$c2,$c2), ($6e,$bd,$d3,$d3), ($ef,$43,$ac,$ac), ($a6,$c4,$62,$62), ($a8,$39,$91,$91), ($a4,$31,$95,$95), ($37,$d3,$e4,$e4), ($8b,$f2,$79,$79), ($32,$d5,$e7,$e7), ($43,$8b,$c8,$c8), ($59,$6e,$37,$37), ($b7,$da,$6d,$6d), ($8c,$01,$8d,$8d), ($64,$b1,$d5,$d5), ($d2,$9c,$4e,$4e), ($e0,$49,$a9,$a9), ($b4,$d8,$6c,$6c), ($fa,$ac,$56,$56), ($07,$f3,$f4,$f4), ($25,$cf,$ea,$ea), ($af,$ca,$65,$65), ($8e,$f4,$7a,$7a), ($e9,$47,$ae,$ae), ($18,$10,$08,$08), ($d5,$6f,$ba,$ba), ($88,$f0,$78,$78), ($6f,$4a,$25,$25), ($72,$5c,$2e,$2e), ($24,$38,$1c,$1c), ($f1,$57,$a6,$a6), ($c7,$73,$b4,$b4), ($51,$97,$c6,$c6), ($23,$cb,$e8,$e8), ($7c,$a1,$dd,$dd), ($9c,$e8,$74,$74), ($21,$3e,$1f,$1f), ($dd,$96,$4b,$4b), ($dc,$61,$bd,$bd), ($86,$0d,$8b,$8b), ($85,$0f,$8a,$8a), ($90,$e0,$70,$70), ($42,$7c,$3e,$3e), ($c4,$71,$b5,$b5), ($aa,$cc,$66,$66), ($d8,$90,$48,$48), ($05,$06,$03,$03), ($01,$f7,$f6,$f6), ($12,$1c,$0e,$0e), ($a3,$c2,$61,$61), ($5f,$6a,$35,$35), ($f9,$ae,$57,$57), ($d0,$69,$b9,$b9), ($91,$17,$86,$86), ($58,$99,$c1,$c1), ($27,$3a,$1d,$1d), ($b9,$27,$9e,$9e), ($38,$d9,$e1,$e1), ($13,$eb,$f8,$f8), ($b3,$2b,$98,$98), ($33,$22,$11,$11), ($bb,$d2,$69,$69), ($70,$a9,$d9,$d9), ($89,$07,$8e,$8e), ($a7,$33,$94,$94), ($b6,$2d,$9b,$9b), ($22,$3c,$1e,$1e), ($92,$15,$87,$87), ($20,$c9,$e9,$e9), ($49,$87,$ce,$ce), ($ff,$aa,$55,$55), ($78,$50,$28,$28), ($7a,$a5,$df,$df), ($8f,$03,$8c,$8c), ($f8,$59,$a1,$a1), ($80,$09,$89,$89), ($17,$1a,$0d,$0d), ($da,$65,$bf,$bf), ($31,$d7,$e6,$e6), ($c6,$84,$42,$42), ($b8,$d0,$68,$68), ($c3,$82,$41,$41), ($b0,$29,$99,$99), ($77,$5a,$2d,$2d), ($11,$1e,$0f,$0f), ($cb,$7b,$b0,$b0), ($fc,$a8,$54,$54), ($d6,$6d,$bb,$bb), ($3a,$2c,$16,$16)); T3: array[0..255,0..3] of byte= ( ($63,$a5,$c6,$63), ($7c,$84,$f8,$7c), ($77,$99,$ee,$77), ($7b,$8d,$f6,$7b), ($f2,$0d,$ff,$f2), ($6b,$bd,$d6,$6b), ($6f,$b1,$de,$6f), ($c5,$54,$91,$c5), ($30,$50,$60,$30), ($01,$03,$02,$01), ($67,$a9,$ce,$67), ($2b,$7d,$56,$2b), ($fe,$19,$e7,$fe), ($d7,$62,$b5,$d7), ($ab,$e6,$4d,$ab), ($76,$9a,$ec,$76), ($ca,$45,$8f,$ca), ($82,$9d,$1f,$82), ($c9,$40,$89,$c9), ($7d,$87,$fa,$7d), ($fa,$15,$ef,$fa), ($59,$eb,$b2,$59), ($47,$c9,$8e,$47), ($f0,$0b,$fb,$f0), ($ad,$ec,$41,$ad), ($d4,$67,$b3,$d4), ($a2,$fd,$5f,$a2), ($af,$ea,$45,$af), ($9c,$bf,$23,$9c), ($a4,$f7,$53,$a4), ($72,$96,$e4,$72), ($c0,$5b,$9b,$c0), ($b7,$c2,$75,$b7), ($fd,$1c,$e1,$fd), ($93,$ae,$3d,$93), ($26,$6a,$4c,$26), ($36,$5a,$6c,$36), ($3f,$41,$7e,$3f), ($f7,$02,$f5,$f7), ($cc,$4f,$83,$cc), ($34,$5c,$68,$34), ($a5,$f4,$51,$a5), ($e5,$34,$d1,$e5), ($f1,$08,$f9,$f1), ($71,$93,$e2,$71), ($d8,$73,$ab,$d8), ($31,$53,$62,$31), ($15,$3f,$2a,$15), ($04,$0c,$08,$04), ($c7,$52,$95,$c7), ($23,$65,$46,$23), ($c3,$5e,$9d,$c3), ($18,$28,$30,$18), ($96,$a1,$37,$96), ($05,$0f,$0a,$05), ($9a,$b5,$2f,$9a), ($07,$09,$0e,$07), ($12,$36,$24,$12), ($80,$9b,$1b,$80), ($e2,$3d,$df,$e2), ($eb,$26,$cd,$eb), ($27,$69,$4e,$27), ($b2,$cd,$7f,$b2), ($75,$9f,$ea,$75), ($09,$1b,$12,$09), ($83,$9e,$1d,$83), ($2c,$74,$58,$2c), ($1a,$2e,$34,$1a), ($1b,$2d,$36,$1b), ($6e,$b2,$dc,$6e), ($5a,$ee,$b4,$5a), ($a0,$fb,$5b,$a0), ($52,$f6,$a4,$52), ($3b,$4d,$76,$3b), ($d6,$61,$b7,$d6), ($b3,$ce,$7d,$b3), ($29,$7b,$52,$29), ($e3,$3e,$dd,$e3), ($2f,$71,$5e,$2f), ($84,$97,$13,$84), ($53,$f5,$a6,$53), ($d1,$68,$b9,$d1), ($00,$00,$00,$00), ($ed,$2c,$c1,$ed), ($20,$60,$40,$20), ($fc,$1f,$e3,$fc), ($b1,$c8,$79,$b1), ($5b,$ed,$b6,$5b), ($6a,$be,$d4,$6a), ($cb,$46,$8d,$cb), ($be,$d9,$67,$be), ($39,$4b,$72,$39), ($4a,$de,$94,$4a), ($4c,$d4,$98,$4c), ($58,$e8,$b0,$58), ($cf,$4a,$85,$cf), ($d0,$6b,$bb,$d0), ($ef,$2a,$c5,$ef), ($aa,$e5,$4f,$aa), ($fb,$16,$ed,$fb), ($43,$c5,$86,$43), ($4d,$d7,$9a,$4d), ($33,$55,$66,$33), ($85,$94,$11,$85), ($45,$cf,$8a,$45), ($f9,$10,$e9,$f9), ($02,$06,$04,$02), ($7f,$81,$fe,$7f), ($50,$f0,$a0,$50), ($3c,$44,$78,$3c), ($9f,$ba,$25,$9f), ($a8,$e3,$4b,$a8), ($51,$f3,$a2,$51), ($a3,$fe,$5d,$a3), ($40,$c0,$80,$40), ($8f,$8a,$05,$8f), ($92,$ad,$3f,$92), ($9d,$bc,$21,$9d), ($38,$48,$70,$38), ($f5,$04,$f1,$f5), ($bc,$df,$63,$bc), ($b6,$c1,$77,$b6), ($da,$75,$af,$da), ($21,$63,$42,$21), ($10,$30,$20,$10), ($ff,$1a,$e5,$ff), ($f3,$0e,$fd,$f3), ($d2,$6d,$bf,$d2), ($cd,$4c,$81,$cd), ($0c,$14,$18,$0c), ($13,$35,$26,$13), ($ec,$2f,$c3,$ec), ($5f,$e1,$be,$5f), ($97,$a2,$35,$97), ($44,$cc,$88,$44), ($17,$39,$2e,$17), ($c4,$57,$93,$c4), ($a7,$f2,$55,$a7), ($7e,$82,$fc,$7e), ($3d,$47,$7a,$3d), ($64,$ac,$c8,$64), ($5d,$e7,$ba,$5d), ($19,$2b,$32,$19), ($73,$95,$e6,$73), ($60,$a0,$c0,$60), ($81,$98,$19,$81), ($4f,$d1,$9e,$4f), ($dc,$7f,$a3,$dc), ($22,$66,$44,$22), ($2a,$7e,$54,$2a), ($90,$ab,$3b,$90), ($88,$83,$0b,$88), ($46,$ca,$8c,$46), ($ee,$29,$c7,$ee), ($b8,$d3,$6b,$b8), ($14,$3c,$28,$14), ($de,$79,$a7,$de), ($5e,$e2,$bc,$5e), ($0b,$1d,$16,$0b), ($db,$76,$ad,$db), ($e0,$3b,$db,$e0), ($32,$56,$64,$32), ($3a,$4e,$74,$3a), ($0a,$1e,$14,$0a), ($49,$db,$92,$49), ($06,$0a,$0c,$06), ($24,$6c,$48,$24), ($5c,$e4,$b8,$5c), ($c2,$5d,$9f,$c2), ($d3,$6e,$bd,$d3), ($ac,$ef,$43,$ac), ($62,$a6,$c4,$62), ($91,$a8,$39,$91), ($95,$a4,$31,$95), ($e4,$37,$d3,$e4), ($79,$8b,$f2,$79), ($e7,$32,$d5,$e7), ($c8,$43,$8b,$c8), ($37,$59,$6e,$37), ($6d,$b7,$da,$6d), ($8d,$8c,$01,$8d), ($d5,$64,$b1,$d5), ($4e,$d2,$9c,$4e), ($a9,$e0,$49,$a9), ($6c,$b4,$d8,$6c), ($56,$fa,$ac,$56), ($f4,$07,$f3,$f4), ($ea,$25,$cf,$ea), ($65,$af,$ca,$65), ($7a,$8e,$f4,$7a), ($ae,$e9,$47,$ae), ($08,$18,$10,$08), ($ba,$d5,$6f,$ba), ($78,$88,$f0,$78), ($25,$6f,$4a,$25), ($2e,$72,$5c,$2e), ($1c,$24,$38,$1c), ($a6,$f1,$57,$a6), ($b4,$c7,$73,$b4), ($c6,$51,$97,$c6), ($e8,$23,$cb,$e8), ($dd,$7c,$a1,$dd), ($74,$9c,$e8,$74), ($1f,$21,$3e,$1f), ($4b,$dd,$96,$4b), ($bd,$dc,$61,$bd), ($8b,$86,$0d,$8b), ($8a,$85,$0f,$8a), ($70,$90,$e0,$70), ($3e,$42,$7c,$3e), ($b5,$c4,$71,$b5), ($66,$aa,$cc,$66), ($48,$d8,$90,$48), ($03,$05,$06,$03), ($f6,$01,$f7,$f6), ($0e,$12,$1c,$0e), ($61,$a3,$c2,$61), ($35,$5f,$6a,$35), ($57,$f9,$ae,$57), ($b9,$d0,$69,$b9), ($86,$91,$17,$86), ($c1,$58,$99,$c1), ($1d,$27,$3a,$1d), ($9e,$b9,$27,$9e), ($e1,$38,$d9,$e1), ($f8,$13,$eb,$f8), ($98,$b3,$2b,$98), ($11,$33,$22,$11), ($69,$bb,$d2,$69), ($d9,$70,$a9,$d9), ($8e,$89,$07,$8e), ($94,$a7,$33,$94), ($9b,$b6,$2d,$9b), ($1e,$22,$3c,$1e), ($87,$92,$15,$87), ($e9,$20,$c9,$e9), ($ce,$49,$87,$ce), ($55,$ff,$aa,$55), ($28,$78,$50,$28), ($df,$7a,$a5,$df), ($8c,$8f,$03,$8c), ($a1,$f8,$59,$a1), ($89,$80,$09,$89), ($0d,$17,$1a,$0d), ($bf,$da,$65,$bf), ($e6,$31,$d7,$e6), ($42,$c6,$84,$42), ($68,$b8,$d0,$68), ($41,$c3,$82,$41), ($99,$b0,$29,$99), ($2d,$77,$5a,$2d), ($0f,$11,$1e,$0f), ($b0,$cb,$7b,$b0), ($54,$fc,$a8,$54), ($bb,$d6,$6d,$bb), ($16,$3a,$2c,$16)); T4: array[0..255,0..3] of byte= ( ($63,$63,$a5,$c6), ($7c,$7c,$84,$f8), ($77,$77,$99,$ee), ($7b,$7b,$8d,$f6), ($f2,$f2,$0d,$ff), ($6b,$6b,$bd,$d6), ($6f,$6f,$b1,$de), ($c5,$c5,$54,$91), ($30,$30,$50,$60), ($01,$01,$03,$02), ($67,$67,$a9,$ce), ($2b,$2b,$7d,$56), ($fe,$fe,$19,$e7), ($d7,$d7,$62,$b5), ($ab,$ab,$e6,$4d), ($76,$76,$9a,$ec), ($ca,$ca,$45,$8f), ($82,$82,$9d,$1f), ($c9,$c9,$40,$89), ($7d,$7d,$87,$fa), ($fa,$fa,$15,$ef), ($59,$59,$eb,$b2), ($47,$47,$c9,$8e), ($f0,$f0,$0b,$fb), ($ad,$ad,$ec,$41), ($d4,$d4,$67,$b3), ($a2,$a2,$fd,$5f), ($af,$af,$ea,$45), ($9c,$9c,$bf,$23), ($a4,$a4,$f7,$53), ($72,$72,$96,$e4), ($c0,$c0,$5b,$9b), ($b7,$b7,$c2,$75), ($fd,$fd,$1c,$e1), ($93,$93,$ae,$3d), ($26,$26,$6a,$4c), ($36,$36,$5a,$6c), ($3f,$3f,$41,$7e), ($f7,$f7,$02,$f5), ($cc,$cc,$4f,$83), ($34,$34,$5c,$68), ($a5,$a5,$f4,$51), ($e5,$e5,$34,$d1), ($f1,$f1,$08,$f9), ($71,$71,$93,$e2), ($d8,$d8,$73,$ab), ($31,$31,$53,$62), ($15,$15,$3f,$2a), ($04,$04,$0c,$08), ($c7,$c7,$52,$95), ($23,$23,$65,$46), ($c3,$c3,$5e,$9d), ($18,$18,$28,$30), ($96,$96,$a1,$37), ($05,$05,$0f,$0a), ($9a,$9a,$b5,$2f), ($07,$07,$09,$0e), ($12,$12,$36,$24), ($80,$80,$9b,$1b), ($e2,$e2,$3d,$df), ($eb,$eb,$26,$cd), ($27,$27,$69,$4e), ($b2,$b2,$cd,$7f), ($75,$75,$9f,$ea), ($09,$09,$1b,$12), ($83,$83,$9e,$1d), ($2c,$2c,$74,$58), ($1a,$1a,$2e,$34), ($1b,$1b,$2d,$36), ($6e,$6e,$b2,$dc), ($5a,$5a,$ee,$b4), ($a0,$a0,$fb,$5b), ($52,$52,$f6,$a4), ($3b,$3b,$4d,$76), ($d6,$d6,$61,$b7), ($b3,$b3,$ce,$7d), ($29,$29,$7b,$52), ($e3,$e3,$3e,$dd), ($2f,$2f,$71,$5e), ($84,$84,$97,$13), ($53,$53,$f5,$a6), ($d1,$d1,$68,$b9), ($00,$00,$00,$00), ($ed,$ed,$2c,$c1), ($20,$20,$60,$40), ($fc,$fc,$1f,$e3), ($b1,$b1,$c8,$79), ($5b,$5b,$ed,$b6), ($6a,$6a,$be,$d4), ($cb,$cb,$46,$8d), ($be,$be,$d9,$67), ($39,$39,$4b,$72), ($4a,$4a,$de,$94), ($4c,$4c,$d4,$98), ($58,$58,$e8,$b0), ($cf,$cf,$4a,$85), ($d0,$d0,$6b,$bb), ($ef,$ef,$2a,$c5), ($aa,$aa,$e5,$4f), ($fb,$fb,$16,$ed), ($43,$43,$c5,$86), ($4d,$4d,$d7,$9a), ($33,$33,$55,$66), ($85,$85,$94,$11), ($45,$45,$cf,$8a), ($f9,$f9,$10,$e9), ($02,$02,$06,$04), ($7f,$7f,$81,$fe), ($50,$50,$f0,$a0), ($3c,$3c,$44,$78), ($9f,$9f,$ba,$25), ($a8,$a8,$e3,$4b), ($51,$51,$f3,$a2), ($a3,$a3,$fe,$5d), ($40,$40,$c0,$80), ($8f,$8f,$8a,$05), ($92,$92,$ad,$3f), ($9d,$9d,$bc,$21), ($38,$38,$48,$70), ($f5,$f5,$04,$f1), ($bc,$bc,$df,$63), ($b6,$b6,$c1,$77), ($da,$da,$75,$af), ($21,$21,$63,$42), ($10,$10,$30,$20), ($ff,$ff,$1a,$e5), ($f3,$f3,$0e,$fd), ($d2,$d2,$6d,$bf), ($cd,$cd,$4c,$81), ($0c,$0c,$14,$18), ($13,$13,$35,$26), ($ec,$ec,$2f,$c3), ($5f,$5f,$e1,$be), ($97,$97,$a2,$35), ($44,$44,$cc,$88), ($17,$17,$39,$2e), ($c4,$c4,$57,$93), ($a7,$a7,$f2,$55), ($7e,$7e,$82,$fc), ($3d,$3d,$47,$7a), ($64,$64,$ac,$c8), ($5d,$5d,$e7,$ba), ($19,$19,$2b,$32), ($73,$73,$95,$e6), ($60,$60,$a0,$c0), ($81,$81,$98,$19), ($4f,$4f,$d1,$9e), ($dc,$dc,$7f,$a3), ($22,$22,$66,$44), ($2a,$2a,$7e,$54), ($90,$90,$ab,$3b), ($88,$88,$83,$0b), ($46,$46,$ca,$8c), ($ee,$ee,$29,$c7), ($b8,$b8,$d3,$6b), ($14,$14,$3c,$28), ($de,$de,$79,$a7), ($5e,$5e,$e2,$bc), ($0b,$0b,$1d,$16), ($db,$db,$76,$ad), ($e0,$e0,$3b,$db), ($32,$32,$56,$64), ($3a,$3a,$4e,$74), ($0a,$0a,$1e,$14), ($49,$49,$db,$92), ($06,$06,$0a,$0c), ($24,$24,$6c,$48), ($5c,$5c,$e4,$b8), ($c2,$c2,$5d,$9f), ($d3,$d3,$6e,$bd), ($ac,$ac,$ef,$43), ($62,$62,$a6,$c4), ($91,$91,$a8,$39), ($95,$95,$a4,$31), ($e4,$e4,$37,$d3), ($79,$79,$8b,$f2), ($e7,$e7,$32,$d5), ($c8,$c8,$43,$8b), ($37,$37,$59,$6e), ($6d,$6d,$b7,$da), ($8d,$8d,$8c,$01), ($d5,$d5,$64,$b1), ($4e,$4e,$d2,$9c), ($a9,$a9,$e0,$49), ($6c,$6c,$b4,$d8), ($56,$56,$fa,$ac), ($f4,$f4,$07,$f3), ($ea,$ea,$25,$cf), ($65,$65,$af,$ca), ($7a,$7a,$8e,$f4), ($ae,$ae,$e9,$47), ($08,$08,$18,$10), ($ba,$ba,$d5,$6f), ($78,$78,$88,$f0), ($25,$25,$6f,$4a), ($2e,$2e,$72,$5c), ($1c,$1c,$24,$38), ($a6,$a6,$f1,$57), ($b4,$b4,$c7,$73), ($c6,$c6,$51,$97), ($e8,$e8,$23,$cb), ($dd,$dd,$7c,$a1), ($74,$74,$9c,$e8), ($1f,$1f,$21,$3e), ($4b,$4b,$dd,$96), ($bd,$bd,$dc,$61), ($8b,$8b,$86,$0d), ($8a,$8a,$85,$0f), ($70,$70,$90,$e0), ($3e,$3e,$42,$7c), ($b5,$b5,$c4,$71), ($66,$66,$aa,$cc), ($48,$48,$d8,$90), ($03,$03,$05,$06), ($f6,$f6,$01,$f7), ($0e,$0e,$12,$1c), ($61,$61,$a3,$c2), ($35,$35,$5f,$6a), ($57,$57,$f9,$ae), ($b9,$b9,$d0,$69), ($86,$86,$91,$17), ($c1,$c1,$58,$99), ($1d,$1d,$27,$3a), ($9e,$9e,$b9,$27), ($e1,$e1,$38,$d9), ($f8,$f8,$13,$eb), ($98,$98,$b3,$2b), ($11,$11,$33,$22), ($69,$69,$bb,$d2), ($d9,$d9,$70,$a9), ($8e,$8e,$89,$07), ($94,$94,$a7,$33), ($9b,$9b,$b6,$2d), ($1e,$1e,$22,$3c), ($87,$87,$92,$15), ($e9,$e9,$20,$c9), ($ce,$ce,$49,$87), ($55,$55,$ff,$aa), ($28,$28,$78,$50), ($df,$df,$7a,$a5), ($8c,$8c,$8f,$03), ($a1,$a1,$f8,$59), ($89,$89,$80,$09), ($0d,$0d,$17,$1a), ($bf,$bf,$da,$65), ($e6,$e6,$31,$d7), ($42,$42,$c6,$84), ($68,$68,$b8,$d0), ($41,$41,$c3,$82), ($99,$99,$b0,$29), ($2d,$2d,$77,$5a), ($0f,$0f,$11,$1e), ($b0,$b0,$cb,$7b), ($54,$54,$fc,$a8), ($bb,$bb,$d6,$6d), ($16,$16,$3a,$2c)); T5: array[0..255,0..3] of byte= ( ($51,$f4,$a7,$50), ($7e,$41,$65,$53), ($1a,$17,$a4,$c3), ($3a,$27,$5e,$96), ($3b,$ab,$6b,$cb), ($1f,$9d,$45,$f1), ($ac,$fa,$58,$ab), ($4b,$e3,$03,$93), ($20,$30,$fa,$55), ($ad,$76,$6d,$f6), ($88,$cc,$76,$91), ($f5,$02,$4c,$25), ($4f,$e5,$d7,$fc), ($c5,$2a,$cb,$d7), ($26,$35,$44,$80), ($b5,$62,$a3,$8f), ($de,$b1,$5a,$49), ($25,$ba,$1b,$67), ($45,$ea,$0e,$98), ($5d,$fe,$c0,$e1), ($c3,$2f,$75,$02), ($81,$4c,$f0,$12), ($8d,$46,$97,$a3), ($6b,$d3,$f9,$c6), ($03,$8f,$5f,$e7), ($15,$92,$9c,$95), ($bf,$6d,$7a,$eb), ($95,$52,$59,$da), ($d4,$be,$83,$2d), ($58,$74,$21,$d3), ($49,$e0,$69,$29), ($8e,$c9,$c8,$44), ($75,$c2,$89,$6a), ($f4,$8e,$79,$78), ($99,$58,$3e,$6b), ($27,$b9,$71,$dd), ($be,$e1,$4f,$b6), ($f0,$88,$ad,$17), ($c9,$20,$ac,$66), ($7d,$ce,$3a,$b4), ($63,$df,$4a,$18), ($e5,$1a,$31,$82), ($97,$51,$33,$60), ($62,$53,$7f,$45), ($b1,$64,$77,$e0), ($bb,$6b,$ae,$84), ($fe,$81,$a0,$1c), ($f9,$08,$2b,$94), ($70,$48,$68,$58), ($8f,$45,$fd,$19), ($94,$de,$6c,$87), ($52,$7b,$f8,$b7), ($ab,$73,$d3,$23), ($72,$4b,$02,$e2), ($e3,$1f,$8f,$57), ($66,$55,$ab,$2a), ($b2,$eb,$28,$07), ($2f,$b5,$c2,$03), ($86,$c5,$7b,$9a), ($d3,$37,$08,$a5), ($30,$28,$87,$f2), ($23,$bf,$a5,$b2), ($02,$03,$6a,$ba), ($ed,$16,$82,$5c), ($8a,$cf,$1c,$2b), ($a7,$79,$b4,$92), ($f3,$07,$f2,$f0), ($4e,$69,$e2,$a1), ($65,$da,$f4,$cd), ($06,$05,$be,$d5), ($d1,$34,$62,$1f), ($c4,$a6,$fe,$8a), ($34,$2e,$53,$9d), ($a2,$f3,$55,$a0), ($05,$8a,$e1,$32), ($a4,$f6,$eb,$75), ($0b,$83,$ec,$39), ($40,$60,$ef,$aa), ($5e,$71,$9f,$06), ($bd,$6e,$10,$51), ($3e,$21,$8a,$f9), ($96,$dd,$06,$3d), ($dd,$3e,$05,$ae), ($4d,$e6,$bd,$46), ($91,$54,$8d,$b5), ($71,$c4,$5d,$05), ($04,$06,$d4,$6f), ($60,$50,$15,$ff), ($19,$98,$fb,$24), ($d6,$bd,$e9,$97), ($89,$40,$43,$cc), ($67,$d9,$9e,$77), ($b0,$e8,$42,$bd), ($07,$89,$8b,$88), ($e7,$19,$5b,$38), ($79,$c8,$ee,$db), ($a1,$7c,$0a,$47), ($7c,$42,$0f,$e9), ($f8,$84,$1e,$c9), ($00,$00,$00,$00), ($09,$80,$86,$83), ($32,$2b,$ed,$48), ($1e,$11,$70,$ac), ($6c,$5a,$72,$4e), ($fd,$0e,$ff,$fb), ($0f,$85,$38,$56), ($3d,$ae,$d5,$1e), ($36,$2d,$39,$27), ($0a,$0f,$d9,$64), ($68,$5c,$a6,$21), ($9b,$5b,$54,$d1), ($24,$36,$2e,$3a), ($0c,$0a,$67,$b1), ($93,$57,$e7,$0f), ($b4,$ee,$96,$d2), ($1b,$9b,$91,$9e), ($80,$c0,$c5,$4f), ($61,$dc,$20,$a2), ($5a,$77,$4b,$69), ($1c,$12,$1a,$16), ($e2,$93,$ba,$0a), ($c0,$a0,$2a,$e5), ($3c,$22,$e0,$43), ($12,$1b,$17,$1d), ($0e,$09,$0d,$0b), ($f2,$8b,$c7,$ad), ($2d,$b6,$a8,$b9), ($14,$1e,$a9,$c8), ($57,$f1,$19,$85), ($af,$75,$07,$4c), ($ee,$99,$dd,$bb), ($a3,$7f,$60,$fd), ($f7,$01,$26,$9f), ($5c,$72,$f5,$bc), ($44,$66,$3b,$c5), ($5b,$fb,$7e,$34), ($8b,$43,$29,$76), ($cb,$23,$c6,$dc), ($b6,$ed,$fc,$68), ($b8,$e4,$f1,$63), ($d7,$31,$dc,$ca), ($42,$63,$85,$10), ($13,$97,$22,$40), ($84,$c6,$11,$20), ($85,$4a,$24,$7d), ($d2,$bb,$3d,$f8), ($ae,$f9,$32,$11), ($c7,$29,$a1,$6d), ($1d,$9e,$2f,$4b), ($dc,$b2,$30,$f3), ($0d,$86,$52,$ec), ($77,$c1,$e3,$d0), ($2b,$b3,$16,$6c), ($a9,$70,$b9,$99), ($11,$94,$48,$fa), ($47,$e9,$64,$22), ($a8,$fc,$8c,$c4), ($a0,$f0,$3f,$1a), ($56,$7d,$2c,$d8), ($22,$33,$90,$ef), ($87,$49,$4e,$c7), ($d9,$38,$d1,$c1), ($8c,$ca,$a2,$fe), ($98,$d4,$0b,$36), ($a6,$f5,$81,$cf), ($a5,$7a,$de,$28), ($da,$b7,$8e,$26), ($3f,$ad,$bf,$a4), ($2c,$3a,$9d,$e4), ($50,$78,$92,$0d), ($6a,$5f,$cc,$9b), ($54,$7e,$46,$62), ($f6,$8d,$13,$c2), ($90,$d8,$b8,$e8), ($2e,$39,$f7,$5e), ($82,$c3,$af,$f5), ($9f,$5d,$80,$be), ($69,$d0,$93,$7c), ($6f,$d5,$2d,$a9), ($cf,$25,$12,$b3), ($c8,$ac,$99,$3b), ($10,$18,$7d,$a7), ($e8,$9c,$63,$6e), ($db,$3b,$bb,$7b), ($cd,$26,$78,$09), ($6e,$59,$18,$f4), ($ec,$9a,$b7,$01), ($83,$4f,$9a,$a8), ($e6,$95,$6e,$65), ($aa,$ff,$e6,$7e), ($21,$bc,$cf,$08), ($ef,$15,$e8,$e6), ($ba,$e7,$9b,$d9), ($4a,$6f,$36,$ce), ($ea,$9f,$09,$d4), ($29,$b0,$7c,$d6), ($31,$a4,$b2,$af), ($2a,$3f,$23,$31), ($c6,$a5,$94,$30), ($35,$a2,$66,$c0), ($74,$4e,$bc,$37), ($fc,$82,$ca,$a6), ($e0,$90,$d0,$b0), ($33,$a7,$d8,$15), ($f1,$04,$98,$4a), ($41,$ec,$da,$f7), ($7f,$cd,$50,$0e), ($17,$91,$f6,$2f), ($76,$4d,$d6,$8d), ($43,$ef,$b0,$4d), ($cc,$aa,$4d,$54), ($e4,$96,$04,$df), ($9e,$d1,$b5,$e3), ($4c,$6a,$88,$1b), ($c1,$2c,$1f,$b8), ($46,$65,$51,$7f), ($9d,$5e,$ea,$04), ($01,$8c,$35,$5d), ($fa,$87,$74,$73), ($fb,$0b,$41,$2e), ($b3,$67,$1d,$5a), ($92,$db,$d2,$52), ($e9,$10,$56,$33), ($6d,$d6,$47,$13), ($9a,$d7,$61,$8c), ($37,$a1,$0c,$7a), ($59,$f8,$14,$8e), ($eb,$13,$3c,$89), ($ce,$a9,$27,$ee), ($b7,$61,$c9,$35), ($e1,$1c,$e5,$ed), ($7a,$47,$b1,$3c), ($9c,$d2,$df,$59), ($55,$f2,$73,$3f), ($18,$14,$ce,$79), ($73,$c7,$37,$bf), ($53,$f7,$cd,$ea), ($5f,$fd,$aa,$5b), ($df,$3d,$6f,$14), ($78,$44,$db,$86), ($ca,$af,$f3,$81), ($b9,$68,$c4,$3e), ($38,$24,$34,$2c), ($c2,$a3,$40,$5f), ($16,$1d,$c3,$72), ($bc,$e2,$25,$0c), ($28,$3c,$49,$8b), ($ff,$0d,$95,$41), ($39,$a8,$01,$71), ($08,$0c,$b3,$de), ($d8,$b4,$e4,$9c), ($64,$56,$c1,$90), ($7b,$cb,$84,$61), ($d5,$32,$b6,$70), ($48,$6c,$5c,$74), ($d0,$b8,$57,$42)); T6: array[0..255,0..3] of byte= ( ($50,$51,$f4,$a7), ($53,$7e,$41,$65), ($c3,$1a,$17,$a4), ($96,$3a,$27,$5e), ($cb,$3b,$ab,$6b), ($f1,$1f,$9d,$45), ($ab,$ac,$fa,$58), ($93,$4b,$e3,$03), ($55,$20,$30,$fa), ($f6,$ad,$76,$6d), ($91,$88,$cc,$76), ($25,$f5,$02,$4c), ($fc,$4f,$e5,$d7), ($d7,$c5,$2a,$cb), ($80,$26,$35,$44), ($8f,$b5,$62,$a3), ($49,$de,$b1,$5a), ($67,$25,$ba,$1b), ($98,$45,$ea,$0e), ($e1,$5d,$fe,$c0), ($02,$c3,$2f,$75), ($12,$81,$4c,$f0), ($a3,$8d,$46,$97), ($c6,$6b,$d3,$f9), ($e7,$03,$8f,$5f), ($95,$15,$92,$9c), ($eb,$bf,$6d,$7a), ($da,$95,$52,$59), ($2d,$d4,$be,$83), ($d3,$58,$74,$21), ($29,$49,$e0,$69), ($44,$8e,$c9,$c8), ($6a,$75,$c2,$89), ($78,$f4,$8e,$79), ($6b,$99,$58,$3e), ($dd,$27,$b9,$71), ($b6,$be,$e1,$4f), ($17,$f0,$88,$ad), ($66,$c9,$20,$ac), ($b4,$7d,$ce,$3a), ($18,$63,$df,$4a), ($82,$e5,$1a,$31), ($60,$97,$51,$33), ($45,$62,$53,$7f), ($e0,$b1,$64,$77), ($84,$bb,$6b,$ae), ($1c,$fe,$81,$a0), ($94,$f9,$08,$2b), ($58,$70,$48,$68), ($19,$8f,$45,$fd), ($87,$94,$de,$6c), ($b7,$52,$7b,$f8), ($23,$ab,$73,$d3), ($e2,$72,$4b,$02), ($57,$e3,$1f,$8f), ($2a,$66,$55,$ab), ($07,$b2,$eb,$28), ($03,$2f,$b5,$c2), ($9a,$86,$c5,$7b), ($a5,$d3,$37,$08), ($f2,$30,$28,$87), ($b2,$23,$bf,$a5), ($ba,$02,$03,$6a), ($5c,$ed,$16,$82), ($2b,$8a,$cf,$1c), ($92,$a7,$79,$b4), ($f0,$f3,$07,$f2), ($a1,$4e,$69,$e2), ($cd,$65,$da,$f4), ($d5,$06,$05,$be), ($1f,$d1,$34,$62), ($8a,$c4,$a6,$fe), ($9d,$34,$2e,$53), ($a0,$a2,$f3,$55), ($32,$05,$8a,$e1), ($75,$a4,$f6,$eb), ($39,$0b,$83,$ec), ($aa,$40,$60,$ef), ($06,$5e,$71,$9f), ($51,$bd,$6e,$10), ($f9,$3e,$21,$8a), ($3d,$96,$dd,$06), ($ae,$dd,$3e,$05), ($46,$4d,$e6,$bd), ($b5,$91,$54,$8d), ($05,$71,$c4,$5d), ($6f,$04,$06,$d4), ($ff,$60,$50,$15), ($24,$19,$98,$fb), ($97,$d6,$bd,$e9), ($cc,$89,$40,$43), ($77,$67,$d9,$9e), ($bd,$b0,$e8,$42), ($88,$07,$89,$8b), ($38,$e7,$19,$5b), ($db,$79,$c8,$ee), ($47,$a1,$7c,$0a), ($e9,$7c,$42,$0f), ($c9,$f8,$84,$1e), ($00,$00,$00,$00), ($83,$09,$80,$86), ($48,$32,$2b,$ed), ($ac,$1e,$11,$70), ($4e,$6c,$5a,$72), ($fb,$fd,$0e,$ff), ($56,$0f,$85,$38), ($1e,$3d,$ae,$d5), ($27,$36,$2d,$39), ($64,$0a,$0f,$d9), ($21,$68,$5c,$a6), ($d1,$9b,$5b,$54), ($3a,$24,$36,$2e), ($b1,$0c,$0a,$67), ($0f,$93,$57,$e7), ($d2,$b4,$ee,$96), ($9e,$1b,$9b,$91), ($4f,$80,$c0,$c5), ($a2,$61,$dc,$20), ($69,$5a,$77,$4b), ($16,$1c,$12,$1a), ($0a,$e2,$93,$ba), ($e5,$c0,$a0,$2a), ($43,$3c,$22,$e0), ($1d,$12,$1b,$17), ($0b,$0e,$09,$0d), ($ad,$f2,$8b,$c7), ($b9,$2d,$b6,$a8), ($c8,$14,$1e,$a9), ($85,$57,$f1,$19), ($4c,$af,$75,$07), ($bb,$ee,$99,$dd), ($fd,$a3,$7f,$60), ($9f,$f7,$01,$26), ($bc,$5c,$72,$f5), ($c5,$44,$66,$3b), ($34,$5b,$fb,$7e), ($76,$8b,$43,$29), ($dc,$cb,$23,$c6), ($68,$b6,$ed,$fc), ($63,$b8,$e4,$f1), ($ca,$d7,$31,$dc), ($10,$42,$63,$85), ($40,$13,$97,$22), ($20,$84,$c6,$11), ($7d,$85,$4a,$24), ($f8,$d2,$bb,$3d), ($11,$ae,$f9,$32), ($6d,$c7,$29,$a1), ($4b,$1d,$9e,$2f), ($f3,$dc,$b2,$30), ($ec,$0d,$86,$52), ($d0,$77,$c1,$e3), ($6c,$2b,$b3,$16), ($99,$a9,$70,$b9), ($fa,$11,$94,$48), ($22,$47,$e9,$64), ($c4,$a8,$fc,$8c), ($1a,$a0,$f0,$3f), ($d8,$56,$7d,$2c), ($ef,$22,$33,$90), ($c7,$87,$49,$4e), ($c1,$d9,$38,$d1), ($fe,$8c,$ca,$a2), ($36,$98,$d4,$0b), ($cf,$a6,$f5,$81), ($28,$a5,$7a,$de), ($26,$da,$b7,$8e), ($a4,$3f,$ad,$bf), ($e4,$2c,$3a,$9d), ($0d,$50,$78,$92), ($9b,$6a,$5f,$cc), ($62,$54,$7e,$46), ($c2,$f6,$8d,$13), ($e8,$90,$d8,$b8), ($5e,$2e,$39,$f7), ($f5,$82,$c3,$af), ($be,$9f,$5d,$80), ($7c,$69,$d0,$93), ($a9,$6f,$d5,$2d), ($b3,$cf,$25,$12), ($3b,$c8,$ac,$99), ($a7,$10,$18,$7d), ($6e,$e8,$9c,$63), ($7b,$db,$3b,$bb), ($09,$cd,$26,$78), ($f4,$6e,$59,$18), ($01,$ec,$9a,$b7), ($a8,$83,$4f,$9a), ($65,$e6,$95,$6e), ($7e,$aa,$ff,$e6), ($08,$21,$bc,$cf), ($e6,$ef,$15,$e8), ($d9,$ba,$e7,$9b), ($ce,$4a,$6f,$36), ($d4,$ea,$9f,$09), ($d6,$29,$b0,$7c), ($af,$31,$a4,$b2), ($31,$2a,$3f,$23), ($30,$c6,$a5,$94), ($c0,$35,$a2,$66), ($37,$74,$4e,$bc), ($a6,$fc,$82,$ca), ($b0,$e0,$90,$d0), ($15,$33,$a7,$d8), ($4a,$f1,$04,$98), ($f7,$41,$ec,$da), ($0e,$7f,$cd,$50), ($2f,$17,$91,$f6), ($8d,$76,$4d,$d6), ($4d,$43,$ef,$b0), ($54,$cc,$aa,$4d), ($df,$e4,$96,$04), ($e3,$9e,$d1,$b5), ($1b,$4c,$6a,$88), ($b8,$c1,$2c,$1f), ($7f,$46,$65,$51), ($04,$9d,$5e,$ea), ($5d,$01,$8c,$35), ($73,$fa,$87,$74), ($2e,$fb,$0b,$41), ($5a,$b3,$67,$1d), ($52,$92,$db,$d2), ($33,$e9,$10,$56), ($13,$6d,$d6,$47), ($8c,$9a,$d7,$61), ($7a,$37,$a1,$0c), ($8e,$59,$f8,$14), ($89,$eb,$13,$3c), ($ee,$ce,$a9,$27), ($35,$b7,$61,$c9), ($ed,$e1,$1c,$e5), ($3c,$7a,$47,$b1), ($59,$9c,$d2,$df), ($3f,$55,$f2,$73), ($79,$18,$14,$ce), ($bf,$73,$c7,$37), ($ea,$53,$f7,$cd), ($5b,$5f,$fd,$aa), ($14,$df,$3d,$6f), ($86,$78,$44,$db), ($81,$ca,$af,$f3), ($3e,$b9,$68,$c4), ($2c,$38,$24,$34), ($5f,$c2,$a3,$40), ($72,$16,$1d,$c3), ($0c,$bc,$e2,$25), ($8b,$28,$3c,$49), ($41,$ff,$0d,$95), ($71,$39,$a8,$01), ($de,$08,$0c,$b3), ($9c,$d8,$b4,$e4), ($90,$64,$56,$c1), ($61,$7b,$cb,$84), ($70,$d5,$32,$b6), ($74,$48,$6c,$5c), ($42,$d0,$b8,$57)); T7: array[0..255,0..3] of byte= ( ($a7,$50,$51,$f4), ($65,$53,$7e,$41), ($a4,$c3,$1a,$17), ($5e,$96,$3a,$27), ($6b,$cb,$3b,$ab), ($45,$f1,$1f,$9d), ($58,$ab,$ac,$fa), ($03,$93,$4b,$e3), ($fa,$55,$20,$30), ($6d,$f6,$ad,$76), ($76,$91,$88,$cc), ($4c,$25,$f5,$02), ($d7,$fc,$4f,$e5), ($cb,$d7,$c5,$2a), ($44,$80,$26,$35), ($a3,$8f,$b5,$62), ($5a,$49,$de,$b1), ($1b,$67,$25,$ba), ($0e,$98,$45,$ea), ($c0,$e1,$5d,$fe), ($75,$02,$c3,$2f), ($f0,$12,$81,$4c), ($97,$a3,$8d,$46), ($f9,$c6,$6b,$d3), ($5f,$e7,$03,$8f), ($9c,$95,$15,$92), ($7a,$eb,$bf,$6d), ($59,$da,$95,$52), ($83,$2d,$d4,$be), ($21,$d3,$58,$74), ($69,$29,$49,$e0), ($c8,$44,$8e,$c9), ($89,$6a,$75,$c2), ($79,$78,$f4,$8e), ($3e,$6b,$99,$58), ($71,$dd,$27,$b9), ($4f,$b6,$be,$e1), ($ad,$17,$f0,$88), ($ac,$66,$c9,$20), ($3a,$b4,$7d,$ce), ($4a,$18,$63,$df), ($31,$82,$e5,$1a), ($33,$60,$97,$51), ($7f,$45,$62,$53), ($77,$e0,$b1,$64), ($ae,$84,$bb,$6b), ($a0,$1c,$fe,$81), ($2b,$94,$f9,$08), ($68,$58,$70,$48), ($fd,$19,$8f,$45), ($6c,$87,$94,$de), ($f8,$b7,$52,$7b), ($d3,$23,$ab,$73), ($02,$e2,$72,$4b), ($8f,$57,$e3,$1f), ($ab,$2a,$66,$55), ($28,$07,$b2,$eb), ($c2,$03,$2f,$b5), ($7b,$9a,$86,$c5), ($08,$a5,$d3,$37), ($87,$f2,$30,$28), ($a5,$b2,$23,$bf), ($6a,$ba,$02,$03), ($82,$5c,$ed,$16), ($1c,$2b,$8a,$cf), ($b4,$92,$a7,$79), ($f2,$f0,$f3,$07), ($e2,$a1,$4e,$69), ($f4,$cd,$65,$da), ($be,$d5,$06,$05), ($62,$1f,$d1,$34), ($fe,$8a,$c4,$a6), ($53,$9d,$34,$2e), ($55,$a0,$a2,$f3), ($e1,$32,$05,$8a), ($eb,$75,$a4,$f6), ($ec,$39,$0b,$83), ($ef,$aa,$40,$60), ($9f,$06,$5e,$71), ($10,$51,$bd,$6e), ($8a,$f9,$3e,$21), ($06,$3d,$96,$dd), ($05,$ae,$dd,$3e), ($bd,$46,$4d,$e6), ($8d,$b5,$91,$54), ($5d,$05,$71,$c4), ($d4,$6f,$04,$06), ($15,$ff,$60,$50), ($fb,$24,$19,$98), ($e9,$97,$d6,$bd), ($43,$cc,$89,$40), ($9e,$77,$67,$d9), ($42,$bd,$b0,$e8), ($8b,$88,$07,$89), ($5b,$38,$e7,$19), ($ee,$db,$79,$c8), ($0a,$47,$a1,$7c), ($0f,$e9,$7c,$42), ($1e,$c9,$f8,$84), ($00,$00,$00,$00), ($86,$83,$09,$80), ($ed,$48,$32,$2b), ($70,$ac,$1e,$11), ($72,$4e,$6c,$5a), ($ff,$fb,$fd,$0e), ($38,$56,$0f,$85), ($d5,$1e,$3d,$ae), ($39,$27,$36,$2d), ($d9,$64,$0a,$0f), ($a6,$21,$68,$5c), ($54,$d1,$9b,$5b), ($2e,$3a,$24,$36), ($67,$b1,$0c,$0a), ($e7,$0f,$93,$57), ($96,$d2,$b4,$ee), ($91,$9e,$1b,$9b), ($c5,$4f,$80,$c0), ($20,$a2,$61,$dc), ($4b,$69,$5a,$77), ($1a,$16,$1c,$12), ($ba,$0a,$e2,$93), ($2a,$e5,$c0,$a0), ($e0,$43,$3c,$22), ($17,$1d,$12,$1b), ($0d,$0b,$0e,$09), ($c7,$ad,$f2,$8b), ($a8,$b9,$2d,$b6), ($a9,$c8,$14,$1e), ($19,$85,$57,$f1), ($07,$4c,$af,$75), ($dd,$bb,$ee,$99), ($60,$fd,$a3,$7f), ($26,$9f,$f7,$01), ($f5,$bc,$5c,$72), ($3b,$c5,$44,$66), ($7e,$34,$5b,$fb), ($29,$76,$8b,$43), ($c6,$dc,$cb,$23), ($fc,$68,$b6,$ed), ($f1,$63,$b8,$e4), ($dc,$ca,$d7,$31), ($85,$10,$42,$63), ($22,$40,$13,$97), ($11,$20,$84,$c6), ($24,$7d,$85,$4a), ($3d,$f8,$d2,$bb), ($32,$11,$ae,$f9), ($a1,$6d,$c7,$29), ($2f,$4b,$1d,$9e), ($30,$f3,$dc,$b2), ($52,$ec,$0d,$86), ($e3,$d0,$77,$c1), ($16,$6c,$2b,$b3), ($b9,$99,$a9,$70), ($48,$fa,$11,$94), ($64,$22,$47,$e9), ($8c,$c4,$a8,$fc), ($3f,$1a,$a0,$f0), ($2c,$d8,$56,$7d), ($90,$ef,$22,$33), ($4e,$c7,$87,$49), ($d1,$c1,$d9,$38), ($a2,$fe,$8c,$ca), ($0b,$36,$98,$d4), ($81,$cf,$a6,$f5), ($de,$28,$a5,$7a), ($8e,$26,$da,$b7), ($bf,$a4,$3f,$ad), ($9d,$e4,$2c,$3a), ($92,$0d,$50,$78), ($cc,$9b,$6a,$5f), ($46,$62,$54,$7e), ($13,$c2,$f6,$8d), ($b8,$e8,$90,$d8), ($f7,$5e,$2e,$39), ($af,$f5,$82,$c3), ($80,$be,$9f,$5d), ($93,$7c,$69,$d0), ($2d,$a9,$6f,$d5), ($12,$b3,$cf,$25), ($99,$3b,$c8,$ac), ($7d,$a7,$10,$18), ($63,$6e,$e8,$9c), ($bb,$7b,$db,$3b), ($78,$09,$cd,$26), ($18,$f4,$6e,$59), ($b7,$01,$ec,$9a), ($9a,$a8,$83,$4f), ($6e,$65,$e6,$95), ($e6,$7e,$aa,$ff), ($cf,$08,$21,$bc), ($e8,$e6,$ef,$15), ($9b,$d9,$ba,$e7), ($36,$ce,$4a,$6f), ($09,$d4,$ea,$9f), ($7c,$d6,$29,$b0), ($b2,$af,$31,$a4), ($23,$31,$2a,$3f), ($94,$30,$c6,$a5), ($66,$c0,$35,$a2), ($bc,$37,$74,$4e), ($ca,$a6,$fc,$82), ($d0,$b0,$e0,$90), ($d8,$15,$33,$a7), ($98,$4a,$f1,$04), ($da,$f7,$41,$ec), ($50,$0e,$7f,$cd), ($f6,$2f,$17,$91), ($d6,$8d,$76,$4d), ($b0,$4d,$43,$ef), ($4d,$54,$cc,$aa), ($04,$df,$e4,$96), ($b5,$e3,$9e,$d1), ($88,$1b,$4c,$6a), ($1f,$b8,$c1,$2c), ($51,$7f,$46,$65), ($ea,$04,$9d,$5e), ($35,$5d,$01,$8c), ($74,$73,$fa,$87), ($41,$2e,$fb,$0b), ($1d,$5a,$b3,$67), ($d2,$52,$92,$db), ($56,$33,$e9,$10), ($47,$13,$6d,$d6), ($61,$8c,$9a,$d7), ($0c,$7a,$37,$a1), ($14,$8e,$59,$f8), ($3c,$89,$eb,$13), ($27,$ee,$ce,$a9), ($c9,$35,$b7,$61), ($e5,$ed,$e1,$1c), ($b1,$3c,$7a,$47), ($df,$59,$9c,$d2), ($73,$3f,$55,$f2), ($ce,$79,$18,$14), ($37,$bf,$73,$c7), ($cd,$ea,$53,$f7), ($aa,$5b,$5f,$fd), ($6f,$14,$df,$3d), ($db,$86,$78,$44), ($f3,$81,$ca,$af), ($c4,$3e,$b9,$68), ($34,$2c,$38,$24), ($40,$5f,$c2,$a3), ($c3,$72,$16,$1d), ($25,$0c,$bc,$e2), ($49,$8b,$28,$3c), ($95,$41,$ff,$0d), ($01,$71,$39,$a8), ($b3,$de,$08,$0c), ($e4,$9c,$d8,$b4), ($c1,$90,$64,$56), ($84,$61,$7b,$cb), ($b6,$70,$d5,$32), ($5c,$74,$48,$6c), ($57,$42,$d0,$b8)); T8: array[0..255,0..3] of byte= ( ($f4,$a7,$50,$51), ($41,$65,$53,$7e), ($17,$a4,$c3,$1a), ($27,$5e,$96,$3a), ($ab,$6b,$cb,$3b), ($9d,$45,$f1,$1f), ($fa,$58,$ab,$ac), ($e3,$03,$93,$4b), ($30,$fa,$55,$20), ($76,$6d,$f6,$ad), ($cc,$76,$91,$88), ($02,$4c,$25,$f5), ($e5,$d7,$fc,$4f), ($2a,$cb,$d7,$c5), ($35,$44,$80,$26), ($62,$a3,$8f,$b5), ($b1,$5a,$49,$de), ($ba,$1b,$67,$25), ($ea,$0e,$98,$45), ($fe,$c0,$e1,$5d), ($2f,$75,$02,$c3), ($4c,$f0,$12,$81), ($46,$97,$a3,$8d), ($d3,$f9,$c6,$6b), ($8f,$5f,$e7,$03), ($92,$9c,$95,$15), ($6d,$7a,$eb,$bf), ($52,$59,$da,$95), ($be,$83,$2d,$d4), ($74,$21,$d3,$58), ($e0,$69,$29,$49), ($c9,$c8,$44,$8e), ($c2,$89,$6a,$75), ($8e,$79,$78,$f4), ($58,$3e,$6b,$99), ($b9,$71,$dd,$27), ($e1,$4f,$b6,$be), ($88,$ad,$17,$f0), ($20,$ac,$66,$c9), ($ce,$3a,$b4,$7d), ($df,$4a,$18,$63), ($1a,$31,$82,$e5), ($51,$33,$60,$97), ($53,$7f,$45,$62), ($64,$77,$e0,$b1), ($6b,$ae,$84,$bb), ($81,$a0,$1c,$fe), ($08,$2b,$94,$f9), ($48,$68,$58,$70), ($45,$fd,$19,$8f), ($de,$6c,$87,$94), ($7b,$f8,$b7,$52), ($73,$d3,$23,$ab), ($4b,$02,$e2,$72), ($1f,$8f,$57,$e3), ($55,$ab,$2a,$66), ($eb,$28,$07,$b2), ($b5,$c2,$03,$2f), ($c5,$7b,$9a,$86), ($37,$08,$a5,$d3), ($28,$87,$f2,$30), ($bf,$a5,$b2,$23), ($03,$6a,$ba,$02), ($16,$82,$5c,$ed), ($cf,$1c,$2b,$8a), ($79,$b4,$92,$a7), ($07,$f2,$f0,$f3), ($69,$e2,$a1,$4e), ($da,$f4,$cd,$65), ($05,$be,$d5,$06), ($34,$62,$1f,$d1), ($a6,$fe,$8a,$c4), ($2e,$53,$9d,$34), ($f3,$55,$a0,$a2), ($8a,$e1,$32,$05), ($f6,$eb,$75,$a4), ($83,$ec,$39,$0b), ($60,$ef,$aa,$40), ($71,$9f,$06,$5e), ($6e,$10,$51,$bd), ($21,$8a,$f9,$3e), ($dd,$06,$3d,$96), ($3e,$05,$ae,$dd), ($e6,$bd,$46,$4d), ($54,$8d,$b5,$91), ($c4,$5d,$05,$71), ($06,$d4,$6f,$04), ($50,$15,$ff,$60), ($98,$fb,$24,$19), ($bd,$e9,$97,$d6), ($40,$43,$cc,$89), ($d9,$9e,$77,$67), ($e8,$42,$bd,$b0), ($89,$8b,$88,$07), ($19,$5b,$38,$e7), ($c8,$ee,$db,$79), ($7c,$0a,$47,$a1), ($42,$0f,$e9,$7c), ($84,$1e,$c9,$f8), ($00,$00,$00,$00), ($80,$86,$83,$09), ($2b,$ed,$48,$32), ($11,$70,$ac,$1e), ($5a,$72,$4e,$6c), ($0e,$ff,$fb,$fd), ($85,$38,$56,$0f), ($ae,$d5,$1e,$3d), ($2d,$39,$27,$36), ($0f,$d9,$64,$0a), ($5c,$a6,$21,$68), ($5b,$54,$d1,$9b), ($36,$2e,$3a,$24), ($0a,$67,$b1,$0c), ($57,$e7,$0f,$93), ($ee,$96,$d2,$b4), ($9b,$91,$9e,$1b), ($c0,$c5,$4f,$80), ($dc,$20,$a2,$61), ($77,$4b,$69,$5a), ($12,$1a,$16,$1c), ($93,$ba,$0a,$e2), ($a0,$2a,$e5,$c0), ($22,$e0,$43,$3c), ($1b,$17,$1d,$12), ($09,$0d,$0b,$0e), ($8b,$c7,$ad,$f2), ($b6,$a8,$b9,$2d), ($1e,$a9,$c8,$14), ($f1,$19,$85,$57), ($75,$07,$4c,$af), ($99,$dd,$bb,$ee), ($7f,$60,$fd,$a3), ($01,$26,$9f,$f7), ($72,$f5,$bc,$5c), ($66,$3b,$c5,$44), ($fb,$7e,$34,$5b), ($43,$29,$76,$8b), ($23,$c6,$dc,$cb), ($ed,$fc,$68,$b6), ($e4,$f1,$63,$b8), ($31,$dc,$ca,$d7), ($63,$85,$10,$42), ($97,$22,$40,$13), ($c6,$11,$20,$84), ($4a,$24,$7d,$85), ($bb,$3d,$f8,$d2), ($f9,$32,$11,$ae), ($29,$a1,$6d,$c7), ($9e,$2f,$4b,$1d), ($b2,$30,$f3,$dc), ($86,$52,$ec,$0d), ($c1,$e3,$d0,$77), ($b3,$16,$6c,$2b), ($70,$b9,$99,$a9), ($94,$48,$fa,$11), ($e9,$64,$22,$47), ($fc,$8c,$c4,$a8), ($f0,$3f,$1a,$a0), ($7d,$2c,$d8,$56), ($33,$90,$ef,$22), ($49,$4e,$c7,$87), ($38,$d1,$c1,$d9), ($ca,$a2,$fe,$8c), ($d4,$0b,$36,$98), ($f5,$81,$cf,$a6), ($7a,$de,$28,$a5), ($b7,$8e,$26,$da), ($ad,$bf,$a4,$3f), ($3a,$9d,$e4,$2c), ($78,$92,$0d,$50), ($5f,$cc,$9b,$6a), ($7e,$46,$62,$54), ($8d,$13,$c2,$f6), ($d8,$b8,$e8,$90), ($39,$f7,$5e,$2e), ($c3,$af,$f5,$82), ($5d,$80,$be,$9f), ($d0,$93,$7c,$69), ($d5,$2d,$a9,$6f), ($25,$12,$b3,$cf), ($ac,$99,$3b,$c8), ($18,$7d,$a7,$10), ($9c,$63,$6e,$e8), ($3b,$bb,$7b,$db), ($26,$78,$09,$cd), ($59,$18,$f4,$6e), ($9a,$b7,$01,$ec), ($4f,$9a,$a8,$83), ($95,$6e,$65,$e6), ($ff,$e6,$7e,$aa), ($bc,$cf,$08,$21), ($15,$e8,$e6,$ef), ($e7,$9b,$d9,$ba), ($6f,$36,$ce,$4a), ($9f,$09,$d4,$ea), ($b0,$7c,$d6,$29), ($a4,$b2,$af,$31), ($3f,$23,$31,$2a), ($a5,$94,$30,$c6), ($a2,$66,$c0,$35), ($4e,$bc,$37,$74), ($82,$ca,$a6,$fc), ($90,$d0,$b0,$e0), ($a7,$d8,$15,$33), ($04,$98,$4a,$f1), ($ec,$da,$f7,$41), ($cd,$50,$0e,$7f), ($91,$f6,$2f,$17), ($4d,$d6,$8d,$76), ($ef,$b0,$4d,$43), ($aa,$4d,$54,$cc), ($96,$04,$df,$e4), ($d1,$b5,$e3,$9e), ($6a,$88,$1b,$4c), ($2c,$1f,$b8,$c1), ($65,$51,$7f,$46), ($5e,$ea,$04,$9d), ($8c,$35,$5d,$01), ($87,$74,$73,$fa), ($0b,$41,$2e,$fb), ($67,$1d,$5a,$b3), ($db,$d2,$52,$92), ($10,$56,$33,$e9), ($d6,$47,$13,$6d), ($d7,$61,$8c,$9a), ($a1,$0c,$7a,$37), ($f8,$14,$8e,$59), ($13,$3c,$89,$eb), ($a9,$27,$ee,$ce), ($61,$c9,$35,$b7), ($1c,$e5,$ed,$e1), ($47,$b1,$3c,$7a), ($d2,$df,$59,$9c), ($f2,$73,$3f,$55), ($14,$ce,$79,$18), ($c7,$37,$bf,$73), ($f7,$cd,$ea,$53), ($fd,$aa,$5b,$5f), ($3d,$6f,$14,$df), ($44,$db,$86,$78), ($af,$f3,$81,$ca), ($68,$c4,$3e,$b9), ($24,$34,$2c,$38), ($a3,$40,$5f,$c2), ($1d,$c3,$72,$16), ($e2,$25,$0c,$bc), ($3c,$49,$8b,$28), ($0d,$95,$41,$ff), ($a8,$01,$71,$39), ($0c,$b3,$de,$08), ($b4,$e4,$9c,$d8), ($56,$c1,$90,$64), ($cb,$84,$61,$7b), ($32,$b6,$70,$d5), ($6c,$5c,$74,$48), ($b8,$57,$42,$d0)); S5: array[0..255] of byte= ( $52,$09,$6a,$d5, $30,$36,$a5,$38, $bf,$40,$a3,$9e, $81,$f3,$d7,$fb, $7c,$e3,$39,$82, $9b,$2f,$ff,$87, $34,$8e,$43,$44, $c4,$de,$e9,$cb, $54,$7b,$94,$32, $a6,$c2,$23,$3d, $ee,$4c,$95,$0b, $42,$fa,$c3,$4e, $08,$2e,$a1,$66, $28,$d9,$24,$b2, $76,$5b,$a2,$49, $6d,$8b,$d1,$25, $72,$f8,$f6,$64, $86,$68,$98,$16, $d4,$a4,$5c,$cc, $5d,$65,$b6,$92, $6c,$70,$48,$50, $fd,$ed,$b9,$da, $5e,$15,$46,$57, $a7,$8d,$9d,$84, $90,$d8,$ab,$00, $8c,$bc,$d3,$0a, $f7,$e4,$58,$05, $b8,$b3,$45,$06, $d0,$2c,$1e,$8f, $ca,$3f,$0f,$02, $c1,$af,$bd,$03, $01,$13,$8a,$6b, $3a,$91,$11,$41, $4f,$67,$dc,$ea, $97,$f2,$cf,$ce, $f0,$b4,$e6,$73, $96,$ac,$74,$22, $e7,$ad,$35,$85, $e2,$f9,$37,$e8, $1c,$75,$df,$6e, $47,$f1,$1a,$71, $1d,$29,$c5,$89, $6f,$b7,$62,$0e, $aa,$18,$be,$1b, $fc,$56,$3e,$4b, $c6,$d2,$79,$20, $9a,$db,$c0,$fe, $78,$cd,$5a,$f4, $1f,$dd,$a8,$33, $88,$07,$c7,$31, $b1,$12,$10,$59, $27,$80,$ec,$5f, $60,$51,$7f,$a9, $19,$b5,$4a,$0d, $2d,$e5,$7a,$9f, $93,$c9,$9c,$ef, $a0,$e0,$3b,$4d, $ae,$2a,$f5,$b0, $c8,$eb,$bb,$3c, $83,$53,$99,$61, $17,$2b,$04,$7e, $ba,$77,$d6,$26, $e1,$69,$14,$63, $55,$21,$0c,$7d); U1: array[0..255,0..3] of byte= ( ($00,$00,$00,$00), ($0e,$09,$0d,$0b), ($1c,$12,$1a,$16), ($12,$1b,$17,$1d), ($38,$24,$34,$2c), ($36,$2d,$39,$27), ($24,$36,$2e,$3a), ($2a,$3f,$23,$31), ($70,$48,$68,$58), ($7e,$41,$65,$53), ($6c,$5a,$72,$4e), ($62,$53,$7f,$45), ($48,$6c,$5c,$74), ($46,$65,$51,$7f), ($54,$7e,$46,$62), ($5a,$77,$4b,$69), ($e0,$90,$d0,$b0), ($ee,$99,$dd,$bb), ($fc,$82,$ca,$a6), ($f2,$8b,$c7,$ad), ($d8,$b4,$e4,$9c), ($d6,$bd,$e9,$97), ($c4,$a6,$fe,$8a), ($ca,$af,$f3,$81), ($90,$d8,$b8,$e8), ($9e,$d1,$b5,$e3), ($8c,$ca,$a2,$fe), ($82,$c3,$af,$f5), ($a8,$fc,$8c,$c4), ($a6,$f5,$81,$cf), ($b4,$ee,$96,$d2), ($ba,$e7,$9b,$d9), ($db,$3b,$bb,$7b), ($d5,$32,$b6,$70), ($c7,$29,$a1,$6d), ($c9,$20,$ac,$66), ($e3,$1f,$8f,$57), ($ed,$16,$82,$5c), ($ff,$0d,$95,$41), ($f1,$04,$98,$4a), ($ab,$73,$d3,$23), ($a5,$7a,$de,$28), ($b7,$61,$c9,$35), ($b9,$68,$c4,$3e), ($93,$57,$e7,$0f), ($9d,$5e,$ea,$04), ($8f,$45,$fd,$19), ($81,$4c,$f0,$12), ($3b,$ab,$6b,$cb), ($35,$a2,$66,$c0), ($27,$b9,$71,$dd), ($29,$b0,$7c,$d6), ($03,$8f,$5f,$e7), ($0d,$86,$52,$ec), ($1f,$9d,$45,$f1), ($11,$94,$48,$fa), ($4b,$e3,$03,$93), ($45,$ea,$0e,$98), ($57,$f1,$19,$85), ($59,$f8,$14,$8e), ($73,$c7,$37,$bf), ($7d,$ce,$3a,$b4), ($6f,$d5,$2d,$a9), ($61,$dc,$20,$a2), ($ad,$76,$6d,$f6), ($a3,$7f,$60,$fd), ($b1,$64,$77,$e0), ($bf,$6d,$7a,$eb), ($95,$52,$59,$da), ($9b,$5b,$54,$d1), ($89,$40,$43,$cc), ($87,$49,$4e,$c7), ($dd,$3e,$05,$ae), ($d3,$37,$08,$a5), ($c1,$2c,$1f,$b8), ($cf,$25,$12,$b3), ($e5,$1a,$31,$82), ($eb,$13,$3c,$89), ($f9,$08,$2b,$94), ($f7,$01,$26,$9f), ($4d,$e6,$bd,$46), ($43,$ef,$b0,$4d), ($51,$f4,$a7,$50), ($5f,$fd,$aa,$5b), ($75,$c2,$89,$6a), ($7b,$cb,$84,$61), ($69,$d0,$93,$7c), ($67,$d9,$9e,$77), ($3d,$ae,$d5,$1e), ($33,$a7,$d8,$15), ($21,$bc,$cf,$08), ($2f,$b5,$c2,$03), ($05,$8a,$e1,$32), ($0b,$83,$ec,$39), ($19,$98,$fb,$24), ($17,$91,$f6,$2f), ($76,$4d,$d6,$8d), ($78,$44,$db,$86), ($6a,$5f,$cc,$9b), ($64,$56,$c1,$90), ($4e,$69,$e2,$a1), ($40,$60,$ef,$aa), ($52,$7b,$f8,$b7), ($5c,$72,$f5,$bc), ($06,$05,$be,$d5), ($08,$0c,$b3,$de), ($1a,$17,$a4,$c3), ($14,$1e,$a9,$c8), ($3e,$21,$8a,$f9), ($30,$28,$87,$f2), ($22,$33,$90,$ef), ($2c,$3a,$9d,$e4), ($96,$dd,$06,$3d), ($98,$d4,$0b,$36), ($8a,$cf,$1c,$2b), ($84,$c6,$11,$20), ($ae,$f9,$32,$11), ($a0,$f0,$3f,$1a), ($b2,$eb,$28,$07), ($bc,$e2,$25,$0c), ($e6,$95,$6e,$65), ($e8,$9c,$63,$6e), ($fa,$87,$74,$73), ($f4,$8e,$79,$78), ($de,$b1,$5a,$49), ($d0,$b8,$57,$42), ($c2,$a3,$40,$5f), ($cc,$aa,$4d,$54), ($41,$ec,$da,$f7), ($4f,$e5,$d7,$fc), ($5d,$fe,$c0,$e1), ($53,$f7,$cd,$ea), ($79,$c8,$ee,$db), ($77,$c1,$e3,$d0), ($65,$da,$f4,$cd), ($6b,$d3,$f9,$c6), ($31,$a4,$b2,$af), ($3f,$ad,$bf,$a4), ($2d,$b6,$a8,$b9), ($23,$bf,$a5,$b2), ($09,$80,$86,$83), ($07,$89,$8b,$88), ($15,$92,$9c,$95), ($1b,$9b,$91,$9e), ($a1,$7c,$0a,$47), ($af,$75,$07,$4c), ($bd,$6e,$10,$51), ($b3,$67,$1d,$5a), ($99,$58,$3e,$6b), ($97,$51,$33,$60), ($85,$4a,$24,$7d), ($8b,$43,$29,$76), ($d1,$34,$62,$1f), ($df,$3d,$6f,$14), ($cd,$26,$78,$09), ($c3,$2f,$75,$02), ($e9,$10,$56,$33), ($e7,$19,$5b,$38), ($f5,$02,$4c,$25), ($fb,$0b,$41,$2e), ($9a,$d7,$61,$8c), ($94,$de,$6c,$87), ($86,$c5,$7b,$9a), ($88,$cc,$76,$91), ($a2,$f3,$55,$a0), ($ac,$fa,$58,$ab), ($be,$e1,$4f,$b6), ($b0,$e8,$42,$bd), ($ea,$9f,$09,$d4), ($e4,$96,$04,$df), ($f6,$8d,$13,$c2), ($f8,$84,$1e,$c9), ($d2,$bb,$3d,$f8), ($dc,$b2,$30,$f3), ($ce,$a9,$27,$ee), ($c0,$a0,$2a,$e5), ($7a,$47,$b1,$3c), ($74,$4e,$bc,$37), ($66,$55,$ab,$2a), ($68,$5c,$a6,$21), ($42,$63,$85,$10), ($4c,$6a,$88,$1b), ($5e,$71,$9f,$06), ($50,$78,$92,$0d), ($0a,$0f,$d9,$64), ($04,$06,$d4,$6f), ($16,$1d,$c3,$72), ($18,$14,$ce,$79), ($32,$2b,$ed,$48), ($3c,$22,$e0,$43), ($2e,$39,$f7,$5e), ($20,$30,$fa,$55), ($ec,$9a,$b7,$01), ($e2,$93,$ba,$0a), ($f0,$88,$ad,$17), ($fe,$81,$a0,$1c), ($d4,$be,$83,$2d), ($da,$b7,$8e,$26), ($c8,$ac,$99,$3b), ($c6,$a5,$94,$30), ($9c,$d2,$df,$59), ($92,$db,$d2,$52), ($80,$c0,$c5,$4f), ($8e,$c9,$c8,$44), ($a4,$f6,$eb,$75), ($aa,$ff,$e6,$7e), ($b8,$e4,$f1,$63), ($b6,$ed,$fc,$68), ($0c,$0a,$67,$b1), ($02,$03,$6a,$ba), ($10,$18,$7d,$a7), ($1e,$11,$70,$ac), ($34,$2e,$53,$9d), ($3a,$27,$5e,$96), ($28,$3c,$49,$8b), ($26,$35,$44,$80), ($7c,$42,$0f,$e9), ($72,$4b,$02,$e2), ($60,$50,$15,$ff), ($6e,$59,$18,$f4), ($44,$66,$3b,$c5), ($4a,$6f,$36,$ce), ($58,$74,$21,$d3), ($56,$7d,$2c,$d8), ($37,$a1,$0c,$7a), ($39,$a8,$01,$71), ($2b,$b3,$16,$6c), ($25,$ba,$1b,$67), ($0f,$85,$38,$56), ($01,$8c,$35,$5d), ($13,$97,$22,$40), ($1d,$9e,$2f,$4b), ($47,$e9,$64,$22), ($49,$e0,$69,$29), ($5b,$fb,$7e,$34), ($55,$f2,$73,$3f), ($7f,$cd,$50,$0e), ($71,$c4,$5d,$05), ($63,$df,$4a,$18), ($6d,$d6,$47,$13), ($d7,$31,$dc,$ca), ($d9,$38,$d1,$c1), ($cb,$23,$c6,$dc), ($c5,$2a,$cb,$d7), ($ef,$15,$e8,$e6), ($e1,$1c,$e5,$ed), ($f3,$07,$f2,$f0), ($fd,$0e,$ff,$fb), ($a7,$79,$b4,$92), ($a9,$70,$b9,$99), ($bb,$6b,$ae,$84), ($b5,$62,$a3,$8f), ($9f,$5d,$80,$be), ($91,$54,$8d,$b5), ($83,$4f,$9a,$a8), ($8d,$46,$97,$a3)); U2: array[0..255,0..3] of byte= ( ($00,$00,$00,$00), ($0b,$0e,$09,$0d), ($16,$1c,$12,$1a), ($1d,$12,$1b,$17), ($2c,$38,$24,$34), ($27,$36,$2d,$39), ($3a,$24,$36,$2e), ($31,$2a,$3f,$23), ($58,$70,$48,$68), ($53,$7e,$41,$65), ($4e,$6c,$5a,$72), ($45,$62,$53,$7f), ($74,$48,$6c,$5c), ($7f,$46,$65,$51), ($62,$54,$7e,$46), ($69,$5a,$77,$4b), ($b0,$e0,$90,$d0), ($bb,$ee,$99,$dd), ($a6,$fc,$82,$ca), ($ad,$f2,$8b,$c7), ($9c,$d8,$b4,$e4), ($97,$d6,$bd,$e9), ($8a,$c4,$a6,$fe), ($81,$ca,$af,$f3), ($e8,$90,$d8,$b8), ($e3,$9e,$d1,$b5), ($fe,$8c,$ca,$a2), ($f5,$82,$c3,$af), ($c4,$a8,$fc,$8c), ($cf,$a6,$f5,$81), ($d2,$b4,$ee,$96), ($d9,$ba,$e7,$9b), ($7b,$db,$3b,$bb), ($70,$d5,$32,$b6), ($6d,$c7,$29,$a1), ($66,$c9,$20,$ac), ($57,$e3,$1f,$8f), ($5c,$ed,$16,$82), ($41,$ff,$0d,$95), ($4a,$f1,$04,$98), ($23,$ab,$73,$d3), ($28,$a5,$7a,$de), ($35,$b7,$61,$c9), ($3e,$b9,$68,$c4), ($0f,$93,$57,$e7), ($04,$9d,$5e,$ea), ($19,$8f,$45,$fd), ($12,$81,$4c,$f0), ($cb,$3b,$ab,$6b), ($c0,$35,$a2,$66), ($dd,$27,$b9,$71), ($d6,$29,$b0,$7c), ($e7,$03,$8f,$5f), ($ec,$0d,$86,$52), ($f1,$1f,$9d,$45), ($fa,$11,$94,$48), ($93,$4b,$e3,$03), ($98,$45,$ea,$0e), ($85,$57,$f1,$19), ($8e,$59,$f8,$14), ($bf,$73,$c7,$37), ($b4,$7d,$ce,$3a), ($a9,$6f,$d5,$2d), ($a2,$61,$dc,$20), ($f6,$ad,$76,$6d), ($fd,$a3,$7f,$60), ($e0,$b1,$64,$77), ($eb,$bf,$6d,$7a), ($da,$95,$52,$59), ($d1,$9b,$5b,$54), ($cc,$89,$40,$43), ($c7,$87,$49,$4e), ($ae,$dd,$3e,$05), ($a5,$d3,$37,$08), ($b8,$c1,$2c,$1f), ($b3,$cf,$25,$12), ($82,$e5,$1a,$31), ($89,$eb,$13,$3c), ($94,$f9,$08,$2b), ($9f,$f7,$01,$26), ($46,$4d,$e6,$bd), ($4d,$43,$ef,$b0), ($50,$51,$f4,$a7), ($5b,$5f,$fd,$aa), ($6a,$75,$c2,$89), ($61,$7b,$cb,$84), ($7c,$69,$d0,$93), ($77,$67,$d9,$9e), ($1e,$3d,$ae,$d5), ($15,$33,$a7,$d8), ($08,$21,$bc,$cf), ($03,$2f,$b5,$c2), ($32,$05,$8a,$e1), ($39,$0b,$83,$ec), ($24,$19,$98,$fb), ($2f,$17,$91,$f6), ($8d,$76,$4d,$d6), ($86,$78,$44,$db), ($9b,$6a,$5f,$cc), ($90,$64,$56,$c1), ($a1,$4e,$69,$e2), ($aa,$40,$60,$ef), ($b7,$52,$7b,$f8), ($bc,$5c,$72,$f5), ($d5,$06,$05,$be), ($de,$08,$0c,$b3), ($c3,$1a,$17,$a4), ($c8,$14,$1e,$a9), ($f9,$3e,$21,$8a), ($f2,$30,$28,$87), ($ef,$22,$33,$90), ($e4,$2c,$3a,$9d), ($3d,$96,$dd,$06), ($36,$98,$d4,$0b), ($2b,$8a,$cf,$1c), ($20,$84,$c6,$11), ($11,$ae,$f9,$32), ($1a,$a0,$f0,$3f), ($07,$b2,$eb,$28), ($0c,$bc,$e2,$25), ($65,$e6,$95,$6e), ($6e,$e8,$9c,$63), ($73,$fa,$87,$74), ($78,$f4,$8e,$79), ($49,$de,$b1,$5a), ($42,$d0,$b8,$57), ($5f,$c2,$a3,$40), ($54,$cc,$aa,$4d), ($f7,$41,$ec,$da), ($fc,$4f,$e5,$d7), ($e1,$5d,$fe,$c0), ($ea,$53,$f7,$cd), ($db,$79,$c8,$ee), ($d0,$77,$c1,$e3), ($cd,$65,$da,$f4), ($c6,$6b,$d3,$f9), ($af,$31,$a4,$b2), ($a4,$3f,$ad,$bf), ($b9,$2d,$b6,$a8), ($b2,$23,$bf,$a5), ($83,$09,$80,$86), ($88,$07,$89,$8b), ($95,$15,$92,$9c), ($9e,$1b,$9b,$91), ($47,$a1,$7c,$0a), ($4c,$af,$75,$07), ($51,$bd,$6e,$10), ($5a,$b3,$67,$1d), ($6b,$99,$58,$3e), ($60,$97,$51,$33), ($7d,$85,$4a,$24), ($76,$8b,$43,$29), ($1f,$d1,$34,$62), ($14,$df,$3d,$6f), ($09,$cd,$26,$78), ($02,$c3,$2f,$75), ($33,$e9,$10,$56), ($38,$e7,$19,$5b), ($25,$f5,$02,$4c), ($2e,$fb,$0b,$41), ($8c,$9a,$d7,$61), ($87,$94,$de,$6c), ($9a,$86,$c5,$7b), ($91,$88,$cc,$76), ($a0,$a2,$f3,$55), ($ab,$ac,$fa,$58), ($b6,$be,$e1,$4f), ($bd,$b0,$e8,$42), ($d4,$ea,$9f,$09), ($df,$e4,$96,$04), ($c2,$f6,$8d,$13), ($c9,$f8,$84,$1e), ($f8,$d2,$bb,$3d), ($f3,$dc,$b2,$30), ($ee,$ce,$a9,$27), ($e5,$c0,$a0,$2a), ($3c,$7a,$47,$b1), ($37,$74,$4e,$bc), ($2a,$66,$55,$ab), ($21,$68,$5c,$a6), ($10,$42,$63,$85), ($1b,$4c,$6a,$88), ($06,$5e,$71,$9f), ($0d,$50,$78,$92), ($64,$0a,$0f,$d9), ($6f,$04,$06,$d4), ($72,$16,$1d,$c3), ($79,$18,$14,$ce), ($48,$32,$2b,$ed), ($43,$3c,$22,$e0), ($5e,$2e,$39,$f7), ($55,$20,$30,$fa), ($01,$ec,$9a,$b7), ($0a,$e2,$93,$ba), ($17,$f0,$88,$ad), ($1c,$fe,$81,$a0), ($2d,$d4,$be,$83), ($26,$da,$b7,$8e), ($3b,$c8,$ac,$99), ($30,$c6,$a5,$94), ($59,$9c,$d2,$df), ($52,$92,$db,$d2), ($4f,$80,$c0,$c5), ($44,$8e,$c9,$c8), ($75,$a4,$f6,$eb), ($7e,$aa,$ff,$e6), ($63,$b8,$e4,$f1), ($68,$b6,$ed,$fc), ($b1,$0c,$0a,$67), ($ba,$02,$03,$6a), ($a7,$10,$18,$7d), ($ac,$1e,$11,$70), ($9d,$34,$2e,$53), ($96,$3a,$27,$5e), ($8b,$28,$3c,$49), ($80,$26,$35,$44), ($e9,$7c,$42,$0f), ($e2,$72,$4b,$02), ($ff,$60,$50,$15), ($f4,$6e,$59,$18), ($c5,$44,$66,$3b), ($ce,$4a,$6f,$36), ($d3,$58,$74,$21), ($d8,$56,$7d,$2c), ($7a,$37,$a1,$0c), ($71,$39,$a8,$01), ($6c,$2b,$b3,$16), ($67,$25,$ba,$1b), ($56,$0f,$85,$38), ($5d,$01,$8c,$35), ($40,$13,$97,$22), ($4b,$1d,$9e,$2f), ($22,$47,$e9,$64), ($29,$49,$e0,$69), ($34,$5b,$fb,$7e), ($3f,$55,$f2,$73), ($0e,$7f,$cd,$50), ($05,$71,$c4,$5d), ($18,$63,$df,$4a), ($13,$6d,$d6,$47), ($ca,$d7,$31,$dc), ($c1,$d9,$38,$d1), ($dc,$cb,$23,$c6), ($d7,$c5,$2a,$cb), ($e6,$ef,$15,$e8), ($ed,$e1,$1c,$e5), ($f0,$f3,$07,$f2), ($fb,$fd,$0e,$ff), ($92,$a7,$79,$b4), ($99,$a9,$70,$b9), ($84,$bb,$6b,$ae), ($8f,$b5,$62,$a3), ($be,$9f,$5d,$80), ($b5,$91,$54,$8d), ($a8,$83,$4f,$9a), ($a3,$8d,$46,$97)); U3: array[0..255,0..3] of byte= ( ($00,$00,$00,$00), ($0d,$0b,$0e,$09), ($1a,$16,$1c,$12), ($17,$1d,$12,$1b), ($34,$2c,$38,$24), ($39,$27,$36,$2d), ($2e,$3a,$24,$36), ($23,$31,$2a,$3f), ($68,$58,$70,$48), ($65,$53,$7e,$41), ($72,$4e,$6c,$5a), ($7f,$45,$62,$53), ($5c,$74,$48,$6c), ($51,$7f,$46,$65), ($46,$62,$54,$7e), ($4b,$69,$5a,$77), ($d0,$b0,$e0,$90), ($dd,$bb,$ee,$99), ($ca,$a6,$fc,$82), ($c7,$ad,$f2,$8b), ($e4,$9c,$d8,$b4), ($e9,$97,$d6,$bd), ($fe,$8a,$c4,$a6), ($f3,$81,$ca,$af), ($b8,$e8,$90,$d8), ($b5,$e3,$9e,$d1), ($a2,$fe,$8c,$ca), ($af,$f5,$82,$c3), ($8c,$c4,$a8,$fc), ($81,$cf,$a6,$f5), ($96,$d2,$b4,$ee), ($9b,$d9,$ba,$e7), ($bb,$7b,$db,$3b), ($b6,$70,$d5,$32), ($a1,$6d,$c7,$29), ($ac,$66,$c9,$20), ($8f,$57,$e3,$1f), ($82,$5c,$ed,$16), ($95,$41,$ff,$0d), ($98,$4a,$f1,$04), ($d3,$23,$ab,$73), ($de,$28,$a5,$7a), ($c9,$35,$b7,$61), ($c4,$3e,$b9,$68), ($e7,$0f,$93,$57), ($ea,$04,$9d,$5e), ($fd,$19,$8f,$45), ($f0,$12,$81,$4c), ($6b,$cb,$3b,$ab), ($66,$c0,$35,$a2), ($71,$dd,$27,$b9), ($7c,$d6,$29,$b0), ($5f,$e7,$03,$8f), ($52,$ec,$0d,$86), ($45,$f1,$1f,$9d), ($48,$fa,$11,$94), ($03,$93,$4b,$e3), ($0e,$98,$45,$ea), ($19,$85,$57,$f1), ($14,$8e,$59,$f8), ($37,$bf,$73,$c7), ($3a,$b4,$7d,$ce), ($2d,$a9,$6f,$d5), ($20,$a2,$61,$dc), ($6d,$f6,$ad,$76), ($60,$fd,$a3,$7f), ($77,$e0,$b1,$64), ($7a,$eb,$bf,$6d), ($59,$da,$95,$52), ($54,$d1,$9b,$5b), ($43,$cc,$89,$40), ($4e,$c7,$87,$49), ($05,$ae,$dd,$3e), ($08,$a5,$d3,$37), ($1f,$b8,$c1,$2c), ($12,$b3,$cf,$25), ($31,$82,$e5,$1a), ($3c,$89,$eb,$13), ($2b,$94,$f9,$08), ($26,$9f,$f7,$01), ($bd,$46,$4d,$e6), ($b0,$4d,$43,$ef), ($a7,$50,$51,$f4), ($aa,$5b,$5f,$fd), ($89,$6a,$75,$c2), ($84,$61,$7b,$cb), ($93,$7c,$69,$d0), ($9e,$77,$67,$d9), ($d5,$1e,$3d,$ae), ($d8,$15,$33,$a7), ($cf,$08,$21,$bc), ($c2,$03,$2f,$b5), ($e1,$32,$05,$8a), ($ec,$39,$0b,$83), ($fb,$24,$19,$98), ($f6,$2f,$17,$91), ($d6,$8d,$76,$4d), ($db,$86,$78,$44), ($cc,$9b,$6a,$5f), ($c1,$90,$64,$56), ($e2,$a1,$4e,$69), ($ef,$aa,$40,$60), ($f8,$b7,$52,$7b), ($f5,$bc,$5c,$72), ($be,$d5,$06,$05), ($b3,$de,$08,$0c), ($a4,$c3,$1a,$17), ($a9,$c8,$14,$1e), ($8a,$f9,$3e,$21), ($87,$f2,$30,$28), ($90,$ef,$22,$33), ($9d,$e4,$2c,$3a), ($06,$3d,$96,$dd), ($0b,$36,$98,$d4), ($1c,$2b,$8a,$cf), ($11,$20,$84,$c6), ($32,$11,$ae,$f9), ($3f,$1a,$a0,$f0), ($28,$07,$b2,$eb), ($25,$0c,$bc,$e2), ($6e,$65,$e6,$95), ($63,$6e,$e8,$9c), ($74,$73,$fa,$87), ($79,$78,$f4,$8e), ($5a,$49,$de,$b1), ($57,$42,$d0,$b8), ($40,$5f,$c2,$a3), ($4d,$54,$cc,$aa), ($da,$f7,$41,$ec), ($d7,$fc,$4f,$e5), ($c0,$e1,$5d,$fe), ($cd,$ea,$53,$f7), ($ee,$db,$79,$c8), ($e3,$d0,$77,$c1), ($f4,$cd,$65,$da), ($f9,$c6,$6b,$d3), ($b2,$af,$31,$a4), ($bf,$a4,$3f,$ad), ($a8,$b9,$2d,$b6), ($a5,$b2,$23,$bf), ($86,$83,$09,$80), ($8b,$88,$07,$89), ($9c,$95,$15,$92), ($91,$9e,$1b,$9b), ($0a,$47,$a1,$7c), ($07,$4c,$af,$75), ($10,$51,$bd,$6e), ($1d,$5a,$b3,$67), ($3e,$6b,$99,$58), ($33,$60,$97,$51), ($24,$7d,$85,$4a), ($29,$76,$8b,$43), ($62,$1f,$d1,$34), ($6f,$14,$df,$3d), ($78,$09,$cd,$26), ($75,$02,$c3,$2f), ($56,$33,$e9,$10), ($5b,$38,$e7,$19), ($4c,$25,$f5,$02), ($41,$2e,$fb,$0b), ($61,$8c,$9a,$d7), ($6c,$87,$94,$de), ($7b,$9a,$86,$c5), ($76,$91,$88,$cc), ($55,$a0,$a2,$f3), ($58,$ab,$ac,$fa), ($4f,$b6,$be,$e1), ($42,$bd,$b0,$e8), ($09,$d4,$ea,$9f), ($04,$df,$e4,$96), ($13,$c2,$f6,$8d), ($1e,$c9,$f8,$84), ($3d,$f8,$d2,$bb), ($30,$f3,$dc,$b2), ($27,$ee,$ce,$a9), ($2a,$e5,$c0,$a0), ($b1,$3c,$7a,$47), ($bc,$37,$74,$4e), ($ab,$2a,$66,$55), ($a6,$21,$68,$5c), ($85,$10,$42,$63), ($88,$1b,$4c,$6a), ($9f,$06,$5e,$71), ($92,$0d,$50,$78), ($d9,$64,$0a,$0f), ($d4,$6f,$04,$06), ($c3,$72,$16,$1d), ($ce,$79,$18,$14), ($ed,$48,$32,$2b), ($e0,$43,$3c,$22), ($f7,$5e,$2e,$39), ($fa,$55,$20,$30), ($b7,$01,$ec,$9a), ($ba,$0a,$e2,$93), ($ad,$17,$f0,$88), ($a0,$1c,$fe,$81), ($83,$2d,$d4,$be), ($8e,$26,$da,$b7), ($99,$3b,$c8,$ac), ($94,$30,$c6,$a5), ($df,$59,$9c,$d2), ($d2,$52,$92,$db), ($c5,$4f,$80,$c0), ($c8,$44,$8e,$c9), ($eb,$75,$a4,$f6), ($e6,$7e,$aa,$ff), ($f1,$63,$b8,$e4), ($fc,$68,$b6,$ed), ($67,$b1,$0c,$0a), ($6a,$ba,$02,$03), ($7d,$a7,$10,$18), ($70,$ac,$1e,$11), ($53,$9d,$34,$2e), ($5e,$96,$3a,$27), ($49,$8b,$28,$3c), ($44,$80,$26,$35), ($0f,$e9,$7c,$42), ($02,$e2,$72,$4b), ($15,$ff,$60,$50), ($18,$f4,$6e,$59), ($3b,$c5,$44,$66), ($36,$ce,$4a,$6f), ($21,$d3,$58,$74), ($2c,$d8,$56,$7d), ($0c,$7a,$37,$a1), ($01,$71,$39,$a8), ($16,$6c,$2b,$b3), ($1b,$67,$25,$ba), ($38,$56,$0f,$85), ($35,$5d,$01,$8c), ($22,$40,$13,$97), ($2f,$4b,$1d,$9e), ($64,$22,$47,$e9), ($69,$29,$49,$e0), ($7e,$34,$5b,$fb), ($73,$3f,$55,$f2), ($50,$0e,$7f,$cd), ($5d,$05,$71,$c4), ($4a,$18,$63,$df), ($47,$13,$6d,$d6), ($dc,$ca,$d7,$31), ($d1,$c1,$d9,$38), ($c6,$dc,$cb,$23), ($cb,$d7,$c5,$2a), ($e8,$e6,$ef,$15), ($e5,$ed,$e1,$1c), ($f2,$f0,$f3,$07), ($ff,$fb,$fd,$0e), ($b4,$92,$a7,$79), ($b9,$99,$a9,$70), ($ae,$84,$bb,$6b), ($a3,$8f,$b5,$62), ($80,$be,$9f,$5d), ($8d,$b5,$91,$54), ($9a,$a8,$83,$4f), ($97,$a3,$8d,$46)); U4: array[0..255,0..3] of byte= ( ($00,$00,$00,$00), ($09,$0d,$0b,$0e), ($12,$1a,$16,$1c), ($1b,$17,$1d,$12), ($24,$34,$2c,$38), ($2d,$39,$27,$36), ($36,$2e,$3a,$24), ($3f,$23,$31,$2a), ($48,$68,$58,$70), ($41,$65,$53,$7e), ($5a,$72,$4e,$6c), ($53,$7f,$45,$62), ($6c,$5c,$74,$48), ($65,$51,$7f,$46), ($7e,$46,$62,$54), ($77,$4b,$69,$5a), ($90,$d0,$b0,$e0), ($99,$dd,$bb,$ee), ($82,$ca,$a6,$fc), ($8b,$c7,$ad,$f2), ($b4,$e4,$9c,$d8), ($bd,$e9,$97,$d6), ($a6,$fe,$8a,$c4), ($af,$f3,$81,$ca), ($d8,$b8,$e8,$90), ($d1,$b5,$e3,$9e), ($ca,$a2,$fe,$8c), ($c3,$af,$f5,$82), ($fc,$8c,$c4,$a8), ($f5,$81,$cf,$a6), ($ee,$96,$d2,$b4), ($e7,$9b,$d9,$ba), ($3b,$bb,$7b,$db), ($32,$b6,$70,$d5), ($29,$a1,$6d,$c7), ($20,$ac,$66,$c9), ($1f,$8f,$57,$e3), ($16,$82,$5c,$ed), ($0d,$95,$41,$ff), ($04,$98,$4a,$f1), ($73,$d3,$23,$ab), ($7a,$de,$28,$a5), ($61,$c9,$35,$b7), ($68,$c4,$3e,$b9), ($57,$e7,$0f,$93), ($5e,$ea,$04,$9d), ($45,$fd,$19,$8f), ($4c,$f0,$12,$81), ($ab,$6b,$cb,$3b), ($a2,$66,$c0,$35), ($b9,$71,$dd,$27), ($b0,$7c,$d6,$29), ($8f,$5f,$e7,$03), ($86,$52,$ec,$0d), ($9d,$45,$f1,$1f), ($94,$48,$fa,$11), ($e3,$03,$93,$4b), ($ea,$0e,$98,$45), ($f1,$19,$85,$57), ($f8,$14,$8e,$59), ($c7,$37,$bf,$73), ($ce,$3a,$b4,$7d), ($d5,$2d,$a9,$6f), ($dc,$20,$a2,$61), ($76,$6d,$f6,$ad), ($7f,$60,$fd,$a3), ($64,$77,$e0,$b1), ($6d,$7a,$eb,$bf), ($52,$59,$da,$95), ($5b,$54,$d1,$9b), ($40,$43,$cc,$89), ($49,$4e,$c7,$87), ($3e,$05,$ae,$dd), ($37,$08,$a5,$d3), ($2c,$1f,$b8,$c1), ($25,$12,$b3,$cf), ($1a,$31,$82,$e5), ($13,$3c,$89,$eb), ($08,$2b,$94,$f9), ($01,$26,$9f,$f7), ($e6,$bd,$46,$4d), ($ef,$b0,$4d,$43), ($f4,$a7,$50,$51), ($fd,$aa,$5b,$5f), ($c2,$89,$6a,$75), ($cb,$84,$61,$7b), ($d0,$93,$7c,$69), ($d9,$9e,$77,$67), ($ae,$d5,$1e,$3d), ($a7,$d8,$15,$33), ($bc,$cf,$08,$21), ($b5,$c2,$03,$2f), ($8a,$e1,$32,$05), ($83,$ec,$39,$0b), ($98,$fb,$24,$19), ($91,$f6,$2f,$17), ($4d,$d6,$8d,$76), ($44,$db,$86,$78), ($5f,$cc,$9b,$6a), ($56,$c1,$90,$64), ($69,$e2,$a1,$4e), ($60,$ef,$aa,$40), ($7b,$f8,$b7,$52), ($72,$f5,$bc,$5c), ($05,$be,$d5,$06), ($0c,$b3,$de,$08), ($17,$a4,$c3,$1a), ($1e,$a9,$c8,$14), ($21,$8a,$f9,$3e), ($28,$87,$f2,$30), ($33,$90,$ef,$22), ($3a,$9d,$e4,$2c), ($dd,$06,$3d,$96), ($d4,$0b,$36,$98), ($cf,$1c,$2b,$8a), ($c6,$11,$20,$84), ($f9,$32,$11,$ae), ($f0,$3f,$1a,$a0), ($eb,$28,$07,$b2), ($e2,$25,$0c,$bc), ($95,$6e,$65,$e6), ($9c,$63,$6e,$e8), ($87,$74,$73,$fa), ($8e,$79,$78,$f4), ($b1,$5a,$49,$de), ($b8,$57,$42,$d0), ($a3,$40,$5f,$c2), ($aa,$4d,$54,$cc), ($ec,$da,$f7,$41), ($e5,$d7,$fc,$4f), ($fe,$c0,$e1,$5d), ($f7,$cd,$ea,$53), ($c8,$ee,$db,$79), ($c1,$e3,$d0,$77), ($da,$f4,$cd,$65), ($d3,$f9,$c6,$6b), ($a4,$b2,$af,$31), ($ad,$bf,$a4,$3f), ($b6,$a8,$b9,$2d), ($bf,$a5,$b2,$23), ($80,$86,$83,$09), ($89,$8b,$88,$07), ($92,$9c,$95,$15), ($9b,$91,$9e,$1b), ($7c,$0a,$47,$a1), ($75,$07,$4c,$af), ($6e,$10,$51,$bd), ($67,$1d,$5a,$b3), ($58,$3e,$6b,$99), ($51,$33,$60,$97), ($4a,$24,$7d,$85), ($43,$29,$76,$8b), ($34,$62,$1f,$d1), ($3d,$6f,$14,$df), ($26,$78,$09,$cd), ($2f,$75,$02,$c3), ($10,$56,$33,$e9), ($19,$5b,$38,$e7), ($02,$4c,$25,$f5), ($0b,$41,$2e,$fb), ($d7,$61,$8c,$9a), ($de,$6c,$87,$94), ($c5,$7b,$9a,$86), ($cc,$76,$91,$88), ($f3,$55,$a0,$a2), ($fa,$58,$ab,$ac), ($e1,$4f,$b6,$be), ($e8,$42,$bd,$b0), ($9f,$09,$d4,$ea), ($96,$04,$df,$e4), ($8d,$13,$c2,$f6), ($84,$1e,$c9,$f8), ($bb,$3d,$f8,$d2), ($b2,$30,$f3,$dc), ($a9,$27,$ee,$ce), ($a0,$2a,$e5,$c0), ($47,$b1,$3c,$7a), ($4e,$bc,$37,$74), ($55,$ab,$2a,$66), ($5c,$a6,$21,$68), ($63,$85,$10,$42), ($6a,$88,$1b,$4c), ($71,$9f,$06,$5e), ($78,$92,$0d,$50), ($0f,$d9,$64,$0a), ($06,$d4,$6f,$04), ($1d,$c3,$72,$16), ($14,$ce,$79,$18), ($2b,$ed,$48,$32), ($22,$e0,$43,$3c), ($39,$f7,$5e,$2e), ($30,$fa,$55,$20), ($9a,$b7,$01,$ec), ($93,$ba,$0a,$e2), ($88,$ad,$17,$f0), ($81,$a0,$1c,$fe), ($be,$83,$2d,$d4), ($b7,$8e,$26,$da), ($ac,$99,$3b,$c8), ($a5,$94,$30,$c6), ($d2,$df,$59,$9c), ($db,$d2,$52,$92), ($c0,$c5,$4f,$80), ($c9,$c8,$44,$8e), ($f6,$eb,$75,$a4), ($ff,$e6,$7e,$aa), ($e4,$f1,$63,$b8), ($ed,$fc,$68,$b6), ($0a,$67,$b1,$0c), ($03,$6a,$ba,$02), ($18,$7d,$a7,$10), ($11,$70,$ac,$1e), ($2e,$53,$9d,$34), ($27,$5e,$96,$3a), ($3c,$49,$8b,$28), ($35,$44,$80,$26), ($42,$0f,$e9,$7c), ($4b,$02,$e2,$72), ($50,$15,$ff,$60), ($59,$18,$f4,$6e), ($66,$3b,$c5,$44), ($6f,$36,$ce,$4a), ($74,$21,$d3,$58), ($7d,$2c,$d8,$56), ($a1,$0c,$7a,$37), ($a8,$01,$71,$39), ($b3,$16,$6c,$2b), ($ba,$1b,$67,$25), ($85,$38,$56,$0f), ($8c,$35,$5d,$01), ($97,$22,$40,$13), ($9e,$2f,$4b,$1d), ($e9,$64,$22,$47), ($e0,$69,$29,$49), ($fb,$7e,$34,$5b), ($f2,$73,$3f,$55), ($cd,$50,$0e,$7f), ($c4,$5d,$05,$71), ($df,$4a,$18,$63), ($d6,$47,$13,$6d), ($31,$dc,$ca,$d7), ($38,$d1,$c1,$d9), ($23,$c6,$dc,$cb), ($2a,$cb,$d7,$c5), ($15,$e8,$e6,$ef), ($1c,$e5,$ed,$e1), ($07,$f2,$f0,$f3), ($0e,$ff,$fb,$fd), ($79,$b4,$92,$a7), ($70,$b9,$99,$a9), ($6b,$ae,$84,$bb), ($62,$a3,$8f,$b5), ($5d,$80,$be,$9f), ($54,$8d,$b5,$91), ($4f,$9a,$a8,$83), ($46,$97,$a3,$8d)); rcon: array[0..29] of cardinal= ( $01, $02, $04, $08, $10, $20, $40, $80, $1b, $36, $6c, $d8, $ab, $4d, $9a, $2f, $5e, $bc, $63, $c6, $97, $35, $6a, $d4, $b3, $7d, $fa, $ef, $c5, $91); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/Ciphers/dcprijndael.pas�����������������������������������������0000664�0001750�0001750�00000030616�13157542637�023126� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of Rijndael *****************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPrijndael; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers; const BC= 4; MAXROUNDS= 14; type TDCP_rijndael= class(TDCP_blockcipher128) protected numrounds: longword; rk, drk: array[0..MAXROUNDS,0..7] of DWord; procedure InitKey(const Key; Size: longword); override; public class function GetID: integer; override; class function GetAlgorithm: string; override; class function GetMaxKeySize: integer; override; class function SelfTest: boolean; override; procedure Burn; override; procedure EncryptECB(const InData; var OutData); override; procedure DecryptECB(const InData; var OutData); override; end; {******************************************************************************} {******************************************************************************} implementation {$R-}{$Q-} {$I DCPrijndael.inc} class function TDCP_rijndael.GetMaxKeySize: integer; begin Result:= 256; end; class function TDCP_rijndael.GetID: integer; begin Result:= DCP_rijndael; end; class function TDCP_rijndael.GetAlgorithm: string; begin Result:= 'Rijndael'; end; class function TDCP_rijndael.SelfTest: boolean; const Key1: array[0..15] of byte= ($00,$01,$02,$03,$05,$06,$07,$08,$0A,$0B,$0C,$0D,$0F,$10,$11,$12); InData1: array[0..15] of byte= ($50,$68,$12,$A4,$5F,$08,$C8,$89,$B9,$7F,$59,$80,$03,$8B,$83,$59); OutData1: array[0..15] of byte= ($D8,$F5,$32,$53,$82,$89,$EF,$7D,$06,$B5,$06,$A4,$FD,$5B,$E9,$C9); Key2: array[0..23] of byte= ($A0,$A1,$A2,$A3,$A5,$A6,$A7,$A8,$AA,$AB,$AC,$AD,$AF,$B0,$B1,$B2, $B4,$B5,$B6,$B7,$B9,$BA,$BB,$BC); InData2: array[0..15] of byte= ($4F,$1C,$76,$9D,$1E,$5B,$05,$52,$C7,$EC,$A8,$4D,$EA,$26,$A5,$49); OutData2: array[0..15] of byte= ($F3,$84,$72,$10,$D5,$39,$1E,$23,$60,$60,$8E,$5A,$CB,$56,$05,$81); Key3: array[0..31] of byte= ($00,$01,$02,$03,$05,$06,$07,$08,$0A,$0B,$0C,$0D,$0F,$10,$11,$12, $14,$15,$16,$17,$19,$1A,$1B,$1C,$1E,$1F,$20,$21,$23,$24,$25,$26); InData3: array[0..15] of byte= ($5E,$25,$CA,$78,$F0,$DE,$55,$80,$25,$24,$D3,$8D,$A3,$FE,$44,$56); OutData3: array[0..15] of byte= ($E8,$B7,$2B,$4E,$8B,$E2,$43,$43,$8C,$9F,$FF,$1F,$0E,$20,$58,$72); var Block: array[0..15] of byte; Cipher: TDCP_rijndael; begin dcpFillChar(Block, SizeOf(Block), 0); Cipher:= TDCP_rijndael.Create(nil); Cipher.Init(Key1,Sizeof(Key1)*8,nil); Cipher.EncryptECB(InData1,Block); Result:= boolean(CompareMem(@Block,@OutData1,16)); Cipher.DecryptECB(Block,Block); Cipher.Burn; Result:= Result and boolean(CompareMem(@Block,@InData1,16)); Cipher.Init(Key2,Sizeof(Key2)*8,nil); Cipher.EncryptECB(InData2,Block); Result:= Result and boolean(CompareMem(@Block,@OutData2,16)); Cipher.DecryptECB(Block,Block); Cipher.Burn; Result:= Result and boolean(CompareMem(@Block,@InData2,16)); Cipher.Init(Key3,Sizeof(Key3)*8,nil); Cipher.EncryptECB(InData3,Block); Result:= Result and boolean(CompareMem(@Block,@OutData3,16)); Cipher.DecryptECB(Block,Block); Cipher.Burn; Result:= Result and boolean(CompareMem(@Block,@InData3,16)); Cipher.Free; end; procedure InvMixColumn(a: PByteArray; BC: byte); var j: longword; begin for j:= 0 to (BC-1) do PDWord(@(a^[j*4]))^:= PDWord(@U1[a^[j*4+0]])^ xor PDWord(@U2[a^[j*4+1]])^ xor PDWord(@U3[a^[j*4+2]])^ xor PDWord(@U4[a^[j*4+3]])^; end; procedure TDCP_rijndael.InitKey(const Key; Size: longword); var KC, ROUNDS, j, r, t, rconpointer: longword; tk: array[0..MAXKC-1,0..3] of byte; begin Size:= Size div 8; dcpFillChar(tk,Sizeof(tk),0); Move(Key,tk,Size); if Size<= 16 then begin KC:= 4; Rounds:= 10; end else if Size<= 24 then begin KC:= 6; Rounds:= 12; end else begin KC:= 8; Rounds:= 14; end; numrounds:= rounds; r:= 0; t:= 0; j:= 0; while (j< KC) and (r< (rounds+1)) do begin while (j< KC) and (t< BC) do begin rk[r,t]:= PDWord(@tk[j])^; Inc(j); Inc(t); end; if t= BC then begin t:= 0; Inc(r); end; end; rconpointer:= 0; while (r< (rounds+1)) do begin tk[0,0]:= tk[0,0] xor S[tk[KC-1,1]]; tk[0,1]:= tk[0,1] xor S[tk[KC-1,2]]; tk[0,2]:= tk[0,2] xor S[tk[KC-1,3]]; tk[0,3]:= tk[0,3] xor S[tk[KC-1,0]]; tk[0,0]:= tk[0,0] xor rcon[rconpointer]; Inc(rconpointer); if KC<> 8 then begin for j:= 1 to (KC-1) do PDWord(@tk[j])^:= PDWord(@tk[j])^ xor PDWord(@tk[j-1])^; end else begin for j:= 1 to ((KC div 2)-1) do PDWord(@tk[j])^:= PDWord(@tk[j])^ xor PDWord(@tk[j-1])^; tk[KC div 2,0]:= tk[KC div 2,0] xor S[tk[KC div 2 - 1,0]]; tk[KC div 2,1]:= tk[KC div 2,1] xor S[tk[KC div 2 - 1,1]]; tk[KC div 2,2]:= tk[KC div 2,2] xor S[tk[KC div 2 - 1,2]]; tk[KC div 2,3]:= tk[KC div 2,3] xor S[tk[KC div 2 - 1,3]]; for j:= ((KC div 2) + 1) to (KC-1) do PDWord(@tk[j])^:= PDWord(@tk[j])^ xor PDWord(@tk[j-1])^; end; j:= 0; while (j< KC) and (r< (rounds+1)) do begin while (j< KC) and (t< BC) do begin rk[r,t]:= PDWord(@tk[j])^; Inc(j); Inc(t); end; if t= BC then begin Inc(r); t:= 0; end; end; end; Move(rk,drk,Sizeof(rk)); for r:= 1 to (numrounds-1) do InvMixColumn(@drk[r],BC); end; procedure TDCP_rijndael.Burn; begin numrounds:= 0; FillChar(rk,Sizeof(rk),0); FillChar(drk,Sizeof(drk),0); inherited Burn; end; procedure TDCP_rijndael.EncryptECB(const InData; var OutData); var r: longword; tempb: array[0..MAXBC-1,0..3] of byte; a: array[0..MAXBC,0..3] of byte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); PDword(@a[0,0])^:= PDword(@InData)^; PDword(@a[1,0])^:= PDword(pointer(@InData)+4)^; PDword(@a[2,0])^:= PDword(pointer(@InData)+8)^; PDword(@a[3,0])^:= PDword(pointer(@InData)+12)^; for r:= 0 to (numrounds-2) do begin PDWord(@tempb[0])^:= PDWord(@a[0])^ xor rk[r,0]; PDWord(@tempb[1])^:= PDWord(@a[1])^ xor rk[r,1]; PDWord(@tempb[2])^:= PDWord(@a[2])^ xor rk[r,2]; PDWord(@tempb[3])^:= PDWord(@a[3])^ xor rk[r,3]; PDWord(@a[0])^:= PDWord(@T1[tempb[0,0]])^ xor PDWord(@T2[tempb[1,1]])^ xor PDWord(@T3[tempb[2,2]])^ xor PDWord(@T4[tempb[3,3]])^; PDWord(@a[1])^:= PDWord(@T1[tempb[1,0]])^ xor PDWord(@T2[tempb[2,1]])^ xor PDWord(@T3[tempb[3,2]])^ xor PDWord(@T4[tempb[0,3]])^; PDWord(@a[2])^:= PDWord(@T1[tempb[2,0]])^ xor PDWord(@T2[tempb[3,1]])^ xor PDWord(@T3[tempb[0,2]])^ xor PDWord(@T4[tempb[1,3]])^; PDWord(@a[3])^:= PDWord(@T1[tempb[3,0]])^ xor PDWord(@T2[tempb[0,1]])^ xor PDWord(@T3[tempb[1,2]])^ xor PDWord(@T4[tempb[2,3]])^; end; PDWord(@tempb[0])^:= PDWord(@a[0])^ xor rk[numrounds-1,0]; PDWord(@tempb[1])^:= PDWord(@a[1])^ xor rk[numrounds-1,1]; PDWord(@tempb[2])^:= PDWord(@a[2])^ xor rk[numrounds-1,2]; PDWord(@tempb[3])^:= PDWord(@a[3])^ xor rk[numrounds-1,3]; a[0,0]:= T1[tempb[0,0],1]; a[0,1]:= T1[tempb[1,1],1]; a[0,2]:= T1[tempb[2,2],1]; a[0,3]:= T1[tempb[3,3],1]; a[1,0]:= T1[tempb[1,0],1]; a[1,1]:= T1[tempb[2,1],1]; a[1,2]:= T1[tempb[3,2],1]; a[1,3]:= T1[tempb[0,3],1]; a[2,0]:= T1[tempb[2,0],1]; a[2,1]:= T1[tempb[3,1],1]; a[2,2]:= T1[tempb[0,2],1]; a[2,3]:= T1[tempb[1,3],1]; a[3,0]:= T1[tempb[3,0],1]; a[3,1]:= T1[tempb[0,1],1]; a[3,2]:= T1[tempb[1,2],1]; a[3,3]:= T1[tempb[2,3],1]; PDWord(@a[0])^:= PDWord(@a[0])^ xor rk[numrounds,0]; PDWord(@a[1])^:= PDWord(@a[1])^ xor rk[numrounds,1]; PDWord(@a[2])^:= PDWord(@a[2])^ xor rk[numrounds,2]; PDWord(@a[3])^:= PDWord(@a[3])^ xor rk[numrounds,3]; PDword(@OutData)^:= PDword(@a[0,0])^; PDword(pointer(@OutData)+4)^:= PDword(@a[1,0])^; PDword(pointer(@OutData)+8)^:= PDword(@a[2,0])^; PDword(pointer(@OutData)+12)^:= PDword(@a[3,0])^; end; procedure TDCP_rijndael.DecryptECB(const InData; var OutData); var r: longword; tempb: array[0..MAXBC-1,0..3] of byte; a: array[0..MAXBC,0..3] of byte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); PDword(@a[0,0])^:= PDword(@InData)^; PDword(@a[1,0])^:= PDword(pointer(@InData)+4)^; PDword(@a[2,0])^:= PDword(pointer(@InData)+8)^; PDword(@a[3,0])^:= PDword(pointer(@InData)+12)^; for r:= NumRounds downto 2 do begin PDWord(@tempb[0])^:= PDWord(@a[0])^ xor drk[r,0]; PDWord(@tempb[1])^:= PDWord(@a[1])^ xor drk[r,1]; PDWord(@tempb[2])^:= PDWord(@a[2])^ xor drk[r,2]; PDWord(@tempb[3])^:= PDWord(@a[3])^ xor drk[r,3]; PDWord(@a[0])^:= PDWord(@T5[tempb[0,0]])^ xor PDWord(@T6[tempb[3,1]])^ xor PDWord(@T7[tempb[2,2]])^ xor PDWord(@T8[tempb[1,3]])^; PDWord(@a[1])^:= PDWord(@T5[tempb[1,0]])^ xor PDWord(@T6[tempb[0,1]])^ xor PDWord(@T7[tempb[3,2]])^ xor PDWord(@T8[tempb[2,3]])^; PDWord(@a[2])^:= PDWord(@T5[tempb[2,0]])^ xor PDWord(@T6[tempb[1,1]])^ xor PDWord(@T7[tempb[0,2]])^ xor PDWord(@T8[tempb[3,3]])^; PDWord(@a[3])^:= PDWord(@T5[tempb[3,0]])^ xor PDWord(@T6[tempb[2,1]])^ xor PDWord(@T7[tempb[1,2]])^ xor PDWord(@T8[tempb[0,3]])^; end; PDWord(@tempb[0])^:= PDWord(@a[0])^ xor drk[1,0]; PDWord(@tempb[1])^:= PDWord(@a[1])^ xor drk[1,1]; PDWord(@tempb[2])^:= PDWord(@a[2])^ xor drk[1,2]; PDWord(@tempb[3])^:= PDWord(@a[3])^ xor drk[1,3]; a[0,0]:= S5[tempb[0,0]]; a[0,1]:= S5[tempb[3,1]]; a[0,2]:= S5[tempb[2,2]]; a[0,3]:= S5[tempb[1,3]]; a[1,0]:= S5[tempb[1,0]]; a[1,1]:= S5[tempb[0,1]]; a[1,2]:= S5[tempb[3,2]]; a[1,3]:= S5[tempb[2,3]]; a[2,0]:= S5[tempb[2,0]]; a[2,1]:= S5[tempb[1,1]]; a[2,2]:= S5[tempb[0,2]]; a[2,3]:= S5[tempb[3,3]]; a[3,0]:= S5[tempb[3,0]]; a[3,1]:= S5[tempb[2,1]]; a[3,2]:= S5[tempb[1,2]]; a[3,3]:= S5[tempb[0,3]]; PDWord(@a[0])^:= PDWord(@a[0])^ xor drk[0,0]; PDWord(@a[1])^:= PDWord(@a[1])^ xor drk[0,1]; PDWord(@a[2])^:= PDWord(@a[2])^ xor drk[0,2]; PDWord(@a[3])^:= PDWord(@a[3])^ xor drk[0,3]; PDword(@OutData)^:= PDword(@a[0,0])^; PDword(pointer(@OutData)+4)^:= PDword(@a[1,0])^; PDword(pointer(@OutData)+8)^:= PDword(@a[2,0])^; PDword(pointer(@OutData)+12)^:= PDword(@a[3,0])^; end; end. ������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/Readme.txt������������������������������������������������������0000664�0001750�0001750�00000011257�12014201074�020455� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= = DCPcrypt Cryptographic Component Library v2 Beta 3 = = Copyright (c) 1999-2003 David Barton = = http://www.cityinthesky.co.uk/ = = crypto@cityinthesky.co.uk = =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Introduction: DCPcrypt is a collection of cryptographic components for the Borland Delphi(tm), C++ Builder(tm) and Kylix(tm) programming languages. The supported versions are Delphi 4, 5, 6, 7, 2005, C++ Builder (3?), 4, 5, (6?) and Kylix 1 (untested), 2 and 3 (untested). Thanks to Manuel C. for the modifications to make DCPcrypt work under Delphi 2005! The idea behind DCPcrypt is that it should be possible to "drop in" any algorithm implementation to replace another with minimum or no code changes. To aid in this goal all cryptographic components are descended from one of several base classes, TDCP_cipher for encryption algorithms and TDCP_hash for message digest algorithms. DCPcrypt is open source software (released under the MIT license) and as such there is no charge for inclusion in other software. However, I am currently a student and if you are making money from my software I would really appreciate a donation of some sort, whether financial or a license for the software you develop (or if anyone wants to sponsor a Mathematical Modelling (Masters) student for their final year...). Please note THIS IS NOT COMPULSORY IN ANY WAY. See http://www.cityinthesky.co.uk/cryptography.html for details on financial donations. This software is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative. If you maintain a website then a link to my page at http://www.cityinthesky.co.uk/ would be great! What's New: Changes since DCPcrypt v2 Beta 2 include * Corrected C++ Builder compilation problem. Changes since DCPcrypt v2 Beta 1 include * Renamed source code files for hashes and ciphers to DCPxxx.pas * Change the format of Cipher.InitStr so that the hash algorithm used to generate the key is explicitly specified. In order to get the same functionality as before, use TDCP_sha1. e.g. Cipher.InitStr('Hello World',TDCP_sha1); * Block ciphers are now inherited from an intermediate component that implements the block size specific chaining mode encryption routines. * Remove the internal component registration, it was more hassle than it was worth. If there is a demand for this to be put back then I might... * Added the full range of operation modes for Haval. By changing the defines at the top of DCPhaval.pas you can specify the number of passes and the output hash size. * Added the Tiger hash algorithm (192bit digest). * Changed the name of the file containing TDCP_ripemd160 for consistency to DCPripemd160 from DCPrmd160. * GOST no longer appears on the component palette pending verifying what the actual standard is (the code is still included however). * Added the RipeMD-128 hash algorithm (128bit digest). * Added the Serpent block cipher (AES finalist). * Added the SHA-256,384,512 hash algorithms (256, 384, 512bit digest respectively). * Added CTR chaining mode to all block ciphers. Installation: Delphi: Open the appropriate package, DCPdelphiX.dpk where X is your version of Delphi (either 4, 5 or 6). Then press the install button. C++ Builder: Create a new design time package and add all the .pas files from the DCPcrypt2.zip archive including all those in the Ciphers and Hashes subdirectories. Then press the install button. Kylix: Open the DCPkylix.dpk package and then press the install button (note: Kylix 1 users may need to create a new package as with C++ Builder as this is a Kylix 2 package). You may need to add the directory containing DCPcrypt (and the Ciphers and Hashes subdirectories) to your library search path (found under Environment Options). Once installed you will find two extra pages of components on your component palette, namely DCPciphers and DCPhashes. You can now place these components onto the form of your application to start using the algorithms. Usage: See the main html documentation in the Docs subdirectory. Contact: I appreciate knowing what DCPcrypt is being used for and also if you have any queries or bug reports please email me at crypto@cityinthesky.co.uk. DCPcrypt is copyrighted (c) 1999-2003 David Barton. All trademarks are property of their respective owners. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/Random/���������������������������������������������������������0000775�0001750�0001750�00000000000�13244011205�017732� 5����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/Random/isaac.pas������������������������������������������������0000664�0001750�0001750�00000031612�13144651123�021532� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������unit ISAAC; {Bob Jenkins' public domain random number generator ISAAC} interface {$i std.inc} (************************************************************************* DESCRIPTION : Bob Jenkins' public domain random number generator ISAAC (Indirection, Shift, Accumulate, Add, and Count) Period at least 2^40, average 2^8295 REQUIREMENTS : TP5-7, D1-D7/D9-D10/D12, FPC, VP, WDOSX EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REFERENCES : http://burtleburtle.net/bob/rand/isaacafa.html (ISAAC: a fast cryptographic random number generator) Version Date Author Modification ------- -------- ------- ------------------------------------------ 0.10 23.07.05 W.Ehrhardt Initial BP7 port of rand.c with RANDSIZ=256 0.11 23.07.05 we Some tweaking in isaac_generate 0.12 23.07.05 we non crypt option (RANDSIZ=16), much slower 0.13 23.07.05 we use RANDSIZ=256 only, procedure Mix 0.14 23.07.05 we use mix array m, use inc where possible 0.15 23.07.05 we BASM16 in isaac_generate 0.16 24.07.05 we routines for word, long, double etc. 0.17 01.09.05 we byte typecast in init0 0.18 05.11.08 we isaac_dword function 0.19 02.12.08 we BTypes/Ptr2Inc 0.20 06.01.09 we Uses BTypes moved to implementation 0.21 14.06.12 we Fix bug in _read for trailing max 3 bytes **************************************************************************) (*------------------------------------------------------------------------- (C) Copyright 2005-2012 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ----------------------------------------------------------------------------*) {$ifdef BIT16} {$N+} {$endif} type isaac_ctx = record {context of random number generator} randmem: array[0..255] of longint; {the internal state} randrsl: array[0..255] of longint; {the results given to the user} randa : longint; {accumulator} randb : longint; {the last result} randc : longint; {counter, guarantees cycle >= 2^40 } nextres: longint; {the next result } randidx: word; {the index in randrsl[] } end; procedure isaac_init (var ctx: isaac_ctx; seed: longint); {-Init context from randrsl[0]=seed, randrsl[i]=0 otherwise} procedure isaac_init0(var ctx: isaac_ctx); {-Init context from randseed} {$ifdef CONST} procedure isaac_inita(var ctx: isaac_ctx; const key: array of longint; klen: integer); {-Init all context variables with separate seeds, klen: number of seeds} {$else} procedure isaac_inita(var ctx: isaac_ctx; var KArr; klen: integer); {-Init all context variables with separate seeds, klen: number of seeds} {$endif} procedure isaac_next(var ctx: isaac_ctx); {-Next step of PRNG} procedure isaac_read(var ctx: isaac_ctx; dest: pointer; len: longint); {-Read len bytes from the PRNG to dest} function isaac_long(var ctx: isaac_ctx): longint; {-Next random positive longint} function isaac_dword(var ctx: isaac_ctx): {$ifdef HAS_CARD32}cardinal{$else}longint{$endif}; {-Next 32 bit random dword (cardinal or longint)} function isaac_word(var ctx: isaac_ctx): word; {-Next random word} function isaac_double(var ctx: isaac_ctx): double; {-Next random double [0..1) with 32 bit precision} function isaac_double53(var ctx: isaac_ctx): double; {-Next random double in [0..1) with full double 53 bit precision} function isaac_selftest: boolean; {-Simple self-test of ISAAC PRNG} {$ifdef testing} {interfaced for cycle testing without overhead, do not use for normal use} procedure isaac_generate(var ctx: isaac_ctx); {-generate next 256 result values, ie refill randrsl} {$endif} implementation uses BTypes; {---------------------------------------------------------------------------} procedure isaac_generate(var ctx: isaac_ctx); {-generate next 256 result values, ie refill randrsl} var x,y: longint; xi : integer absolute x; {better performance for BIT16} i : integer; {$ifdef BASM16} pra: pointer; {pointer to cxt.randa for faster BASM16 access} {$endif} begin {$ifdef BASM16} pra := @ctx.randa; {$endif} with ctx do begin inc(randc); inc(randb, randc); for i:=0 to 255 do begin {$ifdef BASM16} case i and 3 of 0: asm les di,[pra] db $66; mov ax,es:[di] db $66; shl ax,13 db $66; xor es:[di],ax end; 1: asm les di,[pra] db $66; mov ax,es:[di] db $66; shr ax,6 db $66; xor es:[di],ax end; 2: asm les di,[pra] db $66; mov ax,es:[di] db $66; shl ax,2 db $66; xor es:[di],ax end; 3: asm {shr 16 is special, use word [pra+2]} les di,[pra] mov ax, es:[di+2] xor es:[di],ax end; end; {$else} case i and 3 of 0: randa := randa xor (randa shl 13); 1: randa := randa xor (randa shr 6); 2: randa := randa xor (randa shl 2); 3: randa := randa xor (randa shr 16); end; {$endif} x := randmem[i]; inc(randa,randmem[(i+128) and 255]); y := randmem[(xi shr 2) and 255] + randa + randb; randmem[i] := y; randb := randmem[(y shr 10) and 255] + x; randrsl[i] := randb; end; {reset result index} randidx:=0; end; end; {---------------------------------------------------------------------------} procedure internal_init(var ctx: isaac_ctx; flag: boolean); {-Init state, use randrsl if flag=true} var i,j: integer; m: array[0..7] of longint; procedure Mix; {-mix the array} begin m[0] := m[0] xor (m[1] shl 11); inc(m[3], m[0]); inc(m[1], m[2]); m[1] := m[1] xor (m[2] shr 2); inc(m[4], m[1]); inc(m[2], m[3]); m[2] := m[2] xor (m[3] shl 8); inc(m[5], m[2]); inc(m[3], m[4]); m[3] := m[3] xor (m[4] shr 16); inc(m[6], m[3]); inc(m[4], m[5]); m[4] := m[4] xor (m[5] shl 10); inc(m[7], m[4]); inc(m[5], m[6]); m[5] := m[5] xor (m[6] shr 4); inc(m[0], m[5]); inc(m[6], m[7]); m[6] := m[6] xor (m[7] shl 8); inc(m[1], m[6]); inc(m[7], m[0]); m[7] := m[7] xor (m[0] shr 9); inc(m[2], m[7]); inc(m[0], m[1]); end; begin with ctx do begin randa := 0; randb := 0; randc := 0; for i:=0 to 7 do m[i] := longint($9e3779b9); {the golden ratio} for i:=0 to 3 do Mix; i := 0; while i<256 do begin {fill in randmem[] with messy stuff} if flag then begin {use all the information in the seed} for j:=0 to 7 do inc(m[j], randrsl[i+j]); end; Mix; move(m, randmem[i], sizeof(m)); inc(i,8); end; if flag then begin {do a second pass to make all of the seed affect all of randmem} i := 0; while i<256 do begin for j:=0 to 7 do inc(m[j], randmem[i+j]); Mix; move(m, randmem[i], sizeof(m)); inc(i,8); end; end; {generate first set of results} isaac_generate(ctx); {prepare to use the first set of results } randidx := 0; end; end; {---------------------------------------------------------------------------} procedure isaac_init(var ctx: isaac_ctx; seed: longint); {-Init context from randrsl[0]=seed, randrsl[i]=0 otherwise} begin with ctx do begin fillchar(randrsl, sizeof(randrsl),0); randrsl[0] := seed; end; internal_init(ctx, true); end; {---------------------------------------------------------------------------} procedure isaac_init0(var ctx: isaac_ctx); {-Init context from randseed and randrsl[i]:=random} var i,j: integer; tl: longint; ta: packed array[0..3] of byte absolute tl; begin with ctx do begin for i:=0 to 255 do begin for j:=0 to 3 do ta[j] := byte(random(256)); randrsl[i] := tl; end; end; internal_init(ctx, true); end; {---------------------------------------------------------------------------} {$ifdef CONST} procedure isaac_inita(var ctx: isaac_ctx; const key: array of longint; klen: integer); {-Init all context variables with separate seeds, klen: number of seeds} {$else} procedure isaac_inita(var ctx: isaac_ctx; var KArr; klen: integer); {-Init all context variables with separate seeds, klen: number of seeds} var key: packed array[0..255] of longint absolute KArr; {T5-6 do not have open arrrays} {$endif} var i: integer; begin {$ifdef CONST} if klen>high(key)+1 then klen := high(key)+1; {$endif} with ctx do begin for i:=0 to 255 do begin if i<klen then randrsl[i]:=key[i] else randrsl[i]:=0; end; end; internal_init(ctx, true); end; {---------------------------------------------------------------------------} procedure isaac_next(var ctx: isaac_ctx); {-Next step of PRNG} begin with ctx do begin if randidx>255 then isaac_generate(ctx); nextres := randrsl[randidx]; inc(randidx); end; end; {---------------------------------------------------------------------------} procedure isaac_read(var ctx: isaac_ctx; dest: pointer; len: longint); {-Read len bytes from the PRNG to dest} type plong = ^longint; begin {not optimized} while len>3 do begin isaac_next(ctx); plong(dest)^ := ctx.nextres; inc(Ptr2Inc(dest),4); dec(len, 4); end; if len>0 then begin isaac_next(ctx); move(ctx.nextres, dest^, len and 3); end; end; {---------------------------------------------------------------------------} function isaac_long(var ctx: isaac_ctx): longint; {-Next random positive longint} begin isaac_next(ctx); isaac_long := ctx.nextres shr 1; end; {---------------------------------------------------------------------------} function isaac_dword(var ctx: isaac_ctx): {$ifdef HAS_CARD32}cardinal{$else}longint{$endif}; {-Next 32 bit random dword (cardinal or longint)} begin isaac_next(ctx); {$ifdef HAS_CARD32} isaac_dword := cardinal(ctx.nextres); {$else} isaac_dword := ctx.nextres; {$endif} end; {---------------------------------------------------------------------------} function isaac_word(var ctx: isaac_ctx): word; {-Next random word} type TwoWords = packed record L,H: word end; begin isaac_next(ctx); isaac_word := TwoWords(ctx.nextres).H; end; {---------------------------------------------------------------------------} function isaac_double(var ctx: isaac_ctx): double; {-Next random double [0..1) with 32 bit precision} begin isaac_next(ctx); isaac_double := (ctx.nextres + 2147483648.0) / 4294967296.0; end; {---------------------------------------------------------------------------} function isaac_double53(var ctx: isaac_ctx): double; {-Next random double in [0..1) with full double 53 bit precision} var hb,lb: longint; begin isaac_next(ctx); hb := ctx.nextres shr 5; isaac_next(ctx); lb := ctx.nextres shr 6; isaac_double53 := (hb*67108864.0+lb)/9007199254740992.0; end; {---------------------------------------------------------------------------} function isaac_selftest: boolean; {-Simple self-test of ISAAC PRNG} var ctx: isaac_ctx; begin fillchar(ctx, sizeof(ctx),0); internal_init(ctx, true); isaac_generate(ctx); {check first and last longint of randvec.txt} if ctx.randrsl[0]<>longint($f650e4c8) then begin isaac_selftest := false; exit; end; isaac_generate(ctx); isaac_selftest := ctx.randrsl[255] = longint($4bb5af29); end; end. ����������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/dcpcrypt.lpk����������������������������������������������������0000664�0001750�0001750�00000012774�13205072021�021065� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <CONFIG> <Package Version="4"> <Name Value="dcpcrypt"/> <Author Value="David Barton, Barko & Graeme Geldenhuys"/> <CompilerOptions> <Version Value="11"/> <SearchPaths> <IncludeFiles Value="Hashes/Keccak;Ciphers"/> <OtherUnitFiles Value="Ciphers;Hashes;Hashes/Keccak;Random;$(PkgOutDir)"/> <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> </SearchPaths> <Parsing> <SyntaxOptions> <SyntaxMode Value="Delphi"/> <CStyleOperator Value="False"/> <IncludeAssertionCode Value="True"/> <AllowLabel Value="False"/> <CPPInline Value="False"/> </SyntaxOptions> </Parsing> <CodeGeneration> <Optimizations> <OptimizationLevel Value="2"/> </Optimizations> </CodeGeneration> <Linking> <Debugging> <DebugInfoType Value="dsDwarf2Set"/> </Debugging> </Linking> <Other> <CustomOptions Value="-Xd"/> </Other> </CompilerOptions> <Description Value="DCPcrypt Cryptographic Component Library "/> <License Value="DCPcrypt is open source software (released under the MIT license) and as such there is no charge for inclusion in other software. www.cityinthesky.co.uk/cryptography.html "/> <Version Major="2" Minor="1"/> <Files Count="31"> <Item1> <Filename Value="dcpbase64.pas"/> <UnitName Value="DCPbase64"/> </Item1> <Item2> <Filename Value="dcpblockciphers.pas"/> <UnitName Value="DCPblockciphers"/> </Item2> <Item3> <Filename Value="dcpconst.pas"/> <UnitName Value="DCPconst"/> </Item3> <Item4> <Filename Value="dcpcrypt2.pas"/> <UnitName Value="DCPcrypt2"/> </Item4> <Item5> <Filename Value="Hashes/dcphaval.pas"/> <UnitName Value="DCPhaval"/> </Item5> <Item6> <Filename Value="Hashes/dcpmd4.pas"/> <UnitName Value="DCPmd4"/> </Item6> <Item7> <Filename Value="Hashes/dcpmd5.pas"/> <UnitName Value="DCPmd5"/> </Item7> <Item8> <Filename Value="Hashes/dcpripemd128.pas"/> <UnitName Value="DCPripemd128"/> </Item8> <Item9> <Filename Value="Hashes/dcpripemd160.pas"/> <UnitName Value="DCPripemd160"/> </Item9> <Item10> <Filename Value="Hashes/dcpsha1.pas"/> <UnitName Value="DCPsha1"/> </Item10> <Item11> <Filename Value="Hashes/dcpsha256.pas"/> <UnitName Value="DCPsha256"/> </Item11> <Item12> <Filename Value="Hashes/dcpsha512.pas"/> <UnitName Value="DCPsha512"/> </Item12> <Item13> <Filename Value="Hashes/dcptiger.pas"/> <UnitName Value="DCPtiger"/> </Item13> <Item14> <Filename Value="Hashes/DCPhaval3.inc"/> <Type Value="Include"/> </Item14> <Item15> <Filename Value="Hashes/DCPhaval4.inc"/> <Type Value="Include"/> </Item15> <Item16> <Filename Value="Hashes/DCPhaval5.inc"/> <Type Value="Include"/> </Item16> <Item17> <Filename Value="Hashes/dcpcrc32.pas"/> <UnitName Value="DCPcrc32"/> </Item17> <Item18> <Filename Value="Hashes/DCPtiger.inc"/> <Type Value="Include"/> </Item18> <Item19> <Filename Value="Hashes/dccrc32.pp"/> <UnitName Value="DCcrc32"/> </Item19> <Item20> <Filename Value="Hashes/dcblake2.pp"/> <UnitName Value="DCblake2"/> </Item20> <Item21> <Filename Value="Hashes/dcpblake2.pas"/> <UnitName Value="DCPblake2"/> </Item21> <Item22> <Filename Value="Hashes/dcpsha3.pas"/> <UnitName Value="DCPsha3"/> </Item22> <Item23> <Filename Value="Hashes/dcpsha224.pas"/> <UnitName Value="DCPsha224"/> </Item23> <Item24> <Filename Value="Hashes/Keccak/hmac.pas"/> <UnitName Value="HMAC"/> </Item24> <Item25> <Filename Value="Hashes/Keccak/sha3.pas"/> <UnitName Value="SHA3"/> </Item25> <Item26> <Filename Value="Hashes/Keccak/sha3_512.pas"/> <UnitName Value="SHA3_512"/> </Item26> <Item27> <Filename Value="Random/isaac.pas"/> <UnitName Value="ISAAC"/> </Item27> <Item28> <Filename Value="Hashes/Keccak/scrypt.pas"/> <UnitName Value="scrypt"/> </Item28> <Item29> <Filename Value="Ciphers/DCPrijndael.inc"/> <Type Value="Include"/> </Item29> <Item30> <Filename Value="Ciphers/dcprijndael.pas"/> <UnitName Value="DCPrijndael"/> </Item30> <Item31> <Filename Value="Hashes/Keccak/sha1.pas"/> <UnitName Value="SHA1"/> </Item31> </Files> <RequiredPkgs Count="2"> <Item1> <PackageName Value="multithreadprocslaz"/> </Item1> <Item2> <PackageName Value="FCL"/> <MinVersion Major="1" Valid="True"/> </Item2> </RequiredPkgs> <UsageOptions> <UnitPath Value="$(PkgOutDir)"/> </UsageOptions> <PublishOptions> <Version Value="2"/> <IgnoreBinaries Value="False"/> </PublishOptions> </Package> </CONFIG> ����doublecmd-0.8.2/components/dcpcrypt/DCPciphers.lrs��������������������������������������������������0000664�0001750�0001750�00000075366�11652036011�021244� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������LazarusResources.Add('TDCP_3DES','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#238#239 +#255#238#238#255#254#239#255#255#255#254#204#206#254#204#204#239#236#206#255 +#255#255#254#206#236#238#206#238#254#206#236#239#255#255#254#206#236#238#206 +#255#255#238#236#239#255#255#254#206#236#238#204#239#255#236#206#255#255#255 +#254#206#236#238#206#255#254#206#238#255#255#255#254#206#236#238#206#238#254 +#206#236#239#255#255#254#204#206#254#204#204#239#236#206#255#255#255#255#238 +#239#255#238#238#255#254#239#255#255#255#255#255#255#255#254#239#255#255#255 +#255#255#255#255#255#255#255#236#206#255#255#255#255#255#255#255#255#255#254 +#206#236#239#255#255#255#255#255#255#255#255#255#238#236#239#255#255#255#255 +#255#255#255#255#255#236#206#255#255#255#255#255#255#255#255#255#255#238#236 +#239#255#255#255#255#255#255#255#255#254#206#236#239#255#255#255#255#255#255 +#255#255#255#236#206#255#255#255#255#255#255#255#255#255#255#254#239#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_BLOWFISH','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#254#255#255#254 +#238#255#238#239#255#239#254#255#236#239#255#236#204#238#204#206#254#206#236 +#239#236#239#255#254#206#255#238#236#238#206#236#239#236#238#255#254#206#255 +#254#236#238#206#236#239#236#204#239#254#206#255#236#206#254#204#204#239#236 +#238#255#254#206#254#206#239#254#206#236#239#236#238#239#254#206#254#206#238 +#254#206#236#239#236#204#206#236#204#239#236#204#238#206#236#239#254#238#239 +#254#238#255#254#238#255#239#254#255#254#238#255#254#238#239#254#239#255#254 +#254#255#236#204#239#236#204#206#236#206#255#236#236#239#236#238#206#236#238 +#238#206#236#238#206#206#206#236#238#206#236#239#254#206#236#238#206#206#206 +#236#204#239#236#239#254#206#236#238#206#206#206#236#238#206#236#239#254#206 +#236#238#206#238#206#236#238#206#236#239#254#206#236#238#206#254#206#236#204 +#239#236#239#255#236#206#254#206#254#206#254#238#255#254#255#255#254#239#255 +#239#255#239#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_CAST128','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#238#239 +#254#238#239#255#238#255#255#255#255#254#204#206#236#204#206#254#204#239#255 +#255#255#255#236#239#236#238#239#236#238#206#255#255#255#255#236#239#254#206 +#255#236#238#206#255#255#255#255#236#239#255#236#239#254#204#239#255#255#255 +#255#236#239#254#254#206#236#238#206#255#255#255#254#204#239#236#238#206#236 +#238#206#255#255#255#255#236#239#254#204#239#254#204#239#255#255#255#255#254 +#255#255#238#255#255#238#255#255#255#255#238#239#254#255#239#254#238#255#255 +#239#255#254#204#206#236#238#206#236#204#239#254#206#255#236#238#239#236#238 +#206#254#238#206#254#206#255#236#239#255#236#238#206#255#238#206#254#206#255 +#236#239#255#236#204#206#254#204#239#254#206#255#236#239#255#236#238#206#236 +#238#255#254#206#255#236#238#239#236#238#206#236#238#239#254#206#255#254#204 +#206#254#204#239#254#204#206#236#204#239#255#238#239#255#238#255#255#238#239 +#254#238#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_CAST256','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#238#238 +#255#238#239#255#254#239#255#255#255#254#204#204#238#204#206#255#236#206#255 +#255#255#255#236#238#255#238#236#238#206#236#239#255#255#255#255#206#255#238 +#236#238#206#236#239#255#255#255#255#236#238#204#206#254#204#206#255#255#255 +#255#239#236#238#206#239#254#206#238#255#255#255#254#206#236#238#206#238#254 +#206#236#239#255#255#255#236#206#254#204#204#255#236#206#255#255#255#255#254 +#239#255#238#238#255#254#239#255#255#255#238#239#254#255#239#254#238#255#255 +#239#255#254#204#206#236#238#206#236#204#239#254#206#255#236#238#239#236#238 +#206#254#238#206#254#206#255#236#239#255#236#238#206#255#238#206#254#206#255 +#236#239#255#236#204#206#254#204#239#254#206#255#236#239#255#236#238#206#236 +#238#255#254#206#255#236#238#239#236#238#206#236#238#239#254#206#255#254#204 +#206#254#204#239#254#204#206#236#204#239#255#238#239#255#238#255#255#238#239 +#254#238#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_DES','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#238#239#255#238#238#255#254#239#255#255#255#254#204#206#254#204#204#239 +#236#206#255#255#255#254#206#236#238#206#238#254#206#236#239#255#255#254#206 +#236#238#206#255#255#238#236#239#255#255#254#206#236#238#204#239#255#236#206 +#255#255#255#254#206#236#238#206#255#254#206#238#255#255#255#254#206#236#238 +#206#238#254#206#236#239#255#255#254#204#206#254#204#204#239#236#206#255#255 +#255#255#238#239#255#238#238#255#254#239#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_GOST','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#254#239#255#254#239#255#238#239#255#254#255#255#236#206#255#236#206#254#204 +#206#255#236#239#254#206#236#238#206#236#239#238#236#239#236#239#254#206#204 +#238#206#236#239#254#236#239#236#239#254#206#238#254#206#236#239#236#206#255 +#236#239#254#206#254#254#206#236#238#206#239#255#236#239#254#206#236#238#206 +#236#238#206#238#255#236#239#255#236#206#255#236#206#255#236#204#238#204#206 +#255#254#239#255#254#239#255#254#238#255#238#239#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_ICE2','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#254#238#239#255#255#255#255#255#255#255#255#255#236#204#206#255#255#255#255 +#255#255#255#255#255#236#238#239#255#255#255#255#255#255#255#255#255#254#206 +#255#255#255#255#255#255#255#255#255#255#255#236#239#255#255#255#255#255#255 +#255#255#255#254#254#206#255#255#255#255#255#255#255#255#255#236#238#206#255 +#255#255#255#255#255#255#255#255#254#204#239#255#255#255#255#255#255#255#255 +#255#255#238#255#255#255#255#255#255#255#255#238#239#255#238#239#254#238#239 +#255#255#255#254#204#206#254#204#206#236#204#206#255#255#255#255#236#239#236 +#238#239#236#238#239#255#255#255#255#236#239#236#239#255#236#238#255#255#255 +#255#255#236#239#236#239#255#236#204#239#255#255#255#255#236#239#236#239#255 +#236#238#255#255#255#255#255#236#239#236#238#239#236#238#239#255#255#255#254 +#204#206#254#204#206#236#204#206#255#255#255#255#238#239#255#238#239#254#238 +#239#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_ICE','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#238#239#255#238#239#254#238#239#255#255#255#254#204#206#254#204#206#236 +#204#206#255#255#255#255#236#239#236#238#239#236#238#239#255#255#255#255#236 +#239#236#239#255#236#238#255#255#255#255#255#236#239#236#239#255#236#204#239 +#255#255#255#255#236#239#236#239#255#236#238#255#255#255#255#255#236#239#236 +#238#239#236#238#239#255#255#255#254#204#206#254#204#206#236#204#206#255#255 +#255#255#238#239#255#238#239#254#238#239#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_IDEA','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#238#239#254#238#255#254#238#239#254#255#239#254#204#206#236#204#239#236#204 +#206#236#238#206#255#236#239#236#238#206#236#238#239#236#238#206#255#236#239 +#236#238#206#236#238#255#236#238#206#255#236#239#236#238#206#236#204#239#236 +#204#206#255#236#239#236#238#206#236#238#255#236#238#206#255#236#239#236#238 +#206#236#238#239#236#238#206#254#204#206#236#204#239#236#204#206#254#204#239 +#255#238#239#254#238#255#254#238#239#255#238#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_MARS','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#239#255#239#239#254#254#255#239#238#239#255#254#206#254#206#206#236#236#238 +#206#204#206#255#254#206#238#206#206#236#236#238#206#238#236#239#254#206#206 +#206#206#236#236#238#206#254#236#239#254#206#206#206#204#204#236#204#239#236 +#206#255#254#204#236#206#206#236#236#238#206#206#239#255#254#204#236#206#206 +#236#236#238#206#206#238#255#254#206#254#206#236#206#236#204#239#236#204#239 +#255#239#255#239#254#239#254#238#255#254#238#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_MISTY1','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#238#239#255#255#255#255#255#255#255#255#255#254#204#206#255#255#255#255 +#255#255#255#255#255#255#236#239#255#255#255#255#255#255#255#255#255#255#236 +#239#255#255#255#255#255#255#255#255#255#255#236#239#255#255#255#255#255#255 +#255#255#255#255#236#239#255#255#255#255#255#255#255#255#255#254#204#239#255 +#255#255#255#255#255#255#255#255#255#236#239#255#255#255#255#255#255#255#255 +#255#255#254#255#255#255#255#255#255#254#255#254#254#238#254#238#255#254#255 +#238#255#236#239#236#236#204#236#204#239#236#238#204#239#236#238#236#238#206 +#254#238#206#236#239#238#206#236#236#236#238#206#255#238#206#236#239#254#206 +#236#236#236#238#206#254#204#239#236#239#236#206#236#206#204#238#206#236#238 +#255#236#238#206#206#236#206#204#238#206#236#238#239#236#238#206#206#236#239 +#236#236#204#238#204#206#204#206#206#206#254#255#254#254#238#255#238#239#238 +#239#239#239#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_RC2','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#239#254#255#254#238#255#238#238#255#255#255#254#206#236#239#236#204#238 +#204#204#239#255#255#254#206#236#238#206#238#254#206#238#255#255#255#254#206 +#236#238#206#255#255#236#239#255#255#255#254#204#206#254#206#255#255#254#206 +#255#255#255#254#206#236#238#206#255#255#239#236#239#255#255#254#206#236#238 +#206#238#254#206#236#239#255#255#254#204#206#255#236#204#239#236#206#255#255 +#255#255#238#239#255#254#238#255#254#239#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_RC4','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#239#254#255#254#238#255#255#239#255#255#255#254#206#236#239#236#204#239 +#254#206#255#255#255#254#206#236#238#206#238#255#238#206#255#255#255#254#206 +#236#238#206#255#254#204#204#239#255#255#254#204#206#254#206#255#254#206#206 +#255#255#255#254#206#236#238#206#255#254#206#239#255#255#255#254#206#236#238 +#206#238#254#206#255#255#255#255#254#204#206#255#236#204#238#206#255#255#255 +#255#255#238#239#255#254#238#255#239#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_RC5','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#239#254#255#254#238#255#238#239#255#255#255#254#206#236#239#236#204#238 +#204#206#255#255#255#254#206#236#238#206#238#255#238#236#239#255#255#254#206 +#236#238#206#255#255#238#236#239#255#255#254#204#206#254#206#255#254#204#206 +#255#255#255#254#206#236#238#206#255#254#206#239#255#255#255#254#206#236#238 +#206#238#254#206#238#255#255#255#254#204#206#255#236#204#238#204#204#239#255 +#255#255#238#239#255#254#238#255#238#238#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_RC6','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#239#254#255#254#238#255#254#239#255#255#255#254#206#236#239#236#204#239 +#236#206#255#255#255#254#206#236#238#206#238#254#206#236#239#255#255#254#206 +#236#238#206#255#254#206#236#239#255#255#254#204#206#254#206#255#254#204#206 +#255#255#255#254#206#236#238#206#255#254#206#238#255#255#255#254#206#236#238 +#206#238#254#206#236#239#255#255#254#204#206#255#236#204#239#236#206#255#255 +#255#255#238#239#255#254#238#255#254#239#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_RIJNDAEL','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#254#238#255#254 +#255#239#254#238#239#238#238#255#236#204#239#236#238#206#236#204#206#204#204 +#239#236#238#206#236#238#206#236#238#238#206#238#255#236#238#206#236#238#206 +#236#238#254#206#255#255#236#238#206#236#204#206#236#204#238#206#255#255#236 +#238#206#236#238#206#236#238#254#206#255#255#236#238#206#236#238#206#236#238 +#238#206#255#255#236#204#239#254#204#239#236#204#206#206#255#255#254#238#255 +#255#238#255#254#238#239#239#255#255#254#255#239#254#238#255#254#255#255#239 +#254#255#236#238#206#236#204#239#236#239#254#206#236#239#236#238#206#254#206 +#254#206#206#254#206#236#239#236#238#206#254#206#254#206#206#254#206#204#239 +#236#204#239#254#206#255#238#206#254#206#204#239#236#238#206#254#206#255#254 +#206#254#204#236#239#236#238#206#254#206#255#238#206#254#204#236#239#236#204 +#239#236#204#238#204#204#238#206#236#239#254#238#255#254#238#255#238#238#255 +#239#254#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_SERPENT','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#128#128#128#0#192#192#192#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#239#255#254 +#238#239#239#254#255#254#255#255#254#206#255#236#204#206#206#236#239#236#239 +#255#254#206#255#236#238#238#206#204#239#236#239#255#254#206#239#236#238#254 +#206#204#239#236#239#255#254#204#206#236#204#238#204#204#239#236#239#255#254 +#206#236#236#238#254#204#236#239#236#239#255#254#206#236#236#238#238#204#236 +#238#236#238#255#254#204#206#236#204#206#206#236#236#204#204#239#255#238#239 +#254#238#239#239#254#254#238#238#255#255#255#238#239#255#238#238#255#239#254 +#255#255#255#254#204#206#254#204#204#238#206#236#239#255#255#255#238#236#238 +#206#238#254#206#236#239#255#255#255#254#236#238#206#239#254#206#236#239#255 +#255#255#236#206#254#204#206#254#204#206#255#255#255#254#206#239#254#206#239 +#254#206#236#239#255#255#254#206#238#254#206#238#254#206#236#239#255#255#255 +#236#204#238#204#204#238#204#206#255#255#255#255#254#238#255#238#238#255#254 +#239#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_TEA','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#254#255#255#238#238#255#239#254#255#255#255#255#236#239#254#204#204#238 +#206#236#239#255#255#255#236#239#254#206#238#254#206#236#239#255#255#255#236 +#239#254#206#255#254#206#236#239#255#255#255#236#239#254#204#239#254#204#204 +#239#255#255#255#236#239#254#206#255#254#206#236#239#255#255#254#236#238#254 +#206#238#254#206#236#239#255#255#236#204#204#238#204#204#239#236#206#255#255 +#255#254#238#238#255#238#238#255#254#239#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_THINICE','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#238#239 +#255#238#239#254#238#239#255#255#255#254#204#206#254#204#206#236#204#206#255 +#255#255#255#236#239#236#238#239#236#238#239#255#255#255#255#236#239#236#239 +#255#236#238#255#255#255#255#255#236#239#236#239#255#236#204#239#255#255#255 +#255#236#239#236#239#255#236#238#255#255#255#255#255#236#239#236#238#239#236 +#238#239#255#255#255#254#204#206#254#204#206#236#204#206#255#255#255#255#238 +#239#255#238#239#254#238#239#255#255#255#254#255#254#255#239#254#238#255#239 +#254#255#255#236#239#236#238#206#236#204#238#206#236#239#255#236#239#236#238 +#206#254#206#254#206#236#239#255#236#239#236#238#206#254#206#254#206#204#239 +#255#236#239#236#204#206#254#206#254#206#204#239#255#236#239#236#238#206#254 +#206#254#204#236#239#255#236#239#236#238#206#254#206#254#204#236#239#254#204 +#206#236#238#206#236#204#238#206#236#239#255#238#239#254#255#239#254#238#255 +#239#254#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_TWOFISH','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#254#255#255#254 +#238#255#238#239#255#239#254#255#236#239#255#236#204#238#204#206#254#206#236 +#239#236#239#255#254#206#255#238#236#238#206#236#239#236#238#255#254#206#255 +#254#236#238#206#236#239#236#204#239#254#206#255#236#206#254#204#204#239#236 +#238#255#254#206#254#206#239#254#206#236#239#236#238#239#254#206#254#206#238 +#254#206#236#239#236#204#206#236#204#239#236#204#238#206#236#239#254#238#239 +#254#238#255#254#238#255#239#254#255#255#255#254#255#255#254#254#255#255#238 +#255#255#255#255#236#239#255#236#236#239#254#204#239#255#255#255#236#239#254 +#206#206#206#236#238#206#255#255#255#236#239#254#206#206#206#236#238#206#255 +#255#255#236#239#254#206#206#206#236#238#206#255#255#255#236#239#254#206#238 +#206#236#238#206#255#255#254#236#238#254#206#254#206#236#238#206#255#255#236 +#204#204#238#206#254#206#254#204#239#255#255#254#238#238#255#239#255#239#255 +#238#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/dcpblockciphers.pas���������������������������������������������0000664�0001750�0001750�00000051712�13200401360�022361� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* Block cipher component definitions *****************************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPblockciphers; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2; {******************************************************************************} { Base type definition for 64 bit block ciphers } type TDCP_blockcipher64= class(TDCP_blockcipher) private IV, CV: array[0..7] of byte; procedure IncCounter; public class function GetBlockSize: integer; override; { Get the block size of the cipher (in bits) } procedure Reset; override; { Reset any stored chaining information } procedure Burn; override; { Clear all stored key information and chaining information } procedure SetIV(const Value); override; { Sets the IV to Value and performs a reset } procedure GetIV(var Value); override; { Returns the current chaining information, not the actual IV } procedure Init(const Key; Size: longword; InitVector: pointer); override; { Do key setup based on the data in Key, size is in bits } procedure EncryptCBC(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data using the CBC method of encryption } procedure DecryptCBC(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data using the CBC method of decryption } procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data using the CFB (8 bit) method of encryption } procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data using the CFB (8 bit) method of decryption } procedure EncryptCFBblock(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data using the CFB (block) method of encryption } procedure DecryptCFBblock(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data using the CFB (block) method of decryption } procedure EncryptOFB(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data using the OFB method of encryption } procedure DecryptOFB(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data using the OFB method of decryption } procedure EncryptCTR(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data using the CTR method of encryption } procedure DecryptCTR(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data using the CTR method of decryption } end; {******************************************************************************} { Base type definition for 128 bit block ciphers } type TDCP_blockcipher128= class(TDCP_blockcipher) private IV, CV: array[0..15] of byte; procedure IncCounter; public class function GetBlockSize: integer; override; { Get the block size of the cipher (in bits) } procedure Reset; override; { Reset any stored chaining information } procedure Burn; override; { Clear all stored key information and chaining information } procedure SetIV(const Value); override; { Sets the IV to Value and performs a reset } procedure GetIV(var Value); override; { Returns the current chaining information, not the actual IV } procedure Init(const Key; Size: longword; InitVector: pointer); override; { Do key setup based on the data in Key, size is in bits } procedure EncryptCBC(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data using the CBC method of encryption } procedure DecryptCBC(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data using the CBC method of decryption } procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data using the CFB (8 bit) method of encryption } procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data using the CFB (8 bit) method of decryption } procedure EncryptCFBblock(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data using the CFB (block) method of encryption } procedure DecryptCFBblock(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data using the CFB (block) method of decryption } procedure EncryptOFB(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data using the OFB method of encryption } procedure DecryptOFB(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data using the OFB method of decryption } procedure EncryptCTR(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data using the CTR method of encryption } procedure DecryptCTR(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data using the CTR method of decryption } end; implementation {** TDCP_blockcipher64 ********************************************************} procedure TDCP_blockcipher64.IncCounter; var i: integer; begin Inc(CV[7]); i:= 7; while (i> 0) and (CV[i] = 0) do begin Inc(CV[i-1]); Dec(i); end; end; class function TDCP_blockcipher64.GetBlockSize: integer; begin Result:= 64; end; procedure TDCP_blockcipher64.Init(const Key; Size: longword; InitVector: pointer); begin inherited Init(Key,Size,InitVector); InitKey(Key,Size); if InitVector= nil then begin FillChar(IV,8,{$IFDEF DCP1COMPAT}$FF{$ELSE}0{$ENDIF}); EncryptECB(IV,IV); Reset; end else begin Move(InitVector^,IV,8); Reset; end; end; procedure TDCP_blockcipher64.SetIV(const Value); begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); Move(Value,IV,8); Reset; end; procedure TDCP_blockcipher64.GetIV(var Value); begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); Move(CV,Value,8); end; procedure TDCP_blockcipher64.Reset; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized') else Move(IV,CV,8); end; procedure TDCP_blockcipher64.Burn; begin FillChar(IV,8,$FF); FillChar(CV,8,$FF); inherited Burn; end; procedure TDCP_blockcipher64.EncryptCBC(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: pointer; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; for i:= 1 to (Size div 8) do begin Move(p1^,p2^,8); XorBlock(p2^,CV,8); EncryptECB(p2^,p2^); Move(p2^,CV,8); p1:= pointer(p1 + 8); p2:= pointer(p2 + 8); end; if (Size mod 8)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 8); XorBlock(p2^,CV,Size mod 8); end; end; procedure TDCP_blockcipher64.DecryptCBC(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: pointer; Temp: array[0..7] of byte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); dcpFillChar(Temp, SizeOf(Temp), 0); p1:= @Indata; p2:= @Outdata; for i:= 1 to (Size div 8) do begin Move(p1^,p2^,8); Move(p1^,Temp,8); DecryptECB(p2^,p2^); XorBlock(p2^,CV,8); Move(Temp,CV,8); p1:= pointer(p1 + 8); p2:= pointer(p2 + 8); end; if (Size mod 8)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 8); XorBlock(p2^,CV,Size mod 8); end; end; procedure TDCP_blockcipher64.EncryptCFB8bit(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: Pbyte; Temp: array[0..7] of byte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to Size do begin EncryptECB(CV,Temp); p2^:= p1^ xor Temp[0]; Move(CV[1],CV[0],8-1); CV[7]:= p2^; Inc(p1); Inc(p2); end; end; procedure TDCP_blockcipher64.DecryptCFB8bit(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: Pbyte; TempByte: byte; Temp: array[0..7] of byte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to Size do begin TempByte:= p1^; EncryptECB(CV,Temp); p2^:= p1^ xor Temp[0]; Move(CV[1],CV[0],8-1); CV[7]:= TempByte; Inc(p1); Inc(p2); end; end; procedure TDCP_blockcipher64.EncryptCFBblock(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: Pbyte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; for i:= 1 to (Size div 8) do begin EncryptECB(CV,CV); Move(p1^,p2^,8); XorBlock(p2^,CV,8); Move(p2^,CV,8); p1:= pointer(pointer(p1) + 8); p2:= pointer(pointer(p2) + 8); end; if (Size mod 8)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 8); XorBlock(p2^,CV,Size mod 8); end; end; procedure TDCP_blockcipher64.DecryptCFBblock(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: Pbyte; Temp: array[0..7] of byte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to (Size div 8) do begin Move(p1^,Temp,8); EncryptECB(CV,CV); Move(p1^,p2^,8); XorBlock(p2^,CV,8); Move(Temp,CV,8); p1:= pointer(pointer(p1) + 8); p2:= pointer(pointer(p2) + 8); end; if (Size mod 8)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 8); XorBlock(p2^,CV,Size mod 8); end; end; procedure TDCP_blockcipher64.EncryptOFB(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: pointer; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; for i:= 1 to (Size div 8) do begin EncryptECB(CV,CV); Move(p1^,p2^,8); XorBlock(p2^,CV,8); p1:= pointer(p1 + 8); p2:= pointer(p2 + 8); end; if (Size mod 8)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 8); XorBlock(p2^,CV,Size mod 8); end; end; procedure TDCP_blockcipher64.DecryptOFB(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: pointer; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; for i:= 1 to (Size div 8) do begin EncryptECB(CV,CV); Move(p1^,p2^,8); XorBlock(p2^,CV,8); p1:= pointer(p1 + 8); p2:= pointer(p2 + 8); end; if (Size mod 8)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 8); XorBlock(p2^,CV,Size mod 8); end; end; procedure TDCP_blockcipher64.EncryptCTR(const Indata; var Outdata; Size: longword); var temp: array[0..7] of byte; i: longword; p1, p2: pointer; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to (Size div 8) do begin EncryptECB(CV,temp); IncCounter; Move(p1^,p2^,8); XorBlock(p2^,temp,8); p1:= pointer(p1 + 8); p2:= pointer(p2 + 8); end; if (Size mod 8)<> 0 then begin EncryptECB(CV,temp); IncCounter; Move(p1^,p2^,Size mod 8); XorBlock(p2^,temp,Size mod 8); end; end; procedure TDCP_blockcipher64.DecryptCTR(const Indata; var Outdata; Size: longword); var temp: array[0..7] of byte; i: longword; p1, p2: pointer; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to (Size div 8) do begin EncryptECB(CV,temp); IncCounter; Move(p1^,p2^,8); XorBlock(p2^,temp,8); p1:= pointer(p1 + 8); p2:= pointer(p2 + 8); end; if (Size mod 8)<> 0 then begin EncryptECB(CV,temp); IncCounter; Move(p1^,p2^,Size mod 8); XorBlock(p2^,temp,Size mod 8); end; end; {** TDCP_blockcipher128 ********************************************************} procedure TDCP_blockcipher128.IncCounter; begin Inc(PQWord(@CV[0])^); end; class function TDCP_blockcipher128.GetBlockSize: integer; begin Result:= 128; end; procedure TDCP_blockcipher128.Init(const Key; Size: longword; InitVector: pointer); begin inherited Init(Key,Size,InitVector); InitKey(Key,Size); if InitVector= nil then begin FillChar(IV,16,{$IFDEF DCP1COMPAT}$FF{$ELSE}0{$ENDIF}); EncryptECB(IV,IV); Reset; end else begin Move(InitVector^,IV,16); Reset; end; end; procedure TDCP_blockcipher128.SetIV(const Value); begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); Move(Value,IV,16); Reset; end; procedure TDCP_blockcipher128.GetIV(var Value); begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); Move(CV,Value,16); end; procedure TDCP_blockcipher128.Reset; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized') else Move(IV,CV,16); end; procedure TDCP_blockcipher128.Burn; begin FillChar(IV,16,$FF); FillChar(CV,16,$FF); inherited Burn; end; procedure TDCP_blockcipher128.EncryptCBC(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: pointer; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; for i:= 1 to (Size div 16) do begin Move(p1^,p2^,16); XorBlock(p2^,CV,16); EncryptECB(p2^,p2^); Move(p2^,CV,16); p1:= pointer(p1 + 16); p2:= pointer(p2 + 16); end; if (Size mod 16)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 16); XorBlock(p2^,CV,Size mod 16); end; end; procedure TDCP_blockcipher128.DecryptCBC(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: pointer; Temp: array[0..15] of byte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to (Size div 16) do begin Move(p1^,p2^,16); Move(p1^,Temp,16); DecryptECB(p2^,p2^); XorBlock(p2^,CV,16); Move(Temp,CV,16); p1:= pointer(p1 + 16); p2:= pointer(p2 + 16); end; if (Size mod 16)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 16); XorBlock(p2^,CV,Size mod 16); end; end; procedure TDCP_blockcipher128.EncryptCFB8bit(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: Pbyte; Temp: array[0..15] of byte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to Size do begin EncryptECB(CV,Temp); p2^:= p1^ xor Temp[0]; Move(CV[1],CV[0],15); CV[15]:= p2^; Inc(p1); Inc(p2); end; end; procedure TDCP_blockcipher128.DecryptCFB8bit(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: Pbyte; TempByte: byte; Temp: array[0..15] of byte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to Size do begin TempByte:= p1^; EncryptECB(CV,Temp); p2^:= p1^ xor Temp[0]; Move(CV[1],CV[0],15); CV[15]:= TempByte; Inc(p1); Inc(p2); end; end; procedure TDCP_blockcipher128.EncryptCFBblock(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: Pbyte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; for i:= 1 to (Size div 16) do begin EncryptECB(CV,CV); Move(p1^,p2^,16); XorBlock(p2^,CV,16); Move(p2^,CV,16); p1:= pointer(pointer(p1) + 16); p2:= pointer(pointer(p2) + 16); end; if (Size mod 16)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 16); XorBlock(p2^,CV,Size mod 16); end; end; procedure TDCP_blockcipher128.DecryptCFBblock(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: Pbyte; Temp: array[0..15] of byte; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to (Size div 16) do begin Move(p1^,Temp,16); EncryptECB(CV,CV); Move(p1^,p2^,16); XorBlock(p2^,CV,16); Move(Temp,CV,16); p1:= pointer(pointer(p1) + 16); p2:= pointer(pointer(p2) + 16); end; if (Size mod 16)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 16); XorBlock(p2^,CV,Size mod 16); end; end; procedure TDCP_blockcipher128.EncryptOFB(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: pointer; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; for i:= 1 to (Size div 16) do begin EncryptECB(CV,CV); Move(p1^,p2^,16); XorBlock(p2^,CV,16); p1:= pointer(p1 + 16); p2:= pointer(p2 + 16); end; if (Size mod 16)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 16); XorBlock(p2^,CV,Size mod 16); end; end; procedure TDCP_blockcipher128.DecryptOFB(const Indata; var Outdata; Size: longword); var i: longword; p1, p2: pointer; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; for i:= 1 to (Size div 16) do begin EncryptECB(CV,CV); Move(p1^,p2^,16); XorBlock(p2^,CV,16); p1:= pointer(p1 + 16); p2:= pointer(p2 + 16); end; if (Size mod 16)<> 0 then begin EncryptECB(CV,CV); Move(p1^,p2^,Size mod 16); XorBlock(p2^,CV,Size mod 16); end; end; procedure TDCP_blockcipher128.EncryptCTR(const Indata; var Outdata; Size: longword); var temp: array[0..15] of byte; i: longword; p1, p2: pointer; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to (Size div 16) do begin EncryptECB(CV,temp); IncCounter; Move(p1^,p2^,16); XorBlock(p2^,temp,16); p1:= pointer(p1 + 16); p2:= pointer(p2 + 16); end; if (Size mod 16)<> 0 then begin EncryptECB(CV,temp); IncCounter; Move(p1^,p2^,Size mod 16); XorBlock(p2^,temp,Size mod 16); end; end; procedure TDCP_blockcipher128.DecryptCTR(const Indata; var Outdata; Size: longword); var temp: array[0..15] of byte; i: longword; p1, p2: pointer; begin if not fInitialized then raise EDCP_blockcipher.Create('Cipher not initialized'); p1:= @Indata; p2:= @Outdata; dcpFillChar(Temp, SizeOf(Temp), 0); for i:= 1 to (Size div 16) do begin EncryptECB(CV,temp); IncCounter; Move(p1^,p2^,16); XorBlock(p2^,temp,16); p1:= pointer(p1 + 16); p2:= pointer(p2 + 16); end; if (Size mod 16)<> 0 then begin EncryptECB(CV,temp); IncCounter; Move(p1^,p2^,Size mod 16); XorBlock(p2^,temp,Size mod 16); end; end; end. ������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/dcpcrypt.pas����������������������������������������������������0000664�0001750�0001750�00000000770�13200401360�021050� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit dcpcrypt; {$warn 5023 off : no warning about unused units} interface uses DCPbase64, DCPblockciphers, DCPconst, DCPcrypt2, DCPhaval, DCPmd4, DCPmd5, DCPripemd128, DCPripemd160, DCPsha1, DCPsha256, DCPsha512, DCPtiger, DCPcrc32, DCcrc32, DCblake2, DCPblake2, DCPsha3, DCPsha224, HMAC, SHA3, SHA3_512, ISAAC, scrypt, DCPrijndael, SHA1; implementation end. ��������doublecmd-0.8.2/components/dcpcrypt/Docs/�����������������������������������������������������������0000775�0001750�0001750�00000000000�13244011205�017402� 5����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doublecmd-0.8.2/components/dcpcrypt/Docs/Ciphers.html�����������������������������������������������0000664�0001750�0001750�00000042071�11652036011�021674� 0����������������������������������������������������������������������������������������������������ustar �alexx���������������������������alexx������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <head> <title>DCPcrypt v2: Users Guide - Ciphers

    DCPcrypt Cryptographic Component Library v2
    Copyright © 1999-2002 David Barton
    http://www.cityinthesky.co.uk/
    crypto@cityinthesky.co.uk

    Ciphers - TDCP_cipher

    All ciphers are inherited from the TDCP_cipher component either directly for stream ciphers (such as RC4) or via the TDCP_blockcipher component.

    The TDCP_cipher component implements key initialisation features and the basic encryption/decryption interface. Functions available are:

          property Initialized: boolean;
          property Id: integer;
          property Algorithm: string;
          property MaxKeySize: integer;
      
          class function SelfTest: boolean;
      
          procedure Init(const Key; Size: longword; InitVector: pointer); 
          procedure InitStr(const Key: string; HashType: TDCP_hashclass);
          procedure Burn; 
          procedure Reset;
          procedure Encrypt(const Indata; var Outdata; Size: longword); 
          procedure Decrypt(const Indata; var Outdata; Size: longword); 
          function EncryptStream(InStream, OutStream: TStream; Size: longword): longword;
          function DecryptStream(InStream, OutStream: TStream; Size: longword): longword;
          function EncryptString(const Str: string): string; 
          function DecryptString(const Str: string): string; 
        

    Example usage:


    Function descriptions

    property Initialized: boolean;

    Once key initialization has been performed this property is set to true, otherwise it is set to false. Calling Burn will immediately set this to false.

    property Id: integer;

    Every algorithm I implement gets given a unique ID number so that if I use several different algorithms within a program I can determine which one was used. This is a purely arbitrary numbering system.

    property Algorithm: string;

    This contains the name of the algorithm implemented within the component.

    property MaxKeySize: integer;

    This is the maximum size of key you can pass to the cipher (in bits!).

    class function SelfTest: boolean;

    In order to test whether the implementations have all been compiled correctly you can call the SelfTest function. This compares the results of several encryption/decryption operations with known results for the algorithms (so called test vectors). If all the tests are passed then true is returned. If ANY of the tests are failed then false is returned. You may want to run this function for all the components when you first install the DCPcrypt package and again if you modify any of the source files, you don't need to run this everytime your program is run. Note: this only performs a selection of tests, it is not exhaustive.

    procedure Init(const Key; Size: longword; InitVector: pointer);

    This procedure initializes the cipher with the keying material supplied in Key. The Size of the keying material is specified in BITS. The InitVector is a pointer to chaining information (only used for block ciphers). The variable that this points to should be equal to the block size of the algorithm. If nil is specified then (if necessary) an initialization vector is automatically generated from the key. Note: the method for generating automatic IVs is different from DCPcrypt v1.31, if this is a problem uncomment the DCPcrypt v1.31 compatibility mode line in DCPcrypt2.pas.

    Init example: use the hash of a string to initialize the cipher

      procedure TForm1.Button1Click(Sender: TObject);
      var
        Cipher: TDCP_rc4;
        Hash: TDCP_sha1;
        Digest: array[0..19] of byte;  // SHA-1 produces a 160bit (20byte) output
      begin
        Hash:= TDCP_sha1.Create(Self);
        Hash.Init;                     // initialize the hash
        Hash.UpdateStr(Edit1.Text);    // generate a hash of Edit1.Text
        Hash.Final(Digest);            // save the hash in Digest
        Hash.Free;
        Cipher:= TDCP_rc4.Create(Self);
        Cipher.Init(Digest,Sizeof(Digest)*8,nil);  // remember size is in BITS (hence sizeof*8)
        ...
        

    procedure InitStr(const Key: string; HashType: TDCP_hashclass);

    This procedure initializes the cipher with a hash of the key string using the specified hash type (in a way similar to the example above). To replicate the behaviour from DCPcrypt v2 Beta 1 use Cipher.InitStr(KeyStr,TDCP_sha1).

    InitStr example: prompt the user for a passphrase to initialize the cipher

      procedure TForm1.Button1Click(Sender: TObject);
      var
        Cipher: TDCP_rc4;
      begin
        Cipher:= TDCP_rc4.Create(Self);
        Cipher.InitStr(InputBox('Passphrase','Enter a passphrase',''),TDCP_sha1); // prompt for a passphrase
        ...
        

    procedure Burn;

    Once you have finished encrypting/decrypting all your data call Burn to erase all keying information. This is automatically called once the cipher is freed, however it is a good habit to call this procedure explicitly.

    procedure Reset;

    Stream ciphers (and block ciphers in chaining modes) generally store chaining information that is dependant on the information already encrypted. Consequently decrypting a block of information immediately after encrypting it won't result in the original information because when you called the decrypt procedure the chaining information was different from when you called the encrypt procedure. Hence use Reset to restore the chaining information to it's original state.

    Remember that calling EncryptString, DecryptString, EncryptStream and DecryptStream will also affect the chaining information.

    Reset example: encrypting and decrypting

      function TestCipher: boolean;
      const
        InData: array[0..9] of byte= ($01,$23,$45,$56,$67,$78,$89,$10,$AB,$FF);
      var
        Cipher: TDCP_rc4;
        Data: array[0..9] of byte;
      begin
        Cipher:= TDCP_rc4.Create(nil);
        Cipher.InitStr('Hello World',TDCP_sha1);   // initialize the cipher
        Cipher.Encrypt(InData,Data,Sizeof(Data));  // encrypt some known data
        Cipher.Decrypt(Data,Data,Sizeof(Data));    // now decrypt it
        Cipher.Burn;                               // clear keying information
        Cipher.Free;
        Result:= CompareMem(@InData,@Data,Sizeof(Data));  // compare input and output
      end;
        
    The above will ALWAYS result in false due to the chaining information.
      function TestCipher: boolean;
      const
        InData: array[0..9] of byte= ($01,$23,$45,$56,$67,$78,$89,$10,$AB,$FF);
      var
        Cipher: TDCP_rc4;
        Data: array[0..9] of byte;
      begin
        Cipher:= TDCP_rc4.Create(nil);
        Cipher.InitStr('Hello World',TDCP_sha1);   // initialize the cipher
        Cipher.Encrypt(InData,Data,Sizeof(Data));  // encrypt some known data
        Cipher.Reset;                              // reset chaining information
        Cipher.Decrypt(Data,Data,Sizeof(Data));    // now decrypt it
        Cipher.Burn;                               // clear keying information
        Cipher.Free;
        Result:= CompareMem(@InData,@Data,Sizeof(Data));  // compare input and output
      end;
        
    The above should always return true.

    procedure Encrypt(const Indata; var Outdata; Size: longword);

    Encrypt Size bytes from Indata and place it in Outdata. Block ciphers encrypt the data using the method specified by the CipherMode property. Also see the notes on Reset.

    procedure Decrypt(const Indata; var Outdata; Size: longword);

    Decrypt Size bytes from Indata and place it in Outdata. Block ciphers decrypt the data using the method specified by the CipherMode property. Also see the notes on Reset.

    function EncryptStream(InStream, OutStream: TStream; Size: longword): longword;

    Encrypt Size bytes from the InStream and place it in the OutStream, returns the number of bytes read from the InStream. Encryption is done by calling the Encrypt procedure. Also see the notes on Reset.

    function DecryptStream(InStream, OutStream: TStream; Size: longword): longword;

    Decrypt Size bytes from the InStream and place it in the OutStream, returns the number of bytes read from the InStream. Decryption is done by calling the Decrypt procedure. Also see the notes on Reset.

    function EncryptString(const Str: string): string;

    Encrypt the string Str then Base64 encode it and return the result. For stream ciphers the Encrypt procedure is called to do the encryption, for block ciphers the CFB8bit method is always used. Base64 encoding is used to ensure that the output string doesn't contain non-printing characters.

    function DecryptString(const Str: string): string;

    Base64 decode the string then decrypt it and return the result. For stream ciphers the Decrypt procedure is called to do the decryption, for block ciphers the CFB8bit method is always used.


    Example 1: String encryption

    This example shows how you can encrypt the contents of a TMemo and leave the contents printable.

      procedure TForm1.btnEncryptClick(Sender: TObject);
      var
        i: integer;
        Cipher: TDCP_rc4;
        KeyStr: string;
      begin
        KeyStr:= '';
        if InputQuery('Passphrase','Enter passphrase',KeyStr) then  // get the passphrase
        begin
          Cipher:= TDCP_rc4.Create(Self);
          Cipher.InitStr(KeyStr,TDCP_sha1);         // initialize the cipher with a hash of the passphrase
          for i:= 0 to Memo1.Lines.Count-1 do       // encrypt the contents of the memo
            Memo1.Lines[i]:= Cipher.EncryptString(Memo1.Lines[i]);
          Cipher.Burn;
          Cipher.Free;
        end;
      end;
      
      procedure TForm1.btnDecryptClick(Sender: TObject);
      var
        i: integer;
        Cipher: TDCP_rc4;
        KeyStr: string;
      begin
        KeyStr:= '';
        if InputQuery('Passphrase','Enter passphrase',KeyStr) then  // get the passphrase
        begin
          Cipher:= TDCP_rc4.Create(Self);
          Cipher.InitStr(KeyStr,TDCP_sha1);         // initialize the cipher with a hash of the passphrase
          for i:= 0 to Memo1.Lines.Count-1 do       // decrypt the contents of the memo
            Memo1.Lines[i]:= Cipher.DecryptString(Memo1.Lines[i]);
          Cipher.Burn;
          Cipher.Free;
        end;
      end;
        

    Example 2: File encryption

    This example shows how you can encrypt the contents of a file, takes the input and output file names from two edit boxes: boxInputFile and boxOutputFile.

      procedure TForm1.btnEncryptClick(Sender: TObject);
      var
        Cipher: TDCP_rc4;
        KeyStr: string;
        Source, Dest: TFileStream;
      begin
        KeyStr:= '';
        if InputQuery('Passphrase','Enter passphrase',KeyStr) then  // get the passphrase
        begin
          try
            Source:= TFileStream.Create(boxInputFile.Text,fmOpenRead);
            Dest:= TFileStream.Create(boxOutputFile.Text,fmCreate);
            Cipher:= TDCP_rc4.Create(Self);
            Cipher.InitStr(KeyStr,TDCP_sha1);              // initialize the cipher with a hash of the passphrase
            Cipher.EncryptStream(Source,Dest,Source.Size); // encrypt the contents of the file
            Cipher.Burn;
            Cipher.Free;
            Dest.Free;
            Source.Free;
            MessageDlg('File encrypted',mtInformation,[mbOK],0);
          except
            MessageDlg('File IO error',mtError,[mbOK],0);
          end;
        end;
      end;
      
      procedure TForm1.btnDecryptClick(Sender: TObject);
      var
        Cipher: TDCP_rc4;
        KeyStr: string;
        Source, Dest: TFileStream;
      begin
        KeyStr:= '';
        if InputQuery('Passphrase','Enter passphrase',KeyStr) then  // get the passphrase
        begin
          try
            Source:= TFileStream.Create(boxInputFile.Text,fmOpenRead);
            Dest:= TFileStream.Create(boxOutputFile.Text,fmCreate);
            Cipher:= TDCP_rc4.Create(Self);
            Cipher.InitStr(KeyStr,TDCP_sha1);              // initialize the cipher with a hash of the passphrase
            Cipher.DecryptStream(Source,Dest,Source.Size); // decrypt the contents of the file
            Cipher.Burn;
            Cipher.Free;
            Dest.Free;
            Source.Free;
            MessageDlg('File decrypted',mtInformation,[mbOK],0);
          except
            MessageDlg('File IO error',mtError,[mbOK],0);
          end;
        end;
      end;
        

    Example 3: General encryption

    This hypothetical example shows how you might encrypt a packet of information before transmission across a network.

      type
        TSomePacket= record
          Date: double;
          ToUserID: integer;
          FromUserID: integer;
          MsgLen: integer;
          Msg: string;
        end;
        
      procedure EncryptPacket(Cipher: TDCP_cipher; var Packet: TSomePacket);
      // encrypt the information packet with the cipher
      // if the cipher isn't initialized then prompt for passphrase
      begin
        if Cipher= nil then
          raise Exception.Create('Cipher hasn''t been created!')
        else
        begin
          if not Cipher.Initialized then        // check the cipher has been initialized
            Cipher.InitStr(InputBox('Passphrase','Enter passphrase',''),TDCP_sha1);
          if Cipher is TDCP_blockcipher then    // if a block cipher use CFB 8bit as encrypting small packets
            TDCP_blockcipher(Cipher).CipherMode:= cmCFB8bit; 
          // encrypt the record part by part, could do this in one go if it was a packed record
          Cipher.Encrypt(Packet.Date,Packet.Date,Sizeof(Packet.Date));  
          Cipher.Encrypt(Packet.ToUserID,Packet.ToUserID,Sizeof(Packet.ToUserID));
          Cipher.Encrypt(Packet.FromUserID,Packet.FromUserID,Sizeof(Packet.FromUserID));
          Cipher.Encrypt(Packet.MsgLen,Packet.MsgLen,Sizeof(Packet.MsgLen));
          Cipher.Encrypt(Packet.Msg[1],Packet.Msg[1],Length(Packet.Msg));  // slightly different for strings
          // don't bother resetting the cipher, instead keep the chaining information
        end;  
      end;
        

     

    Index, Block Ciphers, Hashes

     

    DCPcrypt is copyrighted © 1999-2002 David Barton.
    All trademarks are property of their respective owners.
    doublecmd-0.8.2/components/dcpcrypt/Docs/Index.html0000664000175000017500000002532411652036011021350 0ustar alexxalexx DCPcrypt v2: Users Guide - Index

    DCPcrypt Cryptographic Component Library v2 Beta 3
    Copyright © 1999-2002 David Barton
    http://www.cityinthesky.co.uk/
    crypto@cityinthesky.co.uk

    Introduction

    DCPcrypt is a collection of cryptographic components for the Borland Delphi(tm), C++ Builder(tm) and Kylix(tm) programming languages. The supported versions are Delphi 4, 5, 6 and 7, C++ Builder (3?), 4, 5, 6 and Kylix 1 (untested) and 2.

    The idea behind DCPcrypt is that it should be possible to "drop in" any algorithm implementation to replace another with minimum or no code changes. To aid in this goal all cryptographic components are descended from one of several base classes, TDCP_cipher for encryption algorithms and TDCP_hash for message digest algorithms.

    DCPcrypt is open source software (released under the MIT license) and as such there is no charge for inclusion in other software. However, I am currently a student and if you are making money from my software I would really appreciate a donation of some sort, whether financial or a license for the software you develop (or if anyone wants to sponsor a Mathematical Modelling (Masters) student for their final year...). Please note THIS IS NOT COMPULSORY IN ANY WAY. See http://www.cityinthesky.co.uk/cryptography.html for details on donations.

    This software is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative.

    If you maintain a website then a link to my page at http://www.cityinthesky.co.uk/ would be great!

     

    What's New

    Changes since DCPcrypt v2 Beta 2:

    • Corrected C++ Builder compilation problem.

    Changes since DCPcrypt v2 Beta 1:

    • Renamed source code files for hashes and ciphers to DCPxxx.pas
    • Change the format of Cipher.InitStr so that the hash algorithm used to generate the key is explicitly specified. In order to get the same functionality as before, use TDCP_sha1. e.g. Cipher.InitStr('Hello World',TDCP_sha1);
    • Block ciphers are now inherited from an intermediate component that implements the block size specific chaining mode encryption routines.
    • Remove the internal component registration, it was more hassle than it was worth. If there is a demand for this to be put back then I might...
    • Added the full range of operation modes for Haval. By changing the defines at the top of DCPhaval.pas you can specify the number of passes and the output hash size.
    • Added the Tiger hash algorithm (192bit digest).
    • Changed the name of the file containing TDCP_ripemd160 for consistency to DCPripemd160 from DCPrmd160.
    • GOST no longer appears on the component palette pending verifying what the actual standard is (the code is still included however).
    • Added the RipeMD-128 hash algorithm (128bit digest).
    • Added the Serpent block cipher (AES finalist).
    • Added the SHA-256,384,512 hash algorithms (256, 384, 512bit digest respectively).
    • Added CTR chaining mode to all block ciphers.

     

    Installation

    Delphi Open the appropriate package, DCPdelphiX.dpk where X is your version of Delphi (either 4, 5 or 6). Then press the install button.
    C++ Builder Create a new design time package and add all the .pas files from the DCPcrypt2.zip archive including all those in the Ciphers and Hashes subdirectories. Then press the install button.
    Kylix Open the DCPkylix.dpk package and then press the install button (note: Kylix 1 users may need to create a new package as with C++ Builder as this is a Kylix 2 package).

    You may need to add the directory containing DCPcrypt (and the Ciphers and Hashes subdirectories) to your library search path (found under Environment Options).

    Once installed you will find two extra pages of components on your component palette, namely DCPciphers and DCPhashes. You can now place these components onto the form of your application to start using the algorithms.

     

    Usage

    Please note that an appreciation of the basic principles of encryption/decryption and key management is needed to ensure the correct usage of the ciphers implemented within this package. A good introduction on this subject is provided by Bruce Schneier's "Applied Cryptography" (ISBN: 0-471-11709-9) also see the NIST publication SP800-38A for information on the block cipher chaining modes.

    • Ciphers - the basic building block of DCPcrypt, the TDCP_cipher component.
    • Block Ciphers - the base of all block ciphers, the TDCP_blockcipher component.
    • Hashes - the base of all hash algorithms, the TDCP_hash component.

    DCPcrypt v2 contains the following ciphers and hash algorithms:

    Ciphers
    Name Patents Block Size Max Key Size*
    Blowfish None 64 bits 448 bits
    Cast-128 None 64 bits 128 bits
    Cast-256 Patented? 128 bits 256 bits
    DES None 64 bits** 64 bits
    3DES None 64 bits 192 bits
    Ice None? 64 bits 64 bits
    Thin Ice None? 64 bits 64 bits
    Ice 2 None? 64 bits 128 bits
    IDEA Free for non-commercial use 64 bits 128 bits
    MARS Patented? 128 bits 1248 bits
    Misty1 Free for non-commercial use 64 bits 128 bits
    RC2 None 64 bits 1024 bits
    RC4 None N/A 2048 bits
    RC5 Patented 64 bits 2048 bits
    RC6 Patented 128 bits 2048 bits
    Rijndael (AES) None 128 bits 256 bits
    Serpent None 128 bits 256 bits
    TEA None 64 bits 128 bits
    Twofish None 128 bits 256 bits

    * although the quoted maximum key size may extremely large it doen't mean that the algorithm is secure to the same level.
    ** a 64bit key is used for DES then every 8th bit is discarded (parity) so the effective size is 56 bits.

    Hash Algorithms
    Name Patents Digest Size
    Haval None 128, 160, 192, 224, 256 bits*
    MD4 None 128 bits
    MD5 None 128 bits
    RipeMD-128 None 128 bits
    RipeMD-160 None 160 bits
    SHA-1 None 160 bits
    SHA-256 None 256 bits
    SHA-384 None 384 bits
    SHA-512 None 512 bits
    Tiger None 192 bits

    * The different digest sizes of Haval can be accessed by uncommenting the $defines at the start of DCPhaval.pas.

     

    Contact

    I appreciate knowing what DCPcrypt is being used for and also if you have any queries or bug reports please email me at crypto@cityinthesky.co.uk.

     

    DCPcrypt is copyrighted © 1999-2003 David Barton.
    All trademarks are property of their respective owners.
    doublecmd-0.8.2/components/dcpcrypt/Docs/osi-certified-120x100.png0000664000175000017500000001551711652036011023563 0ustar alexxalexxPNG  IHDRxdcetIME,k59IDATx}ytwUwLϞd$@@E\P6]{W ЏEP,-ʚe!Lf魾?wM ΄Nt=US~ꩥk BG䁵[p(>Q}DG %m@PEY^^q WjJE)J%lo½KtLՙ_/WTT^^:nG$!!ajRm1Z-i]KKHq o^vSąreB '0! @! ȋ< @AJ?ўdw=Z"B?~hYmc-Z&*T (#q0KOX;:8oԛze|faQ$վ rʯNIi(R(u<+01R`BK#~_[>h D=O}ƦFN}@Kר$Đ@A!8D<}\=M!C<"[;؎D8.Ԕ!Moґ$A OTy]n;;s̬OLDZv*ۍl0^o041sr\vyO{|L"4{O߯Uʘ&¥kŷ!SI7vnYݖQ^f;ha<ڶZ}lI )6@k9RS>{Y="M+I4˱ӖLݾdKys#)!iݼG]G/%5n4TQb "WL\w9J$zW5z۬NT!>}Nb11]zW]^WԴG#R,=b5)TYD0KXS/QS luﮙsA) Jo$ 0tJ~ktFW^4br! "GdULW#^'z}lt1yF@{߁R Օ+6/-G>XΘWǑHh3e4͗?~_#0D:ЙCX%HR%tNsODh IkKxIQ+rBq)0bBiuGw:}We \:u?kmnX.H q5+ 0y$ Lj5GJ#:A;q'e'ݜ!F?}~%Q BVRf6MCPSaP!;.L5`)Y][E pġ藜\nKQTĎzjkKU6u.IHl%QRőTssniPU뮨 *B8hHT }wר5/Wn\qe^ʹ8Ka*dU8߰<}0rDG3`2 $!&xa IiLv9#Tx- l2lϮ-ɡ}0_#x)A#8A]Pa<(` 6TA""D'TJ "Bꔐz6AcVX?_cPj$$"'($sRHJGD6jɖd >T tfCن廃e83ExZTTzbzh YiY~9P,I@rV^;y!`c]~gLy0!R]NFm2L 7/z7fԥ\Sx1Ҿ.ё/Ӡ7l1u9$w Ceu֗GN)),i5ʅVtgQ!gyPa_T~C|nbXZp%nPG_[ik._}YlNWo"#2V^WrD ⑂!0a,e\1KOSj'\ CJIjKBG;0eL.1!>b1:wq~g 0㤂l8hdfXm$JU/'{$KZbM{t8ޗ`kXԌ>k^o6 oԺ?6aDJk05>/:}dQ1ĉ!?K< =X?kyzWI (guNwm t)^ U諌SR7iQk &]"DtSkZguލ+b8z]n=6 \Ԁ$IV3,B~[ygw)+,^wJ6s-4mr؝#\^wDA>J?PBe|5 |)!6! ' oz}ކc6/Tr>3ֶСWv/fZmHH@#4df.}m }^~`ۡ3$$y}޷?}r?UaUwDĐϽ9id~y.~ >Ⱦ0v@) 66]k|7?3jiߟX1,ze{Sʚmvk9~Q i5w9deO=룭G]. "|niPC վ}ڦ]x$BT;w4ɜu:ssn~ͣgA'x75s#ϭ?E@ (!p8hu493[K恅c3b[咕VN55c3p1륆Vy@`wFjTH@kqܴ'.-!쁵uCf=3m+l3o?Mܻg>PC ?[>uJV>15 3O;ֳZH;+]4MwLK<=d'TT\H*ɒ>] K{YU)Uշ~]ٺOgeu%)Z\E4^k߶zZ[W,t4*W=h4O|z٩ތ߮PZ띴Scjr7iZRA{aﰹ'cm]{7Z/i+ZNUmUG<^E 8DPqO-ږۊaئloŬ3?È^ßL߇F{h^WpgѶ 5Dj1;lsD?K %':J݀|ݺu߿?I%m6۞={Ν;G4ayyyEEE¢(8qcR B;wd'hjtT\xϟo6Geee-7lؐ&̜͛7M&a$Ij7l:tAرcV-;CaΜ9#_ϙ3'6!֨QJJJv8q /PWw^EQl4gϞSN_ɓnݺ3 zѵkמ={d21_ зo߽{߿eɓ'*++yJ5{lVf? qyWՁ/[,999L:!vcbb:ubŊӧO{< xh$I|Wv2p?rE 4H^lٲE$PyyyrrlF۷Bعs}\_~eРA8?hO?Եk6ߕ?}ߞh7o^~!4o<CT*0LLL AGm.@4AÆ EQ<}tZZZ+**|> }% gV\4iԺxg*z}-[555~_N~].rl6so555A*++baY)%%ѣyvn֬BðZ ϗݿR]] 0UUUr!BB;Wj4@^@bbbNNαcm|Z֛L)SL2a+W>}6mr8UV͞=bV7NQ@AB $P &_ 6iժU֭ -"Ir_"IB[ A,*I0-<m(k׮]v}ǎ;tPh#ѷ\780SSS}>CKL8QjJƴFKju$I6m*.2C>t{y9J8 t;/f*6EУG6~6U$)O/oNhsz-P*#F-XaǏ;Vv[Jrm۶ 8pǎ_-[&(ϝ;W|dTUU5 Y9ŋS;P(,KeeebbbΝk~f:TnZ{!ښTh/==y9sȒ.]j233͒zdX;&)++饗Bz(-YjBr5ɚW^,\PD,^>+++++8YyQ,$YZZ*/;v8p]~sssz0 *qĉ6id52=fqw H6oBkʯȑ# qɒ%!IN {l޽{7Kaaa2NSL :999)))@t<(7ѣG͜9SY`ѢE*j3f8-|g}699YP`222Fx_t]rrرcSSS 0L՚L{lɒ%'Nlyyy{G[;܁Ο?O#.]yGv/\@QԸqV\ٽ{w9uz0t>Sݻc!y_~y-zaŋm6-Z~~ 6eʔ Re6KJJYeYVcv=$r!3n_F %':JOtp(>QAHIENDB`doublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/0000775000175000017500000000000013244011205021204 5ustar alexxalexxdoublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/TDCP_TIGER.bmp0000664000175000017500000000062611652036011023377 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/TDCP_SHA1.bmp0000664000175000017500000000062611652036011023221 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/TDCP_SHA256.bmp0000664000175000017500000000062611652036011023375 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/TDCP_RIPEMD160.bmp0000664000175000017500000000062611652036011023734 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/TDCP_SHA384.bmp0000664000175000017500000000062611652036011023377 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/TDCP_MD4.bmp0000664000175000017500000000062611652036011023111 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/TDCP_MD5.bmp0000664000175000017500000000062611652036011023112 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/TDCP_SHA512.bmp0000664000175000017500000000062611652036011023370 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/TDCP_HAVAL.bmp0000664000175000017500000000062611652036011023360 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPhashes/TDCP_RIPEMD128.bmp0000664000175000017500000000062611652036011023740 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/Hashes.html0000664000175000017500000001443211652036011021512 0ustar alexxalexx DCPcrypt v2: Users Guide - Hash Algorithms

    DCPcrypt Cryptographic Component Library v2
    Copyright © 1999-2002 David Barton
    http://www.cityinthesky.co.uk/
    crypto@cityinthesky.co.uk

    Hash Algorithms - TDCP_hash

    All hashes are derived from the TDCP_hash component. It provides a range of functions to allow the hashing of virtually every type of data.

    Functions available are:

          property Initialized: boolean;
          property Id: integer;
          property Algorithm: string;
          property HashSize: integer;
      
          class function SelfTest: boolean; 
      
          procedure Init; 
          procedure Final(var Digest); 
          procedure Burn; 
      
          procedure Update(const Buffer; Size: longword); 
          procedure UpdateStream(Stream: TStream; Size: longword);
          procedure UpdateStr(const Str: string);
        

    Example usage:


    property Initialized: boolean;

    This is set to true after Init has been called.

    property Id: integer;

    Every algorithm I implement gets given a unique ID number so that if I use several different algorithms within a program I can determine which one was used. This is a purely arbitrary numbering system.

    property Algorithm: string;

    This is the name of the algorithm implemented in the component.

    property HashSize: integer;

    This is the size of the output of the hash algorithm in BITS.

    class function SelfTest: boolean;

    In order to test whether the implementations have all been compiled correctly you can call the SelfTest function. This compares the results of several hash operations with known results for the algorithms (so called test vectors). If all the tests are passed then true is returned. If ANY of the tests are failed then false is returned. You may want to run this function for all the components when you first install the DCPcrypt package and again if you modify any of the source files, you don't need to run this everytime your program is run. Note: this only performs a selection of tests, it is not exhaustive.

    procedure Init;

    Call this procedure to initialize the hash algorithm, this must be called before using the Update procedure.

    procedure Final(var Digest);

    This procedure returns the final message digest (hash) in Digest. This variable must be the same size as the hash size. This procedure also calls Burn to clear any stored information.

    procedure Burn;

    Call this procedure if you want to abort the hashing operation (normally Final is used). This clears all information stored within the hash. Before the hash can be used again Init must be called.

    procedure Update(const Buffer; Size: longword);

    This procedure hashes Size bytes of Buffer. To get the hash result call Final.

    Update example:

      procedure HashBuffer(const Buffer; Size: longint; var Output);
      var
        Hash: TDCP_ripemd160;
      begin
        Hash:= TDCP_ripemd160.Create(nil);
        Hash.Init;
        Hash.Update(Buffer,Size);
        Hash.Final(Output);
        Hash.Free;
      end;
        

    procedure UpdateStream(Stream: TStream; Size: longword);

    This procedure hashes Size bytes from Stream. To get the hash result call Final.

    procedure UpdateStr(const Str: string);

    This procedure hashes the string Str. To get the hash result call Final.


    Example 1 - File hashing

    This example shows how you can hash the contents of a file

      procedure TForm1.Button1Click(Sender: TObject);
      var
        Hash: TDCP_ripemd160;
        Digest: array[0..19] of byte;  // RipeMD-160 produces a 160bit digest (20bytes)
        Source: TFileStream;
        i: integer;
        s: string;
      begin
        Source:= nil;
        try
          Source:= TFileStream.Create(Edit1.Text,fmOpenRead);  // open the file specified by Edit1
        except
          MessageDlg('Unable to open file',mtError,[mbOK],0);
        end;
        if Source <> nil then
        begin
          Hash:= TDCP_ripemd160.Create(Self);          // create the hash
          Hash.Init;                                   // initialize it
          Hash.UpdateStream(Source,Source.Size);       // hash the stream contents
          Hash.Final(Digest);                          // produce the digest
          Source.Free;
          s:= '';
          for i:= 0 to 19 do
            s:= s + IntToHex(Digest[i],2);
          Edit2.Text:= s;                              // display the digest
        end;
      end;
        

     

    Index, Ciphers, Block Ciphers

     

    DCPcrypt is copyrighted © 1999-2002 David Barton.
    All trademarks are property of their respective owners.
    doublecmd-0.8.2/components/dcpcrypt/Docs/MIT_license.txt0000664000175000017500000000210612014201074022274 0ustar alexxalexxThe MIT License Copyright (c) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/0000775000175000017500000000000013244011205021366 5ustar alexxalexxdoublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_RC5.bmp0000664000175000017500000000062611652036011023300 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_RC6.bmp0000664000175000017500000000062611652036011023301 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_ICE.bmp0000664000175000017500000000062611652036011023307 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_MISTY1.bmp0000664000175000017500000000062611652036011023675 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_ICE2.bmp0000664000175000017500000000062611652036011023371 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_THINICE.bmp0000664000175000017500000000062611652036011023772 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_DES.bmp0000664000175000017500000000062611652036011023322 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_TWOFISH.bmp0000664000175000017500000000062611652036011024032 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_RC4.bmp0000664000175000017500000000062611652036011023277 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_MARS.bmp0000664000175000017500000000062611652036011023451 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_GOST.bmp0000664000175000017500000000062611652036011023463 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_SERPENT.bmp0000664000175000017500000000062611652036011024027 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_RIJNDAEL.bmp0000664000175000017500000000062611652036011024077 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_3DES.bmp0000664000175000017500000000062611652036011023405 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_IDEA.bmp0000664000175000017500000000062611652036011023411 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_RC2.bmp0000664000175000017500000000062611652036011023275 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_BLOWFISH.bmp0000664000175000017500000000062611652036011024124 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_TEA.bmp0000664000175000017500000000062611652036011023320 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_CAST128.bmp0000664000175000017500000000062611652036011023674 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/DCPciphers/TDCP_CAST256.bmp0000664000175000017500000000062611652036011023676 0ustar alexxalexxBMv( doublecmd-0.8.2/components/dcpcrypt/Docs/BlockCiphers.html0000664000175000017500000001604711652036011022653 0ustar alexxalexx DCPcrypt v2: Users Guide - Block Ciphers

    DCPcrypt Cryptographic Component Library v2
    Copyright © 1999-2002 David Barton
    http://www.cityinthesky.co.uk/
    crypto@cityinthesky.co.uk

    Block Ciphers - TDCP_blockcipher

    All block ciphers are inherited from the TDCP_blockcipher component via either the TDCP_blockcipher64 and TDCP_blockcipher128 components (the latter implement the block size specific code).

    The TDCP_blockcipher component extends the TDCP_cipher component to provide chaining mode functions. Functions available are:

          property Initialized: boolean;
          property Id: integer;
          property Algorithm: string;
          property MaxKeySize: integer;
          property BlockSize: integer;
          property CipherMode: TDCP_ciphermode;
      
          class function SelfTest: boolean;
     
          procedure SetIV(const Value);
          procedure GetIV(var Value);
     
          procedure Init(const Key; Size: longword; InitVector: pointer); 
          procedure InitStr(const Key: string; HashType: TDCP_hashclass);
          procedure Burn; 
          procedure Reset;
          procedure Encrypt(const Indata; var Outdata; Size: longword); 
          procedure Decrypt(const Indata; var Outdata; Size: longword); 
          function EncryptStream(InStream, OutStream: TStream; Size: longword): longword;
          function DecryptStream(InStream, OutStream: TStream; Size: longword): longword;
          function EncryptString(const Str: string): string; 
          function DecryptString(const Str: string): string; 
          procedure EncryptECB(const Indata; var Outdata);
          procedure DecryptECB(const Indata; var Outdata);
          procedure EncryptCBC(const Indata; var Outdata; Size: longword);
          procedure DecryptCBC(const Indata; var Outdata; Size: longword);
          procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword);
          procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword);
          procedure EncryptCFBblock(const Indata; var Outdata; Size: longword);
          procedure DecryptCFBblock(const Indata; var Outdata; Size: longword);
          procedure EncryptOFB(const Indata; var Outdata; Size: longword);
          procedure DecryptOFB(const Indata; var Outdata; Size: longword);
          procedure EncryptCTR(const Indata; var Outdata; Size: longword);
          procedure DecryptCTR(const Indata; var Outdata; Size: longword);
        

    Function descriptions

    property BlockSize: integer;

    This contains the block size of the cipher in BITS.

    property CipherMode: TDCP_ciphermode;

    This is the current chaining mode used when Encrypt is called. The available modes are:

    • cmCBC - Cipher block chaining.
    • cmCFB8bit - 8bit cipher feedback.
    • cmCFBblock - Cipher feedback (using the block size of the algorithm).
    • cmOFB - Output feedback.
    • cmCTR - Counter.

    Each chaining mode has it's own pro's and cons. See any good book on cryptography or the NIST publication SP800-38A for details on each.

    procedure SetIV(const Value);

    Use this procedure to set the current chaining mode information to Value. This variable should be the same size as the block size. When Reset is called subsequent to this, the chaining information will be set back to Value.

    procedure GetIV(var Value);

    This returns in Value the current chaining mode information, to get the initial chaining mode information you need to call Reset before calling GetIV. The variable passed in Value must be at least the same size as the block size otherwise you will get a buffer overflow.

    procedure EncryptCBC(const Indata; var Outdata; Size: longword);
    procedure DecryptCBC(const Indata; var Outdata; Size: longword);
    procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword);
    procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword);
    procedure EncryptCFBblock(const Indata; var Outdata; Size: longword);
    procedure DecryptCFBblock(const Indata; var Outdata; Size: longword);
    procedure EncryptOFB(const Indata; var Outdata; Size: longword);
    procedure DecryptOFB(const Indata; var Outdata; Size: longword);
    procedure EncryptCTR(const Indata; var Outdata; Size: longword);
    procedure DecryptCTR(const Indata; var Outdata; Size: longword);

    These procedures encrypt/decrypt Size bytes of data from Indata and places the result in Outdata. These all employ chaining mode methods of encryption/decryption and so may need to be used inconjunction with Reset. The CBC method uses short block encryption as specified in Bruce Schneier's "Applied Cryptography" for data blocks that are not multiples of the block size.

     

    Index, Ciphers, Hashes

     

    DCPcrypt is copyrighted © 1999-2002 David Barton.
    All trademarks are property of their respective owners.
    doublecmd-0.8.2/components/dcpcrypt/Hashes/0000775000175000017500000000000013244011205017725 5ustar alexxalexxdoublecmd-0.8.2/components/dcpcrypt/Hashes/dcpsha224.pas0000664000175000017500000000603413031723465022143 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of SHA224 *******************************} {******************************************************************************} {* Copyright (C) 2016 Alexander Koblov (alexx2000@mail.ru) *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPsha224; {$mode objfpc}{$H+} interface uses Classes, SysUtils, DCPsha256; type { TDCP_sha224 } TDCP_sha224 = class(TDCP_sha256) public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; end; implementation { TDCP_sha224 } class function TDCP_sha224.GetId: integer; begin Result:= 0; end; class function TDCP_sha224.GetAlgorithm: string; begin Result:= 'SHA224'; end; class function TDCP_sha224.GetHashSize: integer; begin Result:= 224; end; class function TDCP_sha224.SelfTest: boolean; begin Result:= False; // TODO: SelfTest SHA2_224 end; procedure TDCP_sha224.Init; begin Burn; CurrentHash[0]:= $C1059ED8; CurrentHash[1]:= $367CD507; CurrentHash[2]:= $3070DD17; CurrentHash[3]:= $F70E5939; CurrentHash[4]:= $FFC00B31; CurrentHash[5]:= $68581511; CurrentHash[6]:= $64F98FA7; CurrentHash[7]:= $BEFA4FA4; fInitialized:= True; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dccrc32.pp0000664000175000017500000001072212573022170021522 0ustar alexxalexx{ Double Commander ------------------------------------------------------------------------- Fast CRC32 calculation algorithm http://create.stephan-brumme.com/crc32 Copyright (C) 2011-2015 Stephan Brumme. All rights reserved. Slicing-by-16 contributed by Bulat Ziganshin See http://create.stephan-brumme.com/disclaimer.html Pascal tranlastion Copyright (C) 2015 Alexander Koblov (alexx2000@mail.ru) This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. 2. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. } unit DCcrc32; {$mode objfpc}{$H+} interface uses Classes, SysUtils; procedure crc32_init; function crc32_16bytes(const data: PByte; length: Integer; previousCrc32: Cardinal = 0): Cardinal; implementation {$R-}{$Q-} const /// zlib's CRC32 polynomial Polynomial: Cardinal = $EDB88320; var HaveTable: Boolean = False; Crc32Lookup: array[0..15, 0..255] of Cardinal; procedure crc32_init; var i, j: Integer; crc: Cardinal; slice: Integer; begin if HaveTable then Exit; //// same algorithm as crc32_bitwise for i := 0 to $FF do begin crc := Cardinal(i); for j := 0 to 7 do begin if (crc and 1) <> 0 then crc := Polynomial xor (crc shr 1) else crc := (crc shr 1); end; Crc32Lookup[0][i] := crc; end; // ... and the following slicing-by-8 algorithm (from Intel): // http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf // http://sourceforge.net/projects/slicing-by-8/ for i := 0 to $FF do begin for slice := 1 to 15 do Crc32Lookup[slice][i] := (Crc32Lookup[slice - 1][i] shr 8) xor Crc32Lookup[0][Crc32Lookup[slice - 1][i] and $FF]; end; HaveTable:= True; end; /// compute CRC32 (Slicing-by-16 algorithm) function crc32_16bytes(const data: PByte; length: Integer; previousCrc32: Cardinal = 0): Cardinal; const Unroll = 4; BytesAtOnce = 16 * Unroll; var crc: cardinal; unrolling: integer; current: PLongWord; currentChar: PByte; one, two, three, four: cardinal; begin crc := previousCrc32 xor $FFFFFFFF; current := PLongWord(data); // enabling optimization (at least -O2) automatically unrolls the inner for-loop while (length >= BytesAtOnce) do begin for unrolling := 0 to Unroll - 1 do begin one := current^ xor crc; Inc(current); two := current^; Inc(current); three := current^; Inc(current); four := current^; Inc(current); crc := Crc32Lookup[ 0][(four shr 24) and $FF] xor Crc32Lookup[ 1][(four shr 16) and $FF] xor Crc32Lookup[ 2][(four shr 8) and $FF] xor Crc32Lookup[ 3][ four and $FF] xor Crc32Lookup[ 4][(three shr 24) and $FF] xor Crc32Lookup[ 5][(three shr 16) and $FF] xor Crc32Lookup[ 6][(three shr 8) and $FF] xor Crc32Lookup[ 7][ three and $FF] xor Crc32Lookup[ 8][(two shr 24) and $FF] xor Crc32Lookup[ 9][(two shr 16) and $FF] xor Crc32Lookup[10][(two shr 8) and $FF] xor Crc32Lookup[11][ two and $FF] xor Crc32Lookup[12][(one shr 24) and $FF] xor Crc32Lookup[13][(one shr 16) and $FF] xor Crc32Lookup[14][(one shr 8) and $FF] xor Crc32Lookup[15][ one and $FF]; end; length -= BytesAtOnce; end; currentChar := PByte(current); // remaining 1 to 63 bytes (standard algorithm) while (length <> 0) do begin crc := (crc shr 8) xor Crc32Lookup[0][(crc and $FF) xor currentChar^]; Inc(currentChar); Dec(length); end; Result:= crc xor $FFFFFFFF; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dcphaval.pas0000664000175000017500000003656612014201074022233 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of Haval ********************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPhaval; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2, DCPconst; type TDCP_haval= class(TDCP_hash) protected LenHi, LenLo: longword; Index: DWord; CurrentHash: array[0..7] of DWord; HashBuffer: array[0..127] of byte; procedure Compress; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; procedure Final(var Digest); override; end; { Choose how many passes (previous versions of DCPcrypt uses 5 passes) } { ONLY UNCOMMENT ONE! } //{$DEFINE PASS3} //{$DEFINE PASS4} {$DEFINE PASS5} { Choose digest length (previous versions of DCPcrypt uses 256bits) } { ONLY UNCOMMENT ONE! } //{$DEFINE DIGEST128} //{$DEFINE DIGEST160} //{$DEFINE DIGEST192} //{$DEFINE DIGEST224} {$DEFINE DIGEST256} {******************************************************************************} {******************************************************************************} implementation {$R-}{$Q-} procedure TDCP_haval.Compress; var t7, t6, t5, t4, t3, t2, t1, t0: DWord; W: array[0..31] of DWord; Temp: dword; begin dcpFillChar(W, SizeOf(W), 0); t0:= CurrentHash[0]; t1:= CurrentHash[1]; t2:= CurrentHash[2]; t3:= CurrentHash[3]; t4:= CurrentHash[4]; t5:= CurrentHash[5]; t6:= CurrentHash[6]; t7:= CurrentHash[7]; Move(HashBuffer,W,Sizeof(W)); {$IFDEF PASS3} {$INCLUDE DCPhaval3.inc} {$ELSE} {$IFDEF PASS4} {$INCLUDE DCPhaval4.inc} {$ELSE} {$INCLUDE DCPhaval5.inc} {$ENDIF} {$ENDIF} Inc(CurrentHash[0],t0); Inc(CurrentHash[1],t1); Inc(CurrentHash[2],t2); Inc(CurrentHash[3],t3); Inc(CurrentHash[4],t4); Inc(CurrentHash[5],t5); Inc(CurrentHash[6],t6); Inc(CurrentHash[7],t7); FillChar(W,Sizeof(W),0); Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); end; class function TDCP_haval.GetHashSize: integer; begin {$IFDEF DIGEST128} Result:= 128; {$ELSE} {$IFDEF DIGEST160} Result:= 160; {$ELSE} {$IFDEF DIGEST192} Result:= 192; {$ELSE} {$IFDEF DIGEST224} Result:= 224; {$ELSE} Result:= 256; {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} end; class function TDCP_haval.GetId: integer; begin Result:= DCP_haval; end; class function TDCP_haval.GetAlgorithm: string; begin Result:= 'Haval ('; {$IFDEF DIGEST128} Result:= Result+'128bit, '; {$ELSE} {$IFDEF DIGEST160} Result:= Result+'160bit, '; {$ELSE} {$IFDEF DIGEST192} Result:= Result+'192bit, '; {$ELSE} {$IFDEF DIGEST224} Result:= Result+'224bit, '; {$ELSE} Result:= Result+'256bit, '; {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$IFDEF PASS3} Result:= Result+'3 passes)'; {$ELSE} {$IFDEF PASS4} Result:= Result+'4 passes)'; {$ELSE} Result:= Result+'5 passes)'; {$ENDIF} {$ENDIF} end; class function TDCP_haval.SelfTest: boolean; {$IFDEF PASS3} {$IFDEF DIGEST128} const Test1Out: array[0..15] of byte= ($1B,$DC,$55,$6B,$29,$AD,$02,$EC,$09,$AF,$8C,$66,$47,$7F,$2A,$87); var TestHash: TDCP_haval; TestOut: array[0..15] of byte; begin TestHash:= TDCP_haval.Create(nil); TestHash.Init; TestHash.UpdateStr(''); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Free; {$ELSE} {$IFDEF DIGEST160} const Test1Out: array[0..19] of byte= ($5E,$16,$10,$FC,$ED,$1D,$3A,$DB,$0B,$B1, $8E,$92,$AC,$2B,$11,$F0,$BD,$99,$D8,$ED); var TestHash: TDCP_haval; TestOut: array[0..19] of byte; begin TestHash:= TDCP_haval.Create(nil); TestHash.Init; TestHash.UpdateStr('a'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Free; {$ELSE} begin Result:= true; {$ENDIF} {$ENDIF} {$ELSE} {$IFDEF PASS4} {$IFDEF DIGEST192} const Test1Out: array[0..23] of byte= ($74,$AA,$31,$18,$2F,$F0,$9B,$CC,$E4,$53,$A7,$F7, $1B,$5A,$7C,$5E,$80,$87,$2F,$A9,$0C,$D9,$3A,$E4); var TestHash: TDCP_haval; TestOut: array[0..23] of byte; begin TestHash:= TDCP_haval.Create(nil); TestHash.Init; TestHash.UpdateStr('HAVAL'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Free; {$ELSE} {$IFDEF DIGEST224} const Test1Out: array[0..27] of byte= ($14,$4C,$B2,$DE,$11,$F0,$5D,$F7,$C3,$56,$28,$2A,$3B,$48, $57,$96,$DA,$65,$3F,$6B,$70,$28,$68,$C7,$DC,$F4,$AE,$76); var TestHash: TDCP_haval; TestOut: array[0..27] of byte; begin TestHash:= TDCP_haval.Create(nil); TestHash.Init; TestHash.UpdateStr('0123456789'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Free; {$ELSE} begin Result:= true; {$ENDIF} {$ENDIF} {$ELSE} {$IFDEF DIGEST256} const Test1Out: array[0..31] of byte= ($1A,$1D,$C8,$09,$9B,$DA,$A7,$F3,$5B,$4D,$A4,$E8,$05,$F1,$A2,$8F, $EE,$90,$9D,$8D,$EE,$92,$01,$98,$18,$5C,$BC,$AE,$D8,$A1,$0A,$8D); Test2Out: array[0..31] of byte= ($C5,$64,$7F,$C6,$C1,$87,$7F,$FF,$96,$74,$2F,$27,$E9,$26,$6B,$68, $74,$89,$4F,$41,$A0,$8F,$59,$13,$03,$3D,$9D,$53,$2A,$ED,$DB,$39); var TestHash: TDCP_haval; TestOut: array[0..31] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_haval.Create(nil); TestHash.Init; TestHash.UpdateStr('abcdefghijklmnopqrstuvwxyz'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Init; TestHash.UpdateStr('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out)) and Result; TestHash.Free; {$ELSE} begin Result:= true; {$ENDIF} {$ENDIF} {$ENDIF} end; procedure TDCP_haval.Init; begin Burn; CurrentHash[0]:= $243F6A88; CurrentHash[1]:= $85A308D3; CurrentHash[2]:= $13198A2E; CurrentHash[3]:= $03707344; CurrentHash[4]:= $A4093822; CurrentHash[5]:= $299F31D0; CurrentHash[6]:= $082EFA98; CurrentHash[7]:= $EC4E6C89; fInitialized:= true; end; procedure TDCP_haval.Burn; begin LenHi:= 0; LenLo:= 0; Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); FillChar(CurrentHash,Sizeof(CurrentHash),0); fInitialized:= false; end; procedure TDCP_haval.Update(const Buffer; Size: longword); var PBuf: ^byte; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); Inc(LenHi,Size shr 29); Inc(LenLo,Size*8); if LenLo< (Size*8) then Inc(LenHi); PBuf:= @Buffer; while Size> 0 do begin if (Sizeof(HashBuffer)-Index)<= DWord(Size) then begin Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index); Dec(Size,Sizeof(HashBuffer)-Index); Inc(PBuf,Sizeof(HashBuffer)-Index); Compress; end else begin Move(PBuf^,HashBuffer[Index],Size); Inc(Index,Size); Size:= 0; end; end; end; procedure TDCP_haval.Final(var Digest); {$IFNDEF DIGEST256} {$IFNDEF DIGEST224} var temp: dword; {$ENDIF} {$ENDIF} begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); HashBuffer[Index]:= $80; if Index>= 118 then Compress; {$IFDEF PASS3} {$IFDEF DIGEST128} HashBuffer[118]:= ((128 and 3) shl 6) or (3 shl 3) or 1; HashBuffer[119]:= (128 shr 2) and $FF; {$ELSE} {$IFDEF DIGEST160} HashBuffer[118]:= ((160 and 3) shl 6) or (3 shl 3) or 1; HashBuffer[119]:= (160 shr 2) and $FF; {$ELSE} {$IFDEF DIGEST192} HashBuffer[118]:= ((192 and 3) shl 6) or (3 shl 3) or 1; HashBuffer[119]:= (192 shr 2) and $FF; {$ELSE} {$IFDEF DIGEST224} HashBuffer[118]:= ((224 and 3) shl 6) or (3 shl 3) or 1; HashBuffer[119]:= (224 shr 2) and $FF; {$ELSE} HashBuffer[118]:= ((256 and 3) shl 6) or (3 shl 3) or 1; HashBuffer[119]:= (256 shr 2) and $FF; {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ELSE} {$IFDEF PASS4} {$IFDEF DIGEST128} HashBuffer[118]:= ((128 and 3) shl 6) or (4 shl 3) or 1; HashBuffer[119]:= (128 shr 2) and $FF; {$ELSE} {$IFDEF DIGEST160} HashBuffer[118]:= ((160 and 3) shl 6) or (4 shl 3) or 1; HashBuffer[119]:= (160 shr 2) and $FF; {$ELSE} {$IFDEF DIGEST192} HashBuffer[118]:= ((192 and 3) shl 6) or (4 shl 3) or 1; HashBuffer[119]:= (192 shr 2) and $FF; {$ELSE} {$IFDEF DIGEST224} HashBuffer[118]:= ((224 and 3) shl 6) or (4 shl 3) or 1; HashBuffer[119]:= (224 shr 2) and $FF; {$ELSE} HashBuffer[118]:= ((256 and 3) shl 6) or (4 shl 3) or 1; HashBuffer[119]:= (256 shr 2) and $FF; {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ELSE} {$IFDEF DIGEST128} HashBuffer[118]:= ((128 and 3) shl 6) or (5 shl 3) or 1; HashBuffer[119]:= (2128 shr 2) and $FF; {$ELSE} {$IFDEF DIGEST160} HashBuffer[118]:= ((160 and 3) shl 6) or (5 shl 3) or 1; HashBuffer[119]:= (160 shr 2) and $FF; {$ELSE} {$IFDEF DIGEST192} HashBuffer[118]:= ((192 and 3) shl 6) or (5 shl 3) or 1; HashBuffer[119]:= (192 shr 2) and $FF; {$ELSE} {$IFDEF DIGEST224} HashBuffer[118]:= ((224 and 3) shl 6) or (5 shl 3) or 1; HashBuffer[119]:= (224 shr 2) and $FF; {$ELSE} HashBuffer[118]:= ((256 and 3) shl 6) or (5 shl 3) or 1; HashBuffer[119]:= (256 shr 2) and $FF; {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} PDWord(@HashBuffer[120])^:= LenLo; PDWord(@HashBuffer[124])^:= LenHi; Compress; {$IFDEF DIGEST128} temp:= (CurrentHash[7] and $000000FF) or (CurrentHash[6] and $FF000000) or (CurrentHash[5] and $00FF0000) or (CurrentHash[4] and $0000FF00); Inc(CurrentHash[0],(temp shr 8) or (temp shl 24)); temp:= (CurrentHash[7] and $0000FF00) or (CurrentHash[6] and $000000FF) or (CurrentHash[5] and $FF000000) or (CurrentHash[4] and $00FF0000); Inc(CurrentHash[1],(temp shr 16) or (temp shl 16)); temp:= (CurrentHash[7] and $00FF0000) or (CurrentHash[6] and $0000FF00) or (CurrentHash[5] and $000000FF) or (CurrentHash[4] and $FF000000); Inc(CurrentHash[2],(temp shr 24) or (temp shl 8)); temp:= (CurrentHash[7] and $FF000000) or (CurrentHash[6] and $00FF0000) or (CurrentHash[5] and $0000FF00) or (CurrentHash[4] and $000000FF); Inc(CurrentHash[3],temp); Move(CurrentHash,Digest,128 div 8); {$ELSE} {$IFDEF DIGEST160} temp:= (CurrentHash[7] and $3F) or (CurrentHash[6] and ($7F shl 25)) or (CurrentHash[5] and ($3F shl 19)); Inc(CurrentHash[0],(temp shr 19) or (temp shl 13)); temp:= (CurrentHash[7] and ($3F shl 6)) or (CurrentHash[6] and $3F) or (CurrentHash[5] and ($7F shl 25)); Inc(CurrentHash[1],(temp shr 25) or (temp shl 7)); temp:= (CurrentHash[7] and ($7F shl 12)) or (CurrentHash[6] and ($3F shl 6)) or (CurrentHash[5] and $3F); Inc(CurrentHash[2],temp); temp:= (CurrentHash[7] and ($3F shl 19)) or (CurrentHash[6] and ($7F shl 12)) or (CurrentHash[5] and ($3F shl 6)); Inc(CurrentHash[3],temp shr 6); temp:= (CurrentHash[7] and ($7F shl 25)) or (CurrentHash[6] and ($3F shl 19)) or (CurrentHash[5] and ($7F shl 12)); Inc(CurrentHash[4],temp shr 12); Move(CurrentHash,Digest,160 div 8); {$ELSE} {$IFDEF DIGEST192} temp:= (CurrentHash[7] and $1F) or (CurrentHash[6] and ($3F shl 26)); Inc(CurrentHash[0],(temp shr 26) or (temp shl 6)); temp:= (CurrentHash[7] and ($1F shl 5)) or (CurrentHash[6] and $1F); Inc(CurrentHash[1],temp); temp:= (CurrentHash[7] and ($3F shl 10)) or (CurrentHash[6] and ($1F shl 5)); Inc(CurrentHash[2],temp shr 5); temp:= (CurrentHash[7] and ($1F shl 16)) or (CurrentHash[6] and ($3F shl 10)); Inc(CurrentHash[3],temp shr 10); temp:= (CurrentHash[7] and ($1F shl 21)) or (CurrentHash[6] and ($1F shl 16)); Inc(CurrentHash[4],temp shr 16); temp:= (CurrentHash[7] and ($3F shl 26)) or (CurrentHash[6] and ($1F shl 21)); Inc(CurrentHash[5],temp shr 21); Move(CurrentHash,Digest,192 div 8); {$ELSE} {$IFDEF DIGEST224} Inc(CurrentHash[0],(CurrentHash[7] shr 27) and $1F); Inc(CurrentHash[1],(CurrentHash[7] shr 22) and $1F); Inc(CurrentHash[2],(CurrentHash[7] shr 18) and $F); Inc(CurrentHash[3],(CurrentHash[7] shr 13) and $1F); Inc(CurrentHash[4],(CurrentHash[7] shr 9) and $F); Inc(CurrentHash[5],(CurrentHash[7] shr 4) and $1F); Inc(CurrentHash[6],CurrentHash[7] and $F); Move(CurrentHash,Digest,224 div 8); {$ELSE} Move(CurrentHash,Digest,256 div 8); {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dcpripemd128.pas0000664000175000017500000004101612014201074022635 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of RipeMD-128 ***************************} {******************************************************************************} {* Copyright (c) 2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPripemd128; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2, DCPconst; type TDCP_ripemd128= class(TDCP_hash) protected LenHi, LenLo: longword; Index: DWord; CurrentHash: array[0..3] of DWord; HashBuffer: array[0..63] of byte; procedure Compress; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; procedure Final(var Digest); override; end; {******************************************************************************} {******************************************************************************} implementation {$R-}{$Q-} procedure TDCP_ripemd128.Compress; var X: array[0..15] of DWord; a, aa, b, bb, c, cc, d, dd, t: dword; begin dcpFillChar(X, SizeOf(X), 0); Move(HashBuffer,X,Sizeof(X)); a:= CurrentHash[0]; aa:= a; b:= CurrentHash[1]; bb:= b; c:= CurrentHash[2]; cc:= c; d:= CurrentHash[3]; dd:= d; t:= a + (b xor c xor d) + X[ 0]; a:= (t shl 11) or (t shr (32-11)); t:= d + (a xor b xor c) + X[ 1]; d:= (t shl 14) or (t shr (32-14)); t:= c + (d xor a xor b) + X[ 2]; c:= (t shl 15) or (t shr (32-15)); t:= b + (c xor d xor a) + X[ 3]; b:= (t shl 12) or (t shr (32-12)); t:= a + (b xor c xor d) + X[ 4]; a:= (t shl 5) or (t shr (32-5)); t:= d + (a xor b xor c) + X[ 5]; d:= (t shl 8) or (t shr (32-8)); t:= c + (d xor a xor b) + X[ 6]; c:= (t shl 7) or (t shr (32-7)); t:= b + (c xor d xor a) + X[ 7]; b:= (t shl 9) or (t shr (32-9)); t:= a + (b xor c xor d) + X[ 8]; a:= (t shl 11) or (t shr (32-11)); t:= d + (a xor b xor c) + X[ 9]; d:= (t shl 13) or (t shr (32-13)); t:= c + (d xor a xor b) + X[10]; c:= (t shl 14) or (t shr (32-14)); t:= b + (c xor d xor a) + X[11]; b:= (t shl 15) or (t shr (32-15)); t:= a + (b xor c xor d) + X[12]; a:= (t shl 6) or (t shr (32-6)); t:= d + (a xor b xor c) + X[13]; d:= (t shl 7) or (t shr (32-7)); t:= c + (d xor a xor b) + X[14]; c:= (t shl 9) or (t shr (32-9)); t:= b + (c xor d xor a) + X[15]; b:= (t shl 8) or (t shr (32-8)); t:= a + ((b and c) or (not b and d)) + X[ 7]+$5A827999; a:= (t shl 7) or (t shr (32-7)); t:= d + ((a and b) or (not a and c)) + X[ 4]+$5A827999; d:= (t shl 6) or (t shr (32-6)); t:= c + ((d and a) or (not d and b)) + X[13]+$5A827999; c:= (t shl 8) or (t shr (32-8)); t:= b + ((c and d) or (not c and a)) + X[ 1]+$5A827999; b:= (t shl 13) or (t shr (32-13)); t:= a + ((b and c) or (not b and d)) + X[10]+$5A827999; a:= (t shl 11) or (t shr (32-11)); t:= d + ((a and b) or (not a and c)) + X[ 6]+$5A827999; d:= (t shl 9) or (t shr (32-9)); t:= c + ((d and a) or (not d and b)) + X[15]+$5A827999; c:= (t shl 7) or (t shr (32-7)); t:= b + ((c and d) or (not c and a)) + X[ 3]+$5A827999; b:= (t shl 15) or (t shr (32-15)); t:= a + ((b and c) or (not b and d)) + X[12]+$5A827999; a:= (t shl 7) or (t shr (32-7)); t:= d + ((a and b) or (not a and c)) + X[ 0]+$5A827999; d:= (t shl 12) or (t shr (32-12)); t:= c + ((d and a) or (not d and b)) + X[ 9]+$5A827999; c:= (t shl 15) or (t shr (32-15)); t:= b + ((c and d) or (not c and a)) + X[ 5]+$5A827999; b:= (t shl 9) or (t shr (32-9)); t:= a + ((b and c) or (not b and d)) + X[ 2]+$5A827999; a:= (t shl 11) or (t shr (32-11)); t:= d + ((a and b) or (not a and c)) + X[14]+$5A827999; d:= (t shl 7) or (t shr (32-7)); t:= c + ((d and a) or (not d and b)) + X[11]+$5A827999; c:= (t shl 13) or (t shr (32-13)); t:= b + ((c and d) or (not c and a)) + X[ 8]+$5A827999; b:= (t shl 12) or (t shr (32-12)); t:= a + ((b or not c) xor d) + X[ 3]+$6ED9EBA1; a:= (t shl 11) or (t shr (32-11)); t:= d + ((a or not b) xor c) + X[10]+$6ED9EBA1; d:= (t shl 13) or (t shr (32-13)); t:= c + ((d or not a) xor b) + X[14]+$6ED9EBA1; c:= (t shl 6) or (t shr (32-6)); t:= b + ((c or not d) xor a) + X[ 4]+$6ED9EBA1; b:= (t shl 7) or (t shr (32-7)); t:= a + ((b or not c) xor d) + X[ 9]+$6ED9EBA1; a:= (t shl 14) or (t shr (32-14)); t:= d + ((a or not b) xor c) + X[15]+$6ED9EBA1; d:= (t shl 9) or (t shr (32-9)); t:= c + ((d or not a) xor b) + X[ 8]+$6ED9EBA1; c:= (t shl 13) or (t shr (32-13)); t:= b + ((c or not d) xor a) + X[ 1]+$6ED9EBA1; b:= (t shl 15) or (t shr (32-15)); t:= a + ((b or not c) xor d) + X[ 2]+$6ED9EBA1; a:= (t shl 14) or (t shr (32-14)); t:= d + ((a or not b) xor c) + X[ 7]+$6ED9EBA1; d:= (t shl 8) or (t shr (32-8)); t:= c + ((d or not a) xor b) + X[ 0]+$6ED9EBA1; c:= (t shl 13) or (t shr (32-13)); t:= b + ((c or not d) xor a) + X[ 6]+$6ED9EBA1; b:= (t shl 6) or (t shr (32-6)); t:= a + ((b or not c) xor d) + X[13]+$6ED9EBA1; a:= (t shl 5) or (t shr (32-5)); t:= d + ((a or not b) xor c) + X[11]+$6ED9EBA1; d:= (t shl 12) or (t shr (32-12)); t:= c + ((d or not a) xor b) + X[ 5]+$6ED9EBA1; c:= (t shl 7) or (t shr (32-7)); t:= b + ((c or not d) xor a) + X[12]+$6ED9EBA1; b:= (t shl 5) or (t shr (32-5)); t:= a + ((b and d) or (c and not d)) + X[ 1]+$8F1BBCDC; a:= (t shl 11) or (t shr (32-11)); t:= d + ((a and c) or (b and not c)) + X[ 9]+$8F1BBCDC; d:= (t shl 12) or (t shr (32-12)); t:= c + ((d and b) or (a and not b)) + X[11]+$8F1BBCDC; c:= (t shl 14) or (t shr (32-14)); t:= b + ((c and a) or (d and not a)) + X[10]+$8F1BBCDC; b:= (t shl 15) or (t shr (32-15)); t:= a + ((b and d) or (c and not d)) + X[ 0]+$8F1BBCDC; a:= (t shl 14) or (t shr (32-14)); t:= d + ((a and c) or (b and not c)) + X[ 8]+$8F1BBCDC; d:= (t shl 15) or (t shr (32-15)); t:= c + ((d and b) or (a and not b)) + X[12]+$8F1BBCDC; c:= (t shl 9) or (t shr (32-9)); t:= b + ((c and a) or (d and not a)) + X[ 4]+$8F1BBCDC; b:= (t shl 8) or (t shr (32-8)); t:= a + ((b and d) or (c and not d)) + X[13]+$8F1BBCDC; a:= (t shl 9) or (t shr (32-9)); t:= d + ((a and c) or (b and not c)) + X[ 3]+$8F1BBCDC; d:= (t shl 14) or (t shr (32-14)); t:= c + ((d and b) or (a and not b)) + X[ 7]+$8F1BBCDC; c:= (t shl 5) or (t shr (32-5)); t:= b + ((c and a) or (d and not a)) + X[15]+$8F1BBCDC; b:= (t shl 6) or (t shr (32-6)); t:= a + ((b and d) or (c and not d)) + X[14]+$8F1BBCDC; a:= (t shl 8) or (t shr (32-8)); t:= d + ((a and c) or (b and not c)) + X[ 5]+$8F1BBCDC; d:= (t shl 6) or (t shr (32-6)); t:= c + ((d and b) or (a and not b)) + X[ 6]+$8F1BBCDC; c:= (t shl 5) or (t shr (32-5)); t:= b + ((c and a) or (d and not a)) + X[ 2]+$8F1BBCDC; b:= (t shl 12) or (t shr (32-12)); t:= aa + ((bb and dd) or (cc and not dd)) + X[ 5]+$50A28BE6; aa:= (t shl 8) or (t shr (32-8)); t:= dd + ((aa and cc) or (bb and not cc)) + X[14]+$50A28BE6; dd:= (t shl 9) or (t shr (32-9)); t:= cc + ((dd and bb) or (aa and not bb)) + X[ 7]+$50A28BE6; cc:= (t shl 9) or (t shr (32-9)); t:= bb + ((cc and aa) or (dd and not aa)) + X[ 0]+$50A28BE6; bb:= (t shl 11) or (t shr (32-11)); t:= aa + ((bb and dd) or (cc and not dd)) + X[ 9]+$50A28BE6; aa:= (t shl 13) or (t shr (32-13)); t:= dd + ((aa and cc) or (bb and not cc)) + X[ 2]+$50A28BE6; dd:= (t shl 15) or (t shr (32-15)); t:= cc + ((dd and bb) or (aa and not bb)) + X[11]+$50A28BE6; cc:= (t shl 15) or (t shr (32-15)); t:= bb + ((cc and aa) or (dd and not aa)) + X[ 4]+$50A28BE6; bb:= (t shl 5) or (t shr (32-5)); t:= aa + ((bb and dd) or (cc and not dd)) + X[13]+$50A28BE6; aa:= (t shl 7) or (t shr (32-7)); t:= dd + ((aa and cc) or (bb and not cc)) + X[ 6]+$50A28BE6; dd:= (t shl 7) or (t shr (32-7)); t:= cc + ((dd and bb) or (aa and not bb)) + X[15]+$50A28BE6; cc:= (t shl 8) or (t shr (32-8)); t:= bb + ((cc and aa) or (dd and not aa)) + X[ 8]+$50A28BE6; bb:= (t shl 11) or (t shr (32-11)); t:= aa + ((bb and dd) or (cc and not dd)) + X[ 1]+$50A28BE6; aa:= (t shl 14) or (t shr (32-14)); t:= dd + ((aa and cc) or (bb and not cc)) + X[10]+$50A28BE6; dd:= (t shl 14) or (t shr (32-14)); t:= cc + ((dd and bb) or (aa and not bb)) + X[ 3]+$50A28BE6; cc:= (t shl 12) or (t shr (32-12)); t:= bb + ((cc and aa) or (dd and not aa)) + X[12]+$50A28BE6; bb:= (t shl 6) or (t shr (32-6)); t:= aa + ((bb or not cc) xor dd) + X[ 6]+$5C4DD124; aa:= (t shl 9) or (t shr (32-9)); t:= dd + ((aa or not bb) xor cc) + X[11]+$5C4DD124; dd:= (t shl 13) or (t shr (32-13)); t:= cc + ((dd or not aa) xor bb) + X[ 3]+$5C4DD124; cc:= (t shl 15) or (t shr (32-15)); t:= bb + ((cc or not dd) xor aa) + X[ 7]+$5C4DD124; bb:= (t shl 7) or (t shr (32-7)); t:= aa + ((bb or not cc) xor dd) + X[ 0]+$5C4DD124; aa:= (t shl 12) or (t shr (32-12)); t:= dd + ((aa or not bb) xor cc) + X[13]+$5C4DD124; dd:= (t shl 8) or (t shr (32-8)); t:= cc + ((dd or not aa) xor bb) + X[ 5]+$5C4DD124; cc:= (t shl 9) or (t shr (32-9)); t:= bb + ((cc or not dd) xor aa) + X[10]+$5C4DD124; bb:= (t shl 11) or (t shr (32-11)); t:= aa + ((bb or not cc) xor dd) + X[14]+$5C4DD124; aa:= (t shl 7) or (t shr (32-7)); t:= dd + ((aa or not bb) xor cc) + X[15]+$5C4DD124; dd:= (t shl 7) or (t shr (32-7)); t:= cc + ((dd or not aa) xor bb) + X[ 8]+$5C4DD124; cc:= (t shl 12) or (t shr (32-12)); t:= bb + ((cc or not dd) xor aa) + X[12]+$5C4DD124; bb:= (t shl 7) or (t shr (32-7)); t:= aa + ((bb or not cc) xor dd) + X[ 4]+$5C4DD124; aa:= (t shl 6) or (t shr (32-6)); t:= dd + ((aa or not bb) xor cc) + X[ 9]+$5C4DD124; dd:= (t shl 15) or (t shr (32-15)); t:= cc + ((dd or not aa) xor bb) + X[ 1]+$5C4DD124; cc:= (t shl 13) or (t shr (32-13)); t:= bb + ((cc or not dd) xor aa) + X[ 2]+$5C4DD124; bb:= (t shl 11) or (t shr (32-11)); t:= aa + ((bb and cc) or (not bb and dd)) + X[15]+$6D703EF3; aa:= (t shl 9) or (t shr (32-9)); t:= dd + ((aa and bb) or (not aa and cc)) + X[ 5]+$6D703EF3; dd:= (t shl 7) or (t shr (32-7)); t:= cc + ((dd and aa) or (not dd and bb)) + X[ 1]+$6D703EF3; cc:= (t shl 15) or (t shr (32-15)); t:= bb + ((cc and dd) or (not cc and aa)) + X[ 3]+$6D703EF3; bb:= (t shl 11) or (t shr (32-11)); t:= aa + ((bb and cc) or (not bb and dd)) + X[ 7]+$6D703EF3; aa:= (t shl 8) or (t shr (32-8)); t:= dd + ((aa and bb) or (not aa and cc)) + X[14]+$6D703EF3; dd:= (t shl 6) or (t shr (32-6)); t:= cc + ((dd and aa) or (not dd and bb)) + X[ 6]+$6D703EF3; cc:= (t shl 6) or (t shr (32-6)); t:= bb + ((cc and dd) or (not cc and aa)) + X[ 9]+$6D703EF3; bb:= (t shl 14) or (t shr (32-14)); t:= aa + ((bb and cc) or (not bb and dd)) + X[11]+$6D703EF3; aa:= (t shl 12) or (t shr (32-12)); t:= dd + ((aa and bb) or (not aa and cc)) + X[ 8]+$6D703EF3; dd:= (t shl 13) or (t shr (32-13)); t:= cc + ((dd and aa) or (not dd and bb)) + X[12]+$6D703EF3; cc:= (t shl 5) or (t shr (32-5)); t:= bb + ((cc and dd) or (not cc and aa)) + X[ 2]+$6D703EF3; bb:= (t shl 14) or (t shr (32-14)); t:= aa + ((bb and cc) or (not bb and dd)) + X[10]+$6D703EF3; aa:= (t shl 13) or (t shr (32-13)); t:= dd + ((aa and bb) or (not aa and cc)) + X[ 0]+$6D703EF3; dd:= (t shl 13) or (t shr (32-13)); t:= cc + ((dd and aa) or (not dd and bb)) + X[ 4]+$6D703EF3; cc:= (t shl 7) or (t shr (32-7)); t:= bb + ((cc and dd) or (not cc and aa)) + X[13]+$6D703EF3; bb:= (t shl 5) or (t shr (32-5)); t:= aa + (bb xor cc xor dd) + X[ 8]; aa:= (t shl 15) or (t shr (32-15)); t:= dd + (aa xor bb xor cc) + X[ 6]; dd:= (t shl 5) or (t shr (32-5)); t:= cc + (dd xor aa xor bb) + X[ 4]; cc:= (t shl 8) or (t shr (32-8)); t:= bb + (cc xor dd xor aa) + X[ 1]; bb:= (t shl 11) or (t shr (32-11)); t:= aa + (bb xor cc xor dd) + X[ 3]; aa:= (t shl 14) or (t shr (32-14)); t:= dd + (aa xor bb xor cc) + X[11]; dd:= (t shl 14) or (t shr (32-14)); t:= cc + (dd xor aa xor bb) + X[15]; cc:= (t shl 6) or (t shr (32-6)); t:= bb + (cc xor dd xor aa) + X[ 0]; bb:= (t shl 14) or (t shr (32-14)); t:= aa + (bb xor cc xor dd) + X[ 5]; aa:= (t shl 6) or (t shr (32-6)); t:= dd + (aa xor bb xor cc) + X[12]; dd:= (t shl 9) or (t shr (32-9)); t:= cc + (dd xor aa xor bb) + X[ 2]; cc:= (t shl 12) or (t shr (32-12)); t:= bb + (cc xor dd xor aa) + X[13]; bb:= (t shl 9) or (t shr (32-9)); t:= aa + (bb xor cc xor dd) + X[ 9]; aa:= (t shl 12) or (t shr (32-12)); t:= dd + (aa xor bb xor cc) + X[ 7]; dd:= (t shl 5) or (t shr (32-5)); t:= cc + (dd xor aa xor bb) + X[10]; cc:= (t shl 15) or (t shr (32-15)); t:= bb + (cc xor dd xor aa) + X[14]; bb:= (t shl 8) or (t shr (32-8)); Inc(dd,c + CurrentHash[1]); CurrentHash[1]:= CurrentHash[2] + d + aa; CurrentHash[2]:= CurrentHash[3] + a + bb; CurrentHash[3]:= CurrentHash[0] + b + cc; CurrentHash[0]:= dd; FillChar(X,Sizeof(X),0); Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); end; class function TDCP_ripemd128.GetHashSize: integer; begin Result:= 128; end; class function TDCP_ripemd128.GetId: integer; begin Result:= DCP_ripemd128; end; class function TDCP_ripemd128.GetAlgorithm: string; begin Result:= 'RipeMD-128'; end; class function TDCP_ripemd128.SelfTest: boolean; const Test1Out: array[0..15] of byte= ($86,$be,$7a,$fa,$33,$9d,$0f,$c7,$cf,$c7,$85,$e7,$2f,$57,$8d,$33); Test2Out: array[0..15] of byte= ($fd,$2a,$a6,$07,$f7,$1d,$c8,$f5,$10,$71,$49,$22,$b3,$71,$83,$4e); var TestHash: TDCP_ripemd128; TestOut: array[0..15] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_ripemd128.Create(nil); TestHash.Init; TestHash.UpdateStr('a'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Init; TestHash.UpdateStr('abcdefghijklmnopqrstuvwxyz'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out)) and Result; TestHash.Free; end; procedure TDCP_ripemd128.Init; begin Burn; CurrentHash[0]:= $67452301; CurrentHash[1]:= $efcdab89; CurrentHash[2]:= $98badcfe; CurrentHash[3]:= $10325476; fInitialized:= true; end; procedure TDCP_ripemd128.Burn; begin LenHi:= 0; LenLo:= 0; Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); FillChar(CurrentHash,Sizeof(CurrentHash),0); fInitialized:= false; end; procedure TDCP_ripemd128.Update(const Buffer; Size: longword); var PBuf: ^byte; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); Inc(LenHi,Size shr 29); Inc(LenLo,Size*8); if LenLo< (Size*8) then Inc(LenHi); PBuf:= @Buffer; while Size> 0 do begin if (Sizeof(HashBuffer)-Index)<= DWord(Size) then begin Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index); Dec(Size,Sizeof(HashBuffer)-Index); Inc(PBuf,Sizeof(HashBuffer)-Index); Compress; end else begin Move(PBuf^,HashBuffer[Index],Size); Inc(Index,Size); Size:= 0; end; end; end; procedure TDCP_ripemd128.Final(var Digest); begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); HashBuffer[Index]:= $80; if Index>= 56 then Compress; PDWord(@HashBuffer[56])^:= LenLo; PDWord(@HashBuffer[60])^:= LenHi; Compress; Move(CurrentHash,Digest,Sizeof(CurrentHash)); Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/DCPhaval4.inc0000664000175000017500000005506012014201074022133 0ustar alexxalexxtemp:= (t3 and (t0 xor t1) xor t5 and t6 xor t4 and t2 xor t0); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0]; temp:= (t2 and (t7 xor t0) xor t4 and t5 xor t3 and t1 xor t7); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 1]; temp:= (t1 and (t6 xor t7) xor t3 and t4 xor t2 and t0 xor t6); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 2]; temp:= (t0 and (t5 xor t6) xor t2 and t3 xor t1 and t7 xor t5); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3]; temp:= (t7 and (t4 xor t5) xor t1 and t2 xor t0 and t6 xor t4); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 4]; temp:= (t6 and (t3 xor t4) xor t0 and t1 xor t7 and t5 xor t3); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 5]; temp:= (t5 and (t2 xor t3) xor t7 and t0 xor t6 and t4 xor t2); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 6]; temp:= (t4 and (t1 xor t2) xor t6 and t7 xor t5 and t3 xor t1); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 7]; temp:= (t3 and (t0 xor t1) xor t5 and t6 xor t4 and t2 xor t0); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 8]; temp:= (t2 and (t7 xor t0) xor t4 and t5 xor t3 and t1 xor t7); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9]; temp:= (t1 and (t6 xor t7) xor t3 and t4 xor t2 and t0 xor t6); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[10]; temp:= (t0 and (t5 xor t6) xor t2 and t3 xor t1 and t7 xor t5); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[11]; temp:= (t7 and (t4 xor t5) xor t1 and t2 xor t0 and t6 xor t4); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[12]; temp:= (t6 and (t3 xor t4) xor t0 and t1 xor t7 and t5 xor t3); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[13]; temp:= (t5 and (t2 xor t3) xor t7 and t0 xor t6 and t4 xor t2); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[14]; temp:= (t4 and (t1 xor t2) xor t6 and t7 xor t5 and t3 xor t1); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[15]; temp:= (t3 and (t0 xor t1) xor t5 and t6 xor t4 and t2 xor t0); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[16]; temp:= (t2 and (t7 xor t0) xor t4 and t5 xor t3 and t1 xor t7); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[17]; temp:= (t1 and (t6 xor t7) xor t3 and t4 xor t2 and t0 xor t6); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[18]; temp:= (t0 and (t5 xor t6) xor t2 and t3 xor t1 and t7 xor t5); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[19]; temp:= (t7 and (t4 xor t5) xor t1 and t2 xor t0 and t6 xor t4); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[20]; temp:= (t6 and (t3 xor t4) xor t0 and t1 xor t7 and t5 xor t3); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[21]; temp:= (t5 and (t2 xor t3) xor t7 and t0 xor t6 and t4 xor t2); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[22]; temp:= (t4 and (t1 xor t2) xor t6 and t7 xor t5 and t3 xor t1); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[23]; temp:= (t3 and (t0 xor t1) xor t5 and t6 xor t4 and t2 xor t0); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[24]; temp:= (t2 and (t7 xor t0) xor t4 and t5 xor t3 and t1 xor t7); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[25]; temp:= (t1 and (t6 xor t7) xor t3 and t4 xor t2 and t0 xor t6); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26]; temp:= (t0 and (t5 xor t6) xor t2 and t3 xor t1 and t7 xor t5); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[27]; temp:= (t7 and (t4 xor t5) xor t1 and t2 xor t0 and t6 xor t4); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28]; temp:= (t6 and (t3 xor t4) xor t0 and t1 xor t7 and t5 xor t3); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[29]; temp:= (t5 and (t2 xor t3) xor t7 and t0 xor t6 and t4 xor t2); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[30]; temp:= (t4 and (t1 xor t2) xor t6 and t7 xor t5 and t3 xor t1); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[31]; temp:= (t1 and (t6 and not t0 xor t2 and t5 xor t3 xor t4) xor t2 and (t6 xor t5) xor t0 and t5 xor t4); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 5] + $452821E6; temp:= (t0 and (t5 and not t7 xor t1 and t4 xor t2 xor t3) xor t1 and (t5 xor t4) xor t7 and t4 xor t3); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $38D01377; temp:= (t7 and (t4 and not t6 xor t0 and t3 xor t1 xor t2) xor t0 and (t4 xor t3) xor t6 and t3 xor t2); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26] + $BE5466CF; temp:= (t6 and (t3 and not t5 xor t7 and t2 xor t0 xor t1) xor t7 and (t3 xor t2) xor t5 and t2 xor t1); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[18] + $34E90C6C; temp:= (t5 and (t2 and not t4 xor t6 and t1 xor t7 xor t0) xor t6 and (t2 xor t1) xor t4 and t1 xor t0); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[11] + $C0AC29B7; temp:= (t4 and (t1 and not t3 xor t5 and t0 xor t6 xor t7) xor t5 and (t1 xor t0) xor t3 and t0 xor t7); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[28] + $C97C50DD; temp:= (t3 and (t0 and not t2 xor t4 and t7 xor t5 xor t6) xor t4 and (t0 xor t7) xor t2 and t7 xor t6); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 7] + $3F84D5B5; temp:= (t2 and (t7 and not t1 xor t3 and t6 xor t4 xor t5) xor t3 and (t7 xor t6) xor t1 and t6 xor t5); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[16] + $B5470917; temp:= (t1 and (t6 and not t0 xor t2 and t5 xor t3 xor t4) xor t2 and (t6 xor t5) xor t0 and t5 xor t4); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0] + $9216D5D9; temp:= (t0 and (t5 and not t7 xor t1 and t4 xor t2 xor t3) xor t1 and (t5 xor t4) xor t7 and t4 xor t3); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[23] + $8979FB1B; temp:= (t7 and (t4 and not t6 xor t0 and t3 xor t1 xor t2) xor t0 and (t4 xor t3) xor t6 and t3 xor t2); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[20] + $D1310BA6; temp:= (t6 and (t3 and not t5 xor t7 and t2 xor t0 xor t1) xor t7 and (t3 xor t2) xor t5 and t2 xor t1); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[22] + $98DFB5AC; temp:= (t5 and (t2 and not t4 xor t6 and t1 xor t7 xor t0) xor t6 and (t2 xor t1) xor t4 and t1 xor t0); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $2FFD72DB; temp:= (t4 and (t1 and not t3 xor t5 and t0 xor t6 xor t7) xor t5 and (t1 xor t0) xor t3 and t0 xor t7); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[10] + $D01ADFB7; temp:= (t3 and (t0 and not t2 xor t4 and t7 xor t5 xor t6) xor t4 and (t0 xor t7) xor t2 and t7 xor t6); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 4] + $B8E1AFED; temp:= (t2 and (t7 and not t1 xor t3 and t6 xor t4 xor t5) xor t3 and (t7 xor t6) xor t1 and t6 xor t5); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 8] + $6A267E96; temp:= (t1 and (t6 and not t0 xor t2 and t5 xor t3 xor t4) xor t2 and (t6 xor t5) xor t0 and t5 xor t4); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[30] + $BA7C9045; temp:= (t0 and (t5 and not t7 xor t1 and t4 xor t2 xor t3) xor t1 and (t5 xor t4) xor t7 and t4 xor t3); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 3] + $F12C7F99; temp:= (t7 and (t4 and not t6 xor t0 and t3 xor t1 xor t2) xor t0 and (t4 xor t3) xor t6 and t3 xor t2); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $24A19947; temp:= (t6 and (t3 and not t5 xor t7 and t2 xor t0 xor t1) xor t7 and (t3 xor t2) xor t5 and t2 xor t1); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 9] + $B3916CF7; temp:= (t5 and (t2 and not t4 xor t6 and t1 xor t7 xor t0) xor t6 and (t2 xor t1) xor t4 and t1 xor t0); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $0801F2E2; temp:= (t4 and (t1 and not t3 xor t5 and t0 xor t6 xor t7) xor t5 and (t1 xor t0) xor t3 and t0 xor t7); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[24] + $858EFC16; temp:= (t3 and (t0 and not t2 xor t4 and t7 xor t5 xor t6) xor t4 and (t0 xor t7) xor t2 and t7 xor t6); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[29] + $636920D8; temp:= (t2 and (t7 and not t1 xor t3 and t6 xor t4 xor t5) xor t3 and (t7 xor t6) xor t1 and t6 xor t5); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 6] + $71574E69; temp:= (t1 and (t6 and not t0 xor t2 and t5 xor t3 xor t4) xor t2 and (t6 xor t5) xor t0 and t5 xor t4); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $A458FEA3; temp:= (t0 and (t5 and not t7 xor t1 and t4 xor t2 xor t3) xor t1 and (t5 xor t4) xor t7 and t4 xor t3); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[12] + $F4933D7E; temp:= (t7 and (t4 and not t6 xor t0 and t3 xor t1 xor t2) xor t0 and (t4 xor t3) xor t6 and t3 xor t2); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[15] + $0D95748F; temp:= (t6 and (t3 and not t5 xor t7 and t2 xor t0 xor t1) xor t7 and (t3 xor t2) xor t5 and t2 xor t1); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[13] + $728EB658; temp:= (t5 and (t2 and not t4 xor t6 and t1 xor t7 xor t0) xor t6 and (t2 xor t1) xor t4 and t1 xor t0); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 2] + $718BCD58; temp:= (t4 and (t1 and not t3 xor t5 and t0 xor t6 xor t7) xor t5 and (t1 xor t0) xor t3 and t0 xor t7); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[25] + $82154AEE; temp:= (t3 and (t0 and not t2 xor t4 and t7 xor t5 xor t6) xor t4 and (t0 xor t7) xor t2 and t7 xor t6); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[31] + $7B54A41D; temp:= (t2 and (t7 and not t1 xor t3 and t6 xor t4 xor t5) xor t3 and (t7 xor t6) xor t1 and t6 xor t5); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $C25A59B5; temp:= (t6 and (t2 and t0 xor t1 xor t5) xor t2 and t3 xor t0 and t4 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $9C30D539; temp:= (t5 and (t1 and t7 xor t0 xor t4) xor t1 and t2 xor t7 and t3 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9] + $2AF26013; temp:= (t4 and (t0 and t6 xor t7 xor t3) xor t0 and t1 xor t6 and t2 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 4] + $C5D1B023; temp:= (t3 and (t7 and t5 xor t6 xor t2) xor t7 and t0 xor t5 and t1 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[20] + $286085F0; temp:= (t2 and (t6 and t4 xor t5 xor t1) xor t6 and t7 xor t4 and t0 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28] + $CA417918; temp:= (t1 and (t5 and t3 xor t4 xor t0) xor t5 and t6 xor t3 and t7 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[17] + $B8DB38EF; temp:= (t0 and (t4 and t2 xor t3 xor t7) xor t4 and t5 xor t2 and t6 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 8] + $8E79DCB0; temp:= (t7 and (t3 and t1 xor t2 xor t6) xor t3 and t4 xor t1 and t5 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[22] + $603A180E; temp:= (t6 and (t2 and t0 xor t1 xor t5) xor t2 and t3 xor t0 and t4 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[29] + $6C9E0E8B; temp:= (t5 and (t1 and t7 xor t0 xor t4) xor t1 and t2 xor t7 and t3 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $B01E8A3E; temp:= (t4 and (t0 and t6 xor t7 xor t3) xor t0 and t1 xor t6 and t2 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[25] + $D71577C1; temp:= (t3 and (t7 and t5 xor t6 xor t2) xor t7 and t0 xor t5 and t1 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[12] + $BD314B27; temp:= (t2 and (t6 and t4 xor t5 xor t1) xor t6 and t7 xor t4 and t0 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[24] + $78AF2FDA; temp:= (t1 and (t5 and t3 xor t4 xor t0) xor t5 and t6 xor t3 and t7 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[30] + $55605C60; temp:= (t0 and (t4 and t2 xor t3 xor t7) xor t4 and t5 xor t2 and t6 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[16] + $E65525F3; temp:= (t7 and (t3 and t1 xor t2 xor t6) xor t3 and t4 xor t1 and t5 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[26] + $AA55AB94; temp:= (t6 and (t2 and t0 xor t1 xor t5) xor t2 and t3 xor t0 and t4 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[31] + $57489862; temp:= (t5 and (t1 and t7 xor t0 xor t4) xor t1 and t2 xor t7 and t3 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[15] + $63E81440; temp:= (t4 and (t0 and t6 xor t7 xor t3) xor t0 and t1 xor t6 and t2 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 7] + $55CA396A; temp:= (t3 and (t7 and t5 xor t6 xor t2) xor t7 and t0 xor t5 and t1 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3] + $2AAB10B6; temp:= (t2 and (t6 and t4 xor t5 xor t1) xor t6 and t7 xor t4 and t0 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $B4CC5C34; temp:= (t1 and (t5 and t3 xor t4 xor t0) xor t5 and t6 xor t3 and t7 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 0] + $1141E8CE; temp:= (t0 and (t4 and t2 xor t3 xor t7) xor t4 and t5 xor t2 and t6 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[18] + $A15486AF; temp:= (t7 and (t3 and t1 xor t2 xor t6) xor t3 and t4 xor t1 and t5 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $7C72E993; temp:= (t6 and (t2 and t0 xor t1 xor t5) xor t2 and t3 xor t0 and t4 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[13] + $B3EE1411; temp:= (t5 and (t1 and t7 xor t0 xor t4) xor t1 and t2 xor t7 and t3 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 6] + $636FBC2A; temp:= (t4 and (t0 and t6 xor t7 xor t3) xor t0 and t1 xor t6 and t2 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $2BA9C55D; temp:= (t3 and (t7 and t5 xor t6 xor t2) xor t7 and t0 xor t5 and t1 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[10] + $741831F6; temp:= (t2 and (t6 and t4 xor t5 xor t1) xor t6 and t7 xor t4 and t0 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[23] + $CE5C3E16; temp:= (t1 and (t5 and t3 xor t4 xor t0) xor t5 and t6 xor t3 and t7 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[11] + $9B87931E; temp:= (t0 and (t4 and t2 xor t3 xor t7) xor t4 and t5 xor t2 and t6 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 5] + $AFD6BA33; temp:= (t7 and (t3 and t1 xor t2 xor t6) xor t3 and t4 xor t1 and t5 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 2] + $6C24CF5C; temp:= (t0 and (t4 and not t2 xor t5 and not t6 xor t1 xor t6 xor t3) xor t5 and (t1 and t2 xor t4 xor t6) xor t2 and t6 xor t3); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[24] + $7A325381; temp:= (t7 and (t3 and not t1 xor t4 and not t5 xor t0 xor t5 xor t2) xor t4 and (t0 and t1 xor t3 xor t5) xor t1 and t5 xor t2); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 4] + $28958677; temp:= (t6 and (t2 and not t0 xor t3 and not t4 xor t7 xor t4 xor t1) xor t3 and (t7 and t0 xor t2 xor t4) xor t0 and t4 xor t1); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 0] + $3B8F4898; temp:= (t5 and (t1 and not t7 xor t2 and not t3 xor t6 xor t3 xor t0) xor t2 and (t6 and t7 xor t1 xor t3) xor t7 and t3 xor t0); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[14] + $6B4BB9AF; temp:= (t4 and (t0 and not t6 xor t1 and not t2 xor t5 xor t2 xor t7) xor t1 and (t5 and t6 xor t0 xor t2) xor t6 and t2 xor t7); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 2] + $C4BFE81B; temp:= (t3 and (t7 and not t5 xor t0 and not t1 xor t4 xor t1 xor t6) xor t0 and (t4 and t5 xor t7 xor t1) xor t5 and t1 xor t6); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 7] + $66282193; temp:= (t2 and (t6 and not t4 xor t7 and not t0 xor t3 xor t0 xor t5) xor t7 and (t3 and t4 xor t6 xor t0) xor t4 and t0 xor t5); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[28] + $61D809CC; temp:= (t1 and (t5 and not t3 xor t6 and not t7 xor t2 xor t7 xor t4) xor t6 and (t2 and t3 xor t5 xor t7) xor t3 and t7 xor t4); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[23] + $FB21A991; temp:= (t0 and (t4 and not t2 xor t5 and not t6 xor t1 xor t6 xor t3) xor t5 and (t1 and t2 xor t4 xor t6) xor t2 and t6 xor t3); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[26] + $487CAC60; temp:= (t7 and (t3 and not t1 xor t4 and not t5 xor t0 xor t5 xor t2) xor t4 and (t0 and t1 xor t3 xor t5) xor t1 and t5 xor t2); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 6] + $5DEC8032; temp:= (t6 and (t2 and not t0 xor t3 and not t4 xor t7 xor t4 xor t1) xor t3 and (t7 and t0 xor t2 xor t4) xor t0 and t4 xor t1); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[30] + $EF845D5D; temp:= (t5 and (t1 and not t7 xor t2 and not t3 xor t6 xor t3 xor t0) xor t2 and (t6 and t7 xor t1 xor t3) xor t7 and t3 xor t0); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[20] + $E98575B1; temp:= (t4 and (t0 and not t6 xor t1 and not t2 xor t5 xor t2 xor t7) xor t1 and (t5 and t6 xor t0 xor t2) xor t6 and t2 xor t7); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[18] + $DC262302; temp:= (t3 and (t7 and not t5 xor t0 and not t1 xor t4 xor t1 xor t6) xor t0 and (t4 and t5 xor t7 xor t1) xor t5 and t1 xor t6); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[25] + $EB651B88; temp:= (t2 and (t6 and not t4 xor t7 and not t0 xor t3 xor t0 xor t5) xor t7 and (t3 and t4 xor t6 xor t0) xor t4 and t0 xor t5); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[19] + $23893E81; temp:= (t1 and (t5 and not t3 xor t6 and not t7 xor t2 xor t7 xor t4) xor t6 and (t2 and t3 xor t5 xor t7) xor t3 and t7 xor t4); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 3] + $D396ACC5; temp:= (t0 and (t4 and not t2 xor t5 and not t6 xor t1 xor t6 xor t3) xor t5 and (t1 and t2 xor t4 xor t6) xor t2 and t6 xor t3); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[22] + $0F6D6FF3; temp:= (t7 and (t3 and not t1 xor t4 and not t5 xor t0 xor t5 xor t2) xor t4 and (t0 and t1 xor t3 xor t5) xor t1 and t5 xor t2); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[11] + $83F44239; temp:= (t6 and (t2 and not t0 xor t3 and not t4 xor t7 xor t4 xor t1) xor t3 and (t7 and t0 xor t2 xor t4) xor t0 and t4 xor t1); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[31] + $2E0B4482; temp:= (t5 and (t1 and not t7 xor t2 and not t3 xor t6 xor t3 xor t0) xor t2 and (t6 and t7 xor t1 xor t3) xor t7 and t3 xor t0); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[21] + $A4842004; temp:= (t4 and (t0 and not t6 xor t1 and not t2 xor t5 xor t2 xor t7) xor t1 and (t5 and t6 xor t0 xor t2) xor t6 and t2 xor t7); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 8] + $69C8F04A; temp:= (t3 and (t7 and not t5 xor t0 and not t1 xor t4 xor t1 xor t6) xor t0 and (t4 and t5 xor t7 xor t1) xor t5 and t1 xor t6); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[27] + $9E1F9B5E; temp:= (t2 and (t6 and not t4 xor t7 and not t0 xor t3 xor t0 xor t5) xor t7 and (t3 and t4 xor t6 xor t0) xor t4 and t0 xor t5); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[12] + $21C66842; temp:= (t1 and (t5 and not t3 xor t6 and not t7 xor t2 xor t7 xor t4) xor t6 and (t2 and t3 xor t5 xor t7) xor t3 and t7 xor t4); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 9] + $F6E96C9A; temp:= (t0 and (t4 and not t2 xor t5 and not t6 xor t1 xor t6 xor t3) xor t5 and (t1 and t2 xor t4 xor t6) xor t2 and t6 xor t3); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 1] + $670C9C61; temp:= (t7 and (t3 and not t1 xor t4 and not t5 xor t0 xor t5 xor t2) xor t4 and (t0 and t1 xor t3 xor t5) xor t1 and t5 xor t2); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[29] + $ABD388F0; temp:= (t6 and (t2 and not t0 xor t3 and not t4 xor t7 xor t4 xor t1) xor t3 and (t7 and t0 xor t2 xor t4) xor t0 and t4 xor t1); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 5] + $6A51A0D2; temp:= (t5 and (t1 and not t7 xor t2 and not t3 xor t6 xor t3 xor t0) xor t2 and (t6 and t7 xor t1 xor t3) xor t7 and t3 xor t0); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[15] + $D8542F68; temp:= (t4 and (t0 and not t6 xor t1 and not t2 xor t5 xor t2 xor t7) xor t1 and (t5 and t6 xor t0 xor t2) xor t6 and t2 xor t7); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $960FA728; temp:= (t3 and (t7 and not t5 xor t0 and not t1 xor t4 xor t1 xor t6) xor t0 and (t4 and t5 xor t7 xor t1) xor t5 and t1 xor t6); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[10] + $AB5133A3; temp:= (t2 and (t6 and not t4 xor t7 and not t0 xor t3 xor t0 xor t5) xor t7 and (t3 and t4 xor t6 xor t0) xor t4 and t0 xor t5); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[16] + $6EEF0B6C; temp:= (t1 and (t5 and not t3 xor t6 and not t7 xor t2 xor t7 xor t4) xor t6 and (t2 and t3 xor t5 xor t7) xor t3 and t7 xor t4); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[13] + $137A3BE4; doublecmd-0.8.2/components/dcpcrypt/Hashes/DCPhaval5.inc0000664000175000017500000007033012014201074022131 0ustar alexxalexxtemp:= (t2 and (t6 xor t1) xor t5 and t4 xor t0 and t3 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0]; temp:= (t1 and (t5 xor t0) xor t4 and t3 xor t7 and t2 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 1]; temp:= (t0 and (t4 xor t7) xor t3 and t2 xor t6 and t1 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 2]; temp:= (t7 and (t3 xor t6) xor t2 and t1 xor t5 and t0 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3]; temp:= (t6 and (t2 xor t5) xor t1 and t0 xor t4 and t7 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 4]; temp:= (t5 and (t1 xor t4) xor t0 and t7 xor t3 and t6 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 5]; temp:= (t4 and (t0 xor t3) xor t7 and t6 xor t2 and t5 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 6]; temp:= (t3 and (t7 xor t2) xor t6 and t5 xor t1 and t4 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 7]; temp:= (t2 and (t6 xor t1) xor t5 and t4 xor t0 and t3 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 8]; temp:= (t1 and (t5 xor t0) xor t4 and t3 xor t7 and t2 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9]; temp:= (t0 and (t4 xor t7) xor t3 and t2 xor t6 and t1 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[10]; temp:= (t7 and (t3 xor t6) xor t2 and t1 xor t5 and t0 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[11]; temp:= (t6 and (t2 xor t5) xor t1 and t0 xor t4 and t7 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[12]; temp:= (t5 and (t1 xor t4) xor t0 and t7 xor t3 and t6 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[13]; temp:= (t4 and (t0 xor t3) xor t7 and t6 xor t2 and t5 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[14]; temp:= (t3 and (t7 xor t2) xor t6 and t5 xor t1 and t4 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[15]; temp:= (t2 and (t6 xor t1) xor t5 and t4 xor t0 and t3 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[16]; temp:= (t1 and (t5 xor t0) xor t4 and t3 xor t7 and t2 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[17]; temp:= (t0 and (t4 xor t7) xor t3 and t2 xor t6 and t1 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[18]; temp:= (t7 and (t3 xor t6) xor t2 and t1 xor t5 and t0 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[19]; temp:= (t6 and (t2 xor t5) xor t1 and t0 xor t4 and t7 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[20]; temp:= (t5 and (t1 xor t4) xor t0 and t7 xor t3 and t6 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[21]; temp:= (t4 and (t0 xor t3) xor t7 and t6 xor t2 and t5 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[22]; temp:= (t3 and (t7 xor t2) xor t6 and t5 xor t1 and t4 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[23]; temp:= (t2 and (t6 xor t1) xor t5 and t4 xor t0 and t3 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[24]; temp:= (t1 and (t5 xor t0) xor t4 and t3 xor t7 and t2 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[25]; temp:= (t0 and (t4 xor t7) xor t3 and t2 xor t6 and t1 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26]; temp:= (t7 and (t3 xor t6) xor t2 and t1 xor t5 and t0 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[27]; temp:= (t6 and (t2 xor t5) xor t1 and t0 xor t4 and t7 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28]; temp:= (t5 and (t1 xor t4) xor t0 and t7 xor t3 and t6 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[29]; temp:= (t4 and (t0 xor t3) xor t7 and t6 xor t2 and t5 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[30]; temp:= (t3 and (t7 xor t2) xor t6 and t5 xor t1 and t4 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[31]; temp:= (t3 and (t4 and not t0 xor t1 and t2 xor t6 xor t5) xor t1 and (t4 xor t2) xor t0 and t2 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 5] + $452821E6; temp:= (t2 and (t3 and not t7 xor t0 and t1 xor t5 xor t4) xor t0 and (t3 xor t1) xor t7 and t1 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $38D01377; temp:= (t1 and (t2 and not t6 xor t7 and t0 xor t4 xor t3) xor t7 and (t2 xor t0) xor t6 and t0 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26] + $BE5466CF; temp:= (t0 and (t1 and not t5 xor t6 and t7 xor t3 xor t2) xor t6 and (t1 xor t7) xor t5 and t7 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[18] + $34E90C6C; temp:= (t7 and (t0 and not t4 xor t5 and t6 xor t2 xor t1) xor t5 and (t0 xor t6) xor t4 and t6 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[11] + $C0AC29B7; temp:= (t6 and (t7 and not t3 xor t4 and t5 xor t1 xor t0) xor t4 and (t7 xor t5) xor t3 and t5 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[28] + $C97C50DD; temp:= (t5 and (t6 and not t2 xor t3 and t4 xor t0 xor t7) xor t3 and (t6 xor t4) xor t2 and t4 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 7] + $3F84D5B5; temp:= (t4 and (t5 and not t1 xor t2 and t3 xor t7 xor t6) xor t2 and (t5 xor t3) xor t1 and t3 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[16] + $B5470917; temp:= (t3 and (t4 and not t0 xor t1 and t2 xor t6 xor t5) xor t1 and (t4 xor t2) xor t0 and t2 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0] + $9216D5D9; temp:= (t2 and (t3 and not t7 xor t0 and t1 xor t5 xor t4) xor t0 and (t3 xor t1) xor t7 and t1 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[23] + $8979FB1B; temp:= (t1 and (t2 and not t6 xor t7 and t0 xor t4 xor t3) xor t7 and (t2 xor t0) xor t6 and t0 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[20] + $D1310BA6; temp:= (t0 and (t1 and not t5 xor t6 and t7 xor t3 xor t2) xor t6 and (t1 xor t7) xor t5 and t7 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[22] + $98DFB5AC; temp:= (t7 and (t0 and not t4 xor t5 and t6 xor t2 xor t1) xor t5 and (t0 xor t6) xor t4 and t6 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $2FFD72DB; temp:= (t6 and (t7 and not t3 xor t4 and t5 xor t1 xor t0) xor t4 and (t7 xor t5) xor t3 and t5 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[10] + $D01ADFB7; temp:= (t5 and (t6 and not t2 xor t3 and t4 xor t0 xor t7) xor t3 and (t6 xor t4) xor t2 and t4 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 4] + $B8E1AFED; temp:= (t4 and (t5 and not t1 xor t2 and t3 xor t7 xor t6) xor t2 and (t5 xor t3) xor t1 and t3 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 8] + $6A267E96; temp:= (t3 and (t4 and not t0 xor t1 and t2 xor t6 xor t5) xor t1 and (t4 xor t2) xor t0 and t2 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[30] + $BA7C9045; temp:= (t2 and (t3 and not t7 xor t0 and t1 xor t5 xor t4) xor t0 and (t3 xor t1) xor t7 and t1 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 3] + $F12C7F99; temp:= (t1 and (t2 and not t6 xor t7 and t0 xor t4 xor t3) xor t7 and (t2 xor t0) xor t6 and t0 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $24A19947; temp:= (t0 and (t1 and not t5 xor t6 and t7 xor t3 xor t2) xor t6 and (t1 xor t7) xor t5 and t7 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 9] + $B3916CF7; temp:= (t7 and (t0 and not t4 xor t5 and t6 xor t2 xor t1) xor t5 and (t0 xor t6) xor t4 and t6 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $0801F2E2; temp:= (t6 and (t7 and not t3 xor t4 and t5 xor t1 xor t0) xor t4 and (t7 xor t5) xor t3 and t5 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[24] + $858EFC16; temp:= (t5 and (t6 and not t2 xor t3 and t4 xor t0 xor t7) xor t3 and (t6 xor t4) xor t2 and t4 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[29] + $636920D8; temp:= (t4 and (t5 and not t1 xor t2 and t3 xor t7 xor t6) xor t2 and (t5 xor t3) xor t1 and t3 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 6] + $71574E69; temp:= (t3 and (t4 and not t0 xor t1 and t2 xor t6 xor t5) xor t1 and (t4 xor t2) xor t0 and t2 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $A458FEA3; temp:= (t2 and (t3 and not t7 xor t0 and t1 xor t5 xor t4) xor t0 and (t3 xor t1) xor t7 and t1 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[12] + $F4933D7E; temp:= (t1 and (t2 and not t6 xor t7 and t0 xor t4 xor t3) xor t7 and (t2 xor t0) xor t6 and t0 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[15] + $0D95748F; temp:= (t0 and (t1 and not t5 xor t6 and t7 xor t3 xor t2) xor t6 and (t1 xor t7) xor t5 and t7 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[13] + $728EB658; temp:= (t7 and (t0 and not t4 xor t5 and t6 xor t2 xor t1) xor t5 and (t0 xor t6) xor t4 and t6 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 2] + $718BCD58; temp:= (t6 and (t7 and not t3 xor t4 and t5 xor t1 xor t0) xor t4 and (t7 xor t5) xor t3 and t5 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[25] + $82154AEE; temp:= (t5 and (t6 and not t2 xor t3 and t4 xor t0 xor t7) xor t3 and (t6 xor t4) xor t2 and t4 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[31] + $7B54A41D; temp:= (t4 and (t5 and not t1 xor t2 and t3 xor t7 xor t6) xor t2 and (t5 xor t3) xor t1 and t3 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $C25A59B5; temp:= (t4 and (t1 and t3 xor t2 xor t5) xor t1 and t0 xor t3 and t6 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $9C30D539; temp:= (t3 and (t0 and t2 xor t1 xor t4) xor t0 and t7 xor t2 and t5 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9] + $2AF26013; temp:= (t2 and (t7 and t1 xor t0 xor t3) xor t7 and t6 xor t1 and t4 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 4] + $C5D1B023; temp:= (t1 and (t6 and t0 xor t7 xor t2) xor t6 and t5 xor t0 and t3 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[20] + $286085F0; temp:= (t0 and (t5 and t7 xor t6 xor t1) xor t5 and t4 xor t7 and t2 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28] + $CA417918; temp:= (t7 and (t4 and t6 xor t5 xor t0) xor t4 and t3 xor t6 and t1 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[17] + $B8DB38EF; temp:= (t6 and (t3 and t5 xor t4 xor t7) xor t3 and t2 xor t5 and t0 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 8] + $8E79DCB0; temp:= (t5 and (t2 and t4 xor t3 xor t6) xor t2 and t1 xor t4 and t7 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[22] + $603A180E; temp:= (t4 and (t1 and t3 xor t2 xor t5) xor t1 and t0 xor t3 and t6 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[29] + $6C9E0E8B; temp:= (t3 and (t0 and t2 xor t1 xor t4) xor t0 and t7 xor t2 and t5 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $B01E8A3E; temp:= (t2 and (t7 and t1 xor t0 xor t3) xor t7 and t6 xor t1 and t4 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[25] + $D71577C1; temp:= (t1 and (t6 and t0 xor t7 xor t2) xor t6 and t5 xor t0 and t3 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[12] + $BD314B27; temp:= (t0 and (t5 and t7 xor t6 xor t1) xor t5 and t4 xor t7 and t2 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[24] + $78AF2FDA; temp:= (t7 and (t4 and t6 xor t5 xor t0) xor t4 and t3 xor t6 and t1 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[30] + $55605C60; temp:= (t6 and (t3 and t5 xor t4 xor t7) xor t3 and t2 xor t5 and t0 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[16] + $E65525F3; temp:= (t5 and (t2 and t4 xor t3 xor t6) xor t2 and t1 xor t4 and t7 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[26] + $AA55AB94; temp:= (t4 and (t1 and t3 xor t2 xor t5) xor t1 and t0 xor t3 and t6 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[31] + $57489862; temp:= (t3 and (t0 and t2 xor t1 xor t4) xor t0 and t7 xor t2 and t5 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[15] + $63E81440; temp:= (t2 and (t7 and t1 xor t0 xor t3) xor t7 and t6 xor t1 and t4 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 7] + $55CA396A; temp:= (t1 and (t6 and t0 xor t7 xor t2) xor t6 and t5 xor t0 and t3 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3] + $2AAB10B6; temp:= (t0 and (t5 and t7 xor t6 xor t1) xor t5 and t4 xor t7 and t2 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $B4CC5C34; temp:= (t7 and (t4 and t6 xor t5 xor t0) xor t4 and t3 xor t6 and t1 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 0] + $1141E8CE; temp:= (t6 and (t3 and t5 xor t4 xor t7) xor t3 and t2 xor t5 and t0 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[18] + $A15486AF; temp:= (t5 and (t2 and t4 xor t3 xor t6) xor t2 and t1 xor t4 and t7 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $7C72E993; temp:= (t4 and (t1 and t3 xor t2 xor t5) xor t1 and t0 xor t3 and t6 xor t5); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[13] + $B3EE1411; temp:= (t3 and (t0 and t2 xor t1 xor t4) xor t0 and t7 xor t2 and t5 xor t4); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 6] + $636FBC2A; temp:= (t2 and (t7 and t1 xor t0 xor t3) xor t7 and t6 xor t1 and t4 xor t3); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $2BA9C55D; temp:= (t1 and (t6 and t0 xor t7 xor t2) xor t6 and t5 xor t0 and t3 xor t2); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[10] + $741831F6; temp:= (t0 and (t5 and t7 xor t6 xor t1) xor t5 and t4 xor t7 and t2 xor t1); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[23] + $CE5C3E16; temp:= (t7 and (t4 and t6 xor t5 xor t0) xor t4 and t3 xor t6 and t1 xor t0); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[11] + $9B87931E; temp:= (t6 and (t3 and t5 xor t4 xor t7) xor t3 and t2 xor t5 and t0 xor t7); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 5] + $AFD6BA33; temp:= (t5 and (t2 and t4 xor t3 xor t6) xor t2 and t1 xor t4 and t7 xor t6); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 2] + $6C24CF5C; temp:= (t3 and (t5 and not t0 xor t2 and not t1 xor t4 xor t1 xor t6) xor t2 and (t4 and t0 xor t5 xor t1) xor t0 and t1 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[24] + $7A325381; temp:= (t2 and (t4 and not t7 xor t1 and not t0 xor t3 xor t0 xor t5) xor t1 and (t3 and t7 xor t4 xor t0) xor t7 and t0 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 4] + $28958677; temp:= (t1 and (t3 and not t6 xor t0 and not t7 xor t2 xor t7 xor t4) xor t0 and (t2 and t6 xor t3 xor t7) xor t6 and t7 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 0] + $3B8F4898; temp:= (t0 and (t2 and not t5 xor t7 and not t6 xor t1 xor t6 xor t3) xor t7 and (t1 and t5 xor t2 xor t6) xor t5 and t6 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[14] + $6B4BB9AF; temp:= (t7 and (t1 and not t4 xor t6 and not t5 xor t0 xor t5 xor t2) xor t6 and (t0 and t4 xor t1 xor t5) xor t4 and t5 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 2] + $C4BFE81B; temp:= (t6 and (t0 and not t3 xor t5 and not t4 xor t7 xor t4 xor t1) xor t5 and (t7 and t3 xor t0 xor t4) xor t3 and t4 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 7] + $66282193; temp:= (t5 and (t7 and not t2 xor t4 and not t3 xor t6 xor t3 xor t0) xor t4 and (t6 and t2 xor t7 xor t3) xor t2 and t3 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[28] + $61D809CC; temp:= (t4 and (t6 and not t1 xor t3 and not t2 xor t5 xor t2 xor t7) xor t3 and (t5 and t1 xor t6 xor t2) xor t1 and t2 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[23] + $FB21A991; temp:= (t3 and (t5 and not t0 xor t2 and not t1 xor t4 xor t1 xor t6) xor t2 and (t4 and t0 xor t5 xor t1) xor t0 and t1 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[26] + $487CAC60; temp:= (t2 and (t4 and not t7 xor t1 and not t0 xor t3 xor t0 xor t5) xor t1 and (t3 and t7 xor t4 xor t0) xor t7 and t0 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 6] + $5DEC8032; temp:= (t1 and (t3 and not t6 xor t0 and not t7 xor t2 xor t7 xor t4) xor t0 and (t2 and t6 xor t3 xor t7) xor t6 and t7 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[30] + $EF845D5D; temp:= (t0 and (t2 and not t5 xor t7 and not t6 xor t1 xor t6 xor t3) xor t7 and (t1 and t5 xor t2 xor t6) xor t5 and t6 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[20] + $E98575B1; temp:= (t7 and (t1 and not t4 xor t6 and not t5 xor t0 xor t5 xor t2) xor t6 and (t0 and t4 xor t1 xor t5) xor t4 and t5 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[18] + $DC262302; temp:= (t6 and (t0 and not t3 xor t5 and not t4 xor t7 xor t4 xor t1) xor t5 and (t7 and t3 xor t0 xor t4) xor t3 and t4 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[25] + $EB651B88; temp:= (t5 and (t7 and not t2 xor t4 and not t3 xor t6 xor t3 xor t0) xor t4 and (t6 and t2 xor t7 xor t3) xor t2 and t3 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[19] + $23893E81; temp:= (t4 and (t6 and not t1 xor t3 and not t2 xor t5 xor t2 xor t7) xor t3 and (t5 and t1 xor t6 xor t2) xor t1 and t2 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 3] + $D396ACC5; temp:= (t3 and (t5 and not t0 xor t2 and not t1 xor t4 xor t1 xor t6) xor t2 and (t4 and t0 xor t5 xor t1) xor t0 and t1 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[22] + $0F6D6FF3; temp:= (t2 and (t4 and not t7 xor t1 and not t0 xor t3 xor t0 xor t5) xor t1 and (t3 and t7 xor t4 xor t0) xor t7 and t0 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[11] + $83F44239; temp:= (t1 and (t3 and not t6 xor t0 and not t7 xor t2 xor t7 xor t4) xor t0 and (t2 and t6 xor t3 xor t7) xor t6 and t7 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[31] + $2E0B4482; temp:= (t0 and (t2 and not t5 xor t7 and not t6 xor t1 xor t6 xor t3) xor t7 and (t1 and t5 xor t2 xor t6) xor t5 and t6 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[21] + $A4842004; temp:= (t7 and (t1 and not t4 xor t6 and not t5 xor t0 xor t5 xor t2) xor t6 and (t0 and t4 xor t1 xor t5) xor t4 and t5 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 8] + $69C8F04A; temp:= (t6 and (t0 and not t3 xor t5 and not t4 xor t7 xor t4 xor t1) xor t5 and (t7 and t3 xor t0 xor t4) xor t3 and t4 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[27] + $9E1F9B5E; temp:= (t5 and (t7 and not t2 xor t4 and not t3 xor t6 xor t3 xor t0) xor t4 and (t6 and t2 xor t7 xor t3) xor t2 and t3 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[12] + $21C66842; temp:= (t4 and (t6 and not t1 xor t3 and not t2 xor t5 xor t2 xor t7) xor t3 and (t5 and t1 xor t6 xor t2) xor t1 and t2 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 9] + $F6E96C9A; temp:= (t3 and (t5 and not t0 xor t2 and not t1 xor t4 xor t1 xor t6) xor t2 and (t4 and t0 xor t5 xor t1) xor t0 and t1 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 1] + $670C9C61; temp:= (t2 and (t4 and not t7 xor t1 and not t0 xor t3 xor t0 xor t5) xor t1 and (t3 and t7 xor t4 xor t0) xor t7 and t0 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[29] + $ABD388F0; temp:= (t1 and (t3 and not t6 xor t0 and not t7 xor t2 xor t7 xor t4) xor t0 and (t2 and t6 xor t3 xor t7) xor t6 and t7 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 5] + $6A51A0D2; temp:= (t0 and (t2 and not t5 xor t7 and not t6 xor t1 xor t6 xor t3) xor t7 and (t1 and t5 xor t2 xor t6) xor t5 and t6 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[15] + $D8542F68; temp:= (t7 and (t1 and not t4 xor t6 and not t5 xor t0 xor t5 xor t2) xor t6 and (t0 and t4 xor t1 xor t5) xor t4 and t5 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $960FA728; temp:= (t6 and (t0 and not t3 xor t5 and not t4 xor t7 xor t4 xor t1) xor t5 and (t7 and t3 xor t0 xor t4) xor t3 and t4 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[10] + $AB5133A3; temp:= (t5 and (t7 and not t2 xor t4 and not t3 xor t6 xor t3 xor t0) xor t4 and (t6 and t2 xor t7 xor t3) xor t2 and t3 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[16] + $6EEF0B6C; temp:= (t4 and (t6 and not t1 xor t3 and not t2 xor t5 xor t2 xor t7) xor t3 and (t5 and t1 xor t6 xor t2) xor t1 and t2 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[13] + $137A3BE4; temp:= (t1 and (t3 and t4 and t6 xor not t5) xor t3 and t0 xor t4 and t5 xor t6 and t2); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[27] + $BA3BF050; temp:= (t0 and (t2 and t3 and t5 xor not t4) xor t2 and t7 xor t3 and t4 xor t5 and t1); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 3] + $7EFB2A98; temp:= (t7 and (t1 and t2 and t4 xor not t3) xor t1 and t6 xor t2 and t3 xor t4 and t0); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $A1F1651D; temp:= (t6 and (t0 and t1 and t3 xor not t2) xor t0 and t5 xor t1 and t2 xor t3 and t7); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[26] + $39AF0176; temp:= (t5 and (t7 and t0 and t2 xor not t1) xor t7 and t4 xor t0 and t1 xor t2 and t6); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $66CA593E; temp:= (t4 and (t6 and t7 and t1 xor not t0) xor t6 and t3 xor t7 and t0 xor t1 and t5); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[11] + $82430E88; temp:= (t3 and (t5 and t6 and t0 xor not t7) xor t5 and t2 xor t6 and t7 xor t0 and t4); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[20] + $8CEE8619; temp:= (t2 and (t4 and t5 and t7 xor not t6) xor t4 and t1 xor t5 and t6 xor t7 and t3); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[29] + $456F9FB4; temp:= (t1 and (t3 and t4 and t6 xor not t5) xor t3 and t0 xor t4 and t5 xor t6 and t2); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $7D84A5C3; temp:= (t0 and (t2 and t3 and t5 xor not t4) xor t2 and t7 xor t3 and t4 xor t5 and t1); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 0] + $3B8B5EBE; temp:= (t7 and (t1 and t2 and t4 xor not t3) xor t1 and t6 xor t2 and t3 xor t4 and t0); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[12] + $E06F75D8; temp:= (t6 and (t0 and t1 and t3 xor not t2) xor t0 and t5 xor t1 and t2 xor t3 and t7); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 7] + $85C12073; temp:= (t5 and (t7 and t0 and t2 xor not t1) xor t7 and t4 xor t0 and t1 xor t2 and t6); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[13] + $401A449F; temp:= (t4 and (t6 and t7 and t1 xor not t0) xor t6 and t3 xor t7 and t0 xor t1 and t5); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 8] + $56C16AA6; temp:= (t3 and (t5 and t6 and t0 xor not t7) xor t5 and t2 xor t6 and t7 xor t0 and t4); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[31] + $4ED3AA62; temp:= (t2 and (t4 and t5 and t7 xor not t6) xor t4 and t1 xor t5 and t6 xor t7 and t3); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[10] + $363F7706; temp:= (t1 and (t3 and t4 and t6 xor not t5) xor t3 and t0 xor t4 and t5 xor t6 and t2); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 5] + $1BFEDF72; temp:= (t0 and (t2 and t3 and t5 xor not t4) xor t2 and t7 xor t3 and t4 xor t5 and t1); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9] + $429B023D; temp:= (t7 and (t1 and t2 and t4 xor not t3) xor t1 and t6 xor t2 and t3 xor t4 and t0); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[14] + $37D0D724; temp:= (t6 and (t0 and t1 and t3 xor not t2) xor t0 and t5 xor t1 and t2 xor t3 and t7); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[30] + $D00A1248; temp:= (t5 and (t7 and t0 and t2 xor not t1) xor t7 and t4 xor t0 and t1 xor t2 and t6); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[18] + $DB0FEAD3; temp:= (t4 and (t6 and t7 and t1 xor not t0) xor t6 and t3 xor t7 and t0 xor t1 and t5); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 6] + $49F1C09B; temp:= (t3 and (t5 and t6 and t0 xor not t7) xor t5 and t2 xor t6 and t7 xor t0 and t4); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[28] + $075372C9; temp:= (t2 and (t4 and t5 and t7 xor not t6) xor t4 and t1 xor t5 and t6 xor t7 and t3); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[24] + $80991B7B; temp:= (t1 and (t3 and t4 and t6 xor not t5) xor t3 and t0 xor t4 and t5 xor t6 and t2); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 2] + $25D479D8; temp:= (t0 and (t2 and t3 and t5 xor not t4) xor t2 and t7 xor t3 and t4 xor t5 and t1); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[23] + $F6E8DEF7; temp:= (t7 and (t1 and t2 and t4 xor not t3) xor t1 and t6 xor t2 and t3 xor t4 and t0); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[16] + $E3FE501A; temp:= (t6 and (t0 and t1 and t3 xor not t2) xor t0 and t5 xor t1 and t2 xor t3 and t7); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[22] + $B6794C3B; temp:= (t5 and (t7 and t0 and t2 xor not t1) xor t7 and t4 xor t0 and t1 xor t2 and t6); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 4] + $976CE0BD; temp:= (t4 and (t6 and t7 and t1 xor not t0) xor t6 and t3 xor t7 and t0 xor t1 and t5); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 1] + $04C006BA; temp:= (t3 and (t5 and t6 and t0 xor not t7) xor t5 and t2 xor t6 and t7 xor t0 and t4); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[25] + $C1A94FB6; temp:= (t2 and (t4 and t5 and t7 xor not t6) xor t4 and t1 xor t5 and t6 xor t7 and t3); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[15] + $409F60C4; doublecmd-0.8.2/components/dcpcrypt/Hashes/DCPhaval3.inc0000664000175000017500000003731312014201074022133 0ustar alexxalexxtemp:= (t2 and (t4 xor t3) xor t6 and t0 xor t5 and t1 xor t4); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0]; temp:= (t1 and (t3 xor t2) xor t5 and t7 xor t4 and t0 xor t3); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 1]; temp:= (t0 and (t2 xor t1) xor t4 and t6 xor t3 and t7 xor t2); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 2]; temp:= (t7 and (t1 xor t0) xor t3 and t5 xor t2 and t6 xor t1); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3]; temp:= (t6 and (t0 xor t7) xor t2 and t4 xor t1 and t5 xor t0); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 4]; temp:= (t5 and (t7 xor t6) xor t1 and t3 xor t0 and t4 xor t7); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 5]; temp:= (t4 and (t6 xor t5) xor t0 and t2 xor t7 and t3 xor t6); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 6]; temp:= (t3 and (t5 xor t4) xor t7 and t1 xor t6 and t2 xor t5); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 7]; temp:= (t2 and (t4 xor t3) xor t6 and t0 xor t5 and t1 xor t4); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 8]; temp:= (t1 and (t3 xor t2) xor t5 and t7 xor t4 and t0 xor t3); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9]; temp:= (t0 and (t2 xor t1) xor t4 and t6 xor t3 and t7 xor t2); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[10]; temp:= (t7 and (t1 xor t0) xor t3 and t5 xor t2 and t6 xor t1); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[11]; temp:= (t6 and (t0 xor t7) xor t2 and t4 xor t1 and t5 xor t0); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[12]; temp:= (t5 and (t7 xor t6) xor t1 and t3 xor t0 and t4 xor t7); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[13]; temp:= (t4 and (t6 xor t5) xor t0 and t2 xor t7 and t3 xor t6); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[14]; temp:= (t3 and (t5 xor t4) xor t7 and t1 xor t6 and t2 xor t5); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[15]; temp:= (t2 and (t4 xor t3) xor t6 and t0 xor t5 and t1 xor t4); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[16]; temp:= (t1 and (t3 xor t2) xor t5 and t7 xor t4 and t0 xor t3); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[17]; temp:= (t0 and (t2 xor t1) xor t4 and t6 xor t3 and t7 xor t2); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[18]; temp:= (t7 and (t1 xor t0) xor t3 and t5 xor t2 and t6 xor t1); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[19]; temp:= (t6 and (t0 xor t7) xor t2 and t4 xor t1 and t5 xor t0); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[20]; temp:= (t5 and (t7 xor t6) xor t1 and t3 xor t0 and t4 xor t7); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[21]; temp:= (t4 and (t6 xor t5) xor t0 and t2 xor t7 and t3 xor t6); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[22]; temp:= (t3 and (t5 xor t4) xor t7 and t1 xor t6 and t2 xor t5); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[23]; temp:= (t2 and (t4 xor t3) xor t6 and t0 xor t5 and t1 xor t4); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[24]; temp:= (t1 and (t3 xor t2) xor t5 and t7 xor t4 and t0 xor t3); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[25]; temp:= (t0 and (t2 xor t1) xor t4 and t6 xor t3 and t7 xor t2); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26]; temp:= (t7 and (t1 xor t0) xor t3 and t5 xor t2 and t6 xor t1); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[27]; temp:= (t6 and (t0 xor t7) xor t2 and t4 xor t1 and t5 xor t0); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28]; temp:= (t5 and (t7 xor t6) xor t1 and t3 xor t0 and t4 xor t7); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[29]; temp:= (t4 and (t6 xor t5) xor t0 and t2 xor t7 and t3 xor t6); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[30]; temp:= (t3 and (t5 xor t4) xor t7 and t1 xor t6 and t2 xor t5); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[31]; temp:= (t5 and (t3 and not t0 xor t1 and t2 xor t4 xor t6) xor t1 and (t3 xor t2) xor t0 and t2 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 5] + $452821E6; temp:= (t4 and (t2 and not t7 xor t0 and t1 xor t3 xor t5) xor t0 and (t2 xor t1) xor t7 and t1 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $38D01377; temp:= (t3 and (t1 and not t6 xor t7 and t0 xor t2 xor t4) xor t7 and (t1 xor t0) xor t6 and t0 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26] + $BE5466CF; temp:= (t2 and (t0 and not t5 xor t6 and t7 xor t1 xor t3) xor t6 and (t0 xor t7) xor t5 and t7 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[18] + $34E90C6C; temp:= (t1 and (t7 and not t4 xor t5 and t6 xor t0 xor t2) xor t5 and (t7 xor t6) xor t4 and t6 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[11] + $C0AC29B7; temp:= (t0 and (t6 and not t3 xor t4 and t5 xor t7 xor t1) xor t4 and (t6 xor t5) xor t3 and t5 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[28] + $C97C50DD; temp:= (t7 and (t5 and not t2 xor t3 and t4 xor t6 xor t0) xor t3 and (t5 xor t4) xor t2 and t4 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 7] + $3F84D5B5; temp:= (t6 and (t4 and not t1 xor t2 and t3 xor t5 xor t7) xor t2 and (t4 xor t3) xor t1 and t3 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[16] + $B5470917; temp:= (t5 and (t3 and not t0 xor t1 and t2 xor t4 xor t6) xor t1 and (t3 xor t2) xor t0 and t2 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0] + $9216D5D9; temp:= (t4 and (t2 and not t7 xor t0 and t1 xor t3 xor t5) xor t0 and (t2 xor t1) xor t7 and t1 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[23] + $8979FB1B; temp:= (t3 and (t1 and not t6 xor t7 and t0 xor t2 xor t4) xor t7 and (t1 xor t0) xor t6 and t0 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[20] + $D1310BA6; temp:= (t2 and (t0 and not t5 xor t6 and t7 xor t1 xor t3) xor t6 and (t0 xor t7) xor t5 and t7 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[22] + $98DFB5AC; temp:= (t1 and (t7 and not t4 xor t5 and t6 xor t0 xor t2) xor t5 and (t7 xor t6) xor t4 and t6 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $2FFD72DB; temp:= (t0 and (t6 and not t3 xor t4 and t5 xor t7 xor t1) xor t4 and (t6 xor t5) xor t3 and t5 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[10] + $D01ADFB7; temp:= (t7 and (t5 and not t2 xor t3 and t4 xor t6 xor t0) xor t3 and (t5 xor t4) xor t2 and t4 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 4] + $B8E1AFED; temp:= (t6 and (t4 and not t1 xor t2 and t3 xor t5 xor t7) xor t2 and (t4 xor t3) xor t1 and t3 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 8] + $6A267E96; temp:= (t5 and (t3 and not t0 xor t1 and t2 xor t4 xor t6) xor t1 and (t3 xor t2) xor t0 and t2 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[30] + $BA7C9045; temp:= (t4 and (t2 and not t7 xor t0 and t1 xor t3 xor t5) xor t0 and (t2 xor t1) xor t7 and t1 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 3] + $F12C7F99; temp:= (t3 and (t1 and not t6 xor t7 and t0 xor t2 xor t4) xor t7 and (t1 xor t0) xor t6 and t0 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $24A19947; temp:= (t2 and (t0 and not t5 xor t6 and t7 xor t1 xor t3) xor t6 and (t0 xor t7) xor t5 and t7 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 9] + $B3916CF7; temp:= (t1 and (t7 and not t4 xor t5 and t6 xor t0 xor t2) xor t5 and (t7 xor t6) xor t4 and t6 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $0801F2E2; temp:= (t0 and (t6 and not t3 xor t4 and t5 xor t7 xor t1) xor t4 and (t6 xor t5) xor t3 and t5 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[24] + $858EFC16; temp:= (t7 and (t5 and not t2 xor t3 and t4 xor t6 xor t0) xor t3 and (t5 xor t4) xor t2 and t4 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[29] + $636920D8; temp:= (t6 and (t4 and not t1 xor t2 and t3 xor t5 xor t7) xor t2 and (t4 xor t3) xor t1 and t3 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 6] + $71574E69; temp:= (t5 and (t3 and not t0 xor t1 and t2 xor t4 xor t6) xor t1 and (t3 xor t2) xor t0 and t2 xor t6); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $A458FEA3; temp:= (t4 and (t2 and not t7 xor t0 and t1 xor t3 xor t5) xor t0 and (t2 xor t1) xor t7 and t1 xor t5); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[12] + $F4933D7E; temp:= (t3 and (t1 and not t6 xor t7 and t0 xor t2 xor t4) xor t7 and (t1 xor t0) xor t6 and t0 xor t4); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[15] + $0D95748F; temp:= (t2 and (t0 and not t5 xor t6 and t7 xor t1 xor t3) xor t6 and (t0 xor t7) xor t5 and t7 xor t3); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[13] + $728EB658; temp:= (t1 and (t7 and not t4 xor t5 and t6 xor t0 xor t2) xor t5 and (t7 xor t6) xor t4 and t6 xor t2); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 2] + $718BCD58; temp:= (t0 and (t6 and not t3 xor t4 and t5 xor t7 xor t1) xor t4 and (t6 xor t5) xor t3 and t5 xor t1); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[25] + $82154AEE; temp:= (t7 and (t5 and not t2 xor t3 and t4 xor t6 xor t0) xor t3 and (t5 xor t4) xor t2 and t4 xor t0); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[31] + $7B54A41D; temp:= (t6 and (t4 and not t1 xor t2 and t3 xor t5 xor t7) xor t2 and (t4 xor t3) xor t1 and t3 xor t7); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $C25A59B5; temp:= (t3 and (t5 and t4 xor t6 xor t0) xor t5 and t2 xor t4 and t1 xor t0); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $9C30D539; temp:= (t2 and (t4 and t3 xor t5 xor t7) xor t4 and t1 xor t3 and t0 xor t7); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9] + $2AF26013; temp:= (t1 and (t3 and t2 xor t4 xor t6) xor t3 and t0 xor t2 and t7 xor t6); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 4] + $C5D1B023; temp:= (t0 and (t2 and t1 xor t3 xor t5) xor t2 and t7 xor t1 and t6 xor t5); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[20] + $286085F0; temp:= (t7 and (t1 and t0 xor t2 xor t4) xor t1 and t6 xor t0 and t5 xor t4); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28] + $CA417918; temp:= (t6 and (t0 and t7 xor t1 xor t3) xor t0 and t5 xor t7 and t4 xor t3); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[17] + $B8DB38EF; temp:= (t5 and (t7 and t6 xor t0 xor t2) xor t7 and t4 xor t6 and t3 xor t2); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 8] + $8E79DCB0; temp:= (t4 and (t6 and t5 xor t7 xor t1) xor t6 and t3 xor t5 and t2 xor t1); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[22] + $603A180E; temp:= (t3 and (t5 and t4 xor t6 xor t0) xor t5 and t2 xor t4 and t1 xor t0); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[29] + $6C9E0E8B; temp:= (t2 and (t4 and t3 xor t5 xor t7) xor t4 and t1 xor t3 and t0 xor t7); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $B01E8A3E; temp:= (t1 and (t3 and t2 xor t4 xor t6) xor t3 and t0 xor t2 and t7 xor t6); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[25] + $D71577C1; temp:= (t0 and (t2 and t1 xor t3 xor t5) xor t2 and t7 xor t1 and t6 xor t5); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[12] + $BD314B27; temp:= (t7 and (t1 and t0 xor t2 xor t4) xor t1 and t6 xor t0 and t5 xor t4); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[24] + $78AF2FDA; temp:= (t6 and (t0 and t7 xor t1 xor t3) xor t0 and t5 xor t7 and t4 xor t3); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[30] + $55605C60; temp:= (t5 and (t7 and t6 xor t0 xor t2) xor t7 and t4 xor t6 and t3 xor t2); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[16] + $E65525F3; temp:= (t4 and (t6 and t5 xor t7 xor t1) xor t6 and t3 xor t5 and t2 xor t1); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[26] + $AA55AB94; temp:= (t3 and (t5 and t4 xor t6 xor t0) xor t5 and t2 xor t4 and t1 xor t0); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[31] + $57489862; temp:= (t2 and (t4 and t3 xor t5 xor t7) xor t4 and t1 xor t3 and t0 xor t7); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[15] + $63E81440; temp:= (t1 and (t3 and t2 xor t4 xor t6) xor t3 and t0 xor t2 and t7 xor t6); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 7] + $55CA396A; temp:= (t0 and (t2 and t1 xor t3 xor t5) xor t2 and t7 xor t1 and t6 xor t5); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3] + $2AAB10B6; temp:= (t7 and (t1 and t0 xor t2 xor t4) xor t1 and t6 xor t0 and t5 xor t4); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $B4CC5C34; temp:= (t6 and (t0 and t7 xor t1 xor t3) xor t0 and t5 xor t7 and t4 xor t3); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 0] + $1141E8CE; temp:= (t5 and (t7 and t6 xor t0 xor t2) xor t7 and t4 xor t6 and t3 xor t2); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[18] + $A15486AF; temp:= (t4 and (t6 and t5 xor t7 xor t1) xor t6 and t3 xor t5 and t2 xor t1); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $7C72E993; temp:= (t3 and (t5 and t4 xor t6 xor t0) xor t5 and t2 xor t4 and t1 xor t0); t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[13] + $B3EE1411; temp:= (t2 and (t4 and t3 xor t5 xor t7) xor t4 and t1 xor t3 and t0 xor t7); t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 6] + $636FBC2A; temp:= (t1 and (t3 and t2 xor t4 xor t6) xor t3 and t0 xor t2 and t7 xor t6); t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $2BA9C55D; temp:= (t0 and (t2 and t1 xor t3 xor t5) xor t2 and t7 xor t1 and t6 xor t5); t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[10] + $741831F6; temp:= (t7 and (t1 and t0 xor t2 xor t4) xor t1 and t6 xor t0 and t5 xor t4); t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[23] + $CE5C3E16; temp:= (t6 and (t0 and t7 xor t1 xor t3) xor t0 and t5 xor t7 and t4 xor t3); t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[11] + $9B87931E; temp:= (t5 and (t7 and t6 xor t0 xor t2) xor t7 and t4 xor t6 and t3 xor t2); t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 5] + $AFD6BA33; temp:= (t4 and (t6 and t5 xor t7 xor t1) xor t6 and t3 xor t5 and t2 xor t1); t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 2] + $6C24CF5C; doublecmd-0.8.2/components/dcpcrypt/Hashes/dcpcrc32.pas0000664000175000017500000001006612573022170022047 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible (with Total Commander) implementation of CRC32 *} {******************************************************************************} {* Copyright (C) 2011-2015 Alexander Koblov (alexx2000@mail.ru) *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPcrc32; {$mode objfpc}{$H+} interface uses Classes, Sysutils, DCPcrypt2, DCPconst, DCcrc32; type { TDCP_crc32 } TDCP_crc32 = class(TDCP_hash) protected CurrentHash: LongWord; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; constructor Create(AOwner: TComponent); override; procedure Init; override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; procedure Final(var Digest); override; end; implementation {$R-}{$Q-} { TDCP_crc32 } class function TDCP_crc32.GetHashSize: integer; begin Result:= 32; end; class function TDCP_crc32.GetId: integer; begin Result:= DCP_crc32; end; class function TDCP_crc32.GetAlgorithm: string; begin Result:= 'CRC32'; end; class function TDCP_crc32.SelfTest: boolean; const Test1Out: array[0..3] of byte=($35,$24,$41,$C2); Test2Out: array[0..3] of byte=($4C,$27,$50,$BD); var TestHash: TDCP_crc32; TestOut: array[0..3] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_crc32.Create(nil); TestHash.Init; TestHash.UpdateStr('abc'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Init; TestHash.UpdateStr('abcdefghijklmnopqrstuvwxyz'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out)) and Result; TestHash.Free; end; constructor TDCP_crc32.Create(AOwner: TComponent); begin inherited Create(AOwner); end; procedure TDCP_crc32.Init; begin Burn; crc32_init; CurrentHash:= 0; fInitialized:= true; end; procedure TDCP_crc32.Burn; begin CurrentHash:= 0; fInitialized:= false; end; procedure TDCP_crc32.Update(const Buffer; Size: longword); var Bytes: PByte; begin Bytes:= @Buffer; CurrentHash:= crc32_16bytes(Bytes, Size, CurrentHash); end; procedure TDCP_crc32.Final(var Digest); begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); CurrentHash:= SwapEndian(CurrentHash); Move(CurrentHash, Digest, Sizeof(CurrentHash)); Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dcpsha3.pas0000664000175000017500000001214212726767147022012 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of SHA3 (224, 256, 384, 512) ************} {******************************************************************************} {* Copyright (C) 2016 Alexander Koblov (alexx2000@mail.ru) *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPsha3; {$mode objfpc}{$H+} interface uses Classes, SysUtils, DCPcrypt2, DCPconst, SHA3; type { TDCP_sha3base } TDCP_sha3base = class(TDCP_hash) protected FState: TSHA3State; public procedure Final(var Digest); override; procedure Update(const Buffer; Size: longword); override; end; { TDCP_sha3_224 } TDCP_sha3_224 = class(TDCP_sha3base) public class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; end; { TDCP_sha3_256 } TDCP_sha3_256 = class(TDCP_sha3base) public class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; end; { TDCP_sha3_384 } TDCP_sha3_384 = class(TDCP_sha3base) public class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; end; { TDCP_sha3_512 } TDCP_sha3_512 = class(TDCP_sha3base) public class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; end; implementation { TDCP_sha3base } procedure TDCP_sha3base.Final(var Digest); begin SHA3_FinalBit_LSB(FState, 0, 0, @Digest, FState.fixedOutputLength); end; procedure TDCP_sha3base.Update(const Buffer; Size: longword); begin SHA3_UpdateXL(FState, @Buffer, Size); end; { TDCP_sha3_224 } class function TDCP_sha3_224.GetAlgorithm: string; begin Result:= 'SHA3_224'; end; class function TDCP_sha3_224.GetHashSize: integer; begin Result:= 224; end; class function TDCP_sha3_224.SelfTest: boolean; begin Result:= False; // TODO: SelfTest SHA3_224 end; procedure TDCP_sha3_224.Init; begin SHA3_Init(FState, __SHA3_224); end; { TDCP_sha3_256 } class function TDCP_sha3_256.GetAlgorithm: string; begin Result:= 'SHA3_256'; end; class function TDCP_sha3_256.GetHashSize: integer; begin Result:= 256; end; class function TDCP_sha3_256.SelfTest: boolean; begin Result:= False; // TODO: SelfTest SHA3_256 end; procedure TDCP_sha3_256.Init; begin SHA3_Init(FState, __SHA3_256); end; { TDCP_sha3_384 } class function TDCP_sha3_384.GetAlgorithm: string; begin Result:= 'SHA3_384'; end; class function TDCP_sha3_384.GetHashSize: integer; begin Result:= 384; end; class function TDCP_sha3_384.SelfTest: boolean; begin Result:= False; // TODO: SelfTest SHA3_384 end; procedure TDCP_sha3_384.Init; begin SHA3_Init(FState, __SHA3_384); end; { TDCP_sha3_512 } class function TDCP_sha3_512.GetAlgorithm: string; begin Result:= 'SHA3_512'; end; class function TDCP_sha3_512.GetHashSize: integer; begin Result:= 512; end; class function TDCP_sha3_512.SelfTest: boolean; begin Result:= False; // TODO: SelfTest SHA3_512 end; procedure TDCP_sha3_512.Init; begin SHA3_Init(FState, __SHA3_512); end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dcpsha256.pas0000664000175000017500000006624312014201074022143 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of SHA256 *******************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPsha256; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2, DCPconst; type TDCP_sha256= class(TDCP_hash) protected LenHi, LenLo: longword; Index: DWord; CurrentHash: array[0..7] of DWord; HashBuffer: array[0..63] of byte; procedure Compress; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Final(var Digest); override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; end; {******************************************************************************} {******************************************************************************} implementation {$R-}{$Q-} function SwapDWord(a: dword): dword; begin Result:= ((a and $FF) shl 24) or ((a and $FF00) shl 8) or ((a and $FF0000) shr 8) or ((a and $FF000000) shr 24); end; procedure TDCP_sha256.Compress; var a, b, c, d, e, f, g, h, t1, t2: DWord; W: array[0..63] of DWord; i: longword; begin Index:= 0; dcpFillChar(W, SizeOf(W), 0); a:= CurrentHash[0]; b:= CurrentHash[1]; c:= CurrentHash[2]; d:= CurrentHash[3]; e:= CurrentHash[4]; f:= CurrentHash[5]; g:= CurrentHash[6]; h:= CurrentHash[7]; Move(HashBuffer,W,Sizeof(HashBuffer)); for i:= 0 to 15 do W[i]:= SwapDWord(W[i]); for i:= 16 to 63 do W[i]:= (((W[i-2] shr 17) or (W[i-2] shl 15)) xor ((W[i-2] shr 19) or (W[i-2] shl 13)) xor (W[i-2] shr 10)) + W[i-7] + (((W[i-15] shr 7) or (W[i-15] shl 25)) xor ((W[i-15] shr 18) or (W[i-15] shl 14)) xor (W[i-15] shr 3)) + W[i-16]; { Non-optimised version for i:= 0 to 63 do begin t1:= h + (((e shr 6) or (e shl 26)) xor ((e shr 11) or (e shl 21)) xor ((e shr 25) or (e shl 7))) + ((e and f) xor (not e and g)) + K[i] + W[i]; t2:= (((a shr 2) or (a shl 30)) xor ((a shr 13) or (a shl 19)) xor ((a shr 22) xor (a shl 10))) + ((a and b) xor (a and c) xor (b and c)); h:= g; g:= f; f:= e; e:= d + t1; d:= c; c:= b; b:= a; a:= t1 + t2; end; } t1:= h + (((e shr 6) or (e shl 26)) xor ((e shr 11) or (e shl 21)) xor ((e shr 25) or (e shl 7))) + ((e and f) xor (not e and g)) + $428a2f98 + W[0]; t2:= (((a shr 2) or (a shl 30)) xor ((a shr 13) or (a shl 19)) xor ((a shr 22) xor (a shl 10))) + ((a and b) xor (a and c) xor (b and c)); h:= t1 + t2; d:= d + t1; t1:= g + (((d shr 6) or (d shl 26)) xor ((d shr 11) or (d shl 21)) xor ((d shr 25) or (d shl 7))) + ((d and e) xor (not d and f)) + $71374491 + W[1]; t2:= (((h shr 2) or (h shl 30)) xor ((h shr 13) or (h shl 19)) xor ((h shr 22) xor (h shl 10))) + ((h and a) xor (h and b) xor (a and b)); g:= t1 + t2; c:= c + t1; t1:= f + (((c shr 6) or (c shl 26)) xor ((c shr 11) or (c shl 21)) xor ((c shr 25) or (c shl 7))) + ((c and d) xor (not c and e)) + $b5c0fbcf + W[2]; t2:= (((g shr 2) or (g shl 30)) xor ((g shr 13) or (g shl 19)) xor ((g shr 22) xor (g shl 10))) + ((g and h) xor (g and a) xor (h and a)); f:= t1 + t2; b:= b + t1; t1:= e + (((b shr 6) or (b shl 26)) xor ((b shr 11) or (b shl 21)) xor ((b shr 25) or (b shl 7))) + ((b and c) xor (not b and d)) + $e9b5dba5 + W[3]; t2:= (((f shr 2) or (f shl 30)) xor ((f shr 13) or (f shl 19)) xor ((f shr 22) xor (f shl 10))) + ((f and g) xor (f and h) xor (g and h)); e:= t1 + t2; a:= a + t1; t1:= d + (((a shr 6) or (a shl 26)) xor ((a shr 11) or (a shl 21)) xor ((a shr 25) or (a shl 7))) + ((a and b) xor (not a and c)) + $3956c25b + W[4]; t2:= (((e shr 2) or (e shl 30)) xor ((e shr 13) or (e shl 19)) xor ((e shr 22) xor (e shl 10))) + ((e and f) xor (e and g) xor (f and g)); d:= t1 + t2; h:= h + t1; t1:= c + (((h shr 6) or (h shl 26)) xor ((h shr 11) or (h shl 21)) xor ((h shr 25) or (h shl 7))) + ((h and a) xor (not h and b)) + $59f111f1 + W[5]; t2:= (((d shr 2) or (d shl 30)) xor ((d shr 13) or (d shl 19)) xor ((d shr 22) xor (d shl 10))) + ((d and e) xor (d and f) xor (e and f)); c:= t1 + t2; g:= g + t1; t1:= b + (((g shr 6) or (g shl 26)) xor ((g shr 11) or (g shl 21)) xor ((g shr 25) or (g shl 7))) + ((g and h) xor (not g and a)) + $923f82a4 + W[6]; t2:= (((c shr 2) or (c shl 30)) xor ((c shr 13) or (c shl 19)) xor ((c shr 22) xor (c shl 10))) + ((c and d) xor (c and e) xor (d and e)); b:= t1 + t2; f:= f + t1; t1:= a + (((f shr 6) or (f shl 26)) xor ((f shr 11) or (f shl 21)) xor ((f shr 25) or (f shl 7))) + ((f and g) xor (not f and h)) + $ab1c5ed5 + W[7]; t2:= (((b shr 2) or (b shl 30)) xor ((b shr 13) or (b shl 19)) xor ((b shr 22) xor (b shl 10))) + ((b and c) xor (b and d) xor (c and d)); a:= t1 + t2; e:= e + t1; t1:= h + (((e shr 6) or (e shl 26)) xor ((e shr 11) or (e shl 21)) xor ((e shr 25) or (e shl 7))) + ((e and f) xor (not e and g)) + $d807aa98 + W[8]; t2:= (((a shr 2) or (a shl 30)) xor ((a shr 13) or (a shl 19)) xor ((a shr 22) xor (a shl 10))) + ((a and b) xor (a and c) xor (b and c)); h:= t1 + t2; d:= d + t1; t1:= g + (((d shr 6) or (d shl 26)) xor ((d shr 11) or (d shl 21)) xor ((d shr 25) or (d shl 7))) + ((d and e) xor (not d and f)) + $12835b01 + W[9]; t2:= (((h shr 2) or (h shl 30)) xor ((h shr 13) or (h shl 19)) xor ((h shr 22) xor (h shl 10))) + ((h and a) xor (h and b) xor (a and b)); g:= t1 + t2; c:= c + t1; t1:= f + (((c shr 6) or (c shl 26)) xor ((c shr 11) or (c shl 21)) xor ((c shr 25) or (c shl 7))) + ((c and d) xor (not c and e)) + $243185be + W[10]; t2:= (((g shr 2) or (g shl 30)) xor ((g shr 13) or (g shl 19)) xor ((g shr 22) xor (g shl 10))) + ((g and h) xor (g and a) xor (h and a)); f:= t1 + t2; b:= b + t1; t1:= e + (((b shr 6) or (b shl 26)) xor ((b shr 11) or (b shl 21)) xor ((b shr 25) or (b shl 7))) + ((b and c) xor (not b and d)) + $550c7dc3 + W[11]; t2:= (((f shr 2) or (f shl 30)) xor ((f shr 13) or (f shl 19)) xor ((f shr 22) xor (f shl 10))) + ((f and g) xor (f and h) xor (g and h)); e:= t1 + t2; a:= a + t1; t1:= d + (((a shr 6) or (a shl 26)) xor ((a shr 11) or (a shl 21)) xor ((a shr 25) or (a shl 7))) + ((a and b) xor (not a and c)) + $72be5d74 + W[12]; t2:= (((e shr 2) or (e shl 30)) xor ((e shr 13) or (e shl 19)) xor ((e shr 22) xor (e shl 10))) + ((e and f) xor (e and g) xor (f and g)); d:= t1 + t2; h:= h + t1; t1:= c + (((h shr 6) or (h shl 26)) xor ((h shr 11) or (h shl 21)) xor ((h shr 25) or (h shl 7))) + ((h and a) xor (not h and b)) + $80deb1fe + W[13]; t2:= (((d shr 2) or (d shl 30)) xor ((d shr 13) or (d shl 19)) xor ((d shr 22) xor (d shl 10))) + ((d and e) xor (d and f) xor (e and f)); c:= t1 + t2; g:= g + t1; t1:= b + (((g shr 6) or (g shl 26)) xor ((g shr 11) or (g shl 21)) xor ((g shr 25) or (g shl 7))) + ((g and h) xor (not g and a)) + $9bdc06a7 + W[14]; t2:= (((c shr 2) or (c shl 30)) xor ((c shr 13) or (c shl 19)) xor ((c shr 22) xor (c shl 10))) + ((c and d) xor (c and e) xor (d and e)); b:= t1 + t2; f:= f + t1; t1:= a + (((f shr 6) or (f shl 26)) xor ((f shr 11) or (f shl 21)) xor ((f shr 25) or (f shl 7))) + ((f and g) xor (not f and h)) + $c19bf174 + W[15]; t2:= (((b shr 2) or (b shl 30)) xor ((b shr 13) or (b shl 19)) xor ((b shr 22) xor (b shl 10))) + ((b and c) xor (b and d) xor (c and d)); a:= t1 + t2; e:= e + t1; t1:= h + (((e shr 6) or (e shl 26)) xor ((e shr 11) or (e shl 21)) xor ((e shr 25) or (e shl 7))) + ((e and f) xor (not e and g)) + $e49b69c1 + W[16]; t2:= (((a shr 2) or (a shl 30)) xor ((a shr 13) or (a shl 19)) xor ((a shr 22) xor (a shl 10))) + ((a and b) xor (a and c) xor (b and c)); h:= t1 + t2; d:= d + t1; t1:= g + (((d shr 6) or (d shl 26)) xor ((d shr 11) or (d shl 21)) xor ((d shr 25) or (d shl 7))) + ((d and e) xor (not d and f)) + $efbe4786 + W[17]; t2:= (((h shr 2) or (h shl 30)) xor ((h shr 13) or (h shl 19)) xor ((h shr 22) xor (h shl 10))) + ((h and a) xor (h and b) xor (a and b)); g:= t1 + t2; c:= c + t1; t1:= f + (((c shr 6) or (c shl 26)) xor ((c shr 11) or (c shl 21)) xor ((c shr 25) or (c shl 7))) + ((c and d) xor (not c and e)) + $0fc19dc6 + W[18]; t2:= (((g shr 2) or (g shl 30)) xor ((g shr 13) or (g shl 19)) xor ((g shr 22) xor (g shl 10))) + ((g and h) xor (g and a) xor (h and a)); f:= t1 + t2; b:= b + t1; t1:= e + (((b shr 6) or (b shl 26)) xor ((b shr 11) or (b shl 21)) xor ((b shr 25) or (b shl 7))) + ((b and c) xor (not b and d)) + $240ca1cc + W[19]; t2:= (((f shr 2) or (f shl 30)) xor ((f shr 13) or (f shl 19)) xor ((f shr 22) xor (f shl 10))) + ((f and g) xor (f and h) xor (g and h)); e:= t1 + t2; a:= a + t1; t1:= d + (((a shr 6) or (a shl 26)) xor ((a shr 11) or (a shl 21)) xor ((a shr 25) or (a shl 7))) + ((a and b) xor (not a and c)) + $2de92c6f + W[20]; t2:= (((e shr 2) or (e shl 30)) xor ((e shr 13) or (e shl 19)) xor ((e shr 22) xor (e shl 10))) + ((e and f) xor (e and g) xor (f and g)); d:= t1 + t2; h:= h + t1; t1:= c + (((h shr 6) or (h shl 26)) xor ((h shr 11) or (h shl 21)) xor ((h shr 25) or (h shl 7))) + ((h and a) xor (not h and b)) + $4a7484aa + W[21]; t2:= (((d shr 2) or (d shl 30)) xor ((d shr 13) or (d shl 19)) xor ((d shr 22) xor (d shl 10))) + ((d and e) xor (d and f) xor (e and f)); c:= t1 + t2; g:= g + t1; t1:= b + (((g shr 6) or (g shl 26)) xor ((g shr 11) or (g shl 21)) xor ((g shr 25) or (g shl 7))) + ((g and h) xor (not g and a)) + $5cb0a9dc + W[22]; t2:= (((c shr 2) or (c shl 30)) xor ((c shr 13) or (c shl 19)) xor ((c shr 22) xor (c shl 10))) + ((c and d) xor (c and e) xor (d and e)); b:= t1 + t2; f:= f + t1; t1:= a + (((f shr 6) or (f shl 26)) xor ((f shr 11) or (f shl 21)) xor ((f shr 25) or (f shl 7))) + ((f and g) xor (not f and h)) + $76f988da + W[23]; t2:= (((b shr 2) or (b shl 30)) xor ((b shr 13) or (b shl 19)) xor ((b shr 22) xor (b shl 10))) + ((b and c) xor (b and d) xor (c and d)); a:= t1 + t2; e:= e + t1; t1:= h + (((e shr 6) or (e shl 26)) xor ((e shr 11) or (e shl 21)) xor ((e shr 25) or (e shl 7))) + ((e and f) xor (not e and g)) + $983e5152 + W[24]; t2:= (((a shr 2) or (a shl 30)) xor ((a shr 13) or (a shl 19)) xor ((a shr 22) xor (a shl 10))) + ((a and b) xor (a and c) xor (b and c)); h:= t1 + t2; d:= d + t1; t1:= g + (((d shr 6) or (d shl 26)) xor ((d shr 11) or (d shl 21)) xor ((d shr 25) or (d shl 7))) + ((d and e) xor (not d and f)) + $a831c66d + W[25]; t2:= (((h shr 2) or (h shl 30)) xor ((h shr 13) or (h shl 19)) xor ((h shr 22) xor (h shl 10))) + ((h and a) xor (h and b) xor (a and b)); g:= t1 + t2; c:= c + t1; t1:= f + (((c shr 6) or (c shl 26)) xor ((c shr 11) or (c shl 21)) xor ((c shr 25) or (c shl 7))) + ((c and d) xor (not c and e)) + $b00327c8 + W[26]; t2:= (((g shr 2) or (g shl 30)) xor ((g shr 13) or (g shl 19)) xor ((g shr 22) xor (g shl 10))) + ((g and h) xor (g and a) xor (h and a)); f:= t1 + t2; b:= b + t1; t1:= e + (((b shr 6) or (b shl 26)) xor ((b shr 11) or (b shl 21)) xor ((b shr 25) or (b shl 7))) + ((b and c) xor (not b and d)) + $bf597fc7 + W[27]; t2:= (((f shr 2) or (f shl 30)) xor ((f shr 13) or (f shl 19)) xor ((f shr 22) xor (f shl 10))) + ((f and g) xor (f and h) xor (g and h)); e:= t1 + t2; a:= a + t1; t1:= d + (((a shr 6) or (a shl 26)) xor ((a shr 11) or (a shl 21)) xor ((a shr 25) or (a shl 7))) + ((a and b) xor (not a and c)) + $c6e00bf3 + W[28]; t2:= (((e shr 2) or (e shl 30)) xor ((e shr 13) or (e shl 19)) xor ((e shr 22) xor (e shl 10))) + ((e and f) xor (e and g) xor (f and g)); d:= t1 + t2; h:= h + t1; t1:= c + (((h shr 6) or (h shl 26)) xor ((h shr 11) or (h shl 21)) xor ((h shr 25) or (h shl 7))) + ((h and a) xor (not h and b)) + $d5a79147 + W[29]; t2:= (((d shr 2) or (d shl 30)) xor ((d shr 13) or (d shl 19)) xor ((d shr 22) xor (d shl 10))) + ((d and e) xor (d and f) xor (e and f)); c:= t1 + t2; g:= g + t1; t1:= b + (((g shr 6) or (g shl 26)) xor ((g shr 11) or (g shl 21)) xor ((g shr 25) or (g shl 7))) + ((g and h) xor (not g and a)) + $06ca6351 + W[30]; t2:= (((c shr 2) or (c shl 30)) xor ((c shr 13) or (c shl 19)) xor ((c shr 22) xor (c shl 10))) + ((c and d) xor (c and e) xor (d and e)); b:= t1 + t2; f:= f + t1; t1:= a + (((f shr 6) or (f shl 26)) xor ((f shr 11) or (f shl 21)) xor ((f shr 25) or (f shl 7))) + ((f and g) xor (not f and h)) + $14292967 + W[31]; t2:= (((b shr 2) or (b shl 30)) xor ((b shr 13) or (b shl 19)) xor ((b shr 22) xor (b shl 10))) + ((b and c) xor (b and d) xor (c and d)); a:= t1 + t2; e:= e + t1; t1:= h + (((e shr 6) or (e shl 26)) xor ((e shr 11) or (e shl 21)) xor ((e shr 25) or (e shl 7))) + ((e and f) xor (not e and g)) + $27b70a85 + W[32]; t2:= (((a shr 2) or (a shl 30)) xor ((a shr 13) or (a shl 19)) xor ((a shr 22) xor (a shl 10))) + ((a and b) xor (a and c) xor (b and c)); h:= t1 + t2; d:= d + t1; t1:= g + (((d shr 6) or (d shl 26)) xor ((d shr 11) or (d shl 21)) xor ((d shr 25) or (d shl 7))) + ((d and e) xor (not d and f)) + $2e1b2138 + W[33]; t2:= (((h shr 2) or (h shl 30)) xor ((h shr 13) or (h shl 19)) xor ((h shr 22) xor (h shl 10))) + ((h and a) xor (h and b) xor (a and b)); g:= t1 + t2; c:= c + t1; t1:= f + (((c shr 6) or (c shl 26)) xor ((c shr 11) or (c shl 21)) xor ((c shr 25) or (c shl 7))) + ((c and d) xor (not c and e)) + $4d2c6dfc + W[34]; t2:= (((g shr 2) or (g shl 30)) xor ((g shr 13) or (g shl 19)) xor ((g shr 22) xor (g shl 10))) + ((g and h) xor (g and a) xor (h and a)); f:= t1 + t2; b:= b + t1; t1:= e + (((b shr 6) or (b shl 26)) xor ((b shr 11) or (b shl 21)) xor ((b shr 25) or (b shl 7))) + ((b and c) xor (not b and d)) + $53380d13 + W[35]; t2:= (((f shr 2) or (f shl 30)) xor ((f shr 13) or (f shl 19)) xor ((f shr 22) xor (f shl 10))) + ((f and g) xor (f and h) xor (g and h)); e:= t1 + t2; a:= a + t1; t1:= d + (((a shr 6) or (a shl 26)) xor ((a shr 11) or (a shl 21)) xor ((a shr 25) or (a shl 7))) + ((a and b) xor (not a and c)) + $650a7354 + W[36]; t2:= (((e shr 2) or (e shl 30)) xor ((e shr 13) or (e shl 19)) xor ((e shr 22) xor (e shl 10))) + ((e and f) xor (e and g) xor (f and g)); d:= t1 + t2; h:= h + t1; t1:= c + (((h shr 6) or (h shl 26)) xor ((h shr 11) or (h shl 21)) xor ((h shr 25) or (h shl 7))) + ((h and a) xor (not h and b)) + $766a0abb + W[37]; t2:= (((d shr 2) or (d shl 30)) xor ((d shr 13) or (d shl 19)) xor ((d shr 22) xor (d shl 10))) + ((d and e) xor (d and f) xor (e and f)); c:= t1 + t2; g:= g + t1; t1:= b + (((g shr 6) or (g shl 26)) xor ((g shr 11) or (g shl 21)) xor ((g shr 25) or (g shl 7))) + ((g and h) xor (not g and a)) + $81c2c92e + W[38]; t2:= (((c shr 2) or (c shl 30)) xor ((c shr 13) or (c shl 19)) xor ((c shr 22) xor (c shl 10))) + ((c and d) xor (c and e) xor (d and e)); b:= t1 + t2; f:= f + t1; t1:= a + (((f shr 6) or (f shl 26)) xor ((f shr 11) or (f shl 21)) xor ((f shr 25) or (f shl 7))) + ((f and g) xor (not f and h)) + $92722c85 + W[39]; t2:= (((b shr 2) or (b shl 30)) xor ((b shr 13) or (b shl 19)) xor ((b shr 22) xor (b shl 10))) + ((b and c) xor (b and d) xor (c and d)); a:= t1 + t2; e:= e + t1; t1:= h + (((e shr 6) or (e shl 26)) xor ((e shr 11) or (e shl 21)) xor ((e shr 25) or (e shl 7))) + ((e and f) xor (not e and g)) + $a2bfe8a1 + W[40]; t2:= (((a shr 2) or (a shl 30)) xor ((a shr 13) or (a shl 19)) xor ((a shr 22) xor (a shl 10))) + ((a and b) xor (a and c) xor (b and c)); h:= t1 + t2; d:= d + t1; t1:= g + (((d shr 6) or (d shl 26)) xor ((d shr 11) or (d shl 21)) xor ((d shr 25) or (d shl 7))) + ((d and e) xor (not d and f)) + $a81a664b + W[41]; t2:= (((h shr 2) or (h shl 30)) xor ((h shr 13) or (h shl 19)) xor ((h shr 22) xor (h shl 10))) + ((h and a) xor (h and b) xor (a and b)); g:= t1 + t2; c:= c + t1; t1:= f + (((c shr 6) or (c shl 26)) xor ((c shr 11) or (c shl 21)) xor ((c shr 25) or (c shl 7))) + ((c and d) xor (not c and e)) + $c24b8b70 + W[42]; t2:= (((g shr 2) or (g shl 30)) xor ((g shr 13) or (g shl 19)) xor ((g shr 22) xor (g shl 10))) + ((g and h) xor (g and a) xor (h and a)); f:= t1 + t2; b:= b + t1; t1:= e + (((b shr 6) or (b shl 26)) xor ((b shr 11) or (b shl 21)) xor ((b shr 25) or (b shl 7))) + ((b and c) xor (not b and d)) + $c76c51a3 + W[43]; t2:= (((f shr 2) or (f shl 30)) xor ((f shr 13) or (f shl 19)) xor ((f shr 22) xor (f shl 10))) + ((f and g) xor (f and h) xor (g and h)); e:= t1 + t2; a:= a + t1; t1:= d + (((a shr 6) or (a shl 26)) xor ((a shr 11) or (a shl 21)) xor ((a shr 25) or (a shl 7))) + ((a and b) xor (not a and c)) + $d192e819 + W[44]; t2:= (((e shr 2) or (e shl 30)) xor ((e shr 13) or (e shl 19)) xor ((e shr 22) xor (e shl 10))) + ((e and f) xor (e and g) xor (f and g)); d:= t1 + t2; h:= h + t1; t1:= c + (((h shr 6) or (h shl 26)) xor ((h shr 11) or (h shl 21)) xor ((h shr 25) or (h shl 7))) + ((h and a) xor (not h and b)) + $d6990624 + W[45]; t2:= (((d shr 2) or (d shl 30)) xor ((d shr 13) or (d shl 19)) xor ((d shr 22) xor (d shl 10))) + ((d and e) xor (d and f) xor (e and f)); c:= t1 + t2; g:= g + t1; t1:= b + (((g shr 6) or (g shl 26)) xor ((g shr 11) or (g shl 21)) xor ((g shr 25) or (g shl 7))) + ((g and h) xor (not g and a)) + $f40e3585 + W[46]; t2:= (((c shr 2) or (c shl 30)) xor ((c shr 13) or (c shl 19)) xor ((c shr 22) xor (c shl 10))) + ((c and d) xor (c and e) xor (d and e)); b:= t1 + t2; f:= f + t1; t1:= a + (((f shr 6) or (f shl 26)) xor ((f shr 11) or (f shl 21)) xor ((f shr 25) or (f shl 7))) + ((f and g) xor (not f and h)) + $106aa070 + W[47]; t2:= (((b shr 2) or (b shl 30)) xor ((b shr 13) or (b shl 19)) xor ((b shr 22) xor (b shl 10))) + ((b and c) xor (b and d) xor (c and d)); a:= t1 + t2; e:= e + t1; t1:= h + (((e shr 6) or (e shl 26)) xor ((e shr 11) or (e shl 21)) xor ((e shr 25) or (e shl 7))) + ((e and f) xor (not e and g)) + $19a4c116 + W[48]; t2:= (((a shr 2) or (a shl 30)) xor ((a shr 13) or (a shl 19)) xor ((a shr 22) xor (a shl 10))) + ((a and b) xor (a and c) xor (b and c)); h:= t1 + t2; d:= d + t1; t1:= g + (((d shr 6) or (d shl 26)) xor ((d shr 11) or (d shl 21)) xor ((d shr 25) or (d shl 7))) + ((d and e) xor (not d and f)) + $1e376c08 + W[49]; t2:= (((h shr 2) or (h shl 30)) xor ((h shr 13) or (h shl 19)) xor ((h shr 22) xor (h shl 10))) + ((h and a) xor (h and b) xor (a and b)); g:= t1 + t2; c:= c + t1; t1:= f + (((c shr 6) or (c shl 26)) xor ((c shr 11) or (c shl 21)) xor ((c shr 25) or (c shl 7))) + ((c and d) xor (not c and e)) + $2748774c + W[50]; t2:= (((g shr 2) or (g shl 30)) xor ((g shr 13) or (g shl 19)) xor ((g shr 22) xor (g shl 10))) + ((g and h) xor (g and a) xor (h and a)); f:= t1 + t2; b:= b + t1; t1:= e + (((b shr 6) or (b shl 26)) xor ((b shr 11) or (b shl 21)) xor ((b shr 25) or (b shl 7))) + ((b and c) xor (not b and d)) + $34b0bcb5 + W[51]; t2:= (((f shr 2) or (f shl 30)) xor ((f shr 13) or (f shl 19)) xor ((f shr 22) xor (f shl 10))) + ((f and g) xor (f and h) xor (g and h)); e:= t1 + t2; a:= a + t1; t1:= d + (((a shr 6) or (a shl 26)) xor ((a shr 11) or (a shl 21)) xor ((a shr 25) or (a shl 7))) + ((a and b) xor (not a and c)) + $391c0cb3 + W[52]; t2:= (((e shr 2) or (e shl 30)) xor ((e shr 13) or (e shl 19)) xor ((e shr 22) xor (e shl 10))) + ((e and f) xor (e and g) xor (f and g)); d:= t1 + t2; h:= h + t1; t1:= c + (((h shr 6) or (h shl 26)) xor ((h shr 11) or (h shl 21)) xor ((h shr 25) or (h shl 7))) + ((h and a) xor (not h and b)) + $4ed8aa4a + W[53]; t2:= (((d shr 2) or (d shl 30)) xor ((d shr 13) or (d shl 19)) xor ((d shr 22) xor (d shl 10))) + ((d and e) xor (d and f) xor (e and f)); c:= t1 + t2; g:= g + t1; t1:= b + (((g shr 6) or (g shl 26)) xor ((g shr 11) or (g shl 21)) xor ((g shr 25) or (g shl 7))) + ((g and h) xor (not g and a)) + $5b9cca4f + W[54]; t2:= (((c shr 2) or (c shl 30)) xor ((c shr 13) or (c shl 19)) xor ((c shr 22) xor (c shl 10))) + ((c and d) xor (c and e) xor (d and e)); b:= t1 + t2; f:= f + t1; t1:= a + (((f shr 6) or (f shl 26)) xor ((f shr 11) or (f shl 21)) xor ((f shr 25) or (f shl 7))) + ((f and g) xor (not f and h)) + $682e6ff3 + W[55]; t2:= (((b shr 2) or (b shl 30)) xor ((b shr 13) or (b shl 19)) xor ((b shr 22) xor (b shl 10))) + ((b and c) xor (b and d) xor (c and d)); a:= t1 + t2; e:= e + t1; t1:= h + (((e shr 6) or (e shl 26)) xor ((e shr 11) or (e shl 21)) xor ((e shr 25) or (e shl 7))) + ((e and f) xor (not e and g)) + $748f82ee + W[56]; t2:= (((a shr 2) or (a shl 30)) xor ((a shr 13) or (a shl 19)) xor ((a shr 22) xor (a shl 10))) + ((a and b) xor (a and c) xor (b and c)); h:= t1 + t2; d:= d + t1; t1:= g + (((d shr 6) or (d shl 26)) xor ((d shr 11) or (d shl 21)) xor ((d shr 25) or (d shl 7))) + ((d and e) xor (not d and f)) + $78a5636f + W[57]; t2:= (((h shr 2) or (h shl 30)) xor ((h shr 13) or (h shl 19)) xor ((h shr 22) xor (h shl 10))) + ((h and a) xor (h and b) xor (a and b)); g:= t1 + t2; c:= c + t1; t1:= f + (((c shr 6) or (c shl 26)) xor ((c shr 11) or (c shl 21)) xor ((c shr 25) or (c shl 7))) + ((c and d) xor (not c and e)) + $84c87814 + W[58]; t2:= (((g shr 2) or (g shl 30)) xor ((g shr 13) or (g shl 19)) xor ((g shr 22) xor (g shl 10))) + ((g and h) xor (g and a) xor (h and a)); f:= t1 + t2; b:= b + t1; t1:= e + (((b shr 6) or (b shl 26)) xor ((b shr 11) or (b shl 21)) xor ((b shr 25) or (b shl 7))) + ((b and c) xor (not b and d)) + $8cc70208 + W[59]; t2:= (((f shr 2) or (f shl 30)) xor ((f shr 13) or (f shl 19)) xor ((f shr 22) xor (f shl 10))) + ((f and g) xor (f and h) xor (g and h)); e:= t1 + t2; a:= a + t1; t1:= d + (((a shr 6) or (a shl 26)) xor ((a shr 11) or (a shl 21)) xor ((a shr 25) or (a shl 7))) + ((a and b) xor (not a and c)) + $90befffa + W[60]; t2:= (((e shr 2) or (e shl 30)) xor ((e shr 13) or (e shl 19)) xor ((e shr 22) xor (e shl 10))) + ((e and f) xor (e and g) xor (f and g)); d:= t1 + t2; h:= h + t1; t1:= c + (((h shr 6) or (h shl 26)) xor ((h shr 11) or (h shl 21)) xor ((h shr 25) or (h shl 7))) + ((h and a) xor (not h and b)) + $a4506ceb + W[61]; t2:= (((d shr 2) or (d shl 30)) xor ((d shr 13) or (d shl 19)) xor ((d shr 22) xor (d shl 10))) + ((d and e) xor (d and f) xor (e and f)); c:= t1 + t2; g:= g + t1; t1:= b + (((g shr 6) or (g shl 26)) xor ((g shr 11) or (g shl 21)) xor ((g shr 25) or (g shl 7))) + ((g and h) xor (not g and a)) + $bef9a3f7 + W[62]; t2:= (((c shr 2) or (c shl 30)) xor ((c shr 13) or (c shl 19)) xor ((c shr 22) xor (c shl 10))) + ((c and d) xor (c and e) xor (d and e)); b:= t1 + t2; f:= f + t1; t1:= a + (((f shr 6) or (f shl 26)) xor ((f shr 11) or (f shl 21)) xor ((f shr 25) or (f shl 7))) + ((f and g) xor (not f and h)) + $c67178f2 + W[63]; t2:= (((b shr 2) or (b shl 30)) xor ((b shr 13) or (b shl 19)) xor ((b shr 22) xor (b shl 10))) + ((b and c) xor (b and d) xor (c and d)); a:= t1 + t2; e:= e + t1; CurrentHash[0]:= CurrentHash[0] + a; CurrentHash[1]:= CurrentHash[1] + b; CurrentHash[2]:= CurrentHash[2] + c; CurrentHash[3]:= CurrentHash[3] + d; CurrentHash[4]:= CurrentHash[4] + e; CurrentHash[5]:= CurrentHash[5] + f; CurrentHash[6]:= CurrentHash[6] + g; CurrentHash[7]:= CurrentHash[7] + h; FillChar(W,Sizeof(W),0); FillChar(HashBuffer,Sizeof(HashBuffer),0); end; class function TDCP_sha256.GetAlgorithm: string; begin Result:= 'SHA256'; end; class function TDCP_sha256.GetId: integer; begin Result:= DCP_sha256; end; class function TDCP_sha256.GetHashSize: integer; begin Result:= 256; end; class function TDCP_sha256.SelfTest: boolean; const Test1Out: array[0..31] of byte= ($ba,$78,$16,$bf,$8f,$01,$cf,$ea,$41,$41,$40,$de,$5d,$ae,$22,$23, $b0,$03,$61,$a3,$96,$17,$7a,$9c,$b4,$10,$ff,$61,$f2,$00,$15,$ad); Test2Out: array[0..31] of byte= ($24,$8d,$6a,$61,$d2,$06,$38,$b8,$e5,$c0,$26,$93,$0c,$3e,$60,$39, $a3,$3c,$e4,$59,$64,$ff,$21,$67,$f6,$ec,$ed,$d4,$19,$db,$06,$c1); var TestHash: TDCP_sha256; TestOut: array[0..31] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_sha256.Create(nil); TestHash.Init; TestHash.UpdateStr('abc'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out))); TestHash.Init; TestHash.UpdateStr('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out))) and Result; TestHash.Free; end; procedure TDCP_sha256.Init; begin Burn; CurrentHash[0]:= $6a09e667; CurrentHash[1]:= $bb67ae85; CurrentHash[2]:= $3c6ef372; CurrentHash[3]:= $a54ff53a; CurrentHash[4]:= $510e527f; CurrentHash[5]:= $9b05688c; CurrentHash[6]:= $1f83d9ab; CurrentHash[7]:= $5be0cd19; fInitialized:= true; end; procedure TDCP_sha256.Burn; begin LenHi:= 0; LenLo:= 0; Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); FillChar(CurrentHash,Sizeof(CurrentHash),0); fInitialized:= false; end; procedure TDCP_sha256.Update(const Buffer; Size: longword); var PBuf: ^byte; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); Inc(LenHi,Size shr 29); Inc(LenLo,Size*8); if LenLo< (Size*8) then Inc(LenHi); PBuf:= @Buffer; while Size> 0 do begin if (Sizeof(HashBuffer)-Index)<= DWord(Size) then begin Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index); Dec(Size,Sizeof(HashBuffer)-Index); Inc(PBuf,Sizeof(HashBuffer)-Index); Compress; end else begin Move(PBuf^,HashBuffer[Index],Size); Inc(Index,Size); Size:= 0; end; end; end; procedure TDCP_sha256.Final(var Digest); begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); HashBuffer[Index]:= $80; if Index>= 56 then Compress; PDWord(@HashBuffer[56])^:= SwapDWord(LenHi); PDWord(@HashBuffer[60])^:= SwapDWord(LenLo); Compress; CurrentHash[0]:= SwapDWord(CurrentHash[0]); CurrentHash[1]:= SwapDWord(CurrentHash[1]); CurrentHash[2]:= SwapDWord(CurrentHash[2]); CurrentHash[3]:= SwapDWord(CurrentHash[3]); CurrentHash[4]:= SwapDWord(CurrentHash[4]); CurrentHash[5]:= SwapDWord(CurrentHash[5]); CurrentHash[6]:= SwapDWord(CurrentHash[6]); CurrentHash[7]:= SwapDWord(CurrentHash[7]); Move(CurrentHash,Digest,Sizeof(CurrentHash)); Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dcpblake2.pas0000664000175000017500000001614012573066072022303 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of BLAKE2S and BLAKE2SP *****************} {******************************************************************************} {* Copyright (C) 2014-2015 Alexander Koblov (alexx2000@mail.ru) *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPblake2; {$mode delphi} interface uses Classes, SysUtils, CTypes, DCPcrypt2, DCPconst, DCblake2; type { TDCP_blake2s } TDCP_blake2s = class(TDCP_hash) protected S: blake2s_state; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; procedure Final(var Digest); override; end; { TDCP_blake2sp } TDCP_blake2sp = class(TDCP_hash) protected S: blake2sp_state; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; procedure Final(var Digest); override; end; implementation { TDCP_blake2s } class function TDCP_blake2s.GetId: integer; begin Result:= DCP_blake2s; end; class function TDCP_blake2s.GetAlgorithm: string; begin Result:= 'BLAKE2S'; end; class function TDCP_blake2s.GetHashSize: integer; begin Result:= 256; end; class function TDCP_blake2s.SelfTest: boolean; const Test1Out: array[0..31] of byte= ($50, $8c, $5e, $8c, $32, $7c, $14, $e2, $e1, $a7, $2b, $a3, $4e, $eb, $45, $2f, $37, $45, $8b, $20, $9e, $d6, $3a, $29, $4d, $99, $9b, $4c, $86, $67, $59, $82); Test2Out: array[0..31] of byte= ($6f, $4d, $f5, $11, $6a, $6f, $33, $2e, $da, $b1, $d9, $e1, $0e, $e8, $7d, $f6, $55, $7b, $ea, $b6, $25, $9d, $76, $63, $f3, $bc, $d5, $72, $2c, $13, $f1, $89 ); var TestHash: TDCP_blake2s; TestOut: array[0..31] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_blake2s.Create(nil); TestHash.Init; TestHash.UpdateStr('abc'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out))); TestHash.Init; TestHash.UpdateStr('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out))) and Result; TestHash.Free; end; procedure TDCP_blake2s.Init; begin if blake2s_init( @S, BLAKE2S_OUTBYTES ) < 0 then raise EDCP_hash.Create('blake2s_init'); fInitialized:= true; end; procedure TDCP_blake2s.Burn; begin fInitialized:= false; end; procedure TDCP_blake2s.Update(const Buffer; Size: longword); var Bytes: PByte; begin Bytes:= @Buffer; if blake2s_update(@S, Bytes, Size) < 0 then raise EDCP_hash.Create('blake2s_update'); end; procedure TDCP_blake2s.Final(var Digest); var Hash: array[0..Pred(BLAKE2S_OUTBYTES)] of cuint8; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); if blake2s_final(@S, Hash, SizeOf(Hash)) < 0 then raise EDCP_hash.Create('blake2s_final'); Move(Hash, Digest, Sizeof(Hash)); Burn; end; { TDCP_blake2sp } class function TDCP_blake2sp.GetId: integer; begin Result:= DCP_blake2sp; end; class function TDCP_blake2sp.GetAlgorithm: string; begin Result:= 'BLAKE2SP'; end; class function TDCP_blake2sp.GetHashSize: integer; begin Result:= 256; end; class function TDCP_blake2sp.SelfTest: boolean; const Test1Out: array[0..31] of byte= ($70, $f7, $5b, $58, $f1, $fe, $ca, $b8, $21, $db, $43, $c8, $8a, $d8, $4e, $dd, $e5, $a5, $26, $00, $61, $6c, $d2, $25, $17, $b7, $bb, $14, $d4, $40, $a7, $d5); Test2Out: array[0..31] of byte= ($3d, $10, $7e, $42, $f1, $7c, $13, $c8, $2b, $43, $6e, $bb, $65, $1a, $48, $de, $f6, $7e, $77, $72, $fa, $06, $f4, $73, $8e, $e9, $68, $c7, $f4, $d8, $b4, $8b); var TestHash: TDCP_blake2sp; TestOut: array[0..31] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_blake2sp.Create(nil); TestHash.Init; TestHash.UpdateStr('abc'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out))); TestHash.Init; TestHash.UpdateStr('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out))) and Result; TestHash.Free; end; procedure TDCP_blake2sp.Init; begin if blake2sp_init( @S, BLAKE2S_OUTBYTES ) < 0 then raise EDCP_hash.Create('blake2sp_init'); fInitialized:= true; end; procedure TDCP_blake2sp.Burn; begin fInitialized:= false; end; procedure TDCP_blake2sp.Update(const Buffer; Size: longword); var Bytes: PByte; begin Bytes:= @Buffer; if blake2sp_update(@S, Bytes, Size) < 0 then raise EDCP_hash.Create('blake2sp_update'); end; procedure TDCP_blake2sp.Final(var Digest); var Hash: array[0..Pred(BLAKE2S_OUTBYTES)] of cuint8; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); if blake2sp_final(@S, Hash, SizeOf(Hash)) < 0 then raise EDCP_hash.Create('blake2sp_final'); Move(Hash, Digest, Sizeof(Hash)); Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/DCPtiger.inc0000664000175000017500000005522112014201074022065 0ustar alexxalexxconst t1: array[0..255] of int64= ( $02AAB17CF7E90C5E, $AC424B03E243A8EC, $72CD5BE30DD5FCD3, $6D019B93F6F97F3A, $CD9978FFD21F9193, $7573A1C9708029E2, $B164326B922A83C3, $46883EEE04915870, $EAACE3057103ECE6, $C54169B808A3535C, $4CE754918DDEC47C, $0AA2F4DFDC0DF40C, $10B76F18A74DBEFA, $C6CCB6235AD1AB6A, $13726121572FE2FF, $1A488C6F199D921E, $4BC9F9F4DA0007CA, $26F5E6F6E85241C7, $859079DBEA5947B6, $4F1885C5C99E8C92, $D78E761EA96F864B, $8E36428C52B5C17D, $69CF6827373063C1, $B607C93D9BB4C56E, $7D820E760E76B5EA, $645C9CC6F07FDC42, $BF38A078243342E0, $5F6B343C9D2E7D04, $F2C28AEB600B0EC6, $6C0ED85F7254BCAC, $71592281A4DB4FE5, $1967FA69CE0FED9F, $FD5293F8B96545DB, $C879E9D7F2A7600B, $860248920193194E, $A4F9533B2D9CC0B3, $9053836C15957613, $DB6DCF8AFC357BF1, $18BEEA7A7A370F57, $037117CA50B99066, $6AB30A9774424A35, $F4E92F02E325249B, $7739DB07061CCAE1, $D8F3B49CECA42A05, $BD56BE3F51382F73, $45FAED5843B0BB28, $1C813D5C11BF1F83, $8AF0E4B6D75FA169, $33EE18A487AD9999, $3C26E8EAB1C94410, $B510102BC0A822F9, $141EEF310CE6123B, $FC65B90059DDB154, $E0158640C5E0E607, $884E079826C3A3CF, $930D0D9523C535FD, $35638D754E9A2B00, $4085FCCF40469DD5, $C4B17AD28BE23A4C, $CAB2F0FC6A3E6A2E, $2860971A6B943FCD, $3DDE6EE212E30446, $6222F32AE01765AE, $5D550BB5478308FE, $A9EFA98DA0EDA22A, $C351A71686C40DA7, $1105586D9C867C84, $DCFFEE85FDA22853, $CCFBD0262C5EEF76, $BAF294CB8990D201, $E69464F52AFAD975, $94B013AFDF133E14, $06A7D1A32823C958, $6F95FE5130F61119, $D92AB34E462C06C0, $ED7BDE33887C71D2, $79746D6E6518393E, $5BA419385D713329, $7C1BA6B948A97564, $31987C197BFDAC67, $DE6C23C44B053D02, $581C49FED002D64D, $DD474D6338261571, $AA4546C3E473D062, $928FCE349455F860, $48161BBACAAB94D9, $63912430770E6F68, $6EC8A5E602C6641C, $87282515337DDD2B, $2CDA6B42034B701B, $B03D37C181CB096D, $E108438266C71C6F, $2B3180C7EB51B255, $DF92B82F96C08BBC, $5C68C8C0A632F3BA, $5504CC861C3D0556, $ABBFA4E55FB26B8F, $41848B0AB3BACEB4, $B334A273AA445D32, $BCA696F0A85AD881, $24F6EC65B528D56C, $0CE1512E90F4524A, $4E9DD79D5506D35A, $258905FAC6CE9779, $2019295B3E109B33, $F8A9478B73A054CC, $2924F2F934417EB0, $3993357D536D1BC4, $38A81AC21DB6FF8B, $47C4FBF17D6016BF, $1E0FAADD7667E3F5, $7ABCFF62938BEB96, $A78DAD948FC179C9, $8F1F98B72911E50D, $61E48EAE27121A91, $4D62F7AD31859808, $ECEBA345EF5CEAEB, $F5CEB25EBC9684CE, $F633E20CB7F76221, $A32CDF06AB8293E4, $985A202CA5EE2CA4, $CF0B8447CC8A8FB1, $9F765244979859A3, $A8D516B1A1240017, $0BD7BA3EBB5DC726, $E54BCA55B86ADB39, $1D7A3AFD6C478063, $519EC608E7669EDD, $0E5715A2D149AA23, $177D4571848FF194, $EEB55F3241014C22, $0F5E5CA13A6E2EC2, $8029927B75F5C361, $AD139FABC3D6E436, $0D5DF1A94CCF402F, $3E8BD948BEA5DFC8, $A5A0D357BD3FF77E, $A2D12E251F74F645, $66FD9E525E81A082, $2E0C90CE7F687A49, $C2E8BCBEBA973BC5, $000001BCE509745F, $423777BBE6DAB3D6, $D1661C7EAEF06EB5, $A1781F354DAACFD8, $2D11284A2B16AFFC, $F1FC4F67FA891D1F, $73ECC25DCB920ADA, $AE610C22C2A12651, $96E0A810D356B78A, $5A9A381F2FE7870F, $D5AD62EDE94E5530, $D225E5E8368D1427, $65977B70C7AF4631, $99F889B2DE39D74F, $233F30BF54E1D143, $9A9675D3D9A63C97, $5470554FF334F9A8, $166ACB744A4F5688, $70C74CAAB2E4AEAD, $F0D091646F294D12, $57B82A89684031D1, $EFD95A5A61BE0B6B, $2FBD12E969F2F29A, $9BD37013FEFF9FE8, $3F9B0404D6085A06, $4940C1F3166CFE15, $09542C4DCDF3DEFB, $B4C5218385CD5CE3, $C935B7DC4462A641, $3417F8A68ED3B63F, $B80959295B215B40, $F99CDAEF3B8C8572, $018C0614F8FCB95D, $1B14ACCD1A3ACDF3, $84D471F200BB732D, $C1A3110E95E8DA16, $430A7220BF1A82B8, $B77E090D39DF210E, $5EF4BD9F3CD05E9D, $9D4FF6DA7E57A444, $DA1D60E183D4A5F8, $B287C38417998E47, $FE3EDC121BB31886, $C7FE3CCC980CCBEF, $E46FB590189BFD03, $3732FD469A4C57DC, $7EF700A07CF1AD65, $59C64468A31D8859, $762FB0B4D45B61F6, $155BAED099047718, $68755E4C3D50BAA6, $E9214E7F22D8B4DF, $2ADDBF532EAC95F4, $32AE3909B4BD0109, $834DF537B08E3450, $FA209DA84220728D, $9E691D9B9EFE23F7, $0446D288C4AE8D7F, $7B4CC524E169785B, $21D87F0135CA1385, $CEBB400F137B8AA5, $272E2B66580796BE, $3612264125C2B0DE, $057702BDAD1EFBB2, $D4BABB8EACF84BE9, $91583139641BC67B, $8BDC2DE08036E024, $603C8156F49F68ED, $F7D236F7DBEF5111, $9727C4598AD21E80, $A08A0896670A5FD7, $CB4A8F4309EBA9CB, $81AF564B0F7036A1, $C0B99AA778199ABD, $959F1EC83FC8E952, $8C505077794A81B9, $3ACAAF8F056338F0, $07B43F50627A6778, $4A44AB49F5ECCC77, $3BC3D6E4B679EE98, $9CC0D4D1CF14108C, $4406C00B206BC8A0, $82A18854C8D72D89, $67E366B35C3C432C, $B923DD61102B37F2, $56AB2779D884271D, $BE83E1B0FF1525AF, $FB7C65D4217E49A9, $6BDBE0E76D48E7D4, $08DF828745D9179E, $22EA6A9ADD53BD34, $E36E141C5622200A, $7F805D1B8CB750EE, $AFE5C7A59F58E837, $E27F996A4FB1C23C, $D3867DFB0775F0D0, $D0E673DE6E88891A, $123AEB9EAFB86C25, $30F1D5D5C145B895, $BB434A2DEE7269E7, $78CB67ECF931FA38, $F33B0372323BBF9C, $52D66336FB279C74, $505F33AC0AFB4EAA, $E8A5CD99A2CCE187, $534974801E2D30BB, $8D2D5711D5876D90, $1F1A412891BC038E, $D6E2E71D82E56648, $74036C3A497732B7, $89B67ED96361F5AB, $FFED95D8F1EA02A2, $E72B3BD61464D43D, $A6300F170BDC4820, $EBC18760ED78A77A); t2: array[0..255] of int64= ( $E6A6BE5A05A12138, $B5A122A5B4F87C98, $563C6089140B6990, $4C46CB2E391F5DD5, $D932ADDBC9B79434, $08EA70E42015AFF5, $D765A6673E478CF1, $C4FB757EAB278D99, $DF11C6862D6E0692, $DDEB84F10D7F3B16, $6F2EF604A665EA04, $4A8E0F0FF0E0DFB3, $A5EDEEF83DBCBA51, $FC4F0A2A0EA4371E, $E83E1DA85CB38429, $DC8FF882BA1B1CE2, $CD45505E8353E80D, $18D19A00D4DB0717, $34A0CFEDA5F38101, $0BE77E518887CAF2, $1E341438B3C45136, $E05797F49089CCF9, $FFD23F9DF2591D14, $543DDA228595C5CD, $661F81FD99052A33, $8736E641DB0F7B76, $15227725418E5307, $E25F7F46162EB2FA, $48A8B2126C13D9FE, $AFDC541792E76EEA, $03D912BFC6D1898F, $31B1AAFA1B83F51B, $F1AC2796E42AB7D9, $40A3A7D7FCD2EBAC, $1056136D0AFBBCC5, $7889E1DD9A6D0C85, $D33525782A7974AA, $A7E25D09078AC09B, $BD4138B3EAC6EDD0, $920ABFBE71EB9E70, $A2A5D0F54FC2625C, $C054E36B0B1290A3, $F6DD59FF62FE932B, $3537354511A8AC7D, $CA845E9172FADCD4, $84F82B60329D20DC, $79C62CE1CD672F18, $8B09A2ADD124642C, $D0C1E96A19D9E726, $5A786A9B4BA9500C, $0E020336634C43F3, $C17B474AEB66D822, $6A731AE3EC9BAAC2, $8226667AE0840258, $67D4567691CAECA5, $1D94155C4875ADB5, $6D00FD985B813FDF, $51286EFCB774CD06, $5E8834471FA744AF, $F72CA0AEE761AE2E, $BE40E4CDAEE8E09A, $E9970BBB5118F665, $726E4BEB33DF1964, $703B000729199762, $4631D816F5EF30A7, $B880B5B51504A6BE, $641793C37ED84B6C, $7B21ED77F6E97D96, $776306312EF96B73, $AE528948E86FF3F4, $53DBD7F286A3F8F8, $16CADCE74CFC1063, $005C19BDFA52C6DD, $68868F5D64D46AD3, $3A9D512CCF1E186A, $367E62C2385660AE, $E359E7EA77DCB1D7, $526C0773749ABE6E, $735AE5F9D09F734B, $493FC7CC8A558BA8, $B0B9C1533041AB45, $321958BA470A59BD, $852DB00B5F46C393, $91209B2BD336B0E5, $6E604F7D659EF19F, $B99A8AE2782CCB24, $CCF52AB6C814C4C7, $4727D9AFBE11727B, $7E950D0C0121B34D, $756F435670AD471F, $F5ADD442615A6849, $4E87E09980B9957A, $2ACFA1DF50AEE355, $D898263AFD2FD556, $C8F4924DD80C8FD6, $CF99CA3D754A173A, $FE477BACAF91BF3C, $ED5371F6D690C12D, $831A5C285E687094, $C5D3C90A3708A0A4, $0F7F903717D06580, $19F9BB13B8FDF27F, $B1BD6F1B4D502843, $1C761BA38FFF4012, $0D1530C4E2E21F3B, $8943CE69A7372C8A, $E5184E11FEB5CE66, $618BDB80BD736621, $7D29BAD68B574D0B, $81BB613E25E6FE5B, $071C9C10BC07913F, $C7BEEB7909AC2D97, $C3E58D353BC5D757, $EB017892F38F61E8, $D4EFFB9C9B1CC21A, $99727D26F494F7AB, $A3E063A2956B3E03, $9D4A8B9A4AA09C30, $3F6AB7D500090FB4, $9CC0F2A057268AC0, $3DEE9D2DEDBF42D1, $330F49C87960A972, $C6B2720287421B41, $0AC59EC07C00369C, $EF4EAC49CB353425, $F450244EEF0129D8, $8ACC46E5CAF4DEB6, $2FFEAB63989263F7, $8F7CB9FE5D7A4578, $5BD8F7644E634635, $427A7315BF2DC900, $17D0C4AA2125261C, $3992486C93518E50, $B4CBFEE0A2D7D4C3, $7C75D6202C5DDD8D, $DBC295D8E35B6C61, $60B369D302032B19, $CE42685FDCE44132, $06F3DDB9DDF65610, $8EA4D21DB5E148F0, $20B0FCE62FCD496F, $2C1B912358B0EE31, $B28317B818F5A308, $A89C1E189CA6D2CF, $0C6B18576AAADBC8, $B65DEAA91299FAE3, $FB2B794B7F1027E7, $04E4317F443B5BEB, $4B852D325939D0A6, $D5AE6BEEFB207FFC, $309682B281C7D374, $BAE309A194C3B475, $8CC3F97B13B49F05, $98A9422FF8293967, $244B16B01076FF7C, $F8BF571C663D67EE, $1F0D6758EEE30DA1, $C9B611D97ADEB9B7, $B7AFD5887B6C57A2, $6290AE846B984FE1, $94DF4CDEACC1A5FD, $058A5BD1C5483AFF, $63166CC142BA3C37, $8DB8526EB2F76F40, $E10880036F0D6D4E, $9E0523C9971D311D, $45EC2824CC7CD691, $575B8359E62382C9, $FA9E400DC4889995, $D1823ECB45721568, $DAFD983B8206082F, $AA7D29082386A8CB, $269FCD4403B87588, $1B91F5F728BDD1E0, $E4669F39040201F6, $7A1D7C218CF04ADE, $65623C29D79CE5CE, $2368449096C00BB1, $AB9BF1879DA503BA, $BC23ECB1A458058E, $9A58DF01BB401ECC, $A070E868A85F143D, $4FF188307DF2239E, $14D565B41A641183, $EE13337452701602, $950E3DCF3F285E09, $59930254B9C80953, $3BF299408930DA6D, $A955943F53691387, $A15EDECAA9CB8784, $29142127352BE9A0, $76F0371FFF4E7AFB, $0239F450274F2228, $BB073AF01D5E868B, $BFC80571C10E96C1, $D267088568222E23, $9671A3D48E80B5B0, $55B5D38AE193BB81, $693AE2D0A18B04B8, $5C48B4ECADD5335F, $FD743B194916A1CA, $2577018134BE98C4, $E77987E83C54A4AD, $28E11014DA33E1B9, $270CC59E226AA213, $71495F756D1A5F60, $9BE853FB60AFEF77, $ADC786A7F7443DBF, $0904456173B29A82, $58BC7A66C232BD5E, $F306558C673AC8B2, $41F639C6B6C9772A, $216DEFE99FDA35DA, $11640CC71C7BE615, $93C43694565C5527, $EA038E6246777839, $F9ABF3CE5A3E2469, $741E768D0FD312D2, $0144B883CED652C6, $C20B5A5BA33F8552, $1AE69633C3435A9D, $97A28CA4088CFDEC, $8824A43C1E96F420, $37612FA66EEEA746, $6B4CB165F9CF0E5A, $43AA1C06A0ABFB4A, $7F4DC26FF162796B, $6CBACC8E54ED9B0F, $A6B7FFEFD2BB253E, $2E25BC95B0A29D4F, $86D6A58BDEF1388C, $DED74AC576B6F054, $8030BDBC2B45805D, $3C81AF70E94D9289, $3EFF6DDA9E3100DB, $B38DC39FDFCC8847, $123885528D17B87E, $F2DA0ED240B1B642, $44CEFADCD54BF9A9, $1312200E433C7EE6, $9FFCC84F3A78C748, $F0CD1F72248576BB, $EC6974053638CFE4, $2BA7B67C0CEC4E4C, $AC2F4DF3E5CE32ED, $CB33D14326EA4C11, $A4E9044CC77E58BC, $5F513293D934FCEF, $5DC9645506E55444, $50DE418F317DE40A, $388CB31A69DDE259, $2DB4A83455820A86, $9010A91E84711AE9, $4DF7F0B7B1498371, $D62A2EABC0977179, $22FAC097AA8D5C0E); t3: array[0..255] of int64= ( $F49FCC2FF1DAF39B, $487FD5C66FF29281, $E8A30667FCDCA83F, $2C9B4BE3D2FCCE63, $DA3FF74B93FBBBC2, $2FA165D2FE70BA66, $A103E279970E93D4, $BECDEC77B0E45E71, $CFB41E723985E497, $B70AAA025EF75017, $D42309F03840B8E0, $8EFC1AD035898579, $96C6920BE2B2ABC5, $66AF4163375A9172, $2174ABDCCA7127FB, $B33CCEA64A72FF41, $F04A4933083066A5, $8D970ACDD7289AF5, $8F96E8E031C8C25E, $F3FEC02276875D47, $EC7BF310056190DD, $F5ADB0AEBB0F1491, $9B50F8850FD58892, $4975488358B74DE8, $A3354FF691531C61, $0702BBE481D2C6EE, $89FB24057DEDED98, $AC3075138596E902, $1D2D3580172772ED, $EB738FC28E6BC30D, $5854EF8F63044326, $9E5C52325ADD3BBE, $90AA53CF325C4623, $C1D24D51349DD067, $2051CFEEA69EA624, $13220F0A862E7E4F, $CE39399404E04864, $D9C42CA47086FCB7, $685AD2238A03E7CC, $066484B2AB2FF1DB, $FE9D5D70EFBF79EC, $5B13B9DD9C481854, $15F0D475ED1509AD, $0BEBCD060EC79851, $D58C6791183AB7F8, $D1187C5052F3EEE4, $C95D1192E54E82FF, $86EEA14CB9AC6CA2, $3485BEB153677D5D, $DD191D781F8C492A, $F60866BAA784EBF9, $518F643BA2D08C74, $8852E956E1087C22, $A768CB8DC410AE8D, $38047726BFEC8E1A, $A67738B4CD3B45AA, $AD16691CEC0DDE19, $C6D4319380462E07, $C5A5876D0BA61938, $16B9FA1FA58FD840, $188AB1173CA74F18, $ABDA2F98C99C021F, $3E0580AB134AE816, $5F3B05B773645ABB, $2501A2BE5575F2F6, $1B2F74004E7E8BA9, $1CD7580371E8D953, $7F6ED89562764E30, $B15926FF596F003D, $9F65293DA8C5D6B9, $6ECEF04DD690F84C, $4782275FFF33AF88, $E41433083F820801, $FD0DFE409A1AF9B5, $4325A3342CDB396B, $8AE77E62B301B252, $C36F9E9F6655615A, $85455A2D92D32C09, $F2C7DEA949477485, $63CFB4C133A39EBA, $83B040CC6EBC5462, $3B9454C8FDB326B0, $56F56A9E87FFD78C, $2DC2940D99F42BC6, $98F7DF096B096E2D, $19A6E01E3AD852BF, $42A99CCBDBD4B40B, $A59998AF45E9C559, $366295E807D93186, $6B48181BFAA1F773, $1FEC57E2157A0A1D, $4667446AF6201AD5, $E615EBCACFB0F075, $B8F31F4F68290778, $22713ED6CE22D11E, $3057C1A72EC3C93B, $CB46ACC37C3F1F2F, $DBB893FD02AAF50E, $331FD92E600B9FCF, $A498F96148EA3AD6, $A8D8426E8B6A83EA, $A089B274B7735CDC, $87F6B3731E524A11, $118808E5CBC96749, $9906E4C7B19BD394, $AFED7F7E9B24A20C, $6509EADEEB3644A7, $6C1EF1D3E8EF0EDE, $B9C97D43E9798FB4, $A2F2D784740C28A3, $7B8496476197566F, $7A5BE3E6B65F069D, $F96330ED78BE6F10, $EEE60DE77A076A15, $2B4BEE4AA08B9BD0, $6A56A63EC7B8894E, $02121359BA34FEF4, $4CBF99F8283703FC, $398071350CAF30C8, $D0A77A89F017687A, $F1C1A9EB9E423569, $8C7976282DEE8199, $5D1737A5DD1F7ABD, $4F53433C09A9FA80, $FA8B0C53DF7CA1D9, $3FD9DCBC886CCB77, $C040917CA91B4720, $7DD00142F9D1DCDF, $8476FC1D4F387B58, $23F8E7C5F3316503, $032A2244E7E37339, $5C87A5D750F5A74B, $082B4CC43698992E, $DF917BECB858F63C, $3270B8FC5BF86DDA, $10AE72BB29B5DD76, $576AC94E7700362B, $1AD112DAC61EFB8F, $691BC30EC5FAA427, $FF246311CC327143, $3142368E30E53206, $71380E31E02CA396, $958D5C960AAD76F1, $F8D6F430C16DA536, $C8FFD13F1BE7E1D2, $7578AE66004DDBE1, $05833F01067BE646, $BB34B5AD3BFE586D, $095F34C9A12B97F0, $247AB64525D60CA8, $DCDBC6F3017477D1, $4A2E14D4DECAD24D, $BDB5E6D9BE0A1EEB, $2A7E70F7794301AB, $DEF42D8A270540FD, $01078EC0A34C22C1, $E5DE511AF4C16387, $7EBB3A52BD9A330A, $77697857AA7D6435, $004E831603AE4C32, $E7A21020AD78E312, $9D41A70C6AB420F2, $28E06C18EA1141E6, $D2B28CBD984F6B28, $26B75F6C446E9D83, $BA47568C4D418D7F, $D80BADBFE6183D8E, $0E206D7F5F166044, $E258A43911CBCA3E, $723A1746B21DC0BC, $C7CAA854F5D7CDD3, $7CAC32883D261D9C, $7690C26423BA942C, $17E55524478042B8, $E0BE477656A2389F, $4D289B5E67AB2DA0, $44862B9C8FBBFD31, $B47CC8049D141365, $822C1B362B91C793, $4EB14655FB13DFD8, $1ECBBA0714E2A97B, $6143459D5CDE5F14, $53A8FBF1D5F0AC89, $97EA04D81C5E5B00, $622181A8D4FDB3F3, $E9BCD341572A1208, $1411258643CCE58A, $9144C5FEA4C6E0A4, $0D33D06565CF620F, $54A48D489F219CA1, $C43E5EAC6D63C821, $A9728B3A72770DAF, $D7934E7B20DF87EF, $E35503B61A3E86E5, $CAE321FBC819D504, $129A50B3AC60BFA6, $CD5E68EA7E9FB6C3, $B01C90199483B1C7, $3DE93CD5C295376C, $AED52EDF2AB9AD13, $2E60F512C0A07884, $BC3D86A3E36210C9, $35269D9B163951CE, $0C7D6E2AD0CDB5FA, $59E86297D87F5733, $298EF221898DB0E7, $55000029D1A5AA7E, $8BC08AE1B5061B45, $C2C31C2B6C92703A, $94CC596BAF25EF42, $0A1D73DB22540456, $04B6A0F9D9C4179A, $EFFDAFA2AE3D3C60, $F7C8075BB49496C4, $9CC5C7141D1CD4E3, $78BD1638218E5534, $B2F11568F850246A, $EDFABCFA9502BC29, $796CE5F2DA23051B, $AAE128B0DC93537C, $3A493DA0EE4B29AE, $B5DF6B2C416895D7, $FCABBD25122D7F37, $70810B58105DC4B1, $E10FDD37F7882A90, $524DCAB5518A3F5C, $3C9E85878451255B, $4029828119BD34E2, $74A05B6F5D3CECCB, $B610021542E13ECA, $0FF979D12F59E2AC, $6037DA27E4F9CC50, $5E92975A0DF1847D, $D66DE190D3E623FE, $5032D6B87B568048, $9A36B7CE8235216E, $80272A7A24F64B4A, $93EFED8B8C6916F7, $37DDBFF44CCE1555, $4B95DB5D4B99BD25, $92D3FDA169812FC0, $FB1A4A9A90660BB6, $730C196946A4B9B2, $81E289AA7F49DA68, $64669A0F83B1A05F, $27B3FF7D9644F48B, $CC6B615C8DB675B3, $674F20B9BCEBBE95, $6F31238275655982, $5AE488713E45CF05, $BF619F9954C21157, $EABAC46040A8EAE9, $454C6FE9F2C0C1CD, $419CF6496412691C, $D3DC3BEF265B0F70, $6D0E60F5C3578A9E); t4: array[0..255] of int64= ( $5B0E608526323C55, $1A46C1A9FA1B59F5, $A9E245A17C4C8FFA, $65CA5159DB2955D7, $05DB0A76CE35AFC2, $81EAC77EA9113D45, $528EF88AB6AC0A0D, $A09EA253597BE3FF, $430DDFB3AC48CD56, $C4B3A67AF45CE46F, $4ECECFD8FBE2D05E, $3EF56F10B39935F0, $0B22D6829CD619C6, $17FD460A74DF2069, $6CF8CC8E8510ED40, $D6C824BF3A6ECAA7, $61243D581A817049, $048BACB6BBC163A2, $D9A38AC27D44CC32, $7FDDFF5BAAF410AB, $AD6D495AA804824B, $E1A6A74F2D8C9F94, $D4F7851235DEE8E3, $FD4B7F886540D893, $247C20042AA4BFDA, $096EA1C517D1327C, $D56966B4361A6685, $277DA5C31221057D, $94D59893A43ACFF7, $64F0C51CCDC02281, $3D33BCC4FF6189DB, $E005CB184CE66AF1, $FF5CCD1D1DB99BEA, $B0B854A7FE42980F, $7BD46A6A718D4B9F, $D10FA8CC22A5FD8C, $D31484952BE4BD31, $C7FA975FCB243847, $4886ED1E5846C407, $28CDDB791EB70B04, $C2B00BE2F573417F, $5C9590452180F877, $7A6BDDFFF370EB00, $CE509E38D6D9D6A4, $EBEB0F00647FA702, $1DCC06CF76606F06, $E4D9F28BA286FF0A, $D85A305DC918C262, $475B1D8732225F54, $2D4FB51668CCB5FE, $A679B9D9D72BBA20, $53841C0D912D43A5, $3B7EAA48BF12A4E8, $781E0E47F22F1DDF, $EFF20CE60AB50973, $20D261D19DFFB742, $16A12B03062A2E39, $1960EB2239650495, $251C16FED50EB8B8, $9AC0C330F826016E, $ED152665953E7671, $02D63194A6369570, $5074F08394B1C987, $70BA598C90B25CE1, $794A15810B9742F6, $0D5925E9FCAF8C6C, $3067716CD868744E, $910AB077E8D7731B, $6A61BBDB5AC42F61, $93513EFBF0851567, $F494724B9E83E9D5, $E887E1985C09648D, $34B1D3C675370CFD, $DC35E433BC0D255D, $D0AAB84234131BE0, $08042A50B48B7EAF, $9997C4EE44A3AB35, $829A7B49201799D0, $263B8307B7C54441, $752F95F4FD6A6CA6, $927217402C08C6E5, $2A8AB754A795D9EE, $A442F7552F72943D, $2C31334E19781208, $4FA98D7CEAEE6291, $55C3862F665DB309, $BD0610175D53B1F3, $46FE6CB840413F27, $3FE03792DF0CFA59, $CFE700372EB85E8F, $A7BE29E7ADBCE118, $E544EE5CDE8431DD, $8A781B1B41F1873E, $A5C94C78A0D2F0E7, $39412E2877B60728, $A1265EF3AFC9A62C, $BCC2770C6A2506C5, $3AB66DD5DCE1CE12, $E65499D04A675B37, $7D8F523481BFD216, $0F6F64FCEC15F389, $74EFBE618B5B13C8, $ACDC82B714273E1D, $DD40BFE003199D17, $37E99257E7E061F8, $FA52626904775AAA, $8BBBF63A463D56F9, $F0013F1543A26E64, $A8307E9F879EC898, $CC4C27A4150177CC, $1B432F2CCA1D3348, $DE1D1F8F9F6FA013, $606602A047A7DDD6, $D237AB64CC1CB2C7, $9B938E7225FCD1D3, $EC4E03708E0FF476, $FEB2FBDA3D03C12D, $AE0BCED2EE43889A, $22CB8923EBFB4F43, $69360D013CF7396D, $855E3602D2D4E022, $073805BAD01F784C, $33E17A133852F546, $DF4874058AC7B638, $BA92B29C678AA14A, $0CE89FC76CFAADCD, $5F9D4E0908339E34, $F1AFE9291F5923B9, $6E3480F60F4A265F, $EEBF3A2AB29B841C, $E21938A88F91B4AD, $57DFEFF845C6D3C3, $2F006B0BF62CAAF2, $62F479EF6F75EE78, $11A55AD41C8916A9, $F229D29084FED453, $42F1C27B16B000E6, $2B1F76749823C074, $4B76ECA3C2745360, $8C98F463B91691BD, $14BCC93CF1ADE66A, $8885213E6D458397, $8E177DF0274D4711, $B49B73B5503F2951, $10168168C3F96B6B, $0E3D963B63CAB0AE, $8DFC4B5655A1DB14, $F789F1356E14DE5C, $683E68AF4E51DAC1, $C9A84F9D8D4B0FD9, $3691E03F52A0F9D1, $5ED86E46E1878E80, $3C711A0E99D07150, $5A0865B20C4E9310, $56FBFC1FE4F0682E, $EA8D5DE3105EDF9B, $71ABFDB12379187A, $2EB99DE1BEE77B9C, $21ECC0EA33CF4523, $59A4D7521805C7A1, $3896F5EB56AE7C72, $AA638F3DB18F75DC, $9F39358DABE9808E, $B7DEFA91C00B72AC, $6B5541FD62492D92, $6DC6DEE8F92E4D5B, $353F57ABC4BEEA7E, $735769D6DA5690CE, $0A234AA642391484, $F6F9508028F80D9D, $B8E319A27AB3F215, $31AD9C1151341A4D, $773C22A57BEF5805, $45C7561A07968633, $F913DA9E249DBE36, $DA652D9B78A64C68, $4C27A97F3BC334EF, $76621220E66B17F4, $967743899ACD7D0B, $F3EE5BCAE0ED6782, $409F753600C879FC, $06D09A39B5926DB6, $6F83AEB0317AC588, $01E6CA4A86381F21, $66FF3462D19F3025, $72207C24DDFD3BFB, $4AF6B6D3E2ECE2EB, $9C994DBEC7EA08DE, $49ACE597B09A8BC4, $B38C4766CF0797BA, $131B9373C57C2A75, $B1822CCE61931E58, $9D7555B909BA1C0C, $127FAFDD937D11D2, $29DA3BADC66D92E4, $A2C1D57154C2ECBC, $58C5134D82F6FE24, $1C3AE3515B62274F, $E907C82E01CB8126, $F8ED091913E37FCB, $3249D8F9C80046C9, $80CF9BEDE388FB63, $1881539A116CF19E, $5103F3F76BD52457, $15B7E6F5AE47F7A8, $DBD7C6DED47E9CCF, $44E55C410228BB1A, $B647D4255EDB4E99, $5D11882BB8AAFC30, $F5098BBB29D3212A, $8FB5EA14E90296B3, $677B942157DD025A, $FB58E7C0A390ACB5, $89D3674C83BD4A01, $9E2DA4DF4BF3B93B, $FCC41E328CAB4829, $03F38C96BA582C52, $CAD1BDBD7FD85DB2, $BBB442C16082AE83, $B95FE86BA5DA9AB0, $B22E04673771A93F, $845358C9493152D8, $BE2A488697B4541E, $95A2DC2DD38E6966, $C02C11AC923C852B, $2388B1990DF2A87B, $7C8008FA1B4F37BE, $1F70D0C84D54E503, $5490ADEC7ECE57D4, $002B3C27D9063A3A, $7EAEA3848030A2BF, $C602326DED2003C0, $83A7287D69A94086, $C57A5FCB30F57A8A, $B56844E479EBE779, $A373B40F05DCBCE9, $D71A786E88570EE2, $879CBACDBDE8F6A0, $976AD1BCC164A32F, $AB21E25E9666D78B, $901063AAE5E5C33C, $9818B34448698D90, $E36487AE3E1E8ABB, $AFBDF931893BDCB4, $6345A0DC5FBBD519, $8628FE269B9465CA, $1E5D01603F9C51EC, $4DE44006A15049B7, $BF6C70E5F776CBB1, $411218F2EF552BED, $CB0C0708705A36A3, $E74D14754F986044, $CD56D9430EA8280E, $C12591D7535F5065, $C83223F1720AEF96, $C3A0396F7363A51F); doublecmd-0.8.2/components/dcpcrypt/Hashes/dcpripemd160.pas0000664000175000017500000007345012014201074022640 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of RipeMD-160 ***************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPripemd160; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2, DCPconst; type TDCP_ripemd160= class(TDCP_hash) protected LenHi, LenLo: longword; Index: DWord; CurrentHash: array[0..4] of DWord; HashBuffer: array[0..63] of byte; procedure Compress; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; procedure Final(var Digest); override; end; {******************************************************************************} {******************************************************************************} implementation {$R-}{$Q-} procedure TDCP_ripemd160.Compress; var aa, bb, cc, dd, ee, aaa, bbb, ccc, ddd, eee: DWord; X: array[0..15] of DWord; begin dcpFillChar(X, SizeOf(X), 0); Move(HashBuffer,X,Sizeof(X)); aa:= CurrentHash[0]; aaa:= CurrentHash[0]; bb:= CurrentHash[1]; bbb:= CurrentHash[1]; cc:= CurrentHash[2]; ccc:= CurrentHash[2]; dd:= CurrentHash[3]; ddd:= CurrentHash[3]; ee:= CurrentHash[4]; eee:= CurrentHash[4]; aa:= aa + (bb xor cc xor dd) + X[ 0]; aa:= ((aa shl 11) or (aa shr (32-11))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + (aa xor bb xor cc) + X[ 1]; ee:= ((ee shl 14) or (ee shr (32-14))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + (ee xor aa xor bb) + X[ 2]; dd:= ((dd shl 15) or (dd shr (32-15))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + (dd xor ee xor aa) + X[ 3]; cc:= ((cc shl 12) or (cc shr (32-12))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + (cc xor dd xor ee) + X[ 4]; bb:= ((bb shl 5) or (bb shr (32-5))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + (bb xor cc xor dd) + X[ 5]; aa:= ((aa shl 8) or (aa shr (32-8))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + (aa xor bb xor cc) + X[ 6]; ee:= ((ee shl 7) or (ee shr (32-7))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + (ee xor aa xor bb) + X[ 7]; dd:= ((dd shl 9) or (dd shr (32-9))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + (dd xor ee xor aa) + X[ 8]; cc:= ((cc shl 11) or (cc shr (32-11))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + (cc xor dd xor ee) + X[ 9]; bb:= ((bb shl 13) or (bb shr (32-13))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + (bb xor cc xor dd) + X[10]; aa:= ((aa shl 14) or (aa shr (32-14))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + (aa xor bb xor cc) + X[11]; ee:= ((ee shl 15) or (ee shr (32-15))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + (ee xor aa xor bb) + X[12]; dd:= ((dd shl 6) or (dd shr (32-6))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + (dd xor ee xor aa) + X[13]; cc:= ((cc shl 7) or (cc shr (32-7))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + (cc xor dd xor ee) + X[14]; bb:= ((bb shl 9) or (bb shr (32-9))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + (bb xor cc xor dd) + X[15]; aa:= ((aa shl 8) or (aa shr (32-8))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + ((aa and bb) or ((not aa) and cc)) + X[ 7] + $5a827999; ee:= ((ee shl 7) or (ee shr (32-7))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + ((ee and aa) or ((not ee) and bb)) + X[ 4] + $5a827999; dd:= ((dd shl 6) or (dd shr (32-6))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + ((dd and ee) or ((not dd) and aa)) + X[13] + $5a827999; cc:= ((cc shl 8) or (cc shr (32-8))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + ((cc and dd) or ((not cc) and ee)) + X[ 1] + $5a827999; bb:= ((bb shl 13) or (bb shr (32-13))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + ((bb and cc) or ((not bb) and dd)) + X[10] + $5a827999; aa:= ((aa shl 11) or (aa shr (32-11))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + ((aa and bb) or ((not aa) and cc)) + X[ 6] + $5a827999; ee:= ((ee shl 9) or (ee shr (32-9))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + ((ee and aa) or ((not ee) and bb)) + X[15] + $5a827999; dd:= ((dd shl 7) or (dd shr (32-7))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + ((dd and ee) or ((not dd) and aa)) + X[ 3] + $5a827999; cc:= ((cc shl 15) or (cc shr (32-15))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + ((cc and dd) or ((not cc) and ee)) + X[12] + $5a827999; bb:= ((bb shl 7) or (bb shr (32-7))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + ((bb and cc) or ((not bb) and dd)) + X[ 0] + $5a827999; aa:= ((aa shl 12) or (aa shr (32-12))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + ((aa and bb) or ((not aa) and cc)) + X[ 9] + $5a827999; ee:= ((ee shl 15) or (ee shr (32-15))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + ((ee and aa) or ((not ee) and bb)) + X[ 5] + $5a827999; dd:= ((dd shl 9) or (dd shr (32-9))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + ((dd and ee) or ((not dd) and aa)) + X[ 2] + $5a827999; cc:= ((cc shl 11) or (cc shr (32-11))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + ((cc and dd) or ((not cc) and ee)) + X[14] + $5a827999; bb:= ((bb shl 7) or (bb shr (32-7))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + ((bb and cc) or ((not bb) and dd)) + X[11] + $5a827999; aa:= ((aa shl 13) or (aa shr (32-13))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + ((aa and bb) or ((not aa) and cc)) + X[ 8] + $5a827999; ee:= ((ee shl 12) or (ee shr (32-12))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + ((ee or (not aa)) xor bb) + X[ 3] + $6ed9eba1; dd:= ((dd shl 11) or (dd shr (32-11))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + ((dd or (not ee)) xor aa) + X[10] + $6ed9eba1; cc:= ((cc shl 13) or (cc shr (32-13))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + ((cc or (not dd)) xor ee) + X[14] + $6ed9eba1; bb:= ((bb shl 6) or (bb shr (32-6))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + ((bb or (not cc)) xor dd) + X[ 4] + $6ed9eba1; aa:= ((aa shl 7) or (aa shr (32-7))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + ((aa or (not bb)) xor cc) + X[ 9] + $6ed9eba1; ee:= ((ee shl 14) or (ee shr (32-14))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + ((ee or (not aa)) xor bb) + X[15] + $6ed9eba1; dd:= ((dd shl 9) or (dd shr (32-9))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + ((dd or (not ee)) xor aa) + X[ 8] + $6ed9eba1; cc:= ((cc shl 13) or (cc shr (32-13))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + ((cc or (not dd)) xor ee) + X[ 1] + $6ed9eba1; bb:= ((bb shl 15) or (bb shr (32-15))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + ((bb or (not cc)) xor dd) + X[ 2] + $6ed9eba1; aa:= ((aa shl 14) or (aa shr (32-14))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + ((aa or (not bb)) xor cc) + X[ 7] + $6ed9eba1; ee:= ((ee shl 8) or (ee shr (32-8))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + ((ee or (not aa)) xor bb) + X[ 0] + $6ed9eba1; dd:= ((dd shl 13) or (dd shr (32-13))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + ((dd or (not ee)) xor aa) + X[ 6] + $6ed9eba1; cc:= ((cc shl 6) or (cc shr (32-6))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + ((cc or (not dd)) xor ee) + X[13] + $6ed9eba1; bb:= ((bb shl 5) or (bb shr (32-5))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + ((bb or (not cc)) xor dd) + X[11] + $6ed9eba1; aa:= ((aa shl 12) or (aa shr (32-12))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + ((aa or (not bb)) xor cc) + X[ 5] + $6ed9eba1; ee:= ((ee shl 7) or (ee shr (32-7))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + ((ee or (not aa)) xor bb) + X[12] + $6ed9eba1; dd:= ((dd shl 5) or (dd shr (32-5))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + ((dd and aa) or (ee and (not aa))) + X[ 1] + $8f1bbcdc; cc:= ((cc shl 11) or (cc shr (32-11))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + ((cc and ee) or (dd and (not ee))) + X[ 9] + $8f1bbcdc; bb:= ((bb shl 12) or (bb shr (32-12))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + ((bb and dd) or (cc and (not dd))) + X[11] + $8f1bbcdc; aa:= ((aa shl 14) or (aa shr (32-14))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + ((aa and cc) or (bb and (not cc))) + X[10] + $8f1bbcdc; ee:= ((ee shl 15) or (ee shr (32-15))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + ((ee and bb) or (aa and (not bb))) + X[ 0] + $8f1bbcdc; dd:= ((dd shl 14) or (dd shr (32-14))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + ((dd and aa) or (ee and (not aa))) + X[ 8] + $8f1bbcdc; cc:= ((cc shl 15) or (cc shr (32-15))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + ((cc and ee) or (dd and (not ee))) + X[12] + $8f1bbcdc; bb:= ((bb shl 9) or (bb shr (32-9))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + ((bb and dd) or (cc and (not dd))) + X[ 4] + $8f1bbcdc; aa:= ((aa shl 8) or (aa shr (32-8))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + ((aa and cc) or (bb and (not cc))) + X[13] + $8f1bbcdc; ee:= ((ee shl 9) or (ee shr (32-9))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + ((ee and bb) or (aa and (not bb))) + X[ 3] + $8f1bbcdc; dd:= ((dd shl 14) or (dd shr (32-14))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + ((dd and aa) or (ee and (not aa))) + X[ 7] + $8f1bbcdc; cc:= ((cc shl 5) or (cc shr (32-5))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + ((cc and ee) or (dd and (not ee))) + X[15] + $8f1bbcdc; bb:= ((bb shl 6) or (bb shr (32-6))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + ((bb and dd) or (cc and (not dd))) + X[14] + $8f1bbcdc; aa:= ((aa shl 8) or (aa shr (32-8))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + ((aa and cc) or (bb and (not cc))) + X[ 5] + $8f1bbcdc; ee:= ((ee shl 6) or (ee shr (32-6))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + ((ee and bb) or (aa and (not bb))) + X[ 6] + $8f1bbcdc; dd:= ((dd shl 5) or (dd shr (32-5))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + ((dd and aa) or (ee and (not aa))) + X[ 2] + $8f1bbcdc; cc:= ((cc shl 12) or (cc shr (32-12))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + (cc xor (dd or (not ee))) + X[ 4] + $a953fd4e; bb:= ((bb shl 9) or (bb shr (32-9))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + (bb xor (cc or (not dd))) + X[ 0] + $a953fd4e; aa:= ((aa shl 15) or (aa shr (32-15))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + (aa xor (bb or (not cc))) + X[ 5] + $a953fd4e; ee:= ((ee shl 5) or (ee shr (32-5))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + (ee xor (aa or (not bb))) + X[ 9] + $a953fd4e; dd:= ((dd shl 11) or (dd shr (32-11))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + (dd xor (ee or (not aa))) + X[ 7] + $a953fd4e; cc:= ((cc shl 6) or (cc shr (32-6))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + (cc xor (dd or (not ee))) + X[12] + $a953fd4e; bb:= ((bb shl 8) or (bb shr (32-8))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + (bb xor (cc or (not dd))) + X[ 2] + $a953fd4e; aa:= ((aa shl 13) or (aa shr (32-13))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + (aa xor (bb or (not cc))) + X[10] + $a953fd4e; ee:= ((ee shl 12) or (ee shr (32-12))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + (ee xor (aa or (not bb))) + X[14] + $a953fd4e; dd:= ((dd shl 5) or (dd shr (32-5))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + (dd xor (ee or (not aa))) + X[ 1] + $a953fd4e; cc:= ((cc shl 12) or (cc shr (32-12))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + (cc xor (dd or (not ee))) + X[ 3] + $a953fd4e; bb:= ((bb shl 13) or (bb shr (32-13))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aa:= aa + (bb xor (cc or (not dd))) + X[ 8] + $a953fd4e; aa:= ((aa shl 14) or (aa shr (32-14))) + ee; cc:= ((cc shl 10) or (cc shr (32-10))); ee:= ee + (aa xor (bb or (not cc))) + X[11] + $a953fd4e; ee:= ((ee shl 11) or (ee shr (32-11))) + dd; bb:= ((bb shl 10) or (bb shr (32-10))); dd:= dd + (ee xor (aa or (not bb))) + X[ 6] + $a953fd4e; dd:= ((dd shl 8) or (dd shr (32-8))) + cc; aa:= ((aa shl 10) or (aa shr (32-10))); cc:= cc + (dd xor (ee or (not aa))) + X[15] + $a953fd4e; cc:= ((cc shl 5) or (cc shr (32-5))) + bb; ee:= ((ee shl 10) or (ee shr (32-10))); bb:= bb + (cc xor (dd or (not ee))) + X[13] + $a953fd4e; bb:= ((bb shl 6) or (bb shr (32-6))) + aa; dd:= ((dd shl 10) or (dd shr (32-10))); aaa:= aaa + (bbb xor (ccc or (not ddd))) + X[ 5] + $50a28be6; aaa:= ((aaa shl 8) or (aaa shr (32-8))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + (aaa xor (bbb or (not ccc))) + X[14] + $50a28be6; eee:= ((eee shl 9) or (eee shr (32-9))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + (eee xor (aaa or (not bbb))) + X[ 7] + $50a28be6; ddd:= ((ddd shl 9) or (ddd shr (32-9))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + (ddd xor (eee or (not aaa))) + X[ 0] + $50a28be6; ccc:= ((ccc shl 11) or (ccc shr (32-11))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + (ccc xor (ddd or (not eee))) + X[ 9] + $50a28be6; bbb:= ((bbb shl 13) or (bbb shr (32-13))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + (bbb xor (ccc or (not ddd))) + X[ 2] + $50a28be6; aaa:= ((aaa shl 15) or (aaa shr (32-15))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + (aaa xor (bbb or (not ccc))) + X[11] + $50a28be6; eee:= ((eee shl 15) or (eee shr (32-15))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + (eee xor (aaa or (not bbb))) + X[ 4] + $50a28be6; ddd:= ((ddd shl 5) or (ddd shr (32-5))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + (ddd xor (eee or (not aaa))) + X[13] + $50a28be6; ccc:= ((ccc shl 7) or (ccc shr (32-7))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + (ccc xor (ddd or (not eee))) + X[ 6] + $50a28be6; bbb:= ((bbb shl 7) or (bbb shr (32-7))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + (bbb xor (ccc or (not ddd))) + X[15] + $50a28be6; aaa:= ((aaa shl 8) or (aaa shr (32-8))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + (aaa xor (bbb or (not ccc))) + X[ 8] + $50a28be6; eee:= ((eee shl 11) or (eee shr (32-11))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + (eee xor (aaa or (not bbb))) + X[ 1] + $50a28be6; ddd:= ((ddd shl 14) or (ddd shr (32-14))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + (ddd xor (eee or (not aaa))) + X[10] + $50a28be6; ccc:= ((ccc shl 14) or (ccc shr (32-14))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + (ccc xor (ddd or (not eee))) + X[ 3] + $50a28be6; bbb:= ((bbb shl 12) or (bbb shr (32-12))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + (bbb xor (ccc or (not ddd))) + X[12] + $50a28be6; aaa:= ((aaa shl 6) or (aaa shr (32-6))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + ((aaa and ccc) or (bbb and (not ccc))) + X[ 6] + $5c4dd124; eee:= ((eee shl 9) or (eee shr (32-9))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + ((eee and bbb) or (aaa and (not bbb))) + X[11] + $5c4dd124; ddd:= ((ddd shl 13) or (ddd shr (32-13))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + ((ddd and aaa) or (eee and (not aaa))) + X[ 3] + $5c4dd124; ccc:= ((ccc shl 15) or (ccc shr (32-15))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + ((ccc and eee) or (ddd and (not eee))) + X[ 7] + $5c4dd124; bbb:= ((bbb shl 7) or (bbb shr (32-7))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + ((bbb and ddd) or (ccc and (not ddd))) + X[ 0] + $5c4dd124; aaa:= ((aaa shl 12) or (aaa shr (32-12))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + ((aaa and ccc) or (bbb and (not ccc))) + X[13] + $5c4dd124; eee:= ((eee shl 8) or (eee shr (32-8))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + ((eee and bbb) or (aaa and (not bbb))) + X[ 5] + $5c4dd124; ddd:= ((ddd shl 9) or (ddd shr (32-9))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + ((ddd and aaa) or (eee and (not aaa))) + X[10] + $5c4dd124; ccc:= ((ccc shl 11) or (ccc shr (32-11))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + ((ccc and eee) or (ddd and (not eee))) + X[14] + $5c4dd124; bbb:= ((bbb shl 7) or (bbb shr (32-7))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + ((bbb and ddd) or (ccc and (not ddd))) + X[15] + $5c4dd124; aaa:= ((aaa shl 7) or (aaa shr (32-7))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + ((aaa and ccc) or (bbb and (not ccc))) + X[ 8] + $5c4dd124; eee:= ((eee shl 12) or (eee shr (32-12))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + ((eee and bbb) or (aaa and (not bbb))) + X[12] + $5c4dd124; ddd:= ((ddd shl 7) or (ddd shr (32-7))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + ((ddd and aaa) or (eee and (not aaa))) + X[ 4] + $5c4dd124; ccc:= ((ccc shl 6) or (ccc shr (32-6))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + ((ccc and eee) or (ddd and (not eee))) + X[ 9] + $5c4dd124; bbb:= ((bbb shl 15) or (bbb shr (32-15))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + ((bbb and ddd) or (ccc and (not ddd))) + X[ 1] + $5c4dd124; aaa:= ((aaa shl 13) or (aaa shr (32-13))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + ((aaa and ccc) or (bbb and (not ccc))) + X[ 2] + $5c4dd124; eee:= ((eee shl 11) or (eee shr (32-11))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + ((eee or (not aaa)) xor bbb) + X[15] + $6d703ef3; ddd:= ((ddd shl 9) or (ddd shr (32-9))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + ((ddd or (not eee)) xor aaa) + X[ 5] + $6d703ef3; ccc:= ((ccc shl 7) or (ccc shr (32-7))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + ((ccc or (not ddd)) xor eee) + X[ 1] + $6d703ef3; bbb:= ((bbb shl 15) or (bbb shr (32-15))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + ((bbb or (not ccc)) xor ddd) + X[ 3] + $6d703ef3; aaa:= ((aaa shl 11) or (aaa shr (32-11))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + ((aaa or (not bbb)) xor ccc) + X[ 7] + $6d703ef3; eee:= ((eee shl 8) or (eee shr (32-8))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + ((eee or (not aaa)) xor bbb) + X[14] + $6d703ef3; ddd:= ((ddd shl 6) or (ddd shr (32-6))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + ((ddd or (not eee)) xor aaa) + X[ 6] + $6d703ef3; ccc:= ((ccc shl 6) or (ccc shr (32-6))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + ((ccc or (not ddd)) xor eee) + X[ 9] + $6d703ef3; bbb:= ((bbb shl 14) or (bbb shr (32-14))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + ((bbb or (not ccc)) xor ddd) + X[11] + $6d703ef3; aaa:= ((aaa shl 12) or (aaa shr (32-12))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + ((aaa or (not bbb)) xor ccc) + X[ 8] + $6d703ef3; eee:= ((eee shl 13) or (eee shr (32-13))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + ((eee or (not aaa)) xor bbb) + X[12] + $6d703ef3; ddd:= ((ddd shl 5) or (ddd shr (32-5))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + ((ddd or (not eee)) xor aaa) + X[ 2] + $6d703ef3; ccc:= ((ccc shl 14) or (ccc shr (32-14))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + ((ccc or (not ddd)) xor eee) + X[10] + $6d703ef3; bbb:= ((bbb shl 13) or (bbb shr (32-13))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + ((bbb or (not ccc)) xor ddd) + X[ 0] + $6d703ef3; aaa:= ((aaa shl 13) or (aaa shr (32-13))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + ((aaa or (not bbb)) xor ccc) + X[ 4] + $6d703ef3; eee:= ((eee shl 7) or (eee shr (32-7))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + ((eee or (not aaa)) xor bbb) + X[13] + $6d703ef3; ddd:= ((ddd shl 5) or (ddd shr (32-5))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + ((ddd and eee) or ((not ddd) and aaa)) + X[ 8] + $7a6d76e9; ccc:= ((ccc shl 15) or (ccc shr (32-15))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + ((ccc and ddd) or ((not ccc) and eee)) + X[ 6] + $7a6d76e9; bbb:= ((bbb shl 5) or (bbb shr (32-5))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + ((bbb and ccc) or ((not bbb) and ddd)) + X[ 4] + $7a6d76e9; aaa:= ((aaa shl 8) or (aaa shr (32-8))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + ((aaa and bbb) or ((not aaa) and ccc)) + X[ 1] + $7a6d76e9; eee:= ((eee shl 11) or (eee shr (32-11))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + ((eee and aaa) or ((not eee) and bbb)) + X[ 3] + $7a6d76e9; ddd:= ((ddd shl 14) or (ddd shr (32-14))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + ((ddd and eee) or ((not ddd) and aaa)) + X[11] + $7a6d76e9; ccc:= ((ccc shl 14) or (ccc shr (32-14))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + ((ccc and ddd) or ((not ccc) and eee)) + X[15] + $7a6d76e9; bbb:= ((bbb shl 6) or (bbb shr (32-6))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + ((bbb and ccc) or ((not bbb) and ddd)) + X[ 0] + $7a6d76e9; aaa:= ((aaa shl 14) or (aaa shr (32-14))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + ((aaa and bbb) or ((not aaa) and ccc)) + X[ 5] + $7a6d76e9; eee:= ((eee shl 6) or (eee shr (32-6))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + ((eee and aaa) or ((not eee) and bbb)) + X[12] + $7a6d76e9; ddd:= ((ddd shl 9) or (ddd shr (32-9))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + ((ddd and eee) or ((not ddd) and aaa)) + X[ 2] + $7a6d76e9; ccc:= ((ccc shl 12) or (ccc shr (32-12))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + ((ccc and ddd) or ((not ccc) and eee)) + X[13] + $7a6d76e9; bbb:= ((bbb shl 9) or (bbb shr (32-9))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + ((bbb and ccc) or ((not bbb) and ddd)) + X[ 9] + $7a6d76e9; aaa:= ((aaa shl 12) or (aaa shr (32-12))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + ((aaa and bbb) or ((not aaa) and ccc)) + X[ 7] + $7a6d76e9; eee:= ((eee shl 5) or (eee shr (32-5))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + ((eee and aaa) or ((not eee) and bbb)) + X[10] + $7a6d76e9; ddd:= ((ddd shl 15) or (ddd shr (32-15))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + ((ddd and eee) or ((not ddd) and aaa)) + X[14] + $7a6d76e9; ccc:= ((ccc shl 8) or (ccc shr (32-8))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + (ccc xor ddd xor eee) + X[12]; bbb:= ((bbb shl 8) or (bbb shr (32-8))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + (bbb xor ccc xor ddd) + X[15]; aaa:= ((aaa shl 5) or (aaa shr (32-5))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + (aaa xor bbb xor ccc) + X[10]; eee:= ((eee shl 12) or (eee shr (32-12))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + (eee xor aaa xor bbb) + X[ 4]; ddd:= ((ddd shl 9) or (ddd shr (32-9))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + (ddd xor eee xor aaa) + X[ 1]; ccc:= ((ccc shl 12) or (ccc shr (32-12))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + (ccc xor ddd xor eee) + X[ 5]; bbb:= ((bbb shl 5) or (bbb shr (32-5))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + (bbb xor ccc xor ddd) + X[ 8]; aaa:= ((aaa shl 14) or (aaa shr (32-14))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + (aaa xor bbb xor ccc) + X[ 7]; eee:= ((eee shl 6) or (eee shr (32-6))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + (eee xor aaa xor bbb) + X[ 6]; ddd:= ((ddd shl 8) or (ddd shr (32-8))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + (ddd xor eee xor aaa) + X[ 2]; ccc:= ((ccc shl 13) or (ccc shr (32-13))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + (ccc xor ddd xor eee) + X[13]; bbb:= ((bbb shl 6) or (bbb shr (32-6))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); aaa:= aaa + (bbb xor ccc xor ddd) + X[14]; aaa:= ((aaa shl 5) or (aaa shr (32-5))) + eee; ccc:= ((ccc shl 10) or (ccc shr (32-10))); eee:= eee + (aaa xor bbb xor ccc) + X[ 0]; eee:= ((eee shl 15) or (eee shr (32-15))) + ddd; bbb:= ((bbb shl 10) or (bbb shr (32-10))); ddd:= ddd + (eee xor aaa xor bbb) + X[ 3]; ddd:= ((ddd shl 13) or (ddd shr (32-13))) + ccc; aaa:= ((aaa shl 10) or (aaa shr (32-10))); ccc:= ccc + (ddd xor eee xor aaa) + X[ 9]; ccc:= ((ccc shl 11) or (ccc shr (32-11))) + bbb; eee:= ((eee shl 10) or (eee shr (32-10))); bbb:= bbb + (ccc xor ddd xor eee) + X[11]; bbb:= ((bbb shl 11) or (bbb shr (32-11))) + aaa; ddd:= ((ddd shl 10) or (ddd shr (32-10))); ddd:= ddd + cc + CurrentHash[1]; CurrentHash[1]:= CurrentHash[2] + dd + eee; CurrentHash[2]:= CurrentHash[3] + ee + aaa; CurrentHash[3]:= CurrentHash[4] + aa + bbb; CurrentHash[4]:= CurrentHash[0] + bb + ccc; CurrentHash[0]:= ddd; FillChar(X,Sizeof(X),0); Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); end; class function TDCP_ripemd160.GetHashSize: integer; begin Result:= 160; end; class function TDCP_ripemd160.GetId: integer; begin Result:= DCP_ripemd160; end; class function TDCP_ripemd160.GetAlgorithm: string; begin Result:= 'RipeMD-160'; end; class function TDCP_ripemd160.SelfTest: boolean; const Test1Out: array[0..19] of byte= ($0B,$DC,$9D,$2D,$25,$6B,$3E,$E9,$DA,$AE,$34,$7B,$E6,$F4,$DC,$83,$5A,$46,$7F,$FE); Test2Out: array[0..19] of byte= ($F7,$1C,$27,$10,$9C,$69,$2C,$1B,$56,$BB,$DC,$EB,$5B,$9D,$28,$65,$B3,$70,$8D,$BC); var TestHash: TDCP_ripemd160; TestOut: array[0..19] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_ripemd160.Create(nil); TestHash.Init; TestHash.UpdateStr('a'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Init; TestHash.UpdateStr('abcdefghijklmnopqrstuvwxyz'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out)) and Result; TestHash.Free; end; procedure TDCP_ripemd160.Init; begin Burn; CurrentHash[0]:= $67452301; CurrentHash[1]:= $efcdab89; CurrentHash[2]:= $98badcfe; CurrentHash[3]:= $10325476; CurrentHash[4]:= $c3d2e1f0; fInitialized:= true; end; procedure TDCP_ripemd160.Burn; begin LenHi:= 0; LenLo:= 0; Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); FillChar(CurrentHash,Sizeof(CurrentHash),0); fInitialized:= false; end; procedure TDCP_ripemd160.Update(const Buffer; Size: longword); var PBuf: ^byte; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); Inc(LenHi,Size shr 29); Inc(LenLo,Size*8); if LenLo< (Size*8) then Inc(LenHi); PBuf:= @Buffer; while Size> 0 do begin if (Sizeof(HashBuffer)-Index)<= DWord(Size) then begin Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index); Dec(Size,Sizeof(HashBuffer)-Index); Inc(PBuf,Sizeof(HashBuffer)-Index); Compress; end else begin Move(PBuf^,HashBuffer[Index],Size); Inc(Index,Size); Size:= 0; end; end; end; procedure TDCP_ripemd160.Final(var Digest); begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); HashBuffer[Index]:= $80; if Index>= 56 then Compress; PDWord(@HashBuffer[56])^:= LenLo; PDWord(@HashBuffer[60])^:= LenHi; Compress; Move(CurrentHash,Digest,Sizeof(CurrentHash)); Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dcpmd5.pas0000664000175000017500000002363612570657777021657 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of MD5 **********************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPmd5; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2, DCPconst; type TDCP_md5= class(TDCP_hash) protected LenHi, LenLo: longword; Index: DWord; CurrentHash: array[0..3] of DWord; HashBuffer: array[0..63] of byte; procedure Compress; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; procedure Final(var Digest); override; end; {******************************************************************************} {******************************************************************************} implementation {$R-}{$Q-} {$macro on}{$define LRot32:=RolDWord} procedure TDCP_md5.Compress; var Data: array[0..15] of dword; A, B, C, D: dword; begin dcpFillChar(Data, SizeOf(Data), 0); Move(HashBuffer,Data,Sizeof(Data)); A:= CurrentHash[0]; B:= CurrentHash[1]; C:= CurrentHash[2]; D:= CurrentHash[3]; A:= B + LRot32(A + (D xor (B and (C xor D))) + Data[ 0] + $d76aa478,7); D:= A + LRot32(D + (C xor (A and (B xor C))) + Data[ 1] + $e8c7b756,12); C:= D + LRot32(C + (B xor (D and (A xor B))) + Data[ 2] + $242070db,17); B:= C + LRot32(B + (A xor (C and (D xor A))) + Data[ 3] + $c1bdceee,22); A:= B + LRot32(A + (D xor (B and (C xor D))) + Data[ 4] + $f57c0faf,7); D:= A + LRot32(D + (C xor (A and (B xor C))) + Data[ 5] + $4787c62a,12); C:= D + LRot32(C + (B xor (D and (A xor B))) + Data[ 6] + $a8304613,17); B:= C + LRot32(B + (A xor (C and (D xor A))) + Data[ 7] + $fd469501,22); A:= B + LRot32(A + (D xor (B and (C xor D))) + Data[ 8] + $698098d8,7); D:= A + LRot32(D + (C xor (A and (B xor C))) + Data[ 9] + $8b44f7af,12); C:= D + LRot32(C + (B xor (D and (A xor B))) + Data[10] + $ffff5bb1,17); B:= C + LRot32(B + (A xor (C and (D xor A))) + Data[11] + $895cd7be,22); A:= B + LRot32(A + (D xor (B and (C xor D))) + Data[12] + $6b901122,7); D:= A + LRot32(D + (C xor (A and (B xor C))) + Data[13] + $fd987193,12); C:= D + LRot32(C + (B xor (D and (A xor B))) + Data[14] + $a679438e,17); B:= C + LRot32(B + (A xor (C and (D xor A))) + Data[15] + $49b40821,22); A:= B + LRot32(A + (C xor (D and (B xor C))) + Data[ 1] + $f61e2562,5); D:= A + LRot32(D + (B xor (C and (A xor B))) + Data[ 6] + $c040b340,9); C:= D + LRot32(C + (A xor (B and (D xor A))) + Data[11] + $265e5a51,14); B:= C + LRot32(B + (D xor (A and (C xor D))) + Data[ 0] + $e9b6c7aa,20); A:= B + LRot32(A + (C xor (D and (B xor C))) + Data[ 5] + $d62f105d,5); D:= A + LRot32(D + (B xor (C and (A xor B))) + Data[10] + $02441453,9); C:= D + LRot32(C + (A xor (B and (D xor A))) + Data[15] + $d8a1e681,14); B:= C + LRot32(B + (D xor (A and (C xor D))) + Data[ 4] + $e7d3fbc8,20); A:= B + LRot32(A + (C xor (D and (B xor C))) + Data[ 9] + $21e1cde6,5); D:= A + LRot32(D + (B xor (C and (A xor B))) + Data[14] + $c33707d6,9); C:= D + LRot32(C + (A xor (B and (D xor A))) + Data[ 3] + $f4d50d87,14); B:= C + LRot32(B + (D xor (A and (C xor D))) + Data[ 8] + $455a14ed,20); A:= B + LRot32(A + (C xor (D and (B xor C))) + Data[13] + $a9e3e905,5); D:= A + LRot32(D + (B xor (C and (A xor B))) + Data[ 2] + $fcefa3f8,9); C:= D + LRot32(C + (A xor (B and (D xor A))) + Data[ 7] + $676f02d9,14); B:= C + LRot32(B + (D xor (A and (C xor D))) + Data[12] + $8d2a4c8a,20); A:= B + LRot32(A + (B xor C xor D) + Data[ 5] + $fffa3942,4); D:= A + LRot32(D + (A xor B xor C) + Data[ 8] + $8771f681,11); C:= D + LRot32(C + (D xor A xor B) + Data[11] + $6d9d6122,16); B:= C + LRot32(B + (C xor D xor A) + Data[14] + $fde5380c,23); A:= B + LRot32(A + (B xor C xor D) + Data[ 1] + $a4beea44,4); D:= A + LRot32(D + (A xor B xor C) + Data[ 4] + $4bdecfa9,11); C:= D + LRot32(C + (D xor A xor B) + Data[ 7] + $f6bb4b60,16); B:= C + LRot32(B + (C xor D xor A) + Data[10] + $bebfbc70,23); A:= B + LRot32(A + (B xor C xor D) + Data[13] + $289b7ec6,4); D:= A + LRot32(D + (A xor B xor C) + Data[ 0] + $eaa127fa,11); C:= D + LRot32(C + (D xor A xor B) + Data[ 3] + $d4ef3085,16); B:= C + LRot32(B + (C xor D xor A) + Data[ 6] + $04881d05,23); A:= B + LRot32(A + (B xor C xor D) + Data[ 9] + $d9d4d039,4); D:= A + LRot32(D + (A xor B xor C) + Data[12] + $e6db99e5,11); C:= D + LRot32(C + (D xor A xor B) + Data[15] + $1fa27cf8,16); B:= C + LRot32(B + (C xor D xor A) + Data[ 2] + $c4ac5665,23); A:= B + LRot32(A + (C xor (B or (not D))) + Data[ 0] + $f4292244,6); D:= A + LRot32(D + (B xor (A or (not C))) + Data[ 7] + $432aff97,10); C:= D + LRot32(C + (A xor (D or (not B))) + Data[14] + $ab9423a7,15); B:= C + LRot32(B + (D xor (C or (not A))) + Data[ 5] + $fc93a039,21); A:= B + LRot32(A + (C xor (B or (not D))) + Data[12] + $655b59c3,6); D:= A + LRot32(D + (B xor (A or (not C))) + Data[ 3] + $8f0ccc92,10); C:= D + LRot32(C + (A xor (D or (not B))) + Data[10] + $ffeff47d,15); B:= C + LRot32(B + (D xor (C or (not A))) + Data[ 1] + $85845dd1,21); A:= B + LRot32(A + (C xor (B or (not D))) + Data[ 8] + $6fa87e4f,6); D:= A + LRot32(D + (B xor (A or (not C))) + Data[15] + $fe2ce6e0,10); C:= D + LRot32(C + (A xor (D or (not B))) + Data[ 6] + $a3014314,15); B:= C + LRot32(B + (D xor (C or (not A))) + Data[13] + $4e0811a1,21); A:= B + LRot32(A + (C xor (B or (not D))) + Data[ 4] + $f7537e82,6); D:= A + LRot32(D + (B xor (A or (not C))) + Data[11] + $bd3af235,10); C:= D + LRot32(C + (A xor (D or (not B))) + Data[ 2] + $2ad7d2bb,15); B:= C + LRot32(B + (D xor (C or (not A))) + Data[ 9] + $eb86d391,21); Inc(CurrentHash[0],A); Inc(CurrentHash[1],B); Inc(CurrentHash[2],C); Inc(CurrentHash[3],D); Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); end; class function TDCP_md5.GetHashSize: integer; begin Result:= 128; end; class function TDCP_md5.GetId: integer; begin Result:= DCP_md5; end; class function TDCP_md5.GetAlgorithm: string; begin Result:= 'MD5'; end; class function TDCP_md5.SelfTest: boolean; const Test1Out: array[0..15] of byte= ($90,$01,$50,$98,$3c,$d2,$4f,$b0,$d6,$96,$3f,$7d,$28,$e1,$7f,$72); Test2Out: array[0..15] of byte= ($c3,$fc,$d3,$d7,$61,$92,$e4,$00,$7d,$fb,$49,$6c,$ca,$67,$e1,$3b); var TestHash: TDCP_md5; TestOut: array[0..19] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_md5.Create(nil); TestHash.Init; TestHash.UpdateStr('abc'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Init; TestHash.UpdateStr('abcdefghijklmnopqrstuvwxyz'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out)) and Result; TestHash.Free; end; procedure TDCP_md5.Init; begin Burn; CurrentHash[0]:= $67452301; CurrentHash[1]:= $efcdab89; CurrentHash[2]:= $98badcfe; CurrentHash[3]:= $10325476; fInitialized:= true; end; procedure TDCP_md5.Burn; begin LenHi:= 0; LenLo:= 0; Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); FillChar(CurrentHash,Sizeof(CurrentHash),0); fInitialized:= false; end; procedure TDCP_md5.Update(const Buffer; Size: longword); var PBuf: ^byte; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); Inc(LenHi,Size shr 29); Inc(LenLo,Size*8); if LenLo< (Size*8) then Inc(LenHi); PBuf:= @Buffer; while Size> 0 do begin if (Sizeof(HashBuffer)-Index)<= DWord(Size) then begin Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index); Dec(Size,Sizeof(HashBuffer)-Index); Inc(PBuf,Sizeof(HashBuffer)-Index); Compress; end else begin Move(PBuf^,HashBuffer[Index],Size); Inc(Index,Size); Size:= 0; end; end; end; procedure TDCP_md5.Final(var Digest); begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); HashBuffer[Index]:= $80; if Index>= 56 then Compress; PDWord(@HashBuffer[56])^:= LenLo; PDWord(@HashBuffer[60])^:= LenHi; Compress; Move(CurrentHash,Digest,Sizeof(CurrentHash)); Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dcpsha1.pas0000664000175000017500000003550112014201074021760 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of SHA1 *********************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPsha1; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2, DCPconst; type TDCP_sha1= class(TDCP_hash) protected LenHi, LenLo: longword; Index: DWord; CurrentHash: array[0..4] of DWord; HashBuffer: array[0..63] of byte; procedure Compress; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Final(var Digest); override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; end; {******************************************************************************} {******************************************************************************} implementation {$R-}{$Q-} function SwapDWord(a: dword): dword; begin Result:= ((a and $FF) shl 24) or ((a and $FF00) shl 8) or ((a and $FF0000) shr 8) or ((a and $FF000000) shr 24); end; procedure TDCP_sha1.Compress; var A, B, C, D, E: DWord; W: array[0..79] of DWord; i: longword; begin Index:= 0; dcpFillChar(W, SizeOf(W), 0); Move(HashBuffer,W,Sizeof(HashBuffer)); for i:= 0 to 15 do W[i]:= SwapDWord(W[i]); for i:= 16 to 79 do W[i]:= ((W[i-3] xor W[i-8] xor W[i-14] xor W[i-16]) shl 1) or ((W[i-3] xor W[i-8] xor W[i-14] xor W[i-16]) shr 31); A:= CurrentHash[0]; B:= CurrentHash[1]; C:= CurrentHash[2]; D:= CurrentHash[3]; E:= CurrentHash[4]; Inc(E,((A shl 5) or (A shr 27)) + (D xor (B and (C xor D))) + $5A827999 + W[ 0]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (C xor (A and (B xor C))) + $5A827999 + W[ 1]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (B xor (E and (A xor B))) + $5A827999 + W[ 2]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (A xor (D and (E xor A))) + $5A827999 + W[ 3]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (E xor (C and (D xor E))) + $5A827999 + W[ 4]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (D xor (B and (C xor D))) + $5A827999 + W[ 5]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (C xor (A and (B xor C))) + $5A827999 + W[ 6]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (B xor (E and (A xor B))) + $5A827999 + W[ 7]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (A xor (D and (E xor A))) + $5A827999 + W[ 8]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (E xor (C and (D xor E))) + $5A827999 + W[ 9]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (D xor (B and (C xor D))) + $5A827999 + W[10]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (C xor (A and (B xor C))) + $5A827999 + W[11]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (B xor (E and (A xor B))) + $5A827999 + W[12]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (A xor (D and (E xor A))) + $5A827999 + W[13]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (E xor (C and (D xor E))) + $5A827999 + W[14]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (D xor (B and (C xor D))) + $5A827999 + W[15]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (C xor (A and (B xor C))) + $5A827999 + W[16]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (B xor (E and (A xor B))) + $5A827999 + W[17]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (A xor (D and (E xor A))) + $5A827999 + W[18]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (E xor (C and (D xor E))) + $5A827999 + W[19]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (B xor C xor D) + $6ED9EBA1 + W[20]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (A xor B xor C) + $6ED9EBA1 + W[21]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (E xor A xor B) + $6ED9EBA1 + W[22]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (D xor E xor A) + $6ED9EBA1 + W[23]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (C xor D xor E) + $6ED9EBA1 + W[24]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (B xor C xor D) + $6ED9EBA1 + W[25]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (A xor B xor C) + $6ED9EBA1 + W[26]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (E xor A xor B) + $6ED9EBA1 + W[27]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (D xor E xor A) + $6ED9EBA1 + W[28]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (C xor D xor E) + $6ED9EBA1 + W[29]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (B xor C xor D) + $6ED9EBA1 + W[30]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (A xor B xor C) + $6ED9EBA1 + W[31]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (E xor A xor B) + $6ED9EBA1 + W[32]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (D xor E xor A) + $6ED9EBA1 + W[33]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (C xor D xor E) + $6ED9EBA1 + W[34]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (B xor C xor D) + $6ED9EBA1 + W[35]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (A xor B xor C) + $6ED9EBA1 + W[36]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (E xor A xor B) + $6ED9EBA1 + W[37]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (D xor E xor A) + $6ED9EBA1 + W[38]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (C xor D xor E) + $6ED9EBA1 + W[39]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + ((B and C) or (D and (B or C))) + $8F1BBCDC + W[40]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + ((A and B) or (C and (A or B))) + $8F1BBCDC + W[41]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + ((E and A) or (B and (E or A))) + $8F1BBCDC + W[42]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + ((D and E) or (A and (D or E))) + $8F1BBCDC + W[43]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + ((C and D) or (E and (C or D))) + $8F1BBCDC + W[44]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + ((B and C) or (D and (B or C))) + $8F1BBCDC + W[45]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + ((A and B) or (C and (A or B))) + $8F1BBCDC + W[46]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + ((E and A) or (B and (E or A))) + $8F1BBCDC + W[47]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + ((D and E) or (A and (D or E))) + $8F1BBCDC + W[48]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + ((C and D) or (E and (C or D))) + $8F1BBCDC + W[49]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + ((B and C) or (D and (B or C))) + $8F1BBCDC + W[50]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + ((A and B) or (C and (A or B))) + $8F1BBCDC + W[51]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + ((E and A) or (B and (E or A))) + $8F1BBCDC + W[52]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + ((D and E) or (A and (D or E))) + $8F1BBCDC + W[53]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + ((C and D) or (E and (C or D))) + $8F1BBCDC + W[54]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + ((B and C) or (D and (B or C))) + $8F1BBCDC + W[55]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + ((A and B) or (C and (A or B))) + $8F1BBCDC + W[56]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + ((E and A) or (B and (E or A))) + $8F1BBCDC + W[57]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + ((D and E) or (A and (D or E))) + $8F1BBCDC + W[58]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + ((C and D) or (E and (C or D))) + $8F1BBCDC + W[59]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (B xor C xor D) + $CA62C1D6 + W[60]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (A xor B xor C) + $CA62C1D6 + W[61]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (E xor A xor B) + $CA62C1D6 + W[62]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (D xor E xor A) + $CA62C1D6 + W[63]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (C xor D xor E) + $CA62C1D6 + W[64]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (B xor C xor D) + $CA62C1D6 + W[65]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (A xor B xor C) + $CA62C1D6 + W[66]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (E xor A xor B) + $CA62C1D6 + W[67]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (D xor E xor A) + $CA62C1D6 + W[68]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (C xor D xor E) + $CA62C1D6 + W[69]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (B xor C xor D) + $CA62C1D6 + W[70]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (A xor B xor C) + $CA62C1D6 + W[71]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (E xor A xor B) + $CA62C1D6 + W[72]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (D xor E xor A) + $CA62C1D6 + W[73]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (C xor D xor E) + $CA62C1D6 + W[74]); C:= (C shl 30) or (C shr 2); Inc(E,((A shl 5) or (A shr 27)) + (B xor C xor D) + $CA62C1D6 + W[75]); B:= (B shl 30) or (B shr 2); Inc(D,((E shl 5) or (E shr 27)) + (A xor B xor C) + $CA62C1D6 + W[76]); A:= (A shl 30) or (A shr 2); Inc(C,((D shl 5) or (D shr 27)) + (E xor A xor B) + $CA62C1D6 + W[77]); E:= (E shl 30) or (E shr 2); Inc(B,((C shl 5) or (C shr 27)) + (D xor E xor A) + $CA62C1D6 + W[78]); D:= (D shl 30) or (D shr 2); Inc(A,((B shl 5) or (B shr 27)) + (C xor D xor E) + $CA62C1D6 + W[79]); C:= (C shl 30) or (C shr 2); CurrentHash[0]:= CurrentHash[0] + A; CurrentHash[1]:= CurrentHash[1] + B; CurrentHash[2]:= CurrentHash[2] + C; CurrentHash[3]:= CurrentHash[3] + D; CurrentHash[4]:= CurrentHash[4] + E; FillChar(W,Sizeof(W),0); FillChar(HashBuffer,Sizeof(HashBuffer),0); end; class function TDCP_sha1.GetAlgorithm: string; begin Result:= 'SHA1'; end; class function TDCP_sha1.GetId: integer; begin Result:= DCP_sha1; end; class function TDCP_sha1.GetHashSize: integer; begin Result:= 160; end; class function TDCP_sha1.SelfTest: boolean; const Test1Out: array[0..19] of byte= ($A9,$99,$3E,$36,$47,$06,$81,$6A,$BA,$3E,$25,$71,$78,$50,$C2,$6C,$9C,$D0,$D8,$9D); Test2Out: array[0..19] of byte= ($84,$98,$3E,$44,$1C,$3B,$D2,$6E,$BA,$AE,$4A,$A1,$F9,$51,$29,$E5,$E5,$46,$70,$F1); var TestHash: TDCP_sha1; TestOut: array[0..19] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_sha1.Create(nil); TestHash.Init; TestHash.UpdateStr('abc'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out))); TestHash.Init; TestHash.UpdateStr('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out))) and Result; TestHash.Free; end; procedure TDCP_sha1.Init; begin Burn; CurrentHash[0]:= $67452301; CurrentHash[1]:= $EFCDAB89; CurrentHash[2]:= $98BADCFE; CurrentHash[3]:= $10325476; CurrentHash[4]:= $C3D2E1F0; fInitialized:= true; end; procedure TDCP_sha1.Burn; begin LenHi:= 0; LenLo:= 0; Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); FillChar(CurrentHash,Sizeof(CurrentHash),0); fInitialized:= false; end; procedure TDCP_sha1.Update(const Buffer; Size: longword); var PBuf: ^byte; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); Inc(LenHi,Size shr 29); Inc(LenLo,Size*8); if LenLo< (Size*8) then Inc(LenHi); PBuf:= @Buffer; while Size> 0 do begin if (Sizeof(HashBuffer)-Index)<= DWord(Size) then begin Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index); Dec(Size,Sizeof(HashBuffer)-Index); Inc(PBuf,Sizeof(HashBuffer)-Index); Compress; end else begin Move(PBuf^,HashBuffer[Index],Size); Inc(Index,Size); Size:= 0; end; end; end; procedure TDCP_sha1.Final(var Digest); begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); HashBuffer[Index]:= $80; if Index>= 56 then Compress; PDWord(@HashBuffer[56])^:= SwapDWord(LenHi); PDWord(@HashBuffer[60])^:= SwapDWord(LenLo); Compress; CurrentHash[0]:= SwapDWord(CurrentHash[0]); CurrentHash[1]:= SwapDWord(CurrentHash[1]); CurrentHash[2]:= SwapDWord(CurrentHash[2]); CurrentHash[3]:= SwapDWord(CurrentHash[3]); CurrentHash[4]:= SwapDWord(CurrentHash[4]); Move(CurrentHash,Digest,Sizeof(CurrentHash)); Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dcpsha512.pas0000664000175000017500000011037212014201074022127 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of SHA512 *******************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPsha512; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2, DCPconst; type TDCP_sha512base= class(TDCP_hash) protected LenHi, LenLo: int64; Index: DWord; CurrentHash: array[0..7] of int64; HashBuffer: array[0..127] of byte; procedure Compress; public procedure Update(const Buffer; Size: longword); override; procedure Burn; override; end; TDCP_sha384= class(TDCP_sha512base) public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Final(var Digest); override; end; TDCP_sha512= class(TDCP_sha512base) public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Final(var Digest); override; end; {******************************************************************************} {******************************************************************************} implementation {$R-}{$Q-} function SwapDWord(a: int64): int64; begin Result:= ((a and $FF) shl 56) or ((a and $FF00) shl 40) or ((a and $FF0000) shl 24) or ((a and $FF000000) shl 8) or ((a and $FF00000000) shr 8) or ((a and $FF0000000000) shr 24) or ((a and $FF000000000000) shr 40) or ((a and $FF00000000000000) shr 56); end; procedure TDCP_sha512base.Compress; var a, b, c, d, e, f, g, h, t1, t2: int64; W: array[0..79] of int64; i: longword; begin Index:= 0; dcpFillChar(W, SizeOf(W), 0); a:= CurrentHash[0]; b:= CurrentHash[1]; c:= CurrentHash[2]; d:= CurrentHash[3]; e:= CurrentHash[4]; f:= CurrentHash[5]; g:= CurrentHash[6]; h:= CurrentHash[7]; Move(HashBuffer,W,Sizeof(HashBuffer)); for i:= 0 to 15 do W[i]:= SwapDWord(W[i]); for i:= 16 to 79 do W[i]:= (((W[i-2] shr 19) or (W[i-2] shl 45)) xor ((W[i-2] shr 61) or (W[i-2] shl 3)) xor (W[i-2] shr 6)) + W[i-7] + (((W[i-15] shr 1) or (W[i-15] shl 63)) xor ((W[i-15] shr 8) or (W[i-15] shl 56)) xor (W[i-15] shr 7)) + W[i-16]; { Non-optimised version for i:= 0 to 79 do begin t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + K[i] + W[i]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); h:= g; g:= f; f:= e; e:= d + t1; d:= c; c:= b; b:= a; a:= t1 + t2; end; } t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + $428a2f98d728ae22 + W[0]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); d:= d + t1; h:= t1 + t2; t1:= g + (((d shr 14) or (d shl 50)) xor ((d shr 18) or (d shl 46)) xor ((d shr 41) or (d shl 23))) + ((d and e) xor (not d and f)) + $7137449123ef65cd + W[1]; t2:= (((h shr 28) or (h shl 36)) xor ((h shr 34) or (h shl 30)) xor ((h shr 39) or (h shl 25))) + ((h and a) xor (h and b) xor (a and b)); c:= c + t1; g:= t1 + t2; t1:= f + (((c shr 14) or (c shl 50)) xor ((c shr 18) or (c shl 46)) xor ((c shr 41) or (c shl 23))) + ((c and d) xor (not c and e)) + $b5c0fbcfec4d3b2f + W[2]; t2:= (((g shr 28) or (g shl 36)) xor ((g shr 34) or (g shl 30)) xor ((g shr 39) or (g shl 25))) + ((g and h) xor (g and a) xor (h and a)); b:= b + t1; f:= t1 + t2; t1:= e + (((b shr 14) or (b shl 50)) xor ((b shr 18) or (b shl 46)) xor ((b shr 41) or (b shl 23))) + ((b and c) xor (not b and d)) + $e9b5dba58189dbbc + W[3]; t2:= (((f shr 28) or (f shl 36)) xor ((f shr 34) or (f shl 30)) xor ((f shr 39) or (f shl 25))) + ((f and g) xor (f and h) xor (g and h)); a:= a + t1; e:= t1 + t2; t1:= d + (((a shr 14) or (a shl 50)) xor ((a shr 18) or (a shl 46)) xor ((a shr 41) or (a shl 23))) + ((a and b) xor (not a and c)) + $3956c25bf348b538 + W[4]; t2:= (((e shr 28) or (e shl 36)) xor ((e shr 34) or (e shl 30)) xor ((e shr 39) or (e shl 25))) + ((e and f) xor (e and g) xor (f and g)); h:= h + t1; d:= t1 + t2; t1:= c + (((h shr 14) or (h shl 50)) xor ((h shr 18) or (h shl 46)) xor ((h shr 41) or (h shl 23))) + ((h and a) xor (not h and b)) + $59f111f1b605d019 + W[5]; t2:= (((d shr 28) or (d shl 36)) xor ((d shr 34) or (d shl 30)) xor ((d shr 39) or (d shl 25))) + ((d and e) xor (d and f) xor (e and f)); g:= g + t1; c:= t1 + t2; t1:= b + (((g shr 14) or (g shl 50)) xor ((g shr 18) or (g shl 46)) xor ((g shr 41) or (g shl 23))) + ((g and h) xor (not g and a)) + $923f82a4af194f9b + W[6]; t2:= (((c shr 28) or (c shl 36)) xor ((c shr 34) or (c shl 30)) xor ((c shr 39) or (c shl 25))) + ((c and d) xor (c and e) xor (d and e)); f:= f + t1; b:= t1 + t2; t1:= a + (((f shr 14) or (f shl 50)) xor ((f shr 18) or (f shl 46)) xor ((f shr 41) or (f shl 23))) + ((f and g) xor (not f and h)) + $ab1c5ed5da6d8118 + W[7]; t2:= (((b shr 28) or (b shl 36)) xor ((b shr 34) or (b shl 30)) xor ((b shr 39) or (b shl 25))) + ((b and c) xor (b and d) xor (c and d)); e:= e + t1; a:= t1 + t2; t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + $d807aa98a3030242 + W[8]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); d:= d + t1; h:= t1 + t2; t1:= g + (((d shr 14) or (d shl 50)) xor ((d shr 18) or (d shl 46)) xor ((d shr 41) or (d shl 23))) + ((d and e) xor (not d and f)) + $12835b0145706fbe + W[9]; t2:= (((h shr 28) or (h shl 36)) xor ((h shr 34) or (h shl 30)) xor ((h shr 39) or (h shl 25))) + ((h and a) xor (h and b) xor (a and b)); c:= c + t1; g:= t1 + t2; t1:= f + (((c shr 14) or (c shl 50)) xor ((c shr 18) or (c shl 46)) xor ((c shr 41) or (c shl 23))) + ((c and d) xor (not c and e)) + $243185be4ee4b28c + W[10]; t2:= (((g shr 28) or (g shl 36)) xor ((g shr 34) or (g shl 30)) xor ((g shr 39) or (g shl 25))) + ((g and h) xor (g and a) xor (h and a)); b:= b + t1; f:= t1 + t2; t1:= e + (((b shr 14) or (b shl 50)) xor ((b shr 18) or (b shl 46)) xor ((b shr 41) or (b shl 23))) + ((b and c) xor (not b and d)) + $550c7dc3d5ffb4e2 + W[11]; t2:= (((f shr 28) or (f shl 36)) xor ((f shr 34) or (f shl 30)) xor ((f shr 39) or (f shl 25))) + ((f and g) xor (f and h) xor (g and h)); a:= a + t1; e:= t1 + t2; t1:= d + (((a shr 14) or (a shl 50)) xor ((a shr 18) or (a shl 46)) xor ((a shr 41) or (a shl 23))) + ((a and b) xor (not a and c)) + $72be5d74f27b896f + W[12]; t2:= (((e shr 28) or (e shl 36)) xor ((e shr 34) or (e shl 30)) xor ((e shr 39) or (e shl 25))) + ((e and f) xor (e and g) xor (f and g)); h:= h + t1; d:= t1 + t2; t1:= c + (((h shr 14) or (h shl 50)) xor ((h shr 18) or (h shl 46)) xor ((h shr 41) or (h shl 23))) + ((h and a) xor (not h and b)) + $80deb1fe3b1696b1 + W[13]; t2:= (((d shr 28) or (d shl 36)) xor ((d shr 34) or (d shl 30)) xor ((d shr 39) or (d shl 25))) + ((d and e) xor (d and f) xor (e and f)); g:= g + t1; c:= t1 + t2; t1:= b + (((g shr 14) or (g shl 50)) xor ((g shr 18) or (g shl 46)) xor ((g shr 41) or (g shl 23))) + ((g and h) xor (not g and a)) + $9bdc06a725c71235 + W[14]; t2:= (((c shr 28) or (c shl 36)) xor ((c shr 34) or (c shl 30)) xor ((c shr 39) or (c shl 25))) + ((c and d) xor (c and e) xor (d and e)); f:= f + t1; b:= t1 + t2; t1:= a + (((f shr 14) or (f shl 50)) xor ((f shr 18) or (f shl 46)) xor ((f shr 41) or (f shl 23))) + ((f and g) xor (not f and h)) + $c19bf174cf692694 + W[15]; t2:= (((b shr 28) or (b shl 36)) xor ((b shr 34) or (b shl 30)) xor ((b shr 39) or (b shl 25))) + ((b and c) xor (b and d) xor (c and d)); e:= e + t1; a:= t1 + t2; t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + $e49b69c19ef14ad2 + W[16]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); d:= d + t1; h:= t1 + t2; t1:= g + (((d shr 14) or (d shl 50)) xor ((d shr 18) or (d shl 46)) xor ((d shr 41) or (d shl 23))) + ((d and e) xor (not d and f)) + $efbe4786384f25e3 + W[17]; t2:= (((h shr 28) or (h shl 36)) xor ((h shr 34) or (h shl 30)) xor ((h shr 39) or (h shl 25))) + ((h and a) xor (h and b) xor (a and b)); c:= c + t1; g:= t1 + t2; t1:= f + (((c shr 14) or (c shl 50)) xor ((c shr 18) or (c shl 46)) xor ((c shr 41) or (c shl 23))) + ((c and d) xor (not c and e)) + $0fc19dc68b8cd5b5 + W[18]; t2:= (((g shr 28) or (g shl 36)) xor ((g shr 34) or (g shl 30)) xor ((g shr 39) or (g shl 25))) + ((g and h) xor (g and a) xor (h and a)); b:= b + t1; f:= t1 + t2; t1:= e + (((b shr 14) or (b shl 50)) xor ((b shr 18) or (b shl 46)) xor ((b shr 41) or (b shl 23))) + ((b and c) xor (not b and d)) + $240ca1cc77ac9c65 + W[19]; t2:= (((f shr 28) or (f shl 36)) xor ((f shr 34) or (f shl 30)) xor ((f shr 39) or (f shl 25))) + ((f and g) xor (f and h) xor (g and h)); a:= a + t1; e:= t1 + t2; t1:= d + (((a shr 14) or (a shl 50)) xor ((a shr 18) or (a shl 46)) xor ((a shr 41) or (a shl 23))) + ((a and b) xor (not a and c)) + $2de92c6f592b0275 + W[20]; t2:= (((e shr 28) or (e shl 36)) xor ((e shr 34) or (e shl 30)) xor ((e shr 39) or (e shl 25))) + ((e and f) xor (e and g) xor (f and g)); h:= h + t1; d:= t1 + t2; t1:= c + (((h shr 14) or (h shl 50)) xor ((h shr 18) or (h shl 46)) xor ((h shr 41) or (h shl 23))) + ((h and a) xor (not h and b)) + $4a7484aa6ea6e483 + W[21]; t2:= (((d shr 28) or (d shl 36)) xor ((d shr 34) or (d shl 30)) xor ((d shr 39) or (d shl 25))) + ((d and e) xor (d and f) xor (e and f)); g:= g + t1; c:= t1 + t2; t1:= b + (((g shr 14) or (g shl 50)) xor ((g shr 18) or (g shl 46)) xor ((g shr 41) or (g shl 23))) + ((g and h) xor (not g and a)) + $5cb0a9dcbd41fbd4 + W[22]; t2:= (((c shr 28) or (c shl 36)) xor ((c shr 34) or (c shl 30)) xor ((c shr 39) or (c shl 25))) + ((c and d) xor (c and e) xor (d and e)); f:= f + t1; b:= t1 + t2; t1:= a + (((f shr 14) or (f shl 50)) xor ((f shr 18) or (f shl 46)) xor ((f shr 41) or (f shl 23))) + ((f and g) xor (not f and h)) + $76f988da831153b5 + W[23]; t2:= (((b shr 28) or (b shl 36)) xor ((b shr 34) or (b shl 30)) xor ((b shr 39) or (b shl 25))) + ((b and c) xor (b and d) xor (c and d)); e:= e + t1; a:= t1 + t2; t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + $983e5152ee66dfab + W[24]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); d:= d + t1; h:= t1 + t2; t1:= g + (((d shr 14) or (d shl 50)) xor ((d shr 18) or (d shl 46)) xor ((d shr 41) or (d shl 23))) + ((d and e) xor (not d and f)) + $a831c66d2db43210 + W[25]; t2:= (((h shr 28) or (h shl 36)) xor ((h shr 34) or (h shl 30)) xor ((h shr 39) or (h shl 25))) + ((h and a) xor (h and b) xor (a and b)); c:= c + t1; g:= t1 + t2; t1:= f + (((c shr 14) or (c shl 50)) xor ((c shr 18) or (c shl 46)) xor ((c shr 41) or (c shl 23))) + ((c and d) xor (not c and e)) + $b00327c898fb213f + W[26]; t2:= (((g shr 28) or (g shl 36)) xor ((g shr 34) or (g shl 30)) xor ((g shr 39) or (g shl 25))) + ((g and h) xor (g and a) xor (h and a)); b:= b + t1; f:= t1 + t2; t1:= e + (((b shr 14) or (b shl 50)) xor ((b shr 18) or (b shl 46)) xor ((b shr 41) or (b shl 23))) + ((b and c) xor (not b and d)) + $bf597fc7beef0ee4 + W[27]; t2:= (((f shr 28) or (f shl 36)) xor ((f shr 34) or (f shl 30)) xor ((f shr 39) or (f shl 25))) + ((f and g) xor (f and h) xor (g and h)); a:= a + t1; e:= t1 + t2; t1:= d + (((a shr 14) or (a shl 50)) xor ((a shr 18) or (a shl 46)) xor ((a shr 41) or (a shl 23))) + ((a and b) xor (not a and c)) + $c6e00bf33da88fc2 + W[28]; t2:= (((e shr 28) or (e shl 36)) xor ((e shr 34) or (e shl 30)) xor ((e shr 39) or (e shl 25))) + ((e and f) xor (e and g) xor (f and g)); h:= h + t1; d:= t1 + t2; t1:= c + (((h shr 14) or (h shl 50)) xor ((h shr 18) or (h shl 46)) xor ((h shr 41) or (h shl 23))) + ((h and a) xor (not h and b)) + $d5a79147930aa725 + W[29]; t2:= (((d shr 28) or (d shl 36)) xor ((d shr 34) or (d shl 30)) xor ((d shr 39) or (d shl 25))) + ((d and e) xor (d and f) xor (e and f)); g:= g + t1; c:= t1 + t2; t1:= b + (((g shr 14) or (g shl 50)) xor ((g shr 18) or (g shl 46)) xor ((g shr 41) or (g shl 23))) + ((g and h) xor (not g and a)) + $06ca6351e003826f + W[30]; t2:= (((c shr 28) or (c shl 36)) xor ((c shr 34) or (c shl 30)) xor ((c shr 39) or (c shl 25))) + ((c and d) xor (c and e) xor (d and e)); f:= f + t1; b:= t1 + t2; t1:= a + (((f shr 14) or (f shl 50)) xor ((f shr 18) or (f shl 46)) xor ((f shr 41) or (f shl 23))) + ((f and g) xor (not f and h)) + $142929670a0e6e70 + W[31]; t2:= (((b shr 28) or (b shl 36)) xor ((b shr 34) or (b shl 30)) xor ((b shr 39) or (b shl 25))) + ((b and c) xor (b and d) xor (c and d)); e:= e + t1; a:= t1 + t2; t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + $27b70a8546d22ffc + W[32]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); d:= d + t1; h:= t1 + t2; t1:= g + (((d shr 14) or (d shl 50)) xor ((d shr 18) or (d shl 46)) xor ((d shr 41) or (d shl 23))) + ((d and e) xor (not d and f)) + $2e1b21385c26c926 + W[33]; t2:= (((h shr 28) or (h shl 36)) xor ((h shr 34) or (h shl 30)) xor ((h shr 39) or (h shl 25))) + ((h and a) xor (h and b) xor (a and b)); c:= c + t1; g:= t1 + t2; t1:= f + (((c shr 14) or (c shl 50)) xor ((c shr 18) or (c shl 46)) xor ((c shr 41) or (c shl 23))) + ((c and d) xor (not c and e)) + $4d2c6dfc5ac42aed + W[34]; t2:= (((g shr 28) or (g shl 36)) xor ((g shr 34) or (g shl 30)) xor ((g shr 39) or (g shl 25))) + ((g and h) xor (g and a) xor (h and a)); b:= b + t1; f:= t1 + t2; t1:= e + (((b shr 14) or (b shl 50)) xor ((b shr 18) or (b shl 46)) xor ((b shr 41) or (b shl 23))) + ((b and c) xor (not b and d)) + $53380d139d95b3df + W[35]; t2:= (((f shr 28) or (f shl 36)) xor ((f shr 34) or (f shl 30)) xor ((f shr 39) or (f shl 25))) + ((f and g) xor (f and h) xor (g and h)); a:= a + t1; e:= t1 + t2; t1:= d + (((a shr 14) or (a shl 50)) xor ((a shr 18) or (a shl 46)) xor ((a shr 41) or (a shl 23))) + ((a and b) xor (not a and c)) + $650a73548baf63de + W[36]; t2:= (((e shr 28) or (e shl 36)) xor ((e shr 34) or (e shl 30)) xor ((e shr 39) or (e shl 25))) + ((e and f) xor (e and g) xor (f and g)); h:= h + t1; d:= t1 + t2; t1:= c + (((h shr 14) or (h shl 50)) xor ((h shr 18) or (h shl 46)) xor ((h shr 41) or (h shl 23))) + ((h and a) xor (not h and b)) + $766a0abb3c77b2a8 + W[37]; t2:= (((d shr 28) or (d shl 36)) xor ((d shr 34) or (d shl 30)) xor ((d shr 39) or (d shl 25))) + ((d and e) xor (d and f) xor (e and f)); g:= g + t1; c:= t1 + t2; t1:= b + (((g shr 14) or (g shl 50)) xor ((g shr 18) or (g shl 46)) xor ((g shr 41) or (g shl 23))) + ((g and h) xor (not g and a)) + $81c2c92e47edaee6 + W[38]; t2:= (((c shr 28) or (c shl 36)) xor ((c shr 34) or (c shl 30)) xor ((c shr 39) or (c shl 25))) + ((c and d) xor (c and e) xor (d and e)); f:= f + t1; b:= t1 + t2; t1:= a + (((f shr 14) or (f shl 50)) xor ((f shr 18) or (f shl 46)) xor ((f shr 41) or (f shl 23))) + ((f and g) xor (not f and h)) + $92722c851482353b + W[39]; t2:= (((b shr 28) or (b shl 36)) xor ((b shr 34) or (b shl 30)) xor ((b shr 39) or (b shl 25))) + ((b and c) xor (b and d) xor (c and d)); e:= e + t1; a:= t1 + t2; t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + $a2bfe8a14cf10364 + W[40]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); d:= d + t1; h:= t1 + t2; t1:= g + (((d shr 14) or (d shl 50)) xor ((d shr 18) or (d shl 46)) xor ((d shr 41) or (d shl 23))) + ((d and e) xor (not d and f)) + $a81a664bbc423001 + W[41]; t2:= (((h shr 28) or (h shl 36)) xor ((h shr 34) or (h shl 30)) xor ((h shr 39) or (h shl 25))) + ((h and a) xor (h and b) xor (a and b)); c:= c + t1; g:= t1 + t2; t1:= f + (((c shr 14) or (c shl 50)) xor ((c shr 18) or (c shl 46)) xor ((c shr 41) or (c shl 23))) + ((c and d) xor (not c and e)) + $c24b8b70d0f89791 + W[42]; t2:= (((g shr 28) or (g shl 36)) xor ((g shr 34) or (g shl 30)) xor ((g shr 39) or (g shl 25))) + ((g and h) xor (g and a) xor (h and a)); b:= b + t1; f:= t1 + t2; t1:= e + (((b shr 14) or (b shl 50)) xor ((b shr 18) or (b shl 46)) xor ((b shr 41) or (b shl 23))) + ((b and c) xor (not b and d)) + $c76c51a30654be30 + W[43]; t2:= (((f shr 28) or (f shl 36)) xor ((f shr 34) or (f shl 30)) xor ((f shr 39) or (f shl 25))) + ((f and g) xor (f and h) xor (g and h)); a:= a + t1; e:= t1 + t2; t1:= d + (((a shr 14) or (a shl 50)) xor ((a shr 18) or (a shl 46)) xor ((a shr 41) or (a shl 23))) + ((a and b) xor (not a and c)) + $d192e819d6ef5218 + W[44]; t2:= (((e shr 28) or (e shl 36)) xor ((e shr 34) or (e shl 30)) xor ((e shr 39) or (e shl 25))) + ((e and f) xor (e and g) xor (f and g)); h:= h + t1; d:= t1 + t2; t1:= c + (((h shr 14) or (h shl 50)) xor ((h shr 18) or (h shl 46)) xor ((h shr 41) or (h shl 23))) + ((h and a) xor (not h and b)) + $d69906245565a910 + W[45]; t2:= (((d shr 28) or (d shl 36)) xor ((d shr 34) or (d shl 30)) xor ((d shr 39) or (d shl 25))) + ((d and e) xor (d and f) xor (e and f)); g:= g + t1; c:= t1 + t2; t1:= b + (((g shr 14) or (g shl 50)) xor ((g shr 18) or (g shl 46)) xor ((g shr 41) or (g shl 23))) + ((g and h) xor (not g and a)) + $f40e35855771202a + W[46]; t2:= (((c shr 28) or (c shl 36)) xor ((c shr 34) or (c shl 30)) xor ((c shr 39) or (c shl 25))) + ((c and d) xor (c and e) xor (d and e)); f:= f + t1; b:= t1 + t2; t1:= a + (((f shr 14) or (f shl 50)) xor ((f shr 18) or (f shl 46)) xor ((f shr 41) or (f shl 23))) + ((f and g) xor (not f and h)) + $106aa07032bbd1b8 + W[47]; t2:= (((b shr 28) or (b shl 36)) xor ((b shr 34) or (b shl 30)) xor ((b shr 39) or (b shl 25))) + ((b and c) xor (b and d) xor (c and d)); e:= e + t1; a:= t1 + t2; t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + $19a4c116b8d2d0c8 + W[48]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); d:= d + t1; h:= t1 + t2; t1:= g + (((d shr 14) or (d shl 50)) xor ((d shr 18) or (d shl 46)) xor ((d shr 41) or (d shl 23))) + ((d and e) xor (not d and f)) + $1e376c085141ab53 + W[49]; t2:= (((h shr 28) or (h shl 36)) xor ((h shr 34) or (h shl 30)) xor ((h shr 39) or (h shl 25))) + ((h and a) xor (h and b) xor (a and b)); c:= c + t1; g:= t1 + t2; t1:= f + (((c shr 14) or (c shl 50)) xor ((c shr 18) or (c shl 46)) xor ((c shr 41) or (c shl 23))) + ((c and d) xor (not c and e)) + $2748774cdf8eeb99 + W[50]; t2:= (((g shr 28) or (g shl 36)) xor ((g shr 34) or (g shl 30)) xor ((g shr 39) or (g shl 25))) + ((g and h) xor (g and a) xor (h and a)); b:= b + t1; f:= t1 + t2; t1:= e + (((b shr 14) or (b shl 50)) xor ((b shr 18) or (b shl 46)) xor ((b shr 41) or (b shl 23))) + ((b and c) xor (not b and d)) + $34b0bcb5e19b48a8 + W[51]; t2:= (((f shr 28) or (f shl 36)) xor ((f shr 34) or (f shl 30)) xor ((f shr 39) or (f shl 25))) + ((f and g) xor (f and h) xor (g and h)); a:= a + t1; e:= t1 + t2; t1:= d + (((a shr 14) or (a shl 50)) xor ((a shr 18) or (a shl 46)) xor ((a shr 41) or (a shl 23))) + ((a and b) xor (not a and c)) + $391c0cb3c5c95a63 + W[52]; t2:= (((e shr 28) or (e shl 36)) xor ((e shr 34) or (e shl 30)) xor ((e shr 39) or (e shl 25))) + ((e and f) xor (e and g) xor (f and g)); h:= h + t1; d:= t1 + t2; t1:= c + (((h shr 14) or (h shl 50)) xor ((h shr 18) or (h shl 46)) xor ((h shr 41) or (h shl 23))) + ((h and a) xor (not h and b)) + $4ed8aa4ae3418acb + W[53]; t2:= (((d shr 28) or (d shl 36)) xor ((d shr 34) or (d shl 30)) xor ((d shr 39) or (d shl 25))) + ((d and e) xor (d and f) xor (e and f)); g:= g + t1; c:= t1 + t2; t1:= b + (((g shr 14) or (g shl 50)) xor ((g shr 18) or (g shl 46)) xor ((g shr 41) or (g shl 23))) + ((g and h) xor (not g and a)) + $5b9cca4f7763e373 + W[54]; t2:= (((c shr 28) or (c shl 36)) xor ((c shr 34) or (c shl 30)) xor ((c shr 39) or (c shl 25))) + ((c and d) xor (c and e) xor (d and e)); f:= f + t1; b:= t1 + t2; t1:= a + (((f shr 14) or (f shl 50)) xor ((f shr 18) or (f shl 46)) xor ((f shr 41) or (f shl 23))) + ((f and g) xor (not f and h)) + $682e6ff3d6b2b8a3 + W[55]; t2:= (((b shr 28) or (b shl 36)) xor ((b shr 34) or (b shl 30)) xor ((b shr 39) or (b shl 25))) + ((b and c) xor (b and d) xor (c and d)); e:= e + t1; a:= t1 + t2; t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + $748f82ee5defb2fc + W[56]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); d:= d + t1; h:= t1 + t2; t1:= g + (((d shr 14) or (d shl 50)) xor ((d shr 18) or (d shl 46)) xor ((d shr 41) or (d shl 23))) + ((d and e) xor (not d and f)) + $78a5636f43172f60 + W[57]; t2:= (((h shr 28) or (h shl 36)) xor ((h shr 34) or (h shl 30)) xor ((h shr 39) or (h shl 25))) + ((h and a) xor (h and b) xor (a and b)); c:= c + t1; g:= t1 + t2; t1:= f + (((c shr 14) or (c shl 50)) xor ((c shr 18) or (c shl 46)) xor ((c shr 41) or (c shl 23))) + ((c and d) xor (not c and e)) + $84c87814a1f0ab72 + W[58]; t2:= (((g shr 28) or (g shl 36)) xor ((g shr 34) or (g shl 30)) xor ((g shr 39) or (g shl 25))) + ((g and h) xor (g and a) xor (h and a)); b:= b + t1; f:= t1 + t2; t1:= e + (((b shr 14) or (b shl 50)) xor ((b shr 18) or (b shl 46)) xor ((b shr 41) or (b shl 23))) + ((b and c) xor (not b and d)) + $8cc702081a6439ec + W[59]; t2:= (((f shr 28) or (f shl 36)) xor ((f shr 34) or (f shl 30)) xor ((f shr 39) or (f shl 25))) + ((f and g) xor (f and h) xor (g and h)); a:= a + t1; e:= t1 + t2; t1:= d + (((a shr 14) or (a shl 50)) xor ((a shr 18) or (a shl 46)) xor ((a shr 41) or (a shl 23))) + ((a and b) xor (not a and c)) + $90befffa23631e28 + W[60]; t2:= (((e shr 28) or (e shl 36)) xor ((e shr 34) or (e shl 30)) xor ((e shr 39) or (e shl 25))) + ((e and f) xor (e and g) xor (f and g)); h:= h + t1; d:= t1 + t2; t1:= c + (((h shr 14) or (h shl 50)) xor ((h shr 18) or (h shl 46)) xor ((h shr 41) or (h shl 23))) + ((h and a) xor (not h and b)) + $a4506cebde82bde9 + W[61]; t2:= (((d shr 28) or (d shl 36)) xor ((d shr 34) or (d shl 30)) xor ((d shr 39) or (d shl 25))) + ((d and e) xor (d and f) xor (e and f)); g:= g + t1; c:= t1 + t2; t1:= b + (((g shr 14) or (g shl 50)) xor ((g shr 18) or (g shl 46)) xor ((g shr 41) or (g shl 23))) + ((g and h) xor (not g and a)) + $bef9a3f7b2c67915 + W[62]; t2:= (((c shr 28) or (c shl 36)) xor ((c shr 34) or (c shl 30)) xor ((c shr 39) or (c shl 25))) + ((c and d) xor (c and e) xor (d and e)); f:= f + t1; b:= t1 + t2; t1:= a + (((f shr 14) or (f shl 50)) xor ((f shr 18) or (f shl 46)) xor ((f shr 41) or (f shl 23))) + ((f and g) xor (not f and h)) + $c67178f2e372532b + W[63]; t2:= (((b shr 28) or (b shl 36)) xor ((b shr 34) or (b shl 30)) xor ((b shr 39) or (b shl 25))) + ((b and c) xor (b and d) xor (c and d)); e:= e + t1; a:= t1 + t2; t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + $ca273eceea26619c + W[64]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); d:= d + t1; h:= t1 + t2; t1:= g + (((d shr 14) or (d shl 50)) xor ((d shr 18) or (d shl 46)) xor ((d shr 41) or (d shl 23))) + ((d and e) xor (not d and f)) + $d186b8c721c0c207 + W[65]; t2:= (((h shr 28) or (h shl 36)) xor ((h shr 34) or (h shl 30)) xor ((h shr 39) or (h shl 25))) + ((h and a) xor (h and b) xor (a and b)); c:= c + t1; g:= t1 + t2; t1:= f + (((c shr 14) or (c shl 50)) xor ((c shr 18) or (c shl 46)) xor ((c shr 41) or (c shl 23))) + ((c and d) xor (not c and e)) + $eada7dd6cde0eb1e + W[66]; t2:= (((g shr 28) or (g shl 36)) xor ((g shr 34) or (g shl 30)) xor ((g shr 39) or (g shl 25))) + ((g and h) xor (g and a) xor (h and a)); b:= b + t1; f:= t1 + t2; t1:= e + (((b shr 14) or (b shl 50)) xor ((b shr 18) or (b shl 46)) xor ((b shr 41) or (b shl 23))) + ((b and c) xor (not b and d)) + $f57d4f7fee6ed178 + W[67]; t2:= (((f shr 28) or (f shl 36)) xor ((f shr 34) or (f shl 30)) xor ((f shr 39) or (f shl 25))) + ((f and g) xor (f and h) xor (g and h)); a:= a + t1; e:= t1 + t2; t1:= d + (((a shr 14) or (a shl 50)) xor ((a shr 18) or (a shl 46)) xor ((a shr 41) or (a shl 23))) + ((a and b) xor (not a and c)) + $06f067aa72176fba + W[68]; t2:= (((e shr 28) or (e shl 36)) xor ((e shr 34) or (e shl 30)) xor ((e shr 39) or (e shl 25))) + ((e and f) xor (e and g) xor (f and g)); h:= h + t1; d:= t1 + t2; t1:= c + (((h shr 14) or (h shl 50)) xor ((h shr 18) or (h shl 46)) xor ((h shr 41) or (h shl 23))) + ((h and a) xor (not h and b)) + $0a637dc5a2c898a6 + W[69]; t2:= (((d shr 28) or (d shl 36)) xor ((d shr 34) or (d shl 30)) xor ((d shr 39) or (d shl 25))) + ((d and e) xor (d and f) xor (e and f)); g:= g + t1; c:= t1 + t2; t1:= b + (((g shr 14) or (g shl 50)) xor ((g shr 18) or (g shl 46)) xor ((g shr 41) or (g shl 23))) + ((g and h) xor (not g and a)) + $113f9804bef90dae + W[70]; t2:= (((c shr 28) or (c shl 36)) xor ((c shr 34) or (c shl 30)) xor ((c shr 39) or (c shl 25))) + ((c and d) xor (c and e) xor (d and e)); f:= f + t1; b:= t1 + t2; t1:= a + (((f shr 14) or (f shl 50)) xor ((f shr 18) or (f shl 46)) xor ((f shr 41) or (f shl 23))) + ((f and g) xor (not f and h)) + $1b710b35131c471b + W[71]; t2:= (((b shr 28) or (b shl 36)) xor ((b shr 34) or (b shl 30)) xor ((b shr 39) or (b shl 25))) + ((b and c) xor (b and d) xor (c and d)); e:= e + t1; a:= t1 + t2; t1:= h + (((e shr 14) or (e shl 50)) xor ((e shr 18) or (e shl 46)) xor ((e shr 41) or (e shl 23))) + ((e and f) xor (not e and g)) + $28db77f523047d84 + W[72]; t2:= (((a shr 28) or (a shl 36)) xor ((a shr 34) or (a shl 30)) xor ((a shr 39) or (a shl 25))) + ((a and b) xor (a and c) xor (b and c)); d:= d + t1; h:= t1 + t2; t1:= g + (((d shr 14) or (d shl 50)) xor ((d shr 18) or (d shl 46)) xor ((d shr 41) or (d shl 23))) + ((d and e) xor (not d and f)) + $32caab7b40c72493 + W[73]; t2:= (((h shr 28) or (h shl 36)) xor ((h shr 34) or (h shl 30)) xor ((h shr 39) or (h shl 25))) + ((h and a) xor (h and b) xor (a and b)); c:= c + t1; g:= t1 + t2; t1:= f + (((c shr 14) or (c shl 50)) xor ((c shr 18) or (c shl 46)) xor ((c shr 41) or (c shl 23))) + ((c and d) xor (not c and e)) + $3c9ebe0a15c9bebc + W[74]; t2:= (((g shr 28) or (g shl 36)) xor ((g shr 34) or (g shl 30)) xor ((g shr 39) or (g shl 25))) + ((g and h) xor (g and a) xor (h and a)); b:= b + t1; f:= t1 + t2; t1:= e + (((b shr 14) or (b shl 50)) xor ((b shr 18) or (b shl 46)) xor ((b shr 41) or (b shl 23))) + ((b and c) xor (not b and d)) + $431d67c49c100d4c + W[75]; t2:= (((f shr 28) or (f shl 36)) xor ((f shr 34) or (f shl 30)) xor ((f shr 39) or (f shl 25))) + ((f and g) xor (f and h) xor (g and h)); a:= a + t1; e:= t1 + t2; t1:= d + (((a shr 14) or (a shl 50)) xor ((a shr 18) or (a shl 46)) xor ((a shr 41) or (a shl 23))) + ((a and b) xor (not a and c)) + $4cc5d4becb3e42b6 + W[76]; t2:= (((e shr 28) or (e shl 36)) xor ((e shr 34) or (e shl 30)) xor ((e shr 39) or (e shl 25))) + ((e and f) xor (e and g) xor (f and g)); h:= h + t1; d:= t1 + t2; t1:= c + (((h shr 14) or (h shl 50)) xor ((h shr 18) or (h shl 46)) xor ((h shr 41) or (h shl 23))) + ((h and a) xor (not h and b)) + $597f299cfc657e2a + W[77]; t2:= (((d shr 28) or (d shl 36)) xor ((d shr 34) or (d shl 30)) xor ((d shr 39) or (d shl 25))) + ((d and e) xor (d and f) xor (e and f)); g:= g + t1; c:= t1 + t2; t1:= b + (((g shr 14) or (g shl 50)) xor ((g shr 18) or (g shl 46)) xor ((g shr 41) or (g shl 23))) + ((g and h) xor (not g and a)) + $5fcb6fab3ad6faec + W[78]; t2:= (((c shr 28) or (c shl 36)) xor ((c shr 34) or (c shl 30)) xor ((c shr 39) or (c shl 25))) + ((c and d) xor (c and e) xor (d and e)); f:= f + t1; b:= t1 + t2; t1:= a + (((f shr 14) or (f shl 50)) xor ((f shr 18) or (f shl 46)) xor ((f shr 41) or (f shl 23))) + ((f and g) xor (not f and h)) + $6c44198c4a475817 + W[79]; t2:= (((b shr 28) or (b shl 36)) xor ((b shr 34) or (b shl 30)) xor ((b shr 39) or (b shl 25))) + ((b and c) xor (b and d) xor (c and d)); e:= e + t1; a:= t1 + t2; CurrentHash[0]:= CurrentHash[0] + a; CurrentHash[1]:= CurrentHash[1] + b; CurrentHash[2]:= CurrentHash[2] + c; CurrentHash[3]:= CurrentHash[3] + d; CurrentHash[4]:= CurrentHash[4] + e; CurrentHash[5]:= CurrentHash[5] + f; CurrentHash[6]:= CurrentHash[6] + g; CurrentHash[7]:= CurrentHash[7] + h; FillChar(W,Sizeof(W),0); FillChar(HashBuffer,Sizeof(HashBuffer),0); end; procedure TDCP_sha512base.Burn; begin LenHi:= 0; LenLo:= 0; Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); FillChar(CurrentHash,Sizeof(CurrentHash),0); fInitialized:= false; end; procedure TDCP_sha512base.Update(const Buffer; Size: longword); var PBuf: ^byte; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); Inc(LenLo,Size*8); if LenLo< (Size*8) then Inc(LenHi); PBuf:= @Buffer; while Size> 0 do begin if (Sizeof(HashBuffer)-Index)<= DWord(Size) then begin Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index); Dec(Size,Sizeof(HashBuffer)-Index); Inc(PBuf,Sizeof(HashBuffer)-Index); Compress; end else begin Move(PBuf^,HashBuffer[Index],Size); Inc(Index,Size); Size:= 0; end; end; end; {******************************************************************************} class function TDCP_sha384.GetAlgorithm: string; begin Result:= 'SHA384'; end; class function TDCP_sha384.GetId: integer; begin Result:= DCP_sha384; end; class function TDCP_sha384.GetHashSize: integer; begin Result:= 384; end; class function TDCP_sha384.SelfTest: boolean; const Test1Out: array[0..47] of byte= ($cb,$00,$75,$3f,$45,$a3,$5e,$8b,$b5,$a0,$3d,$69,$9a,$c6,$50,$07, $27,$2c,$32,$ab,$0e,$de,$d1,$63,$1a,$8b,$60,$5a,$43,$ff,$5b,$ed, $80,$86,$07,$2b,$a1,$e7,$cc,$23,$58,$ba,$ec,$a1,$34,$c8,$25,$a7); Test2Out: array[0..47] of byte= ($09,$33,$0c,$33,$f7,$11,$47,$e8,$3d,$19,$2f,$c7,$82,$cd,$1b,$47, $53,$11,$1b,$17,$3b,$3b,$05,$d2,$2f,$a0,$80,$86,$e3,$b0,$f7,$12, $fc,$c7,$c7,$1a,$55,$7e,$2d,$b9,$66,$c3,$e9,$fa,$91,$74,$60,$39); var TestHash: TDCP_sha384; TestOut: array[0..47] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_sha384.Create(nil); TestHash.Init; TestHash.UpdateStr('abc'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out))); TestHash.Init; TestHash.UpdateStr('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out))) and Result; TestHash.Free; end; procedure TDCP_sha384.Init; begin Burn; CurrentHash[0]:= $cbbb9d5dc1059ed8; CurrentHash[1]:= $629a292a367cd507; CurrentHash[2]:= $9159015a3070dd17; CurrentHash[3]:= $152fecd8f70e5939; CurrentHash[4]:= $67332667ffc00b31; CurrentHash[5]:= $8eb44a8768581511; CurrentHash[6]:= $db0c2e0d64f98fa7; CurrentHash[7]:= $47b5481dbefa4fa4; fInitialized:= true; end; procedure TDCP_sha384.Final(var Digest); begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); HashBuffer[Index]:= $80; if Index>= 112 then Compress; Pint64(@HashBuffer[112])^:= SwapDWord(LenHi); Pint64(@HashBuffer[120])^:= SwapDWord(LenLo); Compress; CurrentHash[0]:= SwapDWord(CurrentHash[0]); CurrentHash[1]:= SwapDWord(CurrentHash[1]); CurrentHash[2]:= SwapDWord(CurrentHash[2]); CurrentHash[3]:= SwapDWord(CurrentHash[3]); CurrentHash[4]:= SwapDWord(CurrentHash[4]); CurrentHash[5]:= SwapDWord(CurrentHash[5]); Move(CurrentHash,Digest,384 div 8); Burn; end; {******************************************************************************} class function TDCP_sha512.GetAlgorithm: string; begin Result:= 'SHA512'; end; class function TDCP_sha512.GetId: integer; begin Result:= DCP_sha512; end; class function TDCP_sha512.GetHashSize: integer; begin Result:= 512; end; class function TDCP_sha512.SelfTest: boolean; const Test1Out: array[0..63] of byte= ($dd,$af,$35,$a1,$93,$61,$7a,$ba,$cc,$41,$73,$49,$ae,$20,$41,$31, $12,$e6,$fa,$4e,$89,$a9,$7e,$a2,$0a,$9e,$ee,$e6,$4b,$55,$d3,$9a, $21,$92,$99,$2a,$27,$4f,$c1,$a8,$36,$ba,$3c,$23,$a3,$fe,$eb,$bd, $45,$4d,$44,$23,$64,$3c,$e8,$0e,$2a,$9a,$c9,$4f,$a5,$4c,$a4,$9f); Test2Out: array[0..63] of byte= ($8e,$95,$9b,$75,$da,$e3,$13,$da,$8c,$f4,$f7,$28,$14,$fc,$14,$3f, $8f,$77,$79,$c6,$eb,$9f,$7f,$a1,$72,$99,$ae,$ad,$b6,$88,$90,$18, $50,$1d,$28,$9e,$49,$00,$f7,$e4,$33,$1b,$99,$de,$c4,$b5,$43,$3a, $c7,$d3,$29,$ee,$b6,$dd,$26,$54,$5e,$96,$e5,$5b,$87,$4b,$e9,$09); var TestHash: TDCP_sha512; TestOut: array[0..63] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_sha512.Create(nil); TestHash.Init; TestHash.UpdateStr('abc'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out))); TestHash.Init; TestHash.UpdateStr('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu'); TestHash.Final(TestOut); Result:= boolean(CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out))) and Result; TestHash.Free; end; procedure TDCP_sha512.Init; begin Burn; CurrentHash[0]:= $6a09e667f3bcc908; CurrentHash[1]:= $bb67ae8584caa73b; CurrentHash[2]:= $3c6ef372fe94f82b; CurrentHash[3]:= $a54ff53a5f1d36f1; CurrentHash[4]:= $510e527fade682d1; CurrentHash[5]:= $9b05688c2b3e6c1f; CurrentHash[6]:= $1f83d9abfb41bd6b; CurrentHash[7]:= $5be0cd19137e2179; fInitialized:= true; end; procedure TDCP_sha512.Final(var Digest); begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); HashBuffer[Index]:= $80; if Index>= 112 then Compress; Pint64(@HashBuffer[112])^:= SwapDWord(LenHi); Pint64(@HashBuffer[120])^:= SwapDWord(LenLo); Compress; CurrentHash[0]:= SwapDWord(CurrentHash[0]); CurrentHash[1]:= SwapDWord(CurrentHash[1]); CurrentHash[2]:= SwapDWord(CurrentHash[2]); CurrentHash[3]:= SwapDWord(CurrentHash[3]); CurrentHash[4]:= SwapDWord(CurrentHash[4]); CurrentHash[5]:= SwapDWord(CurrentHash[5]); CurrentHash[6]:= SwapDWord(CurrentHash[6]); CurrentHash[7]:= SwapDWord(CurrentHash[7]); Move(CurrentHash,Digest,Sizeof(CurrentHash)); Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/0000775000175000017500000000000013244011205021106 5ustar alexxalexxdoublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/sha3.pas0000664000175000017500000005207612726776751022517 0ustar alexxalexxunit SHA3; {SHA3 functions (including SHAKE) based on Keccak} interface {$i STD.INC} {$ifdef FPC} {$ifdef CPUI386} {$define USE_MMXCODE} {$endif} {$ifdef CPU64} {$define USE_64BITCODE} {$endif} {$endif} {.$define USE_64BITCODE} {Use 64-bit for Keccak permutation} {.$define USE_MMXCODE } {Use MMX for Keccak permutation, contributed by Eric Grange} {.$define USE_MMX_AKP } {Use MMX for Keccak permutation, contributed by Anna Kaliszewicz / payl} (************************************************************************* DESCRIPTION : SHA3 functions (including SHAKE) based on Keccak REQUIREMENTS : TP5-7, D1-D7/D9-D10/D12/D17-D18, FPC, VP EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REFERENCES : SHA3: FIPS 202 SHA-3 Standard: 'Permutation-Based Hash and Extendable-Output Functions' available from http://csrc.nist.gov/publications/PubsFIPS.html or http://dx.doi.org/10.6028/NIST.FIPS.202 or http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf Keccak: https://github.com/gvanas/KeccakCodePackage http://keccak.noekeon.org/KeccakReferenceAndOptimized-3.2.zip http://keccak.noekeon.org/KeccakKAT-3.zip (17MB) http://csrc.nist.gov/groups/ST/hash/documents/SHA3-C-API.pdf REMARKS : 1. For 32-bit compilers with int64 (FPC, D6+) there are conditional defines to optionally use MMX or 64-bit code. 2. The current implementation needs little-endian machines Version Date Author Modification ------- -------- ------- ------------------------------------------ 0.01 17.10.12 W.Ehrhardt Initial BP7 version from Keccak-simple32BI.c 0.02 18.10.12 we Fixed buf in xorIntoState 0.03 18.10.12 we Other compilers 0.04 19.10.12 we Separate unit 0.05 20.10.12 we Functions from KeccakSponge 0.06 21.10.12 we Functions from KeccakNISTInterface 0.07 21.10.12 we D2-D6 with ASM RotL function 0.08 22.10.12 we Include files keccperm.i16 and .i32 0.09 22.10.12 we __P2I type casts removed 0.10 22.10.12 we References, comments, remarks 0.11 25.10.12 we Make partialBlock longint 0.12 30.10.12 we Packed arrays, type TKDQueue 0.13 31.10.12 we Partially unrolled 64-bit code from Keccak-inplace.c 0.14 01.11.12 we Compact 64-bit code from Botan 0.15 02.11.12 we 64-bit code about 20% faster with local data 0.16 09.11.12 we KeccakFullBytes, TKeccakMaxDigest 0.17 12.11.12 we USE32BIT forces skipping of 64-bit code 0.18 12.04.14 we Unit renamed to SHA3, SHA3 type definitions 0.19 12.04.14 we SHA3_Init, SHA3_Update, SHA3_FinalEx 0.20 13.04.14 we SHA3_UpdateXL, SHA3_FinalHash, byte sized messages work 0.21 14.04.14 we LSB bit sized messages, SHA3_FinalBit_LSB, working SHAKE 0.22 11.05.14 we Fix duplicate return result and a few typos 0.23 08.08.15 we TSpongeState with words and Fill3, assert HASHCTXSIZE 0.24 09.08.15 we SHA3_FinalBit update final bits in MSB format 0.25 09.08.15 we Removed unused Keccak leftovers 0.26 09.08.15 we Error field in context, rewrite error handling 0.27 16.08.15 we Some code cleanup 0.28 17.08.15 we Updated references 0.29 26.08.15 we $defines USE_64BITCODE, USE_MMXCODE 0.30 23.04.16 we USE_MMX_AKP *************************************************************************) (*------------------------------------------------------------------------- (C) Copyright 2012-2016 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. --------------------------------------------------------------------------- *NOTE FROM THE DESIGNERS OF KECCAK* The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, Michael Peeters and Gilles Van Assche. For more information, feedback or questions, please refer to our website: http://keccak.noekeon.org/ Implementation by the designers (and Ronny Van Keer), hereby denoted as "the implementer". To the extent possible under law, the implementer has waived all copyright and related or neighboring rights to the source code in this file. http://creativecommons.org/publicdomain/zero/1.0/ ----------------------------------------------------------------------------*) uses BTypes, Hash; const SHA3_ERR_INVALID_ALG = 1; SHA3_ERR_WRONG_FINAL = 2; const KeccakPermutationSize = 1600; KeccakMaximumRate = 1536; KeccakPermutationSizeInBytes = KeccakPermutationSize div 8; KeccakMaximumRateInBytes = KeccakMaximumRate div 8; type TState_B = packed array[0..KeccakPermutationSizeInBytes-1] of byte; TState_L = packed array[0..(KeccakPermutationSizeInBytes) div 4 - 1] of longint; TKDQueue = packed array[0..KeccakMaximumRateInBytes-1] of byte; type TSpongeState = packed record state: TState_B; dataQueue: TKDQueue; rate: word; capacity: word; bitsInQueue: word; fixedOutputLength: word; bitsAvailableForSqueezing: word; squeezing: word; Error: int16; Fill3: packed array[407..HASHCTXSIZE] of byte; end; {---------------------------------------------------------------------------} {------------------ S H A 3 / S H A K E functions -----------------------} {---------------------------------------------------------------------------} type TSHA3State = TSpongeState; {Hash state context} type TSHA3_Algo = (__SHA3_224, __SHA3_256, __SHA3_384, __SHA3_512, __SHAKE_128, __SHAKE_256); function SHA3_Init(var state: TSHA3State; algo: TSHA3_Algo): integer; {-Initialize the state of the Keccak[r, c] sponge function. The rate r and the} { capacity c values are determined from the SHA3 algorithm. Result 0=success. } function SHA3_UpdateXL(var state: TSHA3State; Msg: pointer; Len: longint): integer; {-Update context with Msg data of Len bytes} function SHA3_Update(var state: TSHA3State; Msg: pointer; Len: word): integer; {-Update context with Msg data of Len bytes} function SHA3_FinalHash(var state: TSHA3State; digest: pointer): integer; {-Compute SHA3 hash digest and store into hashval. Only for hash} { algorithms, result WRONG_FINAL if called for SHAKE functions. } function SHA3_FinalBit_LSB(var state: TSHA3State; bits: byte; bitlen: integer; hashval: pointer; numbits: longint): integer; {-Update final bits in LSB format, pad, and compute hashval} function SHA3_FinalBit(var state: TSHA3State; bits: byte; bitlen: integer; hashval: pointer; numbits: longint): integer; {-Update final bits in MSB format, pad, and compute hashval} {SHA3_LastError is set by SHA-3 functions which return an error code, where other} {units/algorithms use procedures. Note that the error variable should be treated } {as dummy because it is shared over all contexts/threads etc. The context field } {TSHA3State.error is used to handle context related errors. It will be set to } {0=no error during context initialization.} var SHA3_LastError: integer; implementation const cKeccakNumberOfRounds = 24; {---------------------------------------------------------------------------} {Helper types} {$ifndef BIT16} type TBABytes = array[0..MaxLongint-1] of byte; {$else} type TBABytes = array[0..$FFF0-1] of byte; {$endif} type PBA = ^TBABytes; {---------------------------------------------------------------------------} {$ifndef BIT16} {$ifdef BIT64} {$define USE_64BITCODE} {$else} {$ifndef FPC} {$ifndef CONDITIONALEXPRESSIONS} {Delphi 5 or lower} {$undef USE_MMXCODE} {$undef USE_MMX_AKP} {$endif} {$endif} {$endif} {$ifdef USE_64BITCODE} {$i kperm_64.inc} {$ifdef HAS_MSG} {.$message '* using 64-bit code'} {$endif} {$else} {$ifdef USE_MMXCODE} {$i kperm_mx.inc} {$ifdef HAS_MSG} {$message '* using mmx code (32Bit/eg)'} {$endif} {$else} {$ifdef USE_MMX_AKP} {$i kperm_mp.inc} {$ifdef HAS_MSG} {$message '* using mmx code (32Bit/akp)'} {$endif} {$else} {$i kperm_32.inc} {$endif} {$endif} {$endif} {$else} {$i kperm_16.inc} {$endif} {---------------------------------------------------------------------------} procedure KeccakAbsorb(var state: TState_B; data: pointer; laneCount: integer); begin xorIntoState(TState_L(state),data,laneCount); KeccakPermutation(TState_L(state)); end; {---------------------------------------------------------------------------} function InitSponge(var state: TSpongeState; rate, capacity: integer): integer; {-Function to initialize the state of the Keccak sponge function.} { The sponge function is set to the absorbing phase. Result=0 if } { success, 1 if rate and/or capacity are invalid.} begin InitSponge := 1; {This is the only place where state.error is reset to 0 = SUCCESS} fillchar(state, sizeof(state),0); if (rate+capacity <> 1600) or (rate <= 0) or (rate >= 1600) or ((rate and 63) <> 0) then begin state.error := 1; exit; end; state.rate := rate; state.capacity := capacity; InitSponge := 0; end; {---------------------------------------------------------------------------} procedure AbsorbQueue(var state: TSpongeState); {-Absorb remaining bits from queue} begin {state.bitsInQueue is assumed to be equal to state.rate} KeccakAbsorb(state.state, @state.dataQueue, state.rate div 64); state.bitsInQueue := 0; end; {---------------------------------------------------------------------------} function Absorb(var state: TSpongeState; data: pointer; databitlen: longint): integer; {-Function to give input data for the sponge function to absorb} var i, j, wholeBlocks, partialBlock: longint; partialByte: integer; curData: pByte; begin Absorb := 1; if state.error<>0 then exit; {No further action} if (state.bitsInQueue and 7 <> 0) or (state.squeezing<>0) then begin {Only the last call may contain a partial byte} {and additional input if squeezing} state.error := 1; exit; end; i := 0; while i < databitlen do begin if ((state.bitsInQueue=0) and (databitlen >= state.rate) and (i <= (databitlen-state.rate))) then begin wholeBlocks := (databitlen-i) div state.rate; curData := @PBA(data)^[i div 8]; j := 0; while j state.rate then begin partialBlock := state.rate - state.bitsInQueue; end; partialByte := partialBlock and 7; dec(partialBlock, partialByte); move(PBA(data)^[i div 8], state.dataQueue[state.bitsInQueue div 8], partialBlock div 8); inc(state.bitsInQueue, partialBlock); inc(i, partialBlock); if state.bitsInQueue=state.rate then AbsorbQueue(state); if partialByte > 0 then begin state.dataQueue[state.bitsInQueue div 8] := PBA(data)^[i div 8] and ((1 shl partialByte)-1); inc(state.bitsInQueue, partialByte); inc(i, partialByte); end; end; end; Absorb := 0; end; {---------------------------------------------------------------------------} procedure PadAndSwitchToSqueezingPhase(var state: TSpongeState); var i: integer; begin {Note: the bits are numbered from 0=LSB to 7=MSB} if (state.bitsInQueue + 1 = state.rate) then begin i := state.bitsInQueue div 8; state.dataQueue[i] := state.dataQueue[i] or (1 shl (state.bitsInQueue and 7)); AbsorbQueue(state); fillchar(state.dataQueue, state.rate div 8, 0); end else begin i := state.bitsInQueue div 8; fillchar(state.dataQueue[(state.bitsInQueue+7) div 8], state.rate div 8 - (state.bitsInQueue+7) div 8,0); state.dataQueue[i] := state.dataQueue[i] or (1 shl (state.bitsInQueue and 7)); end; i := (state.rate-1) div 8; state.dataQueue[i] := state.dataQueue[i] or (1 shl ((state.rate-1) and 7)); AbsorbQueue(state); extractFromState(@state.dataQueue, TState_L(state.state), state.rate div 64); state.bitsAvailableForSqueezing := state.rate; state.squeezing := 1; end; {---------------------------------------------------------------------------} function Squeeze(var state: TSpongeState; output: pointer; outputLength: longint): integer; {-Squeeze output data from the sponge function. If the sponge function was } { in the absorbing phase, this function switches it to the squeezing phase.} { Returns 0 if successful, 1 otherwise. output: pointer to the buffer where} { to store the output data; outputLength: number of output bits desired, } { must be a multiple of 8.} var i: longint; partialBlock: integer; begin Squeeze := 1; if state.error<>0 then exit; {No further action} if state.squeezing=0 then PadAndSwitchToSqueezingPhase(state); if outputLength and 7 <> 0 then begin {Only multiple of 8 bits are allowed, truncation can be done at user level} state.error := 1; exit; end; i := 0; while i < outputLength do begin if state.bitsAvailableForSqueezing=0 then begin KeccakPermutation(TState_L(state.state)); extractFromState(@state.dataQueue, TState_L(state.state), state.rate div 64); state.bitsAvailableForSqueezing := state.rate; end; partialBlock := state.bitsAvailableForSqueezing; if partialBlock > outputLength - i then partialBlock := outputLength - i; move(state.dataQueue[(state.rate - state.bitsAvailableForSqueezing) div 8], PBA(output)^[i div 8], partialBlock div 8); dec(state.bitsAvailableForSqueezing, partialBlock); inc(i,partialBlock); end; Squeeze := 0; end; {---------------------------------------------------------------------------} function Update(var state: TSpongeState; data: pointer; databitlen: longint): integer; {-Update state with databitlen bits from data. May be called multiple times, } { only the last databitlen may be a non-multiple of 8 (the corresponding byte} { must be MSB aligned, i.e. in the (databitlen and 7) most significant bits. } var ret: integer; lastByte: byte; begin if state.error<>0 then begin Update := state.error; exit; end; if databitlen and 7 = 0 then ret := Absorb(state, data, databitlen) else begin ret := Absorb(state, data, databitlen - (databitlen and 7)); if ret=0 then begin {Align the last partial byte to the least significant bits} lastByte := PBA(data)^[databitlen div 8] shr (8 - (databitlen and 7)); ret := Absorb(state, @lastByte, databitlen and 7); end end; update := ret; {Update error only with old error=0, i.e. do no reset a non-zero value} if state.error=0 then state.error := ret; end; {---------------------------------------------------------------------------} {---------------------------------------------------------------------------} {---------------------------------------------------------------------------} {---------------------------------------------------------------------------} function SHA3_Init(var state: TSHA3State; algo: TSHA3_Algo): integer; {-Initialize the state of the Keccak[r, c] sponge function. The rate r and the} { capacity c values are determined from the SHA3 algorithm. Result 0=success. } const FOL: array[TSHA3_Algo] of word = (224, 256, 384, 512, 0, 0); begin case algo of __SHA3_224: SHA3_Init := InitSponge(state, 1152, 448); __SHA3_256: SHA3_Init := InitSponge(state, 1088, 512); __SHA3_384: SHA3_Init := InitSponge(state, 832, 768); __SHA3_512: SHA3_Init := InitSponge(state, 576, 1024); __SHAKE_128: SHA3_Init := InitSponge(state, 1344, 256); __SHAKE_256: SHA3_Init := InitSponge(state, 1088, 512); else begin SHA3_Init := SHA3_ERR_INVALID_ALG; state.error := SHA3_ERR_INVALID_ALG; exit; end; end; state.fixedOutputLength := FOL[algo]; end; {---------------------------------------------------------------------------} function SHA3_UpdateXL(var state: TSHA3State; Msg: pointer; Len: longint): integer; {-Update context with Msg data of Len bytes} begin SHA3_UpdateXL := Absorb(state, Msg, Len*8); end; {---------------------------------------------------------------------------} function SHA3_Update(var state: TSHA3State; Msg: pointer; Len: word): integer; {-Update context with Msg data of Len bytes} begin SHA3_Update := SHA3_UpdateXL(state, Msg, Len); end; {---------------------------------------------------------------------------} function SHA3_FinalHash(var state: TSHA3State; digest: pointer): integer; {-Compute SHA3 hash digest and store into hashval. Only for hash} { algorithms, result WRONG_FINAL if called for Shake functions. } var err: integer; begin err := 1; if state.error=0 then begin if state.fixedOutputLength=0 then err := SHA3_ERR_WRONG_FINAL else err := SHA3_FinalBit_LSB(state, 0, 0, digest, state.fixedOutputLength); end; {Update error only with old error=0, i.e. do no reset a non-zero value} if state.error=0 then state.error := err; SHA3_FinalHash := err; end; {---------------------------------------------------------------------------} function SHA3_FinalBit_LSB(var state: TSHA3State; bits: byte; bitlen: integer; hashval: pointer; numbits: longint): integer; {-Update final bits in LSB format, pad, and compute hashval} var err,ll: integer; lw: word; begin {normalize bitlen and bits (zero high bits)} bitlen := bitlen and 7; if bitlen=0 then lw := 0 else lw := bits and pred(word(1) shl bitlen); {'append' (in LSB language) the domain separation bits} if state.fixedOutputLength=0 then begin {SHAKE: append four bits 1111} lw := lw or (word($F) shl bitlen); ll := bitlen+4; end else begin {SHA3: append two bits 01} lw := lw or (word($2) shl bitlen); ll := bitlen+2; end; {update state with final bits} if ll<9 then begin {0..8 bits, one call to update} lw := lw shl (8-ll); err := update(state, @lw, ll); {squeeze the digits from the sponge} if err=0 then err := Squeeze(state, hashval, numbits); end else begin {More than 8 bits, first a regular update with low byte} err := update(state, @lw, 8); if err=0 then begin {Finally update remaining last bits} dec(ll,8); lw := lw shr ll; err := update(state, @lw, ll); if err=0 then err := Squeeze(state, hashval, numbits); end; end; SHA3_FinalBit_LSB := err; if state.error=0 then state.error := err; end; {---------------------------------------------------------------------------} function SHA3_FinalBit(var state: TSHA3State; bits: byte; bitlen: integer; hashval: pointer; numbits: longint): integer; {-Update final bits in MSB format, pad, and compute hashval} var i,m: integer; r,b: byte; begin r := 0; m := bitlen and $7; if m>0 then begin {right align the m bits} b := bits shr (8-m); {store reflected bits in r} for i:=m downto 1 do begin r := r + r + (b and 1); b := b shr 1; end; end; SHA3_FinalBit := SHA3_FinalBit_LSB(state,r,bitlen,hashval,numbits); end; begin {$ifdef HAS_ASSERT} assert(sizeof(TSHA3State)=HASHCTXSIZE , '** Invalid sizeof(TSHA3State)'); {$else} if sizeof(THashContext)<>HASHCTXSIZE then RunError(227); {$endif} SHA3_LastError := 0; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/memh.pas0000664000175000017500000001367513146261166022573 0ustar alexxalexxunit memh; {Basic portable heap memory allocation functions} interface {$i STD.INC} (************************************************************************* DESCRIPTION : Basic portable heap memory allocation functions REQUIREMENTS : TP5-7, D1-D7/D9-D10/D12/D17-D18, FPC, VP, WDOSX EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REMARK : 16-bit compilers and sizes >= $10000: alloc functions return nil, free procedures do nothing! Version Date Author Modification ------- -------- ------- ------------------------------------------ 0.10 15.04.14 W.Ehrhardt Initial version with malloc/mfree 0.11 16.04.14 we calloc/cfree 0.12 16.04.14 we use untyped var p in free routines 0.13 17.04.14 we ialloc with longint size 0.14 17.04.14 we long versions 0.15 18.04.14 we remove word versions, rename long versions **************************************************************************) (*------------------------------------------------------------------------- (C) Copyright 2014 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ----------------------------------------------------------------------------*) function malloc(size: longint): pointer; {-Allocate heap, return nil if error} function calloc(size: longint): pointer; {-Allocate heap, return nil if error, clear allocated memory to 0} procedure mfree(var p; size: longint); {-Deallocate heap if p<>nil, p will be set to nil} procedure cfree(var p; size: longint); {-Deallocate heap if p<>nil, p will be set to nil, memory set to 0} implementation {$ifdef BIT16} {$F+} {--------------------------------------------------------------------------} function HeapFunc(Size: word): integer; {-Forces nil return values instead of runtime error if out of memory} begin if size>0 then HeapFunc := 1; end; {---------------------------------------------------------------------------} function ialloc(size: longint; set0: boolean): pointer; {-Allocate heap, return nil if error, clear allocated memory to 0 if set0} var p, SaveHeapError : pointer; wsize: word absolute size; type LH = packed record L,H: word; end; begin if LH(size).H<>0 then ialloc := nil else begin SaveHeapError := HeapError; HeapError := @HeapFunc; getmem(p, wsize); HeapError := SaveHeapError; if (p<>nil) and set0 then fillchar(p^,wsize,0); ialloc := p; end; end; {---------------------------------------------------------------------------} procedure ifree(var p; size: longint; set0: boolean); {-Dellocate heap if p<>nil, set p=nil, clear allocated memory to 0 if set0} var pp: pointer absolute p; wsize: word absolute size; type LH = packed record L,H: word; end; begin if (pp<>nil) and (LH(size).H=0) then begin if set0 then fillchar(pp^, wsize, 0); freemem(pp, wsize); pp := nil; end; end; {$else} {---------------------------------------------------------------------------} procedure ifree(var p; size: longint; set0: boolean); {-Dellocate heap if p<>nil, set p=nil, clear allocated memory to 0 if set0} var pp: pointer absolute p; begin if pp<>nil then begin if set0 then fillchar(pp^, size, 0); freemem(pp, size); pp := nil; end; end; {$ifdef FPC} {---------------------------------------------------------------------------} function ialloc(size: longint; set0: boolean): pointer; {-Allocate heap, return nil if error, clear allocated memory to 0 if set0} var p: pointer; sh: boolean; begin sh := ReturnNilIfGrowHeapFails; ReturnNilIfGrowHeapFails := true; getmem(p, size); ReturnNilIfGrowHeapFails := sh; if (p<>nil) and set0 then fillchar(p^,size,0); ialloc := p; end; {$else} {---------------------------------------------------------------------------} function ialloc(size: longint; set0: boolean): pointer; {-Allocate heap, return nil if error, clear allocated memory to 0 if set0} var p: pointer; begin try getmem(p, size); except p := nil; end; if (p<>nil) and set0 then fillchar(p^,size,0); ialloc := p; end; {$endif} {$endif} {---------------------------------------------------------------------------} function malloc(size: longint): pointer; {-Allocate heap, return nil if error} begin malloc := ialloc(size,false); end; {---------------------------------------------------------------------------} function calloc(size: longint): pointer; {-Allocate heap, return nil if error, clear allocated memory to 0} begin calloc := ialloc(size,true); end; {---------------------------------------------------------------------------} procedure mfree(var p; size: longint); {-Deallocate heap if p<>nil, p will be set to nil} begin ifree(p,size,false); end; {---------------------------------------------------------------------------} procedure cfree(var p; size: longint); {-Deallocate heap if p<>nil, p will be set to nil, memory set to 0} begin ifree(p,size,true); end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/doublecmd.diff0000664000175000017500000000643513216540737023726 0ustar alexxalexxIndex: kperm_64.inc =================================================================== --- kperm_64.inc (revision 6895) +++ kperm_64.inc (working copy) @@ -33,10 +33,14 @@ {---------------------------------------------------------------------------} +{$IFDEF FPC} + {$MACRO ON} {$DEFINE RotL:= RolQWord} +{$ELSE} function RotL(x: u64bit; c: integer): u64bit; {$ifdef HAS_INLINE} inline; {$endif} begin RotL := (x shl c) or (x shr (64-c)); end; +{$ENDIF} {---------------------------------------------------------------------------} Index: sha1.pas =================================================================== --- sha1.pas +++ sha1.pas @@ -106,7 +106,7 @@ {$i STD.INC} -{$ifdef BIT64} +{$ifndef CPUI386} {$ifndef PurePascal} {$define PurePascal} {$endif} Index: sha3.pas =================================================================== --- sha3.pas (revision 6895) +++ sha3.pas (working copy) @@ -6,6 +6,15 @@ {$i STD.INC} +{$ifdef FPC} + {$ifdef CPUI386} + {$define USE_MMXCODE} + {$endif} + {$ifdef CPU64} + {$define USE_64BITCODE} + {$endif} +{$endif} + {.$define USE_64BITCODE} {Use 64-bit for Keccak permutation} {.$define USE_MMXCODE } {Use MMX for Keccak permutation, contributed by Eric Grange} {.$define USE_MMX_AKP } {Use MMX for Keccak permutation, contributed by Anna Kaliszewicz / payl} Index: scrypt.pas =================================================================== --- scrypt.pas (revision 7740) +++ scrypt.pas (working copy) @@ -90,7 +90,7 @@ implementation uses - sha256; {Register SHA256 for HMAC-SHA256} + SHA3_512; {Register SHA3_512 for HMAC_SHA3_512} type TLA16 = array[0..15] of longint; @@ -361,14 +361,14 @@ {---------------------------------------------------------------------------} -function pbkfd2_hmac_sha256(pPW: pointer; pLen: word; salt: pointer; sLen,C: longint; var DK; dkLen: longint): integer; - {-Derive key DK from password pPW using salt and iteration count C using (hmac-)sha256} +function pbkdf2_hmac_sha3_512(pPW: pointer; pLen: word; salt: pointer; sLen,C: longint; var DK; dkLen: longint): integer; + {-Derive key DK from password pPW using salt and iteration count C using hmac_sha3_512} var phash: PHashDesc; begin - {Note: pbkdf2 will return error indicator phash=nil if _SHA256 is not found!} - phash := FindHash_by_ID(_SHA256); - pbkfd2_hmac_sha256 := pbkdf2(phash,pPW,pLen,salt,sLen,C,DK,dkLen); + {Note: pbkdf2 will return error indicator phash=nil if _SHA3_512 is not found!} + phash := FindHash_by_ID(_SHA3_512); + pbkdf2_hmac_sha3_512 := pbkdf2(phash,pPW,pLen,salt,sLen,C,DK,dkLen); end; @@ -418,7 +418,7 @@ pV := malloc(sV); pXY := malloc(sXY); if (pB<>nil) and (pV<>nil) and (pXY<>nil) then begin - err := pbkfd2_hmac_sha256(pPW, pLen, salt, sLen, 1, pB^, sB); + err := pbkdf2_hmac_sha3_512(pPW, pLen, salt, sLen, 1, pB^, sB); if err=0 then begin pw := pB; for i:=0 to p-1 do begin @@ -425,7 +425,7 @@ smix(pw, r, N, pV, pXY); inc(Ptr2Inc(pw), r*128); end; - err := pbkfd2_hmac_sha256(pPW, pLen, pB, sB, 1, DK, dKlen); + err := pbkdf2_hmac_sha3_512(pPW, pLen, pB, sB, 1, DK, dKlen); end; scrypt_kdf := err; end doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/std.inc0000664000175000017500000004010012726767147022421 0ustar alexxalexx(************************************************************************* DESCRIPTION : Standard definitions and options REQUIREMENTS : TP5-7, D1-D7/D9-D12/D14-D24, FPC, VP, (TPW1.0/1.5,BCB3/4) Version Date Author Modification ------- -------- ------- ------------------------------------------ 1.00 05.10.03 W.Ehrhardt Initial version 1.01 05.10.03 we X_OPT, removed TP4 1.02 30.10.03 we WINCRT 1.03 09.12.03 we {$R+,S+} {$ifdef debug} 1.04 26.12.03 we VP: {&Optimise+,SmartLink+,Speed+} ifndef debug 1.05 28.12.03 we DELPHI = Delphi32 (no Delphi 1!) 1.06 12.04.04 we Delphi 7 1.07 26.09.04 we Record starting values of important options 1.08 10.10.04 we RESULT for Result pseudo variable 1.09 02.01.05 we BIT16: default $F- 1.10 26.02.05 we StrictLong 1.11 05.05.05 we D9 aka Delphi 2005 1.12 22.05.05 we StrictLong for FPC 2.0 1.13 27.05.05 we {$goto on} for FPC 1.14 27.05.05 we moved {$goto on} to default settings 1.15 29.05.05 we HAS_INT64, HAS_MSG, _STD_INC_ 1.16 06.08.05 we J_OPT, N_OPT, HAS_INLINE 1.17 17.08.05 we HAS_ASSERT 1.18 08.11.05 we APPCONS, partial TMT,TPW15 support 1.19 20.11.05 we Default option {$B-} 1.20 08.01.06 we ABSTRACT/DEFAULT 1.21 08.02.06 we Fix Scanhelp quirk 1.22 11.02.06 we VER5X 1.23 15.04.06 we HAS_XTYPES 1.24 08.05.06 we D10 aka Delphi 2006 1.25 25.05.06 we Define RESULT if FPC_OBJFPC is defined 1.26 08.09.06 we Define RESULT/DEFAULT if FPC_DELPHI is defined 1.27 14.11.06 we HAS_ASSERT for FPC VER1 and VER2 1.28 28.11.06 we HAS_UNSAFE, $warn SYMBOL_../UNSAFE_.. OFF 1.29 25.05.07 we D11 aka Delphi 2007, FPC2.1.4 1.30 23.06.07 we FPC_ProcVar: Helper for procedure variables 1.31 18.09.07 we HAS_INLINE for FPC VER2 1.32 04.10.07 we FPC Intel ASMmode only if CPUI386 is defined 1.33 22.11.07 we Record value of $X option, undef RESULT if $X- 1.34 19.05.08 we HAS_UINT64 1.35 21.06.08 we V7PLUS, HAS_UINT64 for FPC VER2_2 1.36 07.09.08 we HAS_CARD32 1.37 21.11.08 we D12 aka D2009 1.38 19.02.09 we TPW 1.0 adjustments 1.39 05.07.09 we D12Plus 1.40 17.10.09 we BASM (BASM16 or Bit32) 1.41 21.10.09 we HAS_OVERLOAD 1.42 07.04.10 we HAS_DENORM_LIT (Denormalised extended literals, e.g. -1.23e-4942) 1.43 20.06.10 we D14 (VER210) 1.45 16.10.10 we WIN16 1.46 05.11.10 we FPC VER2_4 1.47 12.11.11 we FPC VER2_6 1.48 01.01.12 we HAS_UINT64 for FPC VER2_6 1.49 12.01.12 we BIT64, WIN32or64, Bit32or64 1.50 13.01.12 we EXT64 (64 bit extended = double) 1.51 19.01.12 we Define EXT64 if SIMULATE_EXT64 1.52 05.09.12 we Basic support for D14, D15(XE), D16(XE2), D17(XE3) 1.53 01.12.12 we Simplified FPC 2.X.Y definitions 1.54 17.12.12 we UNIT_SCOPE (D16/D17) 1.55 25.12.12 we J_OPT for BIT64 1.56 25.04.13 we D18/XE4 (VER250) 1.57 28.09.13 we Basic support for D19/XE5 (VER260) 1.58 17.04.14 we Basic support for D20/XE6 (VER270) 1.59 06.05.14 we FPC/CPUARM: $define EXT64, i.e. no FP 80-bit extended 1.60 13.09.14 we Basic support for D21/XE7 (VER280) 1.61 22.10.14 we HAS_OUT 1.62 13.01.15 we FPC VER3 (FPC3.0.1/3.1.1), FPC2Plus, FPC271or3 1.63 22.04.15 we Basic support for D22/XE8 (VER290) 1.64 25.04.15 we HAS_INTXX, HAS_PINTXX 1.65 01.09.15 we Basic support for D23 (VER300) 'Seattle' 1.66 26.04.16 we Basic support for D24 (VER310) 'Berlin' **************************************************************************) (*------------------------------------------------------------------------- (C) Copyright 2002-2016 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ----------------------------------------------------------------------------*) {$ifndef _STD_INC_} {$define _STD_INC_} {include STD.INC only once} {.$undef BIT16} {16 Bit code, Pascal / D1} {.$undef BIT32} {32 Bit code} {.$undef BIT64} {64 Bit code} {.$undef DELPHI} {Delphi2+ and BCB++} {.$undef G_OPT} {G+ option support} {.$undef D4PLUS} {Delphi 4 or higher} {.$undef BASM16} {16 Bit BASM} {.$undef LoadArgs} {Register params} {.$undef WINCRT} {Use WinCRT for console} {.$undef WIN16} {Compiler for 16-bit windows} {.$undef WIN32or64} {Compiler for 32/64-bit windows} {.$undef RESULT} {Result pseudo variable} {.$undef StrictLong} {Warning for longint const with MS bit} {.$undef HAS_INT64} { int64 integer type available} {.$undef HAS_UINT64} {uint64 integer type available} {.$undef HAS_CARD32} {Has 32 bit cardinal} {.$undef HAS_MSG} {Has message directive} {.$undef HAS_INLINE} {Has inline procs/funcs (D9)} {.$undef HAS_OUT} {Has OUT parameters: D3+, FPC2+ Delphi/ObjFPC} {.$undef ABSTRACT} {Has abstract methods} {.$undef DEFAULT} {Support default parameters} {.$undef VER5X} {TP5 or TP55} {.$undef HAS_XTYPES} {Xtra types in system: pByte, pLongint etc} {.$undef HAS_UNSAFE} {UNSAFE warnings} {.$undef APPCONS} {Needs "Apptype console" for console application} {.$undef FPC_ProcVar} {FPC handling of @ and proc variables} {.$undef FPC2Plus} {FPC 2 or newer} {.$undef FPC271or3} {FPC 271 or 3 (less accurate for 64 bit or SSE2)} {.$undef D12PLUS} {Delphi 12 or higher} {.$undef HAS_OVERLOAD} {Overloading of procedures and functions} {.$undef HAS_DENORM_LIT} {Denormalised (extended) literals, e.g. -1.23e-4942} {.$undef EXT64} {64 bit extended = double} {.$undef UNIT_SCOPE} {Unit scope name, D16+} {.$undef HAS_INTXX} {Int8 .. Int32, UInt8 .. UInt32} {.$undef HAS_PINTXX} {pInt8 .. pInt32, pUInt8 .. pUInt32} {$define CONST} {const in proc declaration} {$define Q_OPT} {Q- option support} {$define X_OPT} {X+ option support} {$define N_OPT} {N+ option support} {$define BASM} {BASM16 or BIT32} {$define V7PLUS} {TP7 or higher} {$ifdef VER10} {TPW 1.0} {$define BIT16} {$define BASM16} {$define WINCRT} {$define G_OPT} {$undef CONST} {$undef Q_OPT} {$undef V7PLUS} {$endif} {$ifdef VER15} {TPW 1.5} {$define BIT16} {$define BASM16} {$define WINCRT} {$define G_OPT} {$undef CONST} {$undef Q_OPT} {$undef V7PLUS} {$endif} {$ifdef VER50 } {$define BIT16} {$define VER5X} {$undef BASM} {$undef CONST} {$undef Q_OPT} {$undef X_OPT} {$undef V7PLUS} {$endif} {$ifdef VER55 } {$define BIT16} {$define VER5X} {$undef BASM} {$undef CONST} {$undef Q_OPT} {$undef X_OPT} {$undef V7PLUS} {$endif} {$ifdef VER60 } {$define BIT16} {$undef CONST} {$undef Q_OPT} {$define G_OPT} {$define BASM16} {$undef V7PLUS} {$endif} {$ifdef VER70 } {$define BIT16} {$define G_OPT} {$define BASM16} {$endif} {$ifdef VER80} {.$define DELPHI} {D1} {*we V1.05} {$define BIT16 } {$define G_OPT } {$define BASM16} {$define WINCRT} {$define RESULT} {$endif} {$ifdef VER90 } {$define DELPHI} {D2} {$endif} {$ifdef VER93 } {$define DELPHI} {BCB++1} {$endif} {$ifdef VER100} {$define DELPHI} {D3} {$define HAS_ASSERT} {$define HAS_OUT} {$endif} {$ifdef VER110} {$define DELPHI} {BCB3} {$define HAS_OUT} {$endif} {$ifdef VER120} {$define DELPHI} {D4} {$define D4PLUS} {$endif} {$ifdef VER125} {$define DELPHI} {BCB4} {$define D4PLUS} {$endif} {$ifdef VER130} {$define DELPHI} {D5} {$define D4PLUS} {$endif} {$ifdef VER140} {$define DELPHI} {D6} {$define D4PLUS} {$endif} {$ifdef VER150} {$define DELPHI} {D7} {$define D4PLUS} {$define HAS_UNSAFE} {$define HAS_UINT64} {$endif} {$ifdef VER170} {$define DELPHI} {D9} {$define D4PLUS} {$define HAS_INLINE} {$define HAS_UNSAFE} {$define HAS_UINT64} {$endif} {$ifdef VER180} {$define DELPHI} {D10, D11 ifdef VER185} {$define D4PLUS} {$define HAS_INLINE} {$define HAS_UNSAFE} {$define HAS_UINT64} {$endif} {$ifdef VER200} {$define DELPHI} {D12} {$define D12PLUS} {$endif} {$ifdef VER210} {$define DELPHI} {D14} {$define D12PLUS} {$endif} {$ifdef VER220} {$define DELPHI} {D15 - XE} {$define D12PLUS} {$endif} {$ifdef VER230} {$define DELPHI} {D16 - XE2} {$define D12PLUS} {$define UNIT_SCOPE} {$endif} {$ifdef VER240} {$define DELPHI} {D17 - XE3} {$define D12PLUS} {$define UNIT_SCOPE} {$endif} {$ifdef VER250} {$define DELPHI} {D18 - XE4} {$define D12PLUS} {$define UNIT_SCOPE} {$endif} {$ifdef VER260} {$define DELPHI} {D19 - XE5} {$define D12PLUS} {$define UNIT_SCOPE} {$endif} {$ifdef VER270} {$define DELPHI} {D20 - XE6} {$define D12PLUS} {$define UNIT_SCOPE} {$endif} {$ifdef VER280} {$define DELPHI} {D21 - XE7} {$define D12PLUS} {$define UNIT_SCOPE} {$endif} {$ifdef VER290} {$define DELPHI} {D22 - XE8} {$define D12PLUS} {$define UNIT_SCOPE} {$endif} {$ifdef VER300} {$define DELPHI} {D23} {$define D12PLUS} {$define UNIT_SCOPE} {$endif} {$ifdef VER310} {$define DELPHI} {D24} {$define D12PLUS} {$define UNIT_SCOPE} {$endif} {$ifdef CONDITIONALEXPRESSIONS} {D6+} {$ifndef D4PLUS} {$define D4PLUS} {$endif} {$define HAS_MSG} {$define HAS_XTYPES} {$ifdef CPUX64} {$define BIT64} {$endif} {$endif} {$ifdef VER70} {$ifdef windows} {$define WINCRT} {$endif} {$endif} {$ifdef VirtualPascal} {$define G_OPT} {$define RESULT} {$define LoadArgs} {$endif} {$ifdef WIN32} {$define J_OPT} {$endif} {$ifdef BIT64} {$define J_OPT} {$endif} {$ifdef FPC} {$define FPC_ProcVar} {$define ABSTRACT} {$define HAS_XTYPES} {$define HAS_OVERLOAD} {$undef N_OPT} {$ifdef VER1} {$undef J_OPT} {$define HAS_INT64} {$define HAS_CARD32} {$define HAS_MSG} {$define HAS_ASSERT} {$ifndef VER1_0} {FPC 1.9.x} {$define StrictLong} {$else} {$define LoadArgs} {$endif} {$endif} {$ifdef VER2} {$define FPC2Plus} {$define HAS_ASSERT} {$define HAS_INT64} {$define HAS_CARD32} {$define HAS_MSG} {$define HAS_INLINE} {Remember to use -Si} {$define StrictLong} {$ifdef FPC_OBJFPC} {$define DEFAULT} {$endif} {$ifdef FPC_DELPHI} {$define DEFAULT} {$endif} {$ifndef VER2_0} {$ifndef VER2_1} {$define HAS_UINT64} {2.2+} {$endif} {$define HAS_DENORM_LIT} {2.1+} {$endif} {$ifdef VER2_7_1} {$define FPC271or3} {$endif} {$ifdef VER2_6_2} {$define HAS_INTXX} {$endif} {$ifdef VER2_6_4} {$define HAS_INTXX} {$define HAS_PINTXX} {$endif} {$endif} {$ifdef VER3} {$define FPC2Plus} {$define FPC271or3} {$define HAS_ASSERT} {$define HAS_INT64} {$define HAS_CARD32} {$define HAS_MSG} {$define HAS_INLINE} {$define HAS_UINT64} {$define HAS_DENORM_LIT} {$define StrictLong} {$define HAS_INTXX} {$define HAS_PINTXX} {$ifdef FPC_OBJFPC} {$define DEFAULT} {$endif} {$ifdef FPC_DELPHI} {$define DEFAULT} {$endif} {$endif} {Note: Mode detection does not work for -Sxxx and version < 2.0.2} {$ifdef FPC_OBJFPC} {$define RESULT} {$define HAS_OUT} {$endif} {$ifdef FPC_DELPHI} {$define RESULT} {$define HAS_OUT} {$undef FPC_ProcVar} {$endif} {$ifdef FPC_TP} {$undef FPC_ProcVar} {$endif} {$ifdef FPC_GPC} {$undef FPC_ProcVar} {$endif} {$ifdef CPU64} {$define BIT64} {$endif} {$ifdef CPUARM} {$define EXT64} {No extended for ARM} {$endif} {$endif} {$ifdef __TMT__} {$undef N_OPT} {$define RESULT} {$define HAS_INT64} {$define LoadArgs} {$ifdef __WIN32__} {$define WIN32} {$endif} {$endif} {$ifndef BIT16} {$define Bit32or64} {$ifndef BIT64} {$define BIT32} {$endif} {$endif} {$ifdef BIT16} {$ifdef WINDOWS} {$define WIN16} {$endif} {$endif} {$ifdef Delphi} {$define RESULT} {$define ABSTRACT} {$define HAS_DENORM_LIT} {$endif} {$ifdef D12Plus} {$ifndef D4PLUS} {$define D4PLUS} {$endif} {$define HAS_INLINE} {$define HAS_UNSAFE} {$define HAS_UINT64} {$define HAS_INTXX} {$endif} {$ifdef D4Plus} {$define HAS_OUT} {$define HAS_INT64} {$define HAS_CARD32} {$define StrictLong} {$define HAS_ASSERT} {$define DEFAULT} {$define HAS_OVERLOAD} {$endif} {$ifdef WIN32} {$define WIN32or64} {$ifndef VirtualPascal} {$define APPCONS} {$endif} {$endif} {$ifdef WIN64} {$define BIT64} {$define WIN32or64} {$define EXT64} {$define APPCONS} {$endif} {$ifdef BIT64} {$undef BASM} {$endif} {-- Default options --} {$ifndef FPC} {$B-} {short-circuit boolean expression evaluation, FPC has always B-!} {$endif} {$ifdef FPC} {$ifdef CPUI386} {$ASMmode intel} {$endif} {$goto on} {$endif} {$ifdef VirtualPascal} {$ifndef debug} {&Optimise+,SmartLink+,Speed+} {$endif} {$endif} {$ifdef G_OPT} {$G+} {$endif} {$ifdef Q_OPT} {Most Crypto and CRC/Hash units need Q-, define Q+ locally if needed} {$Q-} {$endif} {$ifdef debug} {$R+,S+} {Note: D9+ needs $R- for StrictLong setting!} {$else} {$R-,S-} {$endif} {$ifdef SIMULATE_EXT64} {$define EXT64} {$endif} {$ifdef BIT16} {$F-} {$endif} {-- Record the starting values of important local options --} {$ifopt A+} {$define Align_on} {$endif} {$ifopt B+} {$define BoolEval_on} {$endif} {$ifopt D+} {$define DebugInfo_on} {$endif} {$ifopt I+} {$define IOChecks_on} {$endif} {$ifopt R+} {$define RangeChecks_on} {$endif} {$ifopt V+} {$define VarStringChecks_on} {$endif} {$ifdef Q_OPT} {$ifopt P+} {$define OpenStrings_on} {$endif} {$ifopt Q+} {$define OverflowChecks_on} {$endif} {$endif} {-- Note that X option is GLOBAL --} {$ifdef X_OPT} {$ifopt X+} {$define ExtendedSyntax_on} {$endif} {$ifopt X-} {$undef RESULT} {$endif} {$endif} {$ifdef CONDITIONALEXPRESSIONS} {$warn SYMBOL_PLATFORM OFF} {$warn SYMBOL_DEPRECATED OFF} {$warn SYMBOL_LIBRARY OFF} {$warn UNIT_DEPRECATED OFF} {$warn UNIT_LIBRARY OFF} {$warn UNIT_PLATFORM OFF} {$ifdef HAS_UNSAFE} {$warn UNSAFE_TYPE OFF} {$warn UNSAFE_CODE OFF} {$warn UNSAFE_CAST OFF} {$endif} {$endif} {$else} {$ifdef HAS_MSG} {$message 'std.inc included more than once'} {$endif} {$endif} doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/btypes.pas0000664000175000017500000001344512726767147023163 0ustar alexxalexxunit BTypes; {Common basic type definitions} interface {$i STD.INC} (************************************************************************* DESCRIPTION : Common basic type definitions REQUIREMENTS : TP5-7, D1-D7/D9-D12/D17-D22, FPC, VP, WDOSX EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REFERENCES : --- Version Date Author Modification ------- -------- ------- ------------------------------------------ 0.10 15.04.06 W.Ehrhardt Initial version 0.11 15.04.06 we With $ifdef HAS_XTYPES 0.12 15.04.06 we FPC1_0 and pShortInt 0.13 09.09.08 we UInt32 = cardinal $ifdef HAS_CARD32 0.14 12.11.08 we Str127, Ptr2Inc 0.15 14.11.08 we BString, char8 0.16 21.11.08 we __P2I: type cast pointer to integer for masking etc 0.17 02.12.08 we Use pchar and pAnsiChar for pchar8 if possible 0.18 27.02.09 we pBoolean 0.19 14.02.12 we extended = double $ifdef SIMULATE_EXT64 0.20 06.05.14 we extended = double $ifdef SIMULATE_EXT64 OR EXT64 0.21 25.04.15 we With $ifdef HAS_INTXX, HAS_PINTXX *************************************************************************) (*------------------------------------------------------------------------- (C) Copyright 2006-2015 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ----------------------------------------------------------------------------*) {$ifdef BIT16} type Int8 = ShortInt; { 8 bit signed integer} Int16 = Integer; {16 bit signed integer} Int32 = Longint; {32 bit signed integer} UInt8 = Byte; { 8 bit unsigned integer} UInt16 = Word; {16 bit unsigned integer} UInt32 = Longint; {32 bit unsigned integer} Smallint = Integer; Shortstring = string; pByte = ^Byte; pBoolean = ^Boolean; pShortInt = ^ShortInt; pWord = ^Word; pSmallInt = ^SmallInt; pLongint = ^Longint; {$else} {$ifndef HAS_INTXX} type Int8 = ShortInt; { 8 bit signed integer} Int16 = SmallInt; {16 bit signed integer} Int32 = Longint; {32 bit signed integer} UInt8 = Byte; { 8 bit unsigned integer} UInt16 = Word; {16 bit unsigned integer} {$ifdef HAS_CARD32} UInt32 = Cardinal; {32 bit unsigned integer} {$else} UInt32 = Longint; {32 bit unsigned integer} {$endif} {$endif} {$ifndef HAS_XTYPES} type pByte = ^Byte; pBoolean = ^Boolean; pShortInt = ^ShortInt; pWord = ^Word; pSmallInt = ^SmallInt; pLongint = ^Longint; {$endif} {$ifdef FPC} {$ifdef VER1_0} type pBoolean = ^Boolean; pShortInt = ^ShortInt; {$endif} {$endif} {$endif} {BIT16} type Str255 = string[255]; {Handy type to avoid problems with 32 bit and/or unicode} Str127 = string[127]; type {$ifndef HAS_PINTXX} pInt8 = ^Int8; pInt16 = ^Int16; pInt32 = ^Int32; pUInt8 = ^UInt8; pUInt16 = ^UInt16; pUInt32 = ^UInt32; {$endif} pStr255 = ^Str255; pStr127 = ^Str127; {$ifdef BIT16} {$ifdef V7Plus} type BString = string[255]; {String of 8 bit characters} pBString = ^BString; char8 = char; {8 bit characters} pchar8 = pchar; {$else} type BString = string[255]; {String of 8 bit characters} pBString = ^BString; char8 = char; {8 bit characters} pchar8 = ^char; {$endif} {$else} {$ifdef UNICODE} type BString = AnsiString; {String of 8 bit characters} pBString = pAnsiString; char8 = AnsiChar; {8 bit characters} pchar8 = pAnsiChar; {$else} type BString = AnsiString; {String of 8 bit characters} pBString = pAnsiString; char8 = AnsiChar; {8 bit characters} pchar8 = pAnsiChar; {$endif} {$endif} {$ifdef V7Plus} type Ptr2Inc = pByte; {Type cast to increment untyped pointer} {$else} type Ptr2Inc = Longint; {Type cast to increment untyped pointer} {$endif} {$ifdef FPC} {$ifdef VER1} type __P2I = longint; {Type cast pointer to integer for masking etc} {$else} type __P2I = PtrUInt; {Type cast pointer to integer for masking etc} {$endif} {$else} {$ifdef BIT64} type __P2I = NativeInt; {Type cast pointer to integer for masking etc} {$else} type __P2I = longint; {Type cast pointer to integer for masking etc} {$endif} {$endif} {$ifdef EXT64} type extended = double; {Force 64-bit 'extended'} {$else} {$ifdef SIMULATE_EXT64} type extended = double; {Debug simulation EXT64} {$endif} {$endif} implementation end. doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/kperm_mx.inc0000664000175000017500000002305012726767147023456 0ustar alexxalexx{KeccakF[1600] state permutation for 32 bit compilers with MMX/ASM support} {Compiled from Pascal source to MMX with ad-hoc compiler by Eric Grange. } {Slightly changed by WE to make it compatible with plain D6+ and FPC. } {This code is used if the symbol USE_MMCODE is defined in unit sha3, FPC } {and Delphi 6+. For the variables, structure etc see also kperm_64.inc. } {$ifdef HAS_UINT64} type u64bit = uint64; {$else} type u64bit = int64; {$endif} {$ifdef FPC} {$ASMMODE INTEL} {$endif} type pu64bit = ^u64bit; const cRoundConstants: array[0..23] of u64bit = ( u64bit($0000000000000001), u64bit($0000000000008082), u64bit($800000000000808A), u64bit($8000000080008000), u64bit($000000000000808B), u64bit($0000000080000001), u64bit($8000000080008081), u64bit($8000000000008009), u64bit($000000000000008A), u64bit($0000000000000088), u64bit($0000000080008009), u64bit($000000008000000A), u64bit($000000008000808B), u64bit($800000000000008B), u64bit($8000000000008089), u64bit($8000000000008003), u64bit($8000000000008002), u64bit($8000000000000080), u64bit($000000000000800A), u64bit($800000008000000A), u64bit($8000000080008081), u64bit($8000000000008080), u64bit($0000000080000001), u64bit($8000000080008008)); {---------------------------------------------------------------------------} procedure KeccakPermutationKernel(B, A, C: pointer); begin asm mov eax, [B] mov edx, [A] mov ecx, [C] add edx, 128 add eax, 128 // Theta movq mm2, [edx-112] movq mm0, [edx-128] pxor mm0, [edx-88] pxor mm0, [edx-48] pxor mm0, [edx-8] pxor mm0, [edx+32] movq mm1, [edx-120] movq [ecx], mm0 pxor mm2, [edx-72] pxor mm2, [edx-32] pxor mm2, [edx+8] pxor mm2, [edx+48] movq mm3, [edx-104] movq [ecx+16], mm2 pxor mm1, [edx-80] pxor mm1, [edx-40] pxor mm1, [edx] pxor mm1, [edx+40] movq mm4, [edx-96] movq [ecx+8], mm1 pxor mm3, [edx-64] pxor mm3, [edx-24] pxor mm3, [edx+16] pxor mm3, [edx+56] movq [ecx+24], mm3 pxor mm4, [edx-56] pxor mm4, [edx-16] pxor mm4, [edx+24] pxor mm4, [edx+64] movq [ecx+32], mm4 movq mm6, mm2 psllq mm2, 1 psrlq mm6, 63 por mm2, mm6 pxor mm2, mm0 movq mm7, mm0 psllq mm0, 1 psrlq mm7, 63 por mm0, mm7 pxor mm0, mm3 movq mm5, mm3 psllq mm3, 1 psrlq mm5, 63 por mm3, mm5 pxor mm3, mm1 movq mm6, mm1 psllq mm1, 1 psrlq mm6, 63 por mm1, mm6 pxor mm1, mm4 movq mm7, mm4 psllq mm4, 1 psrlq mm7, 63 por mm4, mm7 pxor mm4, [ecx+16] // Rho Pi movq mm5, [edx-24] movq mm6, [edx-80] pxor mm6, mm2 movq mm7, mm6 psllq mm6, 44 psrlq mm7, 20 por mm6, mm7 movq [eax-120], mm6 movq mm6, [edx+24] pxor mm5, mm4 movq mm7, mm5 psllq mm5, 25 psrlq mm7, 39 por mm5, mm7 movq [eax-32], mm5 movq mm5, [edx-96] pxor mm6, mm0 movq mm7, mm6 psllq mm6, 8 psrlq mm7, 56 por mm6, mm7 movq [eax-24], mm6 movq mm6, [edx-64] pxor mm5, mm0 movq mm7, mm5 psllq mm5, 27 psrlq mm7, 37 por mm5, mm7 movq [eax-8], mm5 pxor mm6, mm4 movq mm7, mm6 psllq mm6, 55 psrlq mm7, 9 por mm6, mm7 movq mm5, [edx] movq [eax+40], mm6 movq mm6, [edx-128] pxor mm6, mm1 movq [eax-128], mm6 movq mm6, [edx-88] pxor mm5, mm2 movq mm7, mm5 psllq mm5, 45 psrlq mm7, 19 por mm5, mm7 movq [eax-64], mm5 movq mm5, [edx-16] pxor mm6, mm1 movq mm7, mm6 psllq mm6, 36 psrlq mm7, 28 por mm6, mm7 movq [eax], mm6 movq mm6, [edx+8] pxor mm5, mm0 movq mm7, mm5 psllq mm5, 39 psrlq mm7, 25 por mm5, mm7 movq [eax+48], mm5 movq mm5, [edx-104] pxor mm6, mm3 movq mm7, mm6 psllq mm6, 15 psrlq mm7, 49 por mm6, mm7 movq [eax+16], mm6 movq mm6, [edx-120] pxor mm5, mm4 movq mm7, mm5 psllq mm5, 28 psrlq mm7, 36 por mm5, mm7 movq [eax-88], mm5 movq mm5, [edx-48] pxor mm6, mm2 movq mm7, mm6 psllq mm6, 1 psrlq mm7, 63 por mm6, mm7 movq [eax-48], mm6 movq mm6, [edx+56] pxor mm5, mm1 movq mm7, mm5 psllq mm5, 3 psrlq mm7, 61 por mm5, mm7 movq [eax-72], mm5 movq mm5, [edx+16] pxor mm6, mm4 movq mm7, mm6 psllq mm6, 56 psrlq mm7, 8 por mm6, mm7 movq [eax+24], mm6 movq mm6, [edx+32] pxor mm5, mm4 movq mm7, mm5 psllq mm5, 21 psrlq mm7, 43 por mm5, mm7 movq [eax-104], mm5 movq mm5, [edx+40] pxor mm6, mm1 movq mm7, mm6 psllq mm6, 18 psrlq mm7, 46 por mm6, mm7 movq [eax-16], mm6 movq mm6, [edx-72] pxor mm5, mm2 movq mm7, mm5 psllq mm5, 2 psrlq mm7, 62 por mm5, mm7 movq [eax+64], mm5 movq mm5, [edx-40] pxor mm6, mm3 movq mm7, mm6 psllq mm6, 6 psrlq mm7, 58 por mm6, mm7 movq [eax-40], mm6 movq mm6, [edx-56] pxor mm5, mm2 movq mm7, mm5 psllq mm5, 10 psrlq mm7, 54 por mm5, mm7 movq [eax+8], mm5 movq mm5, [edx-112] pxor mm6, mm0 movq mm7, mm6 psllq mm6, 20 psrlq mm7, 44 por mm6, mm7 movq [eax-80], mm6 movq mm6, [edx+48] pxor mm5, mm3 movq mm7, mm5 psllq mm5, 62 psrlq mm7, 2 por mm5, mm7 movq [eax+32], mm5 movq mm5, [edx-8] pxor mm6, mm3 movq mm7, mm6 psllq mm6, 61 psrlq mm7, 3 por mm6, mm7 movq [eax-56], mm6 movq mm6, [edx+64] pxor mm5, mm1 movq mm7, mm5 psllq mm5, 41 psrlq mm7, 23 por mm5, mm7 movq [eax+56], mm5 movq mm5, [edx-32] pxor mm6, mm0 movq mm7, mm6 psllq mm6, 14 psrlq mm7, 50 por mm6, mm7 movq [eax-96], mm6 pxor mm5, mm3 movq mm7, mm5 psllq mm5, 43 psrlq mm7, 21 por mm5, mm7 movq [eax-112], mm5 // Chi movq mm4, [eax-128] movq mm2, [eax-104] movq mm1, mm5 movq mm3, mm6 pandn mm3, mm4 pxor mm3, mm2 movq mm0, [eax-120] movq [edx-104], mm3 pandn mm1, mm2 pxor mm1, mm0 movq [edx-120], mm1 pandn mm2, mm6 pxor mm2, mm5 movq [edx-112], mm2 pandn mm0, mm5 pxor mm0, mm4 movq mm5, [eax-80] movq [edx-128], mm0 pandn mm4, [eax-120] pxor mm4, mm6 movq mm0, [eax-56] movq mm6, [eax-72] movq mm1, [eax-88] movq [edx-96], mm4 pandn mm5, mm6 pxor mm5, mm1 movq mm7, [eax-64] movq [edx-88], mm5 pandn mm0, mm1 pxor mm0, mm7 movq [edx-64], mm0 pandn mm6, mm7 pxor mm6, [eax-80] movq mm5, [eax-16] movq [edx-80], mm6 pandn mm1, [eax-80] pxor mm1, [eax-56] movq mm6, [eax-48] movq mm4, [eax-24] movq [edx-56], mm1 pandn mm5, mm6 pxor mm5, mm4 movq mm3, [eax-32] movq [edx-24], mm5 pandn mm7, [eax-56] pxor mm7, [eax-72] movq mm2, [eax-40] movq [edx-72], mm7 pandn mm3, mm4 pxor mm3, mm2 movq mm0, [eax+8] movq [edx-40], mm3 pandn mm2, [eax-32] pxor mm2, mm6 movq mm7, [eax] movq mm1, [eax+16] movq [edx-48], mm2 pandn mm0, mm1 pxor mm0, mm7 movq [edx], mm0 pandn mm6, [eax-40] pxor mm6, [eax-16] movq mm3, [eax-8] movq [edx-16], mm6 movq mm6, [eax+56] pandn mm7, [eax+8] pxor mm7, mm3 movq mm5, [eax+48] movq [edx-8], mm7 movq mm7, [eax+64] pandn mm6, mm7 pxor mm6, mm5 movq [edx+48], mm6 pandn mm4, [eax-16] pxor mm4, [eax-32] movq mm2, [eax+24] movq [edx-32], mm4 pandn mm3, [eax] pxor mm3, mm2 movq mm4, [eax+40] movq mm0, [eax+32] movq [edx+24], mm3 pandn mm7, mm0 pxor mm7, [eax+56] movq [edx+56], mm7 pandn mm4, mm5 pxor mm4, mm0 movq [edx+32], mm4 pandn mm1, mm2 pxor mm1, [eax+8] movq [edx+8], mm1 pandn mm0, [eax+40] pxor mm0, [eax+64] movq [edx+64], mm0 pandn mm5, [eax+56] pxor mm5, [eax+40] movq [edx+40], mm5 pandn mm2, [eax-8] pxor mm2, [eax+16] movq [edx+16], mm2 end; end; {---------------------------------------------------------------------------} procedure EMMS; begin asm emms end; end; {---------------------------------------------------------------------------} procedure KeccakPermutation(var state: TState_L); var A: u64bit absolute state; B: array[0..24] of u64bit; C: array[0..4] of u64bit; i: integer; begin for i:=0 to 23 do begin KeccakPermutationKernel(@B, @A, @C); A := A xor cRoundConstants[i]; end; EMMS; end; {---------------------------------------------------------------------------} procedure ExtractFromState(outp: pointer; const state: TState_L; laneCount: integer); var pI, pS: pu64bit; i: integer; begin pI := outp; pS := @state[0]; for i:=laneCount-1 downto 0 do begin pI^ := pS^; inc(pI); inc(pS); end; end; {---------------------------------------------------------------------------} procedure XorIntoState(var state: TState_L; inp: PLongint; laneCount: integer); {-Include input message data bits into the sponge state} var pI, pS: pu64bit; i: integer; begin pI := pu64bit(inp); pS := @state[0]; for i:=laneCount-1 downto 0 do begin pS^ := pS^ xor pI^; inc(pI); inc(pS); end; end; doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/COPYING.txt0000664000175000017500000000410012726767147023005 0ustar alexxalexx(C) Copyright 2002-2016 Wolfgang Ehrhardt Based on "The zlib/libpng License": http://www.opensource.org/licenses/zlib-license.php __________________ COPYING CONDITIONS This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. _______________________________________ Bedingungen fuer Nutzung und Weitergabe Die Software (Quellcodes und Binaerdateien) wird ohne jegliche Zusagen oder Garantien bezueglich Funktionalitaet oder Funktionsfaehigkeit abgegeben. Die Autoren uebernehmen keine Verantwortung fuer Schaeden, die durch die Benutzung der Software verursacht werden. Die Software darf frei verwendet und weitergegeben werden (kommerzielle Nutzung/Weitergabe ist erlaubt), vorausgesetzt die folgenden Bedingungen werden eingehalten: 1. Die Herkunft der Software darf nicht falsch angegeben werden; es ist nicht erlaubt, die Software als Werk eines anderen auszugeben. Wird die Software in Teilen oder als Ganzes in einem Produkt benutzt, so ist Hinweis auf die Herkunft in der Dokumentation erwuenscht, aber nicht notwendig. 2. Geaenderte Quellcodes muessen deutlich als solche gekennzeichnet werden und duerfen nicht als die Originalsoftware ausgegeben werden. 3. Die Bedingungen ueber die Nutzung/Weitergabe duerfen nicht entfernt oder geaendert werden. doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/sha1.pas0000664000175000017500000007723213216540737022502 0ustar alexxalexxunit SHA1; {SHA1 - 160 bit Secure Hash Function} interface (************************************************************************* DESCRIPTION : SHA1 - 160 bit Secure Hash Function REQUIREMENTS : TP5-7, D1-D7/D9-D10/D12/D17-D18, FPC, VP EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REFERENCES : - Latest specification of Secure Hash Standard: http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf - Test vectors and intermediate values: http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf Version Date Author Modification ------- -------- ------- ------------------------------------------ 1.00 03.01.02 W.Ehrhardt BP7 implementation 1.01 14.03.02 we D1-D6, FPC, VP 1.02 14.03.02 we TP6 1.03 14.03.02 we TP6/7 386-Code 1.04 14.03.02 we TP5.5 1.10 15.03.02 we self test with 2 strings 1.11 02.01.03 we const SFA with @ for FPC 1.0.6 1.20 23.07.03 we With SHA1File, SHA1Full 1.21 26.07.03 we With SHA1Full in self test 2.00 26.07.03 we common vers., longint for word32, D4+ - warnings 2.01 03.08.03 we type TSHA1Block for HMAC 2.02 23.08.03 we SHA1Compress in interface for prng 2.10 29.08.03 we XL versions for Win32 2.20 27.09.03 we FPC/go32v2 2.30 05.10.03 we STD.INC, TP5.0 2.40 10.10.03 we common version, english comments 2.45 11.10.03 we Speedup: partial unroll, no function calls 2.50 16.11.03 we Speedup in update, don't clear W in compress 2.51 17.11.03 we BIT16: partial unroll, BIT32: inline rot 2.52 17.11.03 we ExpandMessageBlocks 2.53 18.11.03 we LRot32, RB mit inline() 2.54 20.11.03 we Full range UpdateLen 2.55 30.11.03 we BIT16: {$F-} 2.56 30.11.03 we BIT16: LRot_5, LRot_30 3.00 01.12.03 we Common version 3.0 3.01 22.12.03 we BIT16: Two INCs 3.02 22.12.03 we BASM16: asm Lrot30 3.03 22.12.03 we TP5/5.5: LRot, RA inline 3.04 22,12.03 we Changed UpdateLen: Definition and TP5/5.5 inline 3.05 05.03.04 we Update fips180-2 URL 3.06 26.02.05 we With {$ifdef StrictLong} 3.07 05.05.05 we Use longint() in SH1Init to avoid D9 errors if $R+ 3.08 17.12.05 we Force $I- in SHA1File 3.09 08.01.06 we SHA1Compress removed from interface 3.10 15.01.06 we uses Hash unit and THashDesc 3.11 18.01.06 we Descriptor fields HAlgNum, HSig 3.12 22.01.06 we Removed HSelfTest from descriptor 3.13 11.02.06 we Descriptor as typed const 3.14 26.03.06 we Round constants K1..K4, code reordering 3.15 07.08.06 we $ifdef BIT32: (const fname: shortstring...) 3.16 22.02.07 we values for OID vector 3.17 30.06.07 we Use conditional define FPC_ProcVar 3.18 04.10.07 we FPC: {$asmmode intel} 3.19 02.05.08 we Bit-API: SHA1FinalBits/Ex 3.20 05.05.08 we THashDesc constant with HFinalBit field 3.21 12.11.08 we uses BTypes, Ptr2Inc and/or Str255/Str127 3.22 12.03.10 we Fix VP feature in ExpandMessageBlocks 3.23 11.03.12 we Updated references 3.24 26.12.12 we D17 and PurePascal 3.25 16.08.15 we Removed $ifdef DLL / stdcall **************************************************************************) (*------------------------------------------------------------------------- (C) Copyright 2002-2015 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ----------------------------------------------------------------------------*) {NOTE: FIPS Ch and May functions can be optimized. Wei Dai (Crypto++ 3.1) credits Rich Schroeppel (rcs@cs.arizona.edu), V 5.1 does not!?} {$i STD.INC} {$ifndef CPUI386} {$ifndef PurePascal} {$define PurePascal} {$endif} {$endif} uses BTypes,Hash; procedure SHA1Init(var Context: THashContext); {-initialize context} procedure SHA1Update(var Context: THashContext; Msg: pointer; Len: word); {-update context with Msg data} procedure SHA1UpdateXL(var Context: THashContext; Msg: pointer; Len: longint); {-update context with Msg data} procedure SHA1Final(var Context: THashContext; var Digest: TSHA1Digest); {-finalize SHA1 calculation, clear context} procedure SHA1FinalEx(var Context: THashContext; var Digest: THashDigest); {-finalize SHA1 calculation, clear context} procedure SHA1FinalBitsEx(var Context: THashContext; var Digest: THashDigest; BData: byte; bitlen: integer); {-finalize SHA1 calculation with bitlen bits from BData (big-endian), clear context} procedure SHA1FinalBits(var Context: THashContext; var Digest: TSHA1Digest; BData: byte; bitlen: integer); {-finalize SHA1 calculation with bitlen bits from BData (big-endian), clear context} function SHA1SelfTest: boolean; {-self test SHA1: compare with known value} procedure SHA1Full(var Digest: TSHA1Digest; Msg: pointer; Len: word); {-SHA1 of Msg with init/update/final} procedure SHA1FullXL(var Digest: TSHA1Digest; Msg: pointer; Len: longint); {-SHA1 of Msg with init/update/final} procedure SHA1File({$ifdef CONST} const {$endif} fname: Str255; var Digest: TSHA1Digest; var buf; bsize: word; var Err: word); {-SHA1 of file, buf: buffer with at least bsize bytes} implementation {$ifdef BIT16} {$F-} {$endif} const SHA1_BlockLen = 64; const {round constants} K1 = longint($5A827999); {round 00..19} K2 = longint($6ED9EBA1); {round 20..39} K3 = longint($8F1BBCDC); {round 40..59} K4 = longint($CA62C1D6); {round 60..79} {Internal types} type TWorkBuf = array[0..79] of longint; {1.3.14.3.2.26} {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) hashAlgorithmIdentifier(26)} const SHA1_OID : TOID_Vec = (1,3,14,3,2,26,-1,-1,-1); {Len=6} {$ifndef VER5X} const SHA1_Desc: THashDesc = ( HSig : C_HashSig; HDSize : sizeof(THashDesc); HDVersion : C_HashVers; HBlockLen : SHA1_BlockLen; HDigestlen: sizeof(TSHA1Digest); {$ifdef FPC_ProcVar} HInit : @SHA1Init; HFinal : @SHA1FinalEx; HUpdateXL : @SHA1UpdateXL; {$else} HInit : SHA1Init; HFinal : SHA1FinalEx; HUpdateXL : SHA1UpdateXL; {$endif} HAlgNum : longint(_SHA1); HName : 'SHA1'; HPtrOID : @SHA1_OID; HLenOID : 6; HFill : 0; {$ifdef FPC_ProcVar} HFinalBit : @SHA1FinalBitsEx; {$else} HFinalBit : SHA1FinalBitsEx; {$endif} HReserved : (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) ); {$else} var SHA1_Desc: THashDesc; {$endif} {$ifndef BIT16} {$ifdef PurePascal} {---------------------------------------------------------------------------} procedure UpdateLen(var whi, wlo: longint; BLen: longint); {-Add BLen to 64 bit value (wlo, whi)} var tmp: int64; begin tmp := int64(cardinal(wlo))+Blen; wlo := longint(tmp and $FFFFFFFF); inc(whi,longint(tmp shr 32)); end; {---------------------------------------------------------------------------} function RB(A: longint): longint; {-reverse byte order in longint} begin RB := ((A and $FF) shl 24) or ((A and $FF00) shl 8) or ((A and $FF0000) shr 8) or ((A and longint($FF000000)) shr 24); end; {---------------------------------------------------------------------------} procedure ExpandMessageBlocks(var W: TWorkBuf; var Buf: THashBuffer); {-Calculate "expanded message blocks"} var i,T: longint; begin {Part 1: Transfer buffer with little -> big endian conversion} for i:= 0 to 15 do W[i]:= RB(THashBuf32(Buf)[i]); {Part 2: Calculate remaining "expanded message blocks"} for i:= 16 to 79 do begin T := W[i-3] xor W[i-8] xor W[i-14] xor W[i-16]; W[i] := (T shl 1) or (T shr 31); end; end; {$else} {---------------------------------------------------------------------------} procedure UpdateLen(var whi, wlo: longint; BLen: longint); {-Add BLen to 64 bit value (wlo, whi)} begin asm mov edx, [wlo] mov ecx, [whi] mov eax, [Blen] add [edx], eax adc dword ptr [ecx], 0 end; end; {---------------------------------------------------------------------------} function RB(A: longint): longint; assembler; {-reverse byte order in longint} asm {$ifdef LoadArgs} mov eax,[A] {$endif} xchg al,ah rol eax,16 xchg al,ah end; {---------------------------------------------------------------------------} procedure ExpandMessageBlocks(var W: TWorkBuf; var Buf: THashBuffer); assembler; {-Calculate "expanded message blocks"} asm {$ifdef LoadArgs} mov edx,Buf mov ecx,W {load W before push ebx to avoid VP crash} push ebx {if compiling with no ASM stack frames} mov ebx,ecx {$else} push ebx mov ebx,eax {$endif} {part1: W[i]:= RB(TW32Buf(Buf)[i])} mov ecx,16 @@1: mov eax,[edx] xchg al,ah rol eax,16 xchg al,ah mov [ebx],eax add ebx,4 add edx,4 dec ecx jnz @@1 {part2: W[i]:= LRot_1(W[i-3] xor W[i-8] xor W[i-14] xor W[i-16]);} mov ecx,64 @@2: mov eax,[ebx- 3*4] xor eax,[ebx- 8*4] xor eax,[ebx-14*4] xor eax,[ebx-16*4] rol eax,1 mov [ebx],eax add ebx,4 dec ecx jnz @@2 pop ebx end; {$endif} {---------------------------------------------------------------------------} procedure SHA1Compress(var Data: THashContext); {-Actual hashing function} var i: integer; A, B, C, D, E: longint; W: TWorkBuf; begin ExpandMessageBlocks(W, Data.Buffer); A := Data.Hash[0]; B := Data.Hash[1]; C := Data.Hash[2]; D := Data.Hash[3]; E := Data.Hash[4]; {SHA1 compression function} {Partial unroll for more speed, full unroll is only slightly faster} {BIT32: rotateleft via inline} i := 0; while i<20 do begin inc(E, (A shl 5 or A shr 27) + (D xor (B and (C xor D))) + W[i ] + K1); B := B shr 2 or B shl 30; inc(D, (E shl 5 or E shr 27) + (C xor (A and (B xor C))) + W[i+1] + K1); A := A shr 2 or A shl 30; inc(C, (D shl 5 or D shr 27) + (B xor (E and (A xor B))) + W[i+2] + K1); E := E shr 2 or E shl 30; inc(B, (C shl 5 or C shr 27) + (A xor (D and (E xor A))) + W[i+3] + K1); D := D shr 2 or D shl 30; inc(A, (B shl 5 or B shr 27) + (E xor (C and (D xor E))) + W[i+4] + K1); C := C shr 2 or C shl 30; inc(i,5); end; while i<40 do begin inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[i ] + K2); B := B shr 2 or B shl 30; inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[i+1] + K2); A := A shr 2 or A shl 30; inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[i+2] + K2); E := E shr 2 or E shl 30; inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[i+3] + K2); D := D shr 2 or D shl 30; inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[i+4] + K2); C := C shr 2 or C shl 30; inc(i,5); end; while i<60 do begin inc(E, (A shl 5 or A shr 27) + ((B and C) or (D and (B or C))) + W[i ] + K3); B := B shr 2 or B shl 30; inc(D, (E shl 5 or E shr 27) + ((A and B) or (C and (A or B))) + W[i+1] + K3); A := A shr 2 or A shl 30; inc(C, (D shl 5 or D shr 27) + ((E and A) or (B and (E or A))) + W[i+2] + K3); E := E shr 2 or E shl 30; inc(B, (C shl 5 or C shr 27) + ((D and E) or (A and (D or E))) + W[i+3] + K3); D := D shr 2 or D shl 30; inc(A, (B shl 5 or B shr 27) + ((C and D) or (E and (C or D))) + W[i+4] + K3); C := C shr 2 or C shl 30; inc(i,5); end; while i<80 do begin inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[i ] + K4); B := B shr 2 or B shl 30; inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[i+1] + K4); A := A shr 2 or A shl 30; inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[i+2] + K4); E := E shr 2 or E shl 30; inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[i+3] + K4); D := D shr 2 or D shl 30; inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[i+4] + K4); C := C shr 2 or C shl 30; inc(i,5); end; {Calculate new working hash} inc(Data.Hash[0], A); inc(Data.Hash[1], B); inc(Data.Hash[2], C); inc(Data.Hash[3], D); inc(Data.Hash[4], E); end; {$else} {$ifdef BASM16} {TP6-7/Delphi1 for 386+} {---------------------------------------------------------------------------} procedure UpdateLen(var whi, wlo: longint; BLen: longint); assembler; {-Add BLen to 64 bit value (wlo, whi)} asm les di,[wlo] db $66; mov ax,word ptr [BLen] db $66; sub dx,dx db $66; add es:[di],ax les di,[whi] db $66; adc es:[di],dx end; {---------------------------------------------------------------------------} function LRot_5(x: longint): longint; {-Rotate left 5} inline( $66/$58/ {pop eax } $66/$C1/$C0/$05/ {rol eax,5 } $66/$8B/$D0/ {mov edx,eax} $66/$C1/$EA/$10); {shr edx,16 } {---------------------------------------------------------------------------} function RB(A: longint): longint; {-reverse byte order in longint} inline( $58/ {pop ax } $5A/ {pop dx } $86/$C6/ {xchg dh,al } $86/$E2); {xchg dl,ah } {---------------------------------------------------------------------------} procedure ExpandMessageBlocks(var W: TWorkBuf; var Buf: THashBuffer); assembler; {-Calculate "expanded message blocks"} asm push ds {part 1: W[i]:= RB(TW32Buf(Buf)[i])} les di,[Buf] lds si,[W] mov cx,16 @@1: db $66; mov ax,es:[di] xchg al,ah db $66; rol ax,16 xchg al,ah db $66; mov [si],ax add si,4 add di,4 dec cx jnz @@1 {part 2: W[i]:= LRot_1(W[i-3] xor W[i-8] xor W[i-14] xor W[i-16]);} mov cx,64 @@2: db $66; mov ax,[si- 3*4] db $66; xor ax,[si- 8*4] db $66; xor ax,[si-14*4] db $66; xor ax,[si-16*4] db $66; rol ax,1 db $66; mov [si],ax add si,4 dec cx jnz @@2 pop ds end; {---------------------------------------------------------------------------} procedure SHA1Compress(var Data: THashContext); {-Actual hashing function} var i: integer; A, B, C, D, E: longint; W: TWorkBuf; begin ExpandMessageBlocks(W, Data.Buffer); {Assign old working hash to variables A..E} A := Data.Hash[0]; B := Data.Hash[1]; C := Data.Hash[2]; D := Data.Hash[3]; E := Data.Hash[4]; {SHA1 compression function} {Partial unroll for more speed, full unroll only marginally faster} {Two INCs, LRot_30 via BASM} i := 0; while i<20 do begin inc(E,LRot_5(A)); inc(E,(D xor (B and (C xor D))) + W[i ] + K1); asm db $66; rol word[B],30 end; inc(D,LRot_5(E)); inc(D,(C xor (A and (B xor C))) + W[i+1] + K1); asm db $66; rol word[A],30 end; inc(C,LRot_5(D)); inc(C,(B xor (E and (A xor B))) + W[i+2] + K1); asm db $66; rol word[E],30 end; inc(B,LRot_5(C)); inc(B,(A xor (D and (E xor A))) + W[i+3] + K1); asm db $66; rol word[D],30 end; inc(A,LRot_5(B)); inc(A,(E xor (C and (D xor E))) + W[i+4] + K1); asm db $66; rol word[C],30 end; inc(i,5); end; while i<40 do begin inc(E,LRot_5(A)); inc(E,(B xor C xor D) + W[i ] + K2); asm db $66; rol word[B],30 end; inc(D,LRot_5(E)); inc(D,(A xor B xor C) + W[i+1] + K2); asm db $66; rol word[A],30 end; inc(C,LRot_5(D)); inc(C,(E xor A xor B) + W[i+2] + K2); asm db $66; rol word[E],30 end; inc(B,LRot_5(C)); inc(B,(D xor E xor A) + W[i+3] + K2); asm db $66; rol word[D],30 end; inc(A,LRot_5(B)); inc(A,(C xor D xor E) + W[i+4] + K2); asm db $66; rol word[C],30 end; inc(i,5); end; while i<60 do begin inc(E,LRot_5(A)); inc(E,((B and C) or (D and (B or C))) + W[i ] + K3); asm db $66; rol word[B],30 end; inc(D,LRot_5(E)); inc(D,((A and B) or (C and (A or B))) + W[i+1] + K3); asm db $66; rol word[A],30 end; inc(C,LRot_5(D)); inc(C,((E and A) or (B and (E or A))) + W[i+2] + K3); asm db $66; rol word[E],30 end; inc(B,LRot_5(C)); inc(B,((D and E) or (A and (D or E))) + W[i+3] + K3); asm db $66; rol word[D],30 end; inc(A,LRot_5(B)); inc(A,((C and D) or (E and (C or D))) + W[i+4] + K3); asm db $66; rol word[C],30 end; inc(i,5); end; while i<80 do begin inc(E,LRot_5(A)); inc(E,(B xor C xor D) + W[i ] + K4); asm db $66; rol word[B],30 end; inc(D,LRot_5(E)); inc(D,(A xor B xor C) + W[i+1] + K4); asm db $66; rol word[A],30 end; inc(C,LRot_5(D)); inc(C,(E xor A xor B) + W[i+2] + K4); asm db $66; rol word[E],30 end; inc(B,LRot_5(C)); inc(B,(D xor E xor A) + W[i+3] + K4); asm db $66; rol word[D],30 end; inc(A,LRot_5(B)); inc(A,(C xor D xor E) + W[i+4] + K4); asm db $66; rol word[C],30 end; inc(i,5); end; {Calculate new working hash} inc(Data.Hash[0], A); inc(Data.Hash[1], B); inc(Data.Hash[2], C); inc(Data.Hash[3], D); inc(Data.Hash[4], E); end; {$else} {TP5/5.5} {---------------------------------------------------------------------------} procedure UpdateLen(var whi, wlo: longint; BLen: longint); {-Add BLen to 64 bit value (wlo, whi)} inline( $58/ {pop ax } $5A/ {pop dx } $5B/ {pop bx } $07/ {pop es } $26/$01/$07/ {add es:[bx],ax } $26/$11/$57/$02/ {adc es:[bx+02],dx} $5B/ {pop bx } $07/ {pop es } $26/$83/$17/$00/ {adc es:[bx],0 } $26/$83/$57/$02/$00);{adc es:[bx+02],0 } {---------------------------------------------------------------------------} function RB(A: longint): longint; {-reverse byte order in longint} inline( $58/ { pop ax } $5A/ { pop dx } $86/$C6/ { xchg dh,al} $86/$E2); { xchg dl,ah} {---------------------------------------------------------------------------} function LRot_1(x: longint): longint; {-Rotate left 1} inline( $58/ { pop ax } $5A/ { pop dx } $2B/$C9/ { sub cx,cx} $D1/$D0/ { rcl ax,1 } $D1/$D2/ { rcl dx,1 } $13/$C1); { adc ax,cx} {---------------------------------------------------------------------------} function LRot_5(x: longint): longint; {-Rotate left 5} inline( $58/ { pop ax } $5A/ { pop dx } $2B/$C9/ { sub cx,cx} $D1/$D0/ { rcl ax,1 } $D1/$D2/ { rcl dx,1 } $13/$C1/ { adc ax,cx} $D1/$D0/ { rcl ax,1 } $D1/$D2/ { rcl dx,1 } $13/$C1/ { adc ax,cx} $D1/$D0/ { rcl ax,1 } $D1/$D2/ { rcl dx,1 } $13/$C1/ { adc ax,cx} $D1/$D0/ { rcl ax,1 } $D1/$D2/ { rcl dx,1 } $13/$C1/ { adc ax,cx} $D1/$D0/ { rcl ax,1 } $D1/$D2/ { rcl dx,1 } $13/$C1); { adc ax,cx} {---------------------------------------------------------------------------} function LRot_30(x: longint): longint; {-Rotate left 30 = rot right 2} inline( $58/ { pop ax } $5A/ { pop dx } $8B/$CA/ { mov cx,dx} $D1/$E9/ { shr cx,1 } $D1/$D8/ { rcr ax,1 } $D1/$DA/ { rcr dx,1 } $8B/$CA/ { mov cx,dx} $D1/$E9/ { shr cx,1 } $D1/$D8/ { rcr ax,1 } $D1/$DA); { rcr dx,1 } {---------------------------------------------------------------------------} procedure ExpandMessageBlocks(var W: TWorkBuf; var Buf: THashBuffer); {-Calculate "expanded message blocks"} var i: integer; begin {Part 1: Transfer buffer with little -> big endian conversion} for i:= 0 to 15 do W[i]:= RB(THashBuf32(Buf)[i]); {Part 2: Calculate remaining "expanded message blocks"} for i:= 16 to 79 do W[i]:= LRot_1(W[i-3] xor W[i-8] xor W[i-14] xor W[i-16]); end; {---------------------------------------------------------------------------} procedure SHA1Compress(var Data: THashContext); {-Actual hashing function} var i: integer; A, B, C, D, E: longint; W: TWorkBuf; begin ExpandMessageBlocks(W, Data.Buffer); {Assign old working hash to variables A..E} A := Data.Hash[0]; B := Data.Hash[1]; C := Data.Hash[2]; D := Data.Hash[3]; E := Data.Hash[4]; {SHA1 compression function} {Partial unroll for more speed, full unroll only marginally faster} {BIT16: rotateleft via function call} i := 0; while i<20 do begin inc(E,LRot_5(A) + (D xor (B and (C xor D))) + W[i ] + K1); B := LRot_30(B); inc(D,LRot_5(E) + (C xor (A and (B xor C))) + W[i+1] + K1); A := LRot_30(A); inc(C,LRot_5(D) + (B xor (E and (A xor B))) + W[i+2] + K1); E := LRot_30(E); inc(B,LRot_5(C) + (A xor (D and (E xor A))) + W[i+3] + K1); D := LRot_30(D); inc(A,LRot_5(B) + (E xor (C and (D xor E))) + W[i+4] + K1); C := LRot_30(C); inc(i,5); end; while i<40 do begin inc(E,LRot_5(A) + (B xor C xor D) + W[i ] + K2); B := LRot_30(B); inc(D,LRot_5(E) + (A xor B xor C) + W[i+1] + K2); A := LRot_30(A); inc(C,LRot_5(D) + (E xor A xor B) + W[i+2] + K2); E := LRot_30(E); inc(B,LRot_5(C) + (D xor E xor A) + W[i+3] + K2); D := LRot_30(D); inc(A,LRot_5(B) + (C xor D xor E) + W[i+4] + K2); C := LRot_30(C); inc(i,5); end; while i<60 do begin inc(E,LRot_5(A) + ((B and C) or (D and (B or C))) + W[i ] + K3); B := LRot_30(B); inc(D,LRot_5(E) + ((A and B) or (C and (A or B))) + W[i+1] + K3); A := LRot_30(A); inc(C,LRot_5(D) + ((E and A) or (B and (E or A))) + W[i+2] + K3); E := LRot_30(E); inc(B,LRot_5(C) + ((D and E) or (A and (D or E))) + W[i+3] + K3); D := LRot_30(D); inc(A,LRot_5(B) + ((C and D) or (E and (C or D))) + W[i+4] + K3); C := LRot_30(C); inc(i,5); end; while i<80 do begin inc(E,LRot_5(A) + (B xor C xor D) + W[i ] + K4); B := LRot_30(B); inc(D,LRot_5(E) + (A xor B xor C) + W[i+1] + K4); A := LRot_30(A); inc(C,LRot_5(D) + (E xor A xor B) + W[i+2] + K4); E := LRot_30(E); inc(B,LRot_5(C) + (D xor E xor A) + W[i+3] + K4); D := LRot_30(D); inc(A,LRot_5(B) + (C xor D xor E) + W[i+4] + K4); C := LRot_30(C); inc(i,5); end; {Calculate new working hash} inc(Data.Hash[0], A); inc(Data.Hash[1], B); inc(Data.Hash[2], C); inc(Data.Hash[3], D); inc(Data.Hash[4], E); end; {$endif BASM16} {$endif BIT16} {---------------------------------------------------------------------------} procedure SHA1Init(var Context: THashContext); {-initialize context} begin {Clear context, buffer=0!!} fillchar(Context,sizeof(Context),0); with Context do begin Hash[0] := longint($67452301); Hash[1] := longint($EFCDAB89); Hash[2] := longint($98BADCFE); Hash[3] := longint($10325476); Hash[4] := longint($C3D2E1F0); end; end; {---------------------------------------------------------------------------} procedure SHA1UpdateXL(var Context: THashContext; Msg: pointer; Len: longint); {-update context with Msg data} var i: integer; begin {Update message bit length} if Len<=$1FFFFFFF then UpdateLen(Context.MLen[1], Context.MLen[0], Len shl 3) else begin for i:=1 to 8 do UpdateLen(Context.MLen[1], Context.MLen[0], Len) end; while Len > 0 do begin {fill block with msg data} Context.Buffer[Context.Index]:= pByte(Msg)^; inc(Ptr2Inc(Msg)); inc(Context.Index); dec(Len); if Context.Index=SHA1_BlockLen then begin {If 512 bit transferred, compress a block} Context.Index:= 0; SHA1Compress(Context); while Len>=SHA1_BlockLen do begin move(Msg^,Context.Buffer,SHA1_BlockLen); SHA1Compress(Context); inc(Ptr2Inc(Msg),SHA1_BlockLen); dec(Len,SHA1_BlockLen); end; end; end; end; {---------------------------------------------------------------------------} procedure SHA1Update(var Context: THashContext; Msg: pointer; Len: word); {-update context with Msg data} begin SHA1UpdateXL(Context, Msg, Len); end; {---------------------------------------------------------------------------} procedure SHA1FinalBitsEx(var Context: THashContext; var Digest: THashDigest; BData: byte; bitlen: integer); {-finalize SHA1 calculation with bitlen bits from BData (big-endian), clear context} var i: integer; begin {Message padding} {append bits from BData and a single '1' bit} if (bitlen>0) and (bitlen<=7) then begin Context.Buffer[Context.Index]:= (BData and BitAPI_Mask[bitlen]) or BitAPI_PBit[bitlen]; UpdateLen(Context.MLen[1], Context.MLen[0], bitlen); end else Context.Buffer[Context.Index]:= $80; for i:=Context.Index+1 to 63 do Context.Buffer[i] := 0; {2. Compress if more than 448 bits, (no room for 64 bit length} if Context.Index>= 56 then begin SHA1Compress(Context); fillchar(Context.Buffer,56,0); end; {Write 64 bit msg length into the last bits of the last block} {(in big endian format) and do a final compress} THashBuf32(Context.Buffer)[14] := RB(Context.MLen[1]); THashBuf32(Context.Buffer)[15] := RB(Context.MLen[0]); SHA1Compress(Context); {Hash->Digest to little endian format} fillchar(Digest, sizeof(Digest), 0); for i:=0 to 4 do THashDig32(Digest)[i]:= RB(Context.Hash[i]); {Clear context} fillchar(Context,sizeof(Context),0); end; {---------------------------------------------------------------------------} procedure SHA1FinalBits(var Context: THashContext; var Digest: TSHA1Digest; BData: byte; bitlen: integer); {-finalize SHA1 calculation with bitlen bits from BData (big-endian), clear context} var tmp: THashDigest; begin SHA1FinalBitsEx(Context, tmp, BData, bitlen); move(tmp, Digest, sizeof(Digest)); end; {---------------------------------------------------------------------------} procedure SHA1FinalEx(var Context: THashContext; var Digest: THashDigest); {-finalize SHA1 calculation, clear context} begin SHA1FinalBitsEx(Context,Digest,0,0); end; {---------------------------------------------------------------------------} procedure SHA1Final(var Context: THashContext; var Digest: TSHA1Digest); {-finalize SHA1 calculation, clear context} var tmp: THashDigest; begin SHA1FinalBitsEx(Context, tmp, 0, 0); move(tmp, Digest, sizeof(Digest)); end; {---------------------------------------------------------------------------} function SHA1SelfTest: boolean; {-self test SHA1: compare with known value} const s1: string[ 3] = 'abc'; s2: string[56] = 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'; D1: TSHA1Digest= ($a9,$99,$3e,$36,$47,$06,$81,$6a,$ba,$3e,$25,$71,$78,$50,$c2,$6c,$9c,$d0,$d8,$9d); D2: TSHA1Digest= ($84,$98,$3E,$44,$1C,$3B,$D2,$6E,$BA,$AE,$4A,$A1,$F9,$51,$29,$E5,$E5,$46,$70,$F1); D3: TSHA1Digest= ($bb,$6b,$3e,$18,$f0,$11,$5b,$57,$92,$52,$41,$67,$6f,$5b,$1a,$e8,$87,$47,$b0,$8a); D4: TSHA1Digest= ($98,$23,$2a,$15,$34,$53,$14,$9a,$f8,$d5,$2a,$61,$50,$3a,$50,$74,$b8,$59,$70,$e8); var Context: THashContext; Digest : TSHA1Digest; function SingleTest(s: Str127; TDig: TSHA1Digest): boolean; {-do a single test, const not allowed for VER<7} { Two sub tests: 1. whole string, 2. one update per char} var i: integer; begin SingleTest := false; {1. Hash complete string} SHA1Full(Digest, @s[1],length(s)); {Compare with known value} if not HashSameDigest(@SHA1_Desc, PHashDigest(@Digest), PHashDigest(@TDig)) then exit; {2. one update call for all chars} SHA1Init(Context); for i:=1 to length(s) do SHA1Update(Context,@s[i],1); SHA1Final(Context,Digest); {Compare with known value} if not HashSameDigest(@SHA1_Desc, PHashDigest(@Digest), PHashDigest(@TDig)) then exit; SingleTest := true; end; begin SHA1SelfTest := false; {1 Zero bit from NESSIE test vectors} SHA1Init(Context); SHA1FinalBits(Context,Digest,0,1); if not HashSameDigest(@SHA1_Desc, PHashDigest(@Digest), PHashDigest(@D3)) then exit; {4 hightest bits of $50, D4 calculated with program shatest from RFC 4634} SHA1Init(Context); SHA1FinalBits(Context,Digest,$50,4); if not HashSameDigest(@SHA1_Desc, PHashDigest(@Digest), PHashDigest(@D4)) then exit; {strings from SHA1 document} SHA1SelfTest := SingleTest(s1, D1) and SingleTest(s2, D2) end; {---------------------------------------------------------------------------} procedure SHA1FullXL(var Digest: TSHA1Digest; Msg: pointer; Len: longint); {-SHA1 of Msg with init/update/final} var Context: THashContext; begin SHA1Init(Context); SHA1UpdateXL(Context, Msg, Len); SHA1Final(Context, Digest); end; {---------------------------------------------------------------------------} procedure SHA1Full(var Digest: TSHA1Digest; Msg: pointer; Len: word); {-SHA1 of Msg with init/update/final} begin SHA1FullXL(Digest, Msg, Len); end; {---------------------------------------------------------------------------} procedure SHA1File({$ifdef CONST} const {$endif} fname: Str255; var Digest: TSHA1Digest; var buf; bsize: word; var Err: word); {-SHA1 of file, buf: buffer with at least bsize bytes} var tmp: THashDigest; begin HashFile(fname, @SHA1_Desc, tmp, buf, bsize, Err); move(tmp, Digest, sizeof(Digest)); end; begin {$ifdef VER5X} fillchar(SHA1_Desc, sizeof(SHA1_Desc), 0); with SHA1_Desc do begin HSig := C_HashSig; HDSize := sizeof(THashDesc); HDVersion := C_HashVers; HBlockLen := SHA1_BlockLen; HDigestlen:= sizeof(TSHA1Digest); HInit := SHA1Init; HFinal := SHA1FinalEx; HUpdateXL := SHA1UpdateXL; HAlgNum := longint(_SHA1); HName := 'SHA1'; HPtrOID := @SHA1_OID; HLenOID := 6; HFinalBit := SHA1FinalBitsEx; end; {$endif} RegisterHash(_SHA1, @SHA1_Desc); end. doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/kdf.pas0000664000175000017500000003713613146261166022407 0ustar alexxalexxunit kdf; {(Password Based) Key Derivation Functions} interface (************************************************************************* DESCRIPTION : (Password Based) Key Derivation Functions REQUIREMENTS : TP5-7, D1-D7/D9-D10/D12/D17-D18, FPC, VP, WDOSX EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REFERENCES : http://tools.ietf.org/html/rfc2898 http://tools.ietf.org/html/rfc3211 [includes test vectors] http://tools.ietf.org/html/rfc5869 [includes test vectors] http://www.di-mgt.com.au/cryptoKDFs.html [includes test vectors] Version Date Author Modification ------- -------- ------- ------------------------------------------ 0.10 17.01.06 W.Ehrhardt Initial version based on keyderiv 1.29 0.11 17.01.06 we error codes 0.12 23.01.06 we new names: unit pb_kdf, functions kdf2/s 0.13 22.06.08 we Make IncMSB work with FPC -dDebug 0.14 12.07.08 we Rename old kdf2 to pbkdf2, unit kdf 0.15 12.07.08 we pbkdf1 0.16 12.07.08 we kdf1, kdf2, kdf3, mgf1 0.17 12.11.08 we uses BTypes, Ptr2Inc and/or Str255 0.18 25.04.09 we updated RFC URL(s) 0.19 19.08.10 we kdf_err_nil_input 0.20 20.08.10 we hkdf/hkdfs 0.21 15.08.14 we pbkdf2 functions with longint sLen, dkLen 0.22 16.08.15 we Removed $ifdef DLL / stdcall **************************************************************************) (*------------------------------------------------------------------------- (C) Copyright 2006-2015 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ----------------------------------------------------------------------------*) {$i STD.INC} uses BTypes,Hash,HMAC; const kdf_err_nil_pointer = $0001; {phash descriptor is nil} kdf_err_digestlen = $0002; {digest length from descriptor is zero} kdf_err_invalid_dKLen = $0003; {dKLen greater than hash digest length} kdf_err_nil_input = $0004; {input nil pointer and non-zero length} function kdf1(phash: PHashDesc; Z: pointer; zLen: word; pOtherInfo: pointer; oiLen: word; var DK; dkLen: word): integer; {-Derive key DK from shared secret Z using optional OtherInfo, hash function from phash} function kdf2(phash: PHashDesc; Z: pointer; zLen: word; pOtherInfo: pointer; oiLen: word; var DK; dkLen: word): integer; {-Derive key DK from shared secret Z using optional OtherInfo, hash function from phash} function kdf3(phash: PHashDesc; Z: pointer; zLen: word; pOtherInfo: pointer; oiLen: word; var DK; dkLen: word): integer; {-Derive key DK from shared secret Z using optional OtherInfo, hash function from phash} function mgf1(phash: PHashDesc; pSeed: pointer; sLen: word; var Mask; mLen: word): integer; {-Derive Mask from seed, hash function from phash, Mask Generation Function 1 for PKCS #1} function pbkdf1(phash: PHashDesc; pPW: pointer; pLen: word; salt: pointer; C: longint; var DK; dkLen: word): integer; {-Derive key DK from password pPW using 8 byte salt and iteration count C, uses hash function from phash} function pbkdf1s(phash: PHashDesc; sPW: Str255; salt: pointer; C: longint; var DK; dkLen: word): integer; {-Derive key DK from password string sPW using 8 byte salt and iteration count C, uses hash function from phash} function pbkdf2(phash: PHashDesc; pPW: pointer; pLen: word; salt: pointer; sLen,C: longint; var DK; dkLen: longint): integer; {-Derive key DK from password pPW using salt and iteration count C, uses hash function from phash} function pbkdf2s(phash: PHashDesc; sPW: Str255; salt: pointer; sLen,C: longint; var DK; dkLen: longint): integer; {-Derive key DK from password string sPW using salt and iteration count C, uses hash function from phash} function hkdf(phash: PHashDesc; {Descriptor of the Hash to use} pIKM: pointer; L_IKM: word; {input key material: addr/length} salt: pointer; L_salt: word; {optional salt; can be nil: see below } info: pointer; L_info: word; {optional context/application specific information} var DK; dkLen: word): integer; {output key material: addr/length} {-Derive key DK from input key material and salt/info, uses hash function from phash} { If salt=nil then phash^.HDigestLen binary zeros will be used as salt.} function hkdfs(phash: PHashDesc; sIKM: Str255; {Hash; input key material as string} salt: pointer; L_salt: word; {optional salt; can be nil: see below } info: pointer; L_info: word; {optional context/application specific information} var DK; dkLen: word): integer; {output key material: addr/length} {-Derive key DK from input key material and salt/info, uses hash function from phash} { If salt=nil then phash^.HDigestLen binary zeros will be used as salt.} implementation {helper type} type TMSBA = array[0..3] of byte; {---------------------------------------------------------------------------} procedure IncMSB(var CTR: TMSBA); {-Increment CTR[3]..CTR[0], i.e. 32 Bit MSB counter} var j: integer; begin for j:=3 downto 0 do begin if CTR[j]=$FF then CTR[j] := 0 else begin inc(CTR[j]); exit; end; end; end; {---------------------------------------------------------------------------} function pbkdf1(phash: PHashDesc; pPW: pointer; pLen: word; salt: pointer; C: longint; var DK; dkLen: word): integer; {-Derive key DK from password pPW using 8 byte salt and iteration count C, uses hash function from phash} var ctx: THashContext; Digest: THashDigest; hlen: word; begin if (phash=nil) or (phash^.HSig<>C_HashSig) then begin pbkdf1 := kdf_err_nil_pointer; exit; end; hLen := phash^.HDigestLen; if hLen=0 then begin pbkdf1 := kdf_err_digestlen; exit; end; if hLen0)) or (salt=nil) then begin pbkdf1 := kdf_err_nil_input; exit; end; pbkdf1 := 0; {calculate T_1 = hash(PW || salt)} with phash^ do begin HInit(ctx); HUpdateXL(ctx, pPW, pLen); HUpdateXL(ctx, salt, 8); HFinal(ctx, Digest); end; while C>1 do begin HashFullXL(phash, Digest, @Digest, hlen); dec(C); end; move(Digest, DK, dKLen); end; {---------------------------------------------------------------------------} function pbkdf1s(phash: PHashDesc; sPW: Str255; salt: pointer; C: longint; var DK; dkLen: word): integer; {-Derive key DK from password string sPW using 8 byte salt and iteration count C, uses hash function from phash} begin pbkdf1s := pbkdf1(phash, @sPW[1], length(sPW), salt, C, DK, dkLen); end; {---------------------------------------------------------------------------} function pbkdf2(phash: PHashDesc; pPW: pointer; pLen: word; salt: pointer; sLen,C: longint; var DK; dkLen: longint): integer; {-Derive key DK from password pPW using salt and iteration count C, uses hash function from phash} var k, hLen: word; i, j, lk: longint; pDK: pByte; {pointer to DK } ii: TMSBA; {i in big endian} u, ucum: THashDigest; ctx: THMAC_Context; begin if phash=nil then begin pbkdf2 := kdf_err_nil_pointer; exit; end; if phash^.HDigestLen=0 then begin pbkdf2 := kdf_err_digestlen; exit; end; if ((pPW=nil) and (pLen>0)) or ((salt=nil) and (sLen>0)) then begin pbkdf2 := kdf_err_nil_input; exit; end; pbkdf2 := 0; hLen := phash^.HDigestLen; lk := 0; pDK := pByte(@DK); fillchar(ii, sizeof(ii), 0); for i:=1 to 1 + pred(dkLen) div hLen do begin IncMSB(ii); fillchar(ucum, sizeof(ucum),0); for j:=1 to C do begin hmac_init(ctx, phash, pPW, pLen); if j=1 then begin {U_1 = PRF(pPW, salt || ii)} hmac_updateXL(ctx, salt, sLen); hmac_updateXL(ctx, @ii, 4); end else begin {U_i = PRF(pPW, U_(i-1)} hmac_updateXL(ctx, @u, hLen); end; hmac_final(ctx, u); {update cumulative XOR U_i} for k:=0 to hLen-1 do ucum[k] := ucum[k] xor u[k]; end; {T_i = F(P,S,C,l) = ucum} for k:=0 to hLen-1 do begin {concat T_i} if lkC_HashSig) then begin kdfx := kdf_err_nil_pointer; exit; end; hLen := phash^.HDigestLen; if hLen=0 then begin kdfx := kdf_err_digestlen; exit; end; if ((Z=nil) and (zLen>0)) or ((pOtherInfo=nil) and (oLen>0)) then begin kdfx := kdf_err_nil_input; exit; end; kdfx := 0; fillchar(ctr, sizeof(ctr), 0); if x=2 then IncMSB(ctr); lk := 0; pDK := pByte(@DK); for i:=1 to 1 + pred(dkLen) div hLen do begin if x=3 then begin {Hash(ctr || Z || [OtherInfo])} {x=3} phash^.HInit(ctx); phash^.HUpdateXL(ctx, @ctr, sizeof(ctr)); phash^.HUpdateXL(ctx, Z, zLen); end else begin {Hash(Z || ctr || [OtherInfo])} {x=1,2} phash^.HInit(ctx); phash^.HUpdateXL(ctx, Z, zLen); phash^.HUpdateXL(ctx, @ctr, sizeof(ctr)); end; if oLen<>0 then phash^.HUpdateXL(ctx, pOtherInfo, oLen); phash^.HFinal(ctx, Digest); for k:=0 to hLen-1 do begin {store T_i} if lkC_HashSig) then begin hkdf := kdf_err_nil_pointer; exit; end; if ((pIKM=nil) and (L_IKM>0)) or ((info=nil) and (L_info>0)) then begin hkdf := kdf_err_nil_input; exit; end; hLen := phash^.HDigestLen; if hLen=0 then begin hkdf := kdf_err_digestlen; exit; end; {Stage 1: Extract} hkdf := 0; {if salt=nil then hLen binary zeros are used} if salt=nil then begin fillchar(TI, sizeof(TI), 0); hmac_init(ctx, phash, @TI, hLen); end else hmac_init(ctx, phash, salt, L_salt); hmac_update(ctx, pIKM, L_IKM); hmac_final(ctx, PRK); {Stage 2: Expand} lt := 0; lk := 0; ctr := 1; pDK := pByte(@DK); for i:=1 to 1 + pred(dkLen) div hLen do begin {calculate T_i from T_(i-1), info, and ctr} hmac_init(ctx, phash, @PRK, hLen); hmac_update(ctx, @TI, lt); hmac_update(ctx, info, L_info); hmac_update(ctx, @ctr, 1); hmac_final(ctx, TI); for k:=0 to hLen-1 do begin {store T_i} if lknil) and (PHash^.HAlgNum=longint(AlgId)) and (PHash^.HSig=C_HashSig) and (PHash^.HDVersion=C_HashVers) and (PHash^.HDSize=sizeof(THashDesc)) then PHashVec[AlgId] := PHash; end; {---------------------------------------------------------------------------} function FindHash_by_ID(AlgoID: THashAlgorithm): PHashDesc; {-Return PHashDesc of AlgoID, nil if not found/registered} var p: PHashDesc; A: longint; begin A := longint(AlgoID); FindHash_by_ID := nil; if (A>=ord(C_MinHash)) and (A<=ord(C_MaxHash)) then begin p := PHashVec[AlgoID]; if (p<>nil) and (p^.HSig=C_HashSig) and (p^.HAlgNum=A) then FindHash_by_ID := p; end; end; {---------------------------------------------------------------------------} function FindHash_by_Name(AlgoName: THashName): PHashDesc; {-Return PHashDesc of Algo with AlgoName, nil if not found/registered} var algo : THashAlgorithm; phash: PHashDesc; function StrUpcase(s: THashName): THashName; {-Upcase for strings} var i: integer; begin for i:=1 to length(s) do s[i] := upcase(s[i]); StrUpcase := s; end; begin AlgoName := StrUpcase(Algoname); {Transform RMD160 alias to standard name} if AlgoName='RMD160' then AlgoName:='RIPEMD160'; FindHash_by_Name := nil; for algo := C_MinHash to C_MaxHash do begin phash := PHashVec[algo]; if (phash<>nil) and (AlgoName=StrUpcase(phash^.HName)) and (phash^.HSig=C_HashSig) and (phash^.HAlgNum=longint(algo)) then begin FindHash_by_Name := phash; exit; end; end; end; {---------------------------------------------------------------------------} procedure HashUpdate(PHash: PHashDesc; var Context: THashContext; Msg: pointer; Len: word); {-update context with Msg data} begin if PHash<>nil then with PHash^ do begin if HSig=C_HashSig then HUpdateXL(Context, Msg, Len); end; end; {---------------------------------------------------------------------------} procedure HashFullXL(PHash: PHashDesc; var Digest: THashDigest; Msg: pointer; Len: longint); {-Calulate hash digest of Msg with init/update/final} var Context: THashContext; begin if PHash<>nil then with PHash^ do begin if HSig=C_HashSig then begin HInit(Context); HUpdateXL(Context, Msg, Len); HFinal(Context, Digest); end; end; end; {---------------------------------------------------------------------------} procedure HashFull(PHash: PHashDesc; var Digest: THashDigest; Msg: pointer; Len: word); {-Calulate hash digest of Msg with init/update/final} begin {test PHash<>nil in HashFullXL} HashFullXL(PHash, Digest, Msg, Len); end; {---------------------------------------------------------------------------} function HashSameDigest(PHash: PHashDesc; PD1, PD2: PHashDigest): boolean; {-Return true if same digests, using HDigestlen of PHash} var i: integer; begin HashSameDigest := false; if PHash<>nil then with PHash^ do begin if (HSig=C_HashSig) and (HDigestlen>0) then begin for i:=0 to pred(HDigestlen) do begin if PD1^[i]<>PD2^[i] then exit; end; HashSameDigest := true; end; end; end; {$i-} {Force I-} {---------------------------------------------------------------------------} procedure HashFile({$ifdef CONST} const {$endif} fname: Str255; PHash: PHashDesc; var Digest: THashDigest; var buf; bsize: word; var Err: word); {-Calulate hash digest of file, buf: buffer with at least bsize bytes} var {$ifdef VirtualPascal} fms: word; {$else} fms: byte; {$endif} {$ifndef BIT16} L: longint; {$else} L: word; {$endif} var Context: THashContext; f: file; begin if (PHash=nil) or (Phash^.HSig<>C_HashSig) then begin Err := 204; {Invalid pointer} exit; end; fms := FileMode; {$ifdef VirtualPascal} FileMode := $40; {open_access_ReadOnly or open_share_DenyNone;} {$else} FileMode := 0; {$endif} system.assign(f,{$ifdef D12Plus} string {$endif} (fname)); system.reset(f,1); Err := IOResult; FileMode := fms; if Err<>0 then exit; with PHash^ do begin HInit(Context); L := bsize; while (Err=0) and (L=bsize) do begin system.blockread(f,buf,bsize,L); Err := IOResult; HUpdateXL(Context, @buf, L); end; system.close(f); if IOResult=0 then {}; HFinal(Context, Digest); end; end; begin {$ifdef HAS_ASSERT} assert(sizeof(THashContext)=HASHCTXSIZE , '** Invalid sizeof(THashContext)'); {$else} if sizeof(THashContext)<>HASHCTXSIZE then RunError(227); {$endif} {Paranoia: initialize all descriptor pointers to nil (should} {be done by compiler/linker because array is in global data)} fillchar(PHashVec,sizeof(PHashVec),0); end. doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/sha3_512.pas0000664000175000017500000003310613144361461023056 0ustar alexxalexxunit SHA3_512; {SHA3-512 - 512 bit Secure Hash Function} interface (************************************************************************* DESCRIPTION : SHA3-512 - 512 bit Secure Hash Function REQUIREMENTS : TP5-7, D1-D7/D9-D10/D12/D17-D18, FPC, VP EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REFERENCES : - FIPS 202 SHA-3 Standard: 'Permutation-Based Hash and Extendable-Output Functions' available from http://csrc.nist.gov/publications/PubsFIPS.html or http://dx.doi.org/10.6028/NIST.FIPS.202 or http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf - Test vectors and intermediate values: http://csrc.nist.gov/groups/ST/toolkit/examples.html Version Date Author Modification ------- -------- ------- ------------------------------------------ 0.10 10.08.15 W.Ehrhardt Initial BP version using SHA3-256 layout 0.11 17.08.15 we Updated references **************************************************************************) (*------------------------------------------------------------------------- (C) Copyright 2015 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ----------------------------------------------------------------------------*) {$i STD.INC} uses BTypes,Hash,SHA3; procedure SHA3_512Init(var Context: THashContext); {-initialize context} procedure SHA3_512Update(var Context: THashContext; Msg: pointer; Len: word); {-update context with Msg data} procedure SHA3_512UpdateXL(var Context: THashContext; Msg: pointer; Len: longint); {-update context with Msg data} procedure SHA3_512Final(var Context: THashContext; var Digest: TSHA3_512Digest); {-finalize SHA3-512 calculation, clear context} procedure SHA3_512FinalEx(var Context: THashContext; var Digest: THashDigest); {-finalize SHA3-512 calculation, clear context} procedure SHA3_512FinalBitsEx(var Context: THashContext; var Digest: THashDigest; BData: byte; bitlen: integer); {-finalize SHA3-512 calculation with bitlen bits from BData (big-endian), clear context} procedure SHA3_512FinalBits(var Context: THashContext; var Digest: TSHA3_512Digest; BData: byte; bitlen: integer); {-finalize SHA3-512 calculation with bitlen bits from BData (big-endian), clear context} procedure SHA3_512FinalBits_LSB(var Context: THashContext; var Digest: TSHA3_512Digest; BData: byte; bitlen: integer); {-finalize SHA3-512 calculation with bitlen bits from BData (LSB format), clear context} function SHA3_512SelfTest: boolean; {-self test for string from SHA3-512 documents} procedure SHA3_512Full(var Digest: TSHA3_512Digest; Msg: pointer; Len: word); {-SHA3-512 of Msg with init/update/final} procedure SHA3_512FullXL(var Digest: TSHA3_512Digest; Msg: pointer; Len: longint); {-SHA3-512 of Msg with init/update/final} procedure SHA3_512File({$ifdef CONST} const {$endif} fname: Str255; var Digest: TSHA3_512Digest; var buf; bsize: word; var Err: word); {-SHA3-512 of file, buf: buffer with at least bsize bytes} implementation const SHA3_512_BlockLen = 72; {Rate / 8, used only for HMAC} {FIPS202, Tab.3} {http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html} {2.16.840.1.101.3.4.2.8} {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) SHA3-512(10)} const SHA3_512_OID : TOID_Vec = (2,16,840,1,101,3,4,2,10); {Len=9} {??? NIST claims it has reserved SHA3-512(10), but e.g.} {http://www.oid-info.com/ does not know it 2015-08-10. } {$ifndef VER5X} const SHA3_512_Desc: THashDesc = ( HSig : C_HashSig; HDSize : sizeof(THashDesc); HDVersion : C_HashVers; HBlockLen : SHA3_512_BlockLen; HDigestlen: sizeof(TSHA3_512Digest); {$ifdef FPC_ProcVar} HInit : @SHA3_512Init; HFinal : @SHA3_512FinalEx; HUpdateXL : @SHA3_512UpdateXL; {$else} HInit : SHA3_512Init; HFinal : SHA3_512FinalEx; HUpdateXL : SHA3_512UpdateXL; {$endif} HAlgNum : longint(_SHA3_512); HName : 'SHA3-512'; HPtrOID : @SHA3_512_OID; HLenOID : 9; HFill : 0; {$ifdef FPC_ProcVar} HFinalBit : @SHA3_512FinalBitsEx; {$else} HFinalBit : SHA3_512FinalBitsEx; {$endif} HReserved : (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) ); {$else} var SHA3_512_Desc: THashDesc; {$endif} {$ifdef BIT16} {$F-} {$endif} {---------------------------------------------------------------------------} procedure SHA3_512Init(var Context: THashContext); {-initialize context} begin {Clear context} SHA3_LastError := SHA3_Init(TSHA3State(Context),__SHA3_512); end; {---------------------------------------------------------------------------} procedure SHA3_512UpdateXL(var Context: THashContext; Msg: pointer; Len: longint); {-update context with Msg data} begin SHA3_LastError := SHA3_UpdateXL(TSHA3State(Context), Msg, Len); end; {---------------------------------------------------------------------------} procedure SHA3_512Update(var Context: THashContext; Msg: pointer; Len: word); {-update context with Msg data} begin SHA3_LastError := SHA3_UpdateXL(TSHA3State(Context), Msg, Len); end; {---------------------------------------------------------------------------} procedure SHA3_512FinalBitsEx(var Context: THashContext; var Digest: THashDigest; BData: byte; bitlen: integer); {-finalize SHA3-512 calculation with bitlen bits from BData (big-endian), clear context} begin SHA3_LastError := SHA3_FinalBit(TSHA3State(Context), BData, bitlen, @Digest[0], 8*sizeof(Digest)); end; {---------------------------------------------------------------------------} procedure SHA3_512FinalBits(var Context: THashContext; var Digest: TSHA3_512Digest; BData: byte; bitlen: integer); {-finalize SHA3-512 calculation with bitlen bits from BData (big-endian), clear context} begin SHA3_LastError := SHA3_FinalBit(TSHA3State(Context), BData, bitlen, @Digest[0], 8*sizeof(Digest)); end; {---------------------------------------------------------------------------} procedure SHA3_512FinalBits_LSB(var Context: THashContext; var Digest: TSHA3_512Digest; BData: byte; bitlen: integer); {-finalize SHA3-512 calculation with bitlen bits from BData (LSB format), clear context} begin SHA3_LastError := SHA3_FinalBit_LSB(TSHA3State(Context), BData, bitlen, @Digest[0], 8*sizeof(Digest)); end; {---------------------------------------------------------------------------} procedure SHA3_512FinalEx(var Context: THashContext; var Digest: THashDigest); {-finalize SHA3-512 calculation, clear context} begin SHA3_LastError := SHA3_FinalHash(TSHA3State(Context), @Digest[0]); end; {---------------------------------------------------------------------------} procedure SHA3_512Final(var Context: THashContext; var Digest: TSHA3_512Digest); {-finalize SHA3-512 calculation, clear context} begin SHA3_LastError := SHA3_FinalHash(TSHA3State(Context), @Digest[0]); end; {---------------------------------------------------------------------------} function SHA3_512SelfTest: boolean; {-self test for string from SHA3-512 documents} const Bl1 = 0; dig1: TSHA3_512Digest = ($A6,$9F,$73,$CC,$A2,$3A,$9A,$C5, $C8,$B5,$67,$DC,$18,$5A,$75,$6E, $97,$C9,$82,$16,$4F,$E2,$58,$59, $E0,$D1,$DC,$C1,$47,$5C,$80,$A6, $15,$B2,$12,$3A,$F1,$F5,$F9,$4C, $11,$E3,$E9,$40,$2C,$3A,$C5,$58, $F5,$00,$19,$9D,$95,$B6,$D3,$E3, $01,$75,$85,$86,$28,$1D,$CD,$26); BL2 = 5; msg2: array[0..0] of byte = ($13); dig2: TSHA3_512Digest = ($A1,$3E,$01,$49,$41,$14,$C0,$98, $00,$62,$2A,$70,$28,$8C,$43,$21, $21,$CE,$70,$03,$9D,$75,$3C,$AD, $D2,$E0,$06,$E4,$D9,$61,$CB,$27, $54,$4C,$14,$81,$E5,$81,$4B,$DC, $EB,$53,$BE,$67,$33,$D5,$E0,$99, $79,$5E,$5E,$81,$91,$8A,$DD,$B0, $58,$E2,$2A,$9F,$24,$88,$3F,$37); BL3 = 30; msg3: array[0..3] of byte = ($53,$58,$7B,$19); dig3: TSHA3_512Digest = ($98,$34,$C0,$5A,$11,$E1,$C5,$D3, $DA,$9C,$74,$0E,$1C,$10,$6D,$9E, $59,$0A,$0E,$53,$0B,$6F,$6A,$AA, $78,$30,$52,$5D,$07,$5C,$A5,$DB, $1B,$D8,$A6,$AA,$98,$1A,$28,$61, $3A,$C3,$34,$93,$4A,$01,$82,$3C, $D4,$5F,$45,$E4,$9B,$6D,$7E,$69, $17,$F2,$F1,$67,$78,$06,$7B,$AB); {https://github.com/gvanas/KeccakCodePackage, SKat len=200} BL4 = 200; msg4: array[0..24] of byte = ($aa,$fd,$c9,$24,$3d,$3d,$4a,$09, $65,$58,$a3,$60,$cc,$27,$c8,$d8, $62,$f0,$be,$73,$db,$5e,$88,$aa,$55); dig4: TSHA3_512Digest = ($62,$86,$c3,$db,$87,$d3,$b4,$5c, $fd,$4d,$e8,$5a,$7a,$dd,$18,$e0, $7a,$e2,$2f,$1f,$0f,$46,$75,$e1, $d4,$e1,$fc,$77,$63,$37,$34,$d7, $96,$28,$18,$a9,$f3,$b9,$6b,$37, $fe,$77,$4f,$c2,$6d,$ea,$78,$74, $85,$31,$7b,$96,$22,$27,$5f,$63, $a7,$dd,$6d,$62,$d6,$50,$d3,$07); var Context: THashContext; Digest : TSHA3_512Digest; function SingleTest(Msg: pointer; BL: word; TDig: TSHA3_512Digest): boolean; var bytes: word; begin SingleTest := false; SHA3_512Init(Context); if SHA3_LastError<>0 then exit; if BL=0 then SHA3_512Final(Context,Digest) else begin if BL>7 then begin bytes := BL shr 3; SHA3_512Update(Context, Msg, BL shr 3); if SHA3_LastError<>0 then exit; inc(Ptr2Inc(Msg), bytes); end; SHA3_512FinalBits_LSB(Context, Digest, pByte(Msg)^, BL and 7); end; if SHA3_LastError<>0 then exit; SingleTest := HashSameDigest(@SHA3_512_Desc, PHashDigest(@TDig), PHashDigest(@Digest)); end; begin SHA3_512SelfTest := SingleTest(nil, BL1, dig1) and SingleTest(@msg2, BL2, dig2) and SingleTest(@msg3, BL3, dig3) and SingleTest(@msg4, BL4, dig4); end; {---------------------------------------------------------------------------} procedure SHA3_512FullXL(var Digest: TSHA3_512Digest; Msg: pointer; Len: longint); {-SHA3-512 of Msg with init/update/final} var Context: THashContext; begin SHA3_512Init(Context); if SHA3_LastError=0 then SHA3_512UpdateXL(Context, Msg, Len); SHA3_512Final(Context, Digest); end; {---------------------------------------------------------------------------} procedure SHA3_512Full(var Digest: TSHA3_512Digest; Msg: pointer; Len: word); {-SHA3-512 of Msg with init/update/final} begin SHA3_512FullXL(Digest, Msg, Len); end; {---------------------------------------------------------------------------} procedure SHA3_512File({$ifdef CONST} const {$endif} fname: Str255; var Digest: TSHA3_512Digest; var buf; bsize: word; var Err: word); {-SHA3-512 of file, buf: buffer with at least bsize bytes} var tmp: THashDigest; begin HashFile(fname, @SHA3_512_Desc, tmp, buf, bsize, Err); move(tmp, Digest, sizeof(Digest)); end; begin {$ifdef VER5X} fillchar(SHA3_512_Desc, sizeof(SHA3_512_Desc), 0); with SHA3_512_Desc do begin HSig := C_HashSig; HDSize := sizeof(THashDesc); HDVersion := C_HashVers; HBlockLen := SHA3_512_BlockLen; HDigestlen:= sizeof(TSHA3_512Digest); HInit := SHA3_512Init; HFinal := SHA3_512FinalEx; HUpdateXL := SHA3_512UpdateXL; HAlgNum := longint(_SHA3_512); HName := 'SHA3-512'; HPtrOID := @SHA3_512_OID; HLenOID := 9; HFinalBit := SHA3_512FinalBitsEx; end; {$endif} RegisterHash(_SHA3_512, @SHA3_512_Desc); end. doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/hmac.pas0000664000175000017500000001523413144361461022543 0ustar alexxalexxunit HMAC; {General HMAC unit} interface (************************************************************************* DESCRIPTION : General HMAC (hash message authentication) unit REQUIREMENTS : TP5-7, D1-D7/D9-D10/D12/D17-D18, FPC, VP EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REFERENCES : - HMAC: Keyed-Hashing for Message Authentication (http://tools.ietf.org/html/rfc2104) - The Keyed-Hash Message Authentication Code (HMAC) http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf - US Secure Hash Algorithms (SHA and HMAC-SHA) (http://tools.ietf.org/html/rfc4634) REMARKS : Trailing bits in SHA3-LSB format must be converted to MSB Version Date Author Modification ------- -------- ------- ------------------------------------------ 0.10 15.01.06 W.Ehrhardt Initial version based on HMACWHIR 0.11 07.05.08 we hmac_final_bits 0.12 12.11.08 we Uses BTypes, THMAC_string replaced by Str255 0.13 25.04.09 we updated RFC URL(s) 0.14 08.08.15 we type of hmacbuf changed to THMacBuffer 0.15 16.08.15 we Removed $ifdef DLL / stdcall **************************************************************************) (*------------------------------------------------------------------------- (C) Copyright 2006-2015 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ----------------------------------------------------------------------------*) uses BTypes,hash; type THMAC_Context = record hashctx: THashContext; hmacbuf: THMacBuffer; phashd : PHashDesc; end; procedure hmac_init(var ctx: THMAC_Context; phash: PHashDesc; key: pointer; klen: word); {-initialize HMAC context with hash descr phash^ and key} procedure hmac_inits(var ctx: THMAC_Context; phash: PHashDesc; skey: Str255); {-initialize HMAC context with hash descr phash^ and skey} procedure hmac_update(var ctx: THMAC_Context; data: pointer; dlen: word); {-HMAC data input, may be called more than once} procedure hmac_updateXL(var ctx: THMAC_Context; data: pointer; dlen: longint); {-HMAC data input, may be called more than once} procedure hmac_final(var ctx: THMAC_Context; var mac: THashDigest); {-end data input, calculate HMAC digest} procedure hmac_final_bits(var ctx: THMAC_Context; var mac: THashDigest; BData: byte; bitlen: integer); {-end data input with bitlen bits (MSB format) from BData, calculate HMAC digest} implementation {---------------------------------------------------------------------------} procedure hmac_init(var ctx: THMAC_Context; phash: PHashDesc; key: pointer; klen: word); {-initialize HMAC context with hash descr phash^ and key} var i,lk,bl: word; kb: THashDigest; begin fillchar(ctx, sizeof(ctx),0); if phash<>nil then with ctx do begin phashd := phash; lk := klen; bl := phash^.HBlockLen; if lk > bl then begin {Hash if key length > block length} HashFullXL(phash, kb, key, lk); lk := phash^.HDigestLen; move(kb, hmacbuf, lk); end else move(key^, hmacbuf, lk); {XOR with ipad} for i:=0 to bl-1 do hmacbuf[i] := hmacbuf[i] xor $36; {start inner hash} phash^.HInit(hashctx); phash^.HUpdateXL(hashctx, @hmacbuf, bl); end; end; {---------------------------------------------------------------------------} procedure hmac_inits(var ctx: THMAC_Context; phash: PHashDesc; skey: Str255); {-initialize HMAC context with hash descr phash^ and skey} begin if phash<>nil then hmac_init(ctx, phash, @skey[1], length(skey)); end; {---------------------------------------------------------------------------} procedure hmac_update(var ctx: THMAC_Context; data: pointer; dlen: word); {-HMAC data input, may be called more than once} begin with ctx do begin if phashd<>nil then phashd^.HUpdateXL(hashctx, data, dlen); end; end; {---------------------------------------------------------------------------} procedure hmac_updateXL(var ctx: THMAC_Context; data: pointer; dlen: longint); {-HMAC data input, may be called more than once} begin with ctx do begin if phashd<>nil then phashd^.HUpdateXL(hashctx, data, dlen); end; end; {---------------------------------------------------------------------------} procedure hmac_final(var ctx: THMAC_Context; var mac: THashDigest); {-end data input, calculate HMAC digest} var i: integer; bl: word; begin with ctx do if phashd<>nil then begin bl := phashd^.HBlockLen; {complete inner hash} phashd^.HFinal(hashctx, mac); {remove ipad from buf, XOR opad} for i:=0 to bl-1 do hmacbuf[i] := hmacbuf[i] xor ($36 xor $5c); {outer hash} phashd^.HInit(hashctx); phashd^.HUpdateXL(hashctx, @hmacbuf, bl); phashd^.HUpdateXL(hashctx, @mac, phashd^.HDigestLen); phashd^.HFinal(hashctx, mac); end; end; {---------------------------------------------------------------------------} procedure hmac_final_bits(var ctx: THMAC_Context; var mac: THashDigest; BData: byte; bitlen: integer); {-end data input with bitlen bits (MSB format) from BData, calculate HMAC digest} var i: integer; bl: word; begin with ctx do if phashd<>nil then begin bl := phashd^.HBlockLen; {complete inner hash} phashd^.HFinalBit(hashctx, mac, BData, bitlen); {remove ipad from buf, XOR opad} for i:=0 to bl-1 do hmacbuf[i] := hmacbuf[i] xor ($36 xor $5c); {outer hash} phashd^.HInit(hashctx); phashd^.HUpdateXL(hashctx, @hmacbuf, bl); phashd^.HUpdateXL(hashctx, @mac, phashd^.HDigestLen); phashd^.HFinal(hashctx, mac); end; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/scrypt.pas0000664000175000017500000004210713146261166023161 0ustar alexxalexxunit scrypt; {scrypt key derivation functions} interface {$i std.inc} uses BTypes, memh, Hash, kdf; (************************************************************************* DESCRIPTION : scrypt key derivation functions REQUIREMENTS : TP5-7, D1-D7/D9-D10/D12/D17-D18, FPC, VP, WDOSX EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REMARKS : - assumes little-endian (checked for FPC) - very restricted for 16-bit because all buffer sizes must be < 64KB REFERENCES : - Colin Percival, Stronger Key Derivation via Sequential Memory-Hard Functions, http://www.tarsnap.com/scrypt/scrypt.pdf - Source code from http://www.tarsnap.com/scrypt/scrypt-1.1.6.tgz - Specification and test vectors from http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01 Version Date Author Modification ------- -------- ------- ------------------------------------------ 0.10 13.08.14 W.Ehrhardt Initial BP7, test case salsa20/8 using salsa unit 0.11 14.08.14 we Test case salsa20/8 without salsa unit 0.12 14.08.14 we blockmix_salsa8 0.13 14.08.14 we smix 0.14 14.08.14 we pbkfd2_hmac_sha256 0.15 14.08.14 we scrypt_kdf 0.16 15.08.14 we Support for other compilers 0.17 15.08.14 we Removed restriction on r*p (longint sLen, dkLen in pbkdf2) 0.18 15.08.14 we String versions scrypt_kdfs, scrypt_kdfss 0.19 15.08.14 we Allow pPW=nil or salt=nil 0.20 15.08.14 we Simply parameter checks, comments 0.21 16.08.14 we Separate unit 0.22 16.08.14 we More parameter checks 0.23 26.08.15 we Faster (reordered) salsa20/8 **************************************************************************) (*------------------------------------------------------------------------- (C) Copyright 2014-2015 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ----------------------------------------------------------------------------*) const sc_kdf_err_mem = -1; {Error from malloc} sc_kdf_err_inv_nrp = -2; {Invalid N,r,p. Note N must be a power of 2} sc_kdf_err_64KB = -3; {16-bit malloc with more than 64 KB} sc_kdf_err_big_endian = -4; {(FPC) compiling with big-endian} function scrypt_kdf(pPW: pointer; pLen: word; salt: pointer; sLen,N,r,p: longint; var DK; dkLen: longint): integer; {-Derive key DK from password pPW and salt using scrypt with parameters N,r,p} function scrypt_kdfs(sPW: Str255; salt: pointer; sLen,N,r,p: longint; var DK; dkLen: longint): integer; {-Derive key DK from password sPW and salt using scrypt with parameters N,r,p} function scrypt_kdfss(sPW, salt: Str255; N,r,p: longint; var DK; dkLen: longint): integer; {-Derive key DK from password sPW and salt using scrypt with parameters N,r,p} implementation uses SHA3_512; {Register SHA3_512 for HMAC_SHA3_512} type TLA16 = array[0..15] of longint; TBA64 = array[0..63] of byte; {---------------------------------------------------------------------------} procedure salsa20_8(var B: TLA16); {-Apply the salsa20/8 core to the provided block B} var i: integer; y: longint; x: TLA16; begin {This is the PurePascal version from my salsa20 unit} x := B; {$ifdef OldOrder} for i:=0 to 3 do begin y := x[ 0] + x[12]; x[ 4] := x[ 4] xor ((y shl 07) or (y shr (32-07))); y := x[ 4] + x[ 0]; x[ 8] := x[ 8] xor ((y shl 09) or (y shr (32-09))); y := x[ 8] + x[ 4]; x[12] := x[12] xor ((y shl 13) or (y shr (32-13))); y := x[12] + x[ 8]; x[ 0] := x[ 0] xor ((y shl 18) or (y shr (32-18))); y := x[ 5] + x[ 1]; x[ 9] := x[ 9] xor ((y shl 07) or (y shr (32-07))); y := x[ 9] + x[ 5]; x[13] := x[13] xor ((y shl 09) or (y shr (32-09))); y := x[13] + x[ 9]; x[ 1] := x[ 1] xor ((y shl 13) or (y shr (32-13))); y := x[ 1] + x[13]; x[ 5] := x[ 5] xor ((y shl 18) or (y shr (32-18))); y := x[10] + x[ 6]; x[14] := x[14] xor ((y shl 07) or (y shr (32-07))); y := x[14] + x[10]; x[ 2] := x[ 2] xor ((y shl 09) or (y shr (32-09))); y := x[ 2] + x[14]; x[ 6] := x[ 6] xor ((y shl 13) or (y shr (32-13))); y := x[ 6] + x[ 2]; x[10] := x[10] xor ((y shl 18) or (y shr (32-18))); y := x[15] + x[11]; x[ 3] := x[ 3] xor ((y shl 07) or (y shr (32-07))); y := x[ 3] + x[15]; x[ 7] := x[ 7] xor ((y shl 09) or (y shr (32-09))); y := x[ 7] + x[ 3]; x[11] := x[11] xor ((y shl 13) or (y shr (32-13))); y := x[11] + x[ 7]; x[15] := x[15] xor ((y shl 18) or (y shr (32-18))); y := x[ 0] + x[ 3]; x[ 1] := x[ 1] xor ((y shl 07) or (y shr (32-07))); y := x[ 1] + x[ 0]; x[ 2] := x[ 2] xor ((y shl 09) or (y shr (32-09))); y := x[ 2] + x[ 1]; x[ 3] := x[ 3] xor ((y shl 13) or (y shr (32-13))); y := x[ 3] + x[ 2]; x[ 0] := x[ 0] xor ((y shl 18) or (y shr (32-18))); y := x[ 5] + x[ 4]; x[ 6] := x[ 6] xor ((y shl 07) or (y shr (32-07))); y := x[ 6] + x[ 5]; x[ 7] := x[ 7] xor ((y shl 09) or (y shr (32-09))); y := x[ 7] + x[ 6]; x[ 4] := x[ 4] xor ((y shl 13) or (y shr (32-13))); y := x[ 4] + x[ 7]; x[ 5] := x[ 5] xor ((y shl 18) or (y shr (32-18))); y := x[10] + x[ 9]; x[11] := x[11] xor ((y shl 07) or (y shr (32-07))); y := x[11] + x[10]; x[ 8] := x[ 8] xor ((y shl 09) or (y shr (32-09))); y := x[ 8] + x[11]; x[ 9] := x[ 9] xor ((y shl 13) or (y shr (32-13))); y := x[ 9] + x[ 8]; x[10] := x[10] xor ((y shl 18) or (y shr (32-18))); y := x[15] + x[14]; x[12] := x[12] xor ((y shl 07) or (y shr (32-07))); y := x[12] + x[15]; x[13] := x[13] xor ((y shl 09) or (y shr (32-09))); y := x[13] + x[12]; x[14] := x[14] xor ((y shl 13) or (y shr (32-13))); y := x[14] + x[13]; x[15] := x[15] xor ((y shl 18) or (y shr (32-18))); end; {$else} for i:=0 to 3 do begin y := x[ 0] + x[12]; x[ 4] := x[ 4] xor ((y shl 07) or (y shr (32-07))); y := x[ 5] + x[ 1]; x[ 9] := x[ 9] xor ((y shl 07) or (y shr (32-07))); y := x[10] + x[ 6]; x[14] := x[14] xor ((y shl 07) or (y shr (32-07))); y := x[15] + x[11]; x[ 3] := x[ 3] xor ((y shl 07) or (y shr (32-07))); y := x[ 4] + x[ 0]; x[ 8] := x[ 8] xor ((y shl 09) or (y shr (32-09))); y := x[ 9] + x[ 5]; x[13] := x[13] xor ((y shl 09) or (y shr (32-09))); y := x[14] + x[10]; x[ 2] := x[ 2] xor ((y shl 09) or (y shr (32-09))); y := x[ 3] + x[15]; x[ 7] := x[ 7] xor ((y shl 09) or (y shr (32-09))); y := x[ 8] + x[ 4]; x[12] := x[12] xor ((y shl 13) or (y shr (32-13))); y := x[13] + x[ 9]; x[ 1] := x[ 1] xor ((y shl 13) or (y shr (32-13))); y := x[ 2] + x[14]; x[ 6] := x[ 6] xor ((y shl 13) or (y shr (32-13))); y := x[ 7] + x[ 3]; x[11] := x[11] xor ((y shl 13) or (y shr (32-13))); y := x[12] + x[ 8]; x[ 0] := x[ 0] xor ((y shl 18) or (y shr (32-18))); y := x[ 1] + x[13]; x[ 5] := x[ 5] xor ((y shl 18) or (y shr (32-18))); y := x[ 6] + x[ 2]; x[10] := x[10] xor ((y shl 18) or (y shr (32-18))); y := x[11] + x[ 7]; x[15] := x[15] xor ((y shl 18) or (y shr (32-18))); y := x[ 0] + x[ 3]; x[ 1] := x[ 1] xor ((y shl 07) or (y shr (32-07))); y := x[ 5] + x[ 4]; x[ 6] := x[ 6] xor ((y shl 07) or (y shr (32-07))); y := x[10] + x[ 9]; x[11] := x[11] xor ((y shl 07) or (y shr (32-07))); y := x[15] + x[14]; x[12] := x[12] xor ((y shl 07) or (y shr (32-07))); y := x[ 1] + x[ 0]; x[ 2] := x[ 2] xor ((y shl 09) or (y shr (32-09))); y := x[ 6] + x[ 5]; x[ 7] := x[ 7] xor ((y shl 09) or (y shr (32-09))); y := x[11] + x[10]; x[ 8] := x[ 8] xor ((y shl 09) or (y shr (32-09))); y := x[12] + x[15]; x[13] := x[13] xor ((y shl 09) or (y shr (32-09))); y := x[ 2] + x[ 1]; x[ 3] := x[ 3] xor ((y shl 13) or (y shr (32-13))); y := x[ 7] + x[ 6]; x[ 4] := x[ 4] xor ((y shl 13) or (y shr (32-13))); y := x[ 8] + x[11]; x[ 9] := x[ 9] xor ((y shl 13) or (y shr (32-13))); y := x[13] + x[12]; x[14] := x[14] xor ((y shl 13) or (y shr (32-13))); y := x[ 3] + x[ 2]; x[ 0] := x[ 0] xor ((y shl 18) or (y shr (32-18))); y := x[ 4] + x[ 7]; x[ 5] := x[ 5] xor ((y shl 18) or (y shr (32-18))); y := x[ 9] + x[ 8]; x[10] := x[10] xor ((y shl 18) or (y shr (32-18))); y := x[14] + x[13]; x[15] := x[15] xor ((y shl 18) or (y shr (32-18))); end; {$endif} for i:=0 to 15 do B[i] := x[i] + B[i] end; {---------------------------------------------------------------------------} procedure xorblock(dest, src: pByte; len: longint); {-xor block dest := dest xor src} begin while len > 0 do begin dest^ := dest^ xor src^; inc(Ptr2Inc(dest)); inc(Ptr2Inc(src)); dec(len); end; end; {---------------------------------------------------------------------------} function scrypt_kdfs(sPW: Str255; salt: pointer; sLen,N,r,p: longint; var DK; dkLen: longint): integer; {-Derive key DK from password sPW and salt using scrypt with parameters N,r,p} begin scrypt_kdfs := scrypt_kdf(@sPW[1], length(sPw), salt,sLen,N,r,p,DK,dkLen); end; {---------------------------------------------------------------------------} function scrypt_kdfss(sPW, salt: Str255; N,r,p: longint; var DK; dkLen: longint): integer; {-Derive key DK from password sPW and salt using scrypt with parameters N,r,p} begin scrypt_kdfss := scrypt_kdf(@sPW[1],length(sPw),@salt[1],length(salt),N,r,p,DK,dkLen); end; {The following scrypt Pascal functions are based on Colin Percival's C} {function crypto_scrypt-ref.c distributed with the BSD-style license: } (*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. *) {---------------------------------------------------------------------------} procedure blockmix_salsa8(B, Y: pByte; r: longint); {-Compute B = BlockMix_(salsa20/8, r)(B). The input B must be 128*r} { bytes in length; the temporary space Y must also be the same size.} var i: longint; pb,py: pByte; X: TBA64; begin (* Parameters: r Block size parameter. B[0], ..., B[2*r-1] input vector of 2*r 64-byte blocks B'[0], ..., B'[2*r-1] output vector of 2*r 64-byte blocks * Algorithm: 1. X = B[2*r-1] 2. for i = 0 to 2*r-1 do T = X xor B[i] X = Salsa(T) Y[i] = X end for 3. B' = (Y[0], Y[2], ..., Y[2 * r - 2], Y[1], Y[3], ..., Y[2 * r - 1]) *) {Step 1} pb := B; inc(Ptr2Inc(pb), (2*r-1)*64); move(pb^, X, 64); pb := B; py := Y; {Steps 2} for i:= 0 to 2*r - 1 do begin xorblock(pByte(@X), pByte(pb), 64); inc(Ptr2Inc(pb), 64); salsa20_8(TLA16(X)); move(X, py^, 64); inc(Ptr2Inc(py), 64); end; {Step 3} pb := B; py := Y; for i:=0 to r-1 do begin move(py^, pb^, 64); inc(Ptr2Inc(pb), 64); inc(Ptr2Inc(py), 128); end; py := Y; inc(Ptr2Inc(py), 64); for i:=0 to r-1 do begin move(py^, pb^, 64); inc(Ptr2Inc(pb), 64); inc(Ptr2Inc(py), 128); end; end; {---------------------------------------------------------------------------} procedure smix(B: pByte; r,N: longint; V, XY: pByte); {-Compute B = SMix_r(B, N). The input B must be 128*r bytes in length; } { the temporary storage V must be 128*r*N bytes in length; the temporary} { storage XY must be 256*r bytes in length. N must be a power of 2. } var i,j,r128: longint; px,py,pv,pj: pByte; begin (* Algorithm scryptROMix Input: r Block size parameter. B Input octet vector of length 128 * r octets. N CPU/Memory cost parameter, must be larger than 1, Output: B' Output octet vector of length 128 * r octets. *) {WE: Note that the reference performs the salsa steps as: Convert to LE,} {salsa compress, convert from LE. Skipped here assuming little-endian. } r128 := 128*r; pv := V; px := XY; py := XY; inc(Ptr2Inc(py), r128); move(B^,px^,r128); for i:=0 to N-1 do begin move(px^, pv^, r128); inc(Ptr2Inc(pv), r128); blockmix_salsa8(px, py, r); end; pj := XY; inc(Ptr2Inc(pj), (2*r - 1)*64); for i:=0 to N-1 do begin {The next line is the function Integerify(X) mod N, i.e. the remainder} {of dividing the multi-precision little-endian integer B[2*r-1] by N. } {Because we assume little-endian and N must be a power of two, this } {reduces to a simple AND operation!} j := pLongint(pj)^ and (N-1); {X = blockmix(V[j] xor X)} pv := V; inc(Ptr2Inc(pv), j*r128); xorblock(px, pv, r128); blockmix_salsa8(px, py, r); end; move(px^, B^, r128); end; {---------------------------------------------------------------------------} function pbkdf2_hmac_sha3_512(pPW: pointer; pLen: word; salt: pointer; sLen,C: longint; var DK; dkLen: longint): integer; {-Derive key DK from password pPW using salt and iteration count C using hmac_sha3_512} var phash: PHashDesc; begin {Note: pbkdf2 will return error indicator phash=nil if _SHA3_512 is not found!} phash := FindHash_by_ID(_SHA3_512); pbkdf2_hmac_sha3_512 := pbkdf2(phash,pPW,pLen,salt,sLen,C,DK,dkLen); end; {---------------------------------------------------------------------------} function scrypt_kdf(pPW: pointer; pLen: word; salt: pointer; sLen,N,r,p: longint; var DK; dkLen: longint): integer; {-Derive key DK from password pPW and salt using scrypt with parameters N,r,p} var pB,pV,pXY,pw: pByte; sB,sV,sXY,i: longint; err: integer; begin {$ifdef ENDIAN_BIG} scrypt_kdf := sc_kdf_err_big_endian; exit; {$endif} {Check parameter values and if N is a power of two} i := MaxLongint div 128; if (r<1) or (r > i div 2) or (p<1) or (p > i div r) or (N<2) or (N and (N-1) <> 0) or (N > i div r) then begin scrypt_kdf := sc_kdf_err_inv_nrp; exit; end; {Compute and store sizes, needed for releasing memory} {sB = 128*r*p, sXY = 256*r, sV = 128*r*N} i := 128*r; {128 <= i < $40000000} sB := p*i; sXY := 2*i; sV := N*i; {Simple sanity checks for possible remaining overflows} if (sV$FF00) or (sLen>$FF00) or (sB>$FF00) or (sXY>$FF00) or (sV>$FF00) then begin scrypt_kdf := sc_kdf_err_64KB; exit; end; {$endif} pB := malloc(sB); pV := malloc(sV); pXY := malloc(sXY); if (pB<>nil) and (pV<>nil) and (pXY<>nil) then begin err := pbkdf2_hmac_sha3_512(pPW, pLen, salt, sLen, 1, pB^, sB); if err=0 then begin pw := pB; for i:=0 to p-1 do begin smix(pw, r, N, pV, pXY); inc(Ptr2Inc(pw), r*128); end; err := pbkdf2_hmac_sha3_512(pPW, pLen, pB, sB, 1, DK, dKlen); end; scrypt_kdf := err; end else scrypt_kdf := sc_kdf_err_mem; mfree(pB,sB); mfree(pV,sV); mfree(pXY,sXY); end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/kperm_32.inc0000664000175000017500000005236112726767147023265 0ustar alexxalexx{KeccakF[1600] state permutation for 32 bit compilers, RotL code inline} {Pascal translation from C code in Keccak-simple32BI.c by Ronny Van Keer} {---------------------------------------------------------------------------} const KeccakF1600RoundConstants_int2: array[0..2*24-1] of longint = (longint($00000001), longint($00000000), longint($00000000), longint($00000089), longint($00000000), longint($8000008b), longint($00000000), longint($80008080), longint($00000001), longint($0000008b), longint($00000001), longint($00008000), longint($00000001), longint($80008088), longint($00000001), longint($80000082), longint($00000000), longint($0000000b), longint($00000000), longint($0000000a), longint($00000001), longint($00008082), longint($00000000), longint($00008003), longint($00000001), longint($0000808b), longint($00000001), longint($8000000b), longint($00000001), longint($8000008a), longint($00000001), longint($80000081), longint($00000000), longint($80000081), longint($00000000), longint($80000008), longint($00000000), longint($00000083), longint($00000000), longint($80008003), longint($00000001), longint($80008088), longint($00000000), longint($80000088), longint($00000001), longint($00008000), longint($00000000), longint($80008082)); {---------------------------------------------------------------------------} procedure KeccakPermutation(var state: TState_L); var Aba0, Abe0, Abi0, Abo0, Abu0: longint; Aba1, Abe1, Abi1, Abo1, Abu1: longint; Aga0, Age0, Agi0, Ago0, Agu0: longint; Aga1, Age1, Agi1, Ago1, Agu1: longint; Aka0, Ake0, Aki0, Ako0, Aku0: longint; Aka1, Ake1, Aki1, Ako1, Aku1: longint; Ama0, Ame0, Ami0, Amo0, Amu0: longint; Ama1, Ame1, Ami1, Amo1, Amu1: longint; Asa0, Ase0, Asi0, Aso0, Asu0: longint; Asa1, Ase1, Asi1, Aso1, Asu1: longint; BCa0, BCe0, BCi0, BCo0, BCu0: longint; BCa1, BCe1, BCi1, BCo1, BCu1: longint; Da0, De0, Di0, Do0, Du0: longint; Da1, De1, Di1, Do1, Du1: longint; Eba0, Ebe0, Ebi0, Ebo0, Ebu0: longint; Eba1, Ebe1, Ebi1, Ebo1, Ebu1: longint; Ega0, Ege0, Egi0, Ego0, Egu0: longint; Ega1, Ege1, Egi1, Ego1, Egu1: longint; Eka0, Eke0, Eki0, Eko0, Eku0: longint; Eka1, Eke1, Eki1, Eko1, Eku1: longint; Ema0, Eme0, Emi0, Emo0, Emu0: longint; Ema1, Eme1, Emi1, Emo1, Emu1: longint; Esa0, Ese0, Esi0, Eso0, Esu0: longint; Esa1, Ese1, Esi1, Eso1, Esu1: longint; var round: integer; begin {copyFromState(A, state)} Aba0 := state[ 0]; Aba1 := state[ 1]; Abe0 := state[ 2]; Abe1 := state[ 3]; Abi0 := state[ 4]; Abi1 := state[ 5]; Abo0 := state[ 6]; Abo1 := state[ 7]; Abu0 := state[ 8]; Abu1 := state[ 9]; Aga0 := state[10]; Aga1 := state[11]; Age0 := state[12]; Age1 := state[13]; Agi0 := state[14]; Agi1 := state[15]; Ago0 := state[16]; Ago1 := state[17]; Agu0 := state[18]; Agu1 := state[19]; Aka0 := state[20]; Aka1 := state[21]; Ake0 := state[22]; Ake1 := state[23]; Aki0 := state[24]; Aki1 := state[25]; Ako0 := state[26]; Ako1 := state[27]; Aku0 := state[28]; Aku1 := state[29]; Ama0 := state[30]; Ama1 := state[31]; Ame0 := state[32]; Ame1 := state[33]; Ami0 := state[34]; Ami1 := state[35]; Amo0 := state[36]; Amo1 := state[37]; Amu0 := state[38]; Amu1 := state[39]; Asa0 := state[40]; Asa1 := state[41]; Ase0 := state[42]; Ase1 := state[43]; Asi0 := state[44]; Asi1 := state[45]; Aso0 := state[46]; Aso1 := state[47]; Asu0 := state[48]; Asu1 := state[49]; round := 0; while round < cKeccakNumberOfRounds do begin {prepareTheta} BCa0 := Aba0 xor Aga0 xor Aka0 xor Ama0 xor Asa0; BCa1 := Aba1 xor Aga1 xor Aka1 xor Ama1 xor Asa1; BCe0 := Abe0 xor Age0 xor Ake0 xor Ame0 xor Ase0; BCe1 := Abe1 xor Age1 xor Ake1 xor Ame1 xor Ase1; BCi0 := Abi0 xor Agi0 xor Aki0 xor Ami0 xor Asi0; BCi1 := Abi1 xor Agi1 xor Aki1 xor Ami1 xor Asi1; BCo0 := Abo0 xor Ago0 xor Ako0 xor Amo0 xor Aso0; BCo1 := Abo1 xor Ago1 xor Ako1 xor Amo1 xor Aso1; BCu0 := Abu0 xor Agu0 xor Aku0 xor Amu0 xor Asu0; BCu1 := Abu1 xor Agu1 xor Aku1 xor Amu1 xor Asu1; {thetaRhoPiChiIota(round, A, E)} Da0 := BCu0 xor (BCe1 shl 1) xor (BCe1 shr (32-1)); Da1 := BCu1 xor BCe0; De0 := BCa0 xor (BCi1 shl 1) xor (BCi1 shr (32-1)); De1 := BCa1 xor BCi0; Di0 := BCe0 xor (BCo1 shl 1) xor (BCo1 shr (32-1)); Di1 := BCe1 xor BCo0; Do0 := BCi0 xor (BCu1 shl 1) xor (BCu1 shr (32-1)); Do1 := BCi1 xor BCu0; Du0 := BCo0 xor (BCa1 shl 1) xor (BCa1 shr (32-1)); Du1 := BCo1 xor BCa0; Aba0 := Aba0 xor Da0; BCa0 := Aba0; Age0 := Age0 xor De0; BCe0 := (Age0 shl 22) xor (Age0 shr (32-22)); Aki1 := Aki1 xor Di1; BCi0 := (Aki1 shl 22) xor (Aki1 shr (32-22)); Amo1 := Amo1 xor Do1; BCo0 := (Amo1 shl 11) xor (Amo1 shr (32-11)); Asu0 := Asu0 xor Du0; BCu0 := (Asu0 shl 7) xor (Asu0 shr (32-7)); Eba0 := BCa0 xor ((not BCe0) and BCi0) xor KeccakF1600RoundConstants_int2[round*2+0]; Ebe0 := BCe0 xor ((not BCi0) and BCo0); Ebi0 := BCi0 xor ((not BCo0) and BCu0); Ebo0 := BCo0 xor ((not BCu0) and BCa0); Ebu0 := BCu0 xor ((not BCa0) and BCe0); Aba1 := Aba1 xor Da1; BCa1 := Aba1; Age1 := Age1 xor De1; BCe1 := (Age1 shl 22) xor (Age1 shr (32-22)); Aki0 := Aki0 xor Di0; BCi1 := (Aki0 shl 21) xor (Aki0 shr (32-21)); Amo0 := Amo0 xor Do0; BCo1 := (Amo0 shl 10) xor (Amo0 shr (32-10)); Asu1 := Asu1 xor Du1; BCu1 := (Asu1 shl 7) xor (Asu1 shr (32-7)); Eba1 := BCa1 xor ((not BCe1) and BCi1) xor KeccakF1600RoundConstants_int2[round*2+1]; Ebe1 := BCe1 xor ((not BCi1) and BCo1); Ebi1 := BCi1 xor ((not BCo1) and BCu1); Ebo1 := BCo1 xor ((not BCu1) and BCa1); Ebu1 := BCu1 xor ((not BCa1) and BCe1); Abo0 := Abo0 xor Do0; BCa0 := (Abo0 shl 14) xor (Abo0 shr (32-14)); Agu0 := Agu0 xor Du0; BCe0 := (Agu0 shl 10) xor (Agu0 shr (32-10)); Aka1 := Aka1 xor Da1; BCi0 := (Aka1 shl 2) xor (Aka1 shr (32-2)); Ame1 := Ame1 xor De1; BCo0 := (Ame1 shl 23) xor (Ame1 shr (32-23)); Asi1 := Asi1 xor Di1; BCu0 := (Asi1 shl 31) xor (Asi1 shr (32-31)); Ega0 := BCa0 xor ((not BCe0) and BCi0); Ege0 := BCe0 xor ((not BCi0) and BCo0); Egi0 := BCi0 xor ((not BCo0) and BCu0); Ego0 := BCo0 xor ((not BCu0) and BCa0); Egu0 := BCu0 xor ((not BCa0) and BCe0); Abo1 := Abo1 xor Do1; BCa1 := (Abo1 shl 14) xor (Abo1 shr (32-14)); Agu1 := Agu1 xor Du1; BCe1 := (Agu1 shl 10) xor (Agu1 shr (32-10)); Aka0 := Aka0 xor Da0; BCi1 := (Aka0 shl 1) xor (Aka0 shr (32-1)); Ame0 := Ame0 xor De0; BCo1 := (Ame0 shl 22) xor (Ame0 shr (32-22)); Asi0 := Asi0 xor Di0; BCu1 := (Asi0 shl 30) xor (Asi0 shr (32-30)); Ega1 := BCa1 xor ((not BCe1) and BCi1); Ege1 := BCe1 xor ((not BCi1) and BCo1); Egi1 := BCi1 xor ((not BCo1) and BCu1); Ego1 := BCo1 xor ((not BCu1) and BCa1); Egu1 := BCu1 xor ((not BCa1) and BCe1); Abe1 := Abe1 xor De1; BCa0 := (Abe1 shl 1) xor (Abe1 shr (32-1)); Agi0 := Agi0 xor Di0; BCe0 := (Agi0 shl 3) xor (Agi0 shr (32-3)); Ako1 := Ako1 xor Do1; BCi0 := (Ako1 shl 13) xor (Ako1 shr (32-13)); Amu0 := Amu0 xor Du0; BCo0 := (Amu0 shl 4) xor (Amu0 shr (32-4)); Asa0 := Asa0 xor Da0; BCu0 := (Asa0 shl 9) xor (Asa0 shr (32-9)); Eka0 := BCa0 xor ((not BCe0) and BCi0 ); Eke0 := BCe0 xor ((not BCi0) and BCo0 ); Eki0 := BCi0 xor ((not BCo0) and BCu0 ); Eko0 := BCo0 xor ((not BCu0) and BCa0 ); Eku0 := BCu0 xor ((not BCa0) and BCe0 ); Abe0 := Abe0 xor De0; BCa1 := Abe0; Agi1 := Agi1 xor Di1; BCe1 := (Agi1 shl 3) xor (Agi1 shr (32-3)); Ako0 := Ako0 xor Do0; BCi1 := (Ako0 shl 12) xor (Ako0 shr (32-12)); Amu1 := Amu1 xor Du1; BCo1 := (Amu1 shl 4) xor (Amu1 shr (32-4)); Asa1 := Asa1 xor Da1; BCu1 := (Asa1 shl 9) xor (Asa1 shr (32-9)); Eka1 := BCa1 xor ((not BCe1) and BCi1); Eke1 := BCe1 xor ((not BCi1) and BCo1); Eki1 := BCi1 xor ((not BCo1) and BCu1); Eko1 := BCo1 xor ((not BCu1) and BCa1); Eku1 := BCu1 xor ((not BCa1) and BCe1); Abu1 := Abu1 xor Du1; BCa0 := (Abu1 shl 14) xor (Abu1 shr (32-14)); Aga0 := Aga0 xor Da0; BCe0 := (Aga0 shl 18) xor (Aga0 shr (32-18)); Ake0 := Ake0 xor De0; BCi0 := (Ake0 shl 5) xor (Ake0 shr (32-5)); Ami1 := Ami1 xor Di1; BCo0 := (Ami1 shl 8) xor (Ami1 shr (32-8)); Aso0 := Aso0 xor Do0; BCu0 := (Aso0 shl 28) xor (Aso0 shr (32-28)); Ema0 := BCa0 xor ((not BCe0) and BCi0); Eme0 := BCe0 xor ((not BCi0) and BCo0); Emi0 := BCi0 xor ((not BCo0) and BCu0); Emo0 := BCo0 xor ((not BCu0) and BCa0); Emu0 := BCu0 xor ((not BCa0) and BCe0); Abu0 := Abu0 xor Du0; BCa1 := (Abu0 shl 13) xor (Abu0 shr (32-13)); Aga1 := Aga1 xor Da1; BCe1 := (Aga1 shl 18) xor (Aga1 shr (32-18)); Ake1 := Ake1 xor De1; BCi1 := (Ake1 shl 5) xor (Ake1 shr (32-5)); Ami0 := Ami0 xor Di0; BCo1 := (Ami0 shl 7) xor (Ami0 shr (32-7)); Aso1 := Aso1 xor Do1; BCu1 := (Aso1 shl 28) xor (Aso1 shr (32-28)); Ema1 := BCa1 xor ((not BCe1) and BCi1); Eme1 := BCe1 xor ((not BCi1) and BCo1); Emi1 := BCi1 xor ((not BCo1) and BCu1); Emo1 := BCo1 xor ((not BCu1) and BCa1); Emu1 := BCu1 xor ((not BCa1) and BCe1); Abi0 := Abi0 xor Di0; BCa0 := (Abi0 shl 31) xor (Abi0 shr (32-31)); Ago1 := Ago1 xor Do1; BCe0 := (Ago1 shl 28) xor (Ago1 shr (32-28)); Aku1 := Aku1 xor Du1; BCi0 := (Aku1 shl 20) xor (Aku1 shr (32-20)); Ama1 := Ama1 xor Da1; BCo0 := (Ama1 shl 21) xor (Ama1 shr (32-21)); Ase0 := Ase0 xor De0; BCu0 := (Ase0 shl 1) xor (Ase0 shr (32-1)); Esa0 := BCa0 xor ((not BCe0) and BCi0); Ese0 := BCe0 xor ((not BCi0) and BCo0); Esi0 := BCi0 xor ((not BCo0) and BCu0); Eso0 := BCo0 xor ((not BCu0) and BCa0); Esu0 := BCu0 xor ((not BCa0) and BCe0); Abi1 := Abi1 xor Di1; BCa1 := (Abi1 shl 31) xor (Abi1 shr (32-31)); Ago0 := Ago0 xor Do0; BCe1 := (Ago0 shl 27) xor (Ago0 shr (32-27)); Aku0 := Aku0 xor Du0; BCi1 := (Aku0 shl 19) xor (Aku0 shr (32-19)); Ama0 := Ama0 xor Da0; BCo1 := (Ama0 shl 20) xor (Ama0 shr (32-20)); Ase1 := Ase1 xor De1; BCu1 := (Ase1 shl 1) xor (Ase1 shr (32-1)); Esa1 := BCa1 xor ((not BCe1) and BCi1); Ese1 := BCe1 xor ((not BCi1) and BCo1); Esi1 := BCi1 xor ((not BCo1) and BCu1); Eso1 := BCo1 xor ((not BCu1) and BCa1); Esu1 := BCu1 xor ((not BCa1) and BCe1); {prepareTheta} BCa0 := Eba0 xor Ega0 xor Eka0 xor Ema0 xor Esa0; BCa1 := Eba1 xor Ega1 xor Eka1 xor Ema1 xor Esa1; BCe0 := Ebe0 xor Ege0 xor Eke0 xor Eme0 xor Ese0; BCe1 := Ebe1 xor Ege1 xor Eke1 xor Eme1 xor Ese1; BCi0 := Ebi0 xor Egi0 xor Eki0 xor Emi0 xor Esi0; BCi1 := Ebi1 xor Egi1 xor Eki1 xor Emi1 xor Esi1; BCo0 := Ebo0 xor Ego0 xor Eko0 xor Emo0 xor Eso0; BCo1 := Ebo1 xor Ego1 xor Eko1 xor Emo1 xor Eso1; BCu0 := Ebu0 xor Egu0 xor Eku0 xor Emu0 xor Esu0; BCu1 := Ebu1 xor Egu1 xor Eku1 xor Emu1 xor Esu1; {thetaRhoPiChiIota(round+1, E, A)} Da0 := BCu0 xor (BCe1 shl 1) xor (BCe1 shr (32-1)); Da1 := BCu1 xor BCe0; De0 := BCa0 xor (BCi1 shl 1) xor (BCi1 shr (32-1)); De1 := BCa1 xor BCi0; Di0 := BCe0 xor (BCo1 shl 1) xor (BCo1 shr (32-1)); Di1 := BCe1 xor BCo0; Do0 := BCi0 xor (BCu1 shl 1) xor (BCu1 shr (32-1)); Do1 := BCi1 xor BCu0; Du0 := BCo0 xor (BCa1 shl 1) xor (BCa1 shr (32-1)); Du1 := BCo1 xor BCa0; Eba0 := Eba0 xor Da0; BCa0 := Eba0; Ege0 := Ege0 xor De0; BCe0 := (Ege0 shl 22) xor (Ege0 shr (32-22)); Eki1 := Eki1 xor Di1; BCi0 := (Eki1 shl 22) xor (Eki1 shr (32-22)); Emo1 := Emo1 xor Do1; BCo0 := (Emo1 shl 11) xor (Emo1 shr (32-11)); Esu0 := Esu0 xor Du0; BCu0 := (Esu0 shl 7) xor (Esu0 shr (32-7)); Aba0 := BCa0 xor ((not BCe0) and BCi0) xor KeccakF1600RoundConstants_int2[round*2+2]; Abe0 := BCe0 xor ((not BCi0) and BCo0); Abi0 := BCi0 xor ((not BCo0) and BCu0); Abo0 := BCo0 xor ((not BCu0) and BCa0); Abu0 := BCu0 xor ((not BCa0) and BCe0); Eba1 := Eba1 xor Da1; BCa1 := Eba1; Ege1 := Ege1 xor De1; BCe1 := (Ege1 shl 22) xor (Ege1 shr (32-22)); Eki0 := Eki0 xor Di0; BCi1 := (Eki0 shl 21) xor (Eki0 shr (32-21)); Emo0 := Emo0 xor Do0; BCo1 := (Emo0 shl 10) xor (Emo0 shr (32-10)); Esu1 := Esu1 xor Du1; BCu1 := (Esu1 shl 7) xor (Esu1 shr (32-7)); Aba1 := BCa1 xor ((not BCe1) and BCi1) xor KeccakF1600RoundConstants_int2[round*2+3]; Abe1 := BCe1 xor ((not BCi1) and BCo1); Abi1 := BCi1 xor ((not BCo1) and BCu1); Abo1 := BCo1 xor ((not BCu1) and BCa1); Abu1 := BCu1 xor ((not BCa1) and BCe1); Ebo0 := Ebo0 xor Do0; BCa0 := (Ebo0 shl 14) xor (Ebo0 shr (32-14)); Egu0 := Egu0 xor Du0; BCe0 := (Egu0 shl 10) xor (Egu0 shr (32-10)); Eka1 := Eka1 xor Da1; BCi0 := (Eka1 shl 2) xor (Eka1 shr (32-2)); Eme1 := Eme1 xor De1; BCo0 := (Eme1 shl 23) xor (Eme1 shr (32-23)); Esi1 := Esi1 xor Di1; BCu0 := (Esi1 shl 31) xor (Esi1 shr (32-31)); Aga0 := BCa0 xor ((not BCe0) and BCi0); Age0 := BCe0 xor ((not BCi0) and BCo0); Agi0 := BCi0 xor ((not BCo0) and BCu0); Ago0 := BCo0 xor ((not BCu0) and BCa0); Agu0 := BCu0 xor ((not BCa0) and BCe0); Ebo1 := Ebo1 xor Do1; BCa1 := (Ebo1 shl 14) xor (Ebo1 shr (32-14)); Egu1 := Egu1 xor Du1; BCe1 := (Egu1 shl 10) xor (Egu1 shr (32-10)); Eka0 := Eka0 xor Da0; BCi1 := (Eka0 shl 1) xor (Eka0 shr (32-1)); Eme0 := Eme0 xor De0; BCo1 := (Eme0 shl 22) xor (Eme0 shr (32-22)); Esi0 := Esi0 xor Di0; BCu1 := (Esi0 shl 30) xor (Esi0 shr (32-30)); Aga1 := BCa1 xor ((not BCe1) and BCi1); Age1 := BCe1 xor ((not BCi1) and BCo1); Agi1 := BCi1 xor ((not BCo1) and BCu1); Ago1 := BCo1 xor ((not BCu1) and BCa1); Agu1 := BCu1 xor ((not BCa1) and BCe1); Ebe1 := Ebe1 xor De1; BCa0 := (Ebe1 shl 1) xor (Ebe1 shr (32-1)); Egi0 := Egi0 xor Di0; BCe0 := (Egi0 shl 3) xor (Egi0 shr (32-3)); Eko1 := Eko1 xor Do1; BCi0 := (Eko1 shl 13) xor (Eko1 shr (32-13)); Emu0 := Emu0 xor Du0; BCo0 := (Emu0 shl 4) xor (Emu0 shr (32-4)); Esa0 := Esa0 xor Da0; BCu0 := (Esa0 shl 9) xor (Esa0 shr (32-9)); Aka0 := BCa0 xor ((not BCe0) and BCi0); Ake0 := BCe0 xor ((not BCi0) and BCo0); Aki0 := BCi0 xor ((not BCo0) and BCu0); Ako0 := BCo0 xor ((not BCu0) and BCa0); Aku0 := BCu0 xor ((not BCa0) and BCe0); Ebe0 := Ebe0 xor De0; BCa1 := Ebe0; Egi1 := Egi1 xor Di1; BCe1 := (Egi1 shl 3) xor (Egi1 shr (32-3)); Eko0 := Eko0 xor Do0; BCi1 := (Eko0 shl 12) xor (Eko0 shr (32-12)); Emu1 := Emu1 xor Du1; BCo1 := (Emu1 shl 4) xor (Emu1 shr (32-4)); Esa1 := Esa1 xor Da1; BCu1 := (Esa1 shl 9) xor (Esa1 shr (32-9)); Aka1 := BCa1 xor ((not BCe1) and BCi1); Ake1 := BCe1 xor ((not BCi1) and BCo1); Aki1 := BCi1 xor ((not BCo1) and BCu1); Ako1 := BCo1 xor ((not BCu1) and BCa1); Aku1 := BCu1 xor ((not BCa1) and BCe1); Ebu1 := Ebu1 xor Du1; BCa0 := (Ebu1 shl 14) xor (Ebu1 shr (32-14)); Ega0 := Ega0 xor Da0; BCe0 := (Ega0 shl 18) xor (Ega0 shr (32-18)); Eke0 := Eke0 xor De0; BCi0 := (Eke0 shl 5) xor (Eke0 shr (32-5)); Emi1 := Emi1 xor Di1; BCo0 := (Emi1 shl 8) xor (Emi1 shr (32-8)); Eso0 := Eso0 xor Do0; BCu0 := (Eso0 shl 28) xor (Eso0 shr (32-28)); Ama0 := BCa0 xor ((not BCe0) and BCi0); Ame0 := BCe0 xor ((not BCi0) and BCo0); Ami0 := BCi0 xor ((not BCo0) and BCu0); Amo0 := BCo0 xor ((not BCu0) and BCa0); Amu0 := BCu0 xor ((not BCa0) and BCe0); Ebu0 := Ebu0 xor Du0; BCa1 := (Ebu0 shl 13) xor (Ebu0 shr (32-13)); Ega1 := Ega1 xor Da1; BCe1 := (Ega1 shl 18) xor (Ega1 shr (32-18)); Eke1 := Eke1 xor De1; BCi1 := (Eke1 shl 5) xor (Eke1 shr (32-5)); Emi0 := Emi0 xor Di0; BCo1 := (Emi0 shl 7) xor (Emi0 shr (32-7)); Eso1 := Eso1 xor Do1; BCu1 := (Eso1 shl 28) xor (Eso1 shr (32-28)); Ama1 := BCa1 xor ((not BCe1) and BCi1); Ame1 := BCe1 xor ((not BCi1) and BCo1); Ami1 := BCi1 xor ((not BCo1) and BCu1); Amo1 := BCo1 xor ((not BCu1) and BCa1); Amu1 := BCu1 xor ((not BCa1) and BCe1); Ebi0 := Ebi0 xor Di0; BCa0 := (Ebi0 shl 31) xor (Ebi0 shr (32-31)); Ego1 := Ego1 xor Do1; BCe0 := (Ego1 shl 28) xor (Ego1 shr (32-28)); Eku1 := Eku1 xor Du1; BCi0 := (Eku1 shl 20) xor (Eku1 shr (32-20)); Ema1 := Ema1 xor Da1; BCo0 := (Ema1 shl 21) xor (Ema1 shr (32-21)); Ese0 := Ese0 xor De0; BCu0 := (Ese0 shl 1) xor (Ese0 shr (32-1)); Asa0 := BCa0 xor ((not BCe0) and BCi0); Ase0 := BCe0 xor ((not BCi0) and BCo0); Asi0 := BCi0 xor ((not BCo0) and BCu0); Aso0 := BCo0 xor ((not BCu0) and BCa0); Asu0 := BCu0 xor ((not BCa0) and BCe0); Ebi1 := Ebi1 xor Di1; BCa1 := (Ebi1 shl 31) xor (Ebi1 shr (32-31)); Ego0 := Ego0 xor Do0; BCe1 := (Ego0 shl 27) xor (Ego0 shr (32-27)); Eku0 := Eku0 xor Du0; BCi1 := (Eku0 shl 19) xor (Eku0 shr (32-19)); Ema0 := Ema0 xor Da0; BCo1 := (Ema0 shl 20) xor (Ema0 shr (32-20)); Ese1 := Ese1 xor De1; BCu1 := (Ese1 shl 1) xor (Ese1 shr (32-1)); Asa1 := BCa1 xor ((not BCe1) and BCi1); Ase1 := BCe1 xor ((not BCi1) and BCo1); Asi1 := BCi1 xor ((not BCo1) and BCu1); Aso1 := BCo1 xor ((not BCu1) and BCa1); Asu1 := BCu1 xor ((not BCa1) and BCe1); inc(round,2); end; {copyToState(state, A)} state[ 0] := Aba0; state[ 1] := Aba1; state[ 2] := Abe0; state[ 3] := Abe1; state[ 4] := Abi0; state[ 5] := Abi1; state[ 6] := Abo0; state[ 7] := Abo1; state[ 8] := Abu0; state[ 9] := Abu1; state[10] := Aga0; state[11] := Aga1; state[12] := Age0; state[13] := Age1; state[14] := Agi0; state[15] := Agi1; state[16] := Ago0; state[17] := Ago1; state[18] := Agu0; state[19] := Agu1; state[20] := Aka0; state[21] := Aka1; state[22] := Ake0; state[23] := Ake1; state[24] := Aki0; state[25] := Aki1; state[26] := Ako0; state[27] := Ako1; state[28] := Aku0; state[29] := Aku1; state[30] := Ama0; state[31] := Ama1; state[32] := Ame0; state[33] := Ame1; state[34] := Ami0; state[35] := Ami1; state[36] := Amo0; state[37] := Amo1; state[38] := Amu0; state[39] := Amu1; state[40] := Asa0; state[41] := Asa1; state[42] := Ase0; state[43] := Ase1; state[44] := Asi0; state[45] := Asi1; state[46] := Aso0; state[47] := Aso1; state[48] := Asu0; state[49] := Asu1; end; {---------------------------------------------------------------------------} procedure extractFromState(outp: pointer; const state: TState_L; laneCount: integer); var pI, pS: PLongint; i: integer; t,x0,x1: longint; const xFFFF0000 = longint($FFFF0000); {Keep D9+ happy} begin {Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002} pI := outp; pS := @state[0]; for i:=laneCount-1 downto 0 do begin x0 := pS^; inc(Ptr2Inc(pS),sizeof(pS^)); x1 := pS^; inc(Ptr2Inc(pS),sizeof(pS^)); t := (x0 and $0000FFFF) or (x1 shl 16); x1 := (x0 shr 16) or (x1 and xFFFF0000); x0 := t; t := (x0 xor (x0 shr 8)) and $0000FF00; x0 := x0 xor t xor (t shl 8); t := (x0 xor (x0 shr 4)) and $00F000F0; x0 := x0 xor t xor (t shl 4); t := (x0 xor (x0 shr 2)) and $0C0C0C0C; x0 := x0 xor t xor (t shl 2); t := (x0 xor (x0 shr 1)) and $22222222; x0 := x0 xor t xor (t shl 1); t := (x1 xor (x1 shr 8)) and $0000FF00; x1 := x1 xor t xor (t shl 8); t := (x1 xor (x1 shr 4)) and $00F000F0; x1 := x1 xor t xor (t shl 4); t := (x1 xor (x1 shr 2)) and $0C0C0C0C; x1 := x1 xor t xor (t shl 2); t := (x1 xor (x1 shr 1)) and $22222222; x1 := x1 xor t xor (t shl 1); pI^:= x0; inc(Ptr2Inc(pI),sizeof(pI^)); pI^:= x1; inc(Ptr2Inc(pI),sizeof(pI^)); end; end; {---------------------------------------------------------------------------} procedure xorIntoState(var state: TState_L; inp: pointer; laneCount: integer); {-Include input message data bits into the sponge state} var t,x0,x1: longint; pI,pS: PLongint; i: integer; const xFFFF0000 = longint($FFFF0000); {Keep D9+ happy} begin {Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002} pI := inp; pS := @state[0]; for i:=laneCount-1 downto 0 do begin x0 := pI^; inc(Ptr2Inc(pI),sizeof(pI^)); t := (x0 xor (x0 shr 1)) and $22222222; x0 := x0 xor t xor (t shl 1); t := (x0 xor (x0 shr 2)) and $0C0C0C0C; x0 := x0 xor t xor (t shl 2); t := (x0 xor (x0 shr 4)) and $00F000F0; x0 := x0 xor t xor (t shl 4); t := (x0 xor (x0 shr 8)) and $0000FF00; x0 := x0 xor t xor (t shl 8); x1 := pI^; inc(Ptr2Inc(pI),sizeof(pI^)); t := (x1 xor (x1 shr 1)) and $22222222; x1 := x1 xor t xor (t shl 1); t := (x1 xor (x1 shr 2)) and $0C0C0C0C; x1 := x1 xor t xor (t shl 2); t := (x1 xor (x1 shr 4)) and $00F000F0; x1 := x1 xor t xor (t shl 4); t := (x1 xor (x1 shr 8)) and $0000FF00; x1 := x1 xor t xor (t shl 8); pS^ := pS^ xor ((x0 and $0000FFFF) or (x1 shl 16)); inc(Ptr2Inc(pS),sizeof(pS^)); pS^ := pS^ xor ((x0 shr 16) or (x1 and xFFFF0000)); inc(Ptr2Inc(pS),sizeof(pS^)); end; end; doublecmd-0.8.2/components/dcpcrypt/Hashes/Keccak/README.txt0000664000175000017500000000024312726776751022637 0ustar alexxalexxCRC / HASH / HMAC http://www.wolfgang-ehrhardt.de/crchash_en.html crc_hash_2016-05-01.zip Some modifications done for Double Commander (see doublecmd.diff). doublecmd-0.8.2/components/dcpcrypt/Hashes/dcptiger.pas0000664000175000017500000003055012014201074022235 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of Tiger ********************************} {******************************************************************************} {* Copyright (c) 2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPtiger; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2, DCPconst; type TDCP_tiger= class(TDCP_hash) protected Len: int64; Index: DWord; CurrentHash: array[0..2] of int64; HashBuffer: array[0..63] of byte; procedure Compress; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; procedure Final(var Digest); override; end; {******************************************************************************} {******************************************************************************} implementation {$R-}{$Q-} {$INCLUDE DCPtiger.inc} procedure TDCP_tiger.Compress; var a, b, c, aa, bb, cc: int64; x: array[0..7] of int64; begin dcpFillChar(x, SizeOf(x), 0); a:= CurrentHash[0]; aa:= a; b:= CurrentHash[1]; bb:= b; c:= CurrentHash[2]; cc:= c; Move(HashBuffer,x,Sizeof(x)); c:= c xor x[0]; a:= a - (t1[c and $FF] xor t2[(c shr 16) and $FF] xor t3[(c shr 32) and $FF] xor t4[(c shr 48) and $FF]); b:= b + (t4[(c shr 8) and $FF] xor t3[(c shr 24) and $FF] xor t2[(c shr 40) and $FF] xor t1[(c shr 56) and $FF]); b:= b * 5; a:= a xor x[1]; b:= b - (t1[a and $FF] xor t2[(a shr 16) and $FF] xor t3[(a shr 32) and $FF] xor t4[(a shr 48) and $FF]); c:= c + (t4[(a shr 8) and $FF] xor t3[(a shr 24) and $FF] xor t2[(a shr 40) and $FF] xor t1[(a shr 56) and $FF]); c:= c * 5; b:= b xor x[2]; c:= c - (t1[b and $FF] xor t2[(b shr 16) and $FF] xor t3[(b shr 32) and $FF] xor t4[(b shr 48) and $FF]); a:= a + (t4[(b shr 8) and $FF] xor t3[(b shr 24) and $FF] xor t2[(b shr 40) and $FF] xor t1[(b shr 56) and $FF]); a:= a * 5; c:= c xor x[3]; a:= a - (t1[c and $FF] xor t2[(c shr 16) and $FF] xor t3[(c shr 32) and $FF] xor t4[(c shr 48) and $FF]); b:= b + (t4[(c shr 8) and $FF] xor t3[(c shr 24) and $FF] xor t2[(c shr 40) and $FF] xor t1[(c shr 56) and $FF]); b:= b * 5; a:= a xor x[4]; b:= b - (t1[a and $FF] xor t2[(a shr 16) and $FF] xor t3[(a shr 32) and $FF] xor t4[(a shr 48) and $FF]); c:= c + (t4[(a shr 8) and $FF] xor t3[(a shr 24) and $FF] xor t2[(a shr 40) and $FF] xor t1[(a shr 56) and $FF]); c:= c * 5; b:= b xor x[5]; c:= c - (t1[b and $FF] xor t2[(b shr 16) and $FF] xor t3[(b shr 32) and $FF] xor t4[(b shr 48) and $FF]); a:= a + (t4[(b shr 8) and $FF] xor t3[(b shr 24) and $FF] xor t2[(b shr 40) and $FF] xor t1[(b shr 56) and $FF]); a:= a * 5; c:= c xor x[6]; a:= a - (t1[c and $FF] xor t2[(c shr 16) and $FF] xor t3[(c shr 32) and $FF] xor t4[(c shr 48) and $FF]); b:= b + (t4[(c shr 8) and $FF] xor t3[(c shr 24) and $FF] xor t2[(c shr 40) and $FF] xor t1[(c shr 56) and $FF]); b:= b * 5; a:= a xor x[7]; b:= b - (t1[a and $FF] xor t2[(a shr 16) and $FF] xor t3[(a shr 32) and $FF] xor t4[(a shr 48) and $FF]); c:= c + (t4[(a shr 8) and $FF] xor t3[(a shr 24) and $FF] xor t2[(a shr 40) and $FF] xor t1[(a shr 56) and $FF]); c:= c * 5; x[0]:= x[0] - (x[7] xor $A5A5A5A5A5A5A5A5); x[1]:= x[1] xor x[0]; x[2]:= x[2] + x[1]; x[3]:= x[3] - (x[2] xor ((not x[1]) shl 19)); x[4]:= x[4] xor x[3]; x[5]:= x[5] + x[4]; x[6]:= x[6] - (x[5] xor ((not x[4]) shr 23)); x[7]:= x[7] xor x[6]; x[0]:= x[0] + x[7]; x[1]:= x[1] - (x[0] xor ((not x[7]) shl 19)); x[2]:= x[2] xor x[1]; x[3]:= x[3] + x[2]; x[4]:= x[4] - (x[3] xor ((not x[2]) shr 23)); x[5]:= x[5] xor x[4]; x[6]:= x[6] + x[5]; x[7]:= x[7] - (x[6] xor $0123456789ABCDEF); b:= b xor x[0]; c:= c - (t1[b and $FF] xor t2[(b shr 16) and $FF] xor t3[(b shr 32) and $FF] xor t4[(b shr 48) and $FF]); a:= a + (t4[(b shr 8) and $FF] xor t3[(b shr 24) and $FF] xor t2[(b shr 40) and $FF] xor t1[(b shr 56) and $FF]); a:= a * 7; c:= c xor x[1]; a:= a - (t1[c and $FF] xor t2[(c shr 16) and $FF] xor t3[(c shr 32) and $FF] xor t4[(c shr 48) and $FF]); b:= b + (t4[(c shr 8) and $FF] xor t3[(c shr 24) and $FF] xor t2[(c shr 40) and $FF] xor t1[(c shr 56) and $FF]); b:= b * 7; a:= a xor x[2]; b:= b - (t1[a and $FF] xor t2[(a shr 16) and $FF] xor t3[(a shr 32) and $FF] xor t4[(a shr 48) and $FF]); c:= c + (t4[(a shr 8) and $FF] xor t3[(a shr 24) and $FF] xor t2[(a shr 40) and $FF] xor t1[(a shr 56) and $FF]); c:= c * 7; b:= b xor x[3]; c:= c - (t1[b and $FF] xor t2[(b shr 16) and $FF] xor t3[(b shr 32) and $FF] xor t4[(b shr 48) and $FF]); a:= a + (t4[(b shr 8) and $FF] xor t3[(b shr 24) and $FF] xor t2[(b shr 40) and $FF] xor t1[(b shr 56) and $FF]); a:= a * 7; c:= c xor x[4]; a:= a - (t1[c and $FF] xor t2[(c shr 16) and $FF] xor t3[(c shr 32) and $FF] xor t4[(c shr 48) and $FF]); b:= b + (t4[(c shr 8) and $FF] xor t3[(c shr 24) and $FF] xor t2[(c shr 40) and $FF] xor t1[(c shr 56) and $FF]); b:= b * 7; a:= a xor x[5]; b:= b - (t1[a and $FF] xor t2[(a shr 16) and $FF] xor t3[(a shr 32) and $FF] xor t4[(a shr 48) and $FF]); c:= c + (t4[(a shr 8) and $FF] xor t3[(a shr 24) and $FF] xor t2[(a shr 40) and $FF] xor t1[(a shr 56) and $FF]); c:= c * 7; b:= b xor x[6]; c:= c - (t1[b and $FF] xor t2[(b shr 16) and $FF] xor t3[(b shr 32) and $FF] xor t4[(b shr 48) and $FF]); a:= a + (t4[(b shr 8) and $FF] xor t3[(b shr 24) and $FF] xor t2[(b shr 40) and $FF] xor t1[(b shr 56) and $FF]); a:= a * 7; c:= c xor x[7]; a:= a - (t1[c and $FF] xor t2[(c shr 16) and $FF] xor t3[(c shr 32) and $FF] xor t4[(c shr 48) and $FF]); b:= b + (t4[(c shr 8) and $FF] xor t3[(c shr 24) and $FF] xor t2[(c shr 40) and $FF] xor t1[(c shr 56) and $FF]); b:= b * 7; x[0]:= x[0] - (x[7] xor $A5A5A5A5A5A5A5A5); x[1]:= x[1] xor x[0]; x[2]:= x[2] + x[1]; x[3]:= x[3] - (x[2] xor ((not x[1]) shl 19)); x[4]:= x[4] xor x[3]; x[5]:= x[5] + x[4]; x[6]:= x[6] - (x[5] xor ((not x[4]) shr 23)); x[7]:= x[7] xor x[6]; x[0]:= x[0] + x[7]; x[1]:= x[1] - (x[0] xor ((not x[7]) shl 19)); x[2]:= x[2] xor x[1]; x[3]:= x[3] + x[2]; x[4]:= x[4] - (x[3] xor ((not x[2]) shr 23)); x[5]:= x[5] xor x[4]; x[6]:= x[6] + x[5]; x[7]:= x[7] - (x[6] xor $0123456789ABCDEF); a:= a xor x[0]; b:= b - (t1[a and $FF] xor t2[(a shr 16) and $FF] xor t3[(a shr 32) and $FF] xor t4[(a shr 48) and $FF]); c:= c + (t4[(a shr 8) and $FF] xor t3[(a shr 24) and $FF] xor t2[(a shr 40) and $FF] xor t1[(a shr 56) and $FF]); c:= c * 9; b:= b xor x[1]; c:= c - (t1[b and $FF] xor t2[(b shr 16) and $FF] xor t3[(b shr 32) and $FF] xor t4[(b shr 48) and $FF]); a:= a + (t4[(b shr 8) and $FF] xor t3[(b shr 24) and $FF] xor t2[(b shr 40) and $FF] xor t1[(b shr 56) and $FF]); a:= a * 9; c:= c xor x[2]; a:= a - (t1[c and $FF] xor t2[(c shr 16) and $FF] xor t3[(c shr 32) and $FF] xor t4[(c shr 48) and $FF]); b:= b + (t4[(c shr 8) and $FF] xor t3[(c shr 24) and $FF] xor t2[(c shr 40) and $FF] xor t1[(c shr 56) and $FF]); b:= b * 9; a:= a xor x[3]; b:= b - (t1[a and $FF] xor t2[(a shr 16) and $FF] xor t3[(a shr 32) and $FF] xor t4[(a shr 48) and $FF]); c:= c + (t4[(a shr 8) and $FF] xor t3[(a shr 24) and $FF] xor t2[(a shr 40) and $FF] xor t1[(a shr 56) and $FF]); c:= c * 9; b:= b xor x[4]; c:= c - (t1[b and $FF] xor t2[(b shr 16) and $FF] xor t3[(b shr 32) and $FF] xor t4[(b shr 48) and $FF]); a:= a + (t4[(b shr 8) and $FF] xor t3[(b shr 24) and $FF] xor t2[(b shr 40) and $FF] xor t1[(b shr 56) and $FF]); a:= a * 9; c:= c xor x[5]; a:= a - (t1[c and $FF] xor t2[(c shr 16) and $FF] xor t3[(c shr 32) and $FF] xor t4[(c shr 48) and $FF]); b:= b + (t4[(c shr 8) and $FF] xor t3[(c shr 24) and $FF] xor t2[(c shr 40) and $FF] xor t1[(c shr 56) and $FF]); b:= b * 9; a:= a xor x[6]; b:= b - (t1[a and $FF] xor t2[(a shr 16) and $FF] xor t3[(a shr 32) and $FF] xor t4[(a shr 48) and $FF]); c:= c + (t4[(a shr 8) and $FF] xor t3[(a shr 24) and $FF] xor t2[(a shr 40) and $FF] xor t1[(a shr 56) and $FF]); c:= c * 9; b:= b xor x[7]; c:= c - (t1[b and $FF] xor t2[(b shr 16) and $FF] xor t3[(b shr 32) and $FF] xor t4[(b shr 48) and $FF]); a:= a + (t4[(b shr 8) and $FF] xor t3[(b shr 24) and $FF] xor t2[(b shr 40) and $FF] xor t1[(b shr 56) and $FF]); a:= a * 9; CurrentHash[0]:= a xor aa; CurrentHash[1]:= b - bb; CurrentHash[2]:= c + cc; Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); end; class function TDCP_tiger.GetHashSize: integer; begin Result:= 192; end; class function TDCP_tiger.GetId: integer; begin Result:= DCP_tiger; end; class function TDCP_tiger.GetAlgorithm: string; begin Result:= 'Tiger'; end; class function TDCP_tiger.SelfTest: boolean; const Test1Out: array[0..2] of int64= ($87FB2A9083851CF7,$470D2CF810E6DF9E,$B586445034A5A386); Test2Out: array[0..2] of int64= ($0C410A042968868A,$1671DA5A3FD29A72,$5EC1E457D3CDB303); var TestHash: TDCP_tiger; TestOut: array[0..2] of int64; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_tiger.Create(nil); TestHash.Init; TestHash.UpdateStr('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Init; TestHash.UpdateStr('Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out)) and Result; TestHash.Free; end; procedure TDCP_tiger.Init; begin Burn; fInitialized:= true; CurrentHash[0]:= $0123456789ABCDEF; CurrentHash[1]:= $FEDCBA9876543210; CurrentHash[2]:= $F096A5B4C3B2E187; end; procedure TDCP_tiger.Burn; begin Len:= 0; Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); FillChar(CurrentHash,Sizeof(CurrentHash),0); fInitialized:= false; end; procedure TDCP_tiger.Update(const Buffer; Size: longword); var PBuf: ^byte; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); Inc(Len,Size*8); PBuf:= @Buffer; while Size> 0 do begin if (Sizeof(HashBuffer)-Index)<= DWord(Size) then begin Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index); Dec(Size,Sizeof(HashBuffer)-Index); Inc(PBuf,Sizeof(HashBuffer)-Index); Compress; end else begin Move(PBuf^,HashBuffer[Index],Size); Inc(Index,Size); Size:= 0; end; end; end; procedure TDCP_tiger.Final(var Digest); begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); HashBuffer[Index]:= $01; if Index>= 56 then Compress; Pint64(@HashBuffer[56])^:= Len; Compress; Move(CurrentHash,Digest,Sizeof(CurrentHash)); Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dcblake2.pp0000664000175000017500000003327712573066072021771 0ustar alexxalexx{ BLAKE2 reference source code package - reference C implementations Written in 2012 by Samuel Neves Pascal tranlastion in 2014-2015 by Alexander Koblov (alexx2000@mail.ru) To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . } unit DCblake2; {$mode objfpc}{$H+} {$macro on}{$R-}{$Q-} {$define USE_MTPROCS} interface uses SysUtils, CTypes; const PARALLELISM_DEGREE = 8; BLAKE2S_BLOCKBYTES = 64; BLAKE2S_OUTBYTES = 32; BLAKE2S_KEYBYTES = 32; BLAKE2S_SALTBYTES = 8; BLAKE2S_PERSONALBYTES = 8; type {$packrecords 1} Pblake2s_param = ^blake2s_param; blake2s_param = record digest_length: cuint8; // 1 key_length: cuint8; // 2 fanout: cuint8; // 3 depth: cuint8; // 4 leaf_length: cuint32; // 8 node_offset: array[0..5] of cuint8;// 14 node_depth: cuint8; // 15 inner_length: cuint8; // 16 // uint8_t reserved[0]; salt: array[0..Pred(BLAKE2S_SALTBYTES)] of cuint8; // 24 personal: array[0..Pred(BLAKE2S_PERSONALBYTES)] of cuint8; // 32 end; {$packrecords 8} Pblake2s_state = ^blake2s_state; blake2s_state = record h: array[0..7] of cuint32; t: array[0..1] of cuint32; f: array[0..1] of cuint32; buf: array[0..Pred(2 * BLAKE2S_BLOCKBYTES)] of cuint8; buflen: csize_t; last_node: cuint8; end; {$packrecords 1} Pblake2sp_state = ^blake2sp_state; blake2sp_state = record S: array[0..7] of blake2s_state; R: blake2s_state; buf: array[0..Pred(8 * BLAKE2S_BLOCKBYTES)] of cuint8; buflen: csize_t; inlen: csize_t; inp: PByte; end; {$packrecords default} function blake2s_init( S: Pblake2s_state; const outlen: cuint8 ): cint; function blake2s_update( S: Pblake2s_state; inp: pcuint8; inlen: cuint64 ): cint; function blake2s_final( S: Pblake2s_state; outp: pcuint8; outlen: cuint8 ): cint; function blake2sp_init( S: Pblake2sp_state; const outlen: cuint8 ): cint; function blake2sp_update( S: Pblake2sp_state; inp: pcuint8; inlen: cuint64 ): cint; function blake2sp_final( S: Pblake2sp_state; outp: pcuint8; const outlen: cuint8 ): cint; implementation {$IF DEFINED(USE_MTPROCS)} uses MTProcs; {$ELSE} type TMultiThreadProcItem = Pointer; {$ENDIF} const blake2s_IV: array[0..7] of cuint32 = ( $6A09E667, $BB67AE85, $3C6EF372, $A54FF53A, $510E527F, $9B05688C, $1F83D9AB, $5BE0CD19 ); const blake2s_sigma: array[0..9] of array[0..15] of cuint8 = ( ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ) , ( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ) , ( 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ) , ( 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ) , ( 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ) , ( 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ) , ( 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ) , ( 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ) , ( 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ) , ( 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 ) ); function load32( const src: Pointer ): cuint32; inline; begin Result := NtoLE(pcuint32(src)^); end; function load64( const src: pointer ): cuint64; inline; begin Result := NtoLE(pcuint64(src)^); end; procedure store32( dst: pointer; w: cuint32 ); inline; begin pcuint32(dst)^ := LEtoN(w); end; procedure store64( dst: pointer; w: cuint64 ); inline; begin pcuint64(dst)^ := LEtoN(w); end; function load48( const src: pointer ): cuint64; inline; var w: cuint64; p: pcuint8; begin p := pcuint8(src); w := p^; Inc(p); w := w or cuint64( p^ ) shl 8; inc(p); w := w or cuint64( p^ ) shl 16; inc(p); w := w or cuint64( p^ ) shl 24; inc(p); w := w or cuint64( p^ ) shl 32; inc(p); w := w or cuint64( p^ ) shl 40; inc(p); Result := w; end; procedure store48( dst: pointer; w: cuint64 ); inline; var p: pcuint8; begin p := pcuint8(dst); p^ := cuint8(w); w := w shr 8; inc(p); p^ := cuint8(w); w := w shr 8; inc(p); p^ := cuint8(w); w := w shr 8; inc(p); p^ := cuint8(w); w := w shr 8; inc(p); p^ := cuint8(w); w := w shr 8; inc(p); p^ := cuint8(w); inc(p); end; function blake2s_set_lastnode( S: Pblake2s_state ): cint; inline; begin S^.f[1] := $FFFFFFFF; Result := 0; end; function blake2s_clear_lastnode( S: Pblake2s_state ): cint; inline; begin S^.f[1] := 0; Result := 0; end; //* Some helper functions, not necessarily useful */ function blake2s_set_lastblock( S: Pblake2s_state ): cint; inline; begin if( S^.last_node <> 0 ) then blake2s_set_lastnode( S ); S^.f[0] := $FFFFFFFF; Result := 0; end; function blake2s_clear_lastblock( S: Pblake2s_state ): cint; inline; begin if( S^.last_node <> 0 ) then blake2s_clear_lastnode( S ); S^.f[0] := 0; Result := 0; end; function blake2s_increment_counter( S: Pblake2s_state; const inc: cuint32 ): cint; inline; begin S^.t[0] += inc; S^.t[1] += cuint32( S^.t[0] < inc ); Result := 0; end; function blake2s_init0( S: Pblake2s_state ): cint; inline; var i: cint; begin FillChar( S^, sizeof( blake2s_state ), 0 ); for i := 0 to 8 - 1 do S^.h[i] := blake2s_IV[i]; Result := 0; end; //* init2 xors IV with input parameter block */ function blake2s_init_param( S: Pblake2s_state; const P: Pblake2s_param ): cint; var i: csize_t; pp: pcuint32; begin blake2s_init0( S ); pp := pcuint32( P ); //* IV XOR ParamBlock */ // for i := 0; i < 8; ++i ) for i := 0 to 8 - 1 do S^.h[i] := S^.h[i] xor load32( @pp[i] ); Result := 0; end; // Sequential blake2s initialization function blake2s_init( S: Pblake2s_state; const outlen: cuint8 ): cint; var P: blake2s_param; begin //* Move interval verification here? */ if ( ( outlen = 0 ) or ( outlen > BLAKE2S_OUTBYTES ) ) then Exit(-1); P.digest_length := outlen; P.key_length := 0; P.fanout := 1; P.depth := 1; store32( @P.leaf_length, 0 ); store48( @P.node_offset, 0 ); P.node_depth := 0; P.inner_length := 0; // memset(P^.reserved, 0, sizeof(P^.reserved) ); FillChar( P.salt, sizeof( P.salt ), 0 ); FillChar( P.personal, sizeof( P.personal ), 0 ); Result := blake2s_init_param( S, @P ); end; function blake2s_compress( S: Pblake2s_state; const block: pcuint8 ): cint; var i: csize_t; m: array[0..15] of cuint32; v: array[0..15] of cuint32; procedure G(r,i: cuint32; var a,b,c,d: cuint32); inline; begin a := a + b + m[blake2s_sigma[r][2*i+0]]; d := RorDWord(d xor a, 16); c := c + d; b := RorDWord(b xor c, 12); a := a + b + m[blake2s_sigma[r][2*i+1]]; d := RorDWord(d xor a, 8); c := c + d; b := RorDWord(b xor c, 7); end; {$define ROUND_MACRO:= G(r_,0,v[ 0],v[ 4],v[ 8],v[12]); G(r_,1,v[ 1],v[ 5],v[ 9],v[13]); G(r_,2,v[ 2],v[ 6],v[10],v[14]); G(r_,3,v[ 3],v[ 7],v[11],v[15]); G(r_,4,v[ 0],v[ 5],v[10],v[15]); G(r_,5,v[ 1],v[ 6],v[11],v[12]); G(r_,6,v[ 2],v[ 7],v[ 8],v[13]); G(r_,7,v[ 3],v[ 4],v[ 9],v[14]); } begin for i := 0 to 15 do m[i] := load32( @block[i * sizeof( m[i] )] ); for i := 0 to 7 do v[i] := S^.h[i]; v[ 8] := blake2s_IV[0]; v[ 9] := blake2s_IV[1]; v[10] := blake2s_IV[2]; v[11] := blake2s_IV[3]; v[12] := S^.t[0] xor blake2s_IV[4]; v[13] := S^.t[1] xor blake2s_IV[5]; v[14] := S^.f[0] xor blake2s_IV[6]; v[15] := S^.f[1] xor blake2s_IV[7]; {$define r_:= 0} ROUND_MACRO; {$define r_:= 1} ROUND_MACRO; {$define r_:= 2} ROUND_MACRO; {$define r_:= 3} ROUND_MACRO; {$define r_:= 4} ROUND_MACRO; {$define r_:= 5} ROUND_MACRO; {$define r_:= 6} ROUND_MACRO; {$define r_:= 7} ROUND_MACRO; {$define r_:= 8} ROUND_MACRO; {$define r_:= 9} ROUND_MACRO; for i := 0 to 7 do S^.h[i] := S^.h[i] xor v[i] xor v[i + 8]; Result := 0; end; function blake2s_update( S: Pblake2s_state; inp: pcuint8; inlen: cuint64 ): cint; var left, fill: csize_t; begin while( inlen > 0 ) do begin left := S^.buflen; fill := 2 * BLAKE2S_BLOCKBYTES - left; if( inlen > fill ) then begin Move( inp^, S^.buf[left], fill ); // Fill buffer S^.buflen += fill; blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); blake2s_compress( S, S^.buf ); // Compress Move( S^.buf[BLAKE2S_BLOCKBYTES], S^.buf, BLAKE2S_BLOCKBYTES ); // Shift buffer left S^.buflen -= BLAKE2S_BLOCKBYTES; inp += fill; inlen -= fill; end else // inlen <= fill begin Move( inp^, S^.buf [left], inlen ); S^.buflen += inlen; // Be lazy, do not compress inp += inlen; inlen -= inlen; end; end; Result := 0; end; function blake2s_final( S: Pblake2s_state; outp: pcuint8; outlen: cuint8 ): cint; var i: cint; buffer: array[0..Pred(BLAKE2S_OUTBYTES)] of cuint8; begin if( S^.buflen > BLAKE2S_BLOCKBYTES ) then begin blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); blake2s_compress( S, S^.buf); S^.buflen -= BLAKE2S_BLOCKBYTES; Move( S^.buf[BLAKE2S_BLOCKBYTES], S^.buf, S^.buflen ); end; blake2s_increment_counter( S, cuint32(S^.buflen) ); blake2s_set_lastblock( S ); FillChar( S^.buf[S^.buflen], 2 * BLAKE2S_BLOCKBYTES - S^.buflen, 0 ); //* Padding */ blake2s_compress( S, S^.buf ); for i := 0 to 7 do //* Output full hash to temp buffer */ store32( @buffer[sizeof( S^.h[i] ) * i], S^.h[i] ); Move( buffer, outp^, outlen ); Result := 0; end; function blake2sp_init_leaf(S: Pblake2s_state; outlen: cuint8; keylen: cuint8; offset: cuint64):cint; inline; var P: blake2s_param; begin P.digest_length := outlen; P.key_length := keylen; P.fanout := PARALLELISM_DEGREE; P.depth := 2; store32( @P.leaf_length, 0 ); store48( @P.node_offset[0], offset ); P.node_depth := 0; P.inner_length := BLAKE2S_OUTBYTES; FillChar( P.salt, sizeof( P.salt ), 0 ); FillChar( P.personal, sizeof( P.personal ), 0 ); Result:= blake2s_init_param( S, @P ); end; function blake2sp_init_root( S: Pblake2s_state; outlen: cuint8; keylen: cuint8 ): cint; inline; var P: blake2s_param; begin P.digest_length := outlen; P.key_length := keylen; P.fanout := PARALLELISM_DEGREE; P.depth := 2; store32( @P.leaf_length, 0 ); store48( @P.node_offset[0], 0 ); P.node_depth := 1; P.inner_length := BLAKE2S_OUTBYTES; FillChar( P.salt, sizeof( P.salt ), 0 ); FillChar( P.personal, sizeof( P.personal ), 0 ); Result:= blake2s_init_param( S, @P ); end; function blake2sp_init( S: Pblake2sp_state; const outlen: cuint8 ): cint; var i: csize_t; begin if (outlen = 0) or (outlen > BLAKE2S_OUTBYTES) then Exit(-1); FillChar( S^.buf, sizeof( S^.buf ), 0 ); S^.buflen := 0; if( blake2sp_init_root( @S^.R, outlen, 0 ) < 0 ) then Exit(-1); for i := 0 to PARALLELISM_DEGREE - 1 do if ( blake2sp_init_leaf( @S^.S[i], outlen, 0, i ) < 0 ) then Exit(-1); S^.R.last_node := 1; S^.S[PARALLELISM_DEGREE - 1].last_node := 1; Result := 0; end; procedure MTProcedure(id__: PtrInt; Data: Pointer; Item: TMultiThreadProcItem); var in__: pcuint8; inlen__: cuint64; S: Pblake2sp_state absolute Data; begin in__ := S^.inp; inlen__ := S^.inlen; in__ += id__ * BLAKE2S_BLOCKBYTES; while ( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) do begin blake2s_update( @S^.S[id__], in__, BLAKE2S_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; end; end; function blake2sp_update( S: Pblake2sp_state; inp: pcuint8; inlen: cuint64 ): cint; var i, left, fill: csize_t; begin left := S^.buflen; fill := sizeof( S^.buf ) - left; if ( left <> 0) and (inlen >= fill ) then begin Move(inp^, S^.buf[left], fill); for i := 0 to PARALLELISM_DEGREE - 1 do blake2s_update( @S^.S[i], @S^.buf[ i * BLAKE2S_BLOCKBYTES], BLAKE2S_BLOCKBYTES ); inp += fill; inlen -= fill; left := 0; end; S^.inp := inp; S^.inlen := inlen; {$IF DEFINED(USE_MTPROCS)} ProcThreadPool.DoParallel(@MTProcedure, 0, PARALLELISM_DEGREE - 1, S); {$ELSE} for i := 0 to PARALLELISM_DEGREE - 1 do MTProcedure(i, S, nil); {$ENDIF} inp += inlen - inlen mod ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ); inlen := inlen mod (PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES); if ( inlen > 0 ) then Move(inp^, S^.buf[left], inlen ); S^.buflen := left + inlen; Result := 0; end; function blake2sp_final( S: Pblake2sp_state; outp: pcuint8; const outlen: cuint8 ): cint; var i, left: csize_t; hash: array[0..Pred(PARALLELISM_DEGREE), 0..Pred(BLAKE2S_OUTBYTES)] of cuint8; begin for i := 0 to PARALLELISM_DEGREE - 1 do begin if ( S^.buflen > i * BLAKE2S_BLOCKBYTES ) then begin left := S^.buflen - i * BLAKE2S_BLOCKBYTES; if ( left > BLAKE2S_BLOCKBYTES ) then left := BLAKE2S_BLOCKBYTES; blake2s_update( @S^.S[i], @S^.buf[i * BLAKE2S_BLOCKBYTES], left ); end; blake2s_final( @S^.S[i], hash[i], BLAKE2S_OUTBYTES ); end; for i := 0 to PARALLELISM_DEGREE - 1 do blake2s_update( @S^.R, hash[i], BLAKE2S_OUTBYTES ); blake2s_final( @S^.R, outp, outlen ); Result := 0; end; end. doublecmd-0.8.2/components/dcpcrypt/Hashes/dcpmd4.pas0000664000175000017500000002121512014201074021605 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A binary compatible implementation of MD4 **********************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPmd4; {$MODE Delphi} interface uses Classes, Sysutils, DCPcrypt2, DCPconst; type TDCP_md4= class(TDCP_hash) protected LenHi, LenLo: longword; Index: DWord; CurrentHash: array[0..3] of DWord; HashBuffer: array[0..63] of byte; procedure Compress; public class function GetId: integer; override; class function GetAlgorithm: string; override; class function GetHashSize: integer; override; class function SelfTest: boolean; override; procedure Init; override; procedure Burn; override; procedure Update(const Buffer; Size: longword); override; procedure Final(var Digest); override; end; {******************************************************************************} {******************************************************************************} implementation {$R-}{$Q-} function LRot32(a, b: longword): longword; begin Result:= (a shl b) or (a shr (32-b)); end; procedure TDCP_md4.Compress; var Data: array[0..15] of dword; A, B, C, D: dword; begin dcpFillChar(Data, SizeOf(Data), 0); Move(HashBuffer,Data,Sizeof(Data)); A:= CurrentHash[0]; B:= CurrentHash[1]; C:= CurrentHash[2]; D:= CurrentHash[3]; A:= LRot32(A + (D xor (B and (C xor D))) + Data[ 0],3); D:= LRot32(D + (C xor (A and (B xor C))) + Data[ 1],7); C:= LRot32(C + (B xor (D and (A xor B))) + Data[ 2],11); B:= LRot32(B + (A xor (C and (D xor A))) + Data[ 3],19); A:= LRot32(A + (D xor (B and (C xor D))) + Data[ 4],3); D:= LRot32(D + (C xor (A and (B xor C))) + Data[ 5],7); C:= LRot32(C + (B xor (D and (A xor B))) + Data[ 6],11); B:= LRot32(B + (A xor (C and (D xor A))) + Data[ 7],19); A:= LRot32(A + (D xor (B and (C xor D))) + Data[ 8],3); D:= LRot32(D + (C xor (A and (B xor C))) + Data[ 9],7); C:= LRot32(C + (B xor (D and (A xor B))) + Data[10],11); B:= LRot32(B + (A xor (C and (D xor A))) + Data[11],19); A:= LRot32(A + (D xor (B and (C xor D))) + Data[12],3); D:= LRot32(D + (C xor (A and (B xor C))) + Data[13],7); C:= LRot32(C + (B xor (D and (A xor B))) + Data[14],11); B:= LRot32(B + (A xor (C and (D xor A))) + Data[15],19); A:= LRot32(A + ((B and C) or (B and D) or (C and D)) + Data[ 0] + $5a827999,3); D:= LRot32(D + ((A and B) or (A and C) or (B and C)) + Data[ 4] + $5a827999,5); C:= LRot32(C + ((D and A) or (D and B) or (A and B)) + Data[ 8] + $5a827999,9); B:= LRot32(B + ((C and D) or (C and A) or (D and A)) + Data[12] + $5a827999,13); A:= LRot32(A + ((B and C) or (B and D) or (C and D)) + Data[ 1] + $5a827999,3); D:= LRot32(D + ((A and B) or (A and C) or (B and C)) + Data[ 5] + $5a827999,5); C:= LRot32(C + ((D and A) or (D and B) or (A and B)) + Data[ 9] + $5a827999,9); B:= LRot32(B + ((C and D) or (C and A) or (D and A)) + Data[13] + $5a827999,13); A:= LRot32(A + ((B and C) or (B and D) or (C and D)) + Data[ 2] + $5a827999,3); D:= LRot32(D + ((A and B) or (A and C) or (B and C)) + Data[ 6] + $5a827999,5); C:= LRot32(C + ((D and A) or (D and B) or (A and B)) + Data[10] + $5a827999,9); B:= LRot32(B + ((C and D) or (C and A) or (D and A)) + Data[14] + $5a827999,13); A:= LRot32(A + ((B and C) or (B and D) or (C and D)) + Data[ 3] + $5a827999,3); D:= LRot32(D + ((A and B) or (A and C) or (B and C)) + Data[ 7] + $5a827999,5); C:= LRot32(C + ((D and A) or (D and B) or (A and B)) + Data[11] + $5a827999,9); B:= LRot32(B + ((C and D) or (C and A) or (D and A)) + Data[15] + $5a827999,13); A:= LRot32(A + (B xor C xor D) + Data[ 0] + $6ed9eba1,3); D:= LRot32(D + (A xor B xor C) + Data[ 8] + $6ed9eba1,9); C:= LRot32(C + (D xor A xor B) + Data[ 4] + $6ed9eba1,11); B:= LRot32(B + (C xor D xor A) + Data[12] + $6ed9eba1,15); A:= LRot32(A + (B xor C xor D) + Data[ 2] + $6ed9eba1,3); D:= LRot32(D + (A xor B xor C) + Data[10] + $6ed9eba1,9); C:= LRot32(C + (D xor A xor B) + Data[ 6] + $6ed9eba1,11); B:= LRot32(B + (C xor D xor A) + Data[14] + $6ed9eba1,15); A:= LRot32(A + (B xor C xor D) + Data[ 1] + $6ed9eba1,3); D:= LRot32(D + (A xor B xor C) + Data[ 9] + $6ed9eba1,9); C:= LRot32(C + (D xor A xor B) + Data[ 5] + $6ed9eba1,11); B:= LRot32(B + (C xor D xor A) + Data[13] + $6ed9eba1,15); A:= LRot32(A + (B xor C xor D) + Data[ 3] + $6ed9eba1,3); D:= LRot32(D + (A xor B xor C) + Data[11] + $6ed9eba1,9); C:= LRot32(C + (D xor A xor B) + Data[ 7] + $6ed9eba1,11); B:= LRot32(B + (C xor D xor A) + Data[15] + $6ed9eba1,15); Inc(CurrentHash[0],A); Inc(CurrentHash[1],B); Inc(CurrentHash[2],C); Inc(CurrentHash[3],D); Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); end; class function TDCP_md4.GetHashSize: integer; begin Result:= 128; end; class function TDCP_md4.GetId: integer; begin Result:= DCP_md4; end; class function TDCP_md4.GetAlgorithm: string; begin Result:= 'MD4'; end; class function TDCP_md4.SelfTest: boolean; const Test1Out: array[0..15] of byte= ($a4,$48,$01,$7a,$af,$21,$d8,$52,$5f,$c1,$0a,$e8,$7a,$a6,$72,$9d); Test2Out: array[0..15] of byte= ($d7,$9e,$1c,$30,$8a,$a5,$bb,$cd,$ee,$a8,$ed,$63,$df,$41,$2d,$a9); var TestHash: TDCP_md4; TestOut: array[0..19] of byte; begin dcpFillChar(TestOut, SizeOf(TestOut), 0); TestHash:= TDCP_md4.Create(nil); TestHash.Init; TestHash.UpdateStr('abc'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out)); TestHash.Init; TestHash.UpdateStr('abcdefghijklmnopqrstuvwxyz'); TestHash.Final(TestOut); Result:= CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out)) and Result; TestHash.Free; end; procedure TDCP_md4.Init; begin Burn; CurrentHash[0]:= $67452301; CurrentHash[1]:= $efcdab89; CurrentHash[2]:= $98badcfe; CurrentHash[3]:= $10325476; fInitialized:= true; end; procedure TDCP_md4.Burn; begin LenHi:= 0; LenLo:= 0; Index:= 0; FillChar(HashBuffer,Sizeof(HashBuffer),0); FillChar(CurrentHash,Sizeof(CurrentHash),0); fInitialized:= false; end; procedure TDCP_md4.Update(const Buffer; Size: longword); var PBuf: ^byte; begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); Inc(LenHi,Size shr 29); Inc(LenLo,Size*8); if LenLo< (Size*8) then Inc(LenHi); PBuf:= @Buffer; while Size> 0 do begin if (Sizeof(HashBuffer)-Index)<= DWord(Size) then begin Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index); Dec(Size,Sizeof(HashBuffer)-Index); Inc(PBuf,Sizeof(HashBuffer)-Index); Compress; end else begin Move(PBuf^,HashBuffer[Index],Size); Inc(Index,Size); Size:= 0; end; end; end; procedure TDCP_md4.Final(var Digest); begin if not fInitialized then raise EDCP_hash.Create('Hash not initialized'); HashBuffer[Index]:= $80; if Index>= 56 then Compress; PDWord(@HashBuffer[56])^:= LenLo; PDWord(@HashBuffer[60])^:= LenHi; Compress; Move(CurrentHash,Digest,Sizeof(CurrentHash)); Burn; end; end. doublecmd-0.8.2/components/dcpcrypt/dcpbase64.pas0000664000175000017500000001263012014201074020773 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* A Base64 encoding/decoding unit ********************************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPbase64; interface uses Sysutils; function Base64EncodeStr(const Value: string): string; { Encode a string into Base64 format } function Base64DecodeStr(const Value: string): string; { Decode a Base64 format string } function Base64Encode(pInput: pointer; pOutput: pointer; Size: longint): longint; { Encode a lump of raw data (output is (4/3) times bigger than input) } function Base64Decode(pInput: pointer; pOutput: pointer; Size: longint): longint; { Decode a lump of raw data } {******************************************************************************} {******************************************************************************} implementation {$Q-}{$R-} const B64: array[0..63] of byte= (65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, 81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108, 109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53, 54,55,56,57,43,47); function Base64Encode(pInput: pointer; pOutput: pointer; Size: longint): longint; var i, iptr, optr: integer; Input, Output: PByteArray; begin Input:= PByteArray(pInput); Output:= PByteArray(pOutput); iptr:= 0; optr:= 0; for i:= 1 to (Size div 3) do begin Output^[optr+0]:= B64[Input^[iptr] shr 2]; Output^[optr+1]:= B64[((Input^[iptr] and 3) shl 4) + (Input^[iptr+1] shr 4)]; Output^[optr+2]:= B64[((Input^[iptr+1] and 15) shl 2) + (Input^[iptr+2] shr 6)]; Output^[optr+3]:= B64[Input^[iptr+2] and 63]; Inc(optr,4); Inc(iptr,3); end; case (Size mod 3) of 1: begin Output^[optr+0]:= B64[Input^[iptr] shr 2]; Output^[optr+1]:= B64[(Input^[iptr] and 3) shl 4]; Output^[optr+2]:= byte('='); Output^[optr+3]:= byte('='); end; 2: begin Output^[optr+0]:= B64[Input^[iptr] shr 2]; Output^[optr+1]:= B64[((Input^[iptr] and 3) shl 4) + (Input^[iptr+1] shr 4)]; Output^[optr+2]:= B64[(Input^[iptr+1] and 15) shl 2]; Output^[optr+3]:= byte('='); end; end; Result:= ((Size+2) div 3) * 4; end; function Base64EncodeStr(const Value: string): string; begin SetLength(Result,((Length(Value)+2) div 3) * 4); Base64Encode(@Value[1],@Result[1],Length(Value)); end; function Base64Decode(pInput: pointer; pOutput: pointer; Size: longint): longint; var i, j, iptr, optr: integer; Temp: array[0..3] of byte; Input, Output: PByteArray; begin Input:= PByteArray(pInput); Output:= PByteArray(pOutput); iptr:= 0; optr:= 0; Result:= 0; for i:= 1 to (Size div 4) do begin for j:= 0 to 3 do begin case Input^[iptr] of 65..90 : Temp[j]:= Input^[iptr] - Ord('A'); 97..122: Temp[j]:= Input^[iptr] - Ord('a') + 26; 48..57 : Temp[j]:= Input^[iptr] - Ord('0') + 52; 43 : Temp[j]:= 62; 47 : Temp[j]:= 63; 61 : Temp[j]:= $FF; end; Inc(iptr); end; Output^[optr]:= (Temp[0] shl 2) or (Temp[1] shr 4); Result:= optr+1; if (Temp[2]<> $FF) and (Temp[3]= $FF) then begin Output^[optr+1]:= (Temp[1] shl 4) or (Temp[2] shr 2); Result:= optr+2; Inc(optr) end else if (Temp[2]<> $FF) then begin Output^[optr+1]:= (Temp[1] shl 4) or (Temp[2] shr 2); Output^[optr+2]:= (Temp[2] shl 6) or Temp[3]; Result:= optr+3; Inc(optr,2); end; Inc(optr); end; end; function Base64DecodeStr(const Value: string): string; begin SetLength(Result,(Length(Value) div 4) * 3); SetLength(Result,Base64Decode(@Value[1],@Result[1],Length(Value))); end; end. doublecmd-0.8.2/components/dcpcrypt/dcpconst.pas0000664000175000017500000000622212573066072021056 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* Constants for use with DCPcrypt ********************************************} {******************************************************************************} {* Copyright (c) 1999-2002 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPconst; interface {******************************************************************************} const { Component registration } DCPcipherpage = 'DCPciphers'; DCPhashpage = 'DCPhashes'; { ID values } DCP_rc2 = 1; DCP_sha1 = 2; DCP_rc5 = 3; DCP_rc6 = 4; DCP_blowfish = 5; DCP_twofish = 6; DCP_cast128 = 7; DCP_gost = 8; DCP_rijndael = 9; DCP_ripemd160 = 10; DCP_misty1 = 11; DCP_idea = 12; DCP_mars = 13; DCP_haval = 14; DCP_cast256 = 15; DCP_md5 = 16; DCP_md4 = 17; DCP_tiger = 18; DCP_rc4 = 19; DCP_ice = 20; DCP_thinice = 21; DCP_ice2 = 22; DCP_des = 23; DCP_3des = 24; DCP_tea = 25; DCP_serpent = 26; DCP_ripemd128 = 27; DCP_sha256 = 28; DCP_sha384 = 29; DCP_sha512 = 30; DCP_blake2s = 97; DCP_blake2sp = 98; DCP_crc32 = 99; {******************************************************************************} {******************************************************************************} implementation end. doublecmd-0.8.2/components/dcpcrypt/DCPhashes.lrs0000664000175000017500000003660211652036011021050 0ustar alexxalexxLazarusResources.Add('TDCP_HAVAL','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#254#254#254#254#255#239#254#254#254#238#255#255#236#236#236#236#238#206#236 +#236#236#204#239#255#236#236#236#236#236#236#236#236#236#238#255#255#236#236 +#236#236#236#236#236#236#236#239#255#255#236#204#236#204#236#236#236#204#236 +#239#255#255#236#236#236#236#236#236#236#236#236#239#255#255#236#236#236#236 +#236#236#236#236#236#239#255#255#236#236#238#206#236#236#238#206#236#239#255 +#255#254#254#255#239#254#254#255#239#254#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_MD4','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#254#255#254#255#238#239#255#255#239#255#255#255#236#239#236#238#204#206#255 +#254#206#255#255#255#236#239#236#238#206#236#239#238#206#255#255#255#236#238 +#236#238#206#236#238#204#204#239#255#255#236#236#236#238#206#236#238#206#206 +#255#255#255#236#236#236#238#206#236#238#206#239#255#255#255#236#206#204#238 +#206#236#238#206#255#255#255#255#236#239#236#238#204#206#254#206#255#255#255 +#255#254#255#254#255#238#239#255#239#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_MD5','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#254#255#254#255#238#239#255#238#239#255#255#255#236#239#236#238#204#206#254 +#204#206#255#255#255#236#239#236#238#206#236#239#238#236#239#255#255#236#238 +#236#238#206#236#239#254#236#239#255#255#236#236#236#238#206#236#239#236#204 +#239#255#255#236#236#236#238#206#236#238#206#238#255#255#255#236#206#204#238 +#206#236#238#206#238#255#255#255#236#239#236#238#204#206#254#204#204#239#255 +#255#254#255#254#255#238#239#255#238#238#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_RIPEMD128','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#128#128#128#0#192#192#192#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#238#239 +#254#238#239#255#238#255#255#255#255#254#204#206#236#204#206#254#204#239#255 +#255#255#255#236#239#254#206#239#236#238#206#255#255#255#255#236#239#255#236 +#239#236#238#206#255#255#255#255#236#239#254#254#206#254#204#239#255#255#255 +#255#236#239#236#238#206#236#238#206#255#255#255#254#204#239#236#238#206#236 +#238#206#255#255#255#255#236#239#254#204#239#254#204#239#255#255#255#255#254 +#255#255#238#255#255#238#255#255#255#255#254#255#239#254#255#254#255#238#239 +#255#255#255#236#238#206#236#239#236#238#204#206#255#255#255#236#238#206#236 +#239#236#238#206#236#239#255#255#236#238#206#236#238#236#238#206#236#239#255 +#255#236#204#239#236#236#236#238#206#236#239#255#255#236#238#206#236#236#236 +#238#206#236#239#255#255#236#238#206#236#206#204#238#206#236#239#255#255#236 +#204#239#236#239#236#238#204#206#255#255#255#254#238#255#254#255#254#255#238 +#239#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_RIPEMD160','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#238#239 +#255#238#255#255#238#255#255#255#255#254#204#206#254#204#239#254#204#239#255 +#255#255#255#236#239#236#238#206#236#238#206#255#255#255#255#236#239#236#238 +#206#236#238#206#255#255#255#255#236#239#236#204#239#236#238#206#255#255#255 +#255#236#239#236#238#239#236#238#206#255#255#255#254#204#239#236#238#206#236 +#238#206#255#255#255#255#236#239#254#204#239#254#204#239#255#255#255#255#254 +#255#255#238#255#255#238#255#255#255#255#254#255#239#254#255#254#255#238#239 +#255#255#255#236#238#206#236#239#236#238#204#206#255#255#255#236#238#206#236 +#239#236#238#206#236#239#255#255#236#238#206#236#238#236#238#206#236#239#255 +#255#236#204#239#236#236#236#238#206#236#239#255#255#236#238#206#236#236#236 +#238#206#236#239#255#255#236#238#206#236#206#204#238#206#236#239#255#255#236 +#204#239#236#239#236#238#204#206#255#255#255#254#238#255#254#255#254#255#238 +#239#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_SHA1','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128#128#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#254 +#238#255#254#255#239#254#255#239#254#238#255#236#204#239#236#238#206#236#238 +#206#236#204#239#254#238#206#236#238#206#236#238#206#254#206#255#255#238#206 +#236#238#206#236#238#206#254#206#255#254#204#239#236#204#206#236#204#206#254 +#206#255#236#238#255#236#238#206#236#238#206#254#206#255#236#238#239#236#238 +#206#236#238#206#236#206#255#254#204#206#236#238#206#254#204#239#254#206#255 +#255#238#239#254#255#239#255#238#255#255#239#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_SHA256','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#128#128#128#0#192#192#192#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#238#238 +#255#238#239#255#254#239#255#255#255#254#204#204#238#204#206#255#236#206#255 +#255#255#255#236#238#255#238#236#238#206#236#239#255#255#255#254#206#255#254 +#236#238#206#236#239#255#255#255#239#236#239#236#206#254#204#206#255#255#255 +#254#206#236#238#206#239#254#206#239#255#255#255#254#206#236#238#206#238#254 +#206#238#255#255#255#255#236#206#254#204#204#239#236#204#239#255#255#255#254 +#239#255#238#238#255#254#238#255#255#255#255#238#239#255#239#254#255#239#254 +#255#255#255#254#204#206#254#206#236#238#206#236#239#255#255#255#238#236#238 +#206#236#238#206#236#239#255#255#255#254#236#238#206#236#238#206#236#239#255 +#255#255#236#206#254#204#204#238#204#204#239#255#255#254#206#239#254#206#236 +#238#206#236#239#255#255#254#206#238#254#206#236#238#206#236#239#255#255#255 +#236#204#238#206#236#239#236#206#255#255#255#255#254#238#255#239#254#255#254 +#239#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_SHA384','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#128#128#128#0#192#192#192#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#238#239 +#255#254#239#255#255#239#255#255#255#254#204#206#255#236#206#255#238#206#255 +#255#255#255#238#236#238#206#236#238#204#204#239#255#255#255#254#236#238#206 +#236#238#206#206#255#255#255#255#236#206#255#236#206#254#206#206#255#255#255 +#255#254#236#238#206#236#238#206#239#255#255#255#255#238#236#238#206#236#239 +#236#239#255#255#255#254#204#206#255#236#206#255#236#239#255#255#255#255#238 +#239#255#254#239#255#254#255#255#255#255#255#238#239#255#239#254#255#239#254 +#255#255#255#254#204#206#254#206#236#238#206#236#239#255#255#255#238#236#238 +#206#236#238#206#236#239#255#255#255#254#236#238#206#236#238#206#236#239#255 +#255#255#236#206#254#204#204#238#204#204#239#255#255#254#206#239#254#206#236 +#238#206#236#239#255#255#254#206#238#254#206#236#238#206#236#239#255#255#255 +#236#204#238#206#236#239#236#206#255#255#255#255#254#238#255#239#254#255#254 +#239#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_SHA512','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#128#128#128#0#192#192#192#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#238#239 +#255#254#238#255#238#238#255#255#255#254#204#206#255#236#204#238#204#204#239 +#255#255#255#238#236#239#254#206#255#236#238#255#255#255#255#254#236#239#254 +#206#255#254#206#255#255#255#255#236#206#255#254#206#255#239#236#239#255#255 +#254#206#239#255#254#206#254#206#236#239#255#255#254#206#238#255#236#206#254 +#206#236#239#255#255#254#204#204#239#254#206#255#236#206#255#255#255#255#238 +#238#255#255#239#255#254#239#255#255#255#255#238#239#255#239#254#255#239#254 +#255#255#255#254#204#206#254#206#236#238#206#236#239#255#255#255#238#236#238 +#206#236#238#206#236#239#255#255#255#254#236#238#206#236#238#206#236#239#255 +#255#255#236#206#254#204#204#238#204#204#239#255#255#254#206#239#254#206#236 +#238#206#236#239#255#255#254#206#238#254#206#236#238#206#236#239#255#255#255 +#236#204#238#206#236#239#236#206#255#255#255#255#254#238#255#239#254#255#254 +#239#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); LazarusResources.Add('TDCP_TIGER','BMP',[ 'BM'#150#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#4#0#0#0#0#0' ' +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128 +#0#128#0#0#0#128#0#128#0#128#128#0#0#128#128#128#0#192#192#192#0#0#0#255#0#0 +#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#254#255#238#239#238#239#238#239#238#239#255#255#236#238#204#206#204#206#204 +#206#206#206#255#255#236#239#236#238#206#206#206#238#206#206#255#255#236#239 +#236#238#206#206#206#238#206#206#255#255#236#239#236#238#204#238#204#206#204 +#239#255#255#236#239#236#238#206#238#206#238#206#206#255#255#236#239#236#238 +#206#206#206#238#206#206#255#254#204#206#204#206#204#206#204#206#204#239#255 +#255#238#239#238#239#238#239#238#239#238#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 +#255 ]); doublecmd-0.8.2/components/dcpcrypt/dcpcrypt2.pas0000664000175000017500000005206111652036011021140 0ustar alexxalexx{******************************************************************************} {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********} {******************************************************************************} {* Main component definitions *************************************************} {******************************************************************************} {* Copyright (c) 1999-2003 David Barton *} {* Permission is hereby granted, free of charge, to any person obtaining a *} {* copy of this software and associated documentation files (the "Software"), *} {* to deal in the Software without restriction, including without limitation *} {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *} {* and/or sell copies of the Software, and to permit persons to whom the *} {* Software is furnished to do so, subject to the following conditions: *} {* *} {* The above copyright notice and this permission notice shall be included in *} {* all copies or substantial portions of the Software. *} {* *} {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *} {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *} {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *} {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *} {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *} {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *} {* DEALINGS IN THE SOFTWARE. *} {******************************************************************************} unit DCPcrypt2; {$MODE Delphi} interface uses Classes, Sysutils, DCPbase64; //{$DEFINE DCP1COMPAT} { DCPcrypt v1.31 compatiblity mode - see documentation } {******************************************************************************} { A few predefined types to help out } type {$IFNDEF FPC} Pbyte= ^byte; Pword= ^word; Pdword= ^dword; Pint64= ^int64; dword= longword; Pwordarray= ^Twordarray; Twordarray= array[0..19383] of word; {$ENDIF} Pdwordarray= ^Tdwordarray; Tdwordarray= array[0..8191] of dword; {******************************************************************************} { The base class from which all hash algorithms are to be derived } type EDCP_hash= class(Exception); TDCP_hash= class(TComponent) protected fInitialized: boolean; { Whether or not the algorithm has been initialized } procedure DeadInt(Value: integer); { Knudge to display vars in the object inspector } procedure DeadStr(Value: string); { Knudge to display vars in the object inspector } private function _GetId: integer; function _GetAlgorithm: string; function _GetHashSize: integer; public property Initialized: boolean read fInitialized; class function GetId: integer; virtual; { Get the algorithm id } class function GetAlgorithm: string; virtual; { Get the algorithm name } class function GetHashSize: integer; virtual; { Get the size of the digest produced - in bits } class function SelfTest: boolean; virtual; { Tests the implementation with several test vectors } procedure Init; virtual; { Initialize the hash algorithm } procedure Final(var Digest); virtual; { Create the final digest and clear the stored information. The size of the Digest var must be at least equal to the hash size } procedure Burn; virtual; { Clear any stored information with out creating the final digest } procedure Update(const Buffer; Size: longword); virtual; { Update the hash buffer with Size bytes of data from Buffer } procedure UpdateStream(Stream: TStream; Size: longword); { Update the hash buffer with Size bytes of data from the stream } procedure UpdateStr(const Str: string); { Update the hash buffer with the string } destructor Destroy; override; published property Id: integer read _GetId write DeadInt; property Algorithm: string read _GetAlgorithm write DeadStr; property HashSize: integer read _GetHashSize write DeadInt; end; TDCP_hashclass= class of TDCP_hash; {******************************************************************************} { The base class from which all encryption components will be derived. } { Stream ciphers will be derived directly from this class where as } { Block ciphers will have a further foundation class TDCP_blockcipher. } type EDCP_cipher= class(Exception); TDCP_cipher= class(TComponent) protected fInitialized: boolean; { Whether or not the key setup has been done yet } procedure DeadInt(Value: integer); { Knudge to display vars in the object inspector } procedure DeadStr(Value: string); { Knudge to display vars in the object inspector } private function _GetId: integer; function _GetAlgorithm: string; function _GetMaxKeySize: integer; public property Initialized: boolean read fInitialized; class function GetId: integer; virtual; { Get the algorithm id } class function GetAlgorithm: string; virtual; { Get the algorithm name } class function GetMaxKeySize: integer; virtual; { Get the maximum key size (in bits) } class function SelfTest: boolean; virtual; { Tests the implementation with several test vectors } procedure Init(const Key; Size: longword; InitVector: pointer); virtual; { Do key setup based on the data in Key, size is in bits } procedure InitStr(const Key: string; HashType: TDCP_hashclass); { Do key setup based on a hash of the key string } procedure Burn; virtual; { Clear all stored key information } procedure Reset; virtual; { Reset any stored chaining information } procedure Encrypt(const Indata; var Outdata; Size: longword); virtual; { Encrypt size bytes of data and place in Outdata } procedure Decrypt(const Indata; var Outdata; Size: longword); virtual; { Decrypt size bytes of data and place in Outdata } function EncryptStream(InStream, OutStream: TStream; Size: longword): longword; { Encrypt size bytes of data from InStream and place in OutStream } function DecryptStream(InStream, OutStream: TStream; Size: longword): longword; { Decrypt size bytes of data from InStream and place in OutStream } function EncryptString(const Str: string): string; virtual; { Encrypt a string and return Base64 encoded } function DecryptString(const Str: string): string; virtual; { Decrypt a Base64 encoded string } constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property Id: integer read _GetId write DeadInt; property Algorithm: string read _GetAlgorithm write DeadStr; property MaxKeySize: integer read _GetMaxKeySize write DeadInt; end; TDCP_cipherclass= class of TDCP_cipher; {******************************************************************************} { The base class from which all block ciphers are to be derived, this } { extra class takes care of the different block encryption modes. } type TDCP_ciphermode= (cmCBC, cmCFB8bit, cmCFBblock, cmOFB, cmCTR); // cmCFB8bit is equal to DCPcrypt v1.xx's CFB mode EDCP_blockcipher= class(EDCP_cipher); TDCP_blockcipher= class(TDCP_cipher) protected fCipherMode: TDCP_ciphermode; { The cipher mode the encrypt method uses } procedure InitKey(const Key; Size: longword); virtual; private function _GetBlockSize: integer; public class function GetBlockSize: integer; virtual; { Get the block size of the cipher (in bits) } procedure SetIV(const Value); virtual; { Sets the IV to Value and performs a reset } procedure GetIV(var Value); virtual; { Returns the current chaining information, not the actual IV } procedure Encrypt(const Indata; var Outdata; Size: longword); override; { Encrypt size bytes of data and place in Outdata using CipherMode } procedure Decrypt(const Indata; var Outdata; Size: longword); override; { Decrypt size bytes of data and place in Outdata using CipherMode } function EncryptString(const Str: string): string; override; { Encrypt a string and return Base64 encoded } function DecryptString(const Str: string): string; override; { Decrypt a Base64 encoded string } procedure EncryptECB(const Indata; var Outdata); virtual; { Encrypt a block of data using the ECB method of encryption } procedure DecryptECB(const Indata; var Outdata); virtual; { Decrypt a block of data using the ECB method of decryption } procedure EncryptCBC(const Indata; var Outdata; Size: longword); virtual; { Encrypt size bytes of data using the CBC method of encryption } procedure DecryptCBC(const Indata; var Outdata; Size: longword); virtual; { Decrypt size bytes of data using the CBC method of decryption } procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword); virtual; { Encrypt size bytes of data using the CFB (8 bit) method of encryption } procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword); virtual; { Decrypt size bytes of data using the CFB (8 bit) method of decryption } procedure EncryptCFBblock(const Indata; var Outdata; Size: longword); virtual; { Encrypt size bytes of data using the CFB (block) method of encryption } procedure DecryptCFBblock(const Indata; var Outdata; Size: longword); virtual; { Decrypt size bytes of data using the CFB (block) method of decryption } procedure EncryptOFB(const Indata; var Outdata; Size: longword); virtual; { Encrypt size bytes of data using the OFB method of encryption } procedure DecryptOFB(const Indata; var Outdata; Size: longword); virtual; { Decrypt size bytes of data using the OFB method of decryption } procedure EncryptCTR(const Indata; var Outdata; Size: longword); virtual; { Encrypt size bytes of data using the CTR method of encryption } procedure DecryptCTR(const Indata; var Outdata; Size: longword); virtual; { Decrypt size bytes of data using the CTR method of decryption } constructor Create(AOwner: TComponent); override; published property BlockSize: integer read _GetBlockSize write DeadInt; property CipherMode: TDCP_ciphermode read fCipherMode write fCipherMode default cmCBC; end; TDCP_blockcipherclass= class of TDCP_blockcipher; {******************************************************************************} { Helper functions } procedure XorBlock(var InData1, InData2; Size: longword); // Supposed to be an optimized version of XorBlock() using 32-bit xor procedure XorBlockEx(var InData1, InData2; Size: longword); // removes the compiler hint due to first param being 'var' instead of 'out' procedure dcpFillChar(out x; count: SizeInt; Value: Byte); overload; procedure dcpFillChar(out x; count: SizeInt; Value: Char); overload; procedure ZeroMemory(Destination: Pointer; Length: PtrUInt); implementation {$Q-}{$R-} {** TDCP_hash *****************************************************************} procedure TDCP_hash.DeadInt(Value: integer); begin end; procedure TDCP_hash.DeadStr(Value: string); begin end; function TDCP_hash._GetId: integer; begin Result:= GetId; end; function TDCP_hash._GetAlgorithm: string; begin Result:= GetAlgorithm; end; function TDCP_hash._GetHashSize: integer; begin Result:= GetHashSize; end; class function TDCP_hash.GetId: integer; begin Result:= -1; end; class function TDCP_hash.GetAlgorithm: string; begin Result:= ''; end; class function TDCP_hash.GetHashSize: integer; begin Result:= -1; end; class function TDCP_hash.SelfTest: boolean; begin Result:= false; end; procedure TDCP_hash.Init; begin end; procedure TDCP_hash.Final(var Digest); begin end; procedure TDCP_hash.Burn; begin end; procedure TDCP_hash.Update(const Buffer; Size: longword); begin end; procedure TDCP_hash.UpdateStream(Stream: TStream; Size: longword); var Buffer: array[0..8191] of byte; i, read: integer; begin dcpFillChar(Buffer, SizeOf(Buffer), 0); for i:= 1 to (Size div Sizeof(Buffer)) do begin read:= Stream.Read(Buffer,Sizeof(Buffer)); Update(Buffer,read); end; if (Size mod Sizeof(Buffer))<> 0 then begin read:= Stream.Read(Buffer,Size mod Sizeof(Buffer)); Update(Buffer,read); end; end; procedure TDCP_hash.UpdateStr(const Str: string); begin Update(Str[1],Length(Str)); end; destructor TDCP_hash.Destroy; begin if fInitialized then Burn; inherited Destroy; end; {** TDCP_cipher ***************************************************************} procedure TDCP_cipher.DeadInt(Value: integer); begin end; procedure TDCP_cipher.DeadStr(Value: string); begin end; function TDCP_cipher._GetId: integer; begin Result:= GetId; end; function TDCP_cipher._GetAlgorithm: string; begin Result:= GetAlgorithm; end; function TDCP_cipher._GetMaxKeySize: integer; begin Result:= GetMaxKeySize; end; class function TDCP_cipher.GetId: integer; begin Result:= -1; end; class function TDCP_cipher.GetAlgorithm: string; begin Result:= ''; end; class function TDCP_cipher.GetMaxKeySize: integer; begin Result:= -1; end; class function TDCP_cipher.SelfTest: boolean; begin Result:= false; end; procedure TDCP_cipher.Init(const Key; Size: longword; InitVector: pointer); begin if fInitialized then Burn; if (Size <= 0) or ((Size and 3)<> 0) or (Size> longword(GetMaxKeySize)) then raise EDCP_cipher.Create('Invalid key size') else fInitialized:= true; end; procedure TDCP_cipher.InitStr(const Key: string; HashType: TDCP_hashclass); var Hash: TDCP_hash; Digest: pointer; begin if fInitialized then Burn; try GetMem(Digest,HashType.GetHashSize div 8); Hash:= HashType.Create(Self); Hash.Init; Hash.UpdateStr(Key); Hash.Final(Digest^); Hash.Free; if MaxKeySize< HashType.GetHashSize then begin Init(Digest^,MaxKeySize,nil); end else begin Init(Digest^,HashType.GetHashSize,nil); end; FillChar(Digest^,HashType.GetHashSize div 8,$FF); FreeMem(Digest); except raise EDCP_cipher.Create('Unable to allocate sufficient memory for hash digest'); end; end; procedure TDCP_cipher.Burn; begin fInitialized:= false; end; procedure TDCP_cipher.Reset; begin end; procedure TDCP_cipher.Encrypt(const Indata; var Outdata; Size: longword); begin end; procedure TDCP_cipher.Decrypt(const Indata; var Outdata; Size: longword); begin end; function TDCP_cipher.EncryptStream(InStream, OutStream: TStream; Size: longword): longword; var Buffer: array[0..8191] of byte; i, Read: longword; begin dcpFillChar(Buffer, SizeOf(Buffer), 0); Result:= 0; for i:= 1 to (Size div Sizeof(Buffer)) do begin Read:= InStream.Read(Buffer,Sizeof(Buffer)); Inc(Result,Read); Encrypt(Buffer,Buffer,Read); OutStream.Write(Buffer,Read); end; if (Size mod Sizeof(Buffer))<> 0 then begin Read:= InStream.Read(Buffer,Size mod Sizeof(Buffer)); Inc(Result,Read); Encrypt(Buffer,Buffer,Read); OutStream.Write(Buffer,Read); end; end; function TDCP_cipher.DecryptStream(InStream, OutStream: TStream; Size: longword): longword; var Buffer: array[0..8191] of byte; i, Read: longword; begin dcpFillChar(Buffer, SizeOf(Buffer), 0); Result:= 0; for i:= 1 to (Size div Sizeof(Buffer)) do begin Read:= InStream.Read(Buffer,Sizeof(Buffer)); Inc(Result,Read); Decrypt(Buffer,Buffer,Read); OutStream.Write(Buffer,Read); end; if (Size mod Sizeof(Buffer))<> 0 then begin Read:= InStream.Read(Buffer,Size mod Sizeof(Buffer)); Inc(Result,Read); Decrypt(Buffer,Buffer,Read); OutStream.Write(Buffer,Read); end; end; function TDCP_cipher.EncryptString(const Str: string): string; begin SetLength(Result,Length(Str)); Encrypt(Str[1],Result[1],Length(Str)); Result:= Base64EncodeStr(Result); end; function TDCP_cipher.DecryptString(const Str: string): string; begin Result:= Base64DecodeStr(Str); Decrypt(Result[1],Result[1],Length(Result)); end; constructor TDCP_cipher.Create(AOwner: TComponent); begin inherited Create(AOwner); Burn; end; destructor TDCP_cipher.Destroy; begin if fInitialized then Burn; inherited Destroy; end; {** TDCP_blockcipher **********************************************************} procedure TDCP_blockcipher.InitKey(const Key; Size: longword); begin end; function TDCP_blockcipher._GetBlockSize: integer; begin Result:= GetBlockSize; end; class function TDCP_blockcipher.GetBlockSize: integer; begin Result:= -1; end; procedure TDCP_blockcipher.SetIV(const Value); begin end; procedure TDCP_blockcipher.GetIV(var Value); begin end; procedure TDCP_blockcipher.Encrypt(const Indata; var Outdata; Size: longword); begin case fCipherMode of cmCBC: EncryptCBC(Indata,Outdata,Size); cmCFB8bit: EncryptCFB8bit(Indata,Outdata,Size); cmCFBblock: EncryptCFBblock(Indata,Outdata,Size); cmOFB: EncryptOFB(Indata,Outdata,Size); cmCTR: EncryptCTR(Indata,Outdata,Size); end; end; function TDCP_blockcipher.EncryptString(const Str: string): string; begin SetLength(Result,Length(Str)); EncryptCFB8bit(Str[1],Result[1],Length(Str)); Result:= Base64EncodeStr(Result); end; function TDCP_blockcipher.DecryptString(const Str: string): string; begin Result:= Base64DecodeStr(Str); DecryptCFB8bit(Result[1],Result[1],Length(Result)); end; procedure TDCP_blockcipher.Decrypt(const Indata; var Outdata; Size: longword); begin case fCipherMode of cmCBC: DecryptCBC(Indata,Outdata,Size); cmCFB8bit: DecryptCFB8bit(Indata,Outdata,Size); cmCFBblock: DecryptCFBblock(Indata,Outdata,Size); cmOFB: DecryptOFB(Indata,Outdata,Size); cmCTR: DecryptCTR(Indata,Outdata,Size); end; end; procedure TDCP_blockcipher.EncryptECB(const Indata; var Outdata); begin end; procedure TDCP_blockcipher.DecryptECB(const Indata; var Outdata); begin end; procedure TDCP_blockcipher.EncryptCBC(const Indata; var Outdata; Size: longword); begin end; procedure TDCP_blockcipher.DecryptCBC(const Indata; var Outdata; Size: longword); begin end; procedure TDCP_blockcipher.EncryptCFB8bit(const Indata; var Outdata; Size: longword); begin end; procedure TDCP_blockcipher.DecryptCFB8bit(const Indata; var Outdata; Size: longword); begin end; procedure TDCP_blockcipher.EncryptCFBblock(const Indata; var Outdata; Size: longword); begin end; procedure TDCP_blockcipher.DecryptCFBblock(const Indata; var Outdata; Size: longword); begin end; procedure TDCP_blockcipher.EncryptOFB(const Indata; var Outdata; Size: longword); begin end; procedure TDCP_blockcipher.DecryptOFB(const Indata; var Outdata; Size: longword); begin end; procedure TDCP_blockcipher.EncryptCTR(const Indata; var Outdata; Size: longword); begin end; procedure TDCP_blockcipher.DecryptCTR(const Indata; var Outdata; Size: longword); begin end; constructor TDCP_blockcipher.Create(AOwner: TComponent); begin inherited Create(AOwner); fCipherMode:= cmCBC; end; {** Helpher functions *********************************************************} procedure XorBlock(var InData1, InData2; Size: longword); var b1: PByteArray; b2: PByteArray; i: longword; begin b1 := @InData1; b2 := @InData2; for i := 0 to size-1 do b1[i] := b1[i] xor b2[i]; end; procedure dcpFillChar(out x; count: SizeInt; Value: Byte); begin {$HINTS OFF} FillChar(x, count, value); {$HINTS ON} end; procedure ZeroMemory(Destination: Pointer; Length: PtrUInt); begin FillChar(Destination^, Length, 0); end; procedure dcpFillChar(out x; count: SizeInt; Value: Char); begin {$HINTS OFF} FillChar(x, count, Value); {$HINTS ON} end; // Supposed to be an optimized version of XorBlock() using 32-bit xor procedure XorBlockEx(var InData1, InData2; Size: longword); var l1: PIntegerArray; l2: PIntegerArray; b1: PByteArray; b2: PByteArray; i: integer; c: integer; begin l1 := @inData1; l2 := @inData2; for i := 0 to size div sizeof(LongWord)-1 do l1[i] := l1[i] xor l2[i]; // the rest of the buffer (3 bytes) c := size mod sizeof(longWord); if c > 0 then begin b1 := @InData1; b2 := @InData2; for i := (size-c) to size-1 do b1[i] := b1[i] xor b2[i]; end; end; end. doublecmd-0.8.2/components/synunihighlighter/0000775000175000017500000000000013244011205020426 5ustar alexxalexxdoublecmd-0.8.2/components/synunihighlighter/synuni.lpk0000664000175000017500000000453413056774146022516 0ustar alexxalexx doublecmd-0.8.2/components/synunihighlighter/synuni.pas0000664000175000017500000000036513056774146022511 0ustar alexxalexx{ This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package. } unit SynUni; interface uses SynUniClasses, SynUniHighlighter, SynUniRules; implementation end. doublecmd-0.8.2/components/synunihighlighter/source/0000775000175000017500000000000013244011205021726 5ustar alexxalexxdoublecmd-0.8.2/components/synunihighlighter/source/SynUniHighlighter.pas0000664000175000017500000012013313161144471026051 0ustar alexxalexx{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is: SynUniHighlighter.pas, released 2003-01 All Rights Reserved. Alternatively, the contents of this file may be used under the terms of the GNU General Public License Version 2 or later (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. }{ @abstract(Provides a universal highlighter for SynEdit) @authors(Fantasist [walking_in_the_sky@yahoo.com], Vit [nevzorov@yahoo.com], Vitalik [vetal-x@mail.ru]) @created(2003) @lastmod(2004-05-12) } (****************************************************************************** Authors: Fantasist (Kirill Burtsev walking_in_the_sky@yahoo.com) Vit (Vitaly Nevzorov nevzorov@yahoo.com) Vitalik (Vitaly Lyapota vetal-x@mail.ru) Official Site: www.delphist.com With all questions, please visit www.delphist.com/forum ******************************************************************************) unit SynUniHighlighter; {$mode delphi} interface uses SysUtils, Classes, Graphics, SynEditTypes, SynEditHighlighter, SynUniClasses, SynUniRules, Laz2_DOM; Const _Root = 'Root'; _New = 'New'; type { TSynUniSyn } TSynUniSyn = class(TSynCustomHighlighter) private procedure ReadSyntax(Reader: TReader); procedure WriteSyntax(Writer: TWriter); protected fMainRules: TSynRange; fEol: boolean; fPrEol: boolean; fLine: PChar; fTrueLine: String; fLineNumber: Integer; Run: LongInt; fTokenPos: Integer; fCurrToken: TSynSymbol; fCurrentRule: TSynRange; SymbolList: array[char] of TAbstractSymbol; //??? fPrepared: boolean; fSchemes: TStringList; //Vitalik 2004 fSchemeIndex: integer; //Vitalik 2004 fImportFormats: TList; procedure SpaceProc; procedure NullProc; function GetIdentChars: TSynIdentChars; override; procedure DefineProperties(Filer: TFiler); override; function GetSampleSource: string; override; procedure SetSampleSource(Value: string); override; public class function GetLanguageName: string; override; public constructor Create(AOwner: TComponent); overload; override; destructor Destroy; override; function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; override; {Abstract} function GetEol: Boolean; override; {Abstract} function GetRange: Pointer; override; function GetToken: string; override; {Abstract} procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override; {Abstract} function GetTokenAttribute: TSynHighlighterAttributes; override; {Abstract} function GetTokenID: Integer; function GetTokenKind: integer; override; {Abstract} function GetTokenPos: Integer; override; {Abstract} function IsKeyword(const AKeyword: string): boolean; override; procedure Next; override; {Abstract} procedure ResetRange; override; procedure SetLine(const NewValue: string; LineNumber: Integer); override; {Abstract} procedure SetRange(Value: Pointer); override; procedure Reset; procedure Clear; procedure Prepare; procedure CreateStandardRules; procedure ReadSchemes(xml: TDOMNode); procedure ReadInfo(xml: TDOMNode); procedure LoadHglFromXml(xml: TDOMNode); procedure LoadHglFromStream(Stream: TStream); procedure LoadHglFromFile(FileName: string); procedure SaveHglToStream(Stream: TStream); procedure SaveHglToFile(FileName: string); procedure LoadFromXml(xml: TDOMNode); procedure LoadFromStream(Stream: TStream; FreeStream: boolean = True); procedure LoadFromFile(FileName: string); function GetAsStream: TMemoryStream; procedure SaveToStream(Stream: TStream; Rule: TSynRule = nil); procedure SaveToFile(FileName: string; Rule: TSynRule = nil); public Info: TSynInfo; Styles: TSynUniStyles; SchemeFileName: string; SchemeName: string; property MainRules: TSynRange read fMainRules; property SchemesList: TStringList read fSchemes write fSchemes; //Vitalik 2004 property SchemeIndex: integer read fSchemeIndex write fSchemeIndex; //Vitalik 2004 end; implementation uses LazUTF8Classes, Laz2_XMLRead; const SYNS_AttrTest = 'Test'; //==== TSynUniSyn ============================================================ constructor TSynUniSyn.Create(AOwner: TComponent); var fTestAttri: TSynHighlighterAttributes; begin inherited Create(AOwner); Info := TSynInfo.Create; Info.History := TStringList.Create; Info.Sample := TStringList.Create; fPrepared := False; //Вот так вот нужно все атрибуты будет добавлять! Потому как нужно еще и обработать [Underline + Italic] fTestAttri := TSynHighLighterAttributes.Create(SYNS_AttrTest); fTestAttri.Style := [fsUnderline, fsItalic]; fTestAttri.Foreground := clBlue; fTestAttri.Background := clSilver; AddAttribute(fTestAttri); fSchemes := TStringList.Create; fSchemeIndex := -1; fMainRules := TSynRange.Create; MainRules.Name := _Root; fEol := False; fPrEol := False; fCurrentRule := MainRules; // AddNewScheme('Noname'); fImportFormats := TList.Create; end; destructor TSynUniSyn.Destroy; //: Destructor of TSynUniSyn begin MainRules.Free; Info.History.Free; Info.Sample.Free; Info.Free; fSchemes.Free; fImportFormats.Free; inherited; end; procedure TSynUniSyn.SetLine(const NewValue: string; LineNumber: Integer); //: Set current line in SynEdit for highlighting function HaveNodeAnyStart(Node: TSymbolNode): boolean; var i: integer; begin Result := False; if Node.StartType = stAny then begin Result := True; Exit; end; for i := 0 to Node.NextSymbs.Count-1 do if (Node.NextSymbs.Nodes[i].StartType = stAny) or HaveNodeAnyStart(Node.NextSymbs.Nodes[i]) then begin Result := True; Exit; end end; var i: integer; begin if LineNumber = 1 then begin MainRules.ResetParents(MainRules); MainRules.ClearParsingFields(); end; if not fCurrentRule.Prepared then begin //: If current Range isn't prepared, Prepare; //: then prepare it and its sub-ranges (*{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ !!!!!!! Это я писал и это зачем-то нужно !!!!!!!!!!!!!!!!!!!!!!!!*) for i := 0 to 255 do if (SymbolList[char(i)] <> nil) {temp}and (TSymbols(SymbolList[char(i)]).HeadNode <> nil){/temp} then fCurrentRule.HasNodeAnyStart[char(i)] := HaveNodeAnyStart(TSymbols(SymbolList[fCurrentRule.CaseFunct(char(i))]).HeadNode); (*}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}*) end; {begin} //Vitalik 2004 {was: fTrueLine := PChar(NewValue); l := Length(NewValue); ReallocMem(fLine, l+1); for i := 0 to l do fLine[i] := fCurrentRule.CaseFunct(fTrueLine[i]); } fTrueLine := NewValue; fLine := PChar(NewValue); //: Current string of SynEdit {end} //Vitalik 2004 Run := 0; //: Set Position of "parser" at the first char of string fTokenPos := 0; //: Set Position of current token at the first char of string fLineNumber := LineNumber; //: Number of current line in SynEdit fEol := False; //: ??? fPrEol := False; //: ??? Next; //: Find first token in the line end; procedure TSynUniSyn.Next; //: Goes to the next token and open/close ranges var ParentCycle, CurrentParent: TSynRange; RangeLink: TSynRangeLink; isFindSame: boolean; begin if fPrEol then //: if it was end of line then begin //: if current range close on end of line then if (fCurrentRule.fRule.fCloseOnEol) or (fCurrentRule.fRule.fCloseOnTerm) then begin if fCurrentRule.OpenCount > 0 then fCurrentRule.OpenCount := fCurrentRule.OpenCount - 1 else if fCurrentRule.ParentBackup <> nil then fCurrentRule.Parent := fCurrentRule.ParentBackup; if fCurrentRule.fRule.fAllowPredClose then begin fCurrentRule := fCurrentRule.Parent; while (fCurrentRule.fRule.fCloseOnEol) or (fCurrentRule.fRule.fCloseOnTerm) do fCurrentRule := fCurrentRule.Parent; end else fCurrentRule := fCurrentRule.Parent; end; fEol := True; //: ??? Exit; end; fTokenPos := Run; //: Start of cf current token is end of previsious //: if current range close on delimeter and current symbol is delimeter then if (fCurrentRule.fRule.fCloseOnTerm) and (fLine[Run] in fCurrentRule.fTermSymbols) then begin if fCurrentRule.OpenCount > 0 then fCurrentRule.OpenCount := fCurrentRule.OpenCount - 1 else if fCurrentRule.ParentBackup <> nil then fCurrentRule.Parent := fCurrentRule.ParentBackup; if fCurrentRule.fRule.fAllowPredClose then begin fCurrentRule := fCurrentRule.Parent; while (fCurrentRule.fRule.fCloseOnTerm) do fCurrentRule := fCurrentRule.Parent; end else fCurrentRule := fCurrentRule.Parent; end; //: if we can't find token from current position: if not fCurrentRule.SymbolList[fCurrentRule.CaseFunct(fLine[Run])].GetToken(fCurrentRule, fLine, Run, fCurrToken) then //Vitalik 2004 begin fCurrToken := fCurrentRule.fDefaultSynSymbol; //: Current token is just default symbol while not ((fLine[Run] in fCurrentRule.fTermSymbols) or fCurrentRule.HasNodeAnyStart[fCurrentRule.CaseFunct(fLine[Run])]) do inc(Run); //: goes to the first non-delimeter symbol end else //: else (we find token!) if (fCurrentRule.fClosingSymbol = fCurrToken) then begin //: if current token close current range // if (fCurrentRule.fClosingSymbol <> nil) and (fCurrentRule.fClosingSymbol.Symbol = fCurrToken.Symbol) then if fCurrentRule.OpenCount > 0 then fCurrentRule.OpenCount := fCurrentRule.OpenCount - 1 else if fCurrentRule.ParentBackup <> nil then fCurrentRule.Parent := fCurrentRule.ParentBackup; if fCurrentRule.fRule.fAllowPredClose then begin fCurrentRule := fCurrentRule.Parent; while (fCurrentRule.fClosingSymbol <> nil) and (fCurrentRule.fClosingSymbol.Symbol = fCurrToken.Symbol) do fCurrentRule := fCurrentRule.Parent; end else fCurrentRule := fCurrentRule.Parent end else if fCurrToken.fOpenRule <> nil then begin //: else if current token open range then CurrentParent := fCurrentRule; if fCurrToken.fOpenRule is TSynRangeLink then begin RangeLink := TSynRangeLink(fCurrToken.fOpenRule); fCurrentRule := RangeLink.Range; ParentCycle := CurrentParent; isFindSame := False; while ParentCycle <> nil do begin // Ищем есть ли у тек. правила такой же родитель if ParentCycle = fCurrentRule then begin if RangeLink.Range.OpenCount = 0 then begin // Первое открытие вложенного в себя правила. fCurrentRule.ParentBackup := RangeLink.Range.Parent; fCurrentRule.Parent := CurrentParent; RangeLink.Range.OpenCount := 1; end else begin RangeLink.Range.OpenCount := RangeLink.Range.OpenCount + 1; end; isFindSame := True; break; end; ParentCycle := ParentCycle.Parent; end; if not isFindSame then begin { fCurrentRule.ParentBackup := RangeLink.Range.Parent; fCurrentRule.Parent := CurrentParent; RangeLink.Range.OpenCount := 1; // fCurrentRule.Parent := RangeLink.Parent;} end end else if fCurrToken.fOpenRule is TSynRange then begin fCurrentRule := TSynRange(fCurrToken.fOpenRule); //: open range fCurrentRule.Parent := CurrentParent; end; end; if fLine[Run] = #0 then //: If end of line fPrEol := True; //: ??? end; procedure TSynUniSyn.SpaceProc; //! Never used!!! SSS begin repeat Inc(Run); until (fLine[Run] > #32) or (fLine[Run] in [#0, #10, #13]); end; function TSynUniSyn.IsKeyword(const aKeyword: string): boolean; //! Never used!!!! ??? SSS begin // Result := fSymbols.FindSymbol(aKeyword) <> nil; end; function TSynUniSyn.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; //: Returns default attribute //: Неопнятно зачем это нужно, но функция предка - абстрактная (может что-нить с ней сделать...) begin case Index of SYN_ATTR_COMMENT: Result := fCurrentRule.Attribs; SYN_ATTR_IDENTIFIER: Result := fCurrentRule.Attribs; SYN_ATTR_KEYWORD: Result := fCurrentRule.Attribs; SYN_ATTR_STRING: Result := fCurrentRule.Attribs; SYN_ATTR_WHITESPACE: Result := fCurrentRule.Attribs; else Result := nil; end; end; function TSynUniSyn.GetEol: Boolean; begin Result := fEol; end; function TSynUniSyn.GetRange: Pointer; //: Returns current Range begin Result := fCurrentRule; end; function TSynUniSyn.GetToken: string; //: Returns current token (string from fTokenPos to Run) var Len: LongInt; begin Len := Run - fTokenPos; Setstring(Result, (fLine + fTokenPos), Len); end; procedure TSynUniSyn.GetTokenEx(out TokenStart: PChar; out TokenLength: integer); begin TokenLength := Run - fTokenPos; TokenStart := PAnsiChar(fTrueLine) + fTokenPos; end; function TSynUniSyn.GetTokenID: Integer; //: Return ID of current token //: ??? Оставлена для непонятной совместимости? Нигде же не вызывается и не используется! //: Можено что-нить с ней сделать... begin Result := 1; //# CODE_REVIEW fCurrToken.ID; end; function TSynUniSyn.GetTokenAttribute: TSynHighlighterAttributes; //: Returns attribute of current token begin // fCurrToken.Attr.Style := fCurrToken.Attr.Style + [fsUnderline]; // if GetEol then // Result := nil Result := fCurrToken.Attributes; end; function TSynUniSyn.GetTokenKind: integer; //~ Можно в Kind у токена fCurrToken хранить что это ?: слово или Range или Set begin Result := 1; //# CODE_REVIEW fCurrToken.ID; end; function TSynUniSyn.GetTokenPos: Integer; //: Returns position of current token begin Result := fTokenPos; end; procedure TSynUniSyn.ResetRange; //: Reset current range to MainRules begin fCurrentRule := MainRules; end; procedure TSynUniSyn.SetRange(Value: Pointer); //: Set current range begin fCurrentRule := TSynRange(Value); end; class function TSynUniSyn.GetLanguageName: string; begin Result := 'UniLanguage'; end; procedure TSynUniSyn.Clear; begin MainRules.Clear; Info.Clear; end; procedure TSynUniSyn.CreateStandardRules; //: Create sample rools var r: TSynRange; kw: TSynKeyList; begin self.MainRules.Clear; self.MainRules.Attribs.Foreground := clBlack; self.MainRules.Attribs.Background := clWhite; self.MainRules.CaseSensitive := False; r := TSynRange.Create('''', ''''); r.Name := 'Strings ''..'''; r.Attribs.Foreground := clRed; r.Attribs.Background := clWhite; r.CaseSensitive := False; r.fRule.fOpenSymbol.BrakeType := btAny; self.MainRules.AddRange(r); r := TSynRange.Create('"', '"'); r.Name := 'Strings ".."'; r.Attribs.Foreground := clRed; r.Attribs.Background := clWhite; r.CaseSensitive := False; r.fRule.fOpenSymbol.BrakeType := btAny; self.MainRules.AddRange(r); r := TSynRange.Create('{', '}'); r.Name := 'Remarks {..}'; r.Attribs.Foreground := clNavy; r.Attribs.Background := clWhite; r.CaseSensitive := False; r.fRule.fOpenSymbol.BrakeType := btAny; self.MainRules.AddRange(r); r := TSynRange.Create('(*', '*)'); r.Name := 'Remarks (*..*)'; r.Attribs.Foreground := clNavy; r.Attribs.Background := clWhite; r.CaseSensitive := False; r.fRule.fOpenSymbol.BrakeType := btAny; self.MainRules.AddRange(r); r := TSynRange.Create('/*', '*/'); r.Name := 'Remarks /*..*/'; r.Attribs.Foreground := clNavy; r.Attribs.Background := clWhite; r.CaseSensitive := False; r.fRule.fOpenSymbol.BrakeType := btAny; self.MainRules.AddRange(r); kw := TSynKeyList.Create(''); kw.Name := 'Key words'; kw.Attribs.Foreground := clGreen; kw.Attribs.Background := clWhite; self.MainRules.AddKeyList(kw); end; procedure TSynUniSyn.Prepare; //: Prepare of SynUniSyn is Prepare of SynUniSyn.fMailRules function HaveNodeAnyStart(Node: TSymbolNode): boolean; var i: integer; begin Result := False; if Node.StartType = stAny then begin Result := True; Exit; end; for i := 0 to Node.NextSymbs.Count-1 do if (Node.NextSymbs.Nodes[i].StartType = stAny) or HaveNodeAnyStart(Node.NextSymbs.Nodes[i]) then begin Result := True; Exit; end end; var i: integer; begin MainRules.Prepare(MainRules); // for i := 0 to 255 do // if (MainRules.SymbolList[char(i)] <> MainRules.fDefaultTermSymbol) and (MainRules.SymbolList[char(i)] <> MainRules.fDefaultSymbols) then // MessageBox(0,PChar(TSymbols(MainRules.SymbolList[char(i)]).HeadNode.tkSynSymbol.Symbol),'1',0); for i := 0 to 255 do // if (MainRules.SymbolList[char(i)] <> nil) {temp}and (TSymbols(MainRules.SymbolList[char(i)]).HeadNode <> nil){/temp} then if (MainRules.SymbolList[char(i)] <> MainRules.fDefaultTermSymbol) and (MainRules.SymbolList[char(i)] <> MainRules.fDefaultSymbols) and (TSymbols(MainRules.SymbolList[char(i)]).HeadNode <> nil) then MainRules.HasNodeAnyStart[char(i)] := HaveNodeAnyStart(TSymbols(MainRules.SymbolList[MainRules.CaseFunct(char(i))]).HeadNode); end; procedure TSynUniSyn.NullProc; //: Never used!!! SSS ??? begin // fEol := True; end; procedure TSynUniSyn.Reset; //: Reset of SynUniSyn is Reset of SynUniSyn.MainRules begin MainRules.Reset; end; procedure TSynUniSyn.DefineProperties(Filer: TFiler); //! Never used ???? var iHasData: boolean; begin inherited; if Filer.Ancestor <> nil then iHasData := True else iHasData := MainRules.RangeCount > 0; Filer.DefineProperty( 'Syntax', ReadSyntax, WriteSyntax, {True}iHasData ); end; procedure TSynUniSyn.ReadSyntax(Reader: TReader); //: This is some metods for reading ??? ??? ??? var iBuffer: TStringStream; begin // iBuffer := nil; // try iBuffer := TStringStream.Create( Reader.ReadString ); iBuffer.Position := 0; LoadFromStream( iBuffer ); // finally // iBuffer.Free; // end; end; procedure TSynUniSyn.WriteSyntax(Writer: TWriter); //: This is some metods for writing ??? ??? ??? var iBuffer: TStringStream; begin iBuffer := TStringStream.Create( '' ); try SaveToStream( iBuffer ); iBuffer.Position := 0; Writer.WriteString( iBuffer.DataString ); finally iBuffer.Free; end; end; function TSynUniSyn.GetIdentChars: TSynIdentChars; //: Return IdentChars - hmm... What for ??? word selection? begin Result := [#32..#255] - fCurrentRule.TermSymbols; end; function TSynUniSyn.GetSampleSource: string; //: Get sample text begin Result := Info.Sample.Text; end; procedure TSynUniSyn.SetSampleSource(Value: string); //: Set sample text begin Info.Sample.Text := Value; end; procedure TSynUniSyn.LoadFromXml(xml: TDOMNode); var i, J, K: integer; ChildNode1, ChildNode2: TDOMNode; Key, Value: string; begin Clear; for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode1:= xml.ChildNodes.Item[J]; if SameText(ChildNode1.NodeName, 'UniHighlighter') then if ChildNode1.Attributes.Length = 0 then begin LoadHglFromXml(ChildNode1); Exit; end else begin for I := 0 to Int32(ChildNode1.ChildNodes.Count) - 1 do begin ChildNode2:= ChildNode1.ChildNodes.Item[I]; if SameText(ChildNode2.NodeName, 'Info') then Info.LoadFromXml(ChildNode2) else if SameText(ChildNode2.NodeName, 'Scheme') then begin SchemeFileName := ''; SchemeName := ''; for K := 0 to Int32(ChildNode2.Attributes.Length) - 1 do begin Key := ChildNode2.Attributes[K].NodeName; Value := ChildNode2.Attributes[K].NodeValue; if SameText('File', Key) then SchemeFileName := Value else if SameText('Name', Key) then SchemeName := Value; end; if FileExists(SchemeFileName) then begin if Styles <> nil then Styles.Free; Styles := TSynUniStyles.Create; Styles.FileName := SchemeFileName; Styles.Load; end; end else if SameText(ChildNode2.NodeName, 'Range') then begin // fMainRules.SetStyles(fStyles); fMainRules.Styles := Styles; fMainRules.LoadFromXml(ChildNode2); Break; end end; end; end end; procedure TSynUniSyn.LoadFromStream(Stream: TStream; FreeStream: boolean); var Len: Integer; Temp: PAnsiChar; Target: PAnsiChar; Source: PAnsiChar; Finish: PAnsiChar; Memory: PAnsiChar; Xml: TXMLDocument; TargetStream: TMemoryStream; begin TargetStream:= TMemoryStream.Create; try Len:= Stream.Size; Source:= GetMem(Len); TargetStream.SetSize(Len * 2); Stream.ReadBuffer(Source^, Len); Temp:= Source; Memory:= Source; Finish:= Temp + Len - 4; Target:= TargetStream.Memory; // Convert '&qt;' to '"' while (Temp < Finish) do begin if (Temp^ <> '&') then Inc(Temp, 1) else if ((Temp + 1)^ <> 'q') then Inc(Temp, 2) else if ((Temp + 2)^ <> 't') then Inc(Temp, 3) else begin Len:= (Temp - Source) + 2; Move(Source^, Target^, Len); Inc(Temp, 4); Inc(Target, Len); Move('uot;', Target^, 4); Inc(Target, 4); Source:= Temp; end; end; Len:= (Temp - Source) + 4; Move(Source^, Target^, Len); Inc(Target, Len); TargetStream.SetSize(Target - TargetStream.Memory); try TargetStream.Position:= 0; ReadXMLFile(Xml, TargetStream); LoadFromXml(Xml); finally DefHighlightChange(Self); end; finally TargetStream.Free; if FreeStream then Stream.Free; if (Memory <> nil) then FreeMem(Memory); end; end; procedure TSynUniSyn.LoadFromFile(FileName: string); begin LoadFromStream(TFileStreamUTF8.Create(FileName, fmOpenRead or fmShareDenyNone)); end; procedure TSynUniSyn.SaveToStream(Stream: TStream; Rule: TSynRule); var StreamWriter: TStreamWriter; begin StreamWriter := TStreamWriter.Create(Stream); with StreamWriter do begin WriteTag(0, 'UniHighlighter'); WriteParam('version', '1.8', CloseStartTag); Info.SaveToStream(StreamWriter, 2); WriteTag(2, 'Scheme'); WriteParam('File', SchemeFileName); WriteParam('Name', SchemeName, CloseEmptyTag); if Rule = nil then MainRules.SaveToStream(StreamWriter, 2) else Rule.SaveToStream(StreamWriter, 2); WriteTag(0, '/UniHighlighter', True); end; StreamWriter.Free; end; function TSynUniSyn.GetAsStream: TMemoryStream; begin Result := TMemoryStream.Create; SaveToStream(Result); end; procedure TSynUniSyn.SaveToFile(FileName: string; Rule: TSynRule); var F: TFileStream; begin if FileName = '' then raise exception.Create(ClassName + '.SaveToFile - FileName is empty'); F := TFileStream.Create(FileName, fmCreate); try SaveToStream(F, Rule) finally F.Free; end; end; function ReadValue(ANode: TDOMNode): String; begin if Assigned(ANode.FirstChild) then Result:= ANode.FirstChild.NodeValue else Result:= EmptyStr; end; procedure TSynUniSyn.SaveHglToStream(Stream: TStream); //: Save Highlighter to stream procedure WriteString(const aStr: string); begin Stream.Write( aStr[1], Length(aStr) ); Stream.Write( #10#13, 1 ); end; function Indent(i: integer): string; begin SetLength( Result, i ); FillChar( Result[1], i, #32 ); end; function GetValidValue(Value: string): string; begin Value := StringReplace(Value, '&', '&', [rfReplaceAll, rfIgnoreCase]); Value := StringReplace(Value, '<', '<', [rfReplaceAll, rfIgnoreCase]); Value := StringReplace(Value, '"', '"', [rfReplaceAll, rfIgnoreCase]); Result := StringReplace(Value, '>', '>', [rfReplaceAll, rfIgnoreCase]); end; procedure InsertTag(Ind: integer; Name: string; Value: string); begin WriteString( Format('%s<%s>%s', [Indent(Ind), Name, GetValidValue(Value), Name]) ); end; procedure OpenTag(Ind: integer; Name: string; Param: string = ''; ParamValue: string = ''); begin if Param = '' then WriteString(Format('%s<%s>', [Indent(Ind), Name])) else WriteString(Format('%s<%s %s="%s">', [Indent(Ind), Name, Param, GetValidValue(ParamValue)])); end; procedure SaveColor(MainTag: string; Ind, Fore, Back: integer; Style: TFontStyles; PFore, PBack: boolean); procedure InsertTagBool(Ind: integer; Name: string; Value: Boolean); begin if Value then WriteString(Format('%s<%s>True', [Indent(Ind), Name, Name])) else WriteString(Format('%s<%s>False', [Indent(Ind), Name, Name])) end; begin OpenTag(Ind, MainTag); InsertTag(Ind+1, 'Back', Inttostr(Back)); InsertTag(Ind+1, 'Fore', Inttostr(Fore)); InsertTag(Ind+1, 'Style', FontStyleToStr(Style)); InsertTagBool(Ind+1, 'ParentForeground', PFore); InsertTagBool(Ind+1, 'ParentBackground', PBack); OpenTag(Ind, '/'+MainTag); end; procedure SaveKWGroup(Ind: integer; G: TSynKeyList); var i: integer; procedure InsertTagBool(Ind: integer; Name: string; Value: Boolean); begin if Value then WriteString(Format('%s<%s>True', [Indent(Ind), Name, Name])) else WriteString(Format('%s<%s>False', [Indent(Ind), Name, Name])) end; begin OpenTag(Ind, 'KW', 'Name', G.Name); for i := 0 to fSchemes.Count-1 do begin G.ind := i; SaveColor('Attri', Ind+1, G.Attribs.Foreground, G.Attribs.Background, G.Attribs.Style, G.Attribs.ParentForeground, G.Attribs.ParentBackground); end; G.ind := fSchemeIndex; InsertTagBool(Ind+1, 'Enabled', G.Enabled); For i := 0 to G.KeyList.Count-1 do InsertTag(Ind+1, 'W', G.KeyList[i]); OpenTag(Ind, '/KW'); end; procedure SaveSet(Ind: integer; S: TSynSet); var i: integer; procedure InsertTagBool(Ind: integer; Name: string; Value: Boolean); begin if Value then WriteString(Format('%s<%s>True', [Indent(Ind), Name, Name])) else WriteString(Format('%s<%s>False', [Indent(Ind), Name, Name])) end; begin OpenTag(Ind, 'Set', 'Name', S.Name); for i := 0 to fSchemes.Count-1 do begin S.ind := i; SaveColor('Attri', Ind+1, S.Attribs.Foreground, S.Attribs.Background, S.Attribs.Style, S.Attribs.ParentForeground, S.Attribs.ParentBackground); end; S.ind := fSchemeIndex; InsertTagBool(Ind+1, 'Enabled', S.Enabled); { if S.StartType = stAny then if S.BrakeType = btAny then InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'True') else InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'Left') else if S.BrakeType = btAny then InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'Right') else InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'False');} InsertTag(Ind+1, 'S', SetToStr(S.SymbSet)); OpenTag(Ind, '/Set'); end; procedure SaveRange(Ind: integer; R: TSynRange); var i: integer; procedure InsertTagBool(Ind: integer; Name: string; Value: Boolean); begin if Value then WriteString(Format('%s<%s>True', [Indent(Ind), Name, Name])) else WriteString(Format('%s<%s>False', [Indent(Ind), Name, Name])) end; begin OpenTag(Ind, 'Range', 'Name', R.Name); for i := 0 to fSchemes.Count-1 do begin R.ind := i; SaveColor('Attri', Ind, R.Attribs.Foreground, R.Attribs.Background, R.Attribs.Style, R.Attribs.ParentForeground, R.Attribs.ParentBackground); end; R.ind := fSchemeIndex; InsertTagBool(Ind, 'Enabled', R.Enabled); if (Length(R.fRule.fOpenSymbol.Symbol) > 0) and (R.fRule.fOpenSymbol.Symbol[Length(R.fRule.fOpenSymbol.Symbol)] = #0) then begin InsertTag(Ind, 'OpenSymbol', copy(R.fRule.fOpenSymbol.Symbol,1,Length(R.fRule.fOpenSymbol.Symbol)-1)); InsertTagBool(Ind, 'OpenSymbolFinishOnEol', true); end else begin InsertTag(Ind, 'OpenSymbol', R.fRule.fOpenSymbol.Symbol); InsertTagBool(Ind, 'OpenSymbolFinishOnEol', false); end; if (Length(R.fRule.fCloseSymbol.Symbol) > 0) and (R.fRule.fCloseSymbol.Symbol[Length(R.fRule.fCloseSymbol.Symbol)] = #0) then begin InsertTag(Ind, 'CloseSymbol', copy(R.fRule.fCloseSymbol.Symbol,1,Length(R.fRule.fCloseSymbol.Symbol)-1)); InsertTagBool(Ind, 'CloseSymbolFinishOnEol', true); end else begin InsertTag(Ind, 'CloseSymbol', R.fRule.fCloseSymbol.Symbol); InsertTagBool(Ind, 'CloseSymbolFinishOnEol', false); end; if R.fRule.fOpenSymbol.StartLine = slFirst then InsertTag(Ind, 'OpenSymbolStartLine', 'True') else if R.fRule.fOpenSymbol.StartLine = slFirstNonSpace then InsertTag(Ind, 'OpenSymbolStartLine', 'NonSpace') else InsertTag(Ind, 'OpenSymbolStartLine', 'False'); if R.fRule.fCloseSymbol.StartLine = slFirst then InsertTag(Ind, 'CloseSymbolStartLine', 'True') else if R.fRule.fCloseSymbol.StartLine = slFirstNonSpace then InsertTag(Ind, 'CloseSymbolStartLine', 'NonSpace') else InsertTag(Ind, 'CloseSymbolStartLine', 'False'); InsertTag(Ind, 'DelimiterChars', SetToStr(R.TermSymbols)); if R.fRule.fOpenSymbol.StartType = stAny then if R.fRule.fOpenSymbol.BrakeType = btAny then InsertTag(Ind, 'OpenSymbolPartOfTerm', 'True') else InsertTag(Ind, 'OpenSymbolPartOfTerm', 'Left') else if R.fRule.fOpenSymbol.BrakeType = btAny then InsertTag(Ind, 'OpenSymbolPartOfTerm', 'Right') else InsertTag(Ind, 'OpenSymbolPartOfTerm', 'False'); if R.fRule.fCloseSymbol.StartType = stAny then if R.fRule.fCloseSymbol.BrakeType = btAny then InsertTag(Ind, 'CloseSymbolPartOfTerm', 'True') else InsertTag(Ind, 'CloseSymbolPartOfTerm', 'Left') else if R.fRule.fCloseSymbol.BrakeType = btAny then InsertTag(Ind, 'CloseSymbolPartOfTerm', 'Right') else InsertTag(Ind, 'CloseSymbolPartOfTerm', 'False'); InsertTagBool(Ind, 'CloseOnTerm', R.fRule.fCloseOnTerm); InsertTagBool(Ind, 'CloseOnEol', R.fRule.fCloseOnEol); InsertTagBool(Ind, 'AllowPredClose', R.fRule.fAllowPredClose); InsertTagBool(Ind, 'CaseSensitive', R.CaseSensitive); For i := 0 to R.KeyListCount-1 do SaveKWGroup(Ind, R.KeyLists[i]); For i := 0 to R.SetCount-1 do SaveSet(Ind, R.Sets[i]); For i := 0 to R.RangeCount-1 do SaveRange(Ind+1, R.Ranges[i]); OpenTag(Ind, '/Range'); end; procedure SaveInfo; var i: integer; begin OpenTag(1, 'Info'); OpenTag(2, 'General'); InsertTag(3, 'Name', info.General.Name); InsertTag(3, 'FileTypeName', info.General.Extensions); // InsertTag(3, 'Layout', info.General.Layout); OpenTag(2, '/General'); OpenTag(2, 'Author'); InsertTag(3, 'Name', Info.Author.Name); InsertTag(3, 'Email', Info.Author.Email); InsertTag(3, 'Web', Info.Author.Web); InsertTag(3, 'Copyright', Info.Author.Copyright); InsertTag(3, 'Company', Info.Author.Company); InsertTag(3, 'Remark', Info.Author.Remark); OpenTag(2, '/Author'); OpenTag(2, 'Version'); InsertTag(3, 'Version', IntToStr(Info.Version.Version)); InsertTag(3, 'Revision', IntToStr(Info.Version.Revision)); InsertTag(3, 'Date', FloatToStr(Info.Version.ReleaseDate)); case Info.Version.VersionType of vtInternalTest: InsertTag(3, 'Type', 'Internal Test'); vtBeta: InsertTag(3, 'Type', 'Beta'); vtRelease: InsertTag(3, 'Type', 'Release'); end; OpenTag(2, '/Version'); OpenTag(2, 'History'); for i := 0 to Info.history.count-1 do InsertTag(3, 'H', Info.history[i]); OpenTag(2, '/History'); OpenTag(2, 'Sample'); for i := 0 to Info.Sample.count-1 do InsertTag(3, 'S', Info.Sample[i]); OpenTag(2, '/Sample'); OpenTag(1, '/Info'); end; procedure SaveSchemes; var i: integer; begin InsertTag(1, 'SchemeIndex', IntToStr(fSchemeIndex)); OpenTag(1, 'Schemes'); for i := 0 to self.SchemesList.Count-1 do InsertTag(2, 'S', fSchemes.Strings[i]); OpenTag(1, '/Schemes'); end; begin OpenTag(0, 'UniHighlighter'); OpenTag(1, 'ImportantInfo'); WriteString(Indent(2)+'******* Please read carefully *************************'); WriteString(Indent(2)+'* Please, make any changes in this file very carefuly!*'); WriteString(Indent(2)+'* It is much more convenient to use native designer! *'); WriteString(Indent(2)+'*******************************************************'); OpenTag(1, '/ImportantInfo'); SaveInfo; SaveSchemes; SaveRange(1, self.MainRules); OpenTag(0, '/UniHighlighter'); end; procedure TSynUniSyn.LoadHglFromXml(xml: TDOMNode); var J: Integer; ChildNode: TDOMNode; begin Clear; SchemeIndex := 0; for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode:= xml.ChildNodes.Item[J]; if SameText(ChildNode.NodeName, 'Info') then ReadInfo(ChildNode) else if SameText(ChildNode.NodeName, 'SchemeIndex') then SchemeIndex := StrToInt(ReadValue(ChildNode)) else if SameText(ChildNode.NodeName, 'Schemes') then ReadSchemes(ChildNode) else if SameText(ChildNode.NodeName, 'Range') then begin fMainRules.LoadHglFromXml(ChildNode, fSchemes.Count, SchemeIndex); end end end; procedure TSynUniSyn.ReadInfo(xml: TDOMNode); var I, J: Integer; ChildNode1, ChildNode2: TDOMNode; AFormatSettings: TFormatSettings; begin for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode1:= xml.ChildNodes.Item[J]; if ChildNode1.NodeName = 'General' then begin for I:= 0 to Int32(ChildNode1.ChildNodes.Count) - 1 do begin ChildNode2 := ChildNode1.ChildNodes.Item[I]; if ChildNode2.NodeName = 'Name' then Info.General.Name:= ReadValue(ChildNode2) else if ChildNode2.NodeName = 'FileTypeName' then Info.General.Extensions := ReadValue(ChildNode2) // else if ChildNode2.NodeName = 'Layout' then Info.General.Layout := ReadValue(ChildNode2); end; end else if ChildNode1.NodeName = 'Author' then begin for I:= 0 to Int32(ChildNode1.ChildNodes.Count) - 1 do begin ChildNode2 := ChildNode1.ChildNodes.Item[I]; if ChildNode2.NodeName = 'Name' then Info.Author.Name:= ReadValue(ChildNode2) else if ChildNode2.NodeName = 'Email' then Info.Author.Email:= ReadValue(ChildNode2) else if ChildNode2.NodeName = 'Web' then Info.Author.Web:= ReadValue(ChildNode2) else if ChildNode2.NodeName = 'Copyright' then Info.Author.Copyright:= ReadValue(ChildNode2) else if ChildNode2.NodeName = 'Company' then Info.Author.Company:= ReadValue(ChildNode2) else if ChildNode2.NodeName = 'Remark' then Info.Author.Remark:= ReadValue(ChildNode2) end; end else if ChildNode1.NodeName = 'Version' then begin for I:= 0 to Int32(ChildNode1.ChildNodes.Count) - 1 do begin ChildNode2 := ChildNode1.ChildNodes.Item[I]; if ChildNode2.NodeName = 'Version' then Info.Version.Version := StrToIntDef(ReadValue(ChildNode2), 0) else if ChildNode2.NodeName = 'Revision' then Info.Version.Revision := StrToIntDef(ReadValue(ChildNode2), 0) else if ChildNode2.NodeName = 'Date' then { try AFormatSettings:= DefaultFormatSettings; Info.Version.ReleaseDate := StrToFloat(ReadValue(ChildNode2), AFormatSettings); except AFormatSettings.DecimalSeparator := '.'; try Info.Version.ReleaseDate := StrToFloat(ReadValue(ChildNode2), AFormatSettings); except // Ignore end; end } else if ChildNode2.NodeName = 'Type' then begin if ReadValue(ChildNode2) = 'Beta' then Info.Version.VersionType := vtBeta else if ReadValue(ChildNode2) = 'Release' then Info.Version.VersionType := vtRelease else Info.Version.VersionType := vtInternalTest end end; end else if ChildNode1.NodeName = 'History' then begin Info.History.Clear; for I:= 0 to Int32(ChildNode1.ChildNodes.Count) - 1 do begin ChildNode2 := ChildNode1.ChildNodes.Item[I]; if ChildNode2.NodeName = 'H' then Info.History.Add(ReadValue(ChildNode2)); end; end else if ChildNode1.NodeName = 'Sample' then begin Info.Sample.Clear; for I:= 0 to Int32(ChildNode1.ChildNodes.Count) - 1 do begin ChildNode2 := ChildNode1.ChildNodes.Item[I]; if ChildNode2.NodeName = 'S' then Info.Sample.Add(ReadValue(ChildNode2)); end; end; end; end; procedure TSynUniSyn.ReadSchemes(xml: TDOMNode); var J: Integer; ChildNode: TDOMNode; begin if fSchemes <> nil then begin fSchemes.Clear(); //MainRules.ClearAttributes(); end else raise Exception.Create(ClassName + '.ReadSchemes - property Schemes not initialized.'); for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode:= xml.ChildNodes.Item[J]; if ChildNode.NodeName = 'S' then fSchemes.Add(ReadValue(ChildNode)); end; end; procedure TSynUniSyn.LoadHglFromFile(FileName: string); //: Load Highlighter'a from file var F: TFileStreamUTF8; begin if not FileExists(FileName) then raise Exception.Create(ClassName + '.LoadHglFromFile - "'+FileName+'" does not exists.'); F := TFileStreamUTF8.Create(FileName, fmOpenRead or fmShareDenyWrite); try LoadHglFromStream( F ); finally F.Free; end; end; procedure TSynUniSyn.SaveHglToFile(FileName: string); //: Save Highlighter to file var F: TFileStreamUTF8; begin if FileName = '' then raise exception.Create(ClassName + '.SaveHglToFile - FileName is empty'); F := TFileStreamUTF8.Create(FileName, fmCreate); try SaveHglToStream( F ); finally F.Free; end; end; procedure TSynUniSyn.LoadHglFromStream(Stream: TStream); var xml: TXMLDocument = nil; begin try ReadXMLFile(xml, Stream); LoadHglFromXml(xml); finally xml.Free; end; DefHighlightChange( Self ); end; initialization {$IFNDEF SYN_CPPB_1} RegisterPlaceableHighlighter(TSynUniSyn); {$ENDIF} end. doublecmd-0.8.2/components/synunihighlighter/source/SynUniDesigner.dfm0000664000175000017500000070440313056765731025361 0ustar alexxalexxobject fmDesigner: TfmDesigner Left = 321 Height = 475 Top = 127 Width = 640 BorderIcons = [biSystemMenu, biMaximize] Caption = 'TSynUniDesigner' ClientHeight = 475 ClientWidth = 640 Color = clBtnFace Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Icon.Data = { 7E03000000000100010010100000180018006803000016000000280000001000 0000200000000100180000000000400300000000000000000000000000010000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000003930323930323930323930323930 3239303239303239303239303239303239303239303239303239303239303239 30323930320AD5F00AD5F00AD5F03930320AD5F00AD5F00AD5F08D6767393032 8D67673930328D67678D67678D67673930323930320AD5F00AD5F00AD5F03930 320AD5F00AD5F08D6767000000CFA7A80000008D67673930328D67678D676739 30323930320AD5F00AD5F00AD5F03930320AD5F08D6767CDA2A4CDA2A4C99C9E CDA2A4CFA7A83333338D67678D67673930323930323930323930323930323930 328A65668D6767D6BEBF8D67670000008D6767CDA2A43930323333338D676739 30323930321518EC1518EC1518EC3930328D6767E3D8D8E3D8D8000000F3C9CB 000000C99C9ECFA7A83333338D67673930323930321518EC1518EC1518EC3930 328D67678D6767F5F0F08D67670000008D6767CDA2A43930323333338D676739 30323930321518EC1518EC1518EC393032FF99FF8D6767FFFFFFF5F0F0E3D8D8 D6BEBFCDA2A43333338D67678D67673930323930323930323930323930323930 323930328D67678D6767000000E3D8D80000003333333333338D67678D676739 3032393032FF100AFF100AFF100A393032FFC333FFC333FFC3338D67678D6767 3333338D67678D67678D67678D6767393032393032FF100AFF100AFF100A3930 32FFC333FFC333FFC3333930320CE3170CE3170CE3173930328D67678D676739 3032393032393032393032393032393032393032393032393032393032393032 3930323930323930323930323930323930323930328D67678D67678D67678D67 678D67678D67678D67678D67678D67678D67678D67678D67678D67678D676739 30323930328D67678D67678D67678D67678D67678D67678D67678D67678D6767 8D67678D6767FFFFFF8D6767FFFFFF3930323930323930323930323930323930 3239303239303239303239303239303239303239303239303239303239303239 3032000032390000323900003239000032390000323900003239000032390000 3239000032390000323900003239000032390000323900003239000032390000 3239 } KeyPreview = True OnCloseQuery = FormCloseQuery OnCreate = FormCreate OnKeyDown = FormKeyDown OnKeyPress = FormKeyPress OnShow = FormShow Position = poDesktopCenter LCLVersion = '0.9.30' object SplitterBottom: TSplitter Cursor = crVSplit Left = 0 Height = 3 Top = 229 Width = 640 Align = alTop MinSize = 17 OnCanResize = SplitterBottomCanResize ResizeAnchor = akTop end object SplitterButtons: TSplitter Cursor = crVSplit Left = 0 Height = 3 Top = 417 Width = 640 Align = alBottom MinSize = 35 OnCanResize = SplitterCannotResize ResizeAnchor = akBottom end object StatusBar: TStatusBar Left = 0 Height = 20 Top = 455 Width = 640 Panels = < item Alignment = taCenter Width = 50 end item Width = 50 end> SimplePanel = False end object pTop: TPanel Tag = -1 Left = 0 Height = 229 Top = 0 Width = 640 Align = alTop BevelInner = bvLowered BevelOuter = bvNone ClientHeight = 229 ClientWidth = 640 TabOrder = 1 object SplitterLeft: TSplitter Left = 185 Height = 227 Top = 1 Width = 3 MinSize = 122 end object SplitterRight: TSplitter Left = 536 Height = 227 Top = 1 Width = 3 Align = alRight OnCanResize = SplitterCannotResize ResizeAnchor = akRight end object pLeft: TPanel Left = 1 Height = 227 Top = 1 Width = 184 Align = alLeft BevelInner = bvLowered BevelOuter = bvNone ClientHeight = 227 ClientWidth = 184 Constraints.MinWidth = 122 TabOrder = 0 object Bevel1: TBevel Left = 1 Height = 1 Top = 16 Width = 182 Align = alTop Style = bsRaised end object pLeftParentCapt: TPanel Left = 1 Height = 15 Top = 1 Width = 182 Align = alTop BevelOuter = bvNone ClientHeight = 15 ClientWidth = 182 Color = clActiveCaption Font.Color = clCaptionText Font.Height = -12 Font.Name = 'Tahoma' Font.Style = [fsBold] ParentColor = False ParentFont = False PopupMenu = popPanels TabOrder = 0 object lbRootMenu: TLabel Left = 0 Height = 15 Hint = 'Tree Menu' Top = 0 Width = 17 Align = alLeft Caption = 'u' Font.Color = clBtnFace Font.Height = -15 Font.Name = 'Marlett' Font.Style = [fsBold] ParentColor = False ParentFont = False ParentShowHint = False ShowHint = True OnClick = lbRootMenuClick OnMouseEnter = LabelMouseEnter OnMouseLeave = LabelMouseLeave OnContextPopup = LabelContextPopup end object pLeftCapt: TPanel Left = 17 Height = 15 Top = 0 Width = 165 Align = alClient BevelOuter = bvNone Caption = 'Rules'' Tree' Color = clActiveCaption ParentColor = False TabOrder = 0 end end object pTree: TPanel Left = 4 Height = 203 Top = 20 Width = 176 Anchors = [akTop, akLeft, akRight, akBottom] BevelOuter = bvNone ClientHeight = 203 ClientWidth = 176 TabOrder = 1 object Tree: TTreeView Left = 0 Height = 203 Top = 0 Width = 176 Align = alClient DefaultItemHeight = 16 HideSelection = False Images = listRules Indent = 19 MultiSelectStyle = [msControlSelect, msShiftSelect] RowSelect = True TabOrder = 0 OnChange = TreeChange OnClick = TreeClick OnEdited = TreeEdited OnKeyDown = TreeKeyDown OnMouseDown = TreeMouseDown OnMouseUp = TreeMouseUp Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoRowSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw] end end end object pRight: TPanel Left = 539 Height = 227 Top = 1 Width = 100 Align = alRight BevelInner = bvLowered BevelOuter = bvNone ClientHeight = 227 ClientWidth = 100 TabOrder = 2 object Bevel2: TBevel Left = 1 Height = 1 Top = 16 Width = 98 Align = alTop Style = bsRaised end object pRightCapt: TPanel Left = 1 Height = 15 Top = 1 Width = 98 Align = alTop BevelOuter = bvNone Caption = 'Attributes' Color = clActiveCaption Font.Color = clCaptionText Font.Height = -12 Font.Name = 'Tahoma' Font.Style = [fsBold] ParentColor = False ParentFont = False PopupMenu = popPanels TabOrder = 0 end object pAttri: TPanel Left = 1 Height = 209 Top = 17 Width = 98 Align = alClient BevelOuter = bvNone ClientHeight = 209 ClientWidth = 98 TabOrder = 1 object PageControl1: TPageControl Left = 0 Height = 209 Top = 0 Width = 98 ActivePage = TabSheet1 Align = alClient MultiLine = True TabIndex = 0 TabOrder = 0 Options = [nboMultiLine] object TabSheet1: TTabSheet Caption = 'Style' ClientHeight = 183 ClientWidth = 90 TabVisible = False object Bevel6: TBevel Tag = 118 Left = 0 Height = 2 Top = 43 Width = 90 end object Label2: TLabel Left = 2 Height = 14 Top = 0 Width = 64 Caption = 'Choose style:' Enabled = False ParentColor = False end object Label4: TLabel Left = 2 Height = 14 Top = 48 Width = 65 Caption = 'Change style:' ParentColor = False end object chStrikeOut: TCheckBox Left = 3 Height = 17 Top = 157 Width = 64 Caption = 'Strike&Out' Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [fsStrikeOut] OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown ParentFont = False TabOrder = 0 end object chUnderline: TCheckBox Left = 3 Height = 17 Top = 141 Width = 65 Caption = '&Underline' Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [fsUnderline] OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown ParentFont = False TabOrder = 1 end object chItalic: TCheckBox Left = 3 Height = 17 Top = 125 Width = 42 Caption = '&Italic' Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [fsItalic] OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown ParentFont = False TabOrder = 2 end object chBold: TCheckBox Left = 3 Height = 17 Top = 109 Width = 45 Caption = '&Bold' Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [fsBold] OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown ParentFont = False TabOrder = 3 end object pForeColorBox: TPanel Left = 2 Height = 23 Top = 82 Width = 41 ClientHeight = 23 ClientWidth = 41 TabOrder = 4 object pForeColor: TPanel Left = 2 Height = 18 Top = 2 Width = 28 BevelInner = bvLowered BevelOuter = bvNone TabOrder = 0 OnClick = PanelColorChange OnMouseUp = pColorMouseUp end object pForeColorArrow: TPanel Left = 31 Height = 18 Top = 2 Width = 8 BevelOuter = bvNone Caption = 'u' Font.Color = clWindowText Font.Height = -11 Font.Name = 'Marlett' ParentFont = False TabOrder = 1 OnMouseUp = pColorArrowMouseUp end end object pBackColorBox: TPanel Left = 48 Height = 22 Top = 82 Width = 41 ClientHeight = 22 ClientWidth = 41 TabOrder = 5 object pBackColor: TPanel Left = 2 Height = 18 Top = 2 Width = 28 BevelInner = bvLowered BevelOuter = bvNone TabOrder = 0 OnClick = PanelColorChange OnMouseUp = pColorMouseUp end object pBackColorArrow: TPanel Left = 31 Height = 18 Top = 2 Width = 8 BevelOuter = bvNone Caption = 'u' Font.Color = clWindowText Font.Height = -11 Font.Name = 'Marlett' ParentFont = False TabOrder = 1 OnMouseUp = pColorArrowMouseUp end end object chForeground: TCheckBox Left = 2 Height = 17 Top = 64 Width = 42 Caption = 'D&FG' Checked = True OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown State = cbChecked TabOrder = 6 end object chBackground: TCheckBox Left = 48 Height = 17 Top = 64 Width = 43 Caption = 'DB&G' Checked = True OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown State = cbChecked TabOrder = 7 end object cbStyle: TComboBox Left = 0 Height = 21 Top = 16 Width = 90 Color = clBtnFace DropDownCount = 16 Enabled = False ItemHeight = 13 Items.Strings = ( 'Root' 'Comments' 'Strings' 'Reserved words' 'Statements' 'Numbers' 'Symbols' 'Directives' 'Types' 'Variables' 'Functions' '' 'New style...' ) OnChange = AttributesChanged Style = csDropDownList TabOrder = 8 end end object TabSheet2: TTabSheet Caption = 'Default' ClientHeight = 0 ClientWidth = 0 ImageIndex = 1 TabVisible = False object CheckBox1: TCheckBox Left = 3 Height = 17 Top = 93 Width = 86 Caption = 'Strike&Out' Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [fsStrikeOut] OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown ParentFont = False TabOrder = 0 end object CheckBox2: TCheckBox Left = 3 Height = 17 Top = 77 Width = 86 Caption = '&Underline' Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [fsUnderline] OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown ParentFont = False TabOrder = 1 end object CheckBox3: TCheckBox Left = 3 Height = 17 Top = 61 Width = 86 Caption = '&Italic' Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [fsItalic] OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown ParentFont = False TabOrder = 2 end object CheckBox4: TCheckBox Left = 3 Height = 17 Top = 45 Width = 86 Caption = '&Bold' Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [fsBold] OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown ParentFont = False TabOrder = 3 end object Panel2: TPanel Left = 2 Height = 23 Top = 18 Width = 41 ClientHeight = 23 ClientWidth = 41 TabOrder = 4 object Panel3: TPanel Left = 2 Height = 18 Top = 2 Width = 28 BevelInner = bvLowered BevelOuter = bvNone TabOrder = 0 OnClick = PanelColorChange OnMouseUp = pColorMouseUp end object Panel4: TPanel Left = 31 Height = 18 Top = 2 Width = 8 BevelOuter = bvNone Caption = 'u' Font.Color = clWindowText Font.Height = -11 Font.Name = 'Marlett' ParentFont = False TabOrder = 1 OnMouseUp = pColorArrowMouseUp end end object Panel5: TPanel Left = 48 Height = 22 Top = 18 Width = 41 ClientHeight = 22 ClientWidth = 41 TabOrder = 5 object Panel6: TPanel Left = 2 Height = 18 Top = 2 Width = 28 BevelInner = bvLowered BevelOuter = bvNone TabOrder = 0 OnClick = PanelColorChange OnMouseUp = pColorMouseUp end object Panel7: TPanel Left = 31 Height = 18 Top = 2 Width = 8 BevelOuter = bvNone Caption = 'u' Font.Color = clWindowText Font.Height = -11 Font.Name = 'Marlett' ParentFont = False TabOrder = 1 OnMouseUp = pColorArrowMouseUp end end object CheckBox5: TCheckBox Left = 2 Height = 17 Top = 0 Width = 41 Caption = 'D&FG' Checked = True OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown State = cbChecked TabOrder = 6 end object CheckBox6: TCheckBox Left = 48 Height = 17 Top = 0 Width = 41 Caption = 'DB&G' Checked = True OnClick = AttributesChanged OnMouseDown = CheckBoxMouseDown State = cbChecked TabOrder = 7 end object CheckBox7: TCheckBox Left = 0 Height = 17 Top = 152 Width = 90 Caption = 'Save defaults' TabOrder = 8 end object Button1: TButton Left = 0 Height = 21 Top = 171 Width = 90 Caption = 'Get from Style' TabOrder = 9 end end end end end object pMiddle: TPanel Left = 188 Height = 227 Top = 1 Width = 348 Align = alClient BevelInner = bvLowered BevelOuter = bvNone ClientHeight = 227 ClientWidth = 348 TabOrder = 1 OnResize = pMiddleResize object Bevel4: TBevel Left = 1 Height = 1 Top = 16 Width = 346 Align = alTop Style = bsRaised end object pMiddleParentCapt: TPanel Left = 1 Height = 15 Top = 1 Width = 346 Align = alTop BevelOuter = bvNone ClientHeight = 15 ClientWidth = 346 Color = clActiveCaption Font.Color = clCaptionText Font.Height = -12 Font.Name = 'Tahoma' Font.Style = [fsBold] ParentColor = False ParentFont = False PopupMenu = popPanels TabOrder = 0 object lbPropBack: TLabel Left = 0 Height = 15 Hint = 'Back' Top = 0 Width = 17 Align = alLeft Caption = '3' Font.Color = clBtnFace Font.Height = -15 Font.Name = 'Marlett' Font.Style = [fsBold] ParentColor = False ParentFont = False ParentShowHint = False ShowHint = True OnClick = lbPropBackClick OnMouseEnter = LabelMouseEnter OnMouseLeave = LabelMouseLeave OnContextPopup = LabelContextPopup end object lbRuleMenu: TLabel Left = 329 Height = 15 Hint = 'Rule Menu' Top = 0 Width = 17 Align = alRight Caption = 'u' Font.Color = clBtnFace Font.Height = -15 Font.Name = 'Marlett' Font.Style = [fsBold] ParentColor = False ParentFont = False ParentShowHint = False ShowHint = True OnClick = lbRuleMenuClick OnMouseEnter = LabelMouseEnter OnMouseLeave = LabelMouseLeave OnContextPopup = LabelContextPopup end object pMiddleCapt: TPanel Left = 17 Height = 15 Top = 0 Width = 312 Align = alClient BevelOuter = bvNone Caption = 'Properties' Color = clActiveCaption ParentColor = False TabOrder = 0 end end object PageControl: TPageControl Left = 1 Height = 209 Top = 17 Width = 346 TabStop = False ActivePage = tabRoot Align = alClient Constraints.MinWidth = 118 TabIndex = 0 TabOrder = 1 object tabRoot: TTabSheet Caption = 'tabRoot' ClientHeight = 183 ClientWidth = 338 OnShow = tabRootShow PopupMenu = popRootMenu TabVisible = False object lbDelimitersRoot: TLabel Left = 0 Height = 14 Top = 134 Width = 46 Caption = '&Delimiters' FocusControl = edDelimitersRoot ParentColor = False end object Label3: TLabel Left = 0 Height = 14 Top = 80 Width = 71 Caption = 'File with styles:' Enabled = False ParentColor = False end object Label5: TLabel Left = 0 Height = 14 Top = 104 Width = 68 Caption = 'Color scheme:' Enabled = False ParentColor = False end object chCaseRoot: TCheckBox Left = 0 Height = 17 Top = 0 Width = 90 Caption = '&Case Sensitive' OnClick = RootChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 0 end object chEnabledRoot: TCheckBox Left = 269 Height = 17 Top = 0 Width = 59 Anchors = [akTop, akRight] Caption = '&Enabled' OnClick = RootChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 1 end object edDelimitersRoot: TEdit Left = 70 Height = 21 Top = 131 Width = 259 Anchors = [akTop, akLeft, akRight] Font.Color = clWindowText Font.Height = -11 Font.Name = 'Courier' OnChange = RootChange OnContextPopup = EditContextPopup OnKeyDown = EditKeyDown ParentFont = False PopupMenu = popStandard TabOrder = 2 end object pRootButtons: TPanel Left = 0 Height = 24 Top = 159 Width = 338 Align = alBottom BevelOuter = bvNone ClientHeight = 24 ClientWidth = 338 TabOrder = 3 object btAddRangeRoot: TButton Left = 0 Height = 24 Top = 0 Width = 108 Caption = 'Add &Range' OnClick = DoAddRangeToRoot TabOrder = 0 end object btAddKeywordsRoot: TButton Left = 110 Height = 24 Top = 0 Width = 109 Caption = 'Add &Keywords' OnClick = DoAddKeywordToRoot TabOrder = 1 end object btAddSetRoot: TButton Left = 221 Height = 24 Top = 0 Width = 108 Caption = 'Add &Set' OnClick = DoAddSetToRoot TabOrder = 2 end end object edStylesFile: TEdit Left = 70 Height = 21 Top = 76 Width = 236 Anchors = [akTop, akLeft, akRight] Color = clBtnFace Enabled = False OnChange = RootChange PopupMenu = popStandard TabOrder = 4 Text = 'Standart.clr' end object btStylesFile: TButton Left = 310 Height = 20 Top = 76 Width = 20 Anchors = [akTop, akRight] Caption = '...' Enabled = False OnClick = btStylesFileClick TabOrder = 5 TabStop = False end object ComboBox2: TComboBox Left = 70 Height = 21 Top = 100 Width = 262 Anchors = [akTop, akLeft, akRight] Color = clBtnFace Enabled = False ItemHeight = 13 ItemIndex = 0 Items.Strings = ( 'Standard' 'Twinight' 'FAR' 'Visual Studio' ) Style = csDropDownList TabOrder = 6 Text = 'Standard' end object Button4: TButton Left = 232 Height = 25 Top = 48 Width = 97 Caption = 'Add link to range' OnClick = DoAddRangeLink TabOrder = 7 Visible = False end end object tabRange: TTabSheet Caption = 'tabRange' ClientHeight = 183 ClientWidth = 338 ImageIndex = 1 OnShow = tabRangeShow PopupMenu = popRangeMenu TabVisible = False object lbDelimitersRange: TLabel Left = 0 Height = 14 Top = 134 Width = 46 Caption = '&Delimiters' FocusControl = edDelimitersRange ParentColor = False end object lbRangeFrom: TLabel Left = 0 Height = 14 Top = 20 Width = 27 Caption = '&From:' ParentColor = False end object lbRangeTo: TLabel Left = 0 Height = 14 Top = 42 Width = 17 Caption = '&To:' ParentColor = False end object edDelimitersRange: TEdit Left = 70 Height = 21 Top = 131 Width = 259 Anchors = [akTop, akLeft, akRight] Font.Color = clWindowText Font.Height = -11 Font.Name = 'Courier' OnChange = RangeChange OnContextPopup = EditContextPopup OnKeyDown = EditKeyDown ParentFont = False PopupMenu = popStandard TabOrder = 14 end object chEnabledRange: TCheckBox Left = 269 Height = 17 Top = 0 Width = 59 Anchors = [akTop, akRight] Caption = '&Enabled' OnClick = RangeChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 2 end object chCaseRange: TCheckBox Left = 30 Height = 17 Top = 0 Width = 90 Caption = '&Case Sensitive' OnClick = RangeChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 1 end object pRangeButtons: TPanel Left = 0 Height = 24 Top = 159 Width = 338 Align = alBottom BevelOuter = bvNone ClientHeight = 24 ClientWidth = 338 TabOrder = 15 object btAddRange: TButton Left = 0 Height = 24 Top = 0 Width = 108 Caption = 'Add &Range' OnClick = DoAddRange TabOrder = 0 end object btAddKeywords: TButton Left = 110 Height = 24 Top = 0 Width = 109 Caption = 'Add &Keywords' OnClick = DoAddKeyword TabOrder = 1 end object btAddSet: TButton Left = 221 Height = 24 Top = 0 Width = 108 Caption = 'Add &Set' OnClick = DoAddSet TabOrder = 2 end end object btChooseRule: TButton Left = 0 Height = 16 Top = 0 Width = 27 Caption = '7' Enabled = False Font.Color = clWindowText Font.Height = -11 Font.Name = 'Marlett' OnClick = btTagMenuClick ParentFont = False TabOrder = 0 end object edFrom: TEdit Left = 30 Height = 21 Top = 18 Width = 226 Anchors = [akTop, akLeft, akRight] AutoSelect = False Font.Color = clWindowText Font.Height = -11 Font.Name = 'Courier' OnChange = RangeChange OnContextPopup = EditContextPopup OnKeyDown = EditKeyDown ParentFont = False PopupMenu = popStandard TabOrder = 3 end object edTo: TEdit Left = 30 Height = 21 Top = 40 Width = 226 Anchors = [akTop, akLeft, akRight] AutoSelect = False Font.Color = clWindowText Font.Height = -11 Font.Name = 'Courier' OnChange = RangeChange OnContextPopup = EditContextPopup OnKeyDown = EditKeyDown ParentFont = False PopupMenu = popStandard TabOrder = 4 end object btFromList: TButton Left = 259 Height = 19 Top = 18 Width = 19 Anchors = [akTop, akRight] Caption = '...' Enabled = False TabOrder = 5 TabStop = False end object chFromEOL: TCheckBox Left = 302 Height = 17 Top = 19 Width = 26 Anchors = [akTop, akRight] Caption = '¶' OnClick = RangeChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 9 end object btToList: TButton Left = 259 Height = 19 Top = 40 Width = 19 Anchors = [akTop, akRight] Caption = '...' Enabled = False TabOrder = 6 TabStop = False end object btToMenu: TButton Left = 281 Height = 19 Top = 40 Width = 19 Anchors = [akTop, akRight] Caption = 'u' Font.Color = clWindowText Font.Height = -11 Font.Name = 'Marlett' OnClick = btTagMenuClick ParentFont = False PopupMenu = popCloseTagMenu TabOrder = 8 end object btFromMenu: TButton Left = 281 Height = 19 Top = 18 Width = 19 Anchors = [akTop, akRight] Caption = 'u' Font.Color = clWindowText Font.Height = -11 Font.Name = 'Marlett' OnClick = btTagMenuClick ParentFont = False PopupMenu = popOpenTagMenu TabOrder = 7 end object chToEOL: TCheckBox Left = 302 Height = 17 Top = 41 Width = 26 Anchors = [akTop, akRight] Caption = '¶' OnClick = RangeChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 10 end object chCloseOnWord: TCheckBox Left = 0 Height = 17 Top = 61 Width = 102 Caption = 'Close on &delimiter' OnClick = RangeChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 11 end object chCloseOnEOL: TCheckBox Left = 0 Height = 17 Top = 77 Width = 113 Caption = 'Close on end of &line' OnClick = RangeChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 12 end object chCloseParent: TCheckBox Left = 0 Height = 17 Top = 93 Width = 161 Caption = 'Close &parent if same close tag' OnClick = RangeChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 13 end object CheckBox8: TCheckBox Left = 0 Height = 17 Top = 109 Width = 161 Caption = 'Close &parent if same close tag' OnClick = RangeChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 16 Visible = False end object Button3: TButton Left = 232 Height = 25 Top = 64 Width = 97 Caption = 'Add link to range' OnClick = DoAddRangeLink TabOrder = 17 Visible = False end end object tabKeywords: TTabSheet Caption = 'tabKeywords' ClientHeight = 183 ClientWidth = 338 ImageIndex = 2 OnShow = tabKeywordsShow PopupMenu = popKeywordsMenu TabVisible = False object pProp: TPanel Left = 264 Height = 183 Top = 0 Width = 74 Align = alRight BevelOuter = bvNone ClientHeight = 183 ClientWidth = 74 Constraints.MinWidth = 70 TabOrder = 1 object lbKeywordCount: TLabel Left = 3 Height = 14 Top = 168 Width = 38 Anchors = [akLeft, akBottom] Caption = 'Lines: 0' ParentColor = False end object btSort: TSpeedButton Left = 3 Height = 22 Hint = 'Sort strings' Top = 24 Width = 23 Glyph.Data = { F6000000424DF600000000000000760000002800000010000000100000000100 04000000000080000000C40E0000C40E00001000000000000000000000000000 8000008000000080800080000000800080008080000080808000C0C0C0000000 FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00DDDDDDDDDDDD DDDDDDCCCCDDDD0DDDDDDDCDDDDDD707DDDDDDDCCDDDD000DDDDDDDDDCDD7000 7DDDDDCDDCDD00000DDDDDDCCDDDDD0DDDDDDDDDDDDDDD0DDDDDDDDD9DDDDD0D DDDDDDDD9DDDDD0DDDDDDDDD9DDDDD0DDDDDDD9D9DDDDD0DDDDDDDD99DDDDD0D DDDDDDDD9DDDDD0DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD } NumGlyphs = 0 OnClick = btSort_oldClick ShowHint = True ParentShowHint = False end object btLowerCase: TSpeedButton Left = 27 Height = 22 Hint = 'Lower case' Top = 24 Width = 23 Glyph.Data = { F6000000424DF600000000000000760000002800000010000000100000000100 0400000000008000000000000000000000001000000000000000000000000000 8000008000000080800080000000800080008080000080808000C0C0C0000000 FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00DDDDDDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD DDDD0DDDDD0DDD0DDD0D0DDDDD00DD0DDD0DD00000D00DD000DDD0DDD0D000D0 D0DDDD0D0DD00DDD0DDDDD0D0DD0DDDD0DDDDDD0DDDDDDDDDDDDDDD0DDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD } NumGlyphs = 0 OnClick = btLowerCase_oldClick ShowHint = True ParentShowHint = False end object btSpacesToEol: TSpeedButton Left = 51 Height = 22 Hint = 'Spaces to EOL' Top = 24 Width = 23 Glyph.Data = { F6000000424DF600000000000000760000002800000010000000100000000100 0400000000008000000000000000000000001000000000000000000000000000 8000008000000080800080000000800080008080000080808000C0C0C0000000 FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00DDDDDDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDDDD0DD0DDDDDDDDDDDD0DD0DDDDDDDDDDDD0DD0DD DDDDDDDDDD0DD0DDDDDDDDDDDD0DD0DDDDDDDDDD000DD0DDDDDDDDD0000DD0DD DDDDDD00000DD0DDDDDDDD00000DD0DDDDDDDD00000DD0DDDDDDDDD0000DD0DD DDDDDDDD00000000DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD } NumGlyphs = 0 OnClick = btSpacesToEol_oldClick ShowHint = True ParentShowHint = False end object chEnabledKeyList: TCheckBox Left = 13 Height = 17 Top = 0 Width = 59 Anchors = [akTop, akRight] Caption = '&Enabled' OnClick = KeywordsChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 0 end object btSort_old: TButton Left = 3 Height = 23 Top = 84 Width = 67 Caption = '&Sort' OnClick = btSort_oldClick TabOrder = 1 Visible = False end object btLowerCase_old: TButton Left = 3 Height = 23 Top = 108 Width = 67 Caption = '&Lower Case' OnClick = btLowerCase_oldClick TabOrder = 2 Visible = False end object btSpacesToEol_old: TButton Left = 3 Height = 23 Top = 132 Width = 67 Caption = 'S&paces -> ¶' OnClick = btSpacesToEol_oldClick TabOrder = 3 Visible = False end end object Memo: TMemo Left = 0 Height = 183 Top = 0 Width = 264 Align = alClient Font.Color = clWindowText Font.Height = -11 Font.Name = 'Courier' Lines.Strings = ( 'Memo' ) OnChange = KeywordsChange OnContextPopup = EditContextPopup OnKeyDown = EditKeyDown ParentFont = False PopupMenu = popStandard ScrollBars = ssBoth TabOrder = 0 end end object tabSet: TTabSheet Caption = 'tabSet' ClientHeight = 183 ClientWidth = 338 ImageIndex = 3 OnShow = tabSetShow PopupMenu = popSetMenu TabVisible = False object lbSymbSet: TLabel Left = 0 Height = 14 Top = 22 Width = 57 Caption = '&Symbol Set:' FocusControl = edSymbSet ParentColor = False end object chEnabledSet: TCheckBox Left = 269 Height = 17 Top = 0 Width = 59 Anchors = [akTop, akRight] Caption = '&Enabled' OnClick = SetChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 1 end object edSymbSet: TEdit Left = 70 Height = 21 Top = 19 Width = 259 Anchors = [akTop, akLeft, akRight] Font.Color = clWindowText Font.Height = -11 Font.Name = 'Courier' OnChange = SetChange OnContextPopup = EditContextPopup OnKeyDown = EditKeyDown ParentFont = False PopupMenu = popStandard TabOrder = 2 end object chAnyStart: TCheckBox Left = 0 Height = 17 Top = 0 Width = 60 Caption = 'AnyStart' Enabled = False OnClick = SetChange OnContextPopup = DontNeedContextPopup OnMouseDown = CheckBoxMouseDown TabOrder = 0 TabStop = False end end object tabSeveralRules: TTabSheet Caption = 'tabSeveralRules' ClientHeight = 183 ClientWidth = 338 ImageIndex = 4 TabVisible = False object Label1: TLabel Left = 4 Height = 15 Top = 2 Width = 321 Alignment = taCenter Anchors = [akTop, akLeft, akRight] AutoSize = False Caption = 'You have selected several rules...' Font.Color = clWindowText Font.Height = -13 Font.Name = 'Tahoma' Font.Style = [fsBold] ParentColor = False ParentFont = False end end end end end object pBottom: TPanel Left = 0 Height = 185 Top = 232 Width = 640 Align = alClient BevelInner = bvLowered BevelOuter = bvLowered ClientHeight = 185 ClientWidth = 640 Constraints.MinHeight = 17 TabOrder = 2 object Bevel5: TBevel Left = 2 Height = 1 Top = 17 Width = 636 Align = alTop Style = bsRaised end object pBottomParentCapt: TPanel Left = 2 Height = 15 Top = 2 Width = 636 Align = alTop BevelOuter = bvNone ClientHeight = 15 ClientWidth = 636 Color = clActiveCaption Font.Color = clCaptionText Font.Height = -12 Font.Name = 'Tahoma' Font.Style = [fsBold] ParentColor = False ParentFont = False PopupMenu = popPanels TabOrder = 0 object lbSampMin: TLabel Left = 602 Height = 15 Hint = 'Minimize' Top = 0 Width = 17 Align = alRight Caption = '0' Font.Color = clBtnFace Font.Height = -15 Font.Name = 'Marlett' Font.Style = [fsBold] ParentColor = False ParentFont = False ParentShowHint = False ShowHint = True OnClick = lbSampMinClick OnMouseEnter = LabelMouseEnter OnMouseLeave = LabelMouseLeave OnContextPopup = LabelContextPopup end object lbSampMax: TLabel Left = 619 Height = 15 Hint = 'Maximize' Top = 0 Width = 17 Align = alRight Caption = '1' Font.Color = clBtnFace Font.Height = -15 Font.Name = 'Marlett' Font.Style = [fsBold] ParentColor = False ParentFont = False ParentShowHint = False ShowHint = True OnClick = lbSampMaxClick OnMouseEnter = LabelMouseEnter OnMouseLeave = LabelMouseLeave OnContextPopup = LabelContextPopup end object Label6: TLabel Left = 0 Height = 15 Hint = 'Minimize' Top = 0 Width = 14 Align = alLeft Caption = '<' Enabled = False Font.Color = clBtnFace Font.Height = -15 Font.Name = 'Wingdings' ParentColor = False ParentFont = False ParentShowHint = False ShowHint = True OnClick = lbSampMinClick OnMouseEnter = LabelMouseEnter OnMouseLeave = LabelMouseLeave OnContextPopup = LabelContextPopup end object pBottomCapt: TPanel Left = 14 Height = 15 Top = 0 Width = 588 Align = alClient BevelOuter = bvNone Caption = 'Sample text (will not save)' Color = clActiveCaption ParentColor = False TabOrder = 0 OnDblClick = PanelDblClick end end inline SampleMemo: TSynEdit Left = 2 Height = 165 Top = 18 Width = 636 Align = alClient Font.Height = -13 Font.Name = 'Courier New' Font.Pitch = fpFixed Font.Quality = fqNonAntialiased ParentColor = False ParentFont = False PopupMenu = popSampleMemoMenu TabOrder = 1 OnKeyDown = SampleMemoKeyDown OnMouseDown = SampleMemoMouseDown Gutter.Width = 57 Gutter.MouseActions = < item Shift = [] ShiftMask = [] Button = mbLeft ClickCount = ccAny ClickDir = cdDown Command = 13 MoveCaret = False Option = 0 Priority = 0 end item Shift = [] ShiftMask = [] Button = mbRight ClickCount = ccSingle ClickDir = cdUp Command = 12 MoveCaret = False Option = 0 Priority = 0 end> RightGutter.Width = 0 RightGutter.MouseActions = < item Shift = [] ShiftMask = [] Button = mbLeft ClickCount = ccAny ClickDir = cdDown Command = 13 MoveCaret = False Option = 0 Priority = 0 end item Shift = [] ShiftMask = [] Button = mbRight ClickCount = ccSingle ClickDir = cdUp Command = 12 MoveCaret = False Option = 0 Priority = 0 end> Highlighter = SynUniSyn Keystrokes = < item Command = ecUp ShortCut = 38 end item Command = ecSelUp ShortCut = 8230 end item Command = ecScrollUp ShortCut = 16422 end item Command = ecDown ShortCut = 40 end item Command = ecSelDown ShortCut = 8232 end item Command = ecScrollDown ShortCut = 16424 end item Command = ecLeft ShortCut = 37 end item Command = ecSelLeft ShortCut = 8229 end item Command = ecWordLeft ShortCut = 16421 end item Command = ecSelWordLeft ShortCut = 24613 end item Command = ecRight ShortCut = 39 end item Command = ecSelRight ShortCut = 8231 end item Command = ecWordRight ShortCut = 16423 end item Command = ecSelWordRight ShortCut = 24615 end item Command = ecPageDown ShortCut = 34 end item Command = ecSelPageDown ShortCut = 8226 end item Command = ecPageBottom ShortCut = 16418 end item Command = ecSelPageBottom ShortCut = 24610 end item Command = ecPageUp ShortCut = 33 end item Command = ecSelPageUp ShortCut = 8225 end item Command = ecPageTop ShortCut = 16417 end item Command = ecSelPageTop ShortCut = 24609 end item Command = ecLineStart ShortCut = 36 end item Command = ecSelLineStart ShortCut = 8228 end item Command = ecEditorTop ShortCut = 16420 end item Command = ecSelEditorTop ShortCut = 24612 end item Command = ecLineEnd ShortCut = 35 end item Command = ecSelLineEnd ShortCut = 8227 end item Command = ecEditorBottom ShortCut = 16419 end item Command = ecSelEditorBottom ShortCut = 24611 end item Command = ecToggleMode ShortCut = 45 end item Command = ecCopy ShortCut = 16429 end item Command = ecPaste ShortCut = 8237 end item Command = ecDeleteChar ShortCut = 46 end item Command = ecCut ShortCut = 8238 end item Command = ecDeleteLastChar ShortCut = 8 end item Command = ecDeleteLastChar ShortCut = 8200 end item Command = ecDeleteLastWord ShortCut = 16392 end item Command = ecUndo ShortCut = 32776 end item Command = ecRedo ShortCut = 40968 end item Command = ecLineBreak ShortCut = 13 end item Command = ecSelectAll ShortCut = 16449 end item Command = ecCopy ShortCut = 16451 end item Command = ecBlockIndent ShortCut = 24649 end item Command = ecLineBreak ShortCut = 16461 end item Command = ecInsertLine ShortCut = 16462 end item Command = ecDeleteWord ShortCut = 16468 end item Command = ecBlockUnindent ShortCut = 24661 end item Command = ecPaste ShortCut = 16470 end item Command = ecCut ShortCut = 16472 end item Command = ecDeleteLine ShortCut = 16473 end item Command = ecDeleteEOL ShortCut = 24665 end item Command = ecUndo ShortCut = 16474 end item Command = ecRedo ShortCut = 24666 end item Command = ecGotoMarker0 ShortCut = 16432 end item Command = ecGotoMarker1 ShortCut = 16433 end item Command = ecGotoMarker2 ShortCut = 16434 end item Command = ecGotoMarker3 ShortCut = 16435 end item Command = ecGotoMarker4 ShortCut = 16436 end item Command = ecGotoMarker5 ShortCut = 16437 end item Command = ecGotoMarker6 ShortCut = 16438 end item Command = ecGotoMarker7 ShortCut = 16439 end item Command = ecGotoMarker8 ShortCut = 16440 end item Command = ecGotoMarker9 ShortCut = 16441 end item Command = ecSetMarker0 ShortCut = 24624 end item Command = ecSetMarker1 ShortCut = 24625 end item Command = ecSetMarker2 ShortCut = 24626 end item Command = ecSetMarker3 ShortCut = 24627 end item Command = ecSetMarker4 ShortCut = 24628 end item Command = ecSetMarker5 ShortCut = 24629 end item Command = ecSetMarker6 ShortCut = 24630 end item Command = ecSetMarker7 ShortCut = 24631 end item Command = ecSetMarker8 ShortCut = 24632 end item Command = ecSetMarker9 ShortCut = 24633 end item Command = EcFoldLevel1 ShortCut = 41009 end item Command = EcFoldLevel2 ShortCut = 41010 end item Command = EcFoldLevel1 ShortCut = 41011 end item Command = EcFoldLevel1 ShortCut = 41012 end item Command = EcFoldLevel1 ShortCut = 41013 end item Command = EcFoldLevel6 ShortCut = 41014 end item Command = EcFoldLevel7 ShortCut = 41015 end item Command = EcFoldLevel8 ShortCut = 41016 end item Command = EcFoldLevel9 ShortCut = 41017 end item Command = EcFoldLevel0 ShortCut = 41008 end item Command = EcFoldCurrent ShortCut = 41005 end item Command = EcUnFoldCurrent ShortCut = 41003 end item Command = EcToggleMarkupWord ShortCut = 32845 end item Command = ecNormalSelect ShortCut = 24654 end item Command = ecColumnSelect ShortCut = 24643 end item Command = ecLineSelect ShortCut = 24652 end item Command = ecTab ShortCut = 9 end item Command = ecShiftTab ShortCut = 8201 end item Command = ecMatchBracket ShortCut = 24642 end item Command = ecColSelUp ShortCut = 40998 end item Command = ecColSelDown ShortCut = 41000 end item Command = ecColSelLeft ShortCut = 40997 end item Command = ecColSelRight ShortCut = 40999 end item Command = ecColSelPageDown ShortCut = 40994 end item Command = ecColSelPageBottom ShortCut = 57378 end item Command = ecColSelPageUp ShortCut = 40993 end item Command = ecColSelPageTop ShortCut = 57377 end item Command = ecColSelLineStart ShortCut = 40996 end item Command = ecColSelLineEnd ShortCut = 40995 end item Command = ecColSelEditorTop ShortCut = 57380 end item Command = ecColSelEditorBottom ShortCut = 57379 end> MouseActions = < item Shift = [] ShiftMask = [ssShift, ssAlt] Button = mbLeft ClickCount = ccSingle ClickDir = cdDown Command = 1 MoveCaret = True Option = 0 Priority = 0 end item Shift = [ssShift] ShiftMask = [ssShift, ssAlt] Button = mbLeft ClickCount = ccSingle ClickDir = cdDown Command = 1 MoveCaret = True Option = 1 Priority = 0 end item Shift = [ssAlt] ShiftMask = [ssShift, ssAlt] Button = mbLeft ClickCount = ccSingle ClickDir = cdDown Command = 3 MoveCaret = True Option = 0 Priority = 0 end item Shift = [ssShift, ssAlt] ShiftMask = [ssShift, ssAlt] Button = mbLeft ClickCount = ccSingle ClickDir = cdDown Command = 3 MoveCaret = True Option = 1 Priority = 0 end item Shift = [] ShiftMask = [] Button = mbRight ClickCount = ccSingle ClickDir = cdUp Command = 12 MoveCaret = False Option = 0 Priority = 0 end item Shift = [] ShiftMask = [] Button = mbLeft ClickCount = ccDouble ClickDir = cdDown Command = 6 MoveCaret = True Option = 0 Priority = 0 end item Shift = [] ShiftMask = [] Button = mbLeft ClickCount = ccTriple ClickDir = cdDown Command = 7 MoveCaret = True Option = 0 Priority = 0 end item Shift = [] ShiftMask = [] Button = mbLeft ClickCount = ccQuad ClickDir = cdDown Command = 8 MoveCaret = True Option = 0 Priority = 0 end item Shift = [] ShiftMask = [] Button = mbMiddle ClickCount = ccSingle ClickDir = cdDown Command = 10 MoveCaret = True Option = 0 Priority = 0 end item Shift = [ssCtrl] ShiftMask = [ssShift, ssAlt, ssCtrl] Button = mbLeft ClickCount = ccSingle ClickDir = cdUp Command = 11 MoveCaret = False Option = 0 Priority = 0 end> MouseSelActions = < item Shift = [] ShiftMask = [] Button = mbLeft ClickCount = ccSingle ClickDir = cdDown Command = 9 MoveCaret = False Option = 0 Priority = 0 end> Lines.Strings = ( 'SynEdit1' ) BracketHighlightStyle = sbhsBoth inline SynLeftGutterPartList1: TSynGutterPartList object SynGutterMarks1: TSynGutterMarks Width = 24 end object SynGutterLineNumber1: TSynGutterLineNumber Width = 17 MouseActions = <> MarkupInfo.Background = clBtnFace MarkupInfo.Foreground = clNone DigitCount = 2 ShowOnlyLineNumbersMultiplesOf = 1 ZeroStart = False LeadingZeros = False end object SynGutterChanges1: TSynGutterChanges Width = 4 ModifiedColor = 59900 SavedColor = clGreen end object SynGutterSeparator1: TSynGutterSeparator Width = 2 end object SynGutterCodeFolding1: TSynGutterCodeFolding MouseActions = < item Shift = [] ShiftMask = [] Button = mbRight ClickCount = ccSingle ClickDir = cdUp Command = 16 MoveCaret = False Option = 0 Priority = 0 end item Shift = [] ShiftMask = [ssShift] Button = mbMiddle ClickCount = ccAny ClickDir = cdDown Command = 14 MoveCaret = False Option = 0 Priority = 0 end item Shift = [ssShift] ShiftMask = [ssShift] Button = mbMiddle ClickCount = ccAny ClickDir = cdDown Command = 14 MoveCaret = False Option = 1 Priority = 0 end item Shift = [] ShiftMask = [] Button = mbLeft ClickCount = ccAny ClickDir = cdDown Command = 0 MoveCaret = False Option = 0 Priority = 0 end> MarkupInfo.Background = clNone MarkupInfo.Foreground = clGray MouseActionsExpanded = < item Shift = [] ShiftMask = [] Button = mbLeft ClickCount = ccAny ClickDir = cdDown Command = 14 MoveCaret = False Option = 0 Priority = 0 end> MouseActionsCollapsed = < item Shift = [ssCtrl] ShiftMask = [ssCtrl] Button = mbLeft ClickCount = ccAny ClickDir = cdDown Command = 15 MoveCaret = False Option = 0 Priority = 0 end item Shift = [] ShiftMask = [ssCtrl] Button = mbLeft ClickCount = ccAny ClickDir = cdDown Command = 15 MoveCaret = False Option = 1 Priority = 0 end> end end end end object pButtons: TPanel Left = 0 Height = 35 Top = 420 Width = 640 Align = alBottom BevelInner = bvLowered BevelOuter = bvLowered ClientHeight = 35 ClientWidth = 640 Constraints.MinHeight = 35 TabOrder = 3 object btOk: TButton Left = 400 Height = 25 Top = 5 Width = 75 Anchors = [akTop, akRight] Caption = 'OK' Default = True OnClick = btOkClick TabOrder = 0 end object btCancel: TButton Left = 480 Height = 25 Top = 5 Width = 75 Anchors = [akTop, akRight] Caption = 'Cancel' OnClick = btCancelClick TabOrder = 1 end object btApply: TButton Left = 560 Height = 25 Top = 5 Width = 75 Anchors = [akTop, akRight] Caption = '&Apply' Enabled = False OnClick = btApplyClick TabOrder = 2 end end object popStandard: TPopupMenu Images = listImages left = 16 top = 32 object popUndo: TMenuItem Caption = '&Undo' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF000000FF000000FF000000FF000000FF0000 00FF800000FF800000FF800000FF800000FF800000FF000000FF000000FF0000 00FF000000FF000000FF800000FF000000FF000000FF000000FF000000FF0000 00FF800000FF800000FF800000FF800000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF800000FF000000FF000000FF000000FF0000 00FF800000FF800000FF800000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF800000FF000000FF000000FF000000FF0000 00FF800000FF800000FF000000FF800000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF800000FF000000FF000000FF000000FF0000 00FF800000FF000000FF000000FF000000FF800000FF800000FF000000FF0000 00FF000000FF000000FF800000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF800000FF8000 00FF800000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 7 ShortCut = 16474 OnClick = popUndoClick end object N1: TMenuItem Caption = '-' end object popCut: TMenuItem Caption = 'Cu&t' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF000000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 0 ShortCut = 16472 OnClick = popCutClick end object popCopy: TMenuItem Caption = '&Copy' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF000000FFFFFF FFFF000000FF000000FFFFFFFFFF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 1 ShortCut = 16451 OnClick = popCopyClick end object popPaste: TMenuItem Caption = '&Paste' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FF800000FF800000FF800000FFFFFFFFFF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF000000FF000000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF008080FF808080FF008080FF8080 80FF008080FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF808080FF808080FF000000FF000000FF000000FF000000FF8080 80FF808080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF008080FF000000FF00FFFFFF000000FF000000FF00FFFFFF0000 00FF808080FF008080FF808080FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF00FFFFFF00FFFFFF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 2 ShortCut = 16470 OnClick = popPasteClick end object popDelete: TMenuItem Caption = '&Delete' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 8 ShortCut = 46 OnClick = popDeleteClick end object N2: TMenuItem Caption = '-' end object popSelectAll: TMenuItem Caption = 'Select &All' ShortCut = 16449 OnClick = popSelectAllClick end end object popOpenTagMenu: TPopupMenu left = 48 top = 32 object Closemenu1: TMenuItem Caption = 'Close menu' end object N3: TMenuItem Caption = '-' end object Opentagisfirstsymbolsonline1: TMenuItem AutoCheck = True Caption = 'Open tag is first symbols on line' OnClick = miOpenTagMenuClick end object Opentagisfirstnonspacesymbolsonline1: TMenuItem AutoCheck = True Caption = 'Open tag is first non-space symbols on line' OnClick = miOpenTagMenuClick end object N4: TMenuItem Caption = '-' end object Opentagispartofterm1: TMenuItem AutoCheck = True Caption = 'Open tag is part of term' RadioItem = True OnClick = miTagMenuClick end object Opentagispartoftermonlyrightside1: TMenuItem AutoCheck = True Caption = 'Open tag is part of term (only right side)' RadioItem = True OnClick = miTagMenuClick end object Opentagispartoftermonlyleftside1: TMenuItem AutoCheck = True Caption = 'Open tag is part of term (only left side)' RadioItem = True OnClick = miTagMenuClick end object Opentagisnotpartofterm1: TMenuItem AutoCheck = True Caption = 'Open tag is not part of term' RadioItem = True OnClick = miTagMenuClick end end object popCloseTagMenu: TPopupMenu left = 80 top = 32 object MenuItem1: TMenuItem Caption = 'Close menu' end object MenuItem2: TMenuItem Caption = '-' end object MenuItem3: TMenuItem AutoCheck = True Caption = 'Close tag is first symbols on line' OnClick = miCloseTagMenuClick end object MenuItem4: TMenuItem AutoCheck = True Caption = 'Close tag is first non-space symbols on line' OnClick = miCloseTagMenuClick end object MenuItem5: TMenuItem Caption = '-' end object MenuItem6: TMenuItem AutoCheck = True Caption = 'Close tag is part of term' RadioItem = True OnClick = miTagMenuClick end object MenuItem7: TMenuItem AutoCheck = True Caption = 'Close tag is part of term (only right side)' RadioItem = True OnClick = miTagMenuClick end object MenuItem8: TMenuItem AutoCheck = True Caption = 'Close tag is part of term (only left side)' RadioItem = True OnClick = miTagMenuClick end object MenuItem9: TMenuItem AutoCheck = True Caption = 'Close tag is not part of term' RadioItem = True OnClick = miTagMenuClick end end object popRootMenu: TPopupMenu Images = listImages left = 16 top = 64 object rootCut: TMenuItem Caption = 'Cu&t Root range' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF000000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 0 ShortCut = 16472 OnClick = rootCutClick end object rootCopy: TMenuItem Caption = '&Copy Root range' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF000000FFFFFF FFFF000000FF000000FFFFFFFFFF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 1 ShortCut = 16451 OnClick = rootCopyClick end object rootPaste: TMenuItem Caption = '&Paste inside Root' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FF800000FF800000FF800000FFFFFFFFFF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF000000FF000000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF008080FF808080FF008080FF8080 80FF008080FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF808080FF808080FF000000FF000000FF000000FF000000FF8080 80FF808080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF008080FF000000FF00FFFFFF000000FF000000FF00FFFFFF0000 00FF808080FF008080FF808080FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF00FFFFFF00FFFFFF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 2 ShortCut = 16470 OnClick = rootPasteInsideClick end object rootPasteAndReplace: TMenuItem Caption = 'Paste and Re&place Root' OnClick = rootPasteAndReplaceClick end object rootBreak1: TMenuItem Caption = '-' end object rootLoadFromFile: TMenuItem Caption = '&Load Root from File...' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFF000000FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF00FFFFFF000000FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFF000000FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF008080FF000000FF000000FF000000FFFFFF FFFF00FFFFFFFFFFFFFF00FFFFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 5 OnClick = rootLoadFromFileClick end object rootSaveToFile: TMenuItem Caption = 'Save Highlighter to File...' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF008080FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 6 OnClick = rootSaveToFileClick end object rootBreak2: TMenuItem Caption = '-' end object rootAddRange: TMenuItem Caption = 'Add &Range to Root' OnClick = DoAddRangeToRoot end object rootAddKeywords: TMenuItem Caption = 'Add &Keywords to Root' OnClick = DoAddKeywordToRoot end object rootAddSetto: TMenuItem Caption = 'Add &Set to Root' OnClick = DoAddSetToRoot end object rootBreak3: TMenuItem Caption = '-' end object rootRename: TMenuItem Caption = 'Re&name Root range' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FF000000FF000000FFFF0000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FF000000FF000000FFFF0000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FF000000FF000000FFFF0000FF000000FFFF0000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FFFF0000FF000000FFFF0000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 3 ShortCut = 113 OnClick = DoRenameNode end object rootDeleteAll: TMenuItem Caption = '&Delete all rules' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF000000FF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF0000 FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000FFFF0000 FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000FFFF0000 FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF0000 FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 4 ShortCut = 46 OnClick = DoDeleteNode end object rootBreak4: TMenuItem Caption = '-' end object rootInfo: TMenuItem Caption = 'Highlighter Info...' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF000000FF000000FFFFFFFFFF000000FF000000FF000000FF000000FF0000 00FFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF000000FF000000FFFFFFFFFF000000FF000000FF000000FF000000FF0000 00FFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF000000FF000000FFFFFFFFFFFFFFFFFFFFFFFFFF000000FFC0C0C0FF0000 00FFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF000000FFC0C0C0FF000000FFFFFFFFFF000000FFC0C0C0FF000000FFC0C0 C0FF000000FF000000FF000000FF000000FF800000FF800000FF000000FFFFFF FFFFFFFFFFFF000000FFC0C0C0FF000000FFC0C0C0FF000000FFC0C0C0FF0000 00FFC0C0C0FFC0C0C0FFC0C0C0FF000000FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FFC0C0C0FF000000FFC0C0C0FF000000FFC0C0 C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FF000000FFC0C0C0FF000000FFC0C0C0FFC0C0 C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FFC0C0C0FFC0C0C0FF000000FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 11 ShortCut = 16496 OnClick = rootInfoClick end end object popRangeMenu: TPopupMenu Images = listImages left = 48 top = 64 object rangeBack: TMenuItem Caption = '&Up to one level' OnClick = lbPropBackClick end object rangeBreak1: TMenuItem Caption = '-' end object rangeCut: TMenuItem Caption = 'Cu&t Range' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF000000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 0 ShortCut = 16472 OnClick = rangeCutClick end object rangeCopy: TMenuItem Caption = '&Copy Range' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF000000FFFFFF FFFF000000FF000000FFFFFFFFFF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 1 ShortCut = 16451 OnClick = rangeCopyClick end object rangePaste: TMenuItem Caption = '&Paste inside Range' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FF800000FF800000FF800000FFFFFFFFFF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF000000FF000000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF008080FF808080FF008080FF8080 80FF008080FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF808080FF808080FF000000FF000000FF000000FF000000FF8080 80FF808080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF008080FF000000FF00FFFFFF000000FF000000FF00FFFFFF0000 00FF808080FF008080FF808080FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF00FFFFFF00FFFFFF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 2 ShortCut = 16470 OnClick = rangePasteInsideClick end object rangePasteAndReplace: TMenuItem Caption = 'Paste and Re&place' OnClick = rangePasteAndReplaceClick end object rangePasteNextTo: TMenuItem Caption = 'Paste next to' OnClick = rangePasteNextToClick end object rangeBreak2: TMenuItem Caption = '-' end object rangeLoadFromFile: TMenuItem Caption = '&Load from File...' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFF000000FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF00FFFFFF000000FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFF000000FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF008080FF000000FF000000FF000000FFFFFF FFFF00FFFFFFFFFFFFFF00FFFFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 5 OnClick = rangeLoadFromFileClick end object rangeSaveToFile: TMenuItem Caption = 'Save Range to File...' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF008080FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 6 OnClick = rangeSaveToFileClick end object rangeBreak3: TMenuItem Caption = '-' end object rangeAddRange: TMenuItem Caption = 'Add &Range' OnClick = DoAddRange end object rangeAddKeywords: TMenuItem Caption = 'Add &Keywords' OnClick = DoAddKeyword end object rangeAddSet: TMenuItem Caption = 'Add &Set' OnClick = DoAddSet end object rangeBreak4: TMenuItem Caption = '-' end object rangeRename: TMenuItem Caption = 'Re&name Range' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FF000000FF000000FFFF0000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FF000000FF000000FFFF0000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FF000000FF000000FFFF0000FF000000FFFF0000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FFFF0000FF000000FFFF0000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 3 ShortCut = 113 OnClick = DoRenameNode end object rangeDelete: TMenuItem Caption = '&Delete Range' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF000000FF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF0000 FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000FFFF0000 FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000FFFF0000 FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF0000 FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 4 ShortCut = 46 OnClick = DoDeleteNode end end object popKeywordsMenu: TPopupMenu Images = listImages left = 80 top = 64 object keywordsBack: TMenuItem Caption = '&Up to one level' OnClick = lbRuleMenuClick end object keywordsBreak1: TMenuItem Caption = '-' end object keywordsCut: TMenuItem Caption = 'Cu&t Keywords' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF000000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 0 ShortCut = 16472 OnClick = rangeCutClick end object keywordsCopy: TMenuItem Caption = '&Copy Keywords' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF000000FFFFFF FFFF000000FF000000FFFFFFFFFF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 1 ShortCut = 16451 OnClick = rangeCopyClick end object keywordsPaste: TMenuItem Caption = 'Paste next to' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FF800000FF800000FF800000FFFFFFFFFF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF000000FF000000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF008080FF808080FF008080FF8080 80FF008080FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF808080FF808080FF000000FF000000FF000000FF000000FF8080 80FF808080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF008080FF000000FF00FFFFFF000000FF000000FF00FFFFFF0000 00FF808080FF008080FF808080FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF00FFFFFF00FFFFFF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 2 ShortCut = 16470 OnClick = rangePasteNextToClick end object keywordsPasteAndReplace: TMenuItem Caption = 'Paste and Re&place' end object keywordsBreak2: TMenuItem Caption = '-' end object keywordsLoadFromFile: TMenuItem Caption = '&Load from File...' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFF000000FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF00FFFFFF000000FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFF000000FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF008080FF000000FF000000FF000000FFFFFF FFFF00FFFFFFFFFFFFFF00FFFFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 5 OnClick = rangeLoadFromFileClick end object keywordsSaveToFile: TMenuItem Caption = 'Save Keywords to File ...' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF008080FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 6 OnClick = rangeSaveToFileClick end object keywordsBreak3: TMenuItem Caption = '-' end object keywordsRename: TMenuItem Caption = 'Re&name Keywords' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FF000000FF000000FFFF0000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FF000000FF000000FFFF0000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FF000000FF000000FFFF0000FF000000FFFF0000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FFFF0000FF000000FFFF0000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 3 ShortCut = 113 OnClick = DoRenameNode end object keywordsDelete: TMenuItem Caption = '&Delete Keywords' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF000000FF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF0000 FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000FFFF0000 FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000FFFF0000 FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF0000 FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 4 ShortCut = 46 OnClick = DoDeleteNode end end object popSetMenu: TPopupMenu Images = listImages left = 112 top = 64 object setBack: TMenuItem Caption = '&Up to one level' OnClick = lbPropBackClick end object setBreak1: TMenuItem Caption = '-' end object setCut: TMenuItem Caption = 'Cu&t Set' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF000000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 0 ShortCut = 16472 OnClick = rangeCutClick end object setCopy: TMenuItem Caption = '&Copy Set' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF000000FFFFFF FFFF000000FF000000FFFFFFFFFF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 1 ShortCut = 16451 OnClick = rangeCopyClick end object setPaste: TMenuItem Caption = 'Paste next to' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FF800000FF800000FF800000FFFFFFFFFF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF000000FF000000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF008080FF808080FF008080FF8080 80FF008080FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF808080FF808080FF000000FF000000FF000000FF000000FF8080 80FF808080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF008080FF000000FF00FFFFFF000000FF000000FF00FFFFFF0000 00FF808080FF008080FF808080FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF00FFFFFF00FFFFFF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 2 ShortCut = 16470 OnClick = rangePasteNextToClick end object setPasteAndReplace: TMenuItem Caption = 'Paste and Re&place' end object setBreak2: TMenuItem Caption = '-' end object setLoadFromFile: TMenuItem Caption = '&Load from File...' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFF000000FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF00FFFFFF000000FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFF000000FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF008080FF000000FF000000FF000000FFFFFF FFFF00FFFFFFFFFFFFFF00FFFFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00FF FFFFFFFFFFFF00FFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 5 OnClick = rangeLoadFromFileClick end object setSaveToFile: TMenuItem Caption = 'Save Set to File...' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF008080FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF008080FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF008080FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 6 OnClick = rangeSaveToFileClick end object setBreak3: TMenuItem Caption = '-' end object setRename: TMenuItem Caption = 'Re&name set' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FF000000FF000000FFFF0000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FF000000FF000000FFFF0000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FF000000FF000000FFFF0000FF000000FFFF0000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FFFF0000FF000000FFFF0000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FF000000FF000000FF000000FFFF0000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF0000FF000000FF000000FF000000FF0000 00FFFF0000FFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 3 ShortCut = 113 OnClick = DoRenameNode end object setDelete: TMenuItem Caption = '&Delete Set' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF000000FF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF0000 FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000FFFF0000 FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF0000FFFF0000FFFF0000FFFF0000 FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF0000FFFF0000FFFF0000FFFF000000FF000000FF0000 FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF0000 00FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 00FF000000FF0000FFFF0000FFFF000000FF000000FF000000FF000000FF0000 FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF0000FFFF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 4 ShortCut = 46 OnClick = DoDeleteNode end end object popPanels: TPopupMenu left = 112 top = 32 object RulesTree1: TMenuItem AutoCheck = True Caption = 'Panel "Rules Tree"' Checked = True OnClick = ShowHideTree end object Properties1: TMenuItem AutoCheck = True Caption = 'Panel "Properties"' Checked = True OnClick = ShowHideProp end object Attributes1: TMenuItem AutoCheck = True Caption = 'Panel "Attributes"' Checked = True OnClick = ShowHideAttr end object Sampletext1: TMenuItem AutoCheck = True Caption = 'Panel "Sample text"' Checked = True OnClick = ShowHideSamp end object Buttons1: TMenuItem AutoCheck = True Caption = 'Bottom Buttons' Checked = True end end object SynUniSyn: TSynUniSyn Enabled = False left = 80 top = 160 end object listImages: TImageList BkColor = clForeground DrawingStyle = dsTransparent left = 16 top = 96 Bitmap = { 4C69160000001000000010000000FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FFFF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FFFF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FFFF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FF000000FFFF00FF00000000FF000000FFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FFFF00FF00000000FFFF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00800000FF000000FF800000FFFF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00800000FFFF00FF00800000FF800000FF800000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF008000 00FF800000FF800000FFFF00FF00800000FFFF00FF00FF00FF00800000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FFFF00 FF00FF00FF00800000FFFF00FF00800000FFFF00FF00FF00FF00800000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FFFF00 FF00FF00FF00800000FFFF00FF00800000FFFF00FF00FF00FF00800000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FFFF00 FF00FF00FF00800000FFFF00FF00FF00FF00800000FF800000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF008000 00FF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FF000000FF0000 00FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFF000000FFFFFFFFFF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFF000000FF000000FFFFFF FFFF000000FF800000FF800000FF800000FF800000FF800000FF800000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF8000 00FFFF00FF00FF00FF00FF00FF00000000FFFFFFFFFF000000FF000000FF0000 00FF000000FF800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFF FFFF800000FFFF00FF00FF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFFFFFFFF000000FF000000FFFFFFFFFF800000FF8000 00FF800000FF800000FFFF00FF00000000FFFFFFFFFF000000FF000000FF0000 00FF000000FF800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFFFFFFFF000000FF000000FF000000FF000000FF0000 00FFFFFFFFFF800000FFFF00FF00000000FF000000FF000000FF000000FF0000 00FF000000FF800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00800000FFFFFFFFFF000000FF000000FF000000FF000000FF0000 00FFFFFFFFFF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00800000FF800000FF800000FF800000FF800000FF800000FF8000 00FF800000FF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FF000000FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FF0000 00FF000000FF00FFFFFF00FFFFFF000000FF000000FF000000FF000000FF0000 00FFFF00FF00FF00FF00FF00FF00000000FF008080FF808080FF008080FF0000 00FF00FFFFFF000000FF000000FF00FFFFFF000000FF808080FF008080FF8080 80FF000000FFFF00FF00FF00FF00000000FF808080FF808080FF000000FFC0C0 C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FF000000FF808080FF0080 80FF000000FFFF00FF00FF00FF00000000FF008080FF808080FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF808080FF8080 80FF000000FFFF00FF00FF00FF00000000FF808080FF008080FF808080FF0080 80FF808080FF008080FF808080FF008080FF808080FF008080FF808080FF0080 80FF000000FFFF00FF00FF00FF00000000FF008080FF808080FF008080FF8080 80FF008080FF800000FF800000FF800000FF800000FF800000FF800000FF8000 00FF000000FFFF00FF00FF00FF00000000FF808080FF008080FF808080FF0080 80FF808080FF800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8000 00FF800000FFFF00FF00FF00FF00000000FF008080FF808080FF008080FF8080 80FF008080FF800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8000 00FFFFFFFFFF800000FFFF00FF00000000FF808080FF008080FF808080FF0080 80FF808080FF800000FFFFFFFFFF800000FF800000FF800000FFFFFFFFFF8000 00FF800000FF800000FF800000FF000000FF008080FF808080FF008080FF8080 80FF008080FF800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FF000000FF808080FF008080FF808080FF0080 80FF808080FF800000FFFFFFFFFF800000FF800000FF800000FF800000FF8000 00FF800000FFFFFFFFFF800000FFFF00FF00000000FF000000FF000000FF0000 00FF000000FF800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00800000FF800000FF800000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF0000FFFF00 00FFFF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00FF00FF00 FF00FF00FF00FF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 00FFFF00FF00FF0000FFFF00FF00FF00FF00FF00FF00FF0000FFFF00FF00FF00 FF00FF00FF00FF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 00FFFF00FF00FF0000FFFF00FF00FF00FF00FF00FF00FF0000FFFF00FF00FF00 FF00FF00FF00FF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00 FF00FF00FF00FF00FF00FF0000FFFF00FF00FF00FF00FF0000FFFF0000FFFF00 00FFFF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00 FF00FF00FF00FF00FF00FF0000FFFF00FF00FF00FF00FF0000FFFF00FF00FF00 FF00FF00FF00FF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00 00FFFF0000FFFF0000FFFF0000FFFF00FF00FF00FF00FF0000FFFF00FF00FF00 FF00FF00FF00FF0000FFFF00FF00FF00FF00FF00FF00FF0000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00FF00FF0000FFFF00FF00FF00 FF00FF00FF00FF0000FFFF00FF00FF00FF00FF00FF00FF0000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00FF00FF0000FFFF0000FFFF00 00FFFF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000FFFF0000FFFFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF000000FFFFFF00FF00FF00FF00FF00FF000000FFFF0000FFFF0000FFFF0000 FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000 FFFF000000FFFF00FF00FF00FF00FF00FF00000000FF0000FFFF0000FFFF0000 FFFF0000FFFFFF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000FFFF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF0000 FFFF0000FFFF0000FFFFFF00FF00FF00FF000000FFFF0000FFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 00FF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FF0000FFFF0000FFFF0000FFFF000000FFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF000000FFFF0000FFFF0000FFFF0000FFFF0000FFFFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 FFFF0000FFFF0000FFFF000000FF000000FF0000FFFF0000FFFFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000 FFFF0000FFFF000000FFFF00FF00FF00FF00000000FF0000FFFF0000FFFFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000FFFF0000 FFFF000000FFFF00FF00FF00FF00FF00FF00FF00FF00000000FF0000FFFFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000FFFF0000FFFF0000 FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF0000 FFFFFF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000FFFF0000FFFF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 00FFFF00FF00FF00FF00FF00FF00FF00FF00000000FF0000FFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF000000FFFFFF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00FF00FF00FF000000 00FFFF00FF00000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FF000000FFFF00FF00FF00FF00000000FF000000FF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 00FF000000FF000000FFFF00FF00000000FF00FFFFFFFFFFFFFF00FFFFFF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFF00FFFFFFFFFFFFFF00FF FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FF00FFFFFFFFFFFFFF00FFFFFFFFFF FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFF000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFF00FFFFFFFFFFFFFF00FF FFFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF00FFFFFFFFFFFFFF00FFFFFF0000 00FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF000000FFFF00FF00000000FFFFFFFFFF00FFFFFF000000FF0080 80FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF000000FFFF00FF00FF00FF00000000FF00FFFFFF000000FF008080FF0080 80FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0000 00FFFF00FF00FF00FF00FF00FF00000000FF000000FF008080FF008080FF0080 80FF008080FF008080FF008080FF008080FF008080FF008080FF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FFFF00FF00FF00FF00000000FF008080FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FFFF00FF00000000FFFF00FF00FF00FF00000000FF008080FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FF000000FF000000FFFF00FF00FF00FF00000000FF008080FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FF008080FF000000FFFF00FF00FF00FF00000000FF008080FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FF008080FF000000FFFF00FF00FF00FF00000000FF008080FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FF008080FF000000FFFF00FF00FF00FF00000000FF008080FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FF008080FF000000FFFF00FF00FF00FF00000000FF008080FF008080FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0080 80FF008080FF000000FFFF00FF00FF00FF00000000FF008080FF008080FF0080 80FF008080FF008080FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF000000FFFF00FF00FF00FF00000000FF008080FF008080FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF008080FF000000FFFF00FF00FF00FF00000000FF008080FF008080FF0000 00FF000000FF000000FF000000FF000000FF000000FFFF00FF00FF00FF000000 00FF008080FF000000FFFF00FF00FF00FF00000000FF008080FF008080FF0000 00FF000000FF000000FF000000FF000000FF000000FFFF00FF00FF00FF000000 00FF008080FF000000FFFF00FF00FF00FF00000000FF008080FF008080FF0000 00FF000000FF000000FF000000FF000000FF000000FFFF00FF00FF00FF000000 00FF008080FF000000FFFF00FF00FF00FF00FF00FF00000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00800000FF800000FF800000FF800000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FFFF00FF00FF00 FF00FF00FF00800000FF800000FFFF00FF00FF00FF00FF00FF00FF00FF008000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FF800000FFFF00 FF00800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00800000FFFF00FF00FF00FF00FF00FF00FF00FF00800000FF800000FF8000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00800000FFFF00FF00FF00FF00FF00FF00FF00FF00800000FF800000FF8000 00FF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00800000FFFF00FF00FF00FF00FF00FF00FF00FF00800000FF800000FF8000 00FF800000FF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF008000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF008000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FFFF00FF00FF00FF00FF00FF00000000FF000000FF0000 00FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 00FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF0000 00FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00000000FF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FF000000FF000000FFFF00FF00FF00FF00000000FF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF000000FF000000FF000000FF000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00000000FF000000FF000000FFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF000000FF000000FF000000FF000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FF000000FF000000FFFF00FF00FF00FF00000000FF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 00FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00000000FF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF0000 00FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF0000 00FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FFFF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FF800000FF800000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FF800000FF800000FFFF00 FF00FF00FF00000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FFFF00FF00FF00FF00FF00FF00800000FF800000FF800000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FF800000FF800000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FF800000FF800000FFFF00 FF00FF00FF00000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FFFF00FF00FF00FF00FF00FF00800000FF800000FF800000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FF800000FF800000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00800000FF800000FF800000FFFF00 FF00FF00FF00000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FFFF00FF00FF00FF00FF00FF00800000FF800000FF800000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00000000FF000000FF000000FF000000FF000000FF0000 00FFFF00FF00800000FF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF800000FF800000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FFC0C0C0FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FF800000FF800000FF000000FF000000FF000000FF000000FF0000 00FFC0C0C0FF000000FFC0C0C0FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FF800000FF800000FF000000FFFFFFFFFFFFFFFFFF000000FFC0C0 C0FF000000FFC0C0C0FF000000FFC0C0C0FF000000FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF800000FF800000FF000000FFFFFFFFFF000000FFC0C0C0FF0000 00FFFFFFFFFF000000FFC0C0C0FF000000FFC0C0C0FF000000FF000000FF0000 00FFFF00FF00800000FF800000FF000000FFFFFFFFFF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFF000000FFC0C0C0FF000000FFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF000000FFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF000000FFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000 FFFF0000FFFF0000FFFF0000FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF000000FFFF0000FFFFFF00FF00FF00FF00FF00 FF00FF00FF000000FFFF0000FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF000000FFFF0000FFFFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF000000FFFFFF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF000000FFFF0000FFFFFF00FF00FF00FF00FF00FF000000 FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF000000FFFF0000FFFFFF00FF00FF00FF000000FFFF0000 FFFFFF00FF00FF00FF00FF00FF00000000FF000000FF000000FF000000FF0000 00FFFF00FF000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000 FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF000000FFFF0000FFFFFF00FF00FF00FF00FF00FF000000FFFFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF000000FFFF0000FFFFFF00FF00FF00FF00FF00FF000000FFFFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF000000FFFF0000FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF000000FFFF0000FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 FFFF0000FFFF0000FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000 FFFF0000FFFF0000FFFF0000FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF00 00FFFF0000FFFF0000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFFFFFFFFFFFFFFC0C0 C0FFFFFFFFFFFFFFFFFF000000FFFF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFFFFFFFFFFFFFFC0C0 C0FFFFFFFFFFFFFFFFFF000000FFFF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FFC0C0C0FF000000FF000000FF000000FF000000FF000000FF0000 00FFFF00FF00000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFFFFFFFFFFFFFFC0C0 C0FFFFFFFFFFFFFFFFFF000000FFFF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFFFFFFFFFFFFFFC0C0 C0FFFFFFFFFFFFFFFFFF000000FFFF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FFC0C0C0FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFFFFFFFFFFFFFFC0C0 C0FFFFFFFFFFFFFFFFFF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFFFFFFFFFFFFFFC0C0 C0FFFFFFFFFFFFFFFFFF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF000000FFFF0000FFFFFF00FF00FF00FF00FF00FF000000FFFFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 FFFF0000FFFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF00 00FFFF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 FFFF0000FFFFFF00FF00FF0000FF0000FFFFFF00FF00FF00FF00FF00FF00FF00 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 FFFF0000FFFF0000FFFF0000FFFF0000FFFFFF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000 FFFFFF00FF00FF0000FF0000FFFFFF00FF00FF00FF00FF0000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000 FFFFFF00FF00FF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000 FFFFFF0000FFFF0000FFFF00FF00FF00FF00FF0000FFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000FFFFFF00 FF00FF0000FFFF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000FFFF0000FFFF0000 FFFFFF0000FFFF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 00FFFF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00 00FFFF0000FFFF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FFFF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FFFF00FF00000000FFFFFFFFFF008000FF008000FF0080 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FFFF00FF00000000FFFFFFFFFF008000FF008000FF0080 00FFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FFFFFFFFFF000000FFFF00FF00000000FFFFFFFFFF008000FF008000FF0080 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FFFF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FFFF00FF00000000FFFF0000FF0000FFFF0000FFFF0000 FFFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF00 00FFFF0000FF000000FFFF00FF00000000FFFF0000FF0000FFFF0000FFFF0000 FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFF0000FF000000FFFF00FF00000000FFFF0000FF0000FFFF0000FFFF0000 FFFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF00 00FFFF0000FF000000FFFF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FFFF00FF00000000FFFFFFFFFFFF0000FFFF0000FFFF00 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FFFF00FF00000000FFFFFFFFFFFF0000FFFF0000FFFF00 00FFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FFFFFFFFFF000000FFFF00FF00000000FFFFFFFFFFFF0000FFFF0000FFFF00 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FFFF00FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF000000FFFF00FF00000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00800080FF000000FFFF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00800080FF808080FF800080FF000000FF000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00800080FF808080FF800080FF800080FF800080FF800080FF000000FF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF008000 80FF808080FF800080FF800080FF800080FF800080FF800080FF800080FF8000 80FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00800080FF8080 80FF800080FF800080FF00FFFFFF00FFFFFF00FFFFFF008080FF800080FF8000 80FF800080FF000000FFFF00FF00FF00FF00FF00FF00800080FF808080FF8000 80FF800080FF008080FF008080FF800080FF00FFFFFF00FFFFFF800080FF8000 80FF000000FF000000FFFF00FF00FF00FF00800080FF808080FF800080FF8000 80FF800080FF800080FFC0C0C0FF00FFFFFF00FFFFFF800080FF800080FF0000 00FF808080FF000000FFFF00FF00800080FF808080FF800080FF800080FF8000 80FF800080FF00FFFFFF008080FF800080FF800080FF800080FF000000FF8080 80FFC0C0C0FF000000FF000000FF800080FF000000FF000000FF800080FF8000 80FF800080FF800080FF800080FF800080FF800080FF000000FF808080FFC0C0 C0FFC0C0C0FF800080FF000000FF800080FF808080FF808080FF000000FF0000 00FF800080FF800080FF800080FF800080FF000000FF808080FFC0C0C0FFC0C0 C0FF800080FF000000FFFF00FF00800080FF808080FFFFFFFFFF808080FF8080 80FF000000FF000000FF800080FF000000FF808080FFC0C0C0FFC0C0C0FF8000 80FF000000FFFF00FF00FF00FF00000000FF808080FFC0C0C0FFFFFFFFFFFFFF FFFF808080FF808080FF000000FF808080FFC0C0C0FFC0C0C0FF800080FF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF808080FFC0C0 C0FFFFFFFFFFFFFFFFFF808080FFC0C0C0FFC0C0C0FF800080FF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF0000 00FF808080FFC0C0C0FFFFFFFFFFC0C0C0FF800080FF000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00000000FF000000FF808080FF800080FF000000FFFF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00000000FF000000FFFF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FFFF00FF00FF00FF00000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FF000000FFFF00FF00000000FFC0C0C0FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FFC0C0C0FF000000FFFF00FF00000000FFC0C0C0FF000000FFFFFF00FFFFFF FFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF0000 00FFC0C0C0FF000000FFFF00FF00000000FFC0C0C0FF000000FFFFFFFFFF8080 80FF808080FF808080FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF0000 00FFC0C0C0FF000000FFFF00FF00000000FFC0C0C0FF000000FFFFFF00FFFFFF FFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF0000 00FFC0C0C0FF000000FFFF00FF00000000FFC0C0C0FF000000FFFFFFFFFF8080 80FF808080FF808080FF808080FF808080FF808080FF808080FFFFFFFFFF0000 00FFC0C0C0FF000000FFFF00FF00000000FFC0C0C0FF000000FFFFFF00FFFFFF FFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF0000 00FFC0C0C0FF000000FFFF00FF00000000FFC0C0C0FF000000FFFFFFFFFF8080 80FF808080FF808080FF808080FF808080FF808080FF808080FFFFFFFFFF0000 00FFC0C0C0FF000000FFFF00FF00000000FFC0C0C0FF000000FFFFFF00FFFFFF FFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF0000 00FFC0C0C0FF000000FFFF00FF00000000FFC0C0C0FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FFC0C0C0FF000000FFFF00FF00000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FF000000FFFF00FF00FF00FF00000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFF00FFFFFFFFFFFFFF00FF FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF00FFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FF00FFFFFFFFFFFFFF00FFFFFFFFFF FFFFFFFFFFFF00FFFFFF808080FF000000FF808080FFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FF00FFFFFFFFFFFFFF00FFFFFFFFFF FFFFFFFFFFFF00FFFFFF000000FF008080FF000000FFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFF00FFFFFFFFFFFFFF00FF FFFF00FFFFFFFFFFFFFF808080FF000000FF808080FF00FFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FF00FFFFFFFFFFFFFF00FFFFFFFFFF FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFF00FFFFFFFFFFFFFF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00000000FFFFFFFFFF00FFFFFFFFFFFFFF0000 00FF00FFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF00FFFFFFFFFFFFFF000000FF8080 80FF000000FF000000FF008080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FFC0C0C0FF000000FF000000FFFFFFFFFF000000FF808080FF8080 80FF808080FF000000FF008080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF000000FF000000FF000000FF808080FF808080FF000000FF8080 80FF000000FF000000FF008080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF008080FF000000FF000000FF808080FF808080FF808080FF0000 00FF808080FF000000FF008080FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF008080FF000000FF000000FF000000FF000000FF0000 00FF000000FF008080FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF008080FF000000FF000000FF000000FF000000FFC0C0 C0FF000000FF008080FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF008080FF000000FF000000FF000000FF000000FFC0C0 C0FF000000FF008080FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF8000 00FF800000FF800000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF8000 00FF800000FF800000FF000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFF FFFFFFFFFFFFFFFFFFFFC0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0FFFFFF FFFFFFFFFFFFC0C0C0FF000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFF FFFFFFFFFFFFFFFFFFFFC0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0FFFFFF FFFFFFFFFFFFC0C0C0FF000000FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFF FFFFFFFFFFFF000000FF008080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FFC0C0C0FF000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFF FFFFFFFFFFFF000000FF008080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF000000FF000000FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FF000000FF008080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF008080FF000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFF FFFFFFFFFFFF000000FF008080FF008080FF000000FF000000FF000000FF0000 00FF008080FF008080FF000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFFFFF FFFFFFFFFFFF000000FF008080FF008080FF008080FF008080FF008080FF0080 80FF008080FF008080FF000000FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FFC0C0C0FF000000FF008080FF000000FF000000FF000000FF000000FF0000 00FF000000FF008080FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF008080FF000000FF000000FF000000FF000000FFC0C0 C0FF000000FF008080FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF008080FF000000FF000000FF000000FF000000FFC0C0 C0FF000000FF008080FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFF0000 FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000FFFFFF00FF000000 FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000 FFFFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00FF00FF00 FF00FF0000FFFF00FF00FF00FF00000000FF000000FF000000FF000000FF0000 00FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF0000FFFF00FF00FF00FF00808080FF000000FF000000FF000000FF8080 80FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00 00FFFF00FF00FF00FF00FF00FF00FF00FF00000000FF000000FF000000FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00808080FF000000FF808080FFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0000FFFF0000FFFF00 00FFFF0000FFFF00FF00FF00FF00FF00FF00FF00FF00000000FFFF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF000000FFFFFF00FF00FF00FF000000FFFFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 00FFFF00FF00FF00FF00FF0000FF0000FFFFFF00FF00FF00FF000000FFFFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 00FFFF00FF00FF00FF00FF0000FFFF00FF000000FFFFFF00FF00FF00FF00FF00 FF00FF00FF00000000FFFF00FF00FF00FF00000000FFFF00FF00FF00FF00FF00 FF00FF00FF00FF0000FFFF00FF00FF00FF000000FFFFFF00FF00FF00FF00FF00 FF00FF00FF00000000FFFF00FF00FF00FF00000000FFFF00FF00FF00FF00FF00 FF00FF0000FFFF00FF00FF00FF000000FFFFFF00FF00FF00FF000000FFFFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF0000FFFF00FF00FF00FF000000FFFFFF00FF00FF00FF000000FFFFFF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF0000FFFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 FF00FF00FF00FF00FF00FF00FF00 } end object OpenDialog: TOpenDialog DefaultExt = '.HLR' Filter = 'All supported files (*.hlr, *.hgl, *.stx, *.txt)|*.hlr;*.hgl;*.stx; *.txt|UniHighlighter Rules (*.hlr)|*.hlr|UniHighlighter Old Format (*.hgl)|*.hgl|EditPlus syntax file (*.stx)|*.stx|UltraEdit syntax file (*.txt)|*.txt|All Files (*.*)|*.*' Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing] left = 16 top = 160 end object SaveDialog: TSaveDialog DefaultExt = '.HLR' Filter = 'UniHighlighter Rules (*.hlr)|*.hlr|All Files (*.*)|*.*' Options = [ofOverwritePrompt, ofHideReadOnly, ofEnableSizing] left = 48 top = 160 end object popColorStd: TPopupMenu left = 48 top = 96 end object popColorAdv: TPopupMenu left = 80 top = 96 end object popColorSys: TPopupMenu left = 112 top = 96 end object listColors16: TImageList left = 48 top = 128 end object listColors40: TImageList left = 80 top = 128 end object listColorsSys: TImageList left = 112 top = 128 end object listRules: TImageList left = 16 top = 128 end object popSampleMemoMenu: TPopupMenu Images = listImages OnPopup = popSampleMemoMenuPopup left = 112 top = 160 object AddselectedtoKeywords1: TMenuItem Caption = 'Add to Keywords' OnClick = AddselectedtoKeywords1Click end object N7: TMenuItem Caption = '-' end object Undo1: TMenuItem Caption = '&Undo' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF000000FF000000FF000000FF000000FF0000 00FF800000FF800000FF800000FF800000FF800000FF000000FF000000FF0000 00FF000000FF000000FF800000FF000000FF000000FF000000FF000000FF0000 00FF800000FF800000FF800000FF800000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF800000FF000000FF000000FF000000FF0000 00FF800000FF800000FF800000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF800000FF000000FF000000FF000000FF0000 00FF800000FF800000FF000000FF800000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF800000FF000000FF000000FF000000FF0000 00FF800000FF000000FF000000FF000000FF800000FF800000FF000000FF0000 00FF000000FF000000FF800000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF800000FF8000 00FF800000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 7 ShortCut = 16474 OnClick = Undo1Click end object N5: TMenuItem Caption = '-' end object Cut1: TMenuItem Caption = 'Cu&t' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF000000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF800000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF800000FF800000FF800000FF000000FF800000FF0000 00FF000000FF800000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF8000 00FF800000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF000000FF800000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 0 ShortCut = 16472 OnClick = Cut1Click end object Copy1: TMenuItem Caption = '&Copy' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FF000000FF000000FF000000FFFFFFFFFF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF000000FF0000 00FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF000000FFFFFF FFFF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF000000FFFFFF FFFF000000FF000000FFFFFFFFFF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 1 ShortCut = 16451 OnClick = Copy1Click end object Paste1: TMenuItem Caption = '&Paste' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF800000FF800000FF800000FF000000FF0000 00FF000000FF000000FF000000FF000000FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FF800000FF800000FF800000FFFFFFFFFF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFF800000FF8000 00FF800000FFFFFFFFFF800000FF800000FF800000FF800000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FFFFFFFFFF800000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF800000FFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF800000FF800000FF000000FF000000FF000000FF0080 80FF808080FF008080FF808080FF008080FF800000FF800000FF800000FF8000 00FF800000FF800000FF800000FF000000FF000000FF000000FF000000FF8080 80FF008080FF808080FF008080FF808080FF008080FF808080FF008080FF8080 80FF008080FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF808080FF808080FF000000FF000000FF000000FF000000FF8080 80FF808080FF000000FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 C0FF000000FF808080FF008080FF000000FF000000FF000000FF000000FF0080 80FF808080FF008080FF000000FF00FFFFFF000000FF000000FF00FFFFFF0000 00FF808080FF008080FF808080FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF00FFFFFF00FFFFFF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 2 ShortCut = 16470 OnClick = Paste1Click end object Delete1: TMenuItem Caption = '&Delete' Bitmap.Data = { 36040000424D3604000000000000360000002800000010000000100000000100 2000000000000004000064000000640000000000000000000000000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF000000FF000000FF } ImageIndex = 8 OnClick = Delete1Click end object N6: TMenuItem Caption = '-' end object SelectAll1: TMenuItem Caption = 'Select &All' ShortCut = 16449 OnClick = SelectAll1Click end end object OpenDialog2: TOpenDialog Filter = 'CLR files (*.clr)|*.clr|All Files (*.*)|*.*' Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing] left = 144 top = 160 end end doublecmd-0.8.2/components/synunihighlighter/source/SynUniDesigner.pas0000664000175000017500000033341413056765731025376 0ustar alexxalexx{------------------------------------------------------------------------------- The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is: SynUniHighlighter.pas, released 2003-01 All Rights Reserved. Alternatively, the contents of this file may be used under the terms of the GNU General Public License Version 2 or later (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. { @abstract(Desginer for TSynUniSyn) @authors(Vit [nevzorov@yahoo.com], Fantasist [walking_in_the_sky@yahoo.com], Vitalik [vetal-x@mail.ru]) @created(2003) @lastmod(2004-05-12) } (****************************************************************************** Authors: Vit (Vitaly Nevzorov nevzorov@yahoo.com) Fantasist (Kirill Burtsev walking_in_the_sky@yahoo.com) Vitalik (Vitaly Lyapota vetal-x@mail.ru) Official Site: www.delphist.com With all questions, please visit www.delphist.com/forum ******************************************************************************) unit SynUniDesigner; //================== SCHMaster ================== {$IFNDEF FPC} //23.02.2012, Alex Dr., SynPlus is plugin for TC... {$DEFINE SYNPLUS} {$ENDIF} //=============================================== {$IFNDEF FPC} {$I SynEdit.inc} {$ELSE} {$IFNDEF SYN_LAZARUS} {$define SYN_LAZARUS} {$ENDIF} {$ENDIF} interface uses {$IFDEF SYN_CLX} Types, kTextDrawer, QGraphics, QControls, QForms, QExtCtrls, QStdCtrls, QComCtrls, QImgList, QDialogs, QMenus, {$ELSE} {$IFNDEF FPC} Windows, Messages, Registry, {$ELSE} LMessages, LCLType, {$ENDIF} Graphics, Controls, Forms, ExtCtrls, StdCtrls, ComCtrls, Dialogs, Menus, {$ENDIF} Classes, SysUtils, SynEdit, SynEditHighlighter, SynUniHighlighter, SynUniClasses, SynUniRules, Clipbrd, ImgList, Inifiles, Buttons, SynUniImport, SynUniImportEditPlus, SynUniImportUltraEdit; type {$IFDEF SYN_CLX} TNodeText = WideString; {$ELSE} TNodeText = string; {$ENDIF} TNodeType = (ntRangeLink, ntRange, ntRoot, ntKeywords, ntSet, ntNone); TAddKind = (akAdd, akInsert, akReplace); TRangeType = (rtRange, rtRoot, rtLink); { TfmDesigner } TfmDesigner = class(TForm) MenuItem10: TMenuItem; //==================== P O P U P M E N U S ============================== //=== popStandard ======================================================== popStandard: TPopupMenu; popUndo: TMenuItem; N1: TMenuItem; popCut: TMenuItem; popCopy: TMenuItem; popPaste: TMenuItem; popDelete: TMenuItem; N2: TMenuItem; popSelectAll: TMenuItem; //=== popSampleMemoMenu ================================================== popSampleMemoMenu: TPopupMenu; AddselectedtoKeywords1: TMenuItem; N7: TMenuItem; Undo1: TMenuItem; N5: TMenuItem; Cut1: TMenuItem; Copy1: TMenuItem; Paste1: TMenuItem; Delete1: TMenuItem; N6: TMenuItem; SelectAll1: TMenuItem; //=== popOpenTagMenu ===================================================== popOpenTagMenu: TPopupMenu; Closemenu1: TMenuItem; N3: TMenuItem; Opentagisfirstsymbolsonline1: TMenuItem; Opentagisfirstnonspacesymbolsonline1: TMenuItem; N4: TMenuItem; Opentagispartofterm1: TMenuItem; Opentagispartoftermonlyrightside1: TMenuItem; Opentagispartoftermonlyleftside1: TMenuItem; Opentagisnotpartofterm1: TMenuItem; //=== popCloseTagMenu ==================================================== popCloseTagMenu: TPopupMenu; MenuItem1: TMenuItem; MenuItem2: TMenuItem; MenuItem3: TMenuItem; MenuItem4: TMenuItem; MenuItem5: TMenuItem; MenuItem6: TMenuItem; MenuItem7: TMenuItem; MenuItem8: TMenuItem; MenuItem9: TMenuItem; //=== popRootMenu ======================================================== popRootMenu: TPopupMenu; rootCut: TMenuItem; rootCopy: TMenuItem; rootPaste: TMenuItem; rootPasteAndReplace: TMenuItem; rootBreak1: TMenuItem; rootLoadFromFile: TMenuItem; rootSaveToFile: TMenuItem; rootBreak2: TMenuItem; rootAddRange: TMenuItem; rootAddKeywords: TMenuItem; rootAddSetto: TMenuItem; rootBreak3: TMenuItem; rootRename: TMenuItem; rootDeleteAll: TMenuItem; rootBreak4: TMenuItem; rootInfo: TMenuItem; //=== popRangeMenu ======================================================= popRangeMenu: TPopupMenu; rangeBack: TMenuItem; rangeBreak1: TMenuItem; rangeCut: TMenuItem; rangeCopy: TMenuItem; rangePaste: TMenuItem; rangePasteAndReplace: TMenuItem; rangePasteNextTo: TMenuItem; rangeBreak2: TMenuItem; rangeLoadFromFile: TMenuItem; rangeSaveToFile: TMenuItem; rangeBreak3: TMenuItem; rangeAddRange: TMenuItem; rangeAddKeywords: TMenuItem; rangeAddSet: TMenuItem; rangeBreak4: TMenuItem; rangeRename: TMenuItem; rangeDelete: TMenuItem; //=== popKeywordsMenu ==================================================== popKeywordsMenu: TPopupMenu; keywordsBack: TMenuItem; keywordsBreak1: TMenuItem; keywordsCut: TMenuItem; keywordsCopy: TMenuItem; keywordsPaste: TMenuItem; keywordsPasteAndReplace: TMenuItem; keywordsBreak2: TMenuItem; keywordsLoadFromFile: TMenuItem; keywordsSaveToFile: TMenuItem; keywordsBreak3: TMenuItem; keywordsRename: TMenuItem; keywordsDelete: TMenuItem; //=== popSetMenu ========================================================= popSetMenu: TPopupMenu; setBack: TMenuItem; setBreak1: TMenuItem; setCut: TMenuItem; setCopy: TMenuItem; setPaste: TMenuItem; setPasteAndReplace: TMenuItem; setBreak2: TMenuItem; setLoadFromFile: TMenuItem; setSaveToFile: TMenuItem; setBreak3: TMenuItem; setRename: TMenuItem; setDelete: TMenuItem; //=== popPanels ========================================================== popPanels: TPopupMenu; RulesTree1: TMenuItem; Properties1: TMenuItem; Attributes1: TMenuItem; Sampletext1: TMenuItem; Buttons1: TMenuItem; //=== Popup Menus ======================================================== popColorStd: TPopupMenu; popColorAdv: TPopupMenu; popColorSys: TPopupMenu; //===================== C O M P O N E N T S ============================== //=== Top panel ========================================================== pTop: TPanel; SplitterBottom: TSplitter; //=== Panel "Rules' Tree" ================================================ pLeft: TPanel; SplitterLeft: TSplitter; pLeftParentCapt: TPanel; lbRootMenu: TLabel; pLeftCapt: TPanel; Bevel1: TBevel; pTree: TPanel; Tree: TTreeView; //=== Panel "Attributes" ================================================= pRight: TPanel; SplitterRight: TSplitter; pRightCapt: TPanel; Bevel2: TBevel; pAttri: TPanel; //=== Panel "Proprties" ================================================== pMiddle: TPanel; pMiddleParentCapt: TPanel; lbPropBack: TLabel; lbRuleMenu: TLabel; pMiddleCapt: TPanel; Bevel4: TBevel; //=== "Root" page ======================================================== PageControl: TPageControl; tabRoot: TTabSheet; chCaseRoot: TCheckBox; chEnabledRoot: TCheckBox; lbDelimitersRoot: TLabel; edDelimitersRoot: TEdit; pRootButtons: TPanel; btAddRangeRoot: TButton; btAddKeywordsRoot: TButton; btAddSetRoot: TButton; //=== "Range" page ======================================================= tabRange: TTabSheet; chCaseRange: TCheckBox; chEnabledRange: TCheckBox; btChooseRule: TButton; lbRangeFrom: TLabel; edFrom: TEdit; btFromList: TButton; btFromMenu: TButton; chFromEOL: TCheckBox; lbRangeTo: TLabel; edTo: TEdit; btToList: TButton; btToMenu: TButton; chToEOL: TCheckBox; chCloseOnWord: TCheckBox; chCloseOnEOL: TCheckBox; chCloseParent: TCheckBox; lbDelimitersRange: TLabel; edDelimitersRange: TEdit; pRangeButtons: TPanel; btAddRange: TButton; btAddKeywords: TButton; btAddSet: TButton; //=== "Keywords" page ==================================================== tabKeywords: TTabSheet; Memo: TMemo; pProp: TPanel; chEnabledKeyList: TCheckBox; btSort_old: TButton; btLowerCase_old: TButton; btSpacesToEol_old: TButton; lbKeywordCount: TLabel; //=== "Set" page ========================================================= tabSet: TTabSheet; chAnyStart: TCheckBox; chEnabledSet: TCheckBox; lbSymbSet: TLabel; edSymbSet: TEdit; //=== Panel "Sample text" ================================================ pBottom: TPanel; pBottomParentCapt: TPanel; lbSampMin: TLabel; lbSampMax: TLabel; pBottomCapt: TPanel; Bevel5: TBevel; SampleMemo: TSynEdit; //=== Panel with "finish" buttons ======================================== StatusBar: TStatusBar; pButtons: TPanel; SplitterButtons: TSplitter; btOk: TButton; btCancel: TButton; btApply: TButton; //=== Invisible components =============================================== SynUniSyn: TSynUniSyn; listImages: TImageList; listRules: TImageList; listColors16: TImageList; listColors40: TImageList; listColorsSys: TImageList; OpenDialog: TOpenDialog; SaveDialog: TSaveDialog; tabSeveralRules: TTabSheet; Label1: TLabel; btSort: TSpeedButton; btLowerCase: TSpeedButton; btSpacesToEol: TSpeedButton; PageControl1: TPageControl; TabSheet1: TTabSheet; chStrikeOut: TCheckBox; chUnderline: TCheckBox; chItalic: TCheckBox; chBold: TCheckBox; pForeColorBox: TPanel; pForeColor: TPanel; pForeColorArrow: TPanel; pBackColorBox: TPanel; pBackColor: TPanel; pBackColorArrow: TPanel; chForeground: TCheckBox; chBackground: TCheckBox; TabSheet2: TTabSheet; CheckBox1: TCheckBox; CheckBox2: TCheckBox; CheckBox3: TCheckBox; CheckBox4: TCheckBox; Panel2: TPanel; Panel3: TPanel; Panel4: TPanel; Panel5: TPanel; Panel6: TPanel; Panel7: TPanel; CheckBox5: TCheckBox; CheckBox6: TCheckBox; CheckBox7: TCheckBox; Button1: TButton; CheckBox8: TCheckBox; Bevel6: TBevel; Label3: TLabel; edStylesFile: TEdit; btStylesFile: TButton; cbStyle: TComboBox; Label2: TLabel; Label4: TLabel; Label5: TLabel; ComboBox2: TComboBox; OpenDialog2: TOpenDialog; Button3: TButton; Button4: TButton; Label6: TLabel; //============================ M E T O D S =================================== //=== Form events ============================================================ procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormKeyPress(Sender: TObject; var Key: Char); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); //=== Translate ============================================================== procedure OldTranslate(LangFile: String); //SCHMaster 2004 procedure Translate(LangFile: String); //=== TreeView =============================================================== procedure TreeEdited(Sender: TObject; Node: TTreeNode; var S: String); procedure TreeKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure TreeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TreeMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TreeChange(Sender: TObject; Node: TTreeNode); //=== Fill Tree with Rules =================================================== procedure FillTree; procedure SetNodeData(Node: TTreeNode; Rule: TAbstractRule; Root: boolean = False); function TreeAddRule(ParentNode: TTreeNode; Rule: TSynRule; AddKind: TAddKind = akAdd): TTreeNode; function TreeAddRangeLink(Node: TTreeNode; RangeLink: TSynRangeLink; AddKind: TAddKind = akAdd): TTreeNode; function TreeAddRange(Node: TTreeNode; Range: TSynRange; AddKind: TAddKind = akAdd): TTreeNode; function TreeAddKeyList(Node: TTreeNode; Keyword: TSynKeyList; AddKind: TAddKind = akAdd): TTreeNode; function TreeAddSet(Node: TTreeNode; SymbSet: TSynSet; AddKind: TAddKind = akAdd): TTreeNode; //=== Adding RangeLink ======================================================= procedure DoAddRangeLinkToRoot(Sender: TObject); procedure DoAddRangeLink(Sender: TObject); procedure AddingRangeLink(ParentNode: TTreeNode); //=== Adding Range =========================================================== procedure DoAddRangeToRoot(Sender: TObject); procedure DoAddRange(Sender: TObject); procedure AddingRange(ParentNode: TTreeNode); //=== Adding KeyList ========================================================= procedure DoAddKeywordToRoot(Sender:TObject); procedure DoAddKeyword(Sender: TObject); procedure AddingKeyWord(ParentNode: TTreeNode); //=== Adding Set ============================================================= procedure DoAddSetToRoot(Sender:TObject); procedure DoAddSet(Sender: TObject); procedure AddingSet(ParentNode: TTreeNode); //=== Delete and Rename Rules ================================================ procedure DoDeleteNode(Sender: TObject); procedure DeleteNode(Node: TTreeNode; OnlyChilds: boolean = False); procedure DoRenameNode(Sender: TObject); //=== Useful functions... ==================================================== function GetNodeType(Node: TTreeNode): TNodeType; procedure TotalUpdate; procedure Modified(State: boolean = True); //=== KeyList Tools ========================================================== procedure btSort_oldClick(Sender: TObject); procedure btLowerCase_oldClick(Sender: TObject); procedure btSpacesToEol_oldClick(Sender: TObject); //=== Finish buttons ========================================================= procedure btOkClick(Sender: TObject); procedure btCancelClick(Sender: TObject); procedure btApplyClick(Sender: TObject); //=== Work with schemes ====================================================== { procedure btNewSchemeClick(Sender: TObject); procedure btDelSchemeClick(Sender: TObject); procedure cbSchemeChange(Sender: TObject); procedure cbSchemeSelect(Sender: TObject);} //=== Rules changed ========================================================== procedure RootChange(Sender: TObject); procedure RangeChange(Sender: TObject); procedure KeywordsChange(Sender: TObject); procedure SetChange(Sender: TObject); //=== Wotk with Attributes =================================================== procedure AttributesChanged(Sender: TObject); procedure SetDefaultAttributes(Node: TTreeNode); procedure SetControlAttributes(Node: TTreeNode; AlreadyUpdate: boolean = False); procedure SetAttributes(Node: TTreeNode); //============================ D E S I G N =================================== //=== Splitter CanResize ===================================================== procedure SplitterBottomCanResize(Sender: TObject; var NewSize: Integer; var Accept: Boolean); procedure SplitterCannotResize(Sender: TObject; var NewSize: Integer; var Accept: Boolean); //=== Label Mouse Leave/Enter ================================================ procedure LabelMouseLeave(Sender: TObject); procedure LabelMouseEnter(Sender: TObject); procedure LabelContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); //=== CheckBox =============================================================== procedure CheckBoxMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure DontNeedContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); //=== Show/Hide panels ======================================================= procedure ShowHideTree(Sender: TObject); procedure ShowHideProp(Sender: TObject); procedure ShowHideAttr(Sender: TObject); procedure ShowHideSamp(Sender: TObject); procedure PanelDblClick(Sender: TObject); //=== Middle panel Resize ==================================================== procedure pMiddleResize(Sender: TObject); //=== Push label clicks ====================================================== procedure lbPropBackClick(Sender: TObject); procedure lbRootMenuClick(Sender: TObject); procedure lbRuleMenuClick(Sender: TObject); procedure lbSampMaxClick(Sender: TObject); //procedure lbSampRestoreClick(Sender: TObject); procedure lbSampMinClick(Sender: TObject); //============================ P O P U P S =================================== //=== Standard PopupMenu ===================================================== procedure SetPopupMenuEnables(Edit: TCustomEdit; popMenu: TPopupMenu); procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure EditContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); procedure popCopyClick(Sender: TObject); procedure popUndoClick(Sender: TObject); procedure popCutClick(Sender: TObject); procedure popPasteClick(Sender: TObject); procedure popDeleteClick(Sender: TObject); procedure popSelectAllClick(Sender: TObject); //=== Sample Memo PopupMenu ================================================== procedure SetPopupMenuEnables2(Edit: TCustomSynEdit; popMenu: TPopupMenu); procedure SampleMemoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure SampleMemoMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Undo1Click(Sender: TObject); procedure Cut1Click(Sender: TObject); procedure Copy1Click(Sender: TObject); procedure Paste1Click(Sender: TObject); procedure Delete1Click(Sender: TObject); procedure SelectAll1Click(Sender: TObject); procedure AddselectedtoKeywords1Click(Sender: TObject); procedure popSampleMemoMenuPopup(Sender: TObject); //=== Tag Menu Clicks... ===================================================== procedure btTagMenuClick(Sender: TObject); procedure miTagMenuClick(Sender: TObject); procedure miOpenTagMenuClick(Sender: TObject); procedure miCloseTagMenuClick(Sender: TObject); //=== ColorBox Clicks... ===================================================== procedure PanelColorChange(Sender: TObject); procedure miColor16Click(Sender: TObject); procedure miColorSysClick(Sender: TObject); procedure miColor40Click(Sender: TObject); {$IFNDEF FPC} procedure Color40MeasureItem(Sender: TObject; ACanvas: TCanvas; var Width, Height: Integer); {$ELSE} procedure Color40MeasureItem(Sender: TObject; ACanvas: TCanvas; var AWidth, AHeight: Integer); {$ENDIF} procedure pColorMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure pColorArrowMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); //=== TabSheet showing ======================================================= procedure tabRootShow(Sender: TObject); procedure tabRangeShow(Sender: TObject); procedure tabKeywordsShow(Sender: TObject); procedure tabSetShow(Sender: TObject); //=== Work with files ======================================================== // procedure LoadFromFileClick(Sender: TObject); procedure rootSaveToFileClick(Sender: TObject); procedure rootLoadFromFileClick(Sender: TObject); procedure rangeLoadFromFileClick(Sender: TObject); procedure rangeSaveToFileClick(Sender: TObject); //=== Clipboard ============================================================== procedure StreamToClipboard(Stream: TStream); function GetClipboardAsStream: TMemoryStream; //=== Root range ============================================================= procedure rootCutClick(Sender: TObject); procedure rootCopyClick(Sender: TObject); procedure rootPasteInsideClick(Sender: TObject); procedure rootPasteAndReplaceClick(Sender: TObject); //=== Other rules ============================================================ procedure rangeCutClick(Sender: TObject); procedure rangeCopyClick(Sender: TObject); procedure rangePasteInsideClick(Sender: TObject); procedure rangePasteAndReplaceClick(Sender: TObject); procedure rangePasteNextToClick(Sender: TObject); //=== NOT SORTED ============================================================= procedure rootInfoClick(Sender: TObject); procedure TreeClick(Sender: TObject); procedure btStylesFileClick(Sender: TObject); private { Private declarations } public { Public declarations } popPropMenu: TPopupMenu; OriginalSyn: TSynUniSyn; ForceClose: boolean; UpdatingControls: boolean; ShowDialog: boolean; _Modified, _Confirm, _DeleteNode, _SaveChanges, _EnterName, _DeleteScheme, _Lines, _Name, _Extensions, _Version, _Date, _Author, _Mail, _Web, _Copyright, _Company, _Remark: string; end; TSynUniDesigner = class(TObject) private Form: TfmDesigner; //=== Standard metods ======================================================== function Execute(FormTitle: string; LangFile: string): boolean; procedure SetSample(const Value: string); function GetSample: string; procedure SetTitle(const Value: string); function GetTitle: string; public constructor Create(Highlighter: TSynUniSyn); destructor Destroy; override; property Title: string read GetTitle write SetTitle; property Sample: string read GetSample write SetSample; class function EditHighlighter(OriginalSyn: TSynUniSyn; FormTitle: string = ''; LangFile: string = ''): boolean; end; implementation {$R *.dfm} {$IFDEF SYN_CLX} uses Qt; const VK_F1 = Key_F1; VK_F2 = Key_F2; VK_RETURN = Key_Return; VK_DELETE = Key_Delete; {$ENDIF} const Colors16: array [0..15] of TColor = (clBlack, clMaroon, clGreen, clOlive, clNavy, clPurple, clTeal, clGray, clSilver, clRed, clLime, clYellow, clBlue, clFuchsia, clAqua, clWhite); const Colors16s: array [0..15] of string = ('Black', 'Maroon', 'Green', 'Olive', 'Navy', 'Purple', 'Teal', 'Gray', 'Silver', 'Red', 'Lime', 'Yellow', 'Blue', 'Fuchsia', 'Aqua', 'White'); const Colors40: array [0..39] of TColor = ( $000000, $000080, $0000FF, $FF00FF, $CC99FF, $003399, $0066FF, $0099FF, $00CCFF, $99CCFF, $003333, $008080, $00CC99, $00FFFF, $99FFFF, $003300, $008000, $669933, $00FF00, $CCFFCC, $663300, $808000, $CCCC33, $FFFF00, $FFFFCC, $800000, $FF0000, $FF6633, $FFCC00, $FFCC99, $993333, $996666, $800080, $663399, $FF99CC, $333333, $808080, $969696, $C0C0C0, $FFFFFF); const ColorsSys: array [0..27] of TColor = (clActiveBorder, clActiveCaption, clAppWorkSpace, clBackground, clBtnFace, clBtnHighlight, clBtnShadow, clBtnText, clCaptionText, clDefault, clGradientActiveCaption, clGradientInactiveCaption, clGrayText, clHighlight, clHighlightText, clInactiveBorder, clInactiveCaption, clInactiveCaptionText, clInfoBk, clInfoText, clMenu, clMenuText, clScrollBar, cl3DDkShadow, cl3DLight, clWindow, clWindowFrame, clWindowText); const _pTopHeight = 210; function GetFontStyle(Bold, Italic, Underline, StrikeOut: boolean): TFontStyles; begin Result := []; if Bold then Result := Result + [fsBold]; if Italic then Result := Result + [fsItalic]; if Underline then Result := Result + [fsUnderline]; if Strikeout then Result := Result + [fsStrikeOut]; end; constructor TSynUniDesigner.Create(Highlighter: TSynUniSyn); (*{$IFNDEF SYN_CLX}Tree.HideSelection:=False;Tree.RightClickSelect:=True;{$ENDIF}*) begin inherited Create; Form := TfmDesigner.Create(nil); Form.OriginalSyn := Highlighter; {popRangeMenu.Items.Items[1].Caption := '&Go to subnode';} {Tree.DragMode := dmAutomatic;} {CreateButtonLabel(lbSampRestore, pBottomParentCapt, alRight, #50, 'Restore');} end; (*procedure TSynUniDesigner.DelimDblClick(Sender: TObject); begin (Sender as TEdit).Text := Set2String( DefaultTermSymbols ); end;*) destructor TSynUniDesigner.Destroy; begin Form.SampleMemo.Highlighter := nil; Form.SampleMemo.Free; Form.Free; inherited; end; class function TSynUniDesigner.EditHighlighter(OriginalSyn: TSynUniSyn; FormTitle: string; LangFile: string): boolean; begin with Create(OriginalSyn) do begin Result := Execute(FormTitle, LangFile); Free; end; end; //=== Standard metods ======================================================== procedure TSynUniDesigner.SetSample(const Value: string); begin Form.SampleMemo.Text := Value; end; function TSynUniDesigner.GetSample: string; begin Result := Form.SampleMemo.Text; end; procedure TSynUniDesigner.SetTitle(const Value: string); begin Form.Caption := Value; end; function TSynUniDesigner.GetTitle: string; begin Result := Form.Caption; end; //================== SCHMaster ================== {$IFDEF SYNPLUS} function TSynUniDesigner.Execute(FormTitle: string; LangFile: string): boolean; var msg : TMsg; TcClosed: boolean; begin ///////////////////////// if FormTitle <> '' then Title := FormTitle; Form.Translate(LangFile); TcClosed := False; Form.ModalResult := mrNone; Form.Show; while (Form.ModalResult = mrNone) do begin GetMessage({$IFDEF FPC} @ {$ENDIF}msg, 0, 0, 0); if (msg.message = WM_QUIT) then begin TcClosed := True; Form.ModalResult := mrCancel; result:=False; end else begin Result := (Form.ModalResult = mrOk); TranslateMessage({$IFDEF FPC} @ {$ENDIF}msg); DispatchMessage({$IFDEF FPC} @ {$ENDIF}msg); end; end; Result := (Form.ModalResult = mrOk); if TcClosed then PostMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam); ///////////////////////// end; {$ELSE} function TSynUniDesigner.Execute(FormTitle: string; LangFile: string): boolean; begin if FormTitle <> '' then Title := FormTitle; Form.Translate(LangFile); Result := (Form.ShowModal = mrOk); end; {$ENDIF} //=============================================== /// /// /// NNNN NNNN EEEEEEEEEEE WWWW WWWW $$$ $$$ $$$ /// /// NNNN NN EE EE WW WW $$$$$ $$$$$ $$$$$ /// /// NN NN NN EE E E WW WW $$$$$ $$$$$ $$$$$ /// /// NN NN NN EEEEEE WW WW WW $$$$$ $$$$$ $$$$$ /// /// NN NN NN EE T T WW WWWW WW $$$ $$$ $$$ /// /// NN NNNN EE TT WWW WWWW /// /// NNNN NNNN EEEETTTTTTT WW WW $$$ $$$ $$$ /// /// /// //============================ M E T O D S =================================== //=== Form events ============================================================ procedure TfmDesigner.FormCreate(Sender: TObject); procedure AddBitmap(ImageList: TImageList; aColor: TColor; aSize: integer; aSymbol: string); var Bitmap: TBitmap; begin Bitmap := TBitmap.Create; with Bitmap do begin Width := 16; Height := 16; end; with Bitmap.Canvas do begin Font.Name := 'Marlett'; Font.Color := aColor; Font.Size := aSize; {$IFNDEF FPC} TextOut(1, 1, aSymbol); {$ELSE} TextOut(0, 0, aSymbol); {$ENDIF} ImageList.AddMasked(Bitmap, clWhite); end; Bitmap.Free; end; procedure AddBitmapColor(out ImageList: TImageList; aColor: TColor); var Bitmap: TBitmap; begin Bitmap := TBitmap.Create; with Bitmap do begin Width := 16; Height := 16; end; with Bitmap.Canvas do begin Brush.Color := clBtnFace; FillRect(Rect(0, 0, 16, 16)); Brush.Color := aColor; Rectangle(1, 1, 15, 15); ImageList.AddMasked(Bitmap, clBtnFace); end; Bitmap.Free; end; procedure CreateMenuItem(out popMenu: TPopupMenu; aCaption: TCaption; aOnClick: TNotifyEvent; aImageIndex: integer); overload; begin popMenu.Items.Add(TMenuItem.Create(Self)); with popMenu.Items.Items[popMenu.Items.Count-1] do begin Caption := aCaption; ImageIndex := aImageIndex; OnClick := aOnClick; end; end; var i: integer; begin ForceClose := False; UpdatingControls := False; ShowDialog := True; _DeleteNode := 'Are you sure you want to delete "%s"?'; _SaveChanges := 'Save changes in highlight rools?'; _EnterName := 'Enter Scheme Name:'; _DeleteScheme := 'Delete current color scheme?'; _Modified := 'Modified'; _Confirm := 'Confirm'; _Lines := 'Lines: %d'; _Name := 'Name: %s'; _Extensions := 'Extensions: %s'; _Version := 'Version: %s'; _Date := 'Date: %s'; _Author := 'Author: %s'; _Mail := 'Mail: %s'; _Web := 'Web: %s'; _Copyright := 'Copyright: %s'; _Company := 'Company: %s'; _Remark := 'Remark: %s'; Caption := 'Unihighlighter Designer © Fantasist, Vit, Vitalik (2002-2004)'; if SynUniSyn.Info.General.Name <> '' then Caption := Caption + ' - [' + SynUniSyn.Info.General.Name + ']'; popColorStd.Images := listColors16; for i := 0 to 15 do begin AddBitmapColor(listColors16, Colors16[i]); CreateMenuItem(popColorStd, Colors16s[i], miColor16Click, i); end; {$note May be error...} {$IFNDEF FPC} popColorStd.Items[8].Break := {$IFDEF FPC} @ {$ENDIF}mbBarBreak; {$ENDIF} popColorAdv.Images := listColors40; for i := 0 to 39 do begin AddBitmapColor(listColors40, Colors40[i]); CreateMenuItem(popColorAdv, '', miColor40Click, i); {$note May be error...} {$IFNDEF FPC} popColorAdv.Items.Items[i].OnMeasureItem := Color40MeasureItem; {$ENDIF} end; {$note May be error...} {$IFNDEF FPC} for i := 1 to 7 do popColorAdv.Items[5*i].Break := mbBreak; {$ENDIF} popColorSys.Images := listColorsSys; for i := 0 to 27 do begin AddBitmapColor(listColorsSys, ColorsSys[i]); CreateMenuItem(popColorSys, ColorToString(ColorsSys[i]), miColorSysClick, i); end; {$note May be error...} {$IFNDEF FPC} popColorSys.Items[14].Break := mbBarBreak; {$ENDIF} AddBitmap(listRules, clRed, 14, #52); //: Image0: 'Root Range' AddBitmap(listRules, clGreen, 14, #52); //: Image1: 'Range' AddBitmap(listRules, clBlue, 14, #104); //: Image2: 'Keyword' AddBitmap(listRules, clMaroon, 14, #104); //: Image3: 'Set' AddBitmap(listRules, clOlive, 14, #52); //: Image1: 'RangeLink' AddBitmap(listRules, clOlive, 14, #52); //: Image4: 'Conteiner' { cbScheme.Items.AddStrings(SynUniSyn.SchemesList); cbScheme.ItemIndex := SynUniSyn.SchemeIndex;} SampleMemo.Highlighter := SynUniSyn; SampleMemo.Lines.Text := SynUniSyn.Info.Sample.Text; end; procedure TfmDesigner.FormShow(Sender: TObject); var Stream: TMemoryStream; begin Stream := TMemoryStream.Create; try OriginalSyn.SaveToStream(Stream); OriginalSyn.SaveToFile('r:\test.xml'); Stream.Position := 0; try if Stream.Size <> 0 then SynUniSyn.LoadFromStream(Stream, False); Stream.Clear; SampleMemo.Text := OriginalSyn.Info.Sample.Text; finally end; finally Stream.Free; end; FillTree; Tree.Selected := Tree.Items[0]; TreeChange(nil, Tree.Selected); Tree.Items[0].Expand(False); end; procedure TfmDesigner.FormKeyPress(Sender: TObject; var Key: Char); begin if (Key = #27) and (not Tree.IsEditing) then Close; end; procedure TfmDesigner.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_F1 then if ssCtrl in Shift then rootInfoClick(Sender) else Application.MessageBox('UniHighlighter Component'+#13#10#13#10+ 'Copyright © 2002-2004:'+#13#10+ 'Fantasist (walking_in_the_sky@yahoo.com)'+#13#10+ 'Vit (nevzorov@yahoo.com)'+#13#10+ 'Vitalik (vetal-x@mail.ru)'+#13#10#13#10+ 'Official Web Site: www.delphist.com'{+#13#10#13#10+ 'Thanks to:'+#13#10+ 'P@VeL, '+ 'bouville, '+ 'StayAtHome, '+ 'Jasny, '+ 'SCHMaster'}, 'About...', MB_ICONINFORMATION) else if (ssAlt in Shift) and (ssShift in Shift) and (ssCtrl in Shift) and (Key = VK_F12) then begin edStylesFile.Enabled := True; btStylesFile.Enabled := True; cbStyle.Enabled := True; end; end; procedure TfmDesigner.FormCloseQuery(Sender: TObject; var CanClose: Boolean); var Choise: integer; begin if Tree.IsEditing then Tree.Selected.EndEdit(False); if ModalResult = mrOk then Exit; if btApply.Enabled then begin if ForceClose then Exit; Choise := Application.MessageBox(PChar(_SaveChanges), PChar(_Confirm), MB_YESNOCANCEL+MB_ICONQUESTION); if Choise = ID_YES then begin btApplyClick(Sender); ModalResult := mrOk end else if Choise = ID_NO then ModalResult := mrCancel else CanClose := False; end else ModalResult := mrCancel; //================== SCHMaster ================== {$IFDEF SYNPLUS} if ModalResult = mrNone then ModalResult:=mrCancel; {$ENDIF} //=============================================== end; //=== Translate ============================================================== procedure TfmDesigner.OldTranslate(LangFile: String); //SCHMaster 2004 var L: TStringList; begin L := TStringList.Create; if (LangFile <> '') and FileExists(LangFile) then L.LoadFromFile(LangFile); if Length(L.Values['2000'])>2 then Caption := L.Values['2000'] + ' - [' + SynUniSyn.Info.General.Name + ']'; with popPanels do begin if Length(L.Values['2001'])>2 then Items[0].Caption := L.Values['2001']; if Length(L.Values['2002'])>2 then Items[1].Caption := L.Values['2002']; if Length(L.Values['2003'])>2 then Items[2].Caption := L.Values['2003']; if Length(L.Values['2004'])>2 then Items[3].Caption := L.Values['2004']; end; if Length(L.Values['2010'])>2 then btOk.Caption := L.Values['2010']; if Length(L.Values['2011'])>2 then btCancel.Caption := L.Values['2011']; if Length(L.Values['2012'])>2 then btApply.Caption := L.Values['2012']; with popStandard do begin if Length(L.Values['2013'])>2 then Items[0].Caption := L.Values['2013']; if Length(L.Values['2014'])>2 then Items[2].Caption := L.Values['2014']; if Length(L.Values['2015'])>2 then Items[3].Caption := L.Values['2015']; if Length(L.Values['2016'])>2 then Items[4].Caption := L.Values['2016']; if Length(L.Values['2017'])>2 then Items[5].Caption := L.Values['2017']; if Length(L.Values['2018'])>2 then Items[7].Caption := L.Values['2018']; end; with popSampleMemoMenu do begin if Length(L.Values['2013'])>2 then Items[2].Caption := L.Values['2013']; if Length(L.Values['2014'])>2 then Items[4].Caption := L.Values['2014']; if Length(L.Values['2015'])>2 then Items[5].Caption := L.Values['2015']; if Length(L.Values['2016'])>2 then Items[6].Caption := L.Values['2016']; if Length(L.Values['2017'])>2 then Items[7].Caption := L.Values['2017']; if Length(L.Values['2018'])>2 then Items[9].Caption := L.Values['2018']; end; if Length(L.Values['2020'])>2 then _Modified := L.Values['2020']; if Length(L.Values['2030'])>2 then _DeleteNode := L.Values['2030']; if Length(L.Values['2031'])>2 then _SaveChanges := L.Values['2031']; if Length(L.Values['2032'])>2 then _EnterName := L.Values['2032']; if Length(L.Values['2033'])>2 then _DeleteScheme := L.Values['2033']; if Length(L.Values['2034'])>2 then _Confirm := L.Values['2034']; if Length(L.Values['2100'])>2 then pLeftCapt.Caption := L.Values['2100']; if Length(L.Values['2200'])>2 then pMiddleCapt.Caption := L.Values['2200']; if Length(L.Values['2201'])>2 then lbPropBack.Hint := L.Values['2201']; if Length(L.Values['2202'])>2 then lbRuleMenu.Hint := L.Values['2202']; with popRootMenu do begin if Length(L.Values['2305'])>2 then Items[8].Caption := L.Values['2305']; if Length(L.Values['2306'])>2 then Items[9].Caption := L.Values['2306']; if Length(L.Values['2307'])>2 then Items[10].Caption := L.Values['2307']; if Length(L.Values['2204'])>2 then Items[13].Caption := L.Values['2204']; end; with popRangeMenu do begin if Length(L.Values['2203'])>2 then Items[0].Caption := L.Values['2203']; if Length(L.Values['2204'])>2 then Items[16].Caption := L.Values['2204']; if Length(L.Values['2406'])>2 then Items[11].Caption := L.Values['2406']; if Length(L.Values['2407'])>2 then Items[12].Caption := L.Values['2407']; if Length(L.Values['2408'])>2 then Items[13].Caption := L.Values['2408']; end; with popKeywordsMenu do begin if Length(L.Values['2203'])>2 then Items[0].Caption := L.Values['2203']; if Length(L.Values['2204'])>2 then Items[11].Caption := L.Values['2204']; end; with popSetMenu do begin if Length(L.Values['2203'])>2 then Items[0].Caption := L.Values['2203']; if Length(L.Values['2204'])>2 then Items[11].Caption := L.Values['2204']; end; if Length(L.Values['2300'])>2 then chCaseRoot.Caption := L.Values['2300']; if Length(L.Values['2300'])>2 then chCaseRange.Caption := L.Values['2300']; if Length(L.Values['2301'])>2 then btAddRangeRoot.Caption := L.Values['2301']; if Length(L.Values['2301'])>2 then btAddRange.Caption := L.Values['2301']; if Length(L.Values['2302'])>2 then btAddKeywordsRoot.Caption := L.Values['2302']; if Length(L.Values['2302'])>2 then btAddKeywords.Caption := L.Values['2302']; if Length(L.Values['2303'])>2 then btAddSetRoot.Caption := L.Values['2303']; if Length(L.Values['2303'])>2 then btAddSet.Caption := L.Values['2303']; if Length(L.Values['2304'])>2 then lbDelimitersRoot.Caption := L.Values['2304']; if Length(L.Values['2304'])>2 then lbDelimitersRange.Caption := L.Values['2304']; if Length(L.Values['2400'])>2 then lbRangeFrom.Caption := L.Values['2400']; if Length(L.Values['2401'])>2 then lbRangeTo.Caption := L.Values['2401']; if Length(L.Values['2402'])>2 then chCloseOnWord.Caption := L.Values['2402']; if Length(L.Values['2403'])>2 then chCloseOnEOL.Caption := L.Values['2403']; if Length(L.Values['2404'])>2 then chCloseParent.Caption := L.Values['2404']; if Length(L.Values['2501'])>2 then btSort.Hint := L.Values['2501']; if Length(L.Values['2502'])>2 then btLowercase.Hint := L.Values['2502']; if Length(L.Values['2503'])>2 then btSpacesToEol.Hint := L.Values['2503']; if Length(L.Values['2600'])>2 then lbSymbSet.Caption := L.Values['2600']; if Length(L.Values['2700'])>2 then pRightCapt.Caption := L.Values['2700']; if Length(L.Values['2701'])>2 then chForeground.Caption := L.Values['2701']; if Length(L.Values['2702'])>2 then chBackground.Caption := L.Values['2702']; if Length(L.Values['2703'])>2 then chBold.Caption := L.Values['2703']; if Length(L.Values['2704'])>2 then chItalic.Caption := L.Values['2704']; if Length(L.Values['2705'])>2 then chUnderline.Caption := L.Values['2705']; if Length(L.Values['2706'])>2 then chStrikeOut.Caption := L.Values['2706']; { if Length(L.Values['2707'])>2 then lbScheme.Caption := L.Values['2707']; if Length(L.Values['2708'])>2 then btNewScheme.Caption := L.Values['2708']; if Length(L.Values['2709'])>2 then btDelScheme.Caption := L.Values['2709'];} if Length(L.Values['2800'])>2 then pBottomCapt.Caption := L.Values['2800']; if Length(L.Values['2801'])>2 then lbSampMin.Hint := L.Values['2801']; if Length(L.Values['2802'])>2 then lbSampMax.Hint := L.Values['2802']; L.Free; end; procedure TfmDesigner.Translate(LangFile: String); var L: TStringList; Ini: TIniFile; i: integer; begin L := TStringList.Create; if (LangFile = '') or not FileExists(LangFile) then Exit; { else if ExtractFileExt(LangFile) = '.lng' then begin OldTranslate(LangFile); Exit; end else Ini := TIniFile.Create(LangFile);} OldTranslate(LangFile); Ini := TIniFile.Create(LangFile); Ini.ReadSectionValues('Form', L); if Length(L.Values['Caption' ]) > 0 then Caption := L.Values['Caption' ]; if Length(L.Values[btOk.Caption ]) > 0 then btOk.Caption := L.Values[btOk.Caption ]; if Length(L.Values[btCancel.Caption ]) > 0 then btCancel.Caption := L.Values[btCancel.Caption ]; if Length(L.Values[btApply.Caption ]) > 0 then btApply.Caption := L.Values[btApply.Caption ]; if Length(L.Values[_Modified ]) > 0 then _Modified := L.Values[_Modified ]; if Length(L.Values[_Name ]) > 0 then _Name := L.Values[_Name ]; if Length(L.Values[_Extensions ]) > 0 then _Extensions := L.Values[_Extensions ]; if Length(L.Values[_Version ]) > 0 then _Version := L.Values[_Version ]; if Length(L.Values[_Date ]) > 0 then _Date := L.Values[_Date ]; if Length(L.Values[_Author ]) > 0 then _Author := L.Values[_Author ]; if Length(L.Values[_Mail ]) > 0 then _Mail := L.Values[_Mail ]; if Length(L.Values[_Web ]) > 0 then _Web := L.Values[_Web ]; if Length(L.Values[_Copyright ]) > 0 then _Copyright := L.Values[_Copyright ]; if Length(L.Values[_Company ]) > 0 then _Company := L.Values[_Company ]; if Length(L.Values[_Remark ]) > 0 then _Remark := L.Values[_Remark ]; if Length(L.Values[_DeleteNode ]) > 0 then _DeleteNode := L.Values[_DeleteNode ]; if Length(L.Values[_SaveChanges ]) > 0 then _SaveChanges := L.Values[_SaveChanges ]; if Length(L.Values[_EnterName ]) > 0 then _EnterName := L.Values[_EnterName ]; if Length(L.Values[_DeleteScheme ]) > 0 then _DeleteScheme := L.Values[_DeleteScheme ]; if Length(L.Values[_Confirm ]) > 0 then _Confirm := L.Values[_Confirm ]; Ini.ReadSectionValues('popPanels', L); with popPanels do for i := 0 to 4 do if Length(L.Values[Items[i].Caption]) > 0 then Items[i].Caption := L.Values[Items[i].Caption]; Ini.ReadSectionValues('popStandard', L); with popStandard do for i := 0 to 7 do if Length(L.Values[Items[i].Caption]) > 0 then Items[i].Caption := L.Values[Items[i].Caption]; Ini.ReadSectionValues('popTagMenus', L); with popOpenTagMenu do for i := 0 to 8 do if Length(L.Values[Items[i].Caption]) > 0 then Items[i].Caption := L.Values[Items[i].Caption]; Ini.ReadSectionValues('popTagMenus', L); with popCloseTagMenu do for i := 0 to 8 do if Length(L.Values[Items[i].Caption]) > 0 then Items[i].Caption := L.Values[Items[i].Caption]; Ini.ReadSectionValues('popRootMenu', L); with popRootMenu do for i := 0 to 15 do if Length(L.Values[Items[i].Caption]) > 0 then Items[i].Caption := L.Values[Items[i].Caption]; Ini.ReadSectionValues('popRangeMenu', L); with popRangeMenu do for i := 0 to 16 do if Length(L.Values[Items[i].Caption]) > 0 then Items[i].Caption := L.Values[Items[i].Caption]; Ini.ReadSectionValues('popKeywordsMenu', L); with popKeywordsMenu do for i := 0 to 11 do if Length(L.Values[Items[i].Caption]) > 0 then Items[i].Caption := L.Values[Items[i].Caption]; Ini.ReadSectionValues('popSetMenu', L); with popSetMenu do for i := 0 to 11 do if Length(L.Values[Items[i].Caption]) > 0 then Items[i].Caption := L.Values[Items[i].Caption]; Ini.ReadSectionValues('popSampleMemoMenu', L); with popSampleMemoMenu do for i := 0 to 9 do if Length(L.Values[Items[i].Caption]) > 0 then Items[i].Caption := L.Values[Items[i].Caption]; Ini.ReadSectionValues('popColorStd', L); with popColorStd do for i := 0 to 15 do if Length(L.Values[Items[i].Caption]) > 0 then Items[i].Caption := L.Values[Items[i].Caption]; Ini.ReadSectionValues('pLeft', L); if Length(L.Values[pLeftCapt.Caption ]) > 0 then pLeftCapt.Caption := L.Values[pLeftCapt.Caption ]; if Length(L.Values[lbRootMenu.Hint ]) > 0 then lbRootMenu.Hint := L.Values[lbRootMenu.Hint ]; Ini.ReadSectionValues('pMiddle', L); if Length(L.Values[pMiddleCapt.Caption ]) > 0 then pMiddleCapt.Caption := L.Values[pMiddleCapt.Caption ]; if Length(L.Values[lbPropBack.Hint ]) > 0 then lbPropBack.Hint := L.Values[lbPropBack.Hint ]; if Length(L.Values[lbRuleMenu.Hint ]) > 0 then lbRuleMenu.Hint := L.Values[lbRuleMenu.Hint ]; Ini.ReadSectionValues('tabRoot', L); if Length(L.Values[chCaseRoot.Caption ]) > 0 then chCaseRoot.Caption := L.Values[chCaseRoot.Caption ]; if Length(L.Values[chEnabledRoot.Caption ]) > 0 then chEnabledRoot.Caption := L.Values[chEnabledRoot.Caption ]; if Length(L.Values[lbDelimitersRoot.Caption ]) > 0 then lbDelimitersRoot.Caption := L.Values[lbDelimitersRoot.Caption ]; if Length(L.Values[btAddRangeRoot.Caption ]) > 0 then btAddRangeRoot.Caption := L.Values[btAddRangeRoot.Caption ]; if Length(L.Values[btAddKeywordsRoot.Caption ]) > 0 then btAddKeywordsRoot.Caption := L.Values[btAddKeywordsRoot.Caption ]; if Length(L.Values[btAddSetRoot.Caption ]) > 0 then btAddSetRoot.Caption := L.Values[btAddSetRoot.Caption ]; Ini.ReadSectionValues('tabRange', L); if Length(L.Values[chCaseRange.Caption ]) > 0 then chCaseRange.Caption := L.Values[chCaseRange.Caption ]; if Length(L.Values[chEnabledRange.Caption ]) > 0 then chEnabledRange.Caption := L.Values[chEnabledRange.Caption ]; if Length(L.Values[lbRangeFrom.Caption ]) > 0 then lbRangeFrom.Caption := L.Values[lbRangeFrom.Caption ]; if Length(L.Values[lbRangeTo.Caption ]) > 0 then lbRangeTo.Caption := L.Values[lbRangeTo.Caption ]; if Length(L.Values[chCloseOnWord.Caption ]) > 0 then chCloseOnWord.Caption := L.Values[chCloseOnWord.Caption ]; if Length(L.Values[chCloseOnEol.Caption ]) > 0 then chCloseOnEol.Caption := L.Values[chCloseOnEol.Caption ]; if Length(L.Values[chCloseParent.Caption ]) > 0 then chCloseParent.Caption := L.Values[chCloseParent.Caption ]; if Length(L.Values[lbDelimitersRange.Caption ]) > 0 then lbDelimitersRange.Caption := L.Values[lbDelimitersRange.Caption ]; if Length(L.Values[btAddRange.Caption ]) > 0 then btAddRange.Caption := L.Values[btAddRange.Caption ]; if Length(L.Values[btAddKeywords.Caption ]) > 0 then btAddKeywords.Caption := L.Values[btAddKeywords.Caption ]; if Length(L.Values[btAddSet.Caption ]) > 0 then btAddSet.Caption := L.Values[btAddSet.Caption ]; Ini.ReadSectionValues('tabKeywords', L); if Length(L.Values[chEnabledKeyList.Caption ]) > 0 then chEnabledKeyList.Caption := L.Values[chEnabledKeyList.Caption ]; if Length(L.Values[btSort.Hint ]) > 0 then btSort.Hint := L.Values[btSort.Hint ]; if Length(L.Values[btLowerCase.Hint ]) > 0 then btLowerCase.Hint := L.Values[btLowerCase.Hint ]; if Length(L.Values[btSpacesToEol.Hint ]) > 0 then btSpacesToEol.Hint := L.Values[btSpacesToEol.Hint ]; if Length(L.Values[_Lines ]) > 0 then _Lines := L.Values[_Lines ]; Ini.ReadSectionValues('tabSet', L); if Length(L.Values[chEnabledSet.Caption ]) > 0 then chEnabledSet.Caption := L.Values[chEnabledSet.Caption ]; if Length(L.Values[lbSymbSet.Caption ]) > 0 then lbSymbSet.Caption := L.Values[lbSymbSet.Caption ]; Ini.ReadSectionValues('tabSeveralRules', L); if Length(L.Values[Label1.Caption]) > 0 then Label1.Caption := L.Values[Label1.Caption]; Ini.ReadSectionValues('pRight', L); if Length(L.Values[pRightCapt.Caption ]) > 0 then pRightCapt.Caption := L.Values[pRightCapt.Caption ]; if Length(L.Values[chForeground.Caption ]) > 0 then chForeground.Caption := L.Values[chForeground.Caption ]; if Length(L.Values[chBackground.Caption ]) > 0 then chBackground.Caption := L.Values[chBackground.Caption ]; if Length(L.Values[chBold.Caption ]) > 0 then chBold.Caption := L.Values[chBold.Caption ]; if Length(L.Values[chItalic.Caption ]) > 0 then chItalic.Caption := L.Values[chItalic.Caption ]; if Length(L.Values[chUnderline.Caption ]) > 0 then chUnderline.Caption := L.Values[chUnderline.Caption ]; if Length(L.Values[chStrikeOut.Caption ]) > 0 then chStrikeOut.Caption := L.Values[chStrikeOut.Caption ]; { if Length(L.Values[lbScheme.Caption ]) > 0 then lbScheme.Caption := L.Values[lbScheme.Caption ]; if Length(L.Values[btNewScheme.Caption ]) > 0 then btNewScheme.Caption := L.Values[btNewScheme.Caption ]; if Length(L.Values[btDelScheme.Caption ]) > 0 then btDelScheme.Caption := L.Values[btDelScheme.Caption ]; } Ini.ReadSectionValues('pBottom', L); if Length(L.Values[pBottomCapt.Caption ]) > 0 then pBottomCapt.Caption := L.Values[pBottomCapt.Caption ]; if Length(L.Values[lbSampMin.Hint ]) > 0 then lbSampMin.Hint := L.Values[lbSampMin.Hint ]; if Length(L.Values[lbSampMax.Hint ]) > 0 then lbSampMax.Hint := L.Values[lbSampMax.Hint ]; { if Length(L.Values[]) > 0 then := L.Values[]; if Length(L.Values[]) > 0 then := L.Values[]; } L.Free; end; //=== TreeView =============================================================== procedure TfmDesigner.TreeEdited(Sender: TObject; Node: TTreeNode; var S: TNodeText); begin if Node.Data = nil then Exit; if TObject(Node.Data) is TSynRange then TSynRange(Node.Data).Name := S; if TObject(Node.Data) is TSynKeyList then TSynKeyList(Node.Data).Name := S; if TObject(Node.Data) is TSynSet then TSynSet(Node.Data).Name := S; Modified(); end; procedure TfmDesigner.TreeKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_DELETE then DoDeleteNode(Sender) else if Key = VK_F2 then DoRenameNode(Sender) else if popPropMenu = popRootMenu then if (Key = ord('X')) and (ssCtrl in Shift) then rootCutClick(Sender) else if (Key = ord('C')) and (ssCtrl in Shift) then rootCopyClick(Sender) else if (Key = ord('V')) and (ssCtrl in Shift) then rootPasteInsideClick(Sender) else else if popPropMenu = popRangeMenu then if (Key = ord('X')) and (ssCtrl in Shift) then rangeCutClick(Sender) else if (Key = ord('C')) and (ssCtrl in Shift) then rangeCopyClick(Sender) else if (Key = ord('V')) and (ssCtrl in Shift) then rangePasteInsideClick(Sender) else else if (popPropMenu = popKeywordsMenu) or (popPropMenu = popSetMenu) then if (Key = ord('X')) and (ssCtrl in Shift) then rangeCutClick(Sender) else if (Key = ord('C')) and (ssCtrl in Shift) then rangeCopyClick(Sender) else if (Key = ord('V')) and (ssCtrl in Shift) then rangePasteNextToClick(Sender) else else end; procedure TfmDesigner.TreeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); //: Handle Right Mouse Up on the Tree var iNode: TTreeNode; begin if Button <> mbRight then Exit; // Tree.PopupMenu := nil; // iNode := Tree.GetNodeAt( X, Y ); iNode := Tree.GetNodeAt( X, Y ); // Tree.PopupMenu := popRuleMenu; // Tree.Items.Item[0].Focused := True; // TreeChange(Sender, iNode); if iNode <> nil then begin iNode.Selected := True; TreeChange(Sender, Tree.Selected); // TreeChange(Sender, iNode); // popRuleMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); end; end; procedure TfmDesigner.TreeMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); //: Handle Right Mouse Up on the Tree //: ??? Переделать ??? var iNode: TTreeNode; begin if Button <> mbRight then Exit; iNode := Tree.GetNodeAt( X, Y ); // TreeChange(Sender, iNode); if iNode <> nil then iNode.Selected := True; TreeChange(Sender, Tree.Selected); { case GetNodeType(Tree.Selected) of ntRoot: popRootMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); ntRange: popRangeMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); ntKeywords: popKeywordsMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); ntSet: popSetMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); end;} popPropMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); // TreeChange(Sender, iNode); // popRuleMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); end; procedure TfmDesigner.TreeClick(Sender: TObject); begin TreeChange(Sender, Tree.Selected); end; procedure TfmDesigner.TreeChange(Sender: TObject; Node: TTreeNode); var Range: TSynRange; Symbol: string; len: integer; // list: TList; begin UpdatingControls := True; // ListBox1.Clear; // list := TList.Create; // Tree.GetSelections(list); { for i := 0 to list.Count-1 do ListBox1.Items.Add(TTreeNode(list.Items[i]).Text); list.Free;} if Tree.SelectionCount > 1 then PageControl.ActivePage := tabSeveralRules else if Tree.SelectionCount = 1 then begin // Tree.Selected := TTreeNode(list.Items[0]); case GetNodeType(Node) of ntRange, ntRangeLink: begin if (TObject(Node.Data) is TSynRangeLink) then Range := TSynRangeLink(Node.Data).Range else Range := TSynRange(Node.Data); with Range do begin Symbol := fRule.fOpenSymbol.Symbol; edFrom.Text := Symbol; len := length(Symbol); if len > 0 then chFromEOL.Checked := Symbol[len] = #0 else chFromEOL.Checked := False; Symbol := fRule.fCloseSymbol.Symbol; edTo.Text := Symbol; len := length(Symbol); if len > 0 then chToEOL.Checked := Symbol[len] = #0 else chToEOL.Checked := False; chEnabledRange.Checked := Enabled; chCloseOnWord.Checked := fRule.fCloseOnTerm; chCloseOnEOL.Checked := fRule.fCloseOnEol; chCloseParent.Checked := fRule.fAllowPredClose; chCaseRange.Checked := CaseSensitive; edDelimitersRange.Text := SetToStr(TermSymbols); popOpenTagMenu.Items.Items[2].Checked := fRule.fOpenSymbol.StartLine = slFirst; popOpenTagMenu.Items.Items[3].Checked := fRule.fOpenSymbol.StartLine = slFirstNonSpace; popCloseTagMenu.Items.Items[2].Checked := fRule.fCloseSymbol.StartLine = slFirst; popCloseTagMenu.Items.Items[3].Checked := fRule.fCloseSymbol.StartLine = slFirstNonSpace; if fRule.fOpenSymbol.StartType = stAny then if fRule.fOpenSymbol.BrakeType = btAny then popOpenTagMenu.Items.Items[5].Checked := True else popOpenTagMenu.Items.Items[7].Checked := True else if fRule.fOpenSymbol.BrakeType = btAny then popOpenTagMenu.Items.Items[6].Checked := True else popOpenTagMenu.Items.Items[8].Checked := True; if fRule.fCloseSymbol.StartType = stAny then if fRule.fCloseSymbol.BrakeType = btAny then popCloseTagMenu.Items.Items[5].Checked := True else popCloseTagMenu.Items.Items[7].Checked := True else if fRule.fCloseSymbol.BrakeType = btAny then popCloseTagMenu.Items.Items[6].Checked := True else popCloseTagMenu.Items.Items[8].Checked := True; SetControlAttributes(Node, True); PageControl.ActivePage := tabRange; end; end; ntRoot: begin chEnabledRoot.Checked := TSynRange(Node.data).Enabled; SetControlAttributes(Node, True); chCaseRoot.Checked := TSynRange(Node.data).CaseSensitive; edStylesFile.Text := SynUniSyn.SchemeFileName; edDelimitersRoot.text := SetToStr(TSynRange(Node.data).TermSymbols); PageControl.ActivePage := tabRoot; end; ntKeywords: begin chEnabledKeyList.Checked := TSynKeyList(Node.Data).Enabled; Memo.Lines.Assign(TSynKeyList(Node.Data).KeyList); SetControlAttributes(Node, True); PageControl.ActivePage := tabKeywords; end; ntSet: begin chEnabledSet.Checked := TSynSet(Node.Data).Enabled; SetControlAttributes(Node, True); edSymbSet.Text := SetToStr(TSynSet(Node.Data).SymbSet); PageControl.ActivePage := tabSet; end; end; end; UpdatingControls := False; end; //=== Fill Tree with Rules =================================================== procedure TfmDesigner.FillTree; //: Fill Tree with Rules begin TreeAddRange(nil, SynUniSyn.MainRules); end; procedure TfmDesigner.SetNodeData(Node: TTreeNode; Rule: TAbstractRule; Root: boolean); begin if Root then begin Node.ImageIndex := 0; Node.SelectedIndex := 0; end else if Rule is TSynRangeLink then begin Node.ImageIndex := 4; Node.SelectedIndex := 4; end else if Rule is TSynRange then begin Node.ImageIndex := 1; Node.SelectedIndex := 1; end else if Rule is TSynKeyList then begin Node.ImageIndex := 2; Node.SelectedIndex := 2; end else if Rule is TSynSet then begin Node.ImageIndex := 3; Node.SelectedIndex := 3; end else raise Exception.Create(ClassName + '.SetNodeData - Unknown rule to set node!'); Node.Data := Rule; end; function TfmDesigner.TreeAddRule(ParentNode: TTreeNode; Rule: TSynRule; AddKind: TAddKind): TTreeNode; begin // if Rule is TSynRangeLink then Result:= TreeAddRangeLink(ParentNode, TSynRangeLink(Rule), AddKind) else if Rule is TSynRange then Result:= TreeAddRange(ParentNode, TSynRange(Rule), AddKind) else if Rule is TSynKeyList then Result:= TreeAddKeyList(ParentNode, TSynKeyList(Rule), AddKind) else if Rule is TSynSet then Result:= TreeAddSet(ParentNode, TSynSet(Rule), AddKind) else raise Exception.Create(ClassName + '.TreeAddRule - Unknown rule to add!'); end; function TfmDesigner.TreeAddRangeLink(Node: TTreeNode; RangeLink: TSynRangeLink; AddKind: TAddKind): TTreeNode; begin Result := Tree.Items.AddChild(Node, RangeLink.Range.Name); SetNodeData(Result, RangeLink); end; function TfmDesigner.TreeAddRange(Node: TTreeNode; Range: TSynRange; AddKind: TAddKind): TTreeNode; var i, ind: integer; begin if AddKind = akReplace then Result := Node else if Node = nil then begin Result := Tree.Items.Add(nil, Range.Name); SetNodeData(Result, Range, True); end else begin if AddKind = akInsert then begin ind := Node.Index; {$IFNDEF FPC} Result := Tree.Items.Insert(Node.Parent.Item[ind], Range.Name) {$ELSE} Result := Tree.Items.Insert(Node.Parent.Items[ind], Range.Name) {$ENDIF} end else Result := Tree.Items.AddChild(Node, Range.Name); SetNodeData(Result, Range); end; for i := 0 to Range.KeyListCount-1 do TreeAddKeyList(Result, Range.KeyLists[i]); for i := 0 to Range.SetCount-1 do TreeAddSet(Result, Range.Sets[i]); for i := 0 to Range.RangeCount-1 do TreeAddRange(Result, Range.Ranges[i]); end; function TfmDesigner.TreeAddKeyList(Node: TTreeNode; Keyword: TSynKeyList; AddKind: TAddKind): TTreeNode; var i, ind: integer; NeedToInsert: boolean; begin if AddKind = akReplace then Result := Node else if AddKind = akInsert then begin ind := Node.Index; {$IFNDEF FPC} Result := Tree.Items.Insert(Node.Parent.Item[ind], Keyword.Name) {$ELSE} Result := Tree.Items.Insert(Node.Parent.Items[ind], Keyword.Name) {$ENDIF} end else if Node.Count = 0 then Result := Tree.Items.AddChild(Node, Keyword.Name) else begin NeedToInsert := False; for i := 0 to Node.Count-1 do {$IFNDEF FPC} if (TObject(Node.Item[i].Data) is TSynRange) or (TObject(Node.Item[i].Data) is TSynSet) then begin {$ELSE} if (TObject(Node.Items[i].Data) is TSynRange) or (TObject(Node.Items[i].Data) is TSynSet) then begin {$ENDIF} NeedToInsert := True; break; end; {$IFNDEF FPC} if NeedToInsert then Result := Tree.Items.Insert(Node.Item[i], Keyword.Name) {$ELSE} if NeedToInsert then Result := Tree.Items.Insert(Node.Items[i], Keyword.Name) {$ENDIF} else Result := Tree.Items.AddChild(Node, Keyword.Name); end; SetNodeData(Result, Keyword); end; function TfmDesigner.TreeAddSet(Node: TTreeNode; SymbSet: TSynSet; AddKind: TAddKind): TTreeNode; var i, ind: integer; NeedToInsert: boolean; begin if AddKind = akReplace then Result := Node else if AddKind = akInsert then begin ind := Node.Index; {$IFNDEF FPC} Result := Tree.Items.Insert(Node.Parent.Item[ind], SymbSet.Name) {$ELSE} Result := Tree.Items.Insert(Node.Parent.Items[ind], SymbSet.Name) {$ENDIF} end else if Node.Count = 0 then Result := Tree.Items.AddChild(Node, SymbSet.Name) else begin NeedToInsert := False; for i := 0 to Node.Count-1 do {$IFNDEF FPC} if TObject(Node.Item[i].Data) is TSynRange then begin {$ELSE} if TObject(Node.Items[i].Data) is TSynRange then begin {$ENDIF} NeedToInsert := True; break; end; {$IFNDEF FPC} if NeedToInsert then Result := Tree.Items.Insert(Node.Item[i], SymbSet.Name) {$ELSE} if NeedToInsert then Result := Tree.Items.Insert(Node.Items[i], SymbSet.Name) {$ENDIF} else Result := Tree.Items.AddChild(Node, SymbSet.Name); end; SetNodeData(Result, SymbSet); end; //=== Adding RangeLink ======================================================= procedure TfmDesigner.DoAddRangeLinkToRoot(Sender:TObject); //: Click on button begin AddingRangeLink(Tree.Items[0]); Modified(); end; procedure TfmDesigner.DoAddRangeLink(Sender: TObject); //: Click on button begin AddingRangeLink(Tree.Selected); Modified(); end; procedure TfmDesigner.AddingRangeLink(ParentNode: TTreeNode); var Node: TTreeNode; RangeLink: TSynRangeLink; // i: integer; begin RangeLink := TSynRangeLink.Create(SynUniSyn.MainRules.Ranges[6]); TSynRange(ParentNode.Data).AddRangeLink(RangeLink); Node := TreeAddRangeLink(ParentNode, RangeLink); with Node do begin Expand(False); Selected := True; Tree.SetFocus; EditText; end; { Range.ClearAttributes(); for i := 0 to SynUniSyn.SchemesList.Count-1 do begin TSynRange(ParentNode.Data).SetAttributesIndex(i); Range.AddAttribute(); SetDefaultAttributes(Node); end; TSynRange(ParentNode.Data).SetAttributesIndex(SynUniSyn.SchemeIndex);} SetControlAttributes(Node); end; //=== Adding Range =========================================================== procedure TfmDesigner.DoAddRangeToRoot(Sender:TObject); //: Click on button begin AddingRange(Tree.Items[0]); Modified(); end; procedure TfmDesigner.DoAddRange(Sender: TObject); //: Click on button begin AddingRange(Tree.Selected); Modified(); end; procedure TfmDesigner.AddingRange(ParentNode: TTreeNode); var Node: TTreeNode; Range: TSynRange; i: integer; begin if ParentNode = nil then begin //Never happened ??? Tree.Items.Clear; Node := Tree.Items.Add(nil, _Root); SynUniSyn.MainRules.Name := _Root; Node.Data := SynUniSyn.MainRules; Node.ImageIndex := 0; Node.SelectedIndex := 0; Exit; end else begin Range := TSynRange.Create; Range.Name := _New; TSynRange(ParentNode.Data).AddRange(Range); Node := TreeAddRange(ParentNode, Range); with Node do begin Expand(False); Selected := True; Tree.SetFocus; EditText; end; end; // Range.ClearAttributes(); for i := 0 to SynUniSyn.SchemesList.Count-1 do begin // TSynRange(ParentNode.Data).SetAttributesIndex(i); // Range.AddAttribute(); SetDefaultAttributes(Node); end; // TSynRange(ParentNode.Data).SetAttributesIndex(SynUniSyn.SchemeIndex); SetControlAttributes(Node); end; //=== Adding KeyList ========================================================= procedure TfmDesigner.DoAddKeywordToRoot(Sender:TObject); //: Click on button begin AddingKeyword(Tree.Items[0]); Modified(); end; procedure TfmDesigner.DoAddKeyword(Sender: TObject); //: Click on button begin AddingKeyWord(Tree.selected); Modified(); end; procedure TfmDesigner.AddingKeyWord(ParentNode: TTreeNode); var Node: TTreeNode; Keyword: TSynKeyList; i: integer; begin Keyword := TSynKeyList.Create; Keyword.Name := _New; Node := TreeAddKeyList(ParentNode, Keyword); with Node do begin Expand(False); Selected := True; Tree.SetFocus; EditText; end; // Keyword.ClearAttributes(); for i := 0 to SynUniSyn.SchemesList.Count-1 do begin // TSynRange(ParentNode.Data).SetAttributesIndex(i); // Keyword.AddAttribute(); SetDefaultAttributes(Node); end; // TSynRange(ParentNode.Data).SetAttributesIndex(SynUniSyn.SchemeIndex); TSynRange(ParentNode.Data).AddKeyList(Keyword); SetControlAttributes(Node); end; //=== Adding Set ============================================================= procedure TfmDesigner.DoAddSetToRoot(Sender:TObject); //: Click on button begin AddingSet(Tree.Items[0]); Modified(); end; procedure TfmDesigner.DoAddSet(Sender: TObject); //: Click on button begin AddingSet(Tree.Selected); Modified(); end; procedure TfmDesigner.AddingSet(ParentNode: TTreeNode); var Node: TTreeNode; SymbolSet: TSynSet; i: integer; begin SymbolSet := TSynSet.Create; SymbolSet.Name := _New; TSynRange(ParentNode.data).AddSet(SymbolSet); Node := TreeAddSet(ParentNode, SymbolSet); with Node do begin Expand(False); Selected := True; Tree.SetFocus; EditText; end; // SymbolSet.ClearAttributes(); for i := 0 to SynUniSyn.SchemesList.Count-1 do begin // TSynRange(ParentNode.Data).SetAttributesIndex(i); // SymbolSet.AddAttribute(); SetDefaultAttributes(Node); end; // TSynRange(ParentNode.Data).SetAttributesIndex(SynUniSyn.SchemeIndex); SetControlAttributes(Node); end; //=== Delete and Rename Rules ================================================ procedure TfmDesigner.DoDeleteNode(Sender: TObject); begin if not Tree.IsEditing then if not ShowDialog or (Application.MessageBox(PChar(Format(_DeleteNode,[Tree.Selected.Text])), PChar(_Confirm), MB_YESNOCANCEL+MB_ICONQUESTION) = ID_YES) then begin DeleteNode(Tree.Selected); TotalUpdate; Modified(); end; ShowDialog := True; end; procedure TfmDesigner.DeleteNode(Node: TTreeNode; OnlyChilds: boolean); begin //Node.DeleteChildren; - когда-нить исправить! while Node.Count > 0 do DeleteNode(Node[0]); if (TSynRange(Node.Data) <> SynUniSyn.MainRules) and not OnlyChilds then begin if TObject(Node.Data) is TSynRange then TSynRange(Node.Parent.Data).DeleteRange(TSynRange(Node.Data)) else if TObject(Node.Data) is TSynKeyList then TSynRange(Node.Parent.Data).DeleteKeyList(TSynKeyList(Node.Data)) else if TObject(Node.Data) is TSynSet then TSynRange(Node.Parent.Data).DeleteSet(TSynSet(Node.Data)); Node.Delete; end; end; procedure TfmDesigner.DoRenameNode(Sender: TObject); begin Tree.Selected.EditText; end; //=== Usefuk functions... ==================================================== function TfmDesigner.GetNodeType(Node: TTreeNode): TNodeType; begin Result := ntNone; if Node <> nil then if (TObject(Node.Data) is TSynRange) and (Node.Level = 0) then Result := ntRoot else if (TObject(Node.Data) is TSynRangeLink) then Result := ntRangeLink else if (TObject(Node.Data) is TSynRange) then Result := ntRange else if (TObject(Node.Data) is TSynKeyList) then Result := ntKeywords else if (TObject(Node.Data) is TSynSet) then Result := ntSet; end; procedure TfmDesigner.TotalUpdate; begin SynUniSyn.Reset; SynUniSyn.MainRules.Reset; SynUniSyn.ResetRange; SynUniSyn.Prepare; SampleMemo.Highlighter := nil; SampleMemo.Highlighter := SynUniSyn; SampleMemo.Refresh; end; procedure TfmDesigner.Modified(State: boolean = True); begin if State then begin btApply.Enabled := True; StatusBar.Panels.Items[0].Text := _Modified; end else begin btApply.Enabled := False; StatusBar.Panels.Items[0].Text := ''; end; end; //=== KeyList Tools ========================================================== procedure TfmDesigner.btSort_oldClick(Sender: TObject); var i: integer; begin With TStringList.Create do try Sorted := True; Duplicates := dupIgnore; for i := 0 to Memo.Lines.Count-1 do if Trim(Memo.Lines[i]) <> '' then Add(Trim(Memo.Lines[i])); Sort; Memo.Text := Trim(Text); finally Free; end; end; procedure TfmDesigner.btLowerCase_oldClick(Sender: TObject); begin Memo.text := LowerCase(Memo.Text); end; procedure TfmDesigner.btSpacesToEol_oldClick(Sender: TObject); begin Memo.text := StringReplace(Memo.Text, ' ', #13#10, [rfReplaceAll]); end; //=== Finish buttons ========================================================= procedure TfmDesigner.btOkClick(Sender: TObject); begin if Tree.IsEditing then Tree.Selected.EndEdit(False) else if btApply.Enabled then begin btApplyClick(Sender); ModalResult := mrOk; end else if (btApply.Tag = 1) then ModalResult := mrOk else ModalResult := mrCancel; ForceClose := True; end; procedure TfmDesigner.btCancelClick(Sender: TObject); begin ModalResult := mrCancel; ForceClose := True; end; procedure TfmDesigner.btApplyClick(Sender: TObject); var Stream: TMemoryStream; begin Stream := TMemoryStream.Create; SynUniSyn.SaveToStream(Stream); Stream.Position := 0; OriginalSyn.LoadFromStream(Stream); OriginalSyn.Info.Sample.Text := SampleMemo.Text; Modified(False); btApply.Tag := 1; end; //=== Work with schemes ====================================================== {procedure TfmDesigner.btNewSchemeClick(Sender: TObject); var Name: string; begin if InputQuery(_EnterName, _EnterName, Name) then begin SynUniSyn.AddNewScheme(Name); SynUniSyn.MainRules.Attribs.ParentForeground := False; SynUniSyn.MainRules.Attribs.ParentBackground := False; cbScheme.ItemIndex := cbScheme.Items.Add(Name); SetControlAttributes(Tree.Selected); TotalUpdate; Modified(); end; end; procedure TfmDesigner.btDelSchemeClick(Sender: TObject); var Index: integer; begin if cbScheme.Items.Count > 1 then if Application.MessageBox(PChar(_DeleteScheme),PChar(_Confirm),MB_YESNOCANCEL+MB_ICONQUESTION) = ID_YES then begin Index := cbScheme.ItemIndex; cbScheme.Items.Delete(Index); SynUniSyn.DeleteScheme(Index); if cbScheme.Items.Count = Index then cbScheme.ItemIndex := Index-1 else cbScheme.ItemIndex := Index; SetControlAttributes(Tree.Selected); TotalUpdate; Modified(); end; end; procedure TfmDesigner.cbSchemeSelect(Sender: TObject); begin SynUniSyn.SetSchemeIndex(cbScheme.ItemIndex); SetControlAttributes(Tree.Selected); TotalUpdate; Modified(); end; procedure TfmDesigner.cbSchemeChange(Sender: TObject); var SelStart, SelLength: integer; begin if cbScheme.ItemIndex > -1 then cbScheme.Tag := cbScheme.ItemIndex; SelStart := cbScheme.SelStart; SelLength := cbScheme.SelLength; cbScheme.Items[cbScheme.Tag] := cbScheme.Text; cbScheme.ItemIndex := cbScheme.Tag; SynUniSyn.SchemesList.Strings[cbScheme.Tag] := cbScheme.Text; cbScheme.SelStart := SelStart; cbScheme.SelLength := SelLength; Modified(); end;} //=== Rules changed ========================================================== procedure TfmDesigner.RootChange(Sender: TObject); var i: integer; begin if UpdatingControls then Exit; with SynUniSyn do begin SchemeFileName := edStylesFile.Text; if Styles <> nil then begin Styles.Free; Styles := nil; end; if FileExists(SchemeFileName) then begin Styles := TSynUniStyles.Create; Styles.FileName := SchemeFileName; Styles.Load; end; end; with TSynRange(Tree.Selected.Data) do begin if GetNodeType(Tree.Selected) in [ntRoot] then begin CaseSensitive := chCaseRoot.Checked; Enabled := chEnabledRoot.Checked; end; TermSymbols := []; { the apparently useless typecast to char is for CLX compatibility } for i := 1 to length(edDelimitersRoot.Text) do TermSymbols := TermSymbols + [char(edDelimitersRoot.Text[i])]; TotalUpdate; end; Modified(); end; procedure TfmDesigner.RangeChange(Sender: TObject); var i: integer; null: string; Range: TSynRange; begin if UpdatingControls then Exit; if GetNodeType(Tree.Selected) in [ntRange, ntRangeLink] then begin if TObject(Tree.Selected.Data) is TSynRange then Range := TSynRange(Tree.Selected.Data) else if TObject(Tree.Selected.Data) is TSynRangeLink then Range := TSynRangeLink(Tree.Selected.Data).Range else Exit; with Range do begin if chFromEOL.Checked then null := #0 else null := ''; fRule.fOpenSymbol.Symbol := edFrom.Text + null; if chToEOL.Checked then null := #0 else null := ''; fRule.fCloseSymbol.Symbol := edTo.Text + null; Enabled := chEnabledRange.Checked; fRule.fCloseOnTerm := chCloseOnWord.Checked; fRule.fCloseOnEol := chCloseOnEOL.Checked; fRule.fAllowPredClose := chCloseParent.Checked; CaseSensitive := chCaseRange.Checked; TermSymbols := StrToSet(edDelimitersRange.Text); { the apparently useless typecast to char is for CLX compatibility } for i := 1 to Length(edDelimitersRange.Text) do TermSymbols := TermSymbols + [Char(edDelimitersRange.Text[i])]; if popOpenTagMenu.Items.Items[2].Checked then fRule.fOpenSymbol.StartLine := slFirst else if popOpenTagMenu.Items.Items[3].Checked then fRule.fOpenSymbol.StartLine := slFirstNonSpace else fRule.fOpenSymbol.StartLine := slNotFirst; if popCloseTagMenu.Items.Items[2].Checked then fRule.fCloseSymbol.StartLine := slFirst else if popCloseTagMenu.Items.Items[3].Checked then fRule.fCloseSymbol.StartLine := slFirstNonSpace else fRule.fCloseSymbol.StartLine := slNotFirst; if popOpenTagMenu.Items.Items[5].Checked then begin fRule.fOpenSymbol.StartType := stAny; fRule.fOpenSymbol.BrakeType := btAny; end else if popOpenTagMenu.Items.Items[6].Checked then begin fRule.fOpenSymbol.StartType := stTerm; fRule.fOpenSymbol.BrakeType := btAny; end else if popOpenTagMenu.Items.Items[7].Checked then begin fRule.fOpenSymbol.StartType := stAny; fRule.fOpenSymbol.BrakeType := btTerm; end else if popOpenTagMenu.Items.Items[8].Checked then begin fRule.fOpenSymbol.StartType := stTerm; fRule.fOpenSymbol.BrakeType := btTerm; end; if popCloseTagMenu.Items.Items[5].Checked then begin fRule.fCloseSymbol.StartType := stAny; fRule.fCloseSymbol.BrakeType := btAny; end else if popCloseTagMenu.Items.Items[6].Checked then begin fRule.fCloseSymbol.StartType := stTerm; fRule.fCloseSymbol.BrakeType := btAny; end else if popCloseTagMenu.Items.Items[7].Checked then begin fRule.fCloseSymbol.StartType := stAny; fRule.fCloseSymbol.BrakeType := btTerm; end else if popCloseTagMenu.Items.Items[8].Checked then begin fRule.fCloseSymbol.StartType := stTerm; fRule.fCloseSymbol.BrakeType := btTerm; end; end; end; TotalUpdate; Modified(); end; procedure TfmDesigner.KeywordsChange(Sender: TObject); begin lbKeywordCount.Caption := Format(_Lines, [Memo.Lines.Count]); if UpdatingControls then Exit; TSynKeyList(Tree.Selected.Data).Enabled := chEnabledKeyList.Checked; TSynKeyList(Tree.Selected.Data).KeyList.Text := Memo.Lines.Text; TotalUpdate; Modified(); end; procedure TfmDesigner.SetChange(Sender: TObject); begin if UpdatingControls then Exit; TSynSet(Tree.Selected.Data).Enabled := chEnabledSet.Checked; TSynSet(Tree.Selected.Data).SymbSet := StrToSet(edSymbSet.Text); TotalUpdate; Modified(); end; //=== Wotk with Attributes =================================================== procedure TfmDesigner.AttributesChanged(Sender: TObject); begin SetAttributes(Tree.Selected); end; procedure TfmDesigner.SetDefaultAttributes(Node: TTreeNode); begin if TObject(Node.Data) is TSynRule then with TSynRule(Node.Data).Attribs do begin ParentForeground := True; ParentBackground := True; Foreground := TSynRange(Node.Parent.Data).Attribs.Foreground; Background := TSynRange(Node.Parent.Data).Attribs.Background; OldColorForeground := Foreground; OldColorBackground := Background; Style := []; end end; procedure TfmDesigner.SetControlAttributes(Node: TTreeNode; AlreadyUpdate: boolean); var Rule: TSynRule; isCustom: boolean; i: integer; begin UpdatingControls := True; if GetNodeType(Node) in [ntRoot] then begin chForeground.Enabled := False; chBackground.Enabled := False; end else begin chForeground.Enabled := True; chBackground.Enabled := True; end; if TObject(Node.Data) is TSynRule then Rule := TSynRule(Node.Data) else if TObject(Node.Data) is TSynRangeLink then Rule := TSynRangeLink(Node.Data).Range else raise Exception.Create(ClassName + '.SetControlAttributes - Wrong Node data!'); with Rule do begin isCustom := True; for i := 0 to cbStyle.Items.Count-2 do if cbStyle.Items.Strings[i] = Style then begin cbStyle.ItemIndex := i; isCustom := False; continue; end; if isCustom then begin cbStyle.ItemIndex := cbStyle.Items.Count-2; //cbStyle.Text := Style; end; if GetNodeType(Node) in [ntRoot] then begin Attribs.ParentForeground := False; //Need to fix this problem another way... !!! Attribs.ParentBackground := False; end; chForeground.Checked := Attribs.ParentForeground; chBackground.Checked := Attribs.ParentBackground; if Attribs.ParentForeground then pForeColor.Color := TSynRange(Node.Parent.Data).Attribs.Foreground else pForeColor.Color := Attribs.Foreground; if Attribs.ParentBackground then pBackColor.Color := TSynRange(Node.Parent.Data).Attribs.Background else pBackColor.Color := Attribs.Background; chBold.checked := fsBold in Attribs.Style; chItalic.checked := fsItalic in Attribs.Style; chUnderline.checked := fsUnderline in Attribs.Style; chStrikeOut.checked := fsStrikeOut in Attribs.Style; end; if not AlreadyUpdate then UpdatingControls := False; end; procedure TfmDesigner.SetAttributes(Node: TTreeNode); var Rule: TSynRule; begin if UpdatingControls then Exit; if (Node <> nil) then begin if (TObject(Node.Data) is TSynRule) then Rule := TSynRule(Node.Data) else if (TObject(Node.Data) is TSynRangeLink) then Rule := TSynRangeLink(Node.Data).Range else Exit; with Rule.Attribs, Rule do begin Style := cbStyle.Text; if (ParentForeground and not chForeground.Checked) then begin if pForeColor.Color = Foreground then pForeColor.Color := OldColorForeground; end else if (not ParentForeground and chForeground.Checked) then begin OldColorForeground := pForeColor.Color; pForeColor.Color := TSynRange(Node.Parent.Data).Attribs.Foreground end else if chForeground.Checked then if pForeColor.Color <> Foreground then chForeground.Checked := False; if (ParentBackground and not chBackground.Checked) then begin if pBackColor.Color = Background then pBackColor.Color := OldColorBackground; end else if (not ParentBackground and chBackground.Checked) then begin OldColorBackground := pBackColor.Color; pBackColor.Color := TSynRange(Node.Parent.Data).Attribs.Background end else if chBackground.Checked then if pBackColor.Color <> Background then chBackground.Checked := False; ParentForeground := chForeground.Checked; ParentBackground := chBackground.Checked; Foreground := pForeColor.Color; Background := pBackColor.Color; Attribs.Style := GetFontStyle(chBold.checked, chItalic.checked, chUnderline.checked, chStrikeOut.checked); if Styles <> nil then begin Attribs := Styles.GetStyleDef(Style, Attribs); SetControlAttributes(Node); end; if TObject(Node.data) is TSynRange then TSynRange(Node.data).SetColorForChilds; TotalUpdate; end; end; Modified(); end; //============================ D E S I G N =================================== //=== Splitter CanResize ===================================================== procedure TfmDesigner.SplitterBottomCanResize(Sender: TObject; var NewSize: Integer; var Accept: Boolean); begin if pTop.Tag <> -1 then begin Accept := False; Exit; end; if pBottom.Height <= pBottom.Constraints.MinHeight then lbSampMin.Enabled := False else lbSampMin.Enabled := True; if pTop.Height = 0 then lbSampMax.Enabled := False else lbSampMax.Enabled := True; if (0 <= NewSize) and (NewSize < 19) then NewSize := 0 else if (19 <= NewSize) and (NewSize <= 19+10) then NewSize := 19 else if (_pTopHeight-10 <= NewSize) and (NewSize <= _pTopHeight+10) then NewSize := _pTopHeight end; procedure TfmDesigner.SplitterCannotResize(Sender: TObject; var NewSize: Integer; var Accept: Boolean); begin Accept := False; end; //=== Label Mouse Leave/Enter ================================================ procedure TfmDesigner.LabelMouseLeave(Sender: TObject); begin (Sender as TLabel).Font.Color := clBtnFace; end; procedure TfmDesigner.LabelMouseEnter(Sender: TObject); begin (Sender as TLabel).Font.Color := clRed; end; procedure TfmDesigner.LabelContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); begin LabelMouseLeave(Sender); end; //=== CheckBox =============================================================== procedure TfmDesigner.CheckBoxMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbRight then with (Sender as TCheckBox) do Checked := not Checked; end; procedure TfmDesigner.DontNeedContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); begin Handled := True; end; //=== Show/Hide panels ======================================================= procedure TfmDesigner.ShowHideTree(Sender: TObject); begin if pLeft.Visible then begin pLeft.Hide; SplitterLeft.Hide; end else begin SplitterLeft.Show; pLeft.Show; end; end; procedure TfmDesigner.ShowHideProp(Sender: TObject); begin if pMiddle.Visible then begin pMiddle.Hide; SplitterLeft.Hide; pLeft.Tag := pLeft.Width; pLeft.Align := alClient; end else begin pLeft.Align := alLeft; pLeft.Width := pLeft.Tag; SplitterLeft.Show; pMiddle.Show; end; end; procedure TfmDesigner.ShowHideAttr(Sender: TObject); begin if pRight.Visible then begin pRight.Hide; SplitterRight.Hide; end else begin pRight.Show; SplitterRight.Show; end; end; procedure TfmDesigner.ShowHideSamp(Sender: TObject); begin if pBottom.Visible then begin pBottom.Hide; SplitterBottom.Hide; pTop.Tag := pTop.Height; pTop.Align := alClient; end else begin pTop.Align := alTop; pTop.Height := pTop.Tag; SplitterBottom.Show; pBottom.Show; end; end; procedure TfmDesigner.PanelDblClick(Sender: TObject); begin if (Sender as TPanel).Name = 'pBottomCapt' then begin if pTop.Height = _pTopHeight then lbSampMaxClick(Sender) else begin pTop.Height := _pTopHeight; lbSampMin.Enabled := True; if pTop.Tag <> -1 then lbSampMinClick(Sender); if not pTop.Visible then lbSampMaxClick(Sender); end; end; end; //=== Middle panel Resize ==================================================== procedure TfmDesigner.pMiddleResize(Sender: TObject); begin if tabRoot.Width <> pRootButtons.Width then begin pRootButtons.ScaleBy(tabRoot.Width, pRootButtons.Width); pRootButtons.Height := 24; btAddRangeRoot.Height := 24; btAddKeywordsRoot.Height := 24; btAddSetRoot.Height := 24; end; if tabRange.Width <> pRangeButtons.Width then begin pRangeButtons.ScaleBy(tabRange.Width, pRangeButtons.Width); pRangeButtons.Height := 24; btAddRange.Height := 24; btAddKeywords.Height := 24; btAddSet.Height := 24; end; end; //=== Push label clicks ====================================================== procedure TfmDesigner.lbPropBackClick(Sender: TObject); begin if (Tree.Selected <> Tree.Items[0]) and (Tree.Selected <> nil) then Tree.Selected.Parent.Selected := True; end; procedure TfmDesigner.lbRootMenuClick(Sender: TObject); begin popRootMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); LabelMouseLeave(Sender); end; procedure TfmDesigner.lbRuleMenuClick(Sender: TObject); begin popPropMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); LabelMouseLeave(Sender); end; procedure TfmDesigner.lbSampMaxClick(Sender: TObject); begin if pTop.Visible then begin //: Not maximized (Maximize) pTop.Hide; lbSampMax.Caption := '2'; if pTop.Tag <> -1 then //: Minimized (Restore) lbSampMinClick(Sender); end else begin //: Maximized (Restore) pTop.Show; lbSampMax.Caption := '1'; end; end; (* procedure TfmDesigner.lbSampRestoreClick(Sender: TObject); begin pTop.Height := _pTopHeight; end; *) procedure TfmDesigner.lbSampMinClick(Sender: TObject); begin if pTop.Tag = -1 then begin //: Not minimized (Minimize) pTop.Tag := pTop.Height; pTop.Height := ClientHeight - pBottom.Constraints.MinHeight - SplitterBottom.Height - pButtons.ClientHeight - StatusBar.ClientHeight - SplitterButtons.ClientHeight; lbSampMin.Caption := '2'; if not pTop.Visible then //: Miximized (Restore) lbSampMaxClick(Sender); end else begin //: Minimized (Restore) pTop.Height := pTop.Tag; PTop.Tag := -1; lbSampMin.Caption := '0'; end; end; //============================ P O P U P S =================================== //=== Standard PopupMenu ===================================================== procedure TfmDesigner.SetPopupMenuEnables(Edit: TCustomEdit; popMenu: TPopupMenu); begin with popMenu, Edit do begin Items[0].Enabled := CanUndo; Items[2].Enabled := SelLength <> 0; Items[3].Enabled := SelLength <> 0; Items[4].Enabled := Clipboard.AsText <> ''; Items[5].Enabled := Length(Edit.Text) <> 0;//SelLength <> 0; Items[7].Enabled := Text <> SelText; end; end; procedure TfmDesigner.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin SetPopupMenuEnables((Sender as TCustomEdit), popStandard); end; procedure TfmDesigner.EditContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); begin SetPopupMenuEnables((Sender as TCustomEdit), popStandard); end; procedure TfmDesigner.popUndoClick(Sender: TObject); begin (ActiveControl as TCustomEdit).Undo; SetPopupMenuEnables((ActiveControl as TCustomEdit), popStandard); end; procedure TfmDesigner.popCutClick(Sender: TObject); begin (ActiveControl as TCustomEdit).CutToClipboard; SetPopupMenuEnables((ActiveControl as TCustomEdit), popStandard); end; procedure TfmDesigner.popCopyClick(Sender: TObject); begin (ActiveControl as TCustomEdit).CopyToClipboard; SetPopupMenuEnables((ActiveControl as TCustomEdit), popStandard); end; procedure TfmDesigner.popPasteClick(Sender: TObject); begin (ActiveControl as TCustomEdit).PasteFromClipboard; SetPopupMenuEnables((ActiveControl as TCustomEdit), popStandard); end; procedure TfmDesigner.popDeleteClick(Sender: TObject); begin if (ActiveControl as TCustomEdit).SelLength = 0 then (ActiveControl as TCustomEdit).SelLength := 1; (ActiveControl as TCustomEdit).ClearSelection; SetPopupMenuEnables((ActiveControl as TCustomEdit), popStandard); end; procedure TfmDesigner.popSelectAllClick(Sender: TObject); begin (ActiveControl as TCustomEdit).SelectAll; SetPopupMenuEnables((ActiveControl as TCustomEdit), popStandard); end; //=== Sample Memo PopupMenu ================================================== procedure TfmDesigner.SetPopupMenuEnables2(Edit: TCustomSynEdit; popMenu: TPopupMenu); begin with popMenu, Edit do begin Items[0].Enabled := (Edit.SelEnd - Edit.SelStart) <> 0; Items[2].Enabled := CanUndo; Items[4].Enabled := (Edit.SelEnd - Edit.SelStart) <> 0; Items[5].Enabled := (Edit.SelEnd - Edit.SelStart) <> 0; Items[6].Enabled := Clipboard.AsText <> ''; Items[7].Enabled := (Edit.SelEnd - Edit.SelStart) <> 0; Items[8].Enabled := Text <> SelText; end; end; procedure TfmDesigner.SampleMemoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin SetPopupMenuEnables2(SampleMemo, popSampleMemoMenu); end; procedure TfmDesigner.SampleMemoMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin SetPopupMenuEnables2(SampleMemo, popSampleMemoMenu); end; procedure TfmDesigner.Undo1Click(Sender: TObject); begin SampleMemo.Undo; end; procedure TfmDesigner.Cut1Click(Sender: TObject); begin SampleMemo.CutToClipboard; end; procedure TfmDesigner.Copy1Click(Sender: TObject); begin SampleMemo.CopyToClipboard; end; procedure TfmDesigner.Paste1Click(Sender: TObject); begin SampleMemo.PasteFromClipboard; end; procedure TfmDesigner.Delete1Click(Sender: TObject); begin SampleMemo.ClearSelection; end; procedure TfmDesigner.SelectAll1Click(Sender: TObject); begin SampleMemo.SelectAll; end; procedure TfmDesigner.AddselectedtoKeywords1Click(Sender: TObject); begin if PageControl.ActivePage = tabKeyWords then begin Memo.Lines.Add(SampleMemo.SelText); TotalUpdate; end; end; procedure TfmDesigner.popSampleMemoMenuPopup(Sender: TObject); begin popSampleMemoMenu.Items[0].Visible := PageControl.ActivePage = tabKeyWords; popSampleMemoMenu.Items[1].Visible := PageControl.ActivePage = tabKeyWords; end; //=== Tag Menu Clicks... ===================================================== procedure TfmDesigner.btTagMenuClick(Sender: TObject); var P: TPoint; begin // popTagMenu.Tag := Mouse.CursorPos.X + Mouse.CursorPos.Y shl 16; P := (Sender as TButton).ClientToScreen(Point(0, 0)); if (Sender as TButton).Name = 'btFromMenu' then popOpenTagMenu.Popup(P.x, P.y) else if (Sender as TButton).Name = 'btToMenu' then popCloseTagMenu.Popup(P.x, P.y) // popTagMenu.Popup(popTagMenu.Tag and $FFFF, // popTagMenu.Tag shr 16); end; procedure TfmDesigner.miTagMenuClick(Sender: TObject); begin if not (Sender as TMenuItem).Checked then (Sender as TMenuItem).Checked := True; RangeChange(Sender); end; procedure TfmDesigner.miOpenTagMenuClick(Sender: TObject); var i: integer; begin i := popOpenTagMenu.Items.IndexOf(Sender as TMenuItem); if popOpenTagMenu.Items.Items[5-i].Checked then popOpenTagMenu.Items.Items[5-i].Checked := False; RangeChange(Sender); end; procedure TfmDesigner.miCloseTagMenuClick(Sender: TObject); var i: integer; begin i := popCloseTagMenu.Items.IndexOf(Sender as TMenuItem); if popCloseTagMenu.Items.Items[5-i].Checked then popCloseTagMenu.Items.Items[5-i].Checked := False; RangeChange(Sender); end; //=== ColorBox Clicks... ===================================================== procedure TfmDesigner.PanelColorChange(Sender: TObject); //: Handle clicking on Color panel (Show ColorBox to choose color) begin with TColorDialog.Create(nil) do try CustomColors.Text := 'ColorA='+inttohex((Sender as TPanel).Color,6)+#13#10+'ColorB=FFFFEE'+#13#10+'ColorC=EEFFFF'+#13#10+'ColorD=EEFFEE'+#13#10+'ColorE=EEEEFF'+#13#10+'ColorF=FFEEEE'+#13#10+'ColorG=EEEEEE'+#13#10+'ColorH=FFEEAA'+#13#10+'ColorJ=FFAAEE'+#13#10+'ColorK=AAFFEE'+#13#10+'ColorI=AAEEFF'+#13#10+'ColorL=EEFFAA'+#13#10+'ColorM=EEAAFF'+#13#10+'ColorN=AAAAAA'+#13#10+'ColorO=DDDDDD'+#13#10+'ColorP=999999'; Color := (Sender as TPanel).Color; {$IFNDEF SYN_CLX} {$IFNDEF FPC} Options := [cdFullOpen]; {$ENDIF} {$ENDIF} if Execute then begin (Sender as TPanel).Color := Color; SetAttributes(Tree.Selected); end; finally Free; end; end; procedure TfmDesigner.miColor16Click(Sender: TObject); begin if popColorStd.Tag = 1 then pForeColor.Color := Colors16[(Sender as TMenuItem).ImageIndex] else if popColorStd.Tag = 2 then pBackColor.Color := Colors16[(Sender as TMenuItem).ImageIndex]; SetAttributes(Tree.Selected); end; procedure TfmDesigner.miColorSysClick(Sender: TObject); begin if popColorStd.Tag = 1 then pForeColor.Color := ColorsSys[(Sender as TMenuItem).ImageIndex] else if popColorStd.Tag = 2 then pBackColor.Color := ColorsSys[(Sender as TMenuItem).ImageIndex]; SetAttributes(Tree.Selected); end; procedure TfmDesigner.miColor40Click(Sender: TObject); begin if popColorStd.Tag = 1 then pForeColor.Color := Colors40[(Sender as TMenuItem).ImageIndex] else if popColorStd.Tag = 2 then pBackColor.Color := Colors40[(Sender as TMenuItem).ImageIndex]; SetAttributes(Tree.Selected); end; {$IFNDEF FPC} procedure TfmDesigner.Color40MeasureItem(Sender: TObject; ACanvas: TCanvas; var Width, Height: Integer); begin Width := 6; end; {$ELSE} procedure TfmDesigner.Color40MeasureItem(Sender: TObject; ACanvas: TCanvas; var AWidth, AHeight: Integer); begin AWidth := 6; end; {$ENDIF} procedure TfmDesigner.pColorMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); //var P: TPoint; begin // if (Button = mbRight) or (Button = mbMiddle) then if ((Sender as TPanel).Name = 'pForeColor') or ((Sender as TPanel).Name = 'pForeColorArrow') then popColorStd.Tag := 1 else if ((Sender as TPanel).Name = 'pBackColor') or ((Sender as TPanel).Name = 'pBackColorArrow') then popColorStd.Tag := 2; // P := ((Sender as TPanel).Parent as TPanel).ClientToScreen(Point(-1, ((Sender as TPanel).Parent as TPanel).Height-1)); if (Button = mbMiddle) then popColorSys.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y) else if ((Button = mbRight) and (ssLeft in Shift)) then popColorAdv.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y) else if Button = mbRight then if ssShift in Shift then popColorAdv.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y) else popColorStd.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); end; procedure TfmDesigner.pColorArrowMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); //var P: TPoint; begin // if (Button = mbRight) or (Button = mbMiddle) then if ((Sender as TPanel).Name = 'pForeColor') or ((Sender as TPanel).Name = 'pForeColorArrow') then popColorStd.Tag := 1 else if ((Sender as TPanel).Name = 'pBackColor') or ((Sender as TPanel).Name = 'pBackColorArrow') then popColorStd.Tag := 2; // P := ((Sender as TPanel).Parent as TPanel).ClientToScreen(Point(-1, ((Sender as TPanel).Parent as TPanel).Height-1)); if ((Sender as TPanel).Name = 'pForeColorArrow') or ((Sender as TPanel).Name = 'pBackColorArrow') then (Sender as TPanel).BevelInner := bvLowered; if (Button = mbLeft) then popColorStd.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); if (Button = mbMiddle) then popColorAdv.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y) else if ((Button = mbRight) and (ssLeft in Shift)) then popColorAdv.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y) else if Button = mbRight then if ssShift in Shift then popColorAdv.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y) else popColorSys.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); if ((Sender as TPanel).Name = 'pForeColorArrow') or ((Sender as TPanel).Name = 'pBackColorArrow') then (Sender as TPanel).BevelInner := bvNone; end; //=== TabSheet showing ======================================================= procedure TfmDesigner.tabRootShow(Sender: TObject); begin popPropMenu := popRootMenu; end; procedure TfmDesigner.tabRangeShow(Sender: TObject); begin popPropMenu := popRangeMenu; end; procedure TfmDesigner.tabKeywordsShow(Sender: TObject); begin popPropMenu := popKeywordsMenu; end; procedure TfmDesigner.tabSetShow(Sender: TObject); begin popPropMenu := popSetMenu; end; ///////////////////////////////////////////////////////////////////////////////// // RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING // // RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING // // RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING // // RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING // // RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING // // RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING RESORTING // ///////////////////////////////////////////////////////////////////////////////// //=== Work with files ======================================================== //procedure TfmDesigner.LoadFromFileClick(Sender: TObject); //resourcestring // sUniFileDescription = 'UniHighlighter Syntax'; //var // iDlg: TOpenDialog; // iFile: TFileStream; // iNode: TTreeNode; // iRange: TSynRange; // cSub: integer; //begin // { TreeMenuPopup should handle this } // Assert( TObject(Tree.Selected.Data) is TSynRange ); // iNode := Tree.Selected; // iRange := TSynRange(iNode.Data); // iDlg := TOpenDialog.Create( nil ); // try // iDlg.DefaultExt := '.hgl'; // iDlg.Filter := sUniFileDescription + ' (*.hgl)|*.hgl'; // if not iDlg.Execute then // Exit; // iFile := TFileStream.Create( iDlg.FileName, fmOpenRead or fmShareDenyWrite ); // try // if iRange = SynUniSyn.MainRules then // begin // SynUniSyn.LoadFromStream( iFile ); // Tree.Items.Clear; // FillTree; // SampleMemo.Lines.Text := SynUniSyn.SampleSource; // iNode := Tree.Items[0]; // end // else begin // iRange.LoadFromStream( iFile ); // iNode.DeleteChildren; // for cSub := 0 to iRange.KeyListCount - 1 do // TreeAddKeyList( iNode, iRange.KeyLists[cSub] ); // for cSub := 0 to iRange.RangeCount - 1 do // TreeAddRange( iNode, iRange.Ranges[cSub] ); // end; // iNode.Expand( False ); // TotalUpdate; // finally // iFile.Free; // end; // finally // iDlg.Free; // end; // Modified(); //end; procedure TfmDesigner.rootSaveToFileClick(Sender: TObject); begin if SaveDialog.Execute then SynUniSyn.SaveToFile(SaveDialog.FileName); end; procedure TfmDesigner.rootLoadFromFileClick(Sender: TObject); var Ext: string; EditPlus: TSynUniImportEditPlus; UltraEdit: TSynUniImportUltraEdit; begin if OpenDialog.Execute then begin Ext := ExtractFileExt(OpenDialog.FileName); try if SameText(Ext, '.hgl') or SameText(Ext, '.hlr') then SynUniSyn.{LoadHglFromFile}LoadFromFile(OpenDialog.FileName) else if SameText(Ext, '.stx') then begin EditPlus := TSynUniImportEditPlus.Create(); EditPlus.LoadFromFile(OpenDialog.FileName); EditPlus.Import(SynUniSyn.MainRules, SynUniSyn.Info); EditPlus.Free; end else if SameText(Ext, '.txt') then begin UltraEdit := TSynUniImportUltraEdit.Create(); UltraEdit.LoadFromFile(OpenDialog.FileName); UltraEdit.Import(SynUniSyn.MainRules, SynUniSyn.Info); UltraEdit.Free; { else // '.hlr' SynUniSyn.LoadFromFile(OpenDialog.FileName);} end else raise Exception.Create(ClassName + '.rootLoadFromFile - Bad file extension!'); finally Tree.Items.Clear; FillTree; SampleMemo.Lines.Text := SynUniSyn.SampleSource; Tree.Items[0].Expand(False); TotalUpdate; Modified(); end; end; end; procedure TfmDesigner.rangeLoadFromFileClick(Sender: TObject); begin if OpenDialog.Execute then begin if Application.MessageBox('It will delete current rule. Continue?', PChar(_Confirm), MB_OKCANCEL+MB_ICONQUESTION) = ID_OK then begin DeleteNode(Tree.Selected, True); TSynRule(Tree.Selected.Data).LoadFromFile(OpenDialog.FileName); //Сделать, что можно загрузить Keywords в Ranges и т.д... TreeAddRange(Tree.Selected, TSynRange(Tree.Selected.Data), akReplace); TreeChange(Sender, Tree.Selected); Tree.Selected.Text := TSynRule(Tree.Selected.Data).Name; Tree.Items[0].Expand(False); TotalUpdate; Modified(); end; end; end; procedure TfmDesigner.rangeSaveToFileClick(Sender: TObject); begin if SaveDialog.Execute then SynUniSyn.SaveToFile(SaveDialog.FileName, TSynRule(Tree.Selected.Data)); end; //=== Clipboard ============================================================== procedure TfmDesigner.StreamToClipboard(Stream: TStream); var Buf: PChar; BufSize: Integer; begin buf := nil; // Чтобы убрать Warning компилятора try BufSize := Stream.Size; GetMem(Buf, BufSize+1); Stream.Position := 0; Stream.ReadBuffer(Buf^, BufSize); Buf[BufSize] := #0; Clipboard.SetTextBuf(Buf); finally FreeMem(Buf); Stream.Free; end; end; function TfmDesigner.GetClipboardAsStream: TMemoryStream; var hClipbrd: THandle; Buf: PChar; begin {$note Error 2} {$IFNDEF FPC} Result := TMemoryStream.Create; ClipBoard.Open; try hClipbrd := Clipboard.GetAsHandle(CF_TEXT); Buf := GlobalLock(hClipbrd); Result.WriteBuffer(Buf^, StrLen(Buf)); Result.Position := 0; GlobalUnlock(hClipbrd); finally Clipboard.Close; end; {$ENDIF} end; //=== Root range ============================================================= procedure TfmDesigner.rootCutClick(Sender: TObject); begin rootCopyClick(Sender); ShowDialog := False; DoDeleteNode(Sender); end; procedure TfmDesigner.rootCopyClick(Sender: TObject); begin StreamToClipboard(SynUniSyn.GetAsStream()); end; procedure TfmDesigner.rootPasteInsideClick(Sender: TObject); begin Tree.Selected.Selected := False; Tree.Selected := Tree.Items[0]; rangePasteInsideClick(Sender); end; procedure TfmDesigner.rootPasteAndReplaceClick(Sender: TObject); begin Tree.Selected := Tree.Items[0]; DeleteNode(Tree.Selected, True); SynUniSyn.LoadFromStream(GetClipboardAsStream); TreeAddRange(Tree.Selected, SynUniSyn.MainRules, akReplace); TreeChange(nil, Tree.Selected); Tree.Selected.Text := TSynRule(Tree.Selected.Data).Name; SampleMemo.Text := SynUniSyn.Info.Sample.Text; TotalUpdate; Modified(); end; //=== Other rules ============================================================ procedure TfmDesigner.rangeCutClick(Sender: TObject); begin rangeCopyClick(Sender); ShowDialog := False; DoDeleteNode(Sender); end; procedure TfmDesigner.rangeCopyClick(Sender: TObject); begin StreamToClipboard(TSynRule(Tree.Selected.Data).GetAsStream); end; procedure TfmDesigner.rangePasteInsideClick(Sender: TObject); var Rule: TSynRule; begin if (copy(Clipboard.AsText, 1, Length(' '' then InfoText := InfoText + Format(_Name, [General.Name]) + #13#10 else InfoText := InfoText + Format(_Name, ['']) + #13#10; if General.Extensions <> '' then InfoText := InfoText + Format(_Extensions, [General.Extensions]) + #13#10; InfoText := InfoText + Format(_Version, [IntToStr(Version.Version) + '.' + IntToStr(Version.Revision)]) + #13#10; InfoText := InfoText + Format(_Date, [DateTimeToStr(Version.ReleaseDate)]) + #13#10; if Author.Name <> '' then InfoText := InfoText + Format(_Author, [Author.Name]) + #13#10; if Author.Email <> '' then InfoText := InfoText + Format(_Mail, [Author.Email]) + #13#10; if Author.Web <> '' then InfoText := InfoText + Format(_Web, [Author.Web]) + #13#10; if Author.Copyright <> '' then InfoText := InfoText + Format(_Copyright, [Author.Copyright]) + #13#10; if Author.Company <> '' then InfoText := InfoText + Format(_Company, [Author.Company]) + #13#10; if Author.Remark <> '' then InfoText := InfoText + Format(_Remark, [Author.Remark]) + #13#10; Application.MessageBox(PChar(InfoText),'About highlighter...', MB_ICONINFORMATION); end; end; procedure TfmDesigner.btStylesFileClick(Sender: TObject); //var // xml: TXMLParser; ++++++++++++ begin { if OpenDialog2.Execute then begin edStylesFile.Text := OpenDialog2.FileName; ComboBox2.Clear; xml := TXMLParser.Create; try if xml.LoadFromFile(edStylesFile.Text) then begin xml.StartScan; while xml.Scan do if (xml.CurPartType = ptStartTag) and SameText(xml.CurName, 'Scheme') then ComboBox2.Items.Add(xml.CurAttr.Value('Name')); end; finally xml.Free; end; ComboBox2.ItemIndex := 0; end; } end; //============================================================================ end. doublecmd-0.8.2/components/synunihighlighter/source/SynUniRules.pas0000664000175000017500000020051713056765731024725 0ustar alexxalexx{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is: SynUniHighlighter.pas, released 2003-01 All Rights Reserved. Alternatively, the contents of this file may be used under the terms of the GNU General Public License Version 2 or later (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. }{ @abstract(Provides a universal highlighter for SynEdit) @authors(Fantasist [walking_in_the_sky@yahoo.com], Vit [nevzorov@yahoo.com], Vitalik [vetal-x@mail.ru]) @created(2003) @lastmod(2004-05-12) } unit SynUniRules; interface uses SysUtils, Graphics, Classes, SynEditHighlighter, SynUniClasses, Laz2_DOM; type TSynRange = class; TSynSet = class; //Vitalik 2004 TAbstractSymbol = class function GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; virtual; abstract; end; TSymbols = class(TAbstractSymbol) HeadNode: TSymbolNode; SynSets: TList; //Vitalik 2004 function GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; override; function FindSymbol(st: string): TSymbolNode; procedure AddSymbol(st: string; tkSynSymbol: TSynSymbol; ABrakeType: TSymbBrakeType); procedure AddSet(SymbolSet: TSynSet); //Vitalik 2004 constructor Create(ch: char; tkSynSymbol: TSynSymbol; ABrakeType: TSymbBrakeType); reintroduce; overload; virtual; constructor Create(SymbolSet: TSynSet); reintroduce; overload; virtual; //Vitalik 2004 destructor Destroy(); override; end; TDefaultSymbols = class(TAbstractSymbol) tkSynSymbol: TSynSymbol; function GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; override; constructor Create(SynSymb: TSynSymbol); reintroduce; virtual; destructor Destroy(); override; end; TDefaultTermSymbols = class(TAbstractSymbol) tkSynSymbol: TSynSymbol; function GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; override; constructor Create(SynSymb: TSynSymbol); virtual; destructor Destroy(); override; end; TSynKeyList = class (TSynRule) KeyList: TStringList; constructor Create(st: string = ''); destructor Destroy(); override; procedure LoadHglFromXml(xml: TDOMNode; SchCount,SchIndex: integer); //Vitalik 2004 procedure LoadFromXml(xml: TDOMNode); override; //Vitalik 2004 procedure SaveToStream(StreamWriter: TStreamWriter; Ind: integer = 0); overload; override; //Vitalik 2004 end; TSynKeyListLink = class(TAbstractRule) //Vitalik 2004 KeyList: TSynKeyList; end; TSynSet = class (TSynRule) //Vitalik 2004 SymbSet: TSymbSet; StartType: TSymbStartType; BrakeType: TSymbBrakeType; constructor Create(aSymbSet: TSymbSet = []); destructor Destroy(); override; procedure LoadHglFromXml(xml: TDOMNode; SchCount,SchIndex: integer); procedure LoadFromXml(xml: TDOMNode); override; procedure SaveToStream(StreamWriter: TStreamWriter; Ind: integer = 0); overload; override; end; TSynSetLink = class(TAbstractRule) //Vitalik 2004 SynSet: TSynSet; end; TSynRangeLink = class(TAbstractRule) //Vitalik 2004 Range: TSynRange; Parent: TSynRange; constructor Create(aRange: TSynRange); virtual; end; TSynRangeRule = class fCloseSymbol: TSynSymbol; fOpenSymbol: TSynSymbol; fCloseOnTerm: boolean; fCloseOnEol: boolean; fAllowPredClose: boolean; //Vitalik 2004 constructor Create(OpenSymbs: string = ''; CloseSymbs: string = ''); destructor Destroy(); override; end; TSynRange = class (TSynRule) private fCaseSensitive: boolean; fOwner: TSynRange; fSynSymbols: TList; fSynRanges: TList; fSynKeyLists: TList; fSynSets: TList; //Vitalik 2004 StringCaseFunct: function (const st: string): string; fPrepared: boolean; public {temp} OpenCount: integer; ParentBackup: TSynRange; fRule: TSynRangeRule; fClosingSymbol: TSynSymbol; fDefaultSynSymbol: TSynSymbol; fDefaultSymbols: TDefaultSymbols; fDefaultTermSymbol: TDefaultTermSymbols; fCommonSynRanges: TList; fSynRangeLinks: TList; CaseFunct: function (ch: char): char; fTermSymbols: TSymbSet; HasNodeAnyStart: array[char] of boolean; //Vitalik 2004 SymbolList: array[char] of TAbstractSymbol; private function GetSynSymbol(Index: Integer): TSynSymbol; function GetCommonSynRange(Index: Integer): TSynRange; function GetSynRangeLink(Index: Integer): TSynRangeLink; function GetSynRange(Index: Integer): TSynRange; function GetSynKeyList(Index: Integer): TSynKeyList; function GetSynSet(Index: Integer): TSynSet; //Vitalik 2004 function GetSynSymbolCount(): Integer; function GetCommonSynRangeCount(): Integer; function GetSynRangeLinkCount(): Integer; function GetSynRangeCount(): Integer; function GetSynKeyListCount(): Integer; function GetSynSetCount(): Integer; //Vitalik 2004 function GetCaseSensitive: boolean; procedure SetCaseSensitive(const Value: boolean); public {temp} procedure LoadHglFromXml(xml: TDOMNode; SchCount, SchIndex: integer); //Vitalik 2004 procedure LoadFromXml(xml: TDOMNode); override; //Vitalik 2004 procedure SaveToStream(StreamWriter: TStreamWriter; Ind: integer = 0); overload; override; //Vitalik 2004 public constructor Create(OpenSymbs: string = ''; CloseSymbs: string = ''); virtual; destructor Destroy(); override; procedure AddSynSymbol(NewSymb: TSynSymbol); procedure AddRule(NewRule: TSynRule); procedure AddCommonRange(Range: TSynRange); procedure AddRangeLink(NewRangeLink: TSynRangeLink); overload; function AddRangeLink(aRange: TSynRange; aName: string; aColor: TColor): TSynRangeLink; overload; procedure AddRange(NewRange: TSynRange); overload; function AddRange(aOpen, aClose, aName: string; aColor: TColor): TSynRange; overload; procedure AddKeyList(NewKeyList: TSynKeyList); overload; function AddKeyList(aName: string; aColor: TColor): TSynKeyList; overload; procedure AddSet(NewSet: TSynSet); overload; //Vitalik 2004 function AddSet(aName: string; aSymbSet: TSymbSet; aColor: TColor): TSynSet; overload;//Vitalik 2004 function FindSymbol(st: string): TSynSymbol; function FindSymbolOwner(Symbol: TSynSymbol): TSynKeyList; procedure DeleteCommonRange(index: integer); overload; procedure DeleteCommonRange(Range: TSynRange); overload; procedure DeleteRangeLink(index: integer); overload; procedure DeleteRangeLink(RangeLink: TSynRangeLink); overload; procedure DeleteRange(index: integer); overload; procedure DeleteRange(Range: TSynRange); overload; procedure DeleteKeyList(index: integer); overload; procedure DeleteKeyList(KeyList: TSynKeyList); overload; procedure DeleteSet(index: integer); overload; //Vitalik 2004 procedure DeleteSet(SynSet: TSynSet); overload; //Vitalik 2004 { procedure SetParentColor; procedure RestoreOldColor; } procedure SetDelimiters(Delimiters: TSymbSet); // procedure SetStyles(aStyles: TSynUniStyles); procedure SetColorForChilds(); //Vitalik 2004 procedure ClearParsingFields(); procedure ResetParents(aParent: TSynRange); procedure Prepare(Owner: TSynRange); procedure Reset(); procedure Clear(); function FindRange(const Name: string): TSynRange; procedure LoadHglFromStream(aSrc: TStream); public property TermSymbols: TSymbSet read fTermSymbols write fTermSymbols; // property OpenSymbol: TSynSymbol read fOpenSymbol; // property CloseSymbol: TSynSymbol read fCloseSymbol; // property CloseOnTerm: boolean read fCloseOnTerm write fCloseOnTerm; // property CloseOnEol: boolean read fCloseOnEol write fCloseOnEol; // property AllowPredClose: boolean read fAllowPredClose write fAllowPredClose; //Vitalik 2004 property CommonRanges[index: integer]: TSynRange read GetCommonSynRange; property CommonRangeCount: integer read GetCommonSynRangeCount; property RangeLinks[index: integer]: TSynRangeLink read GetSynRangeLink; property RangeLinkCount: integer read GetSynRangeLinkCount; property Ranges[index: integer]: TSynRange read GetSynRange; property RangeCount: integer read GetSynRangeCount; property Symbols[index: integer]: TSynSymbol read GetSynSymbol; property SymbolCount: integer read GetSynSymbolCount; property KeyLists[index: integer]: TSynKeyList read GetSynKeyList; property KeyListCount: Integer read GetSynKeyListCount; property Sets[index: integer]: TSynSet read GetSynSet; //Vitalik 2004 property SetCount: Integer read GetSynSetCount; //Vitalik 2004 property CaseSensitive: boolean read GetCaseSensitive write SetCaseSensitive; property Prepared: boolean read fPrepared; property Parent: TSynRange read fOwner write fOwner; end; //function Verify(tag: string; xml: TXMLParser): boolean; overload; const DefaultTermSymbols: TSymbSet = ['*','/','+','-','=','\','|','&','(',')', '[',']','{','}','`','~','!','@',',','$','%','^','?',':',';','''','"','.', '>','<','#']; implementation uses Laz2_XMLRead; function CaseNone(ch: char): char; //: Need for CaseSensitive begin Result := ch; end; function StringCaseNone(const st: string): string; //: Need for CaseSensitive begin Result := st; end; //==== TSymbols ============================================================== procedure TSymbols.AddSymbol(st: string; tkSynSymbol: TSynSymbol; ABrakeType: TSymbBrakeType); //: Add SynSymbol to the tree Symbols var i: integer; l: integer; Node: TSymbolNode; SList: TSymbolList; begin SList := HeadNode.NextSymbs; //: All branches of current node (first - root node) Node := nil; //: Current Node l := Length(st); //: Length of adding string for i := 1 to l do //: Check all symbols of adding string begin Node := SList.FindSymbol(st[i]); //: Try to find current symbol of adding string among branches if Node = nil then //: If we can't find current symbol begin Node := TSymbolNode.Create(st[i]); //: then create node with current symbol SList.AddSymbol(Node); //: and add it to current branches end; SList := Node.NextSymbs; //: Go to finded or added node end; Node.StartType := tkSynSymbol.StartType; Node.BrakeType := ABrakeType; //: Set Break Type and ... Node.tkSynSymbol := tkSynSymbol; //: ... SynSymbol of last Node end; constructor TSymbols.Create(ch: char; tkSynSymbol: TSynSymbol; ABrakeType: TSymbBrakeType); begin HeadNode := TSymbolNode.Create(ch, tkSynSymbol, ABrakeType); SynSets := TList.Create; end; constructor TSymbols.Create(SymbolSet: TSynSet); begin SynSets := TList.Create; AddSet(SymbolSet); end; destructor TSymbols.Destroy; begin if Assigned(HeadNode) then HeadNode.Free; FreeList(SynSets); inherited; end; function TSymbols.FindSymbol(st: string): TSymbolNode; //: Find string st in the tree Symbols var i: integer; l: integer; Node, prvNode: TSymbolNode; begin Node := HeadNode; //: Root of the tree l := Length(st); //: Length of string for i := 1 to l do begin prvNode := Node.NextSymbs.FindSymbol(st[i]); if prvNode = nil then //: If don't find break; //: Exit from cycle Node := prvNode; //: Else go to the brench or nil, if don't find end; Result := Node; //: Return node, if found, and nil, if not found end; procedure TSymbols.AddSet(SymbolSet: TSynSet);// ABrakeType: TSymbBrakeType); begin SynSets.Add(SymbolSet); end; function TSymbols.GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; //: Try to find any token var curNode, nxtStart, prevFind: TSymbolNode; i, posStart, posNext, posPrev: integer; AllowedTermSymbols: TSymbSet; function CanBeToken(): boolean; var i: integer; begin CanBeToken := True; if curNode.tkSynSymbol = nil then CanBeToken := False else if (curNode.BrakeType = btTerm) and not (fLine[succ(Run)] in CurRule.fTermSymbols) then CanBeToken := False else case curNode.tkSynSymbol.StartLine of slFirstNonSpace: for i := 0 to posStart-1 do {$IFNDEF FPC} if not (fLine[i] in [' ', #32, #9]) then begin {$ELSE} if not (fLine[i] in [#32, #9]) then begin {$ENDIF} CanBeToken := False; break; end; slFirst: if posStart <> 0 then CanBeToken := False; end; end; begin //Vitalik 2004 Result := False; posStart := Run; if Assigned(HeadNode) then begin curNode := HeadNode; posNext := posStart; nxtStart := nil; repeat if nxtStart <> nil then begin curNode := nxtStart; Run := posNext; nxtStart := nil; end; if CanBeToken then prevFind := curNode else prevFind := nil; posPrev := Run; while (curNode.NextSymbs.Count > 0) and (fLine[Run] <> #0) do begin inc(Run); curNode := curNode.NextSymbs.FindSymbol(CurRule.CaseFunct(fLine[Run])); if curNode = nil then begin dec(Run); break; end; if CanBeToken then begin prevFind := curNode; posPrev := Run; end; if nxtStart = nil then if (CurRule.HasNodeAnyStart[CurRule.CaseFunct(curNode.ch)] or (curNode.ch in CurRule.fTermSymbols) or (CurRule.CaseFunct(fLine[Run]) in CurRule.fTermSymbols)) then begin nxtStart := curNode; posNext := Run; end; end; Run := posPrev; if prevFind = nil then continue; if prevFind.tkSynSymbol = nil then continue; //Never happened??? if fLine[Run] <> #0 then //: Go to next symbol in line if it isn't end of line inc(Run); if prevFind.BrakeType = btAny then begin //: If token can end by any symbol Result := True; //: We find it! tkSynSymbol := prevFind.tkSynSymbol; //: Here it is! Exit; end; if fLine[Run] in CurRule.fTermSymbols then begin //: If token can end by delimeter and current symbol is delimeter Result := True; //: We find it! tkSynSymbol := prevFind.tkSynSymbol; //: Here it is! Exit; end; until nxtStart = nil; end; //l1: {begin} Run := posStart; // Result := False; AllowedTermSymbols := CurRule.fTermSymbols; for i := 0 to SynSets.Count-1 do begin AllowedTermSymbols := AllowedTermSymbols - TSynSet(SynSets[i]).SymbSet; end; for i := 0 to SynSets.Count-1 do begin Run := posStart; repeat inc(Run); until not (fLine[Run] in TSynSet(SynSets[i]).SymbSet) or (fLine[Run] = #0); //: If number ends on some Term-symbol, then if TSynSet(SynSets[i]).BrakeType = btAny then begin Result := True; //: We find it! tkSynSymbol := TSynSymbol.Create('', TSynSet(SynSets[i]).Attribs); exit; end; if (fLine[Run] in AllowedTermSymbols) then begin Result := True; //: We find it! tkSynSymbol := TSynSymbol.Create('', TSynSet(SynSets[i]).Attribs); exit; end; end; Run := succ(posStart); {end} { was: Result := false; curNode := HeadNode; nxtNode := nil; while (curNode.NextSymbs.Count > 0) and (parser.fLine[parser.Run] <> #0) do begin inc(parser.Run); nxtNode := curNode.NextSymbs.FindSymbol(parser.fCurrentRule.CaseFunct(parser.fLine[parser.Run])); //: Ищем этот символ среди текущих веток if nxtNode = nil then begin dec(parser.Run); break; end; curNode := nxtNode; end; if curNode.tkSynSymbol = nil then exit; if (nxtNode = nil) and (curNode.NextSymbs.Count > 0) then dec(parser.Run); if parser.fLine[parser.Run] <> #0 then inc(parser.Run); if curNode.BrakeType = btAny then begin Result := True; tkSynSymbol := curNode.tkSynSymbol; exit; end; if parser.fLine[parser.Run] in parser.fCurrentRule.fTermSymbols then begin Result := True; tkSynSymbol := curNode.tkSynSymbol; end; } end; //==== TDefaultSymbols ======================================================= constructor TDefaultSymbols.Create(SynSymb: TSynSymbol); begin tkSynSymbol := SynSymb; end; destructor TDefaultSymbols.Destroy; begin tkSynSymbol.Free; inherited; end; function TDefaultSymbols.GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; //: Read just symbol, nothing to return begin inc(Run); Result := False; end; //==== TDefaultTermSymbols =================================================== constructor TDefaultTermSymbols.Create(SynSymb: TSynSymbol); begin tkSynSymbol := SynSymb; end; destructor TDefaultTermSymbols.Destroy; begin tkSynSymbol.Free; inherited; end; function TDefaultTermSymbols.GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; begin if fLine[Run] <> #0 then //: If is not end of line then Inc(Run); //: go to next symbol in fLine tkSynSymbol := self.tkSynSymbol; //: And return DefaultTermSymbol Result := True; //: We found token end; ////////////////////////////////////////////////////////////////////////////// // RRRRRRR UUU UUU LLL EEEEEEE SSSSSS // // R R U U L E S // // RRRRRR U U L EEEEE SSSSSS // // R R U U L L E S // // RRR RR UUUUU LLLLLLL EEEEEEE SSSSSS // ////////////////////////////////////////////////////////////////////////////// //==== TSynKeyList =========================================================== constructor TSynKeyList.Create(st: string); begin inherited Create; // AddAttribute(); KeyList := TStringList.Create; KeyList.Text := st; end; destructor TSynKeyList.Destroy; begin KeyList.Free; inherited; end; //==== TSynSet ========================================================= constructor TSynSet.Create(aSymbSet: TSymbSet = []); //Vitalik 2004 begin inherited Create; // AddAttribute(); SymbSet := aSymbSet; end; destructor TSynSet.Destroy; //Vitalik 2004 begin inherited; end; //==== TSynRangeRule ========================================================= constructor TSynRangeRule.Create(OpenSymbs: string = ''; CloseSymbs: string = ''); begin fOpenSymbol := TSynSymbol.Create(OpenSymbs, nil); fCloseSymbol := TSynSymbol.Create(CloseSymbs, nil); end; destructor TSynRangeRule.Destroy(); begin fOpenSymbol.Free(); fCloseSymbol.Free(); end; //==== TSynRange ============================================================= constructor TSynRange.Create(OpenSymbs: string; CloseSymbs: string); begin inherited Create; OpenCount := 0; fRule := TSynRangeRule.Create(OpenSymbs, CloseSymbs); fRule.fOpenSymbol.StartType := stAny; fRule.fOpenSymbol.BrakeType := btAny; fRule.fCloseSymbol.StartType := stAny; fRule.fCloseSymbol.BrakeType := btAny; FillChar(SymbolList, sizeof(SymbolList), 0); SetCaseSensitive(False); fPrepared := False; fRule.fCloseOnTerm := False; fRule.fCloseOnEol := False; fSynKeyLists := TList.Create; fSynSets := TList.Create; fSynSymbols := TList.Create; fSynRanges := TList.Create; fSynRangeLinks := TList.Create; fTermSymbols := DefaultTermSymbols; // AddAttribute(); end; destructor TSynRange.Destroy; //: Destructor of TSynRange begin //# Reset; ??? fRule.Free(); { if Assigned(fRule.fOpenSymbol) then fRule.fOpenSymbol.Free; if Assigned(fRule.fCloseSymbol) then fRule.fCloseSymbol.Free;} // Attribs.Free; FreeList(fSynKeyLists); FreeList(fSynSets); FreeList(fSynSymbols); FreeList(fSynRanges); FreeList(fSynRangeLinks); inherited; end; //=== Work with fSynSymbols ================================================== procedure TSynRange.AddSynSymbol(NewSymb: TSynSymbol); //: Add SynSymbol to the list fSynSymbols. If SynSymbol already exist in list //: then remove it and add to the end of the list //: ??? Может надо если существет не добавлять??? var SynSym: TSynSymbol; begin SynSym := FindSymbol(NewSymb.Symbol); if SynSym <> nil then begin fSynSymbols.Remove(SynSym); SynSym.Free; end; // NewSymb.Order := Order; fSynSymbols.Add(NewSymb); end; function TSynRange.FindSymbol(st: string): TSynSymbol; //: Find SynSymbol (Symbol = st) in the list fSynSymbols var i: integer; begin Result := nil; for i := 0 to fSynSymbols.Count-1 do if TSynSymbol(fSynSymbols.Items[i]).Symbol = st then begin Result := TSynSymbol(fSynSymbols.Items[i]); exit; end; end; //============================================================================ function TSynRange.FindSymbolOwner(Symbol: TSynSymbol): TSynKeyList; //: Find KeyList that contain SynSymbol //> Never used!!! var i, j: integer; begin Result := nil; for i := 0 to fSynKeyLists.Count-1 do if TSynKeyList(fSynKeyLists[i]).KeyList.Find(Symbol.Symbol, j) then begin Result := TSynKeyList(fSynKeyLists[i]); exit; end; end; //=== Adding rules =========================================================== procedure TSynRange.AddRule(NewRule: TSynRule); begin if NewRule is TSynRange then AddRange(NewRule as TSynRange) else if NewRule is TSynKeyList then AddKeyList(NewRule as TSynKeyList) else if NewRule is TSynSet then AddSet(NewRule as TSynSet) else raise Exception.Create('!!!'); end; procedure TSynRange.AddCommonRange(Range: TSynRange); begin fSynRangeLinks.Add(Range); end; procedure TSynRange.AddRangeLink(NewRangeLink: TSynRangeLink); begin fSynRangeLinks.Add(NewRangeLink); end; function TSynRange.AddRangeLink(aRange: TSynRange; aName: string; aColor: TColor): TSynRangeLink; begin Result := TSynRangeLink.Create(aRange); with Result do begin Name := aName; Attribs.Foreground := aColor; Attribs.ParentForeground := False; end; AddRangeLink(Result); end; procedure TSynRange.AddRange(NewRange: TSynRange); begin fSynRanges.Add(NewRange); end; function TSynRange.AddRange(aOpen, aClose, aName: string; aColor: TColor): TSynRange; begin Result := TSynRange.Create(aOpen, aClose); with Result do begin Name := aName; Attribs.Foreground := aColor; Attribs.ParentForeground := False; end; AddRange(Result); end; procedure TSynRange.AddKeyList(NewKeyList: TSynKeyList); begin fSynKeyLists.Add(NewKeyList); end; function TSynRange.AddKeyList(aName: string; aColor: TColor): TSynKeyList; begin Result := TSynKeyList.Create(''); with Result do begin Name := aName; Attribs.Foreground := aColor; Attribs.ParentForeground := False; end; AddKeyList(Result); end; procedure TSynRange.AddSet(NewSet: TSynSet); //Vitalik 2004 begin fSynSets.Add(NewSet); end; function TSynRange.AddSet(aName: string; aSymbSet: TSymbSet; aColor: TColor): TSynSet; //Vitalik 2004 begin Result := TSynSet.Create(aSymbSet); with Result do begin Name := aName; Attribs.Foreground := aColor; Attribs.ParentForeground := False; end; AddSet(Result); end; //=== Deleting rules ========================================================= procedure TSynRange.DeleteCommonRange(index: integer); begin TSynRangeLink(fCommonSynRanges[index]).Free; fCommonSynRanges.Delete(index); end; procedure TSynRange.DeleteCommonRange(Range: TSynRange); begin fCommonSynRanges.Remove(Range); end; procedure TSynRange.DeleteRangeLink(index: integer); begin TSynRangeLink(fSynRangeLinks[index]).Free; fSynRangeLinks.Delete(index); end; procedure TSynRange.DeleteRangeLink(RangeLink: TSynRangeLink); begin fSynRangeLinks.Remove(RangeLink); RangeLink.Free; end; procedure TSynRange.DeleteRange(Range: TSynRange); begin fSynRanges.Remove(Range); Range.Free; end; procedure TSynRange.DeleteRange(index: integer); begin TSynRange(fSynRanges[index]).Free; fSynRanges.Delete(index); end; procedure TSynRange.DeleteKeyList(KeyList: TSynKeyList); begin fSynKeyLists.Remove(KeyList); KeyList.Free; end; procedure TSynRange.DeleteKeyList(index: integer); begin TSynKeyList(fSynKeyLists[index]).Free; fSynKeyLists.Delete(index); end; procedure TSynRange.DeleteSet(SynSet: TSynSet); //Vitalik 2004 begin fSynSets.Remove(SynSet); SynSet.Free; end; procedure TSynRange.DeleteSet(index: integer); //Vitalik 2004 begin TSynSet(fSynSets[index]).Free; fSynSets.Delete(index); end; //=== GetCount rules ========================================================= function TSynRange.GetSynSymbolCount: Integer; begin Result := fSynSymbols.Count; end; function TSynRange.GetSynRangeLinkCount: Integer; begin Result := fSynRangeLinks.Count; end; function TSynRange.GetCommonSynRangeCount(): Integer; begin Result := fCommonSynRanges.Count; end; function TSynRange.GetSynRangeCount: Integer; begin Result := fSynRanges.Count; end; function TSynRange.GetSynKeyListCount: Integer; begin Result := fSynKeyLists.Count; end; function TSynRange.GetSynSetCount: Integer; //Vitalik 2004 begin Result := fSynSets.Count; end; //=== GetRule from list ====================================================== function TSynRange.GetSynSymbol(Index: Integer): TSynSymbol; begin Result := TSynSymbol(fSynSymbols[Index]); end; function TSynRange.GetCommonSynRange(Index: Integer): TSynRange; begin Result := TSynRange(fCommonSynRanges[Index]); end; function TSynRange.GetSynRangeLink(Index: Integer): TSynRangeLink; begin Result := TSynRangeLink(fSynRangeLinks[Index]); end; function TSynRange.GetSynRange(Index: Integer): TSynRange; begin Result := TSynRange(fSynRanges[Index]); end; function TSynRange.GetSynKeyList(Index: Integer): TSynKeyList; begin Result := TSynKeyList(fSynKeyLists[Index]); end; function TSynRange.GetSynSet(Index: Integer): TSynSet; //Vitalik 2004 begin Result := TSynSet(fSynSets[Index]); end; //=== SetDelimiters ========================================================== procedure TSynRange.SetDelimiters(Delimiters: TSymbSet); var i: integer; begin TermSymbols := Delimiters; for i := 0 to RangeCount-1 do Ranges[i].SetDelimiters(Delimiters); end; (* procedure TSynRange.SetStyles(aStyles: TSynUniStyles); //var // i: integer; begin { Styles := aStyles; for i := 0 to RangeCount-1 do Ranges[i].SetStyles(aStyles);} end; *) //=== Case Sensitive ========================================================= function TSynRange.GetCaseSensitive: boolean; //: Return CaseSensitive begin Result := FCaseSensitive; end; procedure TSynRange.SetCaseSensitive(const Value: boolean); //: Set CaseSensitive begin fCaseSensitive := Value; if not Value then begin CaseFunct := UpCase; StringCaseFunct := UpperCase; end else begin CaseFunct := CaseNone; StringCaseFunct := StringCaseNone; end; end; //=== Prepare rules for parsing ============================================== procedure QuickSortSymbolList(const List: TList; const lowerPos, upperPos: integer); var i, middlePos: integer; pivotValue: string; Begin if lowerPos < upperPos then begin pivotValue := TSynSymbol(List[lowerPos]).Symbol; middlePos := lowerPos; for i := lowerPos + 1 to upperPos do begin if TSynSymbol(List[i]).Symbol < pivotValue then begin inc(middlePos); List.Exchange(i,middlePos); end; end; List.Exchange(lowerPos,middlePos); QuickSortSymbolList(List, lowerPos, middlePos-1); QuickSortSymbolList(List, middlePos+1, upperPos); end; end; // Used in prepare (* replaced by quicksort... arb2004 procedure SortSymbolList(List: TList); //: Sort list fSynSymbols var i: integer; fin: boolean; begin fin := False; while not fin do begin fin := True; for i := 0 to List.Count-2 do if TSynSymbol(List[i]).Symbol > TSynSymbol(List[i+1]).Symbol then begin List.Exchange(i, i+1); fin := False; end; end; end;*) procedure TSynRange.ClearParsingFields(); var i: integer; begin OpenCount := 0; for i := 0 to RangeCount-1 do Ranges[i].ClearParsingFields(); end; procedure TSynRange.ResetParents(aParent: TSynRange); var i: integer; begin Parent := aParent; for i := 0 to RangeCount-1 do Ranges[i].ResetParents(Self); end; procedure TSynRange.Prepare(Owner: TSynRange); //: This procedure prepare Range for parsing //: Is called only from SetLine var i, j, Len: integer; SynSymbol: TSynSymbol; s: string; FirstChar: char; BrakeType: TSymbBrakeType; function SafeInsertSymbol(Symb: TSynSymbol; Rules: TSynRange; Attribs: TSynHighlighterAttributes): TSynSymbol; //: This function add Symb to SynRange, if and only if there is no it there //: Return added or found element begin Result := Rules.FindSymbol(Symb.Symbol); //: Find Symb in Rules if Result = nil then begin //: If Symb not found, then add Symb to Rules Result := TSynSymbol.Create(Symb.Symbol, Symb.Attributes); Result.StartType := Symb.StartType; Result.BrakeType := Symb.BrakeType; Result.StartLine := Symb.StartLine; Rules.AddSynSymbol(Result); end; if Result.Attributes = nil then //: If attributes of SynSymbol not setted Result.Attributes := Attribs; //: then set them to Attribs end; function InsertSymbol(Symb: TSynSymbol; Rules: TSynRange): TSynSymbol; begin Result := Rules.FindSymbol(Symb.Symbol); if Result = nil then begin Result := TSynSymbol.Create(Symb.Symbol, Symb.Attributes); Result.BrakeType := Symb.BrakeType; Rules.AddSynSymbol(Result); end; Result.Attributes := Symb.Attributes; end; var Range: TSynRange; RangeLink: TSynRangeLink; begin Reset; //: If already prepared then reset it! fOwner := Owner; OpenCount := 0; fDefaultSynSymbol := TSynSymbol.Create('', Attribs); fDefaultTermSymbol := TDefaultTermSymbols.Create(TSynSymbol.Create('', Attribs)); fDefaultSymbols := TDefaultSymbols.Create(TSynSymbol.Create('', Attribs)); fTermSymbols := fTermSymbols+AbsoluteTermSymbols; if Enabled then begin //Add all keywords to list fSynSymbols: for i := 0 to fSynKeyLists.Count-1 do //: All KeyLists if TSynKeyList(fSynKeyLists[i]).Enabled then for j := 0 to TSynKeyList(fSynKeyLists[i]).KeyList.Count-1 do begin//: All keywords in KeyLists //: Add current keyword to list fSynSymbols: InsertSymbol{AddSymbol}(TSynSymbol.Create(TSynKeyList(fSynKeyLists[i]).KeyList[j], TSynKeyList(fSynKeyLists[i]).Attribs), self); end; //Assign range opening and closing symbols and Prepare range rules. for i := 0 to fSynRanges.Count-1 do begin Range := TSynRange(fSynRanges[i]); if Range.Enabled then begin //Assign range opening symbol SynSymbol := SafeInsertSymbol(Range.fRule.fOpenSymbol, Self, Range.Attribs); SynSymbol.fOpenRule := Range; //Assing range closing symbols SynSymbol := SafeInsertSymbol(Range.fRule.fCloseSymbol, Range, Range.Attribs); Range.fClosingSymbol := SynSymbol; Range.Prepare(Self); end; end; for i := 0 to fSynRangeLinks.Count-1 do begin RangeLink := TSynRangeLink(fSynRangeLinks[i]); Range := RangeLink.Range; if RangeLink.Enabled then begin //Assign range opening symbol SynSymbol := SafeInsertSymbol(Range.fRule.fOpenSymbol, Self, Range.Attribs); SynSymbol.fOpenRule := RangeLink; RangeLink.Parent := Self; //Assing range closing symbols // SynSymbol := SafeInsertSymbol(Range.fRule.fCloseSymbol, Range, Range.Attribs.Std); // Range.fClosingSymbol := SynSymbol; // Range.Prepare(Self); end; end; //Build tokens table QuickSortSymbolList(fSynSymbols, 0, fSynSymbols.Count-1); //: Sort fSynSymbols for i := 0 to fSynSymbols.Count-1 do begin //: run all SynSymbols SynSymbol := TSynSymbol(fSynSymbols[i]); //: SynSymbol - next SymSymbol Len := Length(SynSymbol.Symbol); if Len < 1 then //: If length equal zero continue; //: then next SynSymbol s := SynSymbol.Symbol; //: String of SynSymbol FirstChar := s[1]; //: First symbol of string of SynSymbol if SynSymbol.BrakeType <> btUnspecified then //: If BrakeType defined then BrakeType := SynSymbol.BrakeType //: Write this BreakType to local variable else //: Else (if BrakeType not defined) if s[Len] in fTermSymbols then //: If last symbol is TermSymbol BrakeType := btAny //: Write to BreakType: btAny else //: Else BrakeType := btTerm; //: Write to BreakType: btTerm if SymbolList[CaseFunct(FirstChar)] = nil then //: If in SymbolList on FirstChar there is no nothing begin if Len = 1 then //: If length of string of SynSymbol equal 1 //: then write SynSymbol in this element of SimbolList SymbolList[CaseFunct(FirstChar)] := TSymbols.Create(FirstChar, SynSymbol, BrakeType) else begin //: Else (length of SynSymbol greate then 1) //: Write fDefaultSynSymbol (???) to this element | FirstChar SymbolList[CaseFunct(FirstChar)] := TSymbols.Create(FirstChar, fDefaultSynSymbol, BrakeType); //: and add SynSymbol to this element | All but without FirstChar TSymbols(SymbolList[CaseFunct(FirstChar)]).AddSymbol(StringCaseFunct(copy(s, 2, Len-1)), SynSymbol, BrakeType); end; end else begin //: Else (if in SynSymbol exist something) if Len = 1 then else //: If length of string SynSymbol greate then 1 //: Add SynSymbol to this element | All but without FirstChar TSymbols(SymbolList[CaseFunct(FirstChar)]).AddSymbol(StringCaseFunct(copy(s, 2, Len-1)), SynSymbol, BrakeType); end; end; {begin} //Vitalik 2004 if fSynSets.Count > 0 then for i := 0 to 255 do for j := 0 to fSynSets.Count-1 do begin if TSynSet(fSynSets[j]).Enabled and (char(i) in TSynSet(fSynSets[j]).SymbSet) then if SymbolList[CaseFunct(char(i))] = nil then SymbolList[CaseFunct(char(i))] := TSymbols.Create(TSynSet(fSynSets[j])) else TSymbols(SymbolList[CaseFunct(char(i))]).AddSet(TSynSet(fSynSets[j])); end; // SymbolList[char(i)] := fSetSymbols; // TSetSymbols(SymbolList[char(i)]).AddSetfSetSymbols; {end} //Vitalik 2004 end; //Fill remaining table for i := 0 to 255 do if SymbolList[char(i)] = nil then begin if char(i) in fTermSymbols then SymbolList[char(i)] := fDefaultTermSymbol else SymbolList[char(i)] := fDefaultSymbols; end; fPrepared := true; end; procedure TSynRange.Reset; //: Clear some properties of SynRange, //: вызывается при очистке Clear, а также при Подготовке SynRang'a (Prepare) //: Ресетится только если SynRange был уже подготовлен! var i: integer; begin if not fPrepared then exit; fDefaultSynSymbol.Free; fDefaultTermSymbol.Free; fDefaultSymbols.Free; for i := 0 to 255 do SymbolList[char(i)] := nil; //maybe need to free??? for i := 0 to fSynRanges.Count-1 do TSynRange( fSynRanges[i] ).Reset; ClearList(fSynSymbols); fPrepared := False; end; procedure TSynRange.Clear; //: Clear primary properties of SynRang, call in creating new rools var i: integer; begin //!!!!!!!!!!!!!!!!!!!!!! Нужно еще очищать или удалять OpenSymbol и CloseSymbol !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Reset; //: Reser Range (clear some properties) for i := 0 to fSynRanges.Count-1 do //: Clear all sub-ranges TSynRange(fSynRanges[i]).Clear; ClearList(fSynRanges); ClearList(fSynSymbols); ClearList(fSynKeyLists); ClearList(fSynSets); end; function TSynRange.FindRange(const Name: string): TSynRange; Var I: integer; begin Result := nil; if fOwner = nil then Exit; for I := 0 to fOwner.RangeCount - 1 do if SameText(Name, fOwner.Ranges[I].Name) then begin Result := fOwner.Ranges[I]; Exit; end; end; procedure TSynRange.SetColorForChilds; //Vitalik 2004 var i: integer; begin for i := 0 to RangeCount-1 do begin if Ranges[i].Attribs.ParentForeground then begin Ranges[i].Attribs.Foreground := Attribs.Foreground; Ranges[i].Attribs.OldColorForeground := Attribs.Foreground; end; if Ranges[i].Attribs.ParentBackground then begin Ranges[i].Attribs.Background := Attribs.Background; Ranges[i].Attribs.OldColorBackground := Attribs.Background; end; Ranges[i].SetColorForChilds; end; for i := 0 to KeyListCount-1 do begin if KeyLists[i].Attribs.ParentForeground then KeyLists[i].Attribs.Foreground := Attribs.Foreground; if KeyLists[i].Attribs.ParentBackground then KeyLists[i].Attribs.Background := Attribs.Background; end; for i := 0 to SetCount-1 do begin if Sets[i].Attribs.ParentForeground then Sets[i].Attribs.Foreground := Attribs.Foreground; if Sets[i].Attribs.ParentBackground then Sets[i].Attribs.Background := Attribs.Background; end; end; //==== TSynRangeLink ========================================================= constructor TSynRangeLink.Create(aRange: TSynRange); begin inherited Create; Range := aRange; Parent := nil; end; ////////////////////////////////////////////////////////////////////////////// // LLL OOOOO AAAAA DDDDDD IIIII NN N GGGGGG // // L O O A A D D I NNN N G // // L O O AAAAAAA D D I N NNN N G GGG // // L L O O A A D D I N NNN G G // // LLLLLLL OOOOO A A DDDDDD IIIII N NN GGGGGG // ////////////////////////////////////////////////////////////////////////////// procedure TSynKeyList.LoadFromXml(xml: TDOMNode); var I, J: Integer; ChildNode: TDOMNode; Key, Value, LowValue: string; // OldAttribs: {TSynHighlighter}TSynAttributes; begin if xml = nil then Exit; if not SameText(xml.NodeName, 'Keywords') then xml:= xml.FindNode('Keywords'); if xml = nil then raise Exception.Create(ClassName + '.LoadFromXml - no keywords to load!'); for I := 0 to Int32(xml.Attributes.Length) - 1 do begin Key := xml.Attributes[I].NodeName; Value := xml.Attributes[I].NodeValue; LowValue := LowerCase(Value); if SameText('Name', Key) then Name := Value else if SameText('Enabled', Key) then Enabled := (LowValue = 'true') else if SameText('Attributes', Key) then Attribs.LoadFromString(Value) else if SameText('Style', Key) then begin Style := Value; if Styles <> nil then //begin // OldAttribs := Attribs; Attribs := Styles.GetStyleDef(Value, Attribs); // if OldAttribs <> Attribs then // Attribs.UseStyle := True; { if (Attribs = DefaultAttr) or (Attribs = nil) then Attribs := DefaultAttri;} // end; end else // Attribs := fStyles.GetStyleDef(getAttrValue('style', xml), defaultattr); end; KeyList.BeginUpdate; KeyList.Clear; try for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode:= xml.ChildNodes.Item[J]; if SameText('Word', ChildNode.NodeName) then if (ChildNode.Attributes.Length > 0) and SameText('Value', ChildNode.Attributes[0].NodeName) then KeyList.Add(ChildNode.Attributes[0].NodeValue); end; finally KeyList.EndUpdate; end; end; procedure TSynSet.LoadFromXml(xml: TDOMNode); var i: integer; Key, Value, LowValue: string; // OldAttribs: {TSynHighlighter}TSynAttributes; begin if xml = nil then Exit; if not SameText(xml.NodeName, 'Set') then xml:= xml.FindNode('Set'); if xml = nil then raise Exception.Create(ClassName + '.LoadFromXml - no set to load!'); for i := 0 to Int32(xml.Attributes.Length) - 1 do begin Key := xml.Attributes[i].NodeName; Value := xml.Attributes[i].NodeValue; LowValue := LowerCase(Value); {ind := 0;} if SameText('Name', Key) then Name := Value else if SameText('Enabled', Key) then Enabled := (LowValue = 'true') else if SameText('Attributes', Key) then Attribs.LoadFromString(Value) else if SameText('Style', Key) then begin Style := Value; if Styles <> nil then //begin // OldAttribs := Attribs; Attribs := Styles.GetStyleDef(Value, Attribs); // if OldAttribs <> Attribs then // Attribs.UseStyle := True; { if (Attribs = DefaultAttr) or (Attribs = nil) then Attribs := DefaultAttri;} // end; end else if SameText('Symbols', Key) then SymbSet := StrToSet(Value) // Attribs := fStyles.GetStyleDef(getAttrValue('style', xml), defaultattr); end; end; procedure TSynRange.LoadFromXml(xml: TDOMNode); var I, J: Integer; ChildNode: TDOMNode; NewSynRange: TSynRange; NewSynKeyList: TSynKeyList; NewSynSet: TSynSet; Key, Value, LowValue: string; // OldAttribs: {TSynHighlighter}TSynAttributes; begin if xml = nil then Exit; if not SameText(xml.NodeName, 'Range') then xml:= xml.FindNode('Range'); if xml = nil then raise Exception.Create(ClassName + '.LoadFromXml - no range to load!'); // Clear; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Вставить нормальный Clear в KeyList и SynSet !!!!!!!!!!!!!!!!!! Enabled := True; CaseSensitive := False; for i := 0 to Int32(xml.Attributes.Length) - 1 do begin Key := xml.Attributes[i].NodeName; Value := xml.Attributes[i].NodeValue; LowValue := LowerCase(Value); if SameText('Name', Key) then Name := Value else if SameText('Enabled', Key) then Enabled := (LowValue = 'true') else if SameText('Attributes', Key) then Attribs.LoadFromString(Value) else if SameText('Style', Key) then begin Style := Value; if Styles <> nil then //begin // OldAttribs := Attribs; Attribs := Styles.GetStyleDef(Value, Attribs); // if OldAttribs <> Attribs then // Attribs.UseStyle := True; { if (Attribs = DefaultAttr) or (Attribs = nil) then Attribs := DefaultAttri;} // end; end else if SameText('CaseSensitive', Key) then CaseSensitive := (LowValue = 'true') else if SameText('Delimiters', Key) then // if SameText(GetAttrValue('spaces', xml), 'true') then // TermSymbols := String2Set(xml.CurContent) + [#32, #9, #13, #10] else TermSymbols := StrToSet(Value) // CloseOnTerm := true; end; for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode:= xml.ChildNodes.Item[J]; if SameText('Rule', ChildNode.NodeName) then for i := 0 to Int32(ChildNode.Attributes.Length) - 1 do begin Key := ChildNode.Attributes[i].NodeName; Value := ChildNode.Attributes[i].NodeValue; LowValue := LowerCase(Value); if SameText('Enabled', Key) then Enabled := (LowValue = 'true') else if SameText('OpenSymbol', Key) then fRule.fOpenSymbol.Symbol := Value else if SameText('OpenSymbolFinishOnEol', Key) then if LowValue = 'true' then fRule.fOpenSymbol.Symbol := fRule.fOpenSymbol.Symbol + #0 else else if SameText('OpenSymbolStartLine', Key) then with fRule.fOpenSymbol do if LowValue = 'true' then StartLine := slFirst else if LowValue = 'nonspace' then StartLine := slFirstNonSpace else StartLine := slNotFirst else if SameText('OpenSymbolPartOfTerm', Key) then with fRule.fOpenSymbol do if LowValue = 'true' then begin StartType := stAny; BrakeType := btAny; end else if LowValue = 'left' then begin StartType := stAny; BrakeType := btTerm; end else if LowValue = 'right' then begin StartType := stTerm; BrakeType := btAny; end else begin StartType := stTerm; BrakeType := btTerm; end else if SameText('CloseSymbol', Key) then fRule.fCloseSymbol.Symbol := Value else if SameText('CloseSymbolFinishOnEol', Key) then if LowValue = 'true' then fRule.fCloseSymbol.Symbol := fRule.fCloseSymbol.Symbol + #0 else else if SameText('CloseSymbolStartLine', Key) then with fRule.fCloseSymbol do if LowValue = 'true' then StartLine := slFirst else if LowValue = 'nonspace' then StartLine := slFirstNonSpace else StartLine := slNotFirst else if SameText('CloseSymbolPartOfTerm', Key) then with fRule.fCloseSymbol do if LowValue = 'true' then begin StartType := stAny; BrakeType := btAny; end else if LowValue = 'left' then begin StartType := stAny; BrakeType := btTerm; end else if LowValue = 'right' then begin StartType := stTerm; BrakeType := btAny; end else begin StartType := stTerm; BrakeType := btTerm; end else if SameText('CloseOnTerm', Key) then fRule.fCloseOnTerm := (LowValue = 'true') else if SameText('CloseOnEol', Key) then fRule.fCloseOnEol := (LowValue = 'true') else if SameText('AllowPredClose', Key) then fRule.fAllowPredClose := (LowValue = 'true') else end else if SameText('Range', ChildNode.NodeName) then begin NewSynRange := TSynRange.Create; NewSynRange.Styles := Styles; AddRange(NewSynRange); NewSynRange.LoadFromXml(ChildNode); end else if SameText('Keywords', ChildNode.NodeName) then begin NewSynKeyList := TSynKeyList.Create; NewSynKeyList.Styles := Styles; AddKeyList(NewSynKeyList); NewSynKeyList.LoadFromXml(ChildNode); end else if SameText('Set', ChildNode.NodeName) then begin NewSynSet := TSynSet.Create; NewSynSet.Styles := Styles; AddSet(NewSynSet); NewSynSet.LoadFromXml(ChildNode); end { else if SameText(xml.CurName, 'TextStyle') then begin DefaultAttri := fStyles.getStyleDef(xml.CurContent, defaultAttr); if (NumberAttri = DefaultAttr) or (NumberAttri = nil) then NumberAttri := DefaultAttri; end else if SameText(xml.CurName, 'NumberStyle') then NumberAttri := fStyles.getStyleDef(xml.CurContent, defaultAttr);} end; end; ////////////////////////////////////////////////////////////////////////////// // SSSSSS AAAAAA V V IIIII NN N GGGGGGG // // S A A V V I NNN N G // // SSSSS AAAAAAAA VV VV I N NNN N G GGG // // S A A VV VV I N NNN G G // // SSSSSS A A V IIIII N NN GGGGGGG // ////////////////////////////////////////////////////////////////////////////// procedure TSynKeyList.SaveToStream(StreamWriter: TStreamWriter; Ind: integer); var i: integer; begin with StreamWriter do begin WriteTag(Ind, 'Keywords'); WriteParam('Name', Name); WriteBoolParam('Enabled', Enabled, True); Attribs.SaveToStream(StreamWriter); WriteParam('Style', Style); WriteString(CloseStartTag + EOL); for i := 0 to KeyList.Count-1 do begin WriteTag(Ind+2, 'Word'); WriteParam('Value', KeyList[i], CloseEmptyTag); end; WriteTag(Ind, '/Keywords', True); end; end; procedure TSynSet.SaveToStream(StreamWriter: TStreamWriter; Ind: integer); begin with StreamWriter do begin WriteTag(Ind, 'Set'); WriteParam('Name', Name); WriteBoolParam('Enabled', Enabled, True); Attribs.SaveToStream(StreamWriter); WriteParam('Style', Style); WriteParam('Symbols', SetToStr(SymbSet), CloseEmptyTag); { if S.StartType = stAny then if S.BrakeType = btAny then InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'True') else InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'Left') else if S.BrakeType = btAny then InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'Right') else InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'False');} end; end; procedure TSynRange.SaveToStream(StreamWriter: TStreamWriter; Ind: integer); var i: integer; begin with StreamWriter do begin WriteTag(Ind, 'Range'); WriteParam('Name', Name); WriteBoolParam('Enabled', Enabled, True); Attribs.SaveToStream(StreamWriter); WriteParam('Style', Style); WriteBoolParam('CaseSensitive', CaseSensitive, False); WriteString(EOL + Indent(Ind + Length(' 0 then if Symbol[Length(Symbol)] = #0 then begin WriteParam('OpenSymbol', copy(Symbol, 1, Length(Symbol) - 1)); WriteParam('OpenSymbolFinishOnEol', 'True'); end else begin WriteParam('OpenSymbol', Symbol); {WriteParam('OpenSymbolFinishOnEol', 'False');} end; if StartLine = slFirst then WriteParam('OpenSymbolStartLine', 'True') else if StartLine = slFirstNonSpace then WriteParam('OpenSymbolStartLine', 'NonSpace'); //else WriteParam('OpenSymbolStartLine', 'False'); if StartType = stAny then if BrakeType = btAny then //WriteParam('OpenSymbolPartOfTerm', 'True') else WriteParam('OpenSymbolPartOfTerm', 'Left') else if BrakeType = btAny then WriteParam('OpenSymbolPartOfTerm', 'Right') else WriteParam('OpenSymbolPartOfTerm', 'False'); end; with fRule.fCloseSymbol do begin if Length(Symbol) > 0 then if Symbol[Length(Symbol)] = #0 then begin WriteParam('CloseSymbol', copy(Symbol, 1, Length(Symbol) - 1)); WriteParam('CloseSymbolFinishOnEol', 'True'); end else begin WriteParam('CloseSymbol', Symbol); {WriteParam('CloseSymbolFinishOnEol', 'False');} end; if StartLine = slFirst then WriteParam('CloseSymbolStartLine', 'True') else if StartLine = slFirstNonSpace then WriteParam('CloseSymbolStartLine', 'NonSpace'); //else WriteParam('CloseSymbolStartLine', 'False'); if StartType = stAny then if BrakeType = btAny then //WriteParam('CloseSymbolPartOfTerm', 'True') else WriteParam('CloseSymbolPartOfTerm', 'Left') else if BrakeType = btAny then WriteParam('CloseSymbolPartOfTerm', 'Right') else WriteParam('CloseSymbolPartOfTerm', 'False'); end; WriteBoolParam('CloseOnTerm', fRule.fCloseOnTerm, False); WriteBoolParam('CloseOnEol', fRule.fCloseOnEol, False); WriteBoolParam('AllowPredClose', fRule.fAllowPredClose, False); WriteString(CloseEmptyTag + EOL); end; for i := 0 to KeyListCount-1 do KeyLists[i].SaveToStream(StreamWriter, Ind+2); for i := 0 to SetCount-1 do Sets[i].SaveToStream(StreamWriter, Ind+2); for i := 0 to RangeCount-1 do Ranges[i].SaveToStream(StreamWriter, Ind+2); WriteTag(Ind, '/Range', True); end; end; function ReadValue(ANode: TDOMNode): String; begin if Assigned(ANode.FirstChild) then Result:= ANode.FirstChild.NodeValue else Result:= EmptyStr; end; function Verify(tag: string; xml: TDOMNode): boolean; overload; begin Result := SameText(xml.NodeName, tag); end; procedure LoadAttri(curRule: TSynRule; xml: TDOMNode); var J: Integer; ChildNode: TDOMNode; begin // inc(CurRule.ind); CurRule.Attribs{ByIndex[0]}.ParentForeground := False; CurRule.Attribs{ByIndex[0]}.ParentBackground := False; for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode:= xml.ChildNodes.Item[J]; if Verify('Back',ChildNode) then begin CurRule.Attribs.Background := StrToIntDef(ReadValue(ChildNode), $FFFFFF); CurRule.Attribs.OldColorBackground := CurRule.Attribs.Background; end else if Verify('Fore',ChildNode) then begin CurRule.Attribs.Foreground := StrToIntDef(ReadValue(ChildNode), 0); CurRule.Attribs.OldColorForeground := CurRule.Attribs.Foreground; end else if Verify('Style',ChildNode) then CurRule.Attribs.Style := StrToFontStyle(ReadValue(ChildNode)) else if Verify('ParentForeground',ChildNode) then CurRule.Attribs.ParentForeground := LowerCase(ReadValue(ChildNode)) = 'true' else if Verify('ParentBackground',ChildNode) then CurRule.Attribs.ParentBackground := LowerCase(ReadValue(ChildNode)) = 'true'; end; end; procedure TSynKeyList.LoadHglFromXml(xml: TDOMNode; SchCount,SchIndex: integer); var J: Integer; ChildNode: TDOMNode; TempSchIndex: integer; begin // if curKw = nil then Exit; if xml = nil then Exit; if ( SameText('KW'{'Keywords'}, xml.NodeName) ) then begin if xml.Attributes.Length > 0 then Name := xml.Attributes[0].NodeValue // Attribs := fStyles.GetStyleDef(getAttrValue('style', xml), defaultattr); end else raise Exception.Create(ClassName + '.LoadFromXml - no keywords to load!'); // ClearAttributes(); // for i := 0 to SchCount-1 do // AddAttribute(); // ind := -1; TempSchIndex := SchIndex; KeyList.BeginUpdate; KeyList.Clear; try for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode:= xml.ChildNodes.Item[J]; if SameText(ChildNode.NodeName, 'Attri') or SameText(ChildNode.NodeName, 'Def') then begin if TempSchIndex >= 0 then LoadAttri(self, ChildNode); dec(TempSchIndex); end else if Verify('Enabled',ChildNode) then Enabled := LowerCase(ReadValue(ChildNode)) = 'true' else if Verify('W',ChildNode) then begin KeyList.Add(ReadValue(ChildNode)); end; end; finally ind := SchIndex; KeyList.EndUpdate; end; end; procedure TSynSet.LoadHglFromXml(xml: TDOMNode; SchCount,SchIndex: integer); var J: Integer; ChildNode: TDOMNode; TempSchIndex: integer; begin // if curSet = nil then Exit; if xml = nil then Exit; if ( SameText('Set', xml.NodeName) ) then begin if xml.Attributes.Length > 0 then Name := xml.Attributes[0].NodeValue // Attribs := fStyles.GetStyleDef(getAttrValue('style', xml), defaultattr); end else raise Exception.Create(ClassName + '.LoadFromXml - no set to load!'); { ClearAttributes(); for i := 0 to SchCount-1 do AddAttribute(); ind := -1;} TempSchIndex := SchIndex; for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode:= xml.ChildNodes.Item[J]; if SameText(ChildNode.NodeName, 'Attri') or SameText(ChildNode.NodeName, 'Def') then begin if TempSchIndex >= 0 then LoadAttri(self, ChildNode); dec(TempSchIndex); end else if Verify('Enabled',ChildNode) then Enabled := LowerCase(ReadValue(ChildNode)) = 'true' else if Verify('S',ChildNode) then SymbSet := StrToSet(ReadValue(ChildNode)); end; ind := SchIndex; end; procedure TSynRange.LoadHglFromXml(xml: TDOMNode; SchCount, SchIndex: integer); var NewSynRange: TSynRange; NewSynKeyList: TSynKeyList; NewSynSet: TSynSet; S: string; TempSchIndex: integer; J: Integer; ChildNode: TDOMNode; begin fRule.fOpenSymbol.BrakeType := btAny; if SameText(xml.NodeName, 'Range') then begin if xml.Attributes.Length > 0 then S:= xml.Attributes[0].NodeValue; if S <> '' then Name := S; end else raise Exception.Create(ClassName + '.LoadFromXml - no range to load!'); { ClearAttributes(); for i := 0 to SchCount-1 do AddAttribute(); ind := -1;} TempSchIndex := SchIndex; for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode:= xml.ChildNodes.Item[J]; if Verify('Enabled', ChildNode) then Enabled := LowerCase(ReadValue(ChildNode)) = 'true' else if Verify('CaseSensitive', ChildNode) then CaseSensitive := LowerCase(ReadValue(ChildNode)) = 'true' else if Verify('OpenSymbol', ChildNode) then fRule.fOpenSymbol.Symbol := ReadValue(ChildNode) else if Verify('CloseSymbol', ChildNode) then fRule.fCloseSymbol.Symbol := ReadValue(ChildNode) else if Verify('OpenSymbolFinishOnEol', ChildNode) then if LowerCase(ReadValue(ChildNode)) = 'true' then fRule.fOpenSymbol.Symbol := fRule.fOpenSymbol.Symbol + #0 else else if Verify('CloseSymbolFinishOnEol',ChildNode) then if LowerCase(ReadValue(ChildNode)) = 'true' then fRule.fCloseSymbol.Symbol := fRule.fCloseSymbol.Symbol + #0 else else if Verify('CloseOnTerm',ChildNode) then fRule.fCloseOnTerm := LowerCase(ReadValue(ChildNode)) = 'true' else if Verify('CloseOnEol',ChildNode) then fRule.fCloseOnEol := LowerCase(ReadValue(ChildNode)) = 'true' else if Verify('AllowPredClose',ChildNode) then fRule.fAllowPredClose := LowerCase(ReadValue(ChildNode)) = 'true' else if Verify('OpenSymbolStartLine',ChildNode) then if LowerCase(ReadValue(ChildNode)) = 'true' then fRule.fOpenSymbol.StartLine := slFirst else if LowerCase(ReadValue(ChildNode)) = 'nonspace' then fRule.fOpenSymbol.StartLine := slFirstNonSpace else fRule.fOpenSymbol.StartLine := slNotFirst else if Verify('CloseSymbolStartLine',ChildNode) then if LowerCase(ReadValue(ChildNode)) = 'true' then fRule.fCloseSymbol.StartLine := slFirst else if LowerCase(ReadValue(ChildNode)) = 'nonspace' then fRule.fCloseSymbol.StartLine := slFirstNonSpace else fRule.fCloseSymbol.StartLine := slNotFirst else if Verify('AnyTerm',ChildNode) then if LowerCase(ReadValue(ChildNode)) = 'true' then fRule.fOpenSymbol.BrakeType := btAny else fRule.fOpenSymbol.BrakeType := btTerm // if StrToBoolDef(ReadValue(ChildNode), false) then // fRule.fOpenSymbol.BrakeType := btTerm; else if Verify('OpenSymbolPartOfTerm',ChildNode) then if LowerCase(ReadValue(ChildNode)) = 'true' then begin fRule.fOpenSymbol.StartType := stAny; fRule.fOpenSymbol.BrakeType := btAny; end else if LowerCase(ReadValue(ChildNode)) = 'left' then begin fRule.fOpenSymbol.StartType := stAny; fRule.fOpenSymbol.BrakeType := btTerm; end else if LowerCase(ReadValue(ChildNode)) = 'right' then begin fRule.fOpenSymbol.StartType := stTerm; fRule.fOpenSymbol.BrakeType := btAny; end else begin fRule.fOpenSymbol.StartType := stTerm; fRule.fOpenSymbol.BrakeType := btTerm; end else if Verify('CloseSymbolPartOfTerm',ChildNode) then if LowerCase(ReadValue(ChildNode)) = 'true' then begin fRule.fCloseSymbol.StartType := stAny; fRule.fCloseSymbol.BrakeType := btAny; end else if LowerCase(ReadValue(ChildNode)) = 'left' then begin fRule.fCloseSymbol.StartType := stAny; fRule.fCloseSymbol.BrakeType := btTerm; end else if LowerCase(ReadValue(ChildNode)) = 'right' then begin fRule.fCloseSymbol.StartType := stTerm; fRule.fCloseSymbol.BrakeType := btAny; end else begin fRule.fCloseSymbol.StartType := stTerm; fRule.fCloseSymbol.BrakeType := btTerm; end else if Verify('DelimiterChars',ChildNode) then // if SameText(GetAttrValue('spaces', xml), 'true') then // TermSymbols := String2Set(ReadValue(ChildNode)) + [#32, #9, #13, #10] // else if Assigned(ChildNode.FirstChild) then TermSymbols := StrToSet(ReadValue(ChildNode)) else // CloseOnTerm := true; else { else if SameText(xml.CurName, 'TextStyle') then begin DefaultAttri := fStyles.getStyleDef(ReadValue(ChildNode), defaultAttr); if (NumberAttri = DefaultAttr) or (NumberAttri = nil) then NumberAttri := DefaultAttri; end else if SameText(xml.CurName, 'NumberStyle') then NumberAttri := fStyles.getStyleDef(ReadValue(ChildNode), defaultAttr);} if SameText(ChildNode.NodeName, 'Attri') or SameText(ChildNode.NodeName, 'Def') then begin if TempSchIndex >= 0 then LoadAttri(self, ChildNode); dec(TempSchIndex); end else if SameText(ChildNode.NodeName, 'Range') then begin NewSynRange := TSynRange.Create; AddRange(NewSynRange); NewSynRange.LoadHglFromXml(ChildNode, SchCount, SchIndex); end else if SameText(ChildNode.NodeName, 'KW') then begin NewSynKeyList := TSynKeyList.Create; AddKeyList(NewSynKeyList); NewSynKeyList.LoadHglFromXml(ChildNode, SchCount, SchIndex); end else if SameText(ChildNode.NodeName, 'Set') then begin NewSynSet := TSynSet.Create; AddSet(NewSynSet); NewSynSet.LoadHglFromXml(ChildNode, SchCount, SchIndex); end; end; ind := SchIndex; end; procedure TSynRange.LoadHglFromStream(aSrc: TStream); var I, J: Integer; xml: TXMLDocument = nil; SchCount, SchIndex: integer; ChildNode, ChildNode2: TDOMNode; begin try SchCount := 0; SchIndex := -1; ReadXMLFile(xml, aSrc); for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode:= xml.ChildNodes.Item[J]; if Verify('SchemeIndex', ChildNode) then SchIndex := StrToInt(ReadValue(ChildNode)) else if Verify('Schemes', ChildNode) then begin for I:= 0 to Int32(ChildNode.ChildNodes.Count) - 1 do begin ChildNode2:= ChildNode.ChildNodes.Item[I]; if Verify('S', ChildNode2) then inc(SchCount); end end else if SameText(ChildNode.NodeName, 'Range') then LoadHglFromXml(ChildNode, SchCount, SchIndex); end; finally xml.Free; end; end; end. doublecmd-0.8.2/components/synunihighlighter/source/SynUniClasses.pas0000664000175000017500000007151713112333426025217 0ustar alexxalexx{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is: SynUniHighlighter.pas, released 2003-01 All Rights Reserved. Alternatively, the contents of this file may be used under the terms of the GNU General Public License Version 2 or later (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. }{ @abstract(Provides a universal highlighter for SynEdit) @authors(Fantasist [walking_in_the_sky@yahoo.com], Vit [nevzorov@yahoo.com], Vitalik [vetal-x@mail.ru]) @created(2003) @lastmod(2004-05-12) } unit SynUniClasses; interface uses SysUtils, Graphics, Classes, SynEditHighlighter, Contnrs, Laz2_DOM; type TSymbSet = set of char; TSynInfo = class; TStreamWriter = class; TSynSymbol = class; TSymbolNode = class; TSymbolList = class; TSynRule = class; TVersionType = (vtInternalTest, vtBeta, vtRelease); TAuthorInfo = record Name: string; Email: string; Web: string; Copyright: string; Company: string; Remark: string; end; TVerInfo = record Version: integer; Revision: integer; VersionType: TVersionType; ReleaseDate: TDateTime; end; THighInfo = record Name: string; Extensions: string; end; TSynInfo = class //Vitalik 2004 Author: TAuthorInfo; Version: TVerInfo; General: THighInfo; History: TStringList; Sample: TStringlist; constructor Create(); procedure Clear(); procedure LoadFromXml(xml: TDOMNode); procedure LoadFromStream(Stream: TStream); procedure SaveToStream(Stream: TStream; Ind: integer = 0); overload; procedure SaveToStream(StreamWriter: TStreamWriter; Ind: integer = 0); overload; end; TSynEditProperties = class //Vitalik 2004 end; TSymbStartType = (stUnspecified, stAny, stTerm); //Vitalik 2004 TSymbBrakeType = (btUnspecified, btAny, btTerm); TSymbStartLine = (slNotFirst, slFirst, slFirstNonSpace); //Vitalik 2004 TStreamWriter = class //Vitalik 2004 Stream: TStream; constructor Create(aStream: TStream); procedure WriteString(const Str: string); procedure InsertTag(Ind: integer; Name: string; Value: string); procedure WriteTag(Ind: integer; Name: string; EndLine: boolean = False); procedure WriteParam(Key, Value: string; CloseTag: string = ''); procedure WriteBoolParam(Key: string; Value, Default: boolean; CloseTag: string = ''); end; TSynAttributes = class (TSynHighlighterAttributes) //Vitalik 2004 public // UseStyle: boolean; OldColorForeground: TColor; OldColorBackground: TColor; ParentForeground: boolean; ParentBackground: boolean; constructor Create(Name: string); // destructor Destroy(); override; procedure LoadFromString(Value: string); procedure SaveToStream(StreamWriter: TStreamWriter); end; TAbstractRule = class; TSynSymbol = class public Symbol: string; fOpenRule: TAbstractRule; StartType: TSymbStartType; //Vitalik 2004 BrakeType: TSymbBrakeType; StartLine: TSymbStartLine; //Vitalik 2004 Attributes: TSynHighlighterAttributes; constructor Create(st: string; Attribs: TSynHighlighterAttributes); virtual; destructor Destroy(); override; end; TSymbolNode = class ch: char; BrakeType: TSymbBrakeType; StartType: TSymbStartType; //Vitalik 2004 NextSymbs: TSymbolList; tkSynSymbol: TSynSymbol; constructor Create(AC: char; SynSymbol: TSynSymbol; ABrakeType: TSymbBrakeType); overload; virtual; constructor Create(AC: char); overload; destructor Destroy(); override; end; TSymbolList = class SymbList: TList; //Vitalik 2004 procedure AddSymbol(symb: TSymbolNode); procedure SetSymbolNode(Index: Integer; Value: TSymbolNode); function FindSymbol(ch: char): TSymbolNode; function GetSymbolNode(Index: integer): TSymbolNode; function GetCount(): integer; property Nodes[index: integer]: TSymbolNode read GetSymbolNode write SetSymbolNode; property Count: Integer read GetCount; constructor Create(); virtual; destructor Destroy(); override; end; TSynUniStyles = class (TObjectList) public FileName: string; constructor Create(); destructor Destroy(); override; function GetStyle(const Name: string): {TSynHighlighter}TSynAttributes; function GetStyleDef(const Name: string; const Def: {TSynHighlighter}TSynAttributes): {TSynHighlighter}TSynAttributes; procedure AddStyle(Name: string; Foreground, Background: TColor; FontStyle: TFontStyles); procedure ListStylesNames(const AList: TStrings); function GetStylesAsXML(): string; procedure Load(); procedure Save(); end; TAbstractRule = class //Vitalik 2004 Enabled: boolean; constructor Create(); end; TSynRule = class(TAbstractRule) //Vitalik 2004 public Ind: integer; //temp Name: string; Attribs: TSynAttributes; Style: string; Styles: TSynUniStyles; constructor Create(); destructor Destroy(); override; procedure LoadFromXml(xml: TDOMNode); virtual; abstract; procedure LoadFromStream(aSrc: TStream); procedure LoadFromFile(FileName: string); function GetAsStream(): TMemoryStream; procedure SaveToStream(Stream: TStream; Ind: integer = 0); overload; procedure SaveToStream(StreamWriter: TStreamWriter; Ind: integer = 0); overload; virtual; abstract; end; function StrToSet(st: string): TSymbSet; function SetToStr(st: TSymbSet): string; function StrToFontStyle(Style: string): TFontStyles; function FontStyleToStr(Style: TFontStyles): string; procedure FreeList(var List: TList); procedure ClearList(List: TList); function Indent(i: integer): string; const AbsoluteTermSymbols: TSymbSet = [#0, #9, #10, #13, #32]; EOL = #13#10; CloseEmptyTag = '/>'; CloseStartTag = '>'; implementation uses Laz2_XMLRead; function StrToSet(st: string): TSymbSet; var i: integer; begin result := []; for i := 1 to length(st) do Result := Result + [st[i]]; end; function SetToStr(st: TSymbSet): string; var b: byte; begin Result := ''; for b := 1 to 255 do if (chr(b) in st) and (not (chr(b) in AbsoluteTermSymbols)) then Result := Result+chr(b); end; function StrToFontStyle(Style: string): TFontStyles; begin Result := []; if Pos('B', Style) > 0 then Include( Result, fsBold ); if Pos('I', Style) > 0 then Include( Result, fsItalic ); if Pos('U', Style) > 0 then Include( Result, fsUnderline ); if Pos('S', Style) > 0 then Include( Result, fsStrikeOut ); end; function FontStyleToStr(Style: TFontStyles): string; begin Result := ''; if fsBold in Style then Result := Result + 'B'; if fsItalic in Style then Result := Result + 'I'; if fsUnderline in Style then Result := Result + 'U'; if fsStrikeOut in Style then Result := Result + 'S'; end; procedure FreeList(var List: TList); var i: integer; begin if List = nil then exit; for i := 0 to List.Count-1 do TObject(List[i]).Free; List.Free; List := nil; end; procedure ClearList(List: TList); var i: integer; begin if List = nil then exit; for i := 0 to List.Count-1 do TObject(List[i]).Free; List.Clear; end; //==== TInfo ================================================================= constructor TSynInfo.Create(); begin inherited; end; procedure TSynInfo.Clear(); begin General.Name := ''; General.Extensions := ''; Author.Name := ''; Author.Email := ''; Author.Web := ''; Author.Copyright := ''; Author.Company := ''; Author.Remark := ''; Version.Version := 0; Version.Revision := 0; Version.ReleaseDate := 0; Version.VersionType := vtInternalTest; History.Clear; Sample.Clear; end; function ReadValue(ANode: TDOMNode): String; begin if Assigned(ANode.FirstChild) then Result:= ANode.FirstChild.NodeValue else Result:= EmptyStr; end; procedure TSynInfo.LoadFromXml(xml: TDOMNode); var i, J: integer; Key, Value: string; ChildNode1, ChildNode2: TDOMNode; begin for J := 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode1:= xml.ChildNodes.Item[J]; if SameText('General', ChildNode1.NodeName) then for i := 0 to Int32(ChildNode1.Attributes.Length) - 1 do begin Key := ChildNode1.Attributes[i].NodeName; Value := ChildNode1.Attributes[i].NodeValue; if SameText('Name', Key) then General.Name := Value else if SameText('Extensions', Key) then General.Extensions := Value end else if SameText('Author', ChildNode1.NodeName) then for i := 0 to Int32(ChildNode1.Attributes.Length) - 1 do begin Key := ChildNode1.Attributes[i].NodeName; Value := ChildNode1.Attributes[i].NodeValue; if SameText('Name', Key) then Author.Name := Value else if SameText('Email', Key) then Author.Email := Value else if SameText('Web', Key) then Author.Web := Value else if SameText('Copyright', Key) then Author.Copyright := Value else if SameText('Company', Key) then Author.Company := Value else if SameText('Remark', Key) then Author.Remark := Value else end else if SameText('Version', ChildNode1.NodeName) then for i := 0 to Int32(ChildNode1.Attributes.Length) - 1 do begin Key := ChildNode1.Attributes[i].NodeName; Value := ChildNode1.Attributes[i].NodeValue; if SameText('Version', Key) then Version.Version := StrToIntDef(Value, 0) else if SameText('Revision', Key) then Version.Revision := StrToIntDef(Value, 0) else if SameText('Date', Key) then try Value := StringReplace(Value, ',', DefaultFormatSettings.DecimalSeparator, [rfReplaceAll]); // Since no one ever call something like "GetFormatSettings", "DefaultFormatSettings" still hold the default values. Value := StringReplace(Value, '.', DefaultFormatSettings.DecimalSeparator, [rfReplaceAll]); // Just in case there is something we did not think about. Version.ReleaseDate := StrToFloat(Value, DefaultFormatSettings); except // Ignore end else if SameText('Type', Key) then if Value = 'Beta' then Version.VersionType := vtBeta else if Value = 'Release' then Version.VersionType := vtRelease else Version.VersionType := vtInternalTest end else if SameText('History', ChildNode1.NodeName) then begin History.Clear; Sample.Clear; for I:= 0 to Int32(ChildNode1.ChildNodes.Count) - 1 do begin ChildNode2 := ChildNode1.ChildNodes.Item[I]; if ChildNode2.NodeName = 'H' then History.Add(ReadValue(ChildNode2)); end; end else if SameText('Sample', ChildNode1.NodeName) then begin Sample.Clear; for I:= 0 to Int32(ChildNode1.ChildNodes.Count) - 1 do begin ChildNode2 := ChildNode1.ChildNodes.Item[I]; if ChildNode2.NodeName = 'S' then Sample.Add(ReadValue(ChildNode2)); end; end; end; end; procedure TSynInfo.LoadFromStream(Stream: TStream); var xml: TXMLDocument = nil; begin try ReadXMLFile(xml, Stream); LoadFromXml(xml); finally xml.Free; end; end; procedure TSynInfo.SaveToStream(Stream: TStream; Ind: integer); var StreamWriter: TStreamWriter; begin StreamWriter := TStreamWriter.Create(Stream); SaveToStream(StreamWriter, Ind); StreamWriter.Free; end; procedure TSynInfo.SaveToStream(StreamWriter: TStreamWriter; Ind: integer); var i: integer; begin with StreamWriter do begin WriteTag(Ind, 'Info', True); WriteTag(Ind+2, 'General'); WriteParam('Name', General.Name); WriteParam('Extensions', General.Extensions, CloseEmptyTag); WriteTag(Ind+2, 'Author'); WriteParam('Name', Author.Name); WriteParam('Email', Author.Email); WriteParam('Web', Author.Web); WriteParam('Copyright', Author.Copyright); WriteParam('Company', Author.Company); WriteParam('Remark', Author.Remark, CloseEmptyTag); WriteTag(Ind+2, 'Version'); WriteParam('Version', IntToStr(Version.Version)); WriteParam('Revision', IntToStr(Version.Revision)); WriteParam('Date', FloatToStr(Version.ReleaseDate), CloseEmptyTag); { case Version.VersionType of vtInternalTest: WriteParam('Type', 'Internal Test'); vtBeta: WriteParam('Type', 'Beta'); vtRelease: WriteParam('Type', 'Release'); end;} WriteTag(Ind+2, 'History', True); for i := 0 to History.Count-1 do InsertTag(Ind+4, 'H', History[i]); WriteTag(Ind+2, '/History', True); WriteTag(Ind+2, 'Sample', True); for i := 0 to Sample.Count-1 do InsertTag(Ind+4, 'S', Sample[i]); WriteTag(Ind+2, '/Sample', True); WriteTag(Ind, '/Info', True); end; end; //==== TStreamWriter ========================================================= function Indent(i: integer): string; begin SetLength(Result, i); // if i > 0 then !!!!!!!!!!!!!!!!!!!!!!!!! {To prevent error...} {$IFDEF FPC} if i > 0 then {$ENDIF} FillChar(Result[1], i, #32); end; function GetValidValue(Value: string): string; begin Value := StringReplace(Value, '&', '&', [rfReplaceAll, rfIgnoreCase]); Value := StringReplace(Value, '<', '<', [rfReplaceAll, rfIgnoreCase]); Value := StringReplace(Value, '"', '"', [rfReplaceAll, rfIgnoreCase]); Result := StringReplace(Value, '>', '>', [rfReplaceAll, rfIgnoreCase]); end; constructor TStreamWriter.Create(aStream: TStream); begin Stream := aStream; end; procedure TStreamWriter.WriteString(const Str: string); begin Stream.Write(Str[1], Length(Str)); end; procedure TStreamWriter.InsertTag(Ind: integer; Name: string; Value: string); begin WriteString(Format('%s<%s>%s'+EOL, [Indent(Ind), Name, GetValidValue(Value), Name])); end; { procedure OpenTag(Ind: integer; Name: string; Param: string = ''; ParamValue: string = ''); begin if Param = '' then WriteString(Format('%s<%s>', [Indent(Ind), Name])) else WriteString(Format('%s<%s %s="%s">', [Indent(Ind), Name, Param, GetValidValue(ParamValue)])); end;} procedure TStreamWriter.WriteTag(Ind: integer; Name: string; EndLine: boolean = False); begin WriteString(Format('%s<%s', [Indent(Ind), Name])); if EndLine then WriteString('>' + EOL); end; { procedure SaveColor(MainTag: string; Ind, Fore, Back: integer; Style: TFontStyles; PFore, PBack: boolean); procedure InsertTagBool(Ind: integer; Name: string; Value: Boolean); begin if Value then WriteString(Format('%s<%s>True', [Indent(Ind), Name, Name])) else WriteString(Format('%s<%s>False', [Indent(Ind), Name, Name])) end; begin OpenTag(Ind, MainTag); InsertTag(Ind+1, 'Back', Inttostr(Back)); InsertTag(Ind+1, 'Fore', Inttostr(Fore)); InsertTag(Ind+1, 'Style', Fs2String(Style)); InsertTagBool(Ind+1, 'ParentForeground', PFore); InsertTagBool(Ind+1, 'ParentBackground', PBack); OpenTag(Ind, '/'+MainTag); end;} procedure TStreamWriter.WriteParam(Key, Value: string; CloseTag: string = ''); begin WriteString(Format(' %s="%s"', [Key, GetValidValue(Value)])); if CloseTag <> '' then WriteString(CloseTag + EOL); end; procedure TStreamWriter.WriteBoolParam(Key: string; Value, Default: boolean; CloseTag: string = ''); begin If Value <> Default then WriteParam(Key, BoolToStr(Value,True), CloseTag); end; //==== TAttributes =========================================================== constructor TSynAttributes.Create(Name: String); begin // Std := TSynHighlighterAttributes.Create(SYNS_AttrDefaultPackage); inherited Create(Name{SYNS_AttrDefaultPackage}); // UseStyle := False; end; {destructor TSynAttributes.Destroy; //var xml: TXMLParser; begin // if not UseStyle then //Std.Free; // xml := TXMLParser.Create; // xml.Standalone inherited; end; } procedure TSynAttributes.LoadFromString(Value: string); begin ParentForeground := False; ParentBackground := False; Foreground := StrToIntDef(Copy(Value, 1, pos(',',Value)-1), 0); OldColorForeground := Foreground; Background := StrToIntDef(Copy(Value, pos(',',Value)+1, pos(';',Value)-pos(',',Value)-1), $FFFFFF); OldColorBackground := Background; ParentForeground := LowerCase(Copy(Value, pos(';',Value)+1, pos(':',Value)-pos(';',Value)-1)) = 'true'; ParentBackground := LowerCase(Copy(Value, pos(':',Value)+1, pos('.',Value)-pos(':',Value)-1)) = 'true'; Style := StrToFontStyle(Copy(Value, pos('.',Value)+1, Length(Value)-pos('.',Value))); // '12345,0;true:false.' { Std.Background := StrToIntDef(Value, $FFFFFF); OldColorBackground := Std.Background; Std.Foreground := StrToIntDef(Value, 0); OldColorForeground := Std.Foreground; Std.Style := String2Fs(Value) ParentForeground := LoweValue = 'true' ParentBackground := LowerValue = 'true';} end; procedure TSynAttributes.SaveToStream(StreamWriter: TStreamWriter); begin with StreamWriter do WriteParam('Attributes', IntToStr(Foreground)+','+IntToStr(Background)+';'+ BoolToStr(ParentForeground,True)+':'+ BoolToStr(ParentBackground,True)+'.'+ FontStyleToStr(Style)); end; //==== TSynSymbol ============================================================ constructor TSynSymbol.Create(st: string; Attribs: TSynHighlighterAttributes); //: Constructor of TSynSymbol begin Attributes := Attribs; Symbol := st; fOpenRule := nil; StartLine := slNotFirst; StartType := stUnspecified; BrakeType := btUnspecified; end; destructor TSynSymbol.Destroy; //: Destructor of TSynSymbol begin inherited; end; //==== TSymbolNode =========================================================== constructor TSymbolNode.Create(AC: char; SynSymbol: TSynSymbol; ABrakeType: TSymbBrakeType); begin ch := AC; NextSymbs := TSymbolList.Create; BrakeType := ABrakeType; StartType := SynSymbol.StartType; tkSynSymbol := SynSymbol; end; constructor TSymbolNode.Create(AC: char); begin ch := AC; NextSymbs := TSymbolList.Create; tkSynSymbol := nil; end; destructor TSymbolNode.Destroy; //: Destructor of TSymbolNode begin NextSymbs.Free; inherited; end; //==== TSymbolList =========================================================== procedure TSymbolList.AddSymbol(symb: TSymbolNode); //: Add Node to SymbolList begin SymbList.Add(symb); end; constructor TSymbolList.Create; //: Constructor of TSymbolList begin SymbList := TList.Create; end; destructor TSymbolList.Destroy; //: Destructor of TSymbolList begin FreeList(SymbList); inherited; end; function TSymbolList.FindSymbol(ch: char): TSymbolNode; //: Find Node in SymbolList by char var i: integer; begin Result := nil; for i := 0 to SymbList.Count-1 do if TSymbolNode(SymbList[i]).ch = ch then begin Result := TSymbolNode(SymbList[i]); break; end; end; function TSymbolList.GetCount: integer; //: Return Node count in SymbolList begin Result := SymbList.Count end; function TSymbolList.GetSymbolNode(Index: integer): TSymbolNode; //: Return Node in SymbolList by index begin Result := TSymbolNode(SymbList[index]); end; procedure TSymbolList.SetSymbolNode(Index: Integer; Value: TSymbolNode); //: Set Node in SymbolList bt index begin if Index < SymbList.Count then TSymbolNode(SymbList[index]).Free; SymbList[index] := Value; end; constructor TAbstractRule.Create(); begin Enabled := True; end; //==== TSynRule ============================================================== {function TSynRule.GetAttribs: TAttributes; begin if (Ind < 0) or (Ind >= AttribsList.Count) then raise Exception.CreateFmt ('Invalid index: %d', [Ind]); Result := TAttributes(AttribsList[Ind]); end; function TSynRule.GetAttribsByIndex(Index: integer): TAttributes; begin if (Index < 0) or (Index >= AttribsList.Count) then raise Exception.CreateFmt ('Invalid index: %d', [Ind]); Result := TAttributes(AttribsList[Index]); end; } constructor TSynRule.Create; begin inherited; ind := -1; Attribs := TSynAttributes.Create('unknown'); // AttribsList := TList.Create; end; destructor TSynRule.Destroy; begin // FreeList(AttribsList); { if Attribs <> nil then begin Attribs.Free; Attribs := nil; end;} inherited; end; {function TSynRule.AddAttribute(): integer; var i: integer; begin ind := AttribsList.Add(TAttributes.Create); Attribs.ParentForeground := True; Attribs.ParentBackground := True; Attribs.Std.Foreground := clBlack; Attribs.Std.Background := clWhite; Attribs.OldColorForeground := Attribs.Std.Foreground; Attribs.OldColorBackground := Attribs.Std.Background; Attribs.Std.Style := []; Result := ind; if self is TSynRange then with self as TSynRange do begin for i := 0 to RangeCount-1 do Ranges[i].AddAttribute(); for i := 0 to KeyListCount-1 do KeyLists[i].AddAttribute(); for i := 0 to SetCount-1 do Sets[i].AddAttribute(); end; end; procedure TSynRule.DeleteAttributes(Index: integer); var i: integer; begin AttribsList.Delete(Index); if AttribsList.Count = Index then ind := Index-1 else ind := Index; if self is TSynRange then with self as TSynRange do begin for i := 0 to RangeCount-1 do Ranges[i].DeleteAttributes(Index); for i := 0 to KeyListCount-1 do KeyLists[i].DeleteAttributes(Index); for i := 0 to SetCount-1 do Sets[i].DeleteAttributes(Index); end; end; procedure TSynRule.ClearAttributes(); var i: integer; begin ClearList(AttribsList); ind := -1; if self is TSynRange then with self as TSynRange do begin for i := 0 to RangeCount-1 do Ranges[i].ClearAttributes(); for i := 0 to KeyListCount-1 do KeyLists[i].ClearAttributes(); for i := 0 to SetCount-1 do Sets[i].ClearAttributes(); end; end; procedure TSynRule.SetAttributesIndex(Index: integer); var i: integer; begin ind := Index; if self is TSynRange then with self as TSynRange do begin for i := 0 to RangeCount-1 do Ranges[i].SetAttributesIndex(Index); for i := 0 to KeyListCount-1 do KeyLists[i].SetAttributesIndex(Index); for i := 0 to SetCount-1 do Sets[i].SetAttributesIndex(Index); end; end;} function TSynRule.GetAsStream: TMemoryStream; begin Result := TMemoryStream.Create; SaveToStream(Result); end; procedure TSynRule.SaveToStream(Stream: TStream; Ind: integer = 0); var StreamWriter: TStreamWriter; begin StreamWriter := TStreamWriter.Create(Stream); SaveToStream(StreamWriter, Ind); StreamWriter.Free; end; procedure TSynRule.LoadFromStream(aSrc: TStream); var I: Integer; ChildNode: TDOMNode; TagName: UnicodeString; xml: TXMLDocument = nil; begin if ClassName = 'TSynRange' then TagName := 'Range' else if ClassName = 'TSynKeyList' then TagName := 'Keywords' else if ClassName = 'TSynSet' then TagName := 'Set' else raise Exception.Create(ClassName + '.LoadFromStream - Unknown rule to load!'); try ReadXMLFile(xml, aSrc); for I:= 0 to Int32(xml.ChildNodes.Count) - 1 do begin ChildNode:= xml.ChildNodes.Item[I]; if SameText(ChildNode.NodeName, TagName) then LoadFromXml(ChildNode); end; finally xml.Free; end; end; procedure TSynRule.LoadFromFile(FileName: string); var xml: TXMLDocument = nil; begin if not FileExists(FileName) then raise Exception.Create(ClassName + '.LoadFromFile - "'+FileName+'" does not exists.'); try ReadXMLFile(xml, FileName); LoadFromXml(xml); finally xml.Free; end; end; //==== TSynUniStyles ========================================================= constructor TSynUniStyles.Create; begin Self.OwnsObjects := True; end; destructor TSynUniStyles.Destroy; begin inherited; end; function TSynUniStyles.GetStyle(const Name: string): {TSynHighlighter}TSynAttributes; begin Result := GetStyleDef(Name, nil); end; function TSynUniStyles.GetStyleDef(const Name: string; const Def: {TSynHighlighter}TSynAttributes): {TSynHighlighter}TSynAttributes; var i: integer; begin Result := Def; for i := 0 to Self.Count-1 do if SameText({TSynHighlighter}TSynAttributes(Self.Items[i]).Name, Name) then begin Result := {TSynHighlighter}TSynAttributes(Self.Items[i]); Exit; end; end; procedure TSynUniStyles.AddStyle(Name: string; Foreground, Background: TColor; FontStyle: TFontStyles); var Atr: {TSynHighlighter}TSynAttributes; begin Atr := {TSynHighlighter}TSynAttributes.Create(Name); Atr.Foreground := Foreground; Atr.Background := Background; Atr.Style := FontStyle; Self.Add(Atr); end; procedure TSynUniStyles.ListStylesNames(const AList: TStrings); var i: integer; begin aList.BeginUpdate; try aList.Clear; for i := 0 to Self.Count-1 do aList.Add({TSynHighlighter}TSynAttributes(Self.Items[i]).Name); finally aList.EndUpdate; end; end; function TSynUniStyles.GetStylesAsXML: string; var i: integer; begin // Result:= ''#13#10#13#10'; Result := ''#13#10; Result := Result + ' '#13#10; for i := 0 to Self.Count-1 do with {TSynHighlighter}TSynAttributes(Self.Items[I]) do Result := Result + '