tqt: Add a TQt-based pinentry.
authorDamien Goutte-Gattat <dgouttegattat@incenp.org>
Tue, 21 Nov 2017 22:46:12 +0000 (22:46 +0000)
committerDamien Goutte-Gattat <dgouttegattat@incenp.org>
Wed, 22 Nov 2017 11:31:00 +0000 (11:31 +0000)
* NEWS: Update.
* Makefile.am: Add new tqt subdirectory.
* configure.ac: Add --enable-pinentry-tqt option.
* tqt/Makefile.am: New file.
* tqt/main.cpp: New file.
* tqt/pinentrydialog.cpp: New file.
* tqt/pinentrydialog.h: New file.
* tqt/secqinternal.cpp: New file.
* tqt/secqinternal_p.h: New file.
* tqt/secqlineedit.cpp: New file.
* tqt/secqlineedit.h: New file.
* tqt/secqstring.cpp: New file.
* tqt/secqstring.h: New file.
--

This is a port of the old Qt3 code to TQt3, part of the
Trinity Desktop (TDE) project.

Co-authored-by: "deloptes" <deloptes@gmail.com>
Signed-off-by: Damien Goutte-Gattat <dgouttegattat@incenp.org>
14 files changed:
.gitignore
Makefile.am
NEWS
configure.ac
tqt/Makefile.am [new file with mode: 0644]
tqt/main.cpp [new file with mode: 0644]
tqt/pinentrydialog.cpp [new file with mode: 0644]
tqt/pinentrydialog.h [new file with mode: 0644]
tqt/secqinternal.cpp [new file with mode: 0644]
tqt/secqinternal_p.h [new file with mode: 0644]
tqt/secqlineedit.cpp [new file with mode: 0644]
tqt/secqlineedit.h [new file with mode: 0644]
tqt/secqstring.cpp [new file with mode: 0644]
tqt/secqstring.h [new file with mode: 0644]

index 8d709c1..cfe59ac 100644 (file)
@@ -30,6 +30,8 @@ pinentry/Makefile.in
 pinentry/Makefile
 qt/Makefile.in
 qt/Makefile
+tqt/Makefile.in
+tqt/Makefile
 secmem/Makefile.in
 secmem/Makefile
 w32/Makefile.in
index e11b009..8c8b8e5 100644 (file)
@@ -64,6 +64,12 @@ else
 pinentry_qt =
 endif
 
+if BUILD_PINENTRY_TQT
+pinentry_tqt = tqt
+else
+pinentry_tqt =
+endif
+
 if BUILD_PINENTRY_W32
 pinentry_w32 = w32
 else
@@ -78,7 +84,8 @@ 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:
diff --git a/NEWS b/NEWS
index 5534d4d..b1976c3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ 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
index 3de0882..86cf98b 100644 (file)
@@ -536,6 +536,42 @@ if test "$pinentry_qt" = "yes"; then
   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.
@@ -606,7 +642,11 @@ 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
@@ -685,6 +725,7 @@ emacs/Makefile
 gtk+-2/Makefile
 gnome3/Makefile
 qt/Makefile
+tqt/Makefile
 w32/Makefile
 fltk/Makefile
 doc/Makefile
@@ -706,6 +747,7 @@ AC_MSG_NOTICE([
        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
 
diff --git a/tqt/Makefile.am b/tqt/Makefile.am
new file mode 100644 (file)
index 0000000..9171b0f
--- /dev/null
@@ -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 (file)
index 0000000..3f7efb4
--- /dev/null
@@ -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 <steffen@klaralvdalens-datakonsult.se>.
+   Modified by Marcus Brinkmann <marcus@g10code.de>.
+
+   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 <stdlib.h>
+#include <errno.h>
+
+#include <ntqapplication.h>
+#include <ntqwidget.h>
+#include <ntqmessagebox.h>
+#include "secqstring.h"
+
+#include "pinentrydialog.h"
+
+#include "pinentry.h"
+
+#ifdef FALLBACK_CURSES
+#include <pinentry-curses.h>
+#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 (file)
index 0000000..2eae54d
--- /dev/null
@@ -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 <steffen@klaralvdalens-datakonsult.se>.
+
+   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 <ntqlayout.h>
+#include <ntqpushbutton.h>
+#include <ntqlabel.h>
+#include <ntqmessagebox.h>
+#include <ntqprogressbar.h>
+#include <ntqtooltip.h>
+
+#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 (file)
index 0000000..4d69a28
--- /dev/null
@@ -0,0 +1,92 @@
+/* pinentrydialog.h - A secure KDE dialog for PIN entry.
+   Copyright (C) 2002 Klarälvdalens Datakonsult AB
+   Written by Steffen Hansen <steffen@klaralvdalens-datakonsult.se>.
+
+   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 <ntqdialog.h>
+#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 (file)
index 0000000..a1113a8
--- /dev/null
@@ -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<TQPixmap> 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<SecTQSharedDoubleBufferCleaner> 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 (file)
index 0000000..35d2b0d
--- /dev/null
@@ -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 (file)
index 0000000..ecf6010
--- /dev/null
@@ -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
+   <marcus@g10code.de>.  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<Command> 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.
+
+    <img src=qlined-m.png> <img src=qlined-w.png>
+
+    \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 (file)
index 0000000..9b396ed
--- /dev/null
@@ -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
+   <marcus@g10code.de>.  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 (file)
index 0000000..4070169
--- /dev/null
@@ -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
+   <marcus@g10code.de>.  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().
+
+    <b>Note for C programmers</b>
+
+    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 *>(&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 (file)
index 0000000..fa309df
--- /dev/null
@@ -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
+   <marcus@g10code.de>.  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 <ntqstring.h>
+
+#ifndef QT_H
+#include "ntqcstring.h"
+#endif // QT_H
+
+
+/*****************************************************************************
+  SecTQString class
+ *****************************************************************************/
+
+class SecTQString;
+class SecTQCharRef;
+template <class T> class TQDeepCopy;
+#include <stdio.h>
+// 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<SecTQString>;
+};
+
+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