diff --git a/.gitignore b/.gitignore
index 8d709c1..cfe59ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,43 +1,45 @@
*.lo
*.o
.deps/
.libs/
/aclocal.m4
/autom4te.cache
/config.h.in
/config.h
/config.log
/config.status
/configure
/Makefile.in
autom4te.cache/
assuan/Makefile.in
assuan/Makefile
curses/Makefile.in
curses/Makefile
doc/Makefile.in
doc/Makefile
doc/pinentry.info
doc/stamp-vti
doc/version.texi
fltk/Makefile.in
fltk/Makefile
gtk+-2/Makefile.in
gtk+-2/Makefile
gnome3/Makefile.in
gnome3/Makefile
pinentry/Makefile.in
pinentry/Makefile
qt/Makefile.in
qt/Makefile
+tqt/Makefile.in
+tqt/Makefile
secmem/Makefile.in
secmem/Makefile
w32/Makefile.in
w32/Makefile
tty/Makefile.in
tty/Makefile
/qt/pinentryconfirm.moc
/qt/pinentrydialog.moc
/qt/qsecurelineedit.moc
/m4/Makefile.in
/emacs/Makefile.in
diff --git a/Makefile.am b/Makefile.am
index e11b009..8c8b8e5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,123 +1,130 @@
# Makefile.am
# Copyright (C) 2002, 2012, 2015 g10 Code GmbH
#
# This file is part of PINENTRY.
#
# PINENTRY 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.
#
# PINENTRY 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 .
# SPDX-License-Identifier: GPL-2.0+
## Process this file with automake to produce Makefile.in
ACLOCAL_AMFLAGS = -I m4
DISTCHECK_CONFIGURE_FLAGS = --disable-pinentry-qt --enable-pinentry-emacs
GITLOG_TO_CHANGELOG=gitlog-to-changelog
EXTRA_DIST = autogen.sh autogen.rc README.GIT ChangeLog-old \
build-aux/gitlog-to-changelog \
build-aux/git-log-fix build-aux/git-log-footer
if BUILD_PINENTRY_CURSES
pinentry_curses = curses
else
pinentry_curses =
endif
if BUILD_PINENTRY_TTY
pinentry_tty = tty
else
pinentry_tty =
endif
if BUILD_PINENTRY_EMACS
pinentry_emacs = emacs
else
pinentry_emacs =
endif
if BUILD_PINENTRY_GTK_2
pinentry_gtk_2 = gtk+-2
else
pinentry_gtk_2 =
endif
if BUILD_PINENTRY_GNOME_3
pinentry_gnome_3 = gnome3
else
pinentry_gnome_3 =
endif
if BUILD_PINENTRY_QT
pinentry_qt = qt
else
pinentry_qt =
endif
+if BUILD_PINENTRY_TQT
+pinentry_tqt = tqt
+else
+pinentry_tqt =
+endif
+
if BUILD_PINENTRY_W32
pinentry_w32 = w32
else
pinentry_w32 =
endif
if BUILD_PINENTRY_FLTK
pinentry_fltk = fltk
else
pinentry_fltk =
endif
SUBDIRS = m4 secmem pinentry ${pinentry_curses} ${pinentry_tty} \
${pinentry_emacs} ${pinentry_gtk_2} ${pinentry_gnome_3} \
- ${pinentry_qt} ${pinentry_w32} ${pinentry_fltk} doc
+ ${pinentry_qt} ${pinentry_tqt} ${pinentry_w32} \
+ ${pinentry_fltk} doc
install-exec-local:
@list='$(bin_PROGRAMS)'; for p in $$list; do \
echo " $(SETCAP) cap_ipc_lock+p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
$(SETCAP) cap_ipc_lock+p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'` || true; \
done
(cd $(DESTDIR)$(bindir); \
rm -f pinentry; \
$(LN_S) $(PINENTRY_DEFAULT)$(EXEEXT) pinentry)
dist-hook: gen-ChangeLog
echo "$(VERSION)" > $(distdir)/VERSION
distcheck-hook:
set -e; ( \
pref="#+macro: pinentry_" ;\
reldate="$$(date -u +%Y-%m-%d)" ;\
echo "$${pref}ver $(PACKAGE_VERSION)" ;\
echo "$${pref}date $${reldate}" ;\
list='$(DIST_ARCHIVES)'; for i in $$list; do \
case "$$i" in *.tar.bz2) \
echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\
echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\
echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\
esac;\
done ) | tee $(distdir).swdb
gen_start_date = 2012-08-08T00:00:00
.PHONY: gen-ChangeLog
gen-ChangeLog:
if test -d $(top_srcdir)/.git; then \
(cd $(top_srcdir) && \
$(GITLOG_TO_CHANGELOG) --append-dot --tear-off \
--amend=build-aux/git-log-fix \
--since=$(gen_start_date) ) > $(distdir)/cl-t; \
cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;\
rm -f $(distdir)/ChangeLog; \
mv $(distdir)/cl-t $(distdir)/ChangeLog; \
fi
diff --git a/NEWS b/NEWS
index 5534d4d..b1976c3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,363 +1,365 @@
Noteworthy changes in version 1.0.1 (unreleased)
------------------------------------------------
* A FLTK1.3-based pinentry has been contributed.
+ * A TQt3-based pinentry has been contributed.
+
* New option --ttyalert for pinentry-curses to alert the user.
* Don't show "save passphrase" checkbox if secret service is
unavailable.
Noteworthy changes in version 1.0.0 (2016-11-22)
------------------------------------------------
* Qt pinentry now supports repeat mode in one dialog.
* Qt and GTK pinentries now make it possible to show the entered
value.
* Qt pinentry now only grabs the keyboard if an entry field is
focused.
* Fixed foreground handling in pinentry-qt if compiled with Qt5 for
Windows.
* Fixed potential crash in Qt qualitybar calculation.
* GTK keyboard grabbing is now a bit more robust. The cursor is
changed to a big dot as a visual indication that a pinentry has
popped up and is waiting for input.
* The GNOME pinentry now falls back to curses if it can't use the
GCR system prompter or a screenlock is active.
* Fixed error output for cached passwords.
* A show/hide passphrase button or checkbox is now available with
some pinentry flavors.
* Improved diagnostics and error codes.
Noteworthy changes in version 0.9.7 (2015-12-07)
------------------------------------------------
* Fix regressions in the Qt pinentry.
* Fix minor problems pinnetyr-tty.
* New option --invisible-char.
Noteworthy changes in version 0.9.6 (2015-09-10)
------------------------------------------------
* Many improvements for the dump tty pinentry.
* Use the standard GTK+-2 text entry widget instead of our outdated
and back-then-it-was-more-secure text widget.
* Use the standard Qt text widget.
* Allow for building a static Qt variant.
* Fix regression in w32 pinentry.
Noteworthy changes in version 0.9.5 (2015-07-01)
------------------------------------------------
* Replaced the internal Assuan and gpg-error code by the standard
libassuan and libgpg-error libraries.
* Add a new Emacs pinentry and use as fallback for GUI programs.
* gnome3: The use-password-manager checkbox does now work.
* Gtk: Improved fallback to curses feature.
* curses: Recognize DEL as backspace.
Noteworthy changes in version 0.9.4 (2015-06-05)
------------------------------------------------
* Fix regression in GTK+ and curses pinentries.
Noteworthy changes in version 0.9.3 (2015-06-01)
------------------------------------------------
* Improved documentation
* New pinentry-gnome3
* More improvements for pinentry-tty.
* Fixes for pinentry-curses including support for Ctrl-W, Ctrl-U,
Ctrl-H, Ctrl-L, and Alt-Backspace
* New Assuan command to request clearing an external cache.
* Fixed problems linking to ncursesw.
* All kind of other minor fixes.
Noteworthy changes in version 0.9.2 (2015-05-11)
------------------------------------------------
* Support for saving the passphrase with libsecret.
* Escape key works in the Gtk+ pinentry.
* Improvements for pinentry-tty.
* Minor cleanups for the native Windows pinentry.
Noteworthy changes in version 0.9.1 (2015-03-18)
------------------------------------------------
* Fixed build problems for systems without ncurses.
* Reworked the option parser to allow building on systems without
getopt_long.
* Fixed Qt4 build problems.
Noteworthy changes in version 0.9.0 (2014-10-26)
------------------------------------------------
* New command SETREPEAT. Currently only supported for Gtk+-2.
* Gtk+-2: Pasting using the mouse is now supported.
* curses: Check that it is actually connected to a tty.
* Removed the old qt-3 and gtk+-1 pinentries.
Noteworthy changes in version 0.8.4 (2014-09-18)
------------------------------------------------
* New pinentry-tty version for dumb terminals.
* Qt4: New option to enable pasting the passphrase from clipboard
* Qt4: Improved accessiblity
* Qt4: Raise confirm message windows into foreground
* Qt4 (Windows): Improve the way pinentry-qt raises itself in the
foreground.
* Improved the build system.
Noteworthy changes in version 0.8.3 (2013-04-26)
------------------------------------------------
* Build fixes for newer mingw32 toolchains.
* Add SETTIMEOUT command for the gtk+-2 pinentry.
Noteworthy changes in version 0.8.2 (2012-08-08)
------------------------------------------------
* New SETTIMEOUT command for the qt4 pinentry.
* Wide character support for the curses pinentry.
* Various bug fixes.
Noteworthy changes in version 0.8.1 (2010-12-16)
------------------------------------------------
* The W32 pinentry now supports WindowsCE.
* The GTK pinentry now always sticks to the top and properly grabs
the keyboard.
* The protocol options default-cancel and default-ok now work for the
pinentry-gtk2 and pinentry-qt (that is QT3).
Noteworthy changes in version 0.8.0 (2010-03-03)
------------------------------------------------
* Beautified the qt4 pinentry
* Minor enhancements.
Noteworthy changes in version 0.7.6 (2009-06-19)
------------------------------------------------
* Make Gtk+-2 pinentry transient to the root window.
* Add Qt4 pinentry.
* Add native W32 pinentry.
* Fix utf-8 problem in Qt pinentries.
* Return GPG_ERR_CANCELED if during a "CONFIRM" command the user
closed the window.
* Add quality bar.
Noteworthy changes in version 0.7.5 (2008-02-15)
------------------------------------------------
* Fix cross compilation for Gtk+-2 pinentry.
* New Assuan command GETINFO with subcommands "version" and "pid".
Noteworthy changes in version 0.7.4 (2007-11-29)
------------------------------------------------
* Pinentry-gtk-2 and pinentry-qt now support a simple passphrase
quality indicator.
Noteworthy changes in version 0.7.3 (2007-07-06)
------------------------------------------------
* New command MESSAGE and --one-button compatibility option to
CONFIRM.
* New Assuan option touch-file to set a file which will be touched
after ncurses does not need the display anymore.
* New option --colors=FG,BG,SO to set the colors for the curses
pinentry.
* Pinentry-w32 does now basically work. It needs some finishing
though. For example the buttons should resize themself according
to the size of the text.
Noteworthy changes in version 0.7.2 (2005-01-27)
------------------------------------------------
* Remove bug in configure script that would use installed version of
Qt even if another path was explicitely specified with QTDIR.
* Honor the rpath setting for Qt.
* Add GTK+-2 pinentry.
* Install a symbolic link under the name "pinentry" that defaults to
pinentry-gtk, pinentry-qt, pinentry-gtk-2, or pinentry-curses, in
that order.
Noteworthy changes in version 0.7.1 (2004-04-21)
------------------------------------------------
* Removed unneeded Assuan cruft.
* Fixes for *BSD.
Noteworthy changes in version 0.7.0 (2003-12-23)
------------------------------------------------
* Make UTF8 description (prompt, error message, button texts) work.
* Make sure that secmem_term is called before program termination.
* Make assuan in Gtk and Curses pinentry use secure memory for
storage.
* Fixed a bug that would occur if a canceled GETPIN was immediately
followed by a CONFIRM.
* Disabled undo/redo in Qt pinentry.
* Print diagnostics for locale problems and return a new error code
in that case.
Noteworthy changes in version 0.6.8 (2003-02-07)
------------------------------------------------
* Bug fix in pinentry-qt.
Noteworthy changes in version 0.6.7 (2002-11-20)
------------------------------------------------
* Workaround for a bug in the curses version which led to an infinite
loop.
Noteworthy changes in version 0.6.6 (2002-11-09)
------------------------------------------------
* Fixed handling of DISPLAY and --display for the sake of the curses
fallback.
* UTF-8 conversion does now work for the GTK+ and CURSES version.
Noteworthy changes in version 0.6.5 (2002-09-30)
------------------------------------------------
* Handle Assuan options in the qt version.
Noteworthy changes in version 0.6.4 (2002-08-19)
------------------------------------------------
* Handle CONFIRM command in the qt version.
Noteworthy changes in version 0.6.3 (2002-06-26)
------------------------------------------------
* Minor bug fixes to the qt version.
Noteworthy changes in version 0.6.2 (2002-05-13)
------------------------------------------------
* Error texts can now be percent-escaped.
* The Curses pinentry supports multi-line error texts.
* The GTK+ and Qt pinentry can fall back to curses if no display is
available.
Noteworthy changes in version 0.6.1 (2002-04-25)
------------------------------------------------
* The Curses pinentry supports user-provided button texts via the
new SETOK and SETCANCEL commands.
* The Curses pinentry supports setting the desired character set
locale with --lc-ctype and correctly translates the UTF-8 strings
into that.
Noteworthy changes in version 0.6.0 (2002-04-05)
------------------------------------------------
* Merged all pinentry frontends into a single module.
* There is now a Curses frontend.
* The curses pinentry supports --ttyname and --ttytype options to
set the desired input/output terminal and its type.
Noteworthy changes in version 0.5.1 (2002-02-18)
------------------------------------------------
* CONFIRM command works
Noteworthy changes in version 0.5.0 (2002-01-04)
------------------------------------------------
* Window layout is somewhat nicer
* percent escape sequences do now work for SETDESC and SETERROR
diff --git a/configure.ac b/configure.ac
index 3de0882..86cf98b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,718 +1,760 @@
# configure.ac
# Copyright (C) 1999 Robert Bihlmeyer
# Copyright (C) 2001, 2002, 2003, 2004, 2007, 2015, 2016 g10 Code GmbH
#
# This file is part of PINENTRY.
#
# PINENTRY 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.
#
# PINENTRY 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 .
# SPDX-License-Identifier: GPL-2.0+
# (Process this file with autoconf to produce a configure script.)
AC_PREREQ(2.69)
min_automake_version="1.14"
# To build a release you need to create a tag with the version number
# (git tag -s pinentry-n.m.k) and run "./autogen.sh --force". Please
# bump the version number immediately after the release, do another
# commit, and a push so that the git magic is able to work.
m4_define(mym4_version, [1.0.1])
# Below is m4 magic to extract and compute the git revision number,
# the decimalized short revision number, a beta version string and a
# flag indicating a development version (mym4_isgit). Note that the
# m4 processing is done by autoconf and not during the configure run.
m4_define([mym4_revision], m4_esyscmd([git branch -v 2>/dev/null \
| awk '/^\* / {printf "%s",$3}']))
m4_define([mym4_revision_dec],
m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))]))
m4_define([mym4_betastring],
m4_esyscmd_s([git describe --match 'pinentry-[0-9].[0-9].*[0-9]' \
--long| awk -F- '$3!=0{print"-beta"$3}']))
m4_define([mym4_isgit],m4_if(mym4_betastring,[],[no],[yes]))
m4_define([mym4_full_version],[mym4_version[]mym4_betastring])
AC_INIT([pinentry],[mym4_full_version], [https://bugs.gnupg.org])
AC_CONFIG_AUX_DIR([build-aux])
AM_CONFIG_HEADER(config.h)
AC_CONFIG_SRCDIR(pinentry/pinentry.h)
AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip])
AC_GNU_SOURCE
AM_MAINTAINER_MODE
AC_CANONICAL_HOST
AH_TOP([
#ifndef PINENTRY_CONFIG_H_INCLUDED
#define PINENTRY_CONFIG_H_INCLUDED
/* Enable gpg-error's strerror macro under W32CE. */
#define GPG_ERR_ENABLE_ERRNO_MACROS 1
])
AH_BOTTOM([
#endif /*PINENTRY_CONFIG_H_INCLUDED*/
])
dnl Checks for programs.
AC_PROG_MAKE_SET
AM_SANITY_CHECK
missing_dir=`cd $ac_aux_dir && pwd`
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_RANLIB
# We need to check for cplusplus here because we may not do the test
# for Qt and autoconf does does not allow that.
AC_PROG_CXX
AC_PROG_LN_S
PKG_PROG_PKG_CONFIG
AC_CHECK_TOOL(WINDRES, windres, :)
AC_CHECK_PROGS(GITLOG_TO_CHANGELOG, gitlog-to-changelog,
[build-aux/gitlog-to-changelog])
have_dosish_system=no
have_w32_system=no
have_w32ce_system=no
case "${host}" in
*-mingw32*)
AC_DEFINE(USE_ONLY_8DOT3,1,
[Set this to limit filenames to the 8.3 format])
have_dosish_system=yes
have_w32_system=yes
case "${host}" in
*-mingw32ce*)
have_w32ce_system=yes
;;
*)
AC_DEFINE(HAVE_DRIVE_LETTERS,1,
[Defined if the OS supports drive letters.])
;;
esac
;;
i?86-emx-os2 | i?86-*-os2*emx )
# OS/2 with the EMX environment
AC_DEFINE(HAVE_DRIVE_LETTERS)
have_dosish_system=yes
;;
i?86-*-msdosdjgpp*)
# DOS with the DJGPP environment
AC_DEFINE(HAVE_DRIVE_LETTERS)
have_dosish_system=yes
;;
esac
if test "$have_dosish_system" = yes; then
AC_DEFINE(HAVE_DOSISH_SYSTEM,1,
[Defined if we run on some of the PCDOS like systems
(DOS, Windoze. OS/2) with special properties like
no file modes])
fi
AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = yes)
if test "$have_w32_system" = yes; then
AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on a W32 API based system])
if test "$have_w32ce_system" = yes; then
AC_DEFINE(HAVE_W32CE_SYSTEM,1,[Defined if we run on WindowsCE])
fi
fi
AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes)
AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes)
dnl Checks for compiler features.
if test "$GCC" = yes; then
# Check whether gcc does not emit a diagnositc for unknown -Wno-*
# options. This is the case for gcc >= 4.6
AC_MSG_CHECKING([if gcc ignores unknown -Wno-* options])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6 )
#kickerror
#endif]],[])],[_gcc_silent_wno=yes],[_gcc_silent_wno=no])
AC_MSG_RESULT($_gcc_silent_wno)
if test "$USE_MAINTAINER_MODE" = "yes"; then
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security"
if test x"$_gcc_silent_wno" = xyes ; then
_gcc_warn=yes
else
AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers])
_gcc_cflags_save=$CFLAGS
CFLAGS="-Wno-missing-field-initializers"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],
[_gcc_warn=yes],[_gcc_warn=no])
AC_MSG_RESULT($_gcc_warn)
CFLAGS=$_gcc_cflags_save;
fi
if test x"$_gcc_warn" = xyes ; then
CFLAGS="$CFLAGS -W -Wno-sign-compare -Wno-missing-field-initializers"
fi
AC_MSG_CHECKING([if gcc supports -Wdeclaration-after-statement])
_gcc_cflags_save=$CFLAGS
CFLAGS="-Wdeclaration-after-statement"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_warn=yes,_gcc_warn=no)
AC_MSG_RESULT($_gcc_warn)
CFLAGS=$_gcc_cflags_save;
if test x"$_gcc_warn" = xyes ; then
CFLAGS="$CFLAGS -Wdeclaration-after-statement"
fi
else
# Not in maintainer mode: Use standard warnings.
CFLAGS="$CFLAGS -Wall"
fi
CPPFLAGS="$CPPFLAGS -Wall"
if test x"$_gcc_silent_wno" = xyes ; then
_gcc_warn=yes
else
AC_MSG_CHECKING([if gcc supports -Wno-pointer-sign])
_gcc_cflags_save=$CFLAGS
CFLAGS="-Wno-pointer-sign"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],[_gcc_warn=yes],[_gcc_warn=no])
AC_MSG_RESULT($_gcc_warn)
CFLAGS=$_gcc_cflags_save;
fi
if test x"$_gcc_warn" = xyes ; then
CFLAGS="$CFLAGS -Wno-pointer-sign"
fi
AC_MSG_CHECKING([if gcc supports -Wpointer-arith])
_gcc_cflags_save=$CFLAGS
CFLAGS="-Wpointer-arith"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_warn=yes,_gcc_warn=no)
AC_MSG_RESULT($_gcc_warn)
CFLAGS=$_gcc_cflags_save;
if test x"$_gcc_warn" = xyes ; then
CFLAGS="$CFLAGS -Wpointer-arith"
fi
fi
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(string.h unistd.h langinfo.h termio.h locale.h utime.h wchar.h)
dnl Checks for library functions.
AC_CHECK_FUNCS(seteuid stpcpy mmap)
GNUPG_CHECK_MLOCK
dnl Checks for standard types.
AC_TYPE_UINT32_T
# Common libraries and cflags.
COMMON_CFLAGS=
COMMON_LIBS=
AC_SUBST(COMMON_CFLAGS)
AC_SUBST(COMMON_LIBS)
dnl Checks for libgpg-error
#
# libgpg-error is a library with error codes shared between GnuPG
# related projects.
#
NEED_GPG_ERROR_VERSION=1.16
have_gpg_error=no
AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION",
have_gpg_error=yes,have_gpg_error=no)
COMMON_CFLAGS="$GPG_ERROR_CFLAGS $COMMON_CFLAGS"
COMMON_LIBS="$GPG_ERROR_LIBS $COMMON_LIBS"
AC_DEFINE_UNQUOTED(GPG_ERR_ENABLE_GETTEXT_MACROS, 1,
[Under Windows we use the gettext code from libgpg-error])
AC_DEFINE_UNQUOTED(GPG_ERR_ENABLE_ERRNO_MACROS, 1,
[Under WindowsCE we use the strerror replacement from libgpg-error.])
dnl Checks for libassuan.
#
# libassuan is used for IPC
#
NEED_LIBASSUAN_API=2
NEED_LIBASSUAN_VERSION=2.1.0
have_libassuan=no
AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION",
have_libassuan=yes,have_libassuan=no)
if test "$have_libassuan" = "yes"; then
AC_DEFINE_UNQUOTED(GNUPG_LIBASSUAN_VERSION, "$libassuan_version",
[version of the libassuan library])
fi
COMMON_CFLAGS="$LIBASSUAN_CFLAGS $COMMON_CFLAGS"
COMMON_LIBS="$LIBASSUAN_LIBS $COMMON_LIBS"
dnl Checks for libsecmem.
GNUPG_CHECK_TYPEDEF(byte, HAVE_BYTE_TYPEDEF)
GNUPG_CHECK_TYPEDEF(ulong, HAVE_ULONG_TYPEDEF)
dnl Check for libcap
AC_ARG_WITH([libcap], AC_HELP_STRING([--without-libcap],
[Disable support for capabilities library]))
if test "x$with_libcap" != "xno"; then
AC_PATH_PROG(SETCAP, setcap, :, "$PATH:/sbin:/usr/sbin")
AC_CHECK_LIB(cap, cap_set_proc, [
AC_DEFINE(USE_CAPABILITIES,1,[The capabilities support library is installed])
LIBCAP=-lcap
])
fi
AC_SUBST(LIBCAP)
dnl
dnl Check for curses pinentry program.
dnl
AC_ARG_ENABLE(pinentry-curses,
AC_HELP_STRING([--enable-pinentry-curses], [build curses pinentry]),
pinentry_curses=$enableval, pinentry_curses=maybe)
AC_ARG_ENABLE(fallback-curses,
AC_HELP_STRING([--enable-fallback-curses], [include curses fallback]),
fallback_curses=$enableval, fallback_curses=maybe)
dnl
dnl Checks for curses libraries. Deal correctly with $pinentry_curses = maybe
dnl and $fallback_curses = maybe.
dnl
if test "$pinentry_curses" != "no" -o "$fallback_curses" != "no"; then
IU_LIB_CURSES
fi
if test "$LIBCURSES"; then
if test "$pinentry_curses" != "no"; then
pinentry_curses=yes
fi
if test "$fallback_curses" != "no"; then
fallback_curses=yes
AC_DEFINE(FALLBACK_CURSES, 1,
[The GUI pinentries should fall back to curses if X is not available.])
fi
else
if test "$pinentry_curses" = "yes" -o "$fallback_curses" = "yes"; then
AC_MSG_ERROR([[
***
*** The curses library is required. The latest version of
*** ncurses is always available from ftp://ftp.gnu.org/gnu/ncurses/.
***]])
fi
pinentry_curses=no
fallback_curses=no
fi
AM_CONDITIONAL(BUILD_LIBPINENTRY_CURSES,
test "$pinentry_curses" = "yes" -o "$fallback_curses" = "yes")
AM_CONDITIONAL(BUILD_PINENTRY_CURSES, test "$pinentry_curses" = "yes")
AM_CONDITIONAL(FALLBACK_CURSES, test "$fallback_curses" = "yes")
if test "$pinentry_curses" = "yes"; then
AC_DEFINE(PINENTRY_CURSES, 1,
[The Curses version of Pinentry is to be build])
fi
dnl
dnl Check for tty pinentry program.
dnl
AC_ARG_ENABLE(pinentry-tty,
AC_HELP_STRING([--enable-pinentry-tty], [build tty pinentry]),
pinentry_tty=$enableval, pinentry_tty=maybe)
AM_CONDITIONAL(BUILD_PINENTRY_TTY, test "$pinentry_tty" = "yes")
if test "$pinentry_tty" = "yes"; then
AC_DEFINE(PINENTRY_TTY, 1,
[The TTY version of Pinentry is to be build])
fi
dnl
dnl Additional checks pinentry Curses.
dnl
if test "$pinentry_curses" = "yes" \
-o "$fallback_curses" = "yes" ; then
AM_ICONV
if test "$am_cv_func_iconv" != "yes"; then
AC_MSG_ERROR([[
***
*** The iconv function is required. You can specify its location
*** using the --with-libiconv-prefix=PREFIX option to configure.
***]])
fi
fi
dnl
dnl Check for emacs pinentry program.
dnl
AC_ARG_ENABLE(pinentry-emacs,
AC_HELP_STRING([--enable-pinentry-emacs], [build emacs pinentry]),
pinentry_emacs=$enableval, pinentry_emacs=no)
AC_ARG_ENABLE(inside-emacs,
AC_HELP_STRING([--enable-inside-emacs], [include emacs hack]),
inside_emacs=$enableval, inside_emacs=maybe)
if test "$pinentry_emacs" != "no" -o "$inside_emacs" != "no"; then
AC_MSG_CHECKING([if Unix domain socket is supported])
AC_TRY_COMPILE([
#include
#include
],
[int s = socket (AF_UNIX, SOCK_STREAM, 0);],
[_unixsock_works=yes],
[_unixsock_works=no])
AC_MSG_RESULT($_unixsock_works)
if test "$_unixsock_works" = "yes"; then
if test "$pinentry_emacs" != "no"; then
pinentry_emacs=yes
fi
if test "$inside_emacs" != "no"; then
inside_emacs=yes
AC_DEFINE(INSIDE_EMACS, 1,
[The GUI pinentries should respect INSIDE_EMACS envvar.])
fi
else
if test "$pinentry_emacs" = "yes" -o "$inside_emacs" = "yes"; then
AC_MSG_ERROR([[
***
*** Support for Unix domain sockets is required.
***]])
fi
pinentry_emacs=no
inside_emacs=no
fi
fi
AM_CONDITIONAL(BUILD_LIBPINENTRY_EMACS,
test "$pinentry_emacs" = "yes" -o "$inside_emacs" = "yes")
AM_CONDITIONAL(BUILD_PINENTRY_EMACS, test "$pinentry_emacs" = "yes")
AM_CONDITIONAL(INSIDE_EMACS, test "$inside_emacs" = "yes")
if test "$pinentry_emacs" = "yes"; then
AC_DEFINE(PINENTRY_EMACS, 1,
[The Emacs version of Pinentry is to be build])
fi
dnl
dnl Check for GTK+-2 / GNOME3 pinentry programs.
dnl
AC_ARG_ENABLE(pinentry-gtk2,
AC_HELP_STRING([--enable-pinentry-gtk2], [build GTK+-2 pinentry]),
pinentry_gtk_2=$enableval, pinentry_gtk_2=maybe)
AC_ARG_ENABLE(pinentry-gnome3,
AC_HELP_STRING([--enable-pinentry-gnome3], [build GNOME 3 pinentry]),
pinentry_gnome_3=$enableval, pinentry_gnome_3=maybe)
dnl check if the module gtk+-2.0 exists
if test "$pinentry_gtk_2" != "no"; then
PKG_CHECK_MODULES(
GTK2,
[gtk+-2.0 >= 2.4.0],
[
test "$pinentry_gtk_2" != "no" && pinentry_gtk_2=yes
test "$pinentry_gnome_3" != "no" && pinentry_gnome_3=yes
],
[
AC_MSG_WARN([pkg-config could not find the module gtk+-2.0])
pinentry_gtk_2=no
]
)
fi
AM_CONDITIONAL(BUILD_PINENTRY_GTK_2, test "$pinentry_gtk_2" = "yes")
if test "$pinentry_gnome_3" != "no"; then
PKG_CHECK_MODULES(
GNOME3,
[gcr-3,gcr-base-3],
[
pinentry_gnome_3=yes
AC_DEFINE(GCR_API_SUBJECT_TO_CHANGE, 1, [Nod nod])
],
[
AC_MSG_WARN([pkg-config could not find the module gcr-3,gcr-base-3])
pinentry_gnome_3=no
]
)
fi
AM_CONDITIONAL(BUILD_PINENTRY_GNOME_3, test "$pinentry_gnome_3" = "yes")
dnl
dnl Check for libsecret.
dnl
AC_ARG_ENABLE(libsecret,
AC_HELP_STRING([--enable-libsecret],
[optionally cache passphrases using libsecret]),
libsecret=$enableval, libsecret=maybe)
dnl check if the module libsecret exists
if test "$libsecret" != "no"; then
PKG_CHECK_MODULES(
LIBSECRET,
[libsecret-1],
[libsecret=yes],
[
AC_MSG_WARN([pkg-config could not find the module libsecret-1])
libsecret=no
]
)
fi
AM_CONDITIONAL(BUILD_WITH_LIBSECRET, test "$libsecret" = "yes")
if test "$libsecret" = "yes"; then
AC_DEFINE(HAVE_LIBSECRET, 1,
[The pinentries should optionally cache the passphrase using libsecret.])
COMMON_CFLAGS="$LIBSECRET_CFLAGS $COMMON_CFLAGS"
COMMON_LIBS="$LIBSECRET_LIBS $COMMON_LIBS"
fi
dnl
dnl Check for Qt pinentry program.
dnl
AC_ARG_ENABLE(pinentry-qt,
AC_HELP_STRING([--enable-pinentry-qt], [build qt pinentry]),
pinentry_qt=$enableval, pinentry_qt=maybe)
dnl
dnl Checks for qt libraries. Deal correctly with $pinentry_qt = maybe.
dnl Tries to find Qt5, falls back on Qt4
dnl
if test "$pinentry_qt" != "no"; then
FIND_QT
if test "$have_qt4_libs" != "yes" -a "$have_qt5_libs" != "yes"; then
if test "$pinentry_qt" = "yes"; then
AC_MSG_ERROR([[
***
*** Qt4 (QtCore, QtGui) or Qt5 (Qt5Core, Qt5Gui, Qt5Widgets) is required.
***]])
else
pinentry_qt=no
fi
fi
fi
AC_SUBST(PINENTRY_QT_CFLAGS)
AC_SUBST(PINENTRY_QT_LIBS)
AC_SUBST(MOC)
dnl If we have come so far, qt pinentry can be build.
if test "$pinentry_qt" != "no"; then
pinentry_qt=yes
fi
AM_CONDITIONAL(BUILD_PINENTRY_QT, test "$pinentry_qt" = "yes")
if test "$pinentry_qt" = "yes"; then
AC_DEFINE(PINENTRY_QT, 1, [The qt version of Pinentry is to be build])
if test "$have_qt4_libs" = "yes"; then
pinentry_qt_lib_version="(Qt4)"
else
pinentry_qt_lib_version="(Qt5)"
fi
fi
+dnl
+dnl Check for TQt pinentry program.
+dnl
+AC_ARG_ENABLE(pinentry-tqt,
+ AC_HELP_STRING([--enable-pinentry-tqt], [build tqt pinentry]),
+ pinentry_tqt=$enableval, pinentry_tqt=no)
+
+if test "$pinentry_tqt" != "no"; then
+
+ if test "$pinentry_qt" = "yes"; then
+ AC_MSG_ERROR([[
+ ***
+ *** Building both Qt and TQt pinentries is not supported.
+ *** Use --disable-pinentry-qt if you want the TQt pinentry.
+ ***]])
+ fi
+
+ PKG_CHECK_MODULES(PINENTRY_TQT, tqt,
+ have_tqt_libs=yes,
+ [PKG_CHECK_MODULES(PINENTRY_TQT, tqt-mt,
+ have_tqt_libs=yes, have_tqt_libs=no)])
+
+ if test "$have_tqt_libs" = "yes"; then
+ AC_CHECK_TOOL([TQT_MOC], tqmoc, "no")
+ fi
+
+ if test "$have_tqt_libs" = "yes" -a "$TQT_MOC" != "no"; then
+ pinentry_tqt=yes
+ else
+ AC_MSG_WARN([TQt is not found])
+ pinentry_tqt=no
+ fi
+
+fi
+AM_CONDITIONAL(BUILD_PINENTRY_TQT, test "$pinentry_tqt" = "yes")
+
#
# Check whether we should build the W32 pinentry. This is actually
# the simplest check as we do this only for that platform.
#
pinentry_w32=no
test $have_w32_system = yes && pinentry_w32=yes
AM_CONDITIONAL(BUILD_PINENTRY_W32, test "$pinentry_w32" = "yes")
dnl
dnl Check for FLTK pinentry program.
dnl
AC_ARG_ENABLE(pinentry-fltk,
AC_HELP_STRING([--enable-pinentry-fltk], [build FLTK 1.3 pinentry]),
pinentry_fltk=$enableval, pinentry_fltk=maybe)
dnl check for fltk-config
if test "$pinentry_fltk" != "no"; then
AC_PATH_PROG(FLTK_CONFIG, fltk-config, no)
if test x"${FLTK_CONFIG}" = xno ; then
AC_MSG_WARN([fltk-config is not found])
pinentry_fltk=no
fi
fi
dnl check for FLTK libraries and set flags
if test "$pinentry_fltk" != "no"; then
AC_MSG_CHECKING([for FLTK 1.3])
FLTK_VERSION=`${FLTK_CONFIG} --api-version`
if test ${FLTK_VERSION} != "1.3" ; then
AC_MSG_RESULT([no])
AC_MSG_WARN([FLTK 1.3 not found (available $FLTK_VERSION)])
pinentry_fltk=no
else
AC_MSG_RESULT([yes])
FLTKCFLAGS=`${FLTK_CONFIG} --cflags`
FLTKCXXFLAGS=`${FLTK_CONFIG} --cxxflags`
FLTKLIBS=`${FLTK_CONFIG} --ldflags`
AC_SUBST(FLTKCFLAGS)
AC_SUBST(FLTKCXXFLAGS)
AC_SUBST(FLTKLIBS)
pinentry_fltk=yes
fi
fi
AM_CONDITIONAL(BUILD_PINENTRY_FLTK, test "$pinentry_fltk" = "yes")
# Figure out the default pinentry. We are very conservative here.
# Please change the order only after verifying that the preferred
# pinentry really is better (more feature-complete and more secure).
if test "$pinentry_gtk_2" = "yes"; then
PINENTRY_DEFAULT=pinentry-gtk-2
else
if test "$pinentry_qt" = "yes"; then
PINENTRY_DEFAULT=pinentry-qt
else
if test "$pinentry_gnome_3" = "yes"; then
PINENTRY_DEFAULT=pinentry-gnome3
else
if test "$pinentry_curses" = "yes"; then
PINENTRY_DEFAULT=pinentry-curses
else
if test "$pinentry_tty" = "yes"; then
PINENTRY_DEFAULT=pinentry-tty
else
if test "$pinentry_w32" = "yes"; then
PINENTRY_DEFAULT=pinentry-w32
else
if test "$pinentry_fltk" = "yes"; then
PINENTRY_DEFAULT=pinentry-fltk
else
- AC_MSG_ERROR([[No pinentry enabled.]])
+ if test "$pinentry_tqt" = "yes"; then
+ PINENTRY_DEFAULT=pinentry-tqt
+ else
+ AC_MSG_ERROR([[No pinentry enabled.]])
+ fi
fi
fi
fi
fi
fi
fi
fi
AC_SUBST(PINENTRY_DEFAULT)
#
# Print errors here so that they are visible all
# together and the user can acquire them all together.
#
die=no
if test "$have_gpg_error" = "no"; then
die=yes
AC_MSG_NOTICE([[
***
*** You need libgpg-error to build this program.
** This library is for example available at
*** ftp://ftp.gnupg.org/gcrypt/libgpg-error
*** (at least version $NEED_GPG_ERROR_VERSION is required.)
***]])
fi
if test "$have_libassuan" = "no"; then
die=yes
AC_MSG_NOTICE([[
***
*** You need libassuan to build this program.
*** This library is for example available at
*** ftp://ftp.gnupg.org/gcrypt/libassuan/
*** (at least version $NEED_LIBASSUAN_VERSION (API $NEED_LIBASSUAN_API) is required).
***]])
fi
if test "$die" = "yes"; then
AC_MSG_ERROR([[
***
*** Required libraries not found. Please consult the above messages
*** and install them before running configure again.
***]])
fi
#
# To avoid double inclusion of config.h which might happen at some
# places, we add the usual double inclusion protection at the top of
# config.h.
#
AH_TOP([
#ifndef GNUPG_CONFIG_H_INCLUDED
#define GNUPG_CONFIG_H_INCLUDED
])
#
# Stuff which goes at the bottom of config.h.
#
AH_BOTTOM([
#ifdef GPG_ERR_SOURCE_DEFAULT
# error GPG_ERR_SOURCE_DEFAULT already defined
#endif
#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_PINENTRY
#endif /*GNUPG_CONFIG_H_INCLUDED*/
])
AC_CONFIG_FILES([
m4/Makefile
secmem/Makefile
pinentry/Makefile
curses/Makefile
tty/Makefile
emacs/Makefile
gtk+-2/Makefile
gnome3/Makefile
qt/Makefile
+tqt/Makefile
w32/Makefile
fltk/Makefile
doc/Makefile
Makefile
])
AC_OUTPUT
AC_MSG_NOTICE([
Pinentry v${VERSION} has been configured as follows:
Revision: mym4_revision (mym4_revision_dec)
Platform: $host
Curses Pinentry ..: $pinentry_curses
TTY Pinentry .....: $pinentry_tty
Emacs Pinentry ...: $pinentry_emacs
GTK+-2 Pinentry ..: $pinentry_gtk_2
GNOME 3 Pinentry .: $pinentry_gnome_3
Qt Pinentry ......: $pinentry_qt $pinentry_qt_lib_version
+ TQt Pinentry .....: $pinentry_tqt
W32 Pinentry .....: $pinentry_w32
FLTK Pinentry ....: $pinentry_fltk
Fallback to Curses: $fallback_curses
Emacs integration : $inside_emacs
libsecret ........: $libsecret
Default Pinentry .: $PINENTRY_DEFAULT
])
diff --git a/tqt/Makefile.am b/tqt/Makefile.am
new file mode 100644
index 0000000..9171b0f
--- /dev/null
+++ b/tqt/Makefile.am
@@ -0,0 +1,58 @@
+# Makefile.am
+# Copyright (C) 2002 g10 Code GmbH, Klarälvdalens Datakonsult AB
+# Copyright (C) 2008, 2015 g10 Code GmbH
+#
+# This file is part of PINENTRY.
+#
+# PINENTRY 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.
+#
+# PINENTRY 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
+
+## Process this file with automake to produce Makefile.in
+
+bin_PROGRAMS = pinentry-tqt
+
+
+if FALLBACK_CURSES
+ncurses_include = $(NCURSES_INCLUDE)
+libcurses = ../pinentry/libpinentry-curses.a $(LIBCURSES) $(LIBICONV)
+else
+ncurses_include =
+libcurses =
+endif
+
+
+AM_CPPFLAGS = $(COMMON_CFLAGS) \
+ -I$(top_srcdir) -I$(top_srcdir)/secmem \
+ $(ncurses_include) -I$(top_srcdir)/pinentry
+AM_CXXFLAGS = $(PINENTRY_TQT_CFLAGS)
+pinentry_tqt_LDADD = \
+ ../pinentry/libpinentry.a $(top_builddir)/secmem/libsecmem.a \
+ $(COMMON_LIBS) $(PINENTRY_TQT_LIBS) $(libcurses) $(LIBCAP)
+
+BUILT_SOURCES = \
+ secqlineedit.moc pinentrydialog.moc
+
+CLEANFILES = \
+ secqlineedit.moc pinentrydialog.moc
+
+pinentry_tqt_SOURCES = pinentrydialog.h pinentrydialog.cpp \
+ main.cpp secqinternal_p.h secqinternal.cpp \
+ secqlineedit.h secqlineedit.cpp \
+ secqstring.h secqstring.cpp
+
+nodist_pinentry_tqt_SOURCES = \
+ secqlineedit.moc pinentrydialog.moc
+
+.h.moc:
+ $(TQT_MOC) `test -f '$<' || echo '$(srcdir)/'`$< -o $@
diff --git a/tqt/main.cpp b/tqt/main.cpp
new file mode 100644
index 0000000..3f7efb4
--- /dev/null
+++ b/tqt/main.cpp
@@ -0,0 +1,241 @@
+/* main.cpp - Secure KDE dialog for PIN entry.
+ Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ Copyright (C) 2003 g10 Code GmbH
+ Written by Steffen Hansen .
+ Modified by Marcus Brinkmann .
+
+ 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 */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+
+#include
+#include
+#include
+#include "secqstring.h"
+
+#include "pinentrydialog.h"
+
+#include "pinentry.h"
+
+#ifdef FALLBACK_CURSES
+#include
+#endif
+
+static TQString escape_accel( const TQString & s ) {
+
+ TQString result;
+ result.reserve( 2 * s.length());
+
+ bool afterUnderscore = false;
+
+ for ( unsigned int i = 0, end = s.length() ; i != end ; ++i ) {
+ const TQChar ch = s[i];
+ if ( ch == TQChar ( '_' ) )
+ {
+ if ( afterUnderscore ) // escaped _
+ {
+ result += TQChar ( '_' );
+ afterUnderscore = false;
+ }
+ else // accel
+ {
+ afterUnderscore = true;
+ }
+ }
+ else
+ {
+ if ( afterUnderscore || // accel
+ ch == TQChar ( '&' ) ) // escape & from being interpreted by TQt
+ result += TQChar ( '&' );
+ result += ch;
+ afterUnderscore = false;
+ }
+ }
+
+ if ( afterUnderscore )
+ // trailing single underscore: shouldn't happen, but deal with it robustly:
+ result += TQChar ( '_' );
+
+ return result;
+}
+
+
+/* Hack for creating a TQWidget with a "foreign" window ID */
+class ForeignWidget : public TQWidget
+{
+public:
+ ForeignWidget( WId wid ) : TQWidget( 0 )
+ {
+ TQWidget::destroy();
+ create( wid, false, false );
+ }
+
+ ~ForeignWidget()
+ {
+ destroy( false, false );
+ }
+};
+
+static int
+qt_cmd_handler (pinentry_t pe)
+{
+ TQWidget *parent = 0;
+
+ int want_pass = !!pe->pin;
+
+ if (want_pass)
+ {
+ /* FIXME: Add parent window ID to pinentry and GTK. */
+ if (pe->parent_wid)
+ parent = new ForeignWidget (pe->parent_wid);
+
+ PinEntryDialog pinentry (parent, NULL, true, !!pe->quality_bar);
+
+ pinentry.setPinentryInfo (pe);
+ pinentry.setPrompt (TQString::fromUtf8 (pe->prompt));
+ pinentry.setDescription (TQString::fromUtf8 (pe->description));
+ /* If we reuse the same dialog window. */
+#if 0
+ pinentry.setText (SecTQString::null);
+#endif
+
+ if (pe->ok)
+ pinentry.setOkText (escape_accel (TQString::fromUtf8 (pe->ok)));
+ else if (pe->default_ok)
+ pinentry.setOkText (escape_accel (TQString::fromUtf8 (pe->default_ok)));
+
+ if (pe->cancel)
+ pinentry.setCancelText (escape_accel (TQString::fromUtf8 (pe->cancel)));
+ else if (pe->default_cancel)
+ pinentry.setCancelText
+ (escape_accel (TQString::fromUtf8 (pe->default_cancel)));
+
+ if (pe->error)
+ pinentry.setError (TQString::fromUtf8 (pe->error));
+ if (pe->quality_bar)
+ pinentry.setQualityBar (TQString::fromUtf8 (pe->quality_bar));
+ if (pe->quality_bar_tt)
+ pinentry.setQualityBarTT (TQString::fromUtf8 (pe->quality_bar_tt));
+
+ bool ret = pinentry.exec ();
+ if (!ret)
+ return -1;
+
+ char *pin = (char *) pinentry.text().utf8();
+ if (!pin)
+ return -1;
+
+ int len = strlen (pin);
+ if (len >= 0)
+ {
+ pinentry_setbufferlen (pe, len + 1);
+ if (pe->pin)
+ {
+ strcpy (pe->pin, pin);
+ ::secmem_free (pin);
+ return len;
+ }
+ }
+ ::secmem_free (pin);
+ return -1;
+ }
+ else
+ {
+ TQString desc = TQString::fromUtf8 (pe->description? pe->description : "");
+ TQString ok = escape_accel
+ (TQString::fromUtf8 (pe->ok ? pe->ok :
+ pe->default_ok ? pe->default_ok : "_OK"));
+ TQString can = escape_accel
+ (TQString::fromUtf8 (pe->cancel ? pe->cancel :
+ pe->default_cancel? pe->default_cancel: "_Cancel"));
+ bool ret;
+
+ ret = TQMessageBox::information (parent, "", desc, ok, can );
+
+ return !ret;
+ }
+}
+
+pinentry_cmd_handler_t pinentry_cmd_handler = qt_cmd_handler;
+
+int
+main (int argc, char *argv[])
+{
+ pinentry_init ("pinentry-tqt");
+
+#ifdef FALLBACK_CURSES
+ if (!pinentry_have_display (argc, argv))
+ pinentry_cmd_handler = curses_cmd_handler;
+ else
+#endif
+ {
+ /* TQt does only understand -display but not --display; thus we
+ are fixing that here. The code is pretty simply and may get
+ confused if an argument is called "--display". */
+ char **new_argv, *p;
+ size_t n;
+ int i, done;
+
+ for (n=0,i=0; i < argc; i++)
+ n += strlen (argv[i])+1;
+ n++;
+ new_argv = (char**)calloc (argc+1, sizeof *new_argv);
+ if (new_argv)
+ *new_argv = (char*)malloc (n);
+ if (!new_argv || !*new_argv)
+ {
+ fprintf (stderr, "pinentry-tqt: can't fixup argument list: %s\n",
+ strerror (errno));
+ exit (EXIT_FAILURE);
+
+ }
+ for (done=0,p=*new_argv,i=0; i < argc; i++)
+ if (!done && !strcmp (argv[i], "--display"))
+ {
+ new_argv[i] = (char*)"-display";
+ done = 1;
+ }
+ else
+ {
+ new_argv[i] = strcpy (p, argv[i]);
+ p += strlen (argv[i]) + 1;
+ }
+
+ /* We use a modal dialog window, so we don't need the application
+ window anymore. */
+ i = argc;
+ new TQApplication (i, new_argv);
+ }
+
+
+ /* Consumes all arguments. */
+ pinentry_parse_opts (argc, argv);
+// if (pinentry_parse_opts (argc, argv))
+// {
+// printf ("pinentry-tqt (pinentry) " VERSION "\n");
+// exit (EXIT_SUCCESS);
+// }
+
+ if (pinentry_loop ())
+ return 1;
+
+ return 0;
+}
diff --git a/tqt/pinentrydialog.cpp b/tqt/pinentrydialog.cpp
new file mode 100644
index 0000000..2eae54d
--- /dev/null
+++ b/tqt/pinentrydialog.cpp
@@ -0,0 +1,234 @@
+/* pinentrydialog.cpp - A secure KDE dialog for PIN entry.
+ Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ Copyright (C) 2007 g10 Code GmbH
+ Written by Steffen Hansen .
+
+ 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 */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "secqlineedit.h"
+
+#include "pinentrydialog.h"
+#include "pinentry.h"
+
+PinEntryDialog::PinEntryDialog( TQWidget* parent, const char* name,
+ bool modal, bool enable_quality_bar )
+ : TQDialog( parent, name, modal, TQt::WStyle_StaysOnTop ), _grabbed( false )
+{
+ TQBoxLayout* top = new TQVBoxLayout( this, 6 );
+ TQBoxLayout* upperLayout = new TQHBoxLayout( top );
+
+ _icon = new TQLabel( this );
+ _icon->setPixmap( TQMessageBox::standardIcon( TQMessageBox::Information ) );
+ upperLayout->addWidget( _icon );
+
+ TQBoxLayout* labelLayout = new TQVBoxLayout( upperLayout );
+
+ _error = new TQLabel( this );
+ labelLayout->addWidget( _error );
+
+ _desc = new TQLabel( this );
+ labelLayout->addWidget( _desc );
+
+ TQGridLayout* grid = new TQGridLayout( labelLayout );
+
+ _prompt = new TQLabel( this );
+ _prompt->setAlignment( TQt::AlignRight | TQt::AlignVCenter );
+ grid->addWidget( _prompt, 0, 0 );
+ _edit = new SecTQLineEdit( this );
+ _edit->setMaxLength( 256 );
+ _edit->setEchoMode( SecTQLineEdit::Password );
+ grid->addWidget( _edit, 0, 1 );
+
+ if (enable_quality_bar)
+ {
+ _quality_bar_label = new TQLabel( this );
+ _quality_bar_label->setAlignment( TQt::AlignRight | TQt::AlignVCenter );
+ grid->addWidget ( _quality_bar_label, 1, 0 );
+ _quality_bar = new TQProgressBar( this );
+ _quality_bar->setCenterIndicator( true );
+ grid->addWidget( _quality_bar, 1, 1 );
+ _have_quality_bar = true;
+ }
+ else
+ _have_quality_bar = false;
+
+ TQBoxLayout* l = new TQHBoxLayout( top );
+
+ _ok = new TQPushButton( tr("OK"), this );
+ _cancel = new TQPushButton( tr("Cancel"), this );
+
+ l->addWidget( _ok );
+ l->addStretch();
+ l->addWidget( _cancel );
+
+ _ok->setDefault(true);
+
+ connect( _ok, SIGNAL( clicked() ),
+ this, SIGNAL( accepted() ) );
+ connect( _cancel, SIGNAL( clicked() ),
+ this, SIGNAL( rejected() ) );
+ connect( _edit, SIGNAL( textModified(const SecTQString&) ),
+ this, SLOT( updateQuality(const SecTQString&) ) );
+ connect (this, SIGNAL (accepted ()),
+ this, SLOT (accept ()));
+ connect (this, SIGNAL (rejected ()),
+ this, SLOT (reject ()));
+ _edit->setFocus();
+}
+
+void PinEntryDialog::paintEvent( TQPaintEvent* ev )
+{
+ // Grab keyboard when widget is mapped to screen
+ // It might be a little weird to do it here, but it works!
+ if( !_grabbed ) {
+ _edit->grabKeyboard();
+ _grabbed = true;
+ }
+ TQDialog::paintEvent( ev );
+}
+
+void PinEntryDialog::hideEvent( TQHideEvent* ev )
+{
+ _edit->releaseKeyboard();
+ _grabbed = false;
+ TQDialog::hideEvent( ev );
+}
+
+void PinEntryDialog::keyPressEvent( TQKeyEvent* e )
+{
+ if ( e->state() == 0 && e->key() == Key_Escape ) {
+ emit rejected();
+ return;
+ }
+ TQDialog::keyPressEvent( e );
+}
+
+
+void PinEntryDialog::updateQuality( const SecTQString & txt )
+{
+ char *pin;
+ int length;
+ int percent;
+ TQPalette pal;
+
+ if (!_have_quality_bar || !_pinentry_info)
+ return;
+ pin = (char*)txt.utf8();
+ length = strlen (pin);
+ percent = length? pinentry_inq_quality (_pinentry_info, pin, length) : 0;
+ ::secmem_free (pin);
+ if (!length)
+ {
+ _quality_bar->reset ();
+ }
+ else
+ {
+ pal = _quality_bar->palette ();
+ if (percent < 0)
+ {
+ pal.setColor (TQColorGroup::Highlight, TQColor("red"));
+ percent = -percent;
+ }
+ else
+ {
+ pal.setColor (TQColorGroup::Highlight, TQColor("green"));
+ }
+ _quality_bar->setPalette (pal);
+ _quality_bar->setProgress (percent);
+ }
+}
+
+
+void PinEntryDialog::setDescription( const TQString& txt )
+{
+ _desc->setText( txt );
+ _icon->setPixmap( TQMessageBox::standardIcon( TQMessageBox::Information ) );
+ setError( TQString::null );
+}
+
+TQString PinEntryDialog::description() const
+{
+ return _desc->text();
+}
+
+void PinEntryDialog::setError( const TQString& txt )
+{
+ if ( !txt.isNull() )
+ _icon->setPixmap( TQMessageBox::standardIcon( TQMessageBox::Critical ) );
+ _error->setText( txt );
+}
+
+TQString PinEntryDialog::error() const
+{
+ return _error->text();
+}
+
+void PinEntryDialog::setText( const SecTQString& txt )
+{
+ _edit->setText( txt );
+}
+
+SecTQString PinEntryDialog::text() const
+{
+ return _edit->text();
+}
+
+void PinEntryDialog::setPrompt( const TQString& txt )
+{
+ _prompt->setText( txt );
+}
+
+TQString PinEntryDialog::prompt() const
+{
+ return _prompt->text();
+}
+
+void PinEntryDialog::setOkText( const TQString& txt )
+{
+ _ok->setText( txt );
+}
+
+void PinEntryDialog::setCancelText( const TQString& txt )
+{
+ _cancel->setText( txt );
+}
+
+void PinEntryDialog::setQualityBar( const TQString& txt )
+{
+ if (_have_quality_bar)
+ _quality_bar_label->setText( txt );
+}
+
+void PinEntryDialog::setQualityBarTT( const TQString& txt )
+{
+ if (_have_quality_bar)
+ TQToolTip::add ( _quality_bar, txt );
+}
+
+void PinEntryDialog::setPinentryInfo (pinentry_t peinfo )
+{
+ _pinentry_info = peinfo;
+}
+
+#include "pinentrydialog.moc"
diff --git a/tqt/pinentrydialog.h b/tqt/pinentrydialog.h
new file mode 100644
index 0000000..4d69a28
--- /dev/null
+++ b/tqt/pinentrydialog.h
@@ -0,0 +1,92 @@
+/* pinentrydialog.h - A secure KDE dialog for PIN entry.
+ Copyright (C) 2002 Klarälvdalens Datakonsult AB
+ Written by Steffen Hansen .
+
+ 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 */
+
+#ifndef __PINENTRYDIALOG_H__
+#define __PINENTRYDIALOG_H__
+
+#include
+#include "pinentry.h"
+
+class TQLabel;
+class TQPushButton;
+class TQProgressBar;
+class SecTQLineEdit;
+class SecTQString;
+
+class PinEntryDialog : public TQDialog {
+ TQ_OBJECT
+
+ TQ_PROPERTY( TQString description READ description WRITE setDescription )
+ TQ_PROPERTY( TQString error READ error WRITE setError )
+ // TQ_PROPERTY( SecTQString text READ text WRITE setText )
+ TQ_PROPERTY( TQString prompt READ prompt WRITE setPrompt )
+public:
+ friend class PinEntryController; // TODO: remove when assuan lets me use TQt eventloop.
+ PinEntryDialog( TQWidget* parent = 0, const char* name = 0,
+ bool modal = false, bool enable_quality_bar = false );
+
+ void setDescription( const TQString& );
+ TQString description() const;
+
+ void setError( const TQString& );
+ TQString error() const;
+
+ void setText( const SecTQString& );
+ SecTQString text() const;
+
+ void setPrompt( const TQString& );
+ TQString prompt() const;
+
+ void setOkText( const TQString& );
+ void setCancelText( const TQString& );
+
+ void setQualityBar( const TQString& );
+ void setQualityBarTT( const TQString& );
+
+ void setPinentryInfo (pinentry_t);
+
+public slots:
+ void updateQuality(const SecTQString &);
+
+signals:
+ void accepted();
+ void rejected();
+
+protected:
+ virtual void keyPressEvent( TQKeyEvent *e );
+ virtual void hideEvent( TQHideEvent* );
+ virtual void paintEvent( TQPaintEvent* );
+
+private:
+ TQLabel* _icon;
+ TQLabel* _desc;
+ TQLabel* _error;
+ TQLabel* _prompt;
+ TQLabel* _quality_bar_label;
+ TQProgressBar* _quality_bar;
+ SecTQLineEdit* _edit;
+ TQPushButton* _ok;
+ TQPushButton* _cancel;
+ bool _grabbed;
+ bool _have_quality_bar;
+ pinentry_t _pinentry_info;
+};
+
+
+#endif // __PINENTRYDIALOG_H__
diff --git a/tqt/secqinternal.cpp b/tqt/secqinternal.cpp
new file mode 100644
index 0000000..a1113a8
--- /dev/null
+++ b/tqt/secqinternal.cpp
@@ -0,0 +1,635 @@
+/****************************************************************************
+** $Id$
+**
+** Implementation of some internal classes
+**
+** Created : 010427
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition
+** licenses may use this file in accordance with the TQt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about TQt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for TQPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "secqinternal_p.h"
+#include "ntqwidget.h"
+#include "ntqpixmap.h"
+#include "ntqpainter.h"
+#include "ntqcleanuphandler.h"
+
+static TQPixmap* qdb_shared_pixmap = 0;
+static TQPixmap *qdb_force_pixmap = 0;
+static SecTQSharedDoubleBuffer* qdb_owner = 0;
+
+static TQCleanupHandler qdb_pixmap_cleanup;
+
+#ifdef Q_WS_MACX
+bool SecTQSharedDoubleBuffer::dblbufr = FALSE;
+#else
+bool SecTQSharedDoubleBuffer::dblbufr = TRUE;
+#endif
+
+
+/*
+ hardLimitWidth/Height: if >= 0, the maximum number of pixels that
+ get double buffered.
+
+ sharedLimitWidth/Height: if >= 0, the maximum number of pixels the
+ shared double buffer can keep.
+
+ For x with sharedLimitSize < x <= hardLimitSize, temporary buffers
+ are constructed.
+ */
+static const int hardLimitWidth = -1;
+static const int hardLimitHeight = -1;
+#if defined( Q_WS_QWS ) || defined( Q_WS_MAC9 )
+// Small in TQt/Embedded / Mac9 - 5K on 32bpp
+static const int sharedLimitWidth = 64;
+static const int sharedLimitHeight = 20;
+#else
+// 240K on 32bpp
+static const int sharedLimitWidth = 640;
+static const int sharedLimitHeight = 100;
+#endif
+
+// *******************************************************************
+// SecTQSharedDoubleBufferCleaner declaration and implementation
+// *******************************************************************
+
+/* \internal
+ This class is responsible for cleaning up the pixmaps created by the
+ SecTQSharedDoubleBuffer class. When SecTQSharedDoubleBuffer creates a
+ pixmap larger than the shared limits, this class deletes it after a
+ specified amount of time.
+
+ When the large pixmap is created/used, you must call start(). If the
+ large pixmap is ever deleted, you must call stop(). The start()
+ method always restarts the timer, so if the large pixmap is
+ constantly in use, the timer will never fire, and the pixmap will
+ not be constantly created and destroyed.
+*/
+
+static const int shared_double_buffer_cleanup_timeout = 30000; // 30 seconds
+
+// declaration
+
+class SecTQSharedDoubleBufferCleaner : public TQObject
+{
+public:
+ SecTQSharedDoubleBufferCleaner( void );
+
+ void start( void );
+ void stop( void );
+
+ void doCleanup( void );
+
+ bool event( TQEvent *e );
+
+private:
+ int timer_id;
+};
+
+// implementation
+
+/* \internal
+ Creates a SecTQSharedDoubleBufferCleaner object. The timer is not
+ started when creating the object.
+*/
+SecTQSharedDoubleBufferCleaner::SecTQSharedDoubleBufferCleaner( void )
+ : TQObject( 0, "internal shared double buffer cleanup object" ),
+ timer_id( -1 )
+{
+}
+
+/* \internal
+ Starts the cleanup timer. Any previously running timer is stopped.
+*/
+void SecTQSharedDoubleBufferCleaner::start( void )
+{
+ stop();
+ timer_id = startTimer( shared_double_buffer_cleanup_timeout );
+}
+
+/* \internal
+ Stops the cleanup timer, if it is running.
+*/
+void SecTQSharedDoubleBufferCleaner::stop( void )
+{
+ if ( timer_id != -1 )
+ killTimer( timer_id );
+ timer_id = -1;
+}
+
+/* \internal
+ */
+void SecTQSharedDoubleBufferCleaner::doCleanup( void )
+{
+ qdb_pixmap_cleanup.remove( &qdb_force_pixmap );
+ delete qdb_force_pixmap;
+ qdb_force_pixmap = 0;
+}
+
+/* \internal
+ Event handler reimplementation. Calls doCleanup() when the timer
+ fires.
+*/
+bool SecTQSharedDoubleBufferCleaner::event( TQEvent *e )
+{
+ if ( e->type() != TQEvent::Timer )
+ return FALSE;
+
+ TQTimerEvent *event = (TQTimerEvent *) e;
+ if ( event->timerId() == timer_id ) {
+ doCleanup();
+ stop();
+ }
+#ifdef QT_CHECK_STATE
+ else {
+ tqWarning( "SecTQSharedDoubleBufferCleaner::event: invalid timer event received." );
+ return FALSE;
+ }
+#endif // QT_CHECK_STATE
+
+ return TRUE;
+}
+
+// static instance
+static SecTQSharedDoubleBufferCleaner *static_cleaner = 0;
+TQSingleCleanupHandler cleanup_static_cleaner;
+
+inline static SecTQSharedDoubleBufferCleaner *staticCleaner()
+{
+ if ( ! static_cleaner ) {
+ static_cleaner = new SecTQSharedDoubleBufferCleaner();
+ cleanup_static_cleaner.set( &static_cleaner );
+ }
+ return static_cleaner;
+}
+
+
+// *******************************************************************
+// SecTQSharedDoubleBuffer implementation
+// *******************************************************************
+
+/* \internal
+ \enum DoubleBufferFlags
+
+ \value InitBG initialize the background of the double buffer.
+
+ \value Force disable shared buffer size limits.
+
+ \value Default InitBG and Force are used by default.
+*/
+
+/* \internal
+ \enum DoubleBufferState
+
+ \value Active indicates that the buffer may be used.
+
+ \value BufferActive indicates that painting with painter() will be
+ double buffered.
+
+ \value ExternalPainter indicates that painter() will return a
+ painter that was not created by SecTQSharedDoubleBuffer.
+*/
+
+/* \internal
+ \class SecTQSharedDoubleBuffer
+
+ This class provides a single, reusable double buffer. This class
+ is used internally by TQt widgets that need double buffering, which
+ prevents each individual widget form creating a double buffering
+ pixmap.
+
+ Using a single pixmap double buffer and sharing it across all
+ widgets is nicer on window system resources.
+*/
+
+/* \internal
+ Creates a SecTQSharedDoubleBuffer with flags \f.
+
+ \sa DoubleBufferFlags
+*/
+SecTQSharedDoubleBuffer::SecTQSharedDoubleBuffer( DBFlags f )
+ : wid( 0 ), rx( 0 ), ry( 0 ), rw( 0 ), rh( 0 ), flags( f ), state( 0 ),
+ p( 0 ), external_p( 0 ), pix( 0 )
+{
+}
+
+/* \internal
+ Creates a SecTQSharedDoubleBuffer with flags \f. The \a widget, \a x,
+ \a y, \a w and \a h arguments are passed to begin().
+
+ \sa DoubleBufferFlags begin()
+*/
+SecTQSharedDoubleBuffer::SecTQSharedDoubleBuffer( TQWidget* widget,
+ int x, int y, int w, int h,
+ DBFlags f )
+ : wid( 0 ), rx( 0 ), ry( 0 ), rw( 0 ), rh( 0 ), flags( f ), state( 0 ),
+ p( 0 ), external_p( 0 ), pix( 0 )
+{
+ begin( widget, x, y, w, h );
+}
+
+/* \internal
+ Creates a SecTQSharedDoubleBuffer with flags \f. The \a painter, \a x,
+ \a y, \a w and \a h arguments are passed to begin().
+
+ \sa DoubleBufferFlags begin()
+*/
+SecTQSharedDoubleBuffer::SecTQSharedDoubleBuffer( TQPainter* painter,
+ int x, int y, int w, int h,
+ DBFlags f)
+ : wid( 0 ), rx( 0 ), ry( 0 ), rw( 0 ), rh( 0 ), flags( f ), state( 0 ),
+ p( 0 ), external_p( 0 ), pix( 0 )
+{
+ begin( painter, x, y, w, h );
+}
+
+/* \internal
+ Creates a SecTQSharedDoubleBuffer with flags \f. The \a widget and
+ \a r arguments are passed to begin().
+
+ \sa DoubleBufferFlags begin()
+*/
+SecTQSharedDoubleBuffer::SecTQSharedDoubleBuffer( TQWidget *widget, const TQRect &r, DBFlags f )
+ : wid( 0 ), rx( 0 ), ry( 0 ), rw( 0 ), rh( 0 ), flags( f ), state( 0 ),
+ p( 0 ), external_p( 0 ), pix( 0 )
+{
+ begin( widget, r );
+}
+
+/* \internal
+ Creates a SecTQSharedDoubleBuffer with flags \f. The \a painter and
+ \a r arguments are passed to begin().
+
+ \sa DoubleBufferFlags begin()
+*/
+SecTQSharedDoubleBuffer::SecTQSharedDoubleBuffer( TQPainter *painter, const TQRect &r, DBFlags f )
+ : wid( 0 ), rx( 0 ), ry( 0 ), rw( 0 ), rh( 0 ), flags( f ), state( 0 ),
+ p( 0 ), external_p( 0 ), pix( 0 )
+{
+ begin( painter, r );
+}
+
+/* \internal
+ Destructs the SecTQSharedDoubleBuffer and calls end() if the buffer is
+ active.
+
+ \sa isActive() end()
+*/
+SecTQSharedDoubleBuffer::~SecTQSharedDoubleBuffer()
+{
+ if ( isActive() )
+ end();
+}
+
+/* \internal
+ Starts double buffered painting in the area specified by \a x,
+ \a y, \a w and \a h on \a painter. Painting should be done using the
+ TQPainter returned by SecTQSharedDoubleBuffer::painter().
+
+ The double buffered area will be updated when calling end().
+
+ \sa painter() isActive() end()
+*/
+bool SecTQSharedDoubleBuffer::begin( TQPainter* painter, int x, int y, int w, int h )
+{
+ if ( isActive() ) {
+#if defined(QT_CHECK_STATE)
+ tqWarning( "SecTQSharedDoubleBuffer::begin: Buffer is already active."
+ "\n\tYou must end() the buffer before a second begin()" );
+#endif // QT_CHECK_STATE
+ return FALSE;
+ }
+
+ external_p = painter;
+
+ if ( painter->device()->devType() == TQInternal::Widget )
+ return begin( (TQWidget *) painter->device(), x, y, w, h );
+
+ state = Active;
+
+ rx = x;
+ ry = y;
+ rw = w;
+ rh = h;
+
+ if ( ( pix = getPixmap() ) ) {
+#ifdef Q_WS_X11
+ if ( painter->device()->x11Screen() != pix->x11Screen() )
+ pix->x11SetScreen( painter->device()->x11Screen() );
+ TQPixmap::x11SetDefaultScreen( pix->x11Screen() );
+#endif // Q_WS_X11
+
+ state |= BufferActive;
+ p = new TQPainter( pix );
+ if ( p->isActive() ) {
+ p->setPen( external_p->pen() );
+ p->setBackgroundColor( external_p->backgroundColor() );
+ p->setFont( external_p->font() );
+ }
+ } else {
+ state |= ExternalPainter;
+ p = external_p;
+ }
+
+ return TRUE;
+}
+
+/* \internal
+
+
+ Starts double buffered painting in the area specified by \a x,
+ \a y, \a w and \a h on \a widget. Painting should be done using the
+ TQPainter returned by SecTQSharedDoubleBuffer::painter().
+
+ The double buffered area will be updated when calling end().
+
+ \sa painter() isActive() end()
+*/
+bool SecTQSharedDoubleBuffer::begin( TQWidget* widget, int x, int y, int w, int h )
+{
+ if ( isActive() ) {
+#if defined(QT_CHECK_STATE)
+ tqWarning( "SecTQSharedDoubleBuffer::begin: Buffer is already active."
+ "\n\tYou must end() the buffer before a second begin()" );
+#endif // QT_CHECK_STATE
+ return FALSE;
+ }
+
+ state = Active;
+
+ wid = widget;
+ rx = x;
+ ry = y;
+ rw = w <= 0 ? wid->width() : w;
+ rh = h <= 0 ? wid->height() : h;
+
+ if ( ( pix = getPixmap() ) ) {
+#ifdef Q_WS_X11
+ if ( wid->x11Screen() != pix->x11Screen() )
+ pix->x11SetScreen( wid->x11Screen() );
+ TQPixmap::x11SetDefaultScreen( pix->x11Screen() );
+#endif // Q_WS_X11
+
+ state |= BufferActive;
+ if ( flags & InitBG ) {
+ pix->fill( wid, rx, ry );
+ }
+ p = new TQPainter( pix, wid );
+ // newly created painters should be translated to the origin
+ // of the widget, so that paint methods can draw onto the double
+ // buffered painter in widget coordinates.
+ p->setBrushOrigin( -rx, -ry );
+ p->translate( -rx, -ry );
+ } else {
+ if ( external_p ) {
+ state |= ExternalPainter;
+ p = external_p;
+ } else {
+ p = new TQPainter( wid );
+ }
+
+ if ( flags & InitBG ) {
+ wid->erase( rx, ry, rw, rh );
+ }
+ }
+ return TRUE;
+}
+
+/* \internal
+ Ends double buffered painting. The contents of the shared double
+ buffer pixmap are drawn onto the destination by calling flush(),
+ and ownership of the shared double buffer pixmap is released.
+
+ \sa begin() flush()
+*/
+bool SecTQSharedDoubleBuffer::end()
+{
+ if ( ! isActive() ) {
+#if defined(QT_CHECK_STATE)
+ tqWarning( "SecTQSharedDoubleBuffer::end: Buffer is not active."
+ "\n\tYou must call begin() before calling end()." );
+#endif // QT_CHECK_STATE
+ return FALSE;
+ }
+
+ if ( ! ( state & ExternalPainter ) ) {
+ p->end();
+ delete p;
+ }
+
+ flush();
+
+ if ( pix ) {
+ releasePixmap();
+ }
+
+ wid = 0;
+ rx = ry = rw = rh = 0;
+ // do not reset flags!
+ state = 0;
+
+ p = external_p = 0;
+ pix = 0;
+
+ return TRUE;
+}
+
+/* \internal
+ Paints the contents of the shared double buffer pixmap onto the
+ destination. The destination is determined from the arguments
+ based to begin().
+
+ Note: You should not need to call this function, since it is called
+ from end().
+
+ \sa begin() end()
+*/
+void SecTQSharedDoubleBuffer::flush()
+{
+ if ( ! isActive() || ! ( state & BufferActive ) )
+ return;
+
+ if ( external_p )
+ external_p->drawPixmap( rx, ry, *pix, 0, 0, rw, rh );
+ else if ( wid && wid->isVisible() )
+ bitBlt( wid, rx, ry, pix, 0, 0, rw, rh );
+}
+
+/* \internal
+ Atquire ownership of the shared double buffer pixmap, subject to the
+ following conditions:
+
+ \list 1
+ \i double buffering is enabled globally.
+ \i the shared double buffer pixmap is not in use.
+ \i the size specified in begin() is valid, and within limits.
+ \endlist
+
+ If all of these conditions are met, then this SecTQSharedDoubleBuffer
+ object becomes the owner of the shared double buffer pixmap. The
+ shared double buffer pixmap is resize if necessary, and this
+ function returns a pointer to the pixmap. Ownership must later be
+ relinquished by calling releasePixmap().
+
+ If none of the above conditions are met, this function returns
+ zero.
+
+ \sa releasePixmap()
+*/
+TQPixmap *SecTQSharedDoubleBuffer::getPixmap()
+{
+ if ( isDisabled() ) {
+ // double buffering disabled globally
+ return 0;
+ }
+
+ if ( qdb_owner ) {
+ // shared pixmap already in use
+ return 0;
+ }
+
+ if ( rw <= 0 || rh <= 0 ||
+ ( hardLimitWidth > 0 && rw >= hardLimitWidth ) ||
+ ( hardLimitHeight > 0 && rh >= hardLimitHeight ) ) {
+ // invalid size, or hard limit reached
+ return 0;
+ }
+
+ if ( rw >= sharedLimitWidth || rh >= sharedLimitHeight ) {
+ if ( flags & Force ) {
+ rw = TQMIN(rw, 8000);
+ rh = TQMIN(rh, 8000);
+ // need to create a big pixmap and start the cleaner
+ if ( ! qdb_force_pixmap ) {
+ qdb_force_pixmap = new TQPixmap( rw, rh );
+ qdb_pixmap_cleanup.add( &qdb_force_pixmap );
+ } else if ( qdb_force_pixmap->width () < rw ||
+ qdb_force_pixmap->height() < rh ) {
+ qdb_force_pixmap->resize( rw, rh );
+ }
+ qdb_owner = this;
+ staticCleaner()->start();
+ return qdb_force_pixmap;
+ }
+
+ // size is outside shared limit
+ return 0;
+ }
+
+ if ( ! qdb_shared_pixmap ) {
+ qdb_shared_pixmap = new TQPixmap( rw, rh );
+ qdb_pixmap_cleanup.add( &qdb_shared_pixmap );
+ } else if ( qdb_shared_pixmap->width() < rw ||
+ qdb_shared_pixmap->height() < rh ) {
+ qdb_shared_pixmap->resize( rw, rh );
+ }
+ qdb_owner = this;
+ return qdb_shared_pixmap;
+}
+
+/* \internal
+ Releases ownership of the shared double buffer pixmap.
+
+ \sa getPixmap()
+*/
+void SecTQSharedDoubleBuffer::releasePixmap()
+{
+ if ( qdb_owner != this ) {
+ // sanity check
+
+#ifdef QT_CHECK_STATE
+ tqWarning( "SecTQSharedDoubleBuffer::releasePixmap: internal error."
+ "\n\t%p does not own shared pixmap, %p does.",
+ (void*)this, (void*)qdb_owner );
+#endif // QT_CHECK_STATE
+
+ return;
+ }
+
+ qdb_owner = 0;
+}
+
+/* \internal
+ \fn bool SecTQSharedDoubleBuffer::isDisabled()
+
+ Returns TRUE is double buffering is disabled globally, FALSE otherwise.
+*/
+
+/* \internal
+ \fn void SecTQSharedDoubleBuffer::setDisabled( bool off )
+
+ Disables global double buffering \a off is TRUE, otherwise global
+ double buffering is enabled.
+*/
+
+/* \internal
+ Deletes the shared double buffer pixmap. You should not need to
+ call this function, since it is called from the TQApplication
+ destructor.
+*/
+void SecTQSharedDoubleBuffer::cleanup()
+{
+ qdb_pixmap_cleanup.remove( &qdb_shared_pixmap );
+ qdb_pixmap_cleanup.remove( &qdb_force_pixmap );
+ delete qdb_shared_pixmap;
+ delete qdb_force_pixmap;
+ qdb_shared_pixmap = 0;
+ qdb_force_pixmap = 0;
+ qdb_owner = 0;
+}
+
+/* \internal
+ \fn bool SecTQSharedDoubleBuffer::begin( TQWidget *widget, const TQRect &r )
+ \overload
+*/
+
+/* \internal
+ \fn bool SecTQSharedDoubleBuffer::begin( TQPainter *painter, const TQRect &r )
+ \overload
+*/
+
+/* \internal
+ \fn TQPainter *SecTQSharedDoubleBuffer::painter() const
+
+ Returns the active painter on the double buffered area,
+ or zero if double buffered painting is not active.
+*/
+
+/* \internal
+ \fn bool SecTQSharedDoubleBuffer::isActive() const
+
+ Returns TRUE if double buffered painting is active, FALSE otherwise.
+*/
+
+/* \internal
+ \fn bool SecTQSharedDoubleBuffer::isBuffered() const
+
+ Returns TRUE if painting is double buffered, FALSE otherwise.
+*/
diff --git a/tqt/secqinternal_p.h b/tqt/secqinternal_p.h
new file mode 100644
index 0000000..35d2b0d
--- /dev/null
+++ b/tqt/secqinternal_p.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+** $Id$
+**
+** Definition of some shared interal classes
+**
+** Created : 010427
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition
+** licenses may use this file in accordance with the TQt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about TQt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for TQPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef SECTQINTERNAL_P_H
+#define SECTQINTERNAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+#ifndef QT_H
+#include "ntqnamespace.h"
+#include "ntqrect.h"
+#include "ntqptrlist.h"
+#include "ntqcstring.h"
+#include "ntqiodevice.h"
+#endif // QT_H
+
+class TQWidget;
+class TQPainter;
+class TQPixmap;
+
+class Q_EXPORT SecTQSharedDoubleBuffer
+{
+public:
+ enum DoubleBufferFlags {
+ NoFlags = 0x00,
+ InitBG = 0x01,
+ Force = 0x02,
+ Default = InitBG | Force
+ };
+ typedef uint DBFlags;
+
+ SecTQSharedDoubleBuffer( DBFlags f = Default );
+ SecTQSharedDoubleBuffer( TQWidget* widget,
+ int x = 0, int y = 0, int w = -1, int h = -1,
+ DBFlags f = Default );
+ SecTQSharedDoubleBuffer( TQPainter* painter,
+ int x = 0, int y = 0, int w = -1, int h = -1,
+ DBFlags f = Default );
+ SecTQSharedDoubleBuffer( TQWidget *widget, const TQRect &r, DBFlags f = Default );
+ SecTQSharedDoubleBuffer( TQPainter *painter, const TQRect &r, DBFlags f = Default );
+ ~SecTQSharedDoubleBuffer();
+
+ bool begin( TQWidget* widget, int x = 0, int y = 0, int w = -1, int h = -1 );
+ bool begin( TQPainter* painter, int x = 0, int y = 0, int w = -1, int h = -1);
+ bool begin( TQWidget* widget, const TQRect &r );
+ bool begin( TQPainter* painter, const TQRect &r );
+ bool end();
+
+ TQPainter* painter() const;
+
+ bool isActive() const;
+ bool isBuffered() const;
+ void flush();
+
+ static bool isDisabled() { return !dblbufr; }
+ static void setDisabled( bool off ) { dblbufr = !off; }
+
+ static void cleanup();
+
+private:
+ enum DoubleBufferState {
+ Active = 0x0100,
+ BufferActive = 0x0200,
+ ExternalPainter = 0x0400
+ };
+ typedef uint DBState;
+
+ TQPixmap *getPixmap();
+ void releasePixmap();
+
+ TQWidget *wid;
+ int rx, ry, rw, rh;
+ DBFlags flags;
+ DBState state;
+
+ TQPainter *p, *external_p;
+ TQPixmap *pix;
+
+ static bool dblbufr;
+};
+
+inline bool SecTQSharedDoubleBuffer::begin( TQWidget* widget, const TQRect &r )
+{ return begin( widget, r.x(), r.y(), r.width(), r.height() ); }
+
+inline bool SecTQSharedDoubleBuffer::begin( TQPainter *painter, const TQRect &r )
+{ return begin( painter, r.x(), r.y(), r.width(), r.height() ); }
+
+inline TQPainter* SecTQSharedDoubleBuffer::painter() const
+{ return p; }
+
+inline bool SecTQSharedDoubleBuffer::isActive() const
+{ return ( state & Active ); }
+
+inline bool SecTQSharedDoubleBuffer::isBuffered() const
+{ return ( state & BufferActive ); }
+
+#endif // SECTQINTERNAL_P_H
diff --git a/tqt/secqlineedit.cpp b/tqt/secqlineedit.cpp
new file mode 100644
index 0000000..ecf6010
--- /dev/null
+++ b/tqt/secqlineedit.cpp
@@ -0,0 +1,1955 @@
+/* secqlineedit.cpp - Secure version of TQLineEdit.
+ Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+ Copyright (C) 2003 g10 Code GmbH
+
+ The license of the original qlineedit.cpp file from which this file
+ is derived can be found below. Modified by Marcus Brinkmann
+ . All modifications are licensed as follows, so
+ that the intersection of the two licenses is then the GNU General
+ Public License version 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA */
+
+
+/* Undo/Redo is disabled, because it uses unsecure memory for the
+ history buffer. */
+#define SECURE_NO_UNDO 1
+
+
+/**********************************************************************
+** $Id$
+**
+** Implementation of SecTQLineEdit widget class
+**
+** Created : 941011
+**
+** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition
+** licenses may use this file in accordance with the TQt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about TQt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for TQPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "secqlineedit.h"
+#include "ntqpainter.h"
+#include "ntqdrawutil.h"
+#include "ntqfontmetrics.h"
+#include "ntqpixmap.h"
+#include "ntqclipboard.h"
+#include "ntqapplication.h"
+#include "ntqtimer.h"
+#include "ntqpopupmenu.h"
+#include "ntqstringlist.h"
+#include "ntqguardedptr.h"
+#include "ntqstyle.h"
+#include "ntqwhatsthis.h"
+#include "secqinternal_p.h"
+#include "private/qtextlayout_p.h"
+#include "ntqvaluevector.h"
+#if defined(QT_ACCESSIBILITY_SUPPORT)
+#include "ntqaccessible.h"
+#endif
+
+#ifndef QT_NO_ACCEL
+#include "ntqkeysequence.h"
+#define ACCEL_KEY(k) "\t" + TQString(TQKeySequence( TQt::CTRL | TQt::Key_ ## k ))
+#else
+#define ACCEL_KEY(k) "\t" + TQString("Ctrl+" #k)
+#endif
+
+#define innerMargin 1
+
+struct SecTQLineEditPrivate : public TQt
+{
+ SecTQLineEditPrivate( SecTQLineEdit *q )
+ : q(q), cursor(0), cursorTimer(0), tripleClickTimer(0), frame(1),
+ cursorVisible(0), separator(0), readOnly(0), modified(0),
+ direction(TQChar::DirON), alignment(0),
+ echoMode(0), textDirty(0), selDirty(0),
+ ascent(0), maxLength(32767), menuId(0),
+ hscroll(0),
+ undoState(0), selstart(0), selend(0),
+ imstart(0), imend(0), imselstart(0), imselend(0)
+ {}
+ void init( const SecTQString&);
+
+ SecTQLineEdit *q;
+ SecTQString text;
+ int cursor;
+ int cursorTimer;
+ TQPoint tripleClick;
+ int tripleClickTimer;
+ uint frame : 1;
+ uint cursorVisible : 1;
+ uint separator : 1;
+ uint readOnly : 1;
+ uint modified : 1;
+ uint direction : 5;
+ uint alignment : 3;
+ uint echoMode : 2;
+ uint textDirty : 1;
+ uint selDirty : 1;
+ int ascent;
+ int maxLength;
+ int menuId;
+ int hscroll;
+
+ void finishChange( int validateFromState = -1, bool setModified = TRUE );
+
+ void setCursorVisible( bool visible );
+
+
+ // undo/redo handling
+ enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection };
+ struct Command {
+ inline Command(){}
+ inline Command( CommandType type, int pos, TQChar c )
+ :type(type),c(c),pos(pos){}
+ uint type : 4;
+ TQChar c;
+ int pos;
+ };
+ int undoState;
+ TQValueVector history;
+#ifndef SECURE_NO_UNDO
+ void addCommand( const Command& cmd );
+#endif /* SECURE_NO_UNDO */
+
+ void insert( const SecTQString& s );
+ void del( bool wasBackspace = FALSE );
+ void remove( int pos );
+
+ inline void separate() { separator = TRUE; }
+#ifndef SECURE_NO_UNDO
+ inline void undo( int until = -1 ) {
+ if ( !isUndoAvailable() )
+ return;
+ deselect();
+ while ( undoState && undoState > until ) {
+ Command& cmd = history[--undoState];
+ switch ( cmd.type ) {
+ case Insert:
+ text.remove( cmd.pos, 1);
+ cursor = cmd.pos;
+ break;
+ case Remove:
+ case RemoveSelection:
+ text.insert( cmd.pos, cmd.c );
+ cursor = cmd.pos + 1;
+ break;
+ case Delete:
+ case DeleteSelection:
+ text.insert( cmd.pos, cmd.c );
+ cursor = cmd.pos;
+ break;
+ case Separator:
+ continue;
+ }
+ if ( until < 0 && undoState ) {
+ Command& next = history[undoState-1];
+ if ( next.type != cmd.type && next.type < RemoveSelection
+ && !( cmd.type >= RemoveSelection && next.type != Separator ) )
+ break;
+ }
+ }
+ modified = ( undoState != 0 );
+ textDirty = TRUE;
+ }
+ inline void redo() {
+ if ( !isRedoAvailable() )
+ return;
+ deselect();
+ while ( undoState < (int)history.size() ) {
+ Command& cmd = history[undoState++];
+ switch ( cmd.type ) {
+ case Insert:
+ text.insert( cmd.pos, cmd.c );
+ cursor = cmd.pos + 1;
+ break;
+ case Remove:
+ case Delete:
+ case RemoveSelection:
+ case DeleteSelection:
+ text.remove( cmd.pos, 1 );
+ cursor = cmd.pos;
+ break;
+ case Separator:
+ continue;
+ }
+ if ( undoState < (int)history.size() ) {
+ Command& next = history[undoState];
+ if ( next.type != cmd.type && cmd.type < RemoveSelection
+ && !( next.type >= RemoveSelection && cmd.type != Separator ) )
+ break;
+ }
+ }
+ textDirty = TRUE;
+ }
+#endif /* SECURE_NO_UNDO */
+ inline bool isUndoAvailable() const { return !readOnly && undoState; }
+ inline bool isRedoAvailable() const { return !readOnly && undoState < (int)history.size(); }
+
+
+ // bidi
+ inline bool isRightToLeft() const { return direction==TQChar::DirON?text.isRightToLeft():(direction==TQChar::DirR); }
+
+ // selection
+ int selstart, selend;
+ inline bool allSelected() const { return !text.isEmpty() && selstart == 0 && selend == (int)text.length(); }
+ inline bool hasSelectedText() const { return !text.isEmpty() && selend > selstart; }
+ inline void deselect() { selDirty |= (selend > selstart); selstart = selend = 0; }
+ void removeSelectedText();
+#ifndef QT_NO_CLIPBOARD
+ void copy( bool clipboard = TRUE ) const;
+#endif
+ inline bool inSelection( int x ) const
+ { if ( selstart >= selend ) return FALSE;
+ int pos = xToPos( x, TQTextItem::OnCharacters ); return pos >= selstart && pos < selend; }
+
+ // input methods
+ int imstart, imend, imselstart, imselend;
+
+ // complex text layout
+ TQTextLayout textLayout;
+ void updateTextLayout();
+ void moveCursor( int pos, bool mark = FALSE );
+ void setText( const SecTQString& txt );
+ int xToPos( int x, TQTextItem::CursorPosition = TQTextItem::BetweenCharacters ) const;
+ inline int visualAlignment() const { return alignment ? alignment : int( isRightToLeft() ? AlignRight : AlignLeft ); }
+ TQRect cursorRect() const;
+ void updateMicroFocusHint();
+
+};
+
+
+/*!
+ \class SecTQLineEdit
+ \brief The SecTQLineEdit widget is a one-line text editor.
+
+ \ingroup basic
+ \mainclass
+
+ A line edit allows the user to enter and edit a single line of
+ plain text with a useful collection of editing functions,
+ including undo and redo, cut and paste,
+
+ By changing the echoMode() of a line edit, it can also be used as
+ a "write-only" field, for inputs such as passwords.
+
+ The length of the text can be constrained to maxLength().
+
+ A related class is TQTextEdit which allows multi-line, rich-text
+ editing.
+
+ You can change the text with setText() or insert(). The text is
+ retrieved with text(); the displayed text (which may be different,
+ see \l{EchoMode}) is retrieved with displayText(). Text can be
+ selected with setSelection() or selectAll(), and the selection can
+ be cut(), copy()ied and paste()d. The text can be aligned with
+ setAlignment().
+
+ When the text changes the textChanged() signal is emitted; when
+ the Return or Enter key is pressed the returnPressed() signal is
+ emitted.
+
+ When the text changes the textModified() signal is emitted in all
+ cases.
+
+ By default, SecTQLineEdits have a frame as specified by the Windows
+ and Motif style guides; you can turn it off by calling
+ setFrame(FALSE).
+
+ The default key bindings are described below.
+ \target desc
+ \table
+ \header \i Keypress \i Action
+ \row \i Left Arrow \i Moves the cursor one character to the left.
+ \row \i Shift+Left Arrow \i Moves and selects text one character to the left.
+ \row \i Right Arrow \i Moves the cursor one character to the right.
+ \row \i Shift+Right Arrow \i Moves and selects text one character to the right.
+ \row \i Home \i Moves the cursor to the beginning of the line.
+ \row \i End \i Moves the cursor to the end of the line.
+ \row \i Backspace \i Deletes the character to the left of the cursor.
+ \row \i Ctrl+Backspace \i Deletes the word to the left of the cursor.
+ \row \i Delete \i Deletes the character to the right of the cursor.
+ \row \i Ctrl+Delete \i Deletes the word to the right of the cursor.
+ \row \i Ctrl+A \i Moves the cursor to the beginning of the line.
+ \row \i Ctrl+B \i Moves the cursor one character to the left.
+ \row \i Ctrl+C \i Copies the selected text to the clipboard.
+ (Windows also supports Ctrl+Insert for this operation.)
+ \row \i Ctrl+D \i Deletes the character to the right of the cursor.
+ \row \i Ctrl+E \i Moves the cursor to the end of the line.
+ \row \i Ctrl+F \i Moves the cursor one character to the right.
+ \row \i Ctrl+H \i Deletes the character to the left of the cursor.
+ \row \i Ctrl+K \i Deletes to the end of the line.
+ \row \i Ctrl+V \i Pastes the clipboard text into line edit.
+ (Windows also supports Shift+Insert for this operation.)
+ \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
+ (Windows also supports Shift+Delete for this operation.)
+ \row \i Ctrl+Z \i Undoes the last operation.
+ \row \i Ctrl+Y \i Redoes the last undone operation.
+ \endtable
+
+ Any other key sequence that represents a valid character, will
+ cause the character to be inserted into the line edit.
+
+
+
+ \sa TQTextEdit TQLabel TQComboBox
+ \link guibooks.html#fowler GUI Design Handbook: Field, Entry\endlink
+*/
+
+
+/*!
+ \fn void SecTQLineEdit::textChanged( const SecTQString& )
+
+ This signal is emitted whenever the text changes. The argument is
+ the new text.
+*/
+
+/*!
+ \fn void SecTQLineEdit::selectionChanged()
+
+ This signal is emitted whenever the selection changes.
+
+ \sa hasSelectedText(), selectedText()
+*/
+
+/*!
+ \fn void SecTQLineEdit::lostFocus()
+
+ This signal is emitted when the line edit has lost focus.
+
+ \sa hasFocus(), TQWidget::focusInEvent(), TQWidget::focusOutEvent()
+*/
+
+
+
+/*!
+ Constructs a line edit with no text.
+
+ The maximum text length is set to 32767 characters.
+
+ The \a parent and \a name arguments are sent to the TQWidget constructor.
+
+ \sa setText(), setMaxLength()
+*/
+
+SecTQLineEdit::SecTQLineEdit( TQWidget* parent, const char* name )
+ : TQFrame( parent, name, WNoAutoErase ), d(new SecTQLineEditPrivate( this ))
+{
+ d->init( SecTQString::null );
+}
+
+/*!
+ Constructs a line edit containing the text \a contents.
+
+ The cursor position is set to the end of the line and the maximum
+ text length to 32767 characters.
+
+ The \a parent and \a name arguments are sent to the TQWidget
+ constructor.
+
+ \sa text(), setMaxLength()
+*/
+
+SecTQLineEdit::SecTQLineEdit( const SecTQString& contents, TQWidget* parent, const char* name )
+ : TQFrame( parent, name, WNoAutoErase ), d(new SecTQLineEditPrivate( this ))
+{
+ d->init( contents );
+}
+
+/*!
+ Destroys the line edit.
+*/
+
+SecTQLineEdit::~SecTQLineEdit()
+{
+ delete d;
+}
+
+
+/*!
+ \property SecTQLineEdit::text
+ \brief the line edit's text
+
+ Setting this property clears the selection, clears the undo/redo
+ history, moves the cursor to the end of the line and resets the
+ \c modified property to FALSE.
+
+ The text is truncated to maxLength() length.
+
+ \sa insert()
+*/
+SecTQString SecTQLineEdit::text() const
+{
+ return ( d->text.isNull() ? SecTQString ("") : d->text );
+}
+
+void SecTQLineEdit::setText( const SecTQString& text)
+{
+ resetInputContext();
+ d->setText( text );
+ d->modified = FALSE;
+ d->finishChange( -1, FALSE );
+}
+
+
+/*!
+ \property SecTQLineEdit::displayText
+ \brief the displayed text
+
+ If \c EchoMode is \c Normal this returns the same as text(); if
+ \c EchoMode is \c Password it returns a string of asterisks
+ text().length() characters long, e.g. "******"; if \c EchoMode is
+ \c NoEcho returns an empty string, "".
+
+ \sa setEchoMode() text() EchoMode
+*/
+
+TQString SecTQLineEdit::displayText() const
+{
+ if ( d->echoMode == NoEcho )
+ return TQString::fromLatin1("");
+
+ TQChar pwd_char = TQChar (style().styleHint( TQStyle::SH_LineEdit_PasswordCharacter, this));
+ TQString res;
+ res.fill (pwd_char, d->text.length ());
+ return res;
+}
+
+
+/*!
+ \property SecTQLineEdit::maxLength
+ \brief the maximum permitted length of the text
+
+ If the text is too long, it is truncated at the limit.
+
+ If truncation occurs any selected text will be unselected, the
+ cursor position is set to 0 and the first part of the string is
+ shown.
+*/
+
+int SecTQLineEdit::maxLength() const
+{
+ return d->maxLength;
+}
+
+void SecTQLineEdit::setMaxLength( int maxLength )
+{
+ d->maxLength = maxLength;
+ setText( d->text );
+}
+
+
+
+/*!
+ \property SecTQLineEdit::frame
+ \brief whether the line edit draws itself with a frame
+
+ If enabled (the default) the line edit draws itself inside a
+ two-pixel frame, otherwise the line edit draws itself without any
+ frame.
+*/
+bool SecTQLineEdit::frame() const
+{
+ return frameShape() != NoFrame;
+}
+
+
+void SecTQLineEdit::setFrame( bool enable )
+{
+ setFrameStyle( enable ? ( LineEditPanel | Sunken ) : NoFrame );
+}
+
+
+/*!
+ \enum SecTQLineEdit::EchoMode
+
+ This enum type describes how a line edit should display its
+ contents.
+
+ \value Normal Display characters as they are entered. This is the
+ default.
+ \value NoEcho Do not display anything. This may be appropriate
+ for passwords where even the length of the
+ password should be kept secret.
+ \value Password Display asterisks instead of the characters
+ actually entered.
+
+ \sa setEchoMode() echoMode()
+*/
+
+
+/*!
+ \property SecTQLineEdit::echoMode
+ \brief the line edit's echo mode
+
+ The initial setting is \c Normal, but SecTQLineEdit also supports \c
+ NoEcho and \c Password modes.
+
+ The widget's display and the ability to copy the text is affected
+ by this setting.
+
+ \sa EchoMode displayText()
+*/
+
+SecTQLineEdit::EchoMode SecTQLineEdit::echoMode() const
+{
+ return (EchoMode) d->echoMode;
+}
+
+void SecTQLineEdit::setEchoMode( EchoMode mode )
+{
+ d->echoMode = mode;
+ d->updateTextLayout();
+ update();
+}
+
+
+
+/*!
+ Returns a recommended size for the widget.
+
+ The width returned, in pixels, is usually enough for about 15 to
+ 20 characters.
+*/
+
+TQSize SecTQLineEdit::sizeHint() const
+{
+ constPolish();
+ TQFontMetrics fm( font() );
+ int h = TQMAX(fm.lineSpacing(), 14) + 2*innerMargin;
+ int w = fm.width( 'x' ) * 17; // "some"
+ int m = frameWidth() * 2;
+ return (style().sizeFromContents(TQStyle::CT_LineEdit, this,
+ TQSize( w + m, h + m ).
+ expandedTo(TQApplication::globalStrut())));
+}
+
+
+/*!
+ Returns a minimum size for the line edit.
+
+ The width returned is enough for at least one character.
+*/
+
+TQSize SecTQLineEdit::minimumSizeHint() const
+{
+ constPolish();
+ TQFontMetrics fm = fontMetrics();
+ int h = fm.height() + TQMAX( 2*innerMargin, fm.leading() );
+ int w = fm.maxWidth();
+ int m = frameWidth() * 2;
+ return TQSize( w + m, h + m );
+}
+
+
+/*!
+ \property SecTQLineEdit::cursorPosition
+ \brief the current cursor position for this line edit
+
+ Setting the cursor position causes a repaint when appropriate.
+*/
+
+int SecTQLineEdit::cursorPosition() const
+{
+ return d->cursor;
+}
+
+
+void SecTQLineEdit::setCursorPosition( int pos )
+{
+ if ( pos <= (int) d->text.length() )
+ d->moveCursor( pos );
+}
+
+
+/*!
+ \property SecTQLineEdit::alignment
+ \brief the alignment of the line edit
+
+ Possible Values are \c TQt::AlignAuto, \c TQt::AlignLeft, \c
+ TQt::AlignRight and \c TQt::AlignHCenter.
+
+ Attempting to set the alignment to an illegal flag combination
+ does nothing.
+
+ \sa TQt::AlignmentFlags
+*/
+
+int SecTQLineEdit::alignment() const
+{
+ return d->alignment;
+}
+
+void SecTQLineEdit::setAlignment( int flag )
+{
+ d->alignment = flag & 0x7;
+ update();
+}
+
+
+/*!
+ \obsolete
+ \fn void SecTQLineEdit::cursorRight( bool, int )
+
+ Use cursorForward() instead.
+
+ \sa cursorForward()
+*/
+
+/*!
+ \obsolete
+ \fn void SecTQLineEdit::cursorLeft( bool, int )
+ For compatibilty with older applications only. Use cursorBackward()
+ instead.
+ \sa cursorBackward()
+*/
+
+/*!
+ Moves the cursor forward \a steps characters. If \a mark is TRUE
+ each character moved over is added to the selection; if \a mark is
+ FALSE the selection is cleared.
+
+ \sa cursorBackward()
+*/
+
+void SecTQLineEdit::cursorForward( bool mark, int steps )
+{
+ int cursor = d->cursor;
+ if ( steps > 0 ) {
+ while( steps-- )
+ cursor = d->textLayout.nextCursorPosition( cursor );
+ } else if ( steps < 0 ) {
+ while ( steps++ )
+ cursor = d->textLayout.previousCursorPosition( cursor );
+ }
+ d->moveCursor( cursor, mark );
+}
+
+
+/*!
+ Moves the cursor back \a steps characters. If \a mark is TRUE each
+ character moved over is added to the selection; if \a mark is
+ FALSE the selection is cleared.
+
+ \sa cursorForward()
+*/
+void SecTQLineEdit::cursorBackward( bool mark, int steps )
+{
+ cursorForward( mark, -steps );
+}
+
+/*!
+ Moves the cursor one word forward. If \a mark is TRUE, the word is
+ also selected.
+
+ \sa cursorWordBackward()
+*/
+void SecTQLineEdit::cursorWordForward( bool mark )
+{
+ d->moveCursor( d->textLayout.nextCursorPosition(d->cursor, TQTextLayout::SkipWords), mark );
+}
+
+/*!
+ Moves the cursor one word backward. If \a mark is TRUE, the word
+ is also selected.
+
+ \sa cursorWordForward()
+*/
+
+void SecTQLineEdit::cursorWordBackward( bool mark )
+{
+ d->moveCursor( d->textLayout.previousCursorPosition(d->cursor, TQTextLayout::SkipWords), mark );
+}
+
+
+/*!
+ If no text is selected, deletes the character to the left of the
+ text cursor and moves the cursor one position to the left. If any
+ text is selected, the cursor is moved to the beginning of the
+ selected text and the selected text is deleted.
+
+ \sa del()
+*/
+void SecTQLineEdit::backspace()
+{
+ int priorState = d->undoState;
+ if ( d->hasSelectedText() ) {
+ d->removeSelectedText();
+ } else if ( d->cursor ) {
+ --d->cursor;
+ d->del( TRUE );
+ }
+ d->finishChange( priorState );
+}
+
+/*!
+ If no text is selected, deletes the character to the right of the
+ text cursor. If any text is selected, the cursor is moved to the
+ beginning of the selected text and the selected text is deleted.
+
+ \sa backspace()
+*/
+
+void SecTQLineEdit::del()
+{
+ int priorState = d->undoState;
+ if ( d->hasSelectedText() ) {
+ d->removeSelectedText();
+ } else {
+ int n = d->textLayout.nextCursorPosition( d->cursor ) - d->cursor;
+ while ( n-- )
+ d->del();
+ }
+ d->finishChange( priorState );
+}
+
+/*!
+ Moves the text cursor to the beginning of the line unless it is
+ already there. If \a mark is TRUE, text is selected towards the
+ first position; otherwise, any selected text is unselected if the
+ cursor is moved.
+
+ \sa end()
+*/
+
+void SecTQLineEdit::home( bool mark )
+{
+ d->moveCursor( 0, mark );
+}
+
+/*!
+ Moves the text cursor to the end of the line unless it is already
+ there. If \a mark is TRUE, text is selected towards the last
+ position; otherwise, any selected text is unselected if the cursor
+ is moved.
+
+ \sa home()
+*/
+
+void SecTQLineEdit::end( bool mark )
+{
+ d->moveCursor( d->text.length(), mark );
+}
+
+
+/*!
+ \property SecTQLineEdit::modified
+ \brief whether the line edit's contents has been modified by the user
+
+ The modified flag is never read by SecTQLineEdit; it has a default value
+ of FALSE and is changed to TRUE whenever the user changes the line
+ edit's contents.
+
+ This is useful for things that need to provide a default value but
+ do not start out knowing what the default should be (perhaps it
+ depends on other fields on the form). Start the line edit without
+ the best default, and when the default is known, if modified()
+ returns FALSE (the user hasn't entered any text), insert the
+ default value.
+
+ Calling clearModified() or setText() resets the modified flag to
+ FALSE.
+*/
+
+bool SecTQLineEdit::isModified() const
+{
+ return d->modified;
+}
+
+/*!
+ Resets the modified flag to FALSE.
+
+ \sa isModified()
+*/
+void SecTQLineEdit::clearModified()
+{
+ d->modified = FALSE;
+ d->history.clear();
+ d->undoState = 0;
+}
+
+/*!
+ \obsolete
+ \property SecTQLineEdit::edited
+ \brief whether the line edit has been edited. Use modified instead.
+*/
+bool SecTQLineEdit::edited() const { return d->modified; }
+void SecTQLineEdit::setEdited( bool on ) { d->modified = on; }
+
+/*!
+ \obsolete
+ \property SecTQLineEdit::hasMarkedText
+ \brief whether part of the text has been selected by the user. Use hasSelectedText instead.
+*/
+
+/*!
+ \property SecTQLineEdit::hasSelectedText
+ \brief whether there is any text selected
+
+ hasSelectedText() returns TRUE if some or all of the text has been
+ selected by the user; otherwise returns FALSE.
+
+ \sa selectedText()
+*/
+
+
+bool SecTQLineEdit::hasSelectedText() const
+{
+ return d->hasSelectedText();
+}
+
+/*!
+ \obsolete
+ \property SecTQLineEdit::markedText
+ \brief the text selected by the user. Use selectedText instead.
+*/
+
+/*!
+ \property SecTQLineEdit::selectedText
+ \brief the selected text
+
+ If there is no selected text this property's value is
+ TQString::null.
+
+ \sa hasSelectedText()
+*/
+
+SecTQString SecTQLineEdit::selectedText() const
+{
+ if ( d->hasSelectedText() )
+ return d->text.mid( d->selstart, d->selend - d->selstart );
+ return SecTQString::null;
+}
+
+/*!
+ selectionStart() returns the index of the first selected character in the
+ line edit or -1 if no text is selected.
+
+ \sa selectedText()
+*/
+
+int SecTQLineEdit::selectionStart() const
+{
+ return d->hasSelectedText() ? d->selstart : -1;
+}
+
+
+/*!
+ Selects text from position \a start and for \a length characters.
+
+ \sa deselect() selectAll()
+*/
+
+void SecTQLineEdit::setSelection( int start, int length )
+{
+ if ( start < 0 || start > (int)d->text.length() || length < 0 ) {
+ d->selstart = d->selend = 0;
+ } else {
+ d->selstart = start;
+ d->selend = TQMIN( start + length, (int)d->text.length() );
+ d->cursor = d->selend;
+ }
+ update();
+}
+
+
+/*!
+ \property SecTQLineEdit::undoAvailable
+ \brief whether undo is available
+*/
+
+bool SecTQLineEdit::isUndoAvailable() const
+{
+ return d->isUndoAvailable();
+}
+
+/*!
+ \property SecTQLineEdit::redoAvailable
+ \brief whether redo is available
+*/
+
+bool SecTQLineEdit::isRedoAvailable() const
+{
+ return d->isRedoAvailable();
+}
+
+/*!
+ Selects all the text (i.e. highlights it) and moves the cursor to
+ the end. This is useful when a default value has been inserted
+ because if the user types before clicking on the widget, the
+ selected text will be deleted.
+
+ \sa setSelection() deselect()
+*/
+
+void SecTQLineEdit::selectAll()
+{
+ d->selstart = d->selend = d->cursor = 0;
+ d->moveCursor( d->text.length(), TRUE );
+}
+
+/*!
+ Deselects any selected text.
+
+ \sa setSelection() selectAll()
+*/
+
+void SecTQLineEdit::deselect()
+{
+ d->deselect();
+ d->finishChange();
+}
+
+
+/*!
+ Deletes any selected text, inserts \a newText and sets it as the
+ new contents of the line edit.
+*/
+void SecTQLineEdit::insert( const SecTQString &newText )
+{
+// q->resetInputContext(); //#### FIX ME IN QT
+ int priorState = d->undoState;
+ d->removeSelectedText();
+ d->insert( newText );
+ d->finishChange( priorState );
+}
+
+/*!
+ Clears the contents of the line edit.
+*/
+void SecTQLineEdit::clear()
+{
+ int priorState = d->undoState;
+ resetInputContext();
+ d->selstart = 0;
+ d->selend = d->text.length();
+ d->removeSelectedText();
+ d->separate();
+ d->finishChange( priorState );
+}
+
+/*!
+ Undoes the last operation if undo is \link
+ SecTQLineEdit::undoAvailable available\endlink. Deselects any current
+ selection, and updates the selection start to the current cursor
+ position.
+*/
+void SecTQLineEdit::undo()
+{
+#ifndef SECURE_NO_UNDO
+ resetInputContext();
+ d->undo();
+ d->finishChange( -1, FALSE );
+#endif
+}
+
+/*!
+ Redoes the last operation if redo is \link
+ SecTQLineEdit::redoAvailable available\endlink.
+*/
+void SecTQLineEdit::redo()
+{
+#ifndef SECURE_NO_UNDO
+ resetInputContext();
+ d->redo();
+ d->finishChange();
+#endif
+}
+
+
+/*!
+ \property SecTQLineEdit::readOnly
+ \brief whether the line edit is read only.
+
+ In read-only mode, the user can still copy the text to the
+ clipboard (if echoMode() is \c Normal), but cannot edit it.
+
+ SecTQLineEdit does not show a cursor in read-only mode.
+
+ \sa setEnabled()
+*/
+
+bool SecTQLineEdit::isReadOnly() const
+{
+ return d->readOnly;
+}
+
+void SecTQLineEdit::setReadOnly( bool enable )
+{
+ d->readOnly = enable;
+#ifndef QT_NO_CURSOR
+ setCursor( enable ? arrowCursor : ibeamCursor );
+#endif
+ update();
+}
+
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+ Copies the selected text to the clipboard and deletes it, if there
+ is any, and if echoMode() is \c Normal.
+
+ \sa copy() paste() setValidator()
+*/
+
+void SecTQLineEdit::cut()
+{
+ if ( hasSelectedText() ) {
+ copy();
+ del();
+ }
+}
+
+
+/*!
+ Copies the selected text to the clipboard, if there is any, and if
+ echoMode() is \c Normal.
+
+ \sa cut() paste()
+*/
+
+void SecTQLineEdit::copy() const
+{
+ d->copy();
+}
+
+/*!
+ Inserts the clipboard's text at the cursor position, deleting any
+ selected text, providing the line edit is not \link
+ SecTQLineEdit::readOnly read-only\endlink.
+
+ \sa copy() cut()
+*/
+
+void SecTQLineEdit::paste()
+{
+ d->removeSelectedText();
+ insert( TQApplication::clipboard()->text( TQClipboard::Clipboard ) );
+}
+
+void SecTQLineEditPrivate::copy( bool clipboard ) const
+{
+#ifndef SECURE
+ TQString t = q->selectedText();
+ if ( !t.isEmpty() && echoMode == SecTQLineEdit::Normal ) {
+ q->disconnect( TQApplication::clipboard(), SIGNAL(selectionChanged()), q, 0);
+ TQApplication::clipboard()->setText( t, clipboard ? TQClipboard::Clipboard : TQClipboard::Selection );
+ q->connect( TQApplication::clipboard(), SIGNAL(selectionChanged()),
+ q, SLOT(clipboardChanged()) );
+ }
+#endif
+}
+
+#endif // !QT_NO_CLIPBOARD
+
+/*!\reimp
+*/
+
+void SecTQLineEdit::resizeEvent( TQResizeEvent *e )
+{
+ TQFrame::resizeEvent( e );
+}
+
+/*! \reimp
+*/
+bool SecTQLineEdit::event( TQEvent * e )
+{
+ if ( e->type() == TQEvent::AccelOverride && !d->readOnly ) {
+ TQKeyEvent* ke = (TQKeyEvent*) e;
+ if ( ke->state() == NoButton || ke->state() == ShiftButton
+ || ke->state() == Keypad ) {
+ if ( ke->key() < Key_Escape ) {
+ ke->accept();
+ } else if ( ke->state() == NoButton
+ || ke->state() == ShiftButton ) {
+ switch ( ke->key() ) {
+ case Key_Delete:
+ case Key_Home:
+ case Key_End:
+ case Key_Backspace:
+ case Key_Left:
+ case Key_Right:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ } else if ( ke->state() & ControlButton ) {
+ switch ( ke->key() ) {
+// Those are too frequently used for application functionality
+/* case Key_A:
+ case Key_B:
+ case Key_D:
+ case Key_E:
+ case Key_F:
+ case Key_H:
+ case Key_K:
+*/
+ case Key_C:
+ case Key_V:
+ case Key_X:
+ case Key_Y:
+ case Key_Z:
+ case Key_Left:
+ case Key_Right:
+#if defined (Q_WS_WIN)
+ case Key_Insert:
+ case Key_Delete:
+#endif
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ } else if ( e->type() == TQEvent::Timer ) {
+ // should be timerEvent, is here for binary compatibility
+ int timerId = ((TQTimerEvent*)e)->timerId();
+ if ( timerId == d->cursorTimer ) {
+ if(!hasSelectedText() || style().styleHint( TQStyle::SH_BlinkCursorWhenTextSelected ))
+ d->setCursorVisible( !d->cursorVisible );
+ } else if ( timerId == d->tripleClickTimer ) {
+ killTimer( d->tripleClickTimer );
+ d->tripleClickTimer = 0;
+ }
+ }
+ return TQWidget::event( e );
+}
+
+/*! \reimp
+*/
+void SecTQLineEdit::mousePressEvent( TQMouseEvent* e )
+{
+ if ( e->button() == RightButton )
+ return;
+ if ( d->tripleClickTimer && ( e->pos() - d->tripleClick ).manhattanLength() <
+ TQApplication::startDragDistance() ) {
+ selectAll();
+ return;
+ }
+ bool mark = e->state() & ShiftButton;
+ int cursor = d->xToPos( e->pos().x() );
+ d->moveCursor( cursor, mark );
+}
+
+/*! \reimp
+*/
+void SecTQLineEdit::mouseMoveEvent( TQMouseEvent * e )
+{
+
+#ifndef QT_NO_CURSOR
+ if ( ( e->state() & MouseButtonMask ) == 0 ) {
+ if ( !d->readOnly )
+ setCursor( ( d->inSelection( e->pos().x() ) ? arrowCursor : ibeamCursor ) );
+ }
+#endif
+
+ if ( e->state() & LeftButton ) {
+ d->moveCursor( d->xToPos( e->pos().x() ), TRUE );
+ }
+}
+
+/*! \reimp
+*/
+void SecTQLineEdit::mouseReleaseEvent( TQMouseEvent* e )
+{
+#ifndef QT_NO_CLIPBOARD
+ if (TQApplication::clipboard()->supportsSelection() ) {
+ if ( e->button() == LeftButton ) {
+ d->copy( FALSE );
+ } else if ( !d->readOnly && e->button() == MidButton ) {
+ d->deselect();
+ insert( TQApplication::clipboard()->text( TQClipboard::Selection ) );
+ }
+ }
+#endif
+}
+
+/*! \reimp
+*/
+void SecTQLineEdit::mouseDoubleClickEvent( TQMouseEvent* e )
+{
+ if ( e->button() == TQt::LeftButton ) {
+ deselect();
+ d->cursor = d->xToPos( e->pos().x() );
+ d->cursor = d->textLayout.previousCursorPosition( d->cursor, TQTextLayout::SkipWords );
+ // ## text layout should support end of words.
+ int end = d->textLayout.nextCursorPosition( d->cursor, TQTextLayout::SkipWords );
+ while ( end > d->cursor && d->text[end-1].isSpace() )
+ --end;
+ d->moveCursor( end, TRUE );
+ d->tripleClickTimer = startTimer( TQApplication::doubleClickInterval() );
+ d->tripleClick = e->pos();
+ }
+}
+
+/*!
+ \fn void SecTQLineEdit::returnPressed()
+
+ This signal is emitted when the Return or Enter key is pressed.
+*/
+
+/*!
+ Converts key press event \a e into a line edit action.
+
+ If Return or Enter is pressed the signal returnPressed() is
+ emitted.
+
+ The default key bindings are listed in the \link #desc detailed
+ description.\endlink
+*/
+
+void SecTQLineEdit::keyPressEvent( TQKeyEvent * e )
+{
+ d->setCursorVisible( TRUE );
+ if ( e->key() == Key_Enter || e->key() == Key_Return ) {
+ emit returnPressed();
+ e->ignore();
+ return;
+ }
+ if ( !d->readOnly ) {
+ TQString t = e->text();
+ if ( !t.isEmpty() && (!e->ascii() || e->ascii()>=32) &&
+ e->key() != Key_Delete &&
+ e->key() != Key_Backspace ) {
+#ifdef Q_WS_X11
+ extern bool tqt_hebrew_keyboard_hack;
+ if ( tqt_hebrew_keyboard_hack ) {
+ // the X11 keyboard layout is broken and does not reverse
+ // braces correctly. This is a hack to get halfway correct
+ // behaviour
+ if ( d->isRightToLeft() ) {
+ TQChar *c = (TQChar *)t.unicode();
+ int l = t.length();
+ while( l-- ) {
+ if ( c->mirrored() )
+ *c = c->mirroredChar();
+ c++;
+ }
+ }
+ }
+#endif
+ insert( t );
+ return;
+ }
+ }
+ bool unknown = FALSE;
+ if ( e->state() & ControlButton ) {
+ switch ( e->key() ) {
+ case Key_A:
+#if defined(Q_WS_X11)
+ home( e->state() & ShiftButton );
+#else
+ selectAll();
+#endif
+ break;
+ case Key_B:
+ cursorForward( e->state() & ShiftButton, -1 );
+ break;
+#ifndef QT_NO_CLIPBOARD
+ case Key_C:
+ copy();
+ break;
+#endif
+ case Key_D:
+ if ( !d->readOnly ) {
+ del();
+ }
+ break;
+ case Key_E:
+ end( e->state() & ShiftButton );
+ break;
+ case Key_F:
+ cursorForward( e->state() & ShiftButton, 1 );
+ break;
+ case Key_H:
+ if ( !d->readOnly ) {
+ backspace();
+ }
+ break;
+ case Key_K:
+ if ( !d->readOnly ) {
+ int priorState = d->undoState;
+ d->deselect();
+ while ( d->cursor < (int) d->text.length() )
+ d->del();
+ d->finishChange( priorState );
+ }
+ break;
+#if defined(Q_WS_X11)
+ case Key_U:
+ if ( !d->readOnly )
+ clear();
+ break;
+#endif
+#ifndef QT_NO_CLIPBOARD
+ case Key_V:
+ if ( !d->readOnly )
+ paste();
+ break;
+ case Key_X:
+ if ( !d->readOnly && d->hasSelectedText() && echoMode() == Normal ) {
+ copy();
+ del();
+ }
+ break;
+#if defined (Q_WS_WIN)
+ case Key_Insert:
+ copy();
+ break;
+#endif
+#endif
+ case Key_Delete:
+ if ( !d->readOnly ) {
+ cursorWordForward( TRUE );
+ del();
+ }
+ break;
+ case Key_Backspace:
+ if ( !d->readOnly ) {
+ cursorWordBackward( TRUE );
+ del();
+ }
+ break;
+ case Key_Right:
+ case Key_Left:
+ if ( d->isRightToLeft() == (e->key() == Key_Right) ) {
+ if ( echoMode() == Normal )
+ cursorWordBackward( e->state() & ShiftButton );
+ else
+ home( e->state() & ShiftButton );
+ } else {
+ if ( echoMode() == Normal )
+ cursorWordForward( e->state() & ShiftButton );
+ else
+ end( e->state() & ShiftButton );
+ }
+ break;
+ case Key_Z:
+ if ( !d->readOnly ) {
+ if(e->state() & ShiftButton)
+ redo();
+ else
+ undo();
+ }
+ break;
+ case Key_Y:
+ if ( !d->readOnly )
+ redo();
+ break;
+ default:
+ unknown = TRUE;
+ }
+ } else { // ### check for *no* modifier
+ switch ( e->key() ) {
+ case Key_Shift:
+ // ### TODO
+ break;
+ case Key_Left:
+ case Key_Right: {
+ int step = (d->isRightToLeft() == (e->key() == Key_Right)) ? -1 : 1;
+ cursorForward( e->state() & ShiftButton, step );
+ }
+ break;
+ case Key_Backspace:
+ if ( !d->readOnly ) {
+ backspace();
+ }
+ break;
+ case Key_Home:
+#ifdef Q_WS_MACX
+ case Key_Up:
+#endif
+ home( e->state() & ShiftButton );
+ break;
+ case Key_End:
+#ifdef Q_WS_MACX
+ case Key_Down:
+#endif
+ end( e->state() & ShiftButton );
+ break;
+ case Key_Delete:
+ if ( !d->readOnly ) {
+#if defined (Q_WS_WIN)
+ if ( e->state() & ShiftButton ) {
+ cut();
+ break;
+ }
+#endif
+ del();
+ }
+ break;
+#if defined (Q_WS_WIN)
+ case Key_Insert:
+ if ( !d->readOnly && e->state() & ShiftButton )
+ paste();
+ else
+ unknown = TRUE;
+ break;
+#endif
+ case Key_F14: // Undo key on Sun keyboards
+ if ( !d->readOnly )
+ undo();
+ break;
+#ifndef QT_NO_CLIPBOARD
+ case Key_F16: // Copy key on Sun keyboards
+ copy();
+ break;
+ case Key_F18: // Paste key on Sun keyboards
+ if ( !d->readOnly )
+ paste();
+ break;
+ case Key_F20: // Cut key on Sun keyboards
+ if ( !d->readOnly && hasSelectedText() && echoMode() == Normal ) {
+ copy();
+ del();
+ }
+ break;
+#endif
+ default:
+ unknown = TRUE;
+ }
+ }
+ if ( e->key() == Key_Direction_L )
+ d->direction = TQChar::DirL;
+ else if ( e->key() == Key_Direction_R )
+ d->direction = TQChar::DirR;
+
+ if ( unknown )
+ e->ignore();
+}
+
+/*! \reimp
+ */
+void SecTQLineEdit::imStartEvent( TQIMEvent *e )
+{
+ if ( d->readOnly ) {
+ e->ignore();
+ return;
+ }
+ d->removeSelectedText();
+ d->updateMicroFocusHint();
+ d->imstart = d->imend = d->imselstart = d->imselend = d->cursor;
+}
+
+/*! \reimp
+ */
+void SecTQLineEdit::imComposeEvent( TQIMEvent *e )
+{
+ if ( d->readOnly ) {
+ e->ignore();
+ } else {
+ d->text.replace( d->imstart, d->imend - d->imstart, e->text() );
+ d->imend = d->imstart + e->text().length();
+ d->imselstart = d->imstart + e->cursorPos();
+ d->imselend = d->imselstart + e->selectionLength();
+ d->cursor = e->selectionLength() ? d->imend : d->imselend;
+ d->updateTextLayout();
+ update();
+ }
+}
+
+/*! \reimp
+ */
+void SecTQLineEdit::imEndEvent( TQIMEvent *e )
+{
+ if ( d->readOnly ) {
+ e->ignore();
+ } else {
+ d->text.remove( d->imstart, d->imend - d->imstart );
+ d->cursor = d->imselstart = d->imselend = d->imend = d->imstart;
+ d->textDirty = TRUE;
+ insert( e->text() );
+ }
+}
+
+/*!\reimp
+*/
+
+void SecTQLineEdit::focusInEvent( TQFocusEvent* e )
+{
+ if ( e->reason() == TQFocusEvent::Tab ||
+ e->reason() == TQFocusEvent::Backtab ||
+ e->reason() == TQFocusEvent::Shortcut )
+ selectAll();
+ if ( !d->cursorTimer ) {
+ int cft = TQApplication::cursorFlashTime();
+ d->cursorTimer = cft ? startTimer( cft/2 ) : -1;
+ }
+ d->updateMicroFocusHint();
+}
+
+/*!\reimp
+*/
+
+void SecTQLineEdit::focusOutEvent( TQFocusEvent* e )
+{
+ if ( e->reason() != TQFocusEvent::ActiveWindow &&
+ e->reason() != TQFocusEvent::Popup )
+ deselect();
+ d->setCursorVisible( FALSE );
+ if ( d->cursorTimer > 0 )
+ killTimer( d->cursorTimer );
+ d->cursorTimer = 0;
+ emit lostFocus();
+}
+
+/*!\reimp
+*/
+void SecTQLineEdit::drawContents( TQPainter *p )
+{
+ const TQColorGroup& cg = colorGroup();
+ TQRect cr = contentsRect();
+ TQFontMetrics fm = fontMetrics();
+ TQRect lineRect( cr.x() + innerMargin, cr.y() + (cr.height() - fm.height() + 1) / 2,
+ cr.width() - 2*innerMargin, fm.height() );
+ TQBrush bg = TQBrush( paletteBackgroundColor() );
+ if ( paletteBackgroundPixmap() )
+ bg = TQBrush( cg.background(), *paletteBackgroundPixmap() );
+ else if ( !isEnabled() )
+ bg = cg.brush( TQColorGroup::Background );
+ p->save();
+ p->setClipRegion( TQRegion(cr) - lineRect );
+ p->fillRect( cr, bg );
+ p->restore();
+ SecTQSharedDoubleBuffer buffer( p, lineRect.x(), lineRect.y(),
+ lineRect.width(), lineRect.height(),
+ hasFocus() ? SecTQSharedDoubleBuffer::Force : 0 );
+ p = buffer.painter();
+ p->fillRect( lineRect, bg );
+
+ // locate cursor position
+ int cix = 0;
+ TQTextItem ci = d->textLayout.findItem( d->cursor );
+ if ( ci.isValid() ) {
+ if ( d->cursor != (int)d->text.length() && d->cursor == ci.from() + ci.length()
+ && ci.isRightToLeft() != d->isRightToLeft() )
+ ci = d->textLayout.findItem( d->cursor + 1 );
+ cix = ci.x() + ci.cursorToX( d->cursor - ci.from() );
+ }
+
+ // horizontal scrolling
+ int minLB = TQMAX( 0, -fm.minLeftBearing() );
+ int minRB = TQMAX( 0, -fm.minRightBearing() );
+ int widthUsed = d->textLayout.widthUsed() + 1 + minRB;
+ if ( (minLB + widthUsed) <= lineRect.width() ) {
+ switch ( d->visualAlignment() ) {
+ case AlignRight:
+ d->hscroll = widthUsed - lineRect.width();
+ break;
+ case AlignHCenter:
+ d->hscroll = ( widthUsed - lineRect.width() ) / 2;
+ break;
+ default:
+ d->hscroll = 0;
+ break;
+ }
+ d->hscroll -= minLB;
+ } else if ( cix - d->hscroll >= lineRect.width() ) {
+ d->hscroll = cix - lineRect.width() + 1;
+ } else if ( cix - d->hscroll < 0 ) {
+ d->hscroll = cix;
+ } else if ( widthUsed - d->hscroll < lineRect.width() ) {
+ d->hscroll = widthUsed - lineRect.width() + 1;
+ }
+ // the y offset is there to keep the baseline constant in case we have script changes in the text.
+ TQPoint topLeft = lineRect.topLeft() - TQPoint(d->hscroll, d->ascent-fm.ascent());
+
+ // draw text, selections and cursors
+ p->setPen( cg.text() );
+ bool supressCursor = d->readOnly, hasRightToLeft = d->isRightToLeft();
+ int textflags = 0;
+ if ( font().underline() )
+ textflags |= TQt::Underline;
+ if ( font().strikeOut() )
+ textflags |= TQt::StrikeOut;
+ if ( font().overline() )
+ textflags |= TQt::Overline;
+
+ for ( int i = 0; i < d->textLayout.numItems(); i++ ) {
+ TQTextItem ti = d->textLayout.itemAt( i );
+ hasRightToLeft |= ti.isRightToLeft();
+ int tix = topLeft.x() + ti.x();
+ int first = ti.from();
+ int last = ti.from() + ti.length() - 1;
+
+ // text and selection
+ if ( d->selstart < d->selend && (last >= d->selstart && first < d->selend ) ) {
+ TQRect highlight = TQRect( TQPoint( tix + ti.cursorToX( TQMAX( d->selstart - first, 0 ) ),
+ lineRect.top() ),
+ TQPoint( tix + ti.cursorToX( TQMIN( d->selend - first, last - first + 1 ) ) - 1,
+ lineRect.bottom() ) ).normalize();
+ p->save();
+ p->setClipRegion( TQRegion( lineRect ) - highlight, TQPainter::CoordPainter );
+ p->drawTextItem( topLeft, ti, textflags );
+ p->setClipRect( lineRect & highlight, TQPainter::CoordPainter );
+ p->fillRect( highlight, cg.highlight() );
+ p->setPen( cg.highlightedText() );
+ p->drawTextItem( topLeft, ti, textflags );
+ p->restore();
+ } else {
+ p->drawTextItem( topLeft, ti, textflags );
+ }
+
+ // input method edit area
+ if ( d->imstart < d->imend && (last >= d->imstart && first < d->imend ) ) {
+ TQRect highlight = TQRect( TQPoint( tix + ti.cursorToX( TQMAX( d->imstart - first, 0 ) ), lineRect.top() ),
+ TQPoint( tix + ti.cursorToX( TQMIN( d->imend - first, last - first + 1 ) )-1, lineRect.bottom() ) ).normalize();
+ p->save();
+ p->setClipRect( lineRect & highlight, TQPainter::CoordPainter );
+
+ int h1, s1, v1, h2, s2, v2;
+ cg.color( TQColorGroup::Base ).hsv( &h1, &s1, &v1 );
+ cg.color( TQColorGroup::Background ).hsv( &h2, &s2, &v2 );
+ TQColor imCol;
+ imCol.setHsv( h1, s1, ( v1 + v2 ) / 2 );
+ p->fillRect( highlight, imCol );
+ p->drawTextItem( topLeft, ti, textflags );
+ p->restore();
+ }
+
+ // input method selection
+ if ( d->imselstart < d->imselend && (last >= d->imselstart && first < d->imselend ) ) {
+ TQRect highlight = TQRect( TQPoint( tix + ti.cursorToX( TQMAX( d->imselstart - first, 0 ) ), lineRect.top() ),
+ TQPoint( tix + ti.cursorToX( TQMIN( d->imselend - first, last - first + 1 ) )-1, lineRect.bottom() ) ).normalize();
+ p->save();
+ p->setClipRect( lineRect & highlight, TQPainter::CoordPainter );
+ p->fillRect( highlight, cg.text() );
+ p->setPen( paletteBackgroundColor() );
+ p->drawTextItem( topLeft, ti, textflags );
+ p->restore();
+ }
+ }
+
+ // draw cursor
+ if ( d->cursorVisible && !supressCursor ) {
+ TQPoint from( topLeft.x() + cix, lineRect.top() );
+ TQPoint to = from + TQPoint( 0, lineRect.height() );
+ p->drawLine( from, to );
+ if ( hasRightToLeft ) {
+ to = from + TQPoint( (ci.isRightToLeft()?-2:2), 2 );
+ p->drawLine( from, to );
+ from.ry() += 4;
+ p->drawLine( from, to );
+ }
+ }
+ buffer.end();
+}
+
+
+enum { IdUndo, IdRedo, IdSep1, IdCut, IdCopy, IdPaste, IdClear, IdSep2, IdSelectAll };
+
+
+/*! \reimp */
+void SecTQLineEdit::windowActivationChange( bool b )
+{
+ //### remove me with WHighlightSelection attribute
+ if ( palette().active() != palette().inactive() )
+ update();
+ TQWidget::windowActivationChange( b );
+}
+
+/*! \reimp */
+
+void SecTQLineEdit::setPalette( const TQPalette & p )
+{
+ //### remove me with WHighlightSelection attribute
+ TQWidget::setPalette( p );
+ update();
+}
+
+/*!
+ \obsolete
+ \fn void SecTQLineEdit::repaintArea( int from, int to )
+ Repaints all characters from \a from to \a to. If cursorPos is
+ between from and to, ensures that cursorPos is visible.
+*/
+
+/*! \reimp
+ */
+void SecTQLineEdit::setFont( const TQFont & f )
+{
+ TQWidget::setFont( f );
+ d->updateTextLayout();
+}
+
+
+void SecTQLineEdit::clipboardChanged()
+{
+}
+
+void SecTQLineEditPrivate::init( const SecTQString& txt )
+{
+#ifndef QT_NO_CURSOR
+ q->setCursor( readOnly ? arrowCursor : ibeamCursor );
+#endif
+ q->setFocusPolicy( TQWidget::StrongFocus );
+ q->setInputMethodEnabled( TRUE );
+ // Specifies that this widget can use more, but is able to survive on
+ // less, horizontal space; and is fixed vertically.
+ q->setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
+ q->setBackgroundMode( PaletteBase );
+ q->setKeyCompression( TRUE );
+ q->setMouseTracking( TRUE );
+ q->setAcceptDrops( TRUE );
+ q->setFrame( TRUE );
+ text = txt;
+ updateTextLayout();
+ cursor = text.length();
+}
+
+void SecTQLineEditPrivate::updateTextLayout()
+{
+ // replace all non-printable characters with spaces (to avoid
+ // drawing boxes when using fonts that don't have glyphs for such
+ // characters)
+ const TQString &displayText = q->displayText();
+ TQString str(displayText.unicode(), displayText.length());
+ TQChar* uc = (TQChar*)str.unicode();
+ for (int i = 0; i < (int)str.length(); ++i) {
+ if (! uc[i].isPrint())
+ uc[i] = TQChar(0x0020);
+ }
+ textLayout.setText( str, q->font() );
+ // ### want to do textLayout.setRightToLeft( text.isRightToLeft() );
+ textLayout.beginLayout( TQTextLayout::SingleLine );
+ textLayout.beginLine( INT_MAX );
+ while ( !textLayout.atEnd() )
+ textLayout.addCurrentItem();
+ ascent = 0;
+ textLayout.endLine(0, 0, TQt::AlignLeft, &ascent);
+}
+
+int SecTQLineEditPrivate::xToPos( int x, TQTextItem::CursorPosition betweenOrOn ) const
+{
+ x-= q->contentsRect().x() - hscroll + innerMargin;
+ for ( int i = 0; i < textLayout.numItems(); ++i ) {
+ TQTextItem ti = textLayout.itemAt( i );
+ TQRect tir = ti.rect();
+ if ( x >= tir.left() && x <= tir.right() )
+ return ti.xToCursor( x - tir.x(), betweenOrOn ) + ti.from();
+ }
+ return x < 0 ? 0 : text.length();
+}
+
+
+TQRect SecTQLineEditPrivate::cursorRect() const
+{
+ TQRect cr = q->contentsRect();
+ int cix = cr.x() - hscroll + innerMargin;
+ TQTextItem ci = textLayout.findItem( cursor );
+ if ( ci.isValid() ) {
+ if ( cursor != (int)text.length() && cursor == ci.from() + ci.length()
+ && ci.isRightToLeft() != isRightToLeft() )
+ ci = textLayout.findItem( cursor + 1 );
+ cix += ci.x() + ci.cursorToX( cursor - ci.from() );
+ }
+ int ch = q->fontMetrics().height();
+ return TQRect( cix-4, cr.y() + ( cr.height() - ch + 1) / 2, 8, ch + 1 );
+}
+
+void SecTQLineEditPrivate::updateMicroFocusHint()
+{
+ if ( q->hasFocus() ) {
+ TQRect r = cursorRect();
+ q->setMicroFocusHint( r.x(), r.y(), r.width(), r.height() );
+ }
+}
+
+void SecTQLineEditPrivate::moveCursor( int pos, bool mark )
+{
+ if ( pos != cursor )
+ separate();
+ bool fullUpdate = mark || hasSelectedText();
+ if ( mark ) {
+ int anchor;
+ if ( selend > selstart && cursor == selstart )
+ anchor = selend;
+ else if ( selend > selstart && cursor == selend )
+ anchor = selstart;
+ else
+ anchor = cursor;
+ selstart = TQMIN( anchor, pos );
+ selend = TQMAX( anchor, pos );
+ } else {
+ selstart = selend = 0;
+ }
+ if ( fullUpdate ) {
+ cursor = pos;
+ q->update();
+ } else {
+ setCursorVisible( FALSE );
+ cursor = pos;
+ setCursorVisible( TRUE );
+ }
+ updateMicroFocusHint();
+ if ( mark ) {
+ if( !q->style().styleHint( TQStyle::SH_BlinkCursorWhenTextSelected ))
+ setCursorVisible( FALSE );
+ emit q->selectionChanged();
+ }
+}
+
+void SecTQLineEditPrivate::finishChange( int validateFromState, bool setModified )
+{
+ bool lineDirty = selDirty;
+ if ( textDirty ) {
+ if ( validateFromState >= 0 ) {
+#ifndef SECURE_NO_UNDO
+ undo( validateFromState );
+#endif /* SECURE_NO_UNDO */
+ history.resize( undoState );
+ textDirty = setModified = FALSE;
+ }
+ updateTextLayout();
+ updateMicroFocusHint();
+ lineDirty |= textDirty;
+ if ( setModified )
+ modified = TRUE;
+ if ( textDirty ) {
+ textDirty = FALSE;
+ emit q->textChanged( text );
+ }
+ emit q->textModified( text );
+#if defined(QT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( q, 0, TQAccessible::ValueChanged );
+#endif
+ }
+ if ( selDirty ) {
+ selDirty = FALSE;
+ emit q->selectionChanged();
+ }
+ if ( lineDirty || !setModified )
+ q->update();
+}
+
+void SecTQLineEditPrivate::setText( const SecTQString& txt )
+{
+ deselect();
+ SecTQString oldText = text;
+ text = txt.isEmpty() ? SecTQString ("") : txt.left( maxLength );
+ history.clear();
+ undoState = 0;
+ cursor = text.length();
+ textDirty = 1; // Err on safe side.
+}
+
+
+void SecTQLineEditPrivate::setCursorVisible( bool visible )
+{
+ if ( (bool)cursorVisible == visible )
+ return;
+ if ( cursorTimer )
+ cursorVisible = visible;
+ TQRect r = cursorRect();
+ if ( !q->contentsRect().contains( r ) )
+ q->update();
+ else
+ q->update( r );
+}
+
+#ifndef SECURE_NO_UNDO
+
+void SecTQLineEditPrivate::addCommand( const Command& cmd )
+{
+ if ( separator && undoState && history[undoState-1].type != Separator ) {
+ history.resize( undoState + 2 );
+ history[undoState++] = Command( Separator, 0, 0 );
+ } else {
+ history.resize( undoState + 1);
+ }
+ separator = FALSE;
+ history[ undoState++ ] = cmd;
+}
+#endif /* SECURE_NO_UNDO */
+
+void SecTQLineEditPrivate::insert( const SecTQString& s )
+{
+ int remaining = maxLength - text.length();
+ text.insert( cursor, s.left(remaining) );
+ for ( int i = 0; i < (int) s.left(remaining).length(); ++i )
+ {
+#ifndef SECURE_NO_UNDO
+ addCommand( Command( Insert, cursor, s.at(i) ) );
+#endif /* SECURE_NO_UNDO */
+ cursor++;
+ }
+ textDirty = TRUE;
+}
+
+void SecTQLineEditPrivate::del( bool wasBackspace )
+{
+ if ( cursor < (int) text.length() ) {
+#ifndef SECURE_NO_UNDO
+ addCommand ( Command( (CommandType)(wasBackspace?Remove:Delete), cursor, text.at(cursor) ) );
+#endif /* SECURE_NO_UNDO */
+ text.remove( cursor, 1 );
+ textDirty = TRUE;
+ }
+}
+
+void SecTQLineEditPrivate::removeSelectedText()
+{
+ if ( selstart < selend && selend <= (int) text.length() ) {
+ separate();
+#ifndef SECURE_NO_UNDO
+ int i ;
+ if ( selstart <= cursor && cursor < selend ) {
+ // cursor is within the selection. Split up the commands
+ // to be able to restore the correct cursor position
+ for ( i = cursor; i >= selstart; --i )
+ addCommand ( Command( DeleteSelection, i, text.at(i) ) );
+ for ( i = selend - 1; i > cursor; --i )
+ addCommand ( Command( DeleteSelection, i - cursor + selstart - 1, text.at(i) ) );
+ } else {
+ for ( i = selend-1; i >= selstart; --i )
+ addCommand ( Command( RemoveSelection, i, text.at(i) ) );
+ }
+#endif /* SECURE_NO_UNDO */
+ text.remove( selstart, selend - selstart );
+ if ( cursor > selstart )
+ cursor -= TQMIN( cursor, selend ) - selstart;
+ deselect();
+ textDirty = TRUE;
+ }
+}
+
+#include "secqlineedit.moc"
diff --git a/tqt/secqlineedit.h b/tqt/secqlineedit.h
new file mode 100644
index 0000000..9b396ed
--- /dev/null
+++ b/tqt/secqlineedit.h
@@ -0,0 +1,227 @@
+/* secntqlineedit.h - Secure version of TQLineEdit.
+ Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+ Copyright (C) 2003 g10 Code GmbH
+
+ The license of the original ntqlineedit.h file from which this file
+ is derived can be found below. Modified by Marcus Brinkmann
+ . All modifications are licensed as follows, so
+ that the intersection of the two licenses is then the GNU General
+ Public License version 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA */
+
+#include "secqstring.h"
+
+/* This disables some insecure code. */
+#define SECURE 1
+
+/**********************************************************************
+** $Id$
+**
+** Definition of SecTQLineEdit widget class
+**
+** Created : 941011
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition
+** licenses may use this file in accordance with the TQt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about TQt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for TQPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef SECTQLINEEDIT_H
+#define SECTQLINEEDIT_H
+
+struct SecTQLineEditPrivate;
+
+class TQPopupMenu;
+
+#ifndef QT_H
+#include "ntqframe.h"
+#include "ntqstring.h"
+#endif // QT_H
+
+class TQTextParagraph;
+class TQTextCursor;
+
+class Q_EXPORT SecTQLineEdit : public TQFrame
+{
+ TQ_OBJECT
+ TQ_ENUMS( EchoMode )
+ // TQ_PROPERTY( SecTQString text READ text WRITE setText )
+ TQ_PROPERTY( int maxLength READ maxLength WRITE setMaxLength )
+ TQ_PROPERTY( bool frame READ frame WRITE setFrame )
+ TQ_PROPERTY( EchoMode echoMode READ echoMode WRITE setEchoMode )
+ TQ_PROPERTY( TQString displayText READ displayText )
+ TQ_PROPERTY( int cursorPosition READ cursorPosition WRITE setCursorPosition )
+ TQ_PROPERTY( Alignment alignment READ alignment WRITE setAlignment )
+ TQ_PROPERTY( bool edited READ edited WRITE setEdited DESIGNABLE false )
+ TQ_PROPERTY( bool modified READ isModified )
+ TQ_PROPERTY( bool hasSelectedText READ hasSelectedText )
+ // TQ_PROPERTY( SecTQString markedText READ markedText DESIGNABLE false )
+ // TQ_PROPERTY( SecTQString selectedText READ selectedText )
+ TQ_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly )
+ TQ_PROPERTY( bool undoAvailable READ isUndoAvailable )
+ TQ_PROPERTY( bool redoAvailable READ isRedoAvailable )
+
+public:
+ SecTQLineEdit( TQWidget* parent, const char* name=0 );
+ SecTQLineEdit( const SecTQString &, TQWidget* parent, const char* name=0 );
+ SecTQLineEdit( const SecTQString &, const TQString &, TQWidget* parent, const char* name=0 );
+ ~SecTQLineEdit();
+
+ SecTQString text() const;
+
+ TQString displayText() const;
+
+ int maxLength() const;
+
+ bool frame() const;
+
+ enum EchoMode { Normal, NoEcho, Password };
+ EchoMode echoMode() const;
+
+ bool isReadOnly() const;
+
+ TQSize sizeHint() const;
+ TQSize minimumSizeHint() const;
+
+ int cursorPosition() const;
+ bool validateAndSet( const SecTQString &, int, int, int ); // obsolete
+
+ int alignment() const;
+
+#ifndef QT_NO_COMPAT
+ void cursorLeft( bool mark, int steps = 1 ) { cursorForward( mark, -steps ); }
+ void cursorRight( bool mark, int steps = 1 ) { cursorForward( mark, steps ); }
+#endif
+ void cursorForward( bool mark, int steps = 1 );
+ void cursorBackward( bool mark, int steps = 1 );
+ void cursorWordForward( bool mark );
+ void cursorWordBackward( bool mark );
+ void backspace();
+ void del();
+ void home( bool mark );
+ void end( bool mark );
+
+ bool isModified() const;
+ void clearModified();
+
+ bool edited() const; // obsolete, use isModified()
+ void setEdited( bool ); // obsolete, use clearModified()
+
+ bool hasSelectedText() const;
+ SecTQString selectedText() const;
+ int selectionStart() const;
+
+ bool isUndoAvailable() const;
+ bool isRedoAvailable() const;
+
+#ifndef QT_NO_COMPAT
+ bool hasMarkedText() const { return hasSelectedText(); }
+ SecTQString markedText() const { return selectedText(); }
+#endif
+
+public slots:
+ virtual void setText( const SecTQString &);
+ virtual void selectAll();
+ virtual void deselect();
+ virtual void insert( const SecTQString &);
+ virtual void clear();
+ virtual void undo();
+ virtual void redo();
+ virtual void setMaxLength( int );
+ virtual void setFrame( bool );
+ virtual void setEchoMode( EchoMode );
+ virtual void setReadOnly( bool );
+ virtual void setFont( const TQFont & );
+ virtual void setPalette( const TQPalette & );
+ virtual void setSelection( int, int );
+ virtual void setCursorPosition( int );
+ virtual void setAlignment( int flag );
+#ifndef QT_NO_CLIPBOARD
+ virtual void cut();
+ virtual void copy() const;
+ virtual void paste();
+#endif
+
+signals:
+ void textChanged( const SecTQString &);
+ void textModified( const SecTQString &);
+ void returnPressed();
+ void lostFocus();
+ void selectionChanged();
+
+protected:
+ bool event( TQEvent * );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseDoubleClickEvent( TQMouseEvent * );
+ void keyPressEvent( TQKeyEvent * );
+ void imStartEvent( TQIMEvent * );
+ void imComposeEvent( TQIMEvent * );
+ void imEndEvent( TQIMEvent * );
+ void focusInEvent( TQFocusEvent * );
+ void focusOutEvent( TQFocusEvent * );
+ void resizeEvent( TQResizeEvent * );
+ void drawContents( TQPainter * );
+ void windowActivationChange( bool );
+#ifndef QT_NO_COMPAT
+ void repaintArea( int, int ) { update(); }
+#endif
+
+private slots:
+ void clipboardChanged();
+
+public:
+ TQChar passwordChar() const; // obsolete internal
+
+private:
+ friend struct SecTQLineEditPrivate;
+ SecTQLineEditPrivate * d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ SecTQLineEdit( const SecTQLineEdit & );
+ SecTQLineEdit &operator=( const SecTQLineEdit & );
+#endif
+};
+
+#endif // SECTQLINEEDIT_H
diff --git a/tqt/secqstring.cpp b/tqt/secqstring.cpp
new file mode 100644
index 0000000..4070169
--- /dev/null
+++ b/tqt/secqstring.cpp
@@ -0,0 +1,939 @@
+/* secqstring.cpp - Secure version of TQString.
+ Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+ Copyright (C) 2003 g10 Code GmbH
+
+ The license of the original qstring.cpp file from which this file
+ is derived can be found below. Modified by Marcus Brinkmann
+ . All modifications are licensed as follows, so
+ that the intersection of the two licenses is then the GNU General
+ Public License version 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA */
+
+/****************************************************************************
+** $Id$
+**
+** Implementation of the SecTQString class and related Unicode functions
+**
+** Created : 920722
+**
+** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition
+** licenses may use this file in accordance with the TQt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about TQt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for TQPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+// Don't define it while compiling this module, or USERS of TQt will
+// not be able to link.
+
+#include "secqstring.h"
+
+static uint computeNewMax( uint len )
+{
+ uint newMax = 4;
+ while ( newMax < len )
+ newMax *= 2;
+ // try to save some memory
+ if ( newMax >= 1024 * 1024 && len <= newMax - (newMax >> 2) )
+ newMax -= newMax >> 2;
+ return newMax;
+}
+
+// These macros are used for efficient allocation of TQChar strings.
+// IMPORTANT! If you change these, make sure you also change the
+// "delete unicode" statement in ~SecTQStringData() in SecTQString.h correspondingly!
+
+#define QT_ALLOC_SECTQCHAR_VEC(N) (TQChar*) ::secmem_malloc (sizeof(TQChar) * (N))
+#define QT_DELETE_SECTQCHAR_VEC(P) ::secmem_free (P)
+
+
+/*****************************************************************************
+ SecTQString member functions
+ *****************************************************************************/
+
+/*!
+ \class SecTQString SecTQString.h
+ \reentrant
+
+ \brief The SecTQString class provides an abstraction of Unicode text
+ and the classic C '\0'-terminated char array.
+
+ \ingroup tools
+ \ingroup shared
+ \ingroup text
+ \mainclass
+
+ SecTQString uses \link shclass.html implicit sharing\endlink, which
+ makes it very efficient and easy to use.
+
+ In all of the SecTQString methods that take \c {const char *}
+ parameters, the \c {const char *} is interpreted as a classic
+ C-style '\0'-terminated ASCII string. It is legal for the \c
+ {const char *} parameter to be 0. If the \c {const char *} is not
+ '\0'-terminated, the results are undefined. Functions that copy
+ classic C strings into a SecTQString will not copy the terminating
+ '\0' character. The TQChar array of the SecTQString (as returned by
+ unicode()) is generally not terminated by a '\0'. If you need to
+ pass a SecTQString to a function that requires a C '\0'-terminated
+ string use latin1().
+
+ \keyword SecTQString::null
+ A SecTQString that has not been assigned to anything is \e null, i.e.
+ both the length and data pointer is 0. A SecTQString that references
+ the empty string ("", a single '\0' char) is \e empty. Both null
+ and empty SecTQStrings are legal parameters to the methods. Assigning
+ \c{(const char *) 0} to SecTQString gives a null SecTQString. For
+ convenience, \c SecTQString::null is a null SecTQString. When sorting,
+ empty strings come first, followed by non-empty strings, followed
+ by null strings. We recommend using \c{if ( !str.isNull() )} to
+ check for a non-null string rather than \c{if ( !str )}; see \l
+ operator!() for an explanation.
+
+ Note that if you find that you are mixing usage of \l TQCString,
+ SecTQString, and \l TQByteArray, this causes lots of unnecessary
+ copying and might indicate that the true nature of the data you
+ are dealing with is uncertain. If the data is '\0'-terminated 8-bit
+ data, use \l TQCString; if it is unterminated (i.e. contains '\0's)
+ 8-bit data, use \l TQByteArray; if it is text, use SecTQString.
+
+ Lists of strings are handled by the SecTQStringList class. You can
+ split a string into a list of strings using SecTQStringList::split(),
+ and join a list of strings into a single string with an optional
+ separator using SecTQStringList::join(). You can obtain a list of
+ strings from a string list that contain a particular substring or
+ that match a particular \link ntqregexp.html regex\endlink using
+ SecTQStringList::grep().
+
+ Note for C programmers
+
+ Due to C++'s type system and the fact that SecTQString is implicitly
+ shared, SecTQStrings may be treated like ints or other simple base
+ types. For example:
+
+ \code
+ SecTQString boolToString( bool b )
+ {
+ SecTQString result;
+ if ( b )
+ result = "True";
+ else
+ result = "False";
+ return result;
+ }
+ \endcode
+
+ The variable, result, is an auto variable allocated on the stack.
+ When return is called, because we're returning by value, The copy
+ constructor is called and a copy of the string is returned. (No
+ actual copying takes place thanks to the implicit sharing, see
+ below.)
+
+ Throughout TQt's source code you will encounter SecTQString usages like
+ this:
+ \code
+ SecTQString func( const SecTQString& input )
+ {
+ SecTQString output = input;
+ // process output
+ return output;
+ }
+ \endcode
+
+ The 'copying' of input to output is almost as fast as copying a
+ pointer because behind the scenes copying is achieved by
+ incrementing a reference count. SecTQString (like all TQt's implicitly
+ shared classes) operates on a copy-on-write basis, only copying if
+ an instance is actually changed.
+
+ If you wish to create a deep copy of a SecTQString without losing any
+ Unicode information then you should use TQDeepCopy.
+
+ \sa TQChar TQCString TQByteArray SecTQConstString
+*/
+
+Q_EXPORT SecTQStringData *SecTQString::shared_null = 0;
+QT_STATIC_CONST_IMPL SecTQString SecTQString::null;
+QT_STATIC_CONST_IMPL TQChar TQChar::null;
+QT_STATIC_CONST_IMPL TQChar TQChar::replacement((ushort)0xfffd);
+QT_STATIC_CONST_IMPL TQChar TQChar::byteOrderMark((ushort)0xfeff);
+QT_STATIC_CONST_IMPL TQChar TQChar::byteOrderSwapped((ushort)0xfffe);
+QT_STATIC_CONST_IMPL TQChar TQChar::nbsp((ushort)0x00a0);
+
+SecTQStringData* SecTQString::makeSharedNull()
+{
+ SecTQString::shared_null = new SecTQStringData;
+#if defined( Q_OS_MAC )
+ SecTQString *that = const_cast(&SecTQString::null);
+ that->d = SecTQString::shared_null;
+#endif
+ return SecTQString::shared_null;
+}
+
+/*!
+ \fn SecTQString::SecTQString()
+
+ Constructs a null string, i.e. both the length and data pointer
+ are 0.
+
+ \sa isNull()
+*/
+
+/*!
+ Constructs a string of length one, containing the character \a ch.
+*/
+SecTQString::SecTQString( TQChar ch )
+{
+ d = new SecTQStringData( QT_ALLOC_SECTQCHAR_VEC( 1 ), 1, 1 );
+ d->unicode[0] = ch;
+}
+
+/*!
+ Constructs an implicitly shared copy of \a s. This is very fast
+ since it only involves incrementing a reference count.
+*/
+SecTQString::SecTQString( const SecTQString &s ) :
+ d(s.d)
+{
+ d->ref();
+}
+
+
+SecTQString::SecTQString( int size, bool /*dummy*/ )
+{
+ if ( size ) {
+ int l = size;
+ TQChar* uc = QT_ALLOC_SECTQCHAR_VEC( l );
+ d = new SecTQStringData( uc, 0, l );
+ } else {
+ d = shared_null ? shared_null : (shared_null=new SecTQStringData);
+ d->ref();
+ }
+}
+
+
+/* Deep copy of STR. */
+SecTQString::SecTQString( const TQString &str )
+{
+ const TQChar *unicode = str.unicode ();
+ uint length = str.length ();
+
+ if ( !unicode && !length ) {
+ d = shared_null ? shared_null : makeSharedNull();
+ d->ref();
+ } else {
+ TQChar* uc = QT_ALLOC_SECTQCHAR_VEC( length );
+ if ( unicode )
+ memcpy(uc, unicode, length*sizeof(TQChar));
+ d = new SecTQStringData(uc,unicode ? length : 0,length);
+ }
+}
+
+
+/*!
+ Constructs a string that is a deep copy of the first \a length
+ characters in the TQChar array.
+
+ If \a unicode and \a length are 0, then a null string is created.
+
+ If only \a unicode is 0, the string is empty but has \a length
+ characters of space preallocated: SecTQString expands automatically
+ anyway, but this may speed up some cases a little. We recommend
+ using the plain constructor and setLength() for this purpose since
+ it will result in more readable code.
+
+ \sa isNull() setLength()
+*/
+
+SecTQString::SecTQString( const TQChar* unicode, uint length )
+{
+ if ( !unicode && !length ) {
+ d = shared_null ? shared_null : makeSharedNull();
+ d->ref();
+ } else {
+ TQChar* uc = QT_ALLOC_SECTQCHAR_VEC( length );
+ if ( unicode )
+ memcpy(uc, unicode, length*sizeof(TQChar));
+ d = new SecTQStringData(uc,unicode ? length : 0,length);
+ }
+}
+
+/*!
+ \fn SecTQString::~SecTQString()
+
+ Destroys the string and frees the string's data if this is the
+ last reference to the string.
+*/
+
+
+/*!
+ Deallocates any space reserved solely by this SecTQString.
+
+ If the string does not share its data with another SecTQString
+ instance, nothing happens; otherwise the function creates a new,
+ unique copy of this string. This function is called whenever the
+ string is modified.
+*/
+
+void SecTQString::real_detach()
+{
+ setLength( length() );
+}
+
+void SecTQString::deref()
+{
+ if ( d && d->deref() ) {
+ if ( d != shared_null )
+ delete d;
+ d = 0;
+ }
+}
+
+void SecTQStringData::deleteSelf()
+{
+ delete this;
+}
+
+/*!
+ \fn SecTQString& SecTQString::operator=( TQChar c )
+
+ Sets the string to contain just the single character \a c.
+*/
+
+
+/*!
+ \overload
+
+ Assigns a shallow copy of \a s to this string and returns a
+ reference to this string. This is very fast because the string
+ isn't actually copied.
+*/
+SecTQString &SecTQString::operator=( const SecTQString &s )
+{
+ s.d->ref();
+ deref();
+ d = s.d;
+ return *this;
+}
+
+
+/*!
+ \fn bool SecTQString::isNull() const
+
+ Returns TRUE if the string is null; otherwise returns FALSE. A
+ null string is always empty.
+
+ \code
+ SecTQString a; // a.unicode() == 0, a.length() == 0
+ a.isNull(); // TRUE, because a.unicode() == 0
+ a.isEmpty(); // TRUE, because a.length() == 0
+ \endcode
+
+ \sa isEmpty(), length()
+*/
+
+/*!
+ \fn bool SecTQString::isEmpty() const
+
+ Returns TRUE if the string is empty, i.e. if length() == 0;
+ otherwise returns FALSE. Null strings are also empty.
+
+ \code
+ SecTQString a( "" );
+ a.isEmpty(); // TRUE
+ a.isNull(); // FALSE
+
+ SecTQString b;
+ b.isEmpty(); // TRUE
+ b.isNull(); // TRUE
+ \endcode
+
+ \sa isNull(), length()
+*/
+
+/*!
+ \fn uint SecTQString::length() const
+
+ Returns the length of the string.
+
+ Null strings and empty strings have zero length.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ If \a newLen is less than the length of the string, then the
+ string is truncated at position \a newLen. Otherwise nothing
+ happens.
+
+ \code
+ SecTQString s = "truncate me";
+ s.truncate( 5 ); // s == "trunc"
+ \endcode
+
+ \sa setLength()
+*/
+
+void SecTQString::truncate( uint newLen )
+{
+ if ( newLen < d->len )
+ setLength( newLen );
+}
+
+/*!
+ Ensures that at least \a newLen characters are allocated to the
+ string, and sets the length of the string to \a newLen. Any new
+ space allocated contains arbitrary data.
+
+ \sa reserve(), truncate()
+*/
+void SecTQString::setLength( uint newLen )
+{
+ if ( d->count != 1 || newLen > d->maxl ||
+ ( newLen * 4 < d->maxl && d->maxl > 4 ) ) {
+ // detach, grow or shrink
+ uint newMax = computeNewMax( newLen );
+ TQChar* nd = QT_ALLOC_SECTQCHAR_VEC( newMax );
+ if ( nd ) {
+ uint len = TQMIN( d->len, newLen );
+ memcpy( nd, d->unicode, sizeof(TQChar) * len );
+ deref();
+ d = new SecTQStringData( nd, newLen, newMax );
+ }
+ } else {
+ d->len = newLen;
+ }
+}
+
+
+/*!
+ \internal
+
+ Like setLength, but doesn't shrink the allocated memory.
+*/
+void SecTQString::grow( uint newLen )
+{
+ if ( d->count != 1 || newLen > d->maxl ) {
+ setLength( newLen );
+ } else {
+ d->len = newLen;
+ }
+}
+
+
+/*!
+ Returns a substring that contains the \a len leftmost characters
+ of the string.
+
+ The whole string is returned if \a len exceeds the length of the
+ string.
+
+ \code
+ SecTQString s = "Pineapple";
+ SecTQString t = s.left( 4 ); // t == "Pine"
+ \endcode
+
+ \sa right(), mid(), isEmpty()
+*/
+
+SecTQString SecTQString::left( uint len ) const
+{
+ if ( isEmpty() ) {
+ return SecTQString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return SecTQString ("");
+ } else if ( len >= length() ) {
+ return *this;
+ } else {
+ SecTQString s( len, TRUE );
+ memcpy( s.d->unicode, d->unicode, len * sizeof(TQChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a string that contains the \a len rightmost characters of
+ the string.
+
+ If \a len is greater than the length of the string then the whole
+ string is returned.
+
+ \code
+ SecTQString string( "Pineapple" );
+ SecTQString t = string.right( 5 ); // t == "apple"
+ \endcode
+
+ \sa left(), mid(), isEmpty()
+*/
+
+SecTQString SecTQString::right( uint len ) const
+{
+ if ( isEmpty() ) {
+ return SecTQString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return SecTQString ("");
+ } else {
+ uint l = length();
+ if ( len >= l )
+ return *this;
+ SecTQString s( len, TRUE );
+ memcpy( s.d->unicode, d->unicode+(l-len), len*sizeof(TQChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a string that contains the \a len characters of this
+ string, starting at position \a index.
+
+ Returns a null string if the string is empty or \a index is out of
+ range. Returns the whole string from \a index if \a index + \a len
+ exceeds the length of the string.
+
+ \code
+ SecTQString s( "Five pineapples" );
+ SecTQString t = s.mid( 5, 4 ); // t == "pine"
+ \endcode
+
+ \sa left(), right()
+*/
+
+SecTQString SecTQString::mid( uint index, uint len ) const
+{
+ uint slen = length();
+ if ( isEmpty() || index >= slen ) {
+ return SecTQString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return SecTQString ("");
+ } else {
+ if ( len > slen-index )
+ len = slen - index;
+ if ( index == 0 && len == slen )
+ return *this;
+ register const TQChar *p = unicode()+index;
+ SecTQString s( len, TRUE );
+ memcpy( s.d->unicode, p, len * sizeof(TQChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Inserts \a s into the string at position \a index.
+
+ If \a index is beyond the end of the string, the string is
+ extended with spaces to length \a index and \a s is then appended
+ and returns a reference to the string.
+
+ \code
+ SecTQString string( "I like fish" );
+ str = string.insert( 2, "don't " );
+ // str == "I don't like fish"
+ \endcode
+
+ \sa remove(), replace()
+*/
+
+SecTQString &SecTQString::insert( uint index, const SecTQString &s )
+{
+ // the sub function takes care of &s == this case.
+ return insert( index, s.unicode(), s.length() );
+}
+
+/*!
+ \overload
+
+ Inserts the first \a len characters in \a s into the string at
+ position \a index and returns a reference to the string.
+*/
+
+SecTQString &SecTQString::insert( uint index, const TQChar* s, uint len )
+{
+ if ( len == 0 )
+ return *this;
+ uint olen = length();
+ int nlen = olen + len;
+
+ if ( s >= d->unicode && (uint)(s - d->unicode) < d->maxl ) {
+ // Part of me - take a copy.
+ TQChar *tmp = QT_ALLOC_SECTQCHAR_VEC( len );
+ memcpy(tmp,s,len*sizeof(TQChar));
+ insert(index,tmp,len);
+ QT_DELETE_SECTQCHAR_VEC( tmp );
+ return *this;
+ }
+
+ if ( index >= olen ) { // insert after end of string
+ grow( len + index );
+ int n = index - olen;
+ TQChar* uc = d->unicode+olen;
+ while (n--)
+ *uc++ = ' ';
+ memcpy( d->unicode+index, s, sizeof(TQChar)*len );
+ } else { // normal insert
+ grow( nlen );
+ memmove( d->unicode + index + len, unicode() + index,
+ sizeof(TQChar) * (olen - index) );
+ memcpy( d->unicode + index, s, sizeof(TQChar) * len );
+ }
+ return *this;
+}
+
+/*!
+ Removes \a len characters from the string starting at position \a
+ index, and returns a reference to the string.
+
+ If \a index is beyond the length of the string, nothing happens.
+ If \a index is within the string, but \a index + \a len is beyond
+ the end of the string, the string is truncated at position \a
+ index.
+
+ \code
+ SecTQString string( "Montreal" );
+ string.remove( 1, 4 ); // string == "Meal"
+ \endcode
+
+ \sa insert(), replace()
+*/
+
+SecTQString &SecTQString::remove( uint index, uint len )
+{
+ uint olen = length();
+ if ( index >= olen ) {
+ // range problems
+ } else if ( index + len >= olen ) { // index ok
+ setLength( index );
+ } else if ( len != 0 ) {
+ real_detach();
+ memmove( d->unicode+index, d->unicode+index+len,
+ sizeof(TQChar)*(olen-index-len) );
+ setLength( olen-len );
+ }
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Replaces \a len characters with \a slen characters of TQChar data
+ from \a s, starting at position \a index, and returns a reference
+ to the string.
+
+ \sa insert(), remove()
+*/
+
+SecTQString &SecTQString::replace( uint index, uint len, const TQChar* s, uint slen )
+{
+ real_detach();
+ if ( len == slen && index + len <= length() ) {
+ // Optimized common case: replace without size change
+ memcpy( d->unicode+index, s, len * sizeof(TQChar) );
+ } else if ( s >= d->unicode && (uint)(s - d->unicode) < d->maxl ) {
+ // Part of me - take a copy.
+ TQChar *tmp = QT_ALLOC_SECTQCHAR_VEC( slen );
+ memcpy( tmp, s, slen * sizeof(TQChar) );
+ replace( index, len, tmp, slen );
+ QT_DELETE_SECTQCHAR_VEC( tmp );
+ } else {
+ remove( index, len );
+ insert( index, s, slen );
+ }
+ return *this;
+}
+
+
+/*!
+ Replaces \a len characters from the string with \a s, starting at
+ position \a index, and returns a reference to the string.
+
+ If \a index is beyond the length of the string, nothing is deleted
+ and \a s is appended at the end of the string. If \a index is
+ valid, but \a index + \a len is beyond the end of the string,
+ the string is truncated at position \a index, then \a s is
+ appended at the end.
+
+ \code
+ TQString string( "Say yes!" );
+ string = string.replace( 4, 3, "NO" );
+ // string == "Say NO!"
+ \endcode
+
+ \sa insert(), remove()
+*/
+
+SecTQString &SecTQString::replace( uint index, uint len, const SecTQString &s )
+{
+ return replace( index, len, s.unicode(), s.length() );
+}
+
+
+/*!
+ Appends \a str to the string and returns a reference to the string.
+*/
+SecTQString& SecTQString::operator+=( const SecTQString &str )
+{
+ uint len1 = length();
+ uint len2 = str.length();
+ if ( len2 ) {
+ if ( isEmpty() ) {
+ operator=( str );
+ } else {
+ grow( len1+len2 );
+ memcpy( d->unicode+len1, str.unicode(), sizeof(TQChar)*len2 );
+ }
+ } else if ( isNull() && !str.isNull() ) { // ## just for 1.x compat:
+ *this = SecTQString ("");
+ }
+ return *this;
+}
+
+
+/*!
+ Returns the string encoded in UTF-8 format.
+
+ See TQTextCodec for more diverse coding/decoding of Unicode strings.
+
+ \sa fromUtf8(), ascii(), latin1(), local8Bit()
+*/
+uchar *SecTQString::utf8() const
+{
+ int l = length();
+ int rlen = l*3+1;
+ uchar* rstr = (uchar*) ::secmem_malloc (rlen);
+ uchar* cursor = rstr;
+ const TQChar *ch = d->unicode;
+ for (int i=0; i < l; i++) {
+ uint u = ch->unicode();
+ if ( u < 0x80 ) {
+ *cursor++ = (uchar)u;
+ } else {
+ if ( u < 0x0800 ) {
+ *cursor++ = 0xc0 | ((uchar) (u >> 6));
+ } else {
+ if (u >= 0xd800 && u < 0xdc00 && i < l-1) {
+ unsigned short low = ch[1].unicode();
+ if (low >= 0xdc00 && low < 0xe000) {
+ ++ch;
+ ++i;
+ u = (u - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ }
+ }
+ if (u > 0xffff) {
+ // if people are working in utf8, but strings are encoded in eg. latin1, the resulting
+ // name might be invalid utf8. This and the corresponding code in fromUtf8 takes care
+ // we can handle this without loosing information. This can happen with latin filenames
+ // and a utf8 locale under Unix.
+ if (u > 0x10fe00 && u < 0x10ff00) {
+ *cursor++ = (u - 0x10fe00);
+ ++ch;
+ continue;
+ } else {
+ *cursor++ = 0xf0 | ((uchar) (u >> 18));
+ *cursor++ = 0x80 | ( ((uchar) (u >> 12)) & 0x3f);
+ }
+ } else {
+ *cursor++ = 0xe0 | ((uchar) (u >> 12));
+ }
+ *cursor++ = 0x80 | ( ((uchar) (u >> 6)) & 0x3f);
+ }
+ *cursor++ = 0x80 | ((uchar) (u&0x3f));
+ }
+ ++ch;
+ }
+ /* FIXME: secmem_realloc doesn't release extra memory. */
+ *cursor = '\0';
+ return rstr;
+}
+
+
+/*!
+ \fn TQChar SecTQString::at( uint ) const
+
+ Returns the character at index \a i, or 0 if \a i is beyond the
+ length of the string.
+
+ \code
+ const SecTQString string( "abcdefgh" );
+ TQChar ch = string.at( 4 );
+ // ch == 'e'
+ \endcode
+
+ If the SecTQString is not const (i.e. const SecTQString) or const& (i.e.
+ const SecTQString &), then the non-const overload of at() will be used
+ instead.
+*/
+
+/*!
+ \fn TQChar SecTQString::constref(uint i) const
+
+ Returns the TQChar at index \a i by value.
+
+ Equivalent to at(\a i).
+
+ \sa ref()
+*/
+
+/*!
+ \fn TQChar& SecTQString::ref(uint i)
+
+ Returns the TQChar at index \a i by reference, expanding the string
+ with TQChar::null if necessary. The resulting reference can be
+ assigned to, or otherwise used immediately, but becomes invalid
+ once furher modifications are made to the string.
+
+ \code
+ SecTQString string("ABCDEF");
+ TQChar ch = string.ref( 3 ); // ch == 'D'
+ \endcode
+
+ \sa constref()
+*/
+
+/*!
+ \fn TQChar SecTQString::operator[]( int ) const
+
+ Returns the character at index \a i, or TQChar::null if \a i is
+ beyond the length of the string.
+
+ If the SecTQString is not const (i.e., const SecTQString) or const\&
+ (i.e., const SecTQString\&), then the non-const overload of operator[]
+ will be used instead.
+*/
+
+/*!
+ \fn TQCharRef SecTQString::operator[]( int )
+
+ \overload
+
+ The function returns a reference to the character at index \a i.
+ The resulting reference can then be assigned to, or used
+ immediately, but it will become invalid once further modifications
+ are made to the original string.
+
+ If \a i is beyond the length of the string then the string is
+ expanded with TQChar::nulls, so that the TQCharRef references a
+ valid (null) character in the string.
+
+ The TQCharRef internal class can be used much like a constant
+ TQChar, but if you assign to it, you change the original string
+ (which will detach itself because of SecTQString's copy-on-write
+ semantics). You will get compilation errors if you try to use the
+ result as anything but a TQChar.
+*/
+
+/*!
+ \fn TQCharRef SecTQString::at( uint i )
+
+ \overload
+
+ The function returns a reference to the character at index \a i.
+ The resulting reference can then be assigned to, or used
+ immediately, but it will become invalid once further modifications
+ are made to the original string.
+
+ If \a i is beyond the length of the string then the string is
+ expanded with TQChar::null.
+*/
+
+/*
+ Internal chunk of code to handle the
+ uncommon cases of at() above.
+*/
+void SecTQString::subat( uint i )
+{
+ uint olen = d->len;
+ if ( i >= olen ) {
+ setLength( i+1 ); // i is index; i+1 is needed length
+ for ( uint j=olen; j<=i; j++ )
+ d->unicode[j] = TQChar::null;
+ } else {
+ // Just be sure to detach
+ real_detach();
+ }
+}
+
+
+/*! \internal
+ */
+bool SecTQString::isRightToLeft() const
+{
+ int len = length();
+ TQChar *p = d->unicode;
+ while ( len-- ) {
+ switch( (*p).direction () )
+ {
+ case TQChar::DirL:
+ case TQChar::DirLRO:
+ case TQChar::DirLRE:
+ return FALSE;
+ case TQChar::DirR:
+ case TQChar::DirAL:
+ case TQChar::DirRLO:
+ case TQChar::DirRLE:
+ return TRUE;
+ default:
+ break;
+ }
+ ++p;
+ }
+ return FALSE;
+}
+
+
+/*!
+ \fn const SecTQString operator+( const SecTQString &s1, const SecTQString &s2 )
+
+ \relates SecTQString
+
+ Returns a string which is the result of concatenating the string
+ \a s1 and the string \a s2.
+
+ Equivalent to \a {s1}.append(\a s2).
+*/
+
+
+/*! \fn void SecTQString::detach()
+ If the string does not share its data with another SecTQString instance,
+ nothing happens; otherwise the function creates a new, unique copy of
+ this string. This function is called whenever the string is modified. The
+ implicit sharing mechanism is implemented this way.
+*/
diff --git a/tqt/secqstring.h b/tqt/secqstring.h
new file mode 100644
index 0000000..fa309df
--- /dev/null
+++ b/tqt/secqstring.h
@@ -0,0 +1,307 @@
+/* secntqstring.h - Secure version of TQString.
+ Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+ Copyright (C) 2003 g10 Code GmbH
+
+ The license of the original ntqstring.h file from which this file is
+ derived can be found below. Modified by Marcus Brinkmann
+ . All modifications are licensed as follows, so
+ that the intersection of the two licenses is then the GNU General
+ Public License version 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA */
+
+/****************************************************************************
+** $Id$
+**
+** Definition of the SecTQString class, and related Unicode functions.
+**
+** Created : 920609
+**
+** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition
+** licenses may use this file in accordance with the TQt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about TQt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for TQPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef SECTQSTRING_H
+#define SECTQSTRING_H
+
+extern "C"
+{
+#include "memory.h"
+}
+
+/* We need the original qchar and qstring for transparent conversion
+ from TQChar to TQChar and TQString to SecTQString (but not the other
+ way round). */
+#include
+
+#ifndef QT_H
+#include "ntqcstring.h"
+#endif // QT_H
+
+
+/*****************************************************************************
+ SecTQString class
+ *****************************************************************************/
+
+class SecTQString;
+class SecTQCharRef;
+template class TQDeepCopy;
+#include
+// internal
+struct Q_EXPORT SecTQStringData : public TQShared {
+ SecTQStringData() :
+ TQShared(), unicode(0), len(0), maxl(0) { ref(); }
+ SecTQStringData(TQChar *u, uint l, uint m) :
+ TQShared(), unicode(u), len(l), maxl(m) { }
+ ~SecTQStringData() { if ( unicode ) ::secmem_free ((char*) unicode); }
+
+ void deleteSelf();
+ TQChar *unicode;
+#ifdef Q_OS_MAC9
+ uint len;
+#else
+ uint len : 30;
+#endif
+#ifdef Q_OS_MAC9
+ uint maxl;
+#else
+ uint maxl : 30;
+#endif
+};
+
+
+class Q_EXPORT SecTQString
+{
+public:
+ SecTQString(); // make null string
+ SecTQString( TQChar ); // one-char string
+ SecTQString( const SecTQString & ); // impl-shared copy
+ /* We need a way to convert a TQString to a SecTQString ("importing"
+ it). Having no conversion for the other way prevents
+ accidential bugs where the secure string is copied to insecure
+ memory. */
+ SecTQString( const TQString & ); // deep copy
+ SecTQString( const TQChar* unicode, uint length ); // deep copy
+ ~SecTQString();
+
+ SecTQString &operator=( const SecTQString & ); // impl-shared copy
+
+ QT_STATIC_CONST SecTQString null;
+
+ bool isNull() const;
+ bool isEmpty() const;
+ uint length() const;
+ void truncate( uint pos );
+
+ SecTQString left( uint len ) const;
+ SecTQString right( uint len ) const;
+ SecTQString mid( uint index, uint len=0xffffffff) const;
+
+
+ SecTQString &insert( uint index, const SecTQString & );
+ SecTQString &insert( uint index, const TQChar*, uint len );
+ SecTQString &remove( uint index, uint len );
+ SecTQString &replace( uint index, uint len, const SecTQString & );
+ SecTQString &replace( uint index, uint len, const TQChar*, uint clen );
+
+ SecTQString &operator+=( const SecTQString &str );
+
+ TQChar at( uint i ) const
+ { return i < d->len ? d->unicode[i] : TQChar::null; }
+ TQChar operator[]( int i ) const { return at((uint)i); }
+ SecTQCharRef at( uint i );
+ SecTQCharRef operator[]( int i );
+
+ TQChar constref(uint i) const
+ { return at(i); }
+ TQChar& ref(uint i)
+ { // Optimized for easy-inlining by simple compilers.
+ if ( d->count != 1 || i >= d->len )
+ subat( i );
+ return d->unicode[i];
+ }
+
+ const TQChar* unicode() const { return d->unicode; }
+
+ uchar* utf8() const;
+
+ void setLength( uint newLength );
+
+ bool isRightToLeft() const;
+
+
+private:
+ SecTQString( int size, bool /* dummy */ ); // allocate size incl. \0
+
+ void deref();
+ void real_detach();
+ void subat( uint );
+
+ void grow( uint newLength );
+
+ SecTQStringData *d;
+ static SecTQStringData* shared_null;
+ static SecTQStringData* makeSharedNull();
+
+ friend class SecTQConstString;
+ friend class TQTextStream;
+ SecTQString( SecTQStringData* dd, bool /* dummy */ ) : d(dd) { }
+
+ // needed for TQDeepCopy
+ void detach();
+ friend class TQDeepCopy;
+};
+
+class Q_EXPORT SecTQCharRef {
+ friend class SecTQString;
+ SecTQString& s;
+ uint p;
+ SecTQCharRef(SecTQString* str, uint pos) : s(*str), p(pos) { }
+
+public:
+ // most TQChar operations repeated here
+
+ // all this is not documented: We just say "like TQChar" and let it be.
+#ifndef Q_QDOC
+ ushort unicode() const { return s.constref(p).unicode(); }
+
+ // An operator= for each TQChar cast constructors
+ SecTQCharRef operator=(char c ) { s.ref(p)=c; return *this; }
+ SecTQCharRef operator=(uchar c ) { s.ref(p)=c; return *this; }
+ SecTQCharRef operator=(TQChar c ) { s.ref(p)=c; return *this; }
+ SecTQCharRef operator=(const SecTQCharRef& c ) { s.ref(p)=c.unicode(); return *this; }
+ SecTQCharRef operator=(ushort rc ) { s.ref(p)=rc; return *this; }
+ SecTQCharRef operator=(short rc ) { s.ref(p)=rc; return *this; }
+ SecTQCharRef operator=(uint rc ) { s.ref(p)=rc; return *this; }
+ SecTQCharRef operator=(int rc ) { s.ref(p)=rc; return *this; }
+
+ operator TQChar () const { return s.constref(p); }
+
+ // each function...
+ bool isNull() const { return unicode()==0; }
+ bool isPrint() const { return s.constref(p).isPrint(); }
+ bool isPunct() const { return s.constref(p).isPunct(); }
+ bool isSpace() const { return s.constref(p).isSpace(); }
+ bool isMark() const { return s.constref(p).isMark(); }
+ bool isLetter() const { return s.constref(p).isLetter(); }
+ bool isNumber() const { return s.constref(p).isNumber(); }
+ bool isLetterOrNumber() { return s.constref(p).isLetterOrNumber(); }
+ bool isDigit() const { return s.constref(p).isDigit(); }
+
+ int digitValue() const { return s.constref(p).digitValue(); }
+ TQChar lower() const { return s.constref(p).lower(); }
+ TQChar upper() const { return s.constref(p).upper(); }
+
+ TQChar::Category category() const { return s.constref(p).category(); }
+ TQChar::Direction direction() const { return s.constref(p).direction(); }
+ TQChar::Joining joining() const { return s.constref(p).joining(); }
+ bool mirrored() const { return s.constref(p).mirrored(); }
+ TQChar mirroredChar() const { return s.constref(p).mirroredChar(); }
+ // const SecTQString &decomposition() const { return s.constref(p).decomposition(); }
+ TQChar::Decomposition decompositionTag() const { return s.constref(p).decompositionTag(); }
+ unsigned char combiningClass() const { return s.constref(p).combiningClass(); }
+
+ // Not the non-const ones of these.
+ uchar cell() const { return s.constref(p).cell(); }
+ uchar row() const { return s.constref(p).row(); }
+#endif
+};
+
+inline SecTQCharRef SecTQString::at( uint i ) { return SecTQCharRef(this,i); }
+inline SecTQCharRef SecTQString::operator[]( int i ) { return at((uint)i); }
+
+class Q_EXPORT SecTQConstString : private SecTQString {
+public:
+ SecTQConstString( const TQChar* unicode, uint length );
+ ~SecTQConstString();
+ const SecTQString& string() const { return *this; }
+};
+
+
+/*****************************************************************************
+ SecTQString inline functions
+ *****************************************************************************/
+
+// These two move code into makeSharedNull() and deletesData()
+// to improve cache-coherence (and reduce code bloat), while
+// keeping the common cases fast.
+//
+// No safe way to pre-init shared_null on ALL compilers/linkers.
+inline SecTQString::SecTQString() :
+ d(shared_null ? shared_null : makeSharedNull())
+{
+ d->ref();
+}
+//
+inline SecTQString::~SecTQString()
+{
+ if ( d->deref() ) {
+ if ( d != shared_null )
+ d->deleteSelf();
+ }
+}
+
+// needed for TQDeepCopy
+inline void SecTQString::detach()
+{ real_detach(); }
+
+inline bool SecTQString::isNull() const
+{ return unicode() == 0; }
+
+inline uint SecTQString::length() const
+{ return d->len; }
+
+inline bool SecTQString::isEmpty() const
+{ return length() == 0; }
+
+/*****************************************************************************
+ SecTQString non-member operators
+ *****************************************************************************/
+
+Q_EXPORT inline const SecTQString operator+( const SecTQString &s1, const SecTQString &s2 )
+{
+ SecTQString tmp( s1 );
+ tmp += s2;
+ return tmp;
+}
+
+#endif // SECTQSTRING_H