[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    Asynch wallet reading in KHTML
From:       George Staikos <staikos () kde ! org>
Date:       2004-11-04 12:16:22
Message-ID: 200411040716.22138.staikos () kde ! org
[Download RAW message or body]

This patch makes wallet reading in KHTML asynchronous.  It also adds the 
instrumentation for asynchronous writes, but HTMLFormElementImpl needs more 
work and a bit of thinking before that can be implemented.  Is it work 
committing this as is for now?  The two can coexist peacefully.

-- 
George Staikos
KDE Developer				http://www.kde.org/
Staikos Computing Services Inc.		http://www.staikos.net/

["asyncwalletread.patch" (text/x-diff)]

Index: khtml_part.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_part.cpp,v
retrieving revision 1.1041
diff -u -3 -p -r1.1041 khtml_part.cpp
--- khtml_part.cpp	2 Nov 2004 23:07:49 -0000	1.1041
+++ khtml_part.cpp	4 Nov 2004 12:07:08 -0000
@@ -6631,14 +6631,116 @@ void KHTMLPart::restoreScrollPosition()
   }
 }
 
-KWallet::Wallet* KHTMLPart::wallet()
+
+void KHTMLPart::openWallet(DOM::HTMLFormElementImpl *form)
 {
-  // ### close wallet after a certain timeout period automatically
-  //      No - KWallet already does this based on user preferences. (GS)
-  // ### close wallet after screensaver was enabled
-  //      No - KWalletD should do this, if anything. (GS)
+  KHTMLPart *p;
+
+  for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
+  }
+
+  if (p) {
+    p->openWallet(form);
+    return;
+  }
+
+  if (d->m_wallet) {
+    if (d->m_wallet->isOpen()) {
+      form->walletOpened(d->m_wallet);
+      return;
+    }
+    delete d->m_wallet;
+    d->m_wallet = 0L;
+    d->m_bWalletOpened = false;
+  }
 
-  KHTMLPart* p;
+  if (!d->m_wq) {
+    KWallet::Wallet *wallet = \
KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? \
widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous); +    d->m_wq \
= new KHTMLWalletQueue(this); +    d->m_wq->wallet = wallet;
+    connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
+    connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, \
SLOT(walletOpened(KWallet::Wallet*))); +  }
+  assert(form);
+  d->m_wq->callers.append(KHTMLWalletQueue::Caller(form, form->getDocument()));
+}
+
+
+void KHTMLPart::saveToWallet(const QString& key, const QMap<QString,QString>& data)
+{
+  KHTMLPart *p;
+
+  for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
+  }
+
+  if (p) {
+    p->saveToWallet(key, data);
+    return;
+  }
+
+  if (d->m_wallet) {
+    if (d->m_wallet->isOpen()) {
+      d->m_wallet->setFolder(KWallet::Wallet::FormDataFolder());
+      d->m_wallet->writeMap(key, data);
+      return;
+    }
+    delete d->m_wallet;
+    d->m_wallet = 0L;
+    d->m_bWalletOpened = false;
+  }
+
+  if (!d->m_wq) {
+    KWallet::Wallet *wallet = \
KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? \
widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous); +    d->m_wq \
= new KHTMLWalletQueue(this); +    d->m_wq->wallet = wallet;
+    connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
+    connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, \
SLOT(walletOpened(KWallet::Wallet*))); +  }
+  d->m_wq->savers.append(qMakePair(key, data));
+}
+
+
+void KHTMLPart::dequeueWallet(DOM::HTMLFormElementImpl *form) {
+  if (d->m_wq) {
+    d->m_wq->callers.remove(KHTMLWalletQueue::Caller(form, form->getDocument()));
+  }
+}
+
+
+void KHTMLPart::walletOpened(KWallet::Wallet *wallet) {
+  assert(!d->m_wallet);
+
+  d->m_wq->deleteLater(); // safe?
+  d->m_wq = 0L;
+
+  if (!wallet) {
+    if (d->m_statusBarWalletLabel) {
+      d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
+      delete d->m_statusBarWalletLabel;
+      d->m_statusBarWalletLabel = 0L;
+    }
+    d->m_bWalletOpened = false;
+    return;
+  }
+
+  d->m_wallet = wallet;
+  d->m_bWalletOpened = true;
+  connect(d->m_wallet, SIGNAL(walletClosed()), SLOT(slotWalletClosed()));
+  d->m_statusBarWalletLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
+  d->m_statusBarWalletLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
 +  d->m_statusBarWalletLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, \
QSizePolicy::Fixed)); +  d->m_statusBarWalletLabel->setUseCursor(false);
+  d->m_statusBarExtension->addStatusBarItem(d->m_statusBarWalletLabel, 0, false);
+  QToolTip::add(d->m_statusBarWalletLabel, i18n("The wallet '%1' is open and being \
used for form data and passwords.").arg(KWallet::Wallet::NetworkWallet())); +  \
d->m_statusBarWalletLabel->setPixmap(SmallIcon("wallet_open", instance())); +  \
connect(d->m_statusBarWalletLabel, SIGNAL(leftClickedURL()), \
SLOT(launchWalletManager())); +  connect(d->m_statusBarWalletLabel, \
SIGNAL(rightClickedURL()), SLOT(walletMenu())); +}
+
+
+KWallet::Wallet *KHTMLPart::wallet()
+{
+  KHTMLPart *p;
 
   for (p = parentPart(); p && p->parentPart(); p = p->parentPart())
     ;
Index: khtmlpart_p.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtmlpart_p.h,v
retrieving revision 1.57
diff -u -3 -p -r1.57 khtmlpart_p.h
--- khtmlpart_p.h	2 Nov 2004 22:30:09 -0000	1.57
+++ khtmlpart_p.h	4 Nov 2004 12:07:08 -0000
@@ -34,8 +34,13 @@
 #include <kparts/statusbarextension.h>
 #include <kparts/browserextension.h>
 #include <kwallet.h>
+
+#include <qguardedptr.h>
+#include <qmap.h>
 #include <qtimer.h>
+#include <qvaluelist.h>
 
+#include "html/html_formimpl.h"
 #include "khtml_run.h"
 #include "khtml_factory.h"
 #include "khtml_events.h"
@@ -119,6 +124,53 @@ typedef KHTMLFrameList::Iterator FrameIt
 
 static int khtml_part_dcop_counter = 0;
 
+
+class KHTMLWalletQueue : public QObject
+{
+  Q_OBJECT
+  public:
+    KHTMLWalletQueue(QObject *parent) : QObject(parent) {
+      wallet = 0L;
+    }
+
+    virtual ~KHTMLWalletQueue() {
+      delete wallet;
+      wallet = 0L;
+    }
+
+    KWallet::Wallet *wallet;
+    typedef QPair<DOM::HTMLFormElementImpl*, QGuardedPtr<DOM::DocumentImpl> > \
Caller; +    typedef QValueList<Caller> CallerList;
+    CallerList callers;
+    QValueList<QPair<QString, QMap<QString, QString> > > savers;
+
+  signals:
+    void walletOpened(KWallet::Wallet*);
+
+  public slots:
+    void walletOpened(bool success) {
+      if (!success) {
+        delete wallet;
+        wallet = 0L;
+      }
+      emit walletOpened(wallet);
+      if (wallet) {
+        for (CallerList::Iterator i = callers.begin(); i != callers.end(); ++i) {
+          if ((*i).first && (*i).second) {
+            (*i).first->walletOpened(wallet);
+          }
+        }
+        wallet->setFolder(KWallet::Wallet::FormDataFolder());
+        for (QValueList<QPair<QString, QMap<QString, QString> > >::Iterator i = \
savers.begin(); i != savers.end(); ++i) { +          wallet->writeMap((*i).first, \
(*i).second); +        }
+      }
+      callers.clear();
+      savers.clear();
+      wallet = 0L; // gave it away
+    }
+};
+
 class KHTMLPartPrivate
 {
   KHTMLPartPrivate(const KHTMLPartPrivate & other);
@@ -221,6 +273,7 @@ public:
     m_statusBarUALabel = 0L;
     m_statusBarJSErrorLabel = 0L;
     m_userStyleSheetLastModified = 0;
+    m_wq = 0;
   }
   ~KHTMLPartPrivate()
   {
@@ -482,6 +535,8 @@ public:
   }
 
   time_t m_userStyleSheetLastModified;
+
+  KHTMLWalletQueue *m_wq;
 };
 
 #endif
Index: html/html_formimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_formimpl.cpp,v
retrieving revision 1.398
diff -u -3 -p -r1.398 html_formimpl.cpp
--- html/html_formimpl.cpp	30 Oct 2004 15:06:38 -0000	1.398
+++ html/html_formimpl.cpp	4 Nov 2004 12:07:09 -0000
@@ -85,6 +85,9 @@ HTMLFormElementImpl::HTMLFormElementImpl
 
 HTMLFormElementImpl::~HTMLFormElementImpl()
 {
+    if (getDocument()) {
+        getDocument()->view()->part()->dequeueWallet(this);
+    }
     QPtrListIterator<HTMLGenericFormElementImpl> it(formElements);
     for (; it.current(); ++it)
         it.current()->m_form = 0;
@@ -418,30 +421,33 @@ void HTMLFormElementImpl::doAutoFill()
 
     if (KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(),
                                          KWallet::Wallet::FormDataFolder(),
-                                         key) )
+                                         key))
         return;
 
     // assert(view())
-    KWallet::Wallet* const w = getDocument()->view()->part()->wallet();
+    getDocument()->view()->part()->openWallet(this);
+}
 
-    if (w) {
-        if (!w->hasFolder(KWallet::Wallet::FormDataFolder())) {
-            if (!w->createFolder(KWallet::Wallet::FormDataFolder()))
-                return; // failed
-        }
-        w->setFolder(KWallet::Wallet::FormDataFolder());
-        QMap<QString, QString> map;
-        if (w->readMap(key, map))
-            return; // failed, abort
-
-        for (QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); \
                it.current(); ++it) {
-            if (it.current()->id() == ID_INPUT) {
-                HTMLInputElementImpl* const current = \
                static_cast<HTMLInputElementImpl*>(it.current());
-                if (current->inputType() == HTMLInputElementImpl::PASSWORD ||
+
+void HTMLFormElementImpl::walletOpened(KWallet::Wallet *w) {
+    assert(w);
+    const QString key = calculateAutoFillKey(*this);
+    if (!w->hasFolder(KWallet::Wallet::FormDataFolder())) {
+        if (!w->createFolder(KWallet::Wallet::FormDataFolder()))
+            return; // failed
+    }
+    w->setFolder(KWallet::Wallet::FormDataFolder());
+    QMap<QString, QString> map;
+    if (w->readMap(key, map))
+        return; // failed, abort
+
+    for (QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); \
it.current(); ++it) { +        if (it.current()->id() == ID_INPUT) {
+            HTMLInputElementImpl* const current = \
static_cast<HTMLInputElementImpl*>(it.current()); +            if \
(current->inputType() == HTMLInputElementImpl::PASSWORD ||  current->inputType() == \
HTMLInputElementImpl::TEXT &&  map.contains(current->name().string()))
-                    current->setValue(map[current->name().string()]);
-            }
+                current->setValue(map[current->name().string()]);
         }
     }
 }
Index: html/html_formimpl.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_formimpl.h,v
retrieving revision 1.157
diff -u -3 -p -r1.157 html_formimpl.h
--- html/html_formimpl.h	23 Oct 2004 13:12:29 -0000	1.157
+++ html/html_formimpl.h	4 Nov 2004 12:07:09 -0000
@@ -52,6 +52,10 @@ namespace khtml
     typedef QValueList<QCString> encodingList;
 }
 
+namespace KWallet {
+    class Wallet;
+}
+
 namespace DOM {
 
 class HTMLFormElement;
@@ -78,6 +82,7 @@ public:
 
     bool autoComplete() const { return m_autocomplete; }
     void doAutoFill();
+    void walletOpened(KWallet::Wallet *w);
 
     virtual void parseAttribute(AttributeImpl *attr);
 
Index: khtml_part.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_part.h,v
retrieving revision 1.266
diff -u -3 -p -r1.266 khtml_part.h
--- khtml_part.h	7 Oct 2004 12:16:47 -0000	1.266
+++ khtml_part.h	4 Nov 2004 12:10:01 -0000
@@ -1458,6 +1458,8 @@ private slots:
    */
   void restoreScrollPosition();
 
+  void walletOpened(KWallet::Wallet*);
+
 private:
 
   KJSErrorDlg *jsErrorExtension();
@@ -1476,7 +1478,11 @@ private:
 
   bool processObjectRequest( khtml::ChildFrame *child, const KURL &url, const \
QString &mimetype );  
-  KWallet::Wallet* wallet();
+  KWallet::Wallet* wallet() KDE_DEPRECATED;
+
+  void openWallet(DOM::HTMLFormElementImpl*);
+  void saveToWallet(const QString& key, const QMap<QString,QString>& data);
+  void dequeueWallet(DOM::HTMLFormElementImpl*);
 
   /**
    * @internal



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic