<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[126340] trunk/dports/kde/kdelibs4</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="https://trac.macports.org/changeset/126340">126340</a></dd>
<dt>Author</dt> <dd>nicos@macports.org</dd>
<dt>Date</dt> <dd>2014-10-08 04:03:41 -0700 (Wed, 08 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>kdelibs4: update to 4.13.3
add patches
review dependencies</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkdportskdekdelibs4Portfile">trunk/dports/kde/kdelibs4/Portfile</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkdportskdekdelibs4filespatchKdePreferencesdiff">trunk/dports/kde/kdelibs4/files/patch-KdePreferences.diff</a></li>
<li><a href="#trunkdportskdekdelibs4filespatchauthBackendsdiff">trunk/dports/kde/kdelibs4/files/patch-authBackends.diff</a></li>
<li><a href="#trunkdportskdekdelibs4filespatchfixKCrashdiff">trunk/dports/kde/kdelibs4/files/patch-fixKCrash.diff</a></li>
<li><a href="#trunkdportskdekdelibs4filespatchnativeDialogsdiff">trunk/dports/kde/kdelibs4/files/patch-nativeDialogs.diff</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkdportskdekdelibs4filespatchcmakemodulesKDE4Macroscmakediff">trunk/dports/kde/kdelibs4/files/patch-cmake-modules-KDE4Macros.cmake.diff</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkdportskdekdelibs4Portfile"></a>
<div class="modfile"><h4>Modified: trunk/dports/kde/kdelibs4/Portfile (126339 => 126340)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/dports/kde/kdelibs4/Portfile        2014-10-08 10:38:21 UTC (rev 126339)
+++ trunk/dports/kde/kdelibs4/Portfile        2014-10-08 11:03:41 UTC (rev 126340)
</span><span class="lines">@@ -5,8 +5,7 @@
</span><span class="cx"> PortGroup           kde4   1.1
</span><span class="cx"> 
</span><span class="cx"> name                kdelibs4
</span><del>-version             4.12.5
-revision            3
</del><ins>+version             4.13.3
</ins><span class="cx"> categories          kde kde4
</span><span class="cx"> maintainers         nicos
</span><span class="cx"> license             LGPL-2+ GPL-2+ BSD
</span><span class="lines">@@ -18,8 +17,8 @@
</span><span class="cx"> use_xz              yes
</span><span class="cx"> distname            kdelibs-${version}
</span><span class="cx"> 
</span><del>-checksums           rmd160  aa0bb8fb44d6c49ddd8787c4cb79c1f1bdd331b8 \
-                    sha256  9711c3a3d29387dc8b40425cc2957e9f1f2d747d83e9e0213bb8ff6638e68e09
</del><ins>+checksums           rmd160  8db76ec77ed09d180223fb3a37b38e8ca8798d75 \
+                    sha256  d291b4bc159a3f686ad93ff3dfbe90a0a7e33600357e8390c84154ec050efc82
</ins><span class="cx"> 
</span><span class="cx"> #No binary links to openssl libraries, apart from libkio.dylib at
</span><span class="cx"> #runtime if required. As libkio.dylib code is purely LGPL, there is no
</span><span class="lines">@@ -29,14 +28,12 @@
</span><span class="cx"> depends_build-append port:flex port:gmake port:docbook-xsl-ns
</span><span class="cx"> 
</span><span class="cx"> depends_lib-append  port:bzip2 port:zlib \
</span><del>-                    port:soprano port:cyrus-sasl2 \
</del><ins>+                    port:soprano \
</ins><span class="cx">                     port:strigi port:gettext \
</span><span class="cx">                     port:pcre port:shared-mime-info \
</span><del>-                    lib:libgif:giflib port:tiff \
</del><ins>+                    lib:libgif:giflib \
</ins><span class="cx">                     port:jpeg port:libpng \
</span><span class="cx">                     port:jasper port:openexr \
</span><del>-                    port:expat port:libart_lgpl \
-                    port:libidn port:libiconv \
</del><span class="cx">                     path:lib/pkgconfig/glib-2.0.pc:glib2 \
</span><span class="cx">                     port:openssl port:enchant \
</span><span class="cx">                     port:aspell port:aspell-dict-en \
</span><span class="lines">@@ -45,8 +42,9 @@
</span><span class="cx">                     port:libxml2 port:libxslt \
</span><span class="cx">                     port:dbusmenu-qt port:docbook-xml \
</span><span class="cx">                     port:docbook-xsl port:grantlee \
</span><del>-                    port:kerberos5 \
-                    port:shared-desktop-ontologies
</del><ins>+                    port:kerberos5 port:bison \
+                    port:shared-desktop-ontologies \
+                    port:perl5
</ins><span class="cx"> 
</span><span class="cx"> # the aspell dictionaries are just files
</span><span class="cx"> depends_skip_archcheck aspell-dict-en
</span><span class="lines">@@ -59,8 +57,10 @@
</span><span class="cx"> #add-bundles-to-path: improve support for KIO slaves by adding a search path
</span><span class="cx"> #kapplications-raster: ensures that kde applications start in raster (faster) mode, but also provides a switch for non-working applications
</span><span class="cx"> #removeFindFlex: remove FindFlex.cmake which may hide the working one of cmake (ticket #44119)
</span><del>-#patch-cmake-modules-FindKDE4-Internal.cmake: Fixes zlib detection (see ticket #24128)
-#patch-cmake-modules-KDE4Macros.cmake: Ensures that compiled objects are properly detected during build (see ticket #43720)
</del><ins>+#cmake-modules-FindKDE4-Internal.cmake: Fixes zlib detection (see ticket #24128)
+#fixKCrash: Fix issues in the KDE reporting system on OSX (see https://git.reviewboard.kde.org/r/119497/, committed upstream)
+#nativeDialogs: Use native mac dialogs (see https://reviewboard.kde.org/r/119243/)
+#KdePreferences: Handles menus to be closer to standard Mac layout (see https://reviewboard.kde.org/r/120149/)
</ins><span class="cx"> 
</span><span class="cx"> patchfiles           workaround-kdeinit4-crash.patch \
</span><span class="cx">                      avoid-kwindowinfo-destructor.patch \
</span><span class="lines">@@ -69,7 +69,9 @@
</span><span class="cx">                      patch-kapplications-raster.diff \
</span><span class="cx">                      patch-removeFindFlex.diff \
</span><span class="cx">                      patch-cmake-modules-FindKDE4-Internal.cmake.diff \
</span><del>-                     patch-cmake-modules-KDE4Macros.cmake.diff
</del><ins>+                     patch-fixKCrash.diff \
+                     patch-nativeDialogs.diff \
+                     patch-KdePreferences.diff
</ins><span class="cx"> 
</span><span class="cx"> patch.pre_args      -p1
</span><span class="cx"> 
</span><span class="lines">@@ -144,6 +146,12 @@
</span><span class="cx"> To start it run the following command:
</span><span class="cx">  launchctl load -w ${startup_root}/Library/LaunchAgents/org.macports.kdecache.plist&quot;
</span><span class="cx"> 
</span><ins>+#patch-authBackends: make possible to use OS X keychain through kwallet (see https://git.reviewboard.kde.org/r/119838/, shipped)
+variant osxkeychain description {kwallet uses the OSX KeyChain} {
+    configure.args-append   -DMAC_USE_OSXKEYCHAIN:BOOL=ON
+    patchfiles-append       patch-authBackends.diff
+}
+
</ins><span class="cx"> variant no_root description {Run the kde cache agent as MacPorts install user.} {
</span><span class="cx">     pre-fetch {
</span><span class="cx">         if { ${install.user}==&quot;root&quot; || ${install.group}==&quot;wheel&quot; } {
</span></span></pre></div>
<a id="trunkdportskdekdelibs4filespatchKdePreferencesdiff"></a>
<div class="addfile"><h4>Added: trunk/dports/kde/kdelibs4/files/patch-KdePreferences.diff (0 => 126340)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/dports/kde/kdelibs4/files/patch-KdePreferences.diff                                (rev 0)
+++ trunk/dports/kde/kdelibs4/files/patch-KdePreferences.diff        2014-10-08 11:03:41 UTC (rev 126340)
</span><span class="lines">@@ -0,0 +1,113 @@
</span><ins>+diff -ur kdelibs-4.13.3-orig/kdeui/actions/kaction.cpp kdelibs-4.13.3/kdeui/actions/kaction.cpp
+--- kdelibs-4.13.3-orig/kdeui/actions/kaction.cpp        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kdeui/actions/kaction.cpp        2014-09-20 23:58:07.000000000 +0900
+@@ -142,11 +142,52 @@
+   d-&gt;init(this);
+ }

++#ifdef Q_OS_MAC
++
++#include &lt;QMenuBar&gt;
++#include &lt;kaboutdata.h&gt;
++
++static void setTextWithCorrectMenuRole( KAction *action, const QString &amp;text )
++{
++    // texts containing &quot;config, options, setup, settings or preferences&quot; will get PreferencesRole
++    // from Qt unless they have a role set. We prevent that, because KDE has its own way of
++    // defining a the application preferences menu (&quot;Configure &lt;appName&gt;&quot;) which should go under the OS X Preferences menu.
++    // But when a KAction is created with the standard preferences title (&quot;Configure &lt;appName&gt;...&quot;), this action
++    // is set to PreferencesRole .
++    // The compare actions using QMenuBar::tr are copied from Qt's own qmenu_mac.mm :
++    action-&gt;setText(text);
++    const KAboutData *aboutData = KGlobal::mainComponent().aboutData();
++    QString appName = i18n( &quot;%1...&quot;, (aboutData) ? aboutData-&gt;programName() : qApp-&gt;applicationName() );
++    if( text.startsWith(QMenuBar::tr(&quot;Config&quot;).toLower()) ||  text.startsWith( &quot;&amp;&quot; % QMenuBar::tr(&quot;Config&quot;).toLower()) ){
++        if( text.endsWith(appName) ){
++            kDebug() &lt;&lt; &quot;### Setting QAction::PreferencesRole from&quot; &lt;&lt; action-&gt;menuRole() &lt;&lt; &quot;for menuAction with text&quot; &lt;&lt; text;
++            action-&gt;setMenuRole(QAction::PreferencesRole);
++        }
++        else{
++            kDebug() &lt;&lt; &quot;### Setting QAction::NoRole from&quot; &lt;&lt; action-&gt;menuRole() &lt;&lt; &quot;for menuAction with text&quot; &lt;&lt; text;
++            action-&gt;setMenuRole(QAction::NoRole);
++        }
++    }
++    else if( text.contains(QMenuBar::tr(&quot;Options&quot;).toLower())
++        || text.contains(QMenuBar::tr(&quot;Setup&quot;).toLower())
++        || text.contains(QMenuBar::tr(&quot;Settings&quot;).toLower())
++        || text.contains(QMenuBar::tr(&quot;Preferences&quot;).toLower())
++    ){
++        kDebug() &lt;&lt; &quot;### Setting QAction::NoRole from&quot; &lt;&lt; action-&gt;menuRole() &lt;&lt; &quot;for menuAction with text&quot; &lt;&lt; text;
++        action-&gt;setMenuRole(QAction::NoRole);
++    }
++}
++#endif //Q_OS_MAC
++
+ KAction::KAction(const QString &amp;text, QObject *parent)
+   : QWidgetAction(parent), d(new KActionPrivate)
+ {
+   d-&gt;init(this);
++#ifdef Q_OS_MAC
++  setTextWithCorrectMenuRole(this, text);
++#else
+   setText(text);
++#endif
+ }

+ KAction::KAction(const KIcon &amp;icon, const QString &amp;text, QObject *parent)
+@@ -154,7 +195,11 @@
+ {
+   d-&gt;init(this);
+   setIcon(icon);
++#ifdef Q_OS_MAC
++  setTextWithCorrectMenuRole(this, text);
++#else
+   setText(text);
++#endif
+ }

+ KAction::~KAction()
+diff -ur kdelibs-4.13.3-orig/kdeui/notifications/kstatusnotifieritem.cpp kdelibs-4.13.3/kdeui/notifications/kstatusnotifieritem.cpp
+--- kdelibs-4.13.3-orig/kdeui/notifications/kstatusnotifieritem.cpp        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kdeui/notifications/kstatusnotifieritem.cpp        2014-09-20 23:58:14.000000000 +0900
+@@ -683,6 +683,9 @@

+         return false;
+     }
++#else
++    Q_UNUSED(pos);
++    Q_UNUSED(perform);
+ #endif

+     return true;
+@@ -722,6 +725,10 @@
+ {
+ }

++#ifdef Q_OS_MAC
++#   include &lt;kconfiggroup.h&gt;
++#endif
++
+ void KStatusNotifierItemPrivate::init(const QString &amp;extraId)
+ {
+     // Ensure that closing the last KMainWindow doesn't exit the application
+@@ -745,8 +752,20 @@

+     //create a default menu, just like in KSystemtrayIcon
+     KMenu *m = new KMenu(associatedWidget);
++#ifdef Q_OS_MAC
++    // emulate addTitle/setTitle by adding an inactive menu item.
++    titleAction = m-&gt;addAction( qApp-&gt;windowIcon(), KGlobal::mainComponent().aboutData()-&gt;programName() );
++    titleAction-&gt;setEnabled(false);
++    titleAction-&gt;setIconVisibleInMenu(true);
++    m-&gt;addAction( titleAction );
++    m-&gt;addSeparator();
++    kDebug() &lt;&lt; &quot;### Added SystemTray titleAction=&quot; &lt;&lt; titleAction;
++    kDebug() &lt;&lt; &quot;### SystemTray for app&quot; &lt;&lt; qApp &lt;&lt; &quot;=&quot; &lt;&lt; KGlobal::mainComponent().aboutData()-&gt;programName()
++        &lt;&lt; &quot;/&quot; &lt;&lt; KGlobal::caption() &lt;&lt; &quot;with icon&quot; &lt;&lt; qApp-&gt;windowIcon().name();
++#else
+     titleAction = m-&gt;addTitle(qApp-&gt;windowIcon(), KGlobal::caption());
+     m-&gt;setTitle(KGlobal::mainComponent().aboutData()-&gt;programName());
++#endif
+     q-&gt;setContextMenu(m);

+     KStandardAction::quit(q, SLOT(maybeQuit()), actionCollection);
</ins></span></pre></div>
<a id="trunkdportskdekdelibs4filespatchauthBackendsdiff"></a>
<div class="addfile"><h4>Added: trunk/dports/kde/kdelibs4/files/patch-authBackends.diff (0 => 126340)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/dports/kde/kdelibs4/files/patch-authBackends.diff                                (rev 0)
+++ trunk/dports/kde/kdelibs4/files/patch-authBackends.diff        2014-10-08 11:03:41 UTC (rev 126340)
</span><span class="lines">@@ -0,0 +1,4535 @@
</span><ins>+diff -urN kdelibs-4.13.3-orig/kdecore/auth/backends/mac/AuthServicesBackend.cpp kdelibs-4.13.3/kdecore/auth/backends/mac/AuthServicesBackend.cpp
+--- kdelibs-4.13.3-orig/kdecore/auth/backends/mac/AuthServicesBackend.cpp        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kdecore/auth/backends/mac/AuthServicesBackend.cpp        2014-09-22 19:46:01.000000000 +0900
+@@ -1,5 +1,6 @@
+ /*
+ *   Copyright (C) 2008 Nicola Gigante &lt;nicola.gigante@gmail.com&gt;
++*   Modifications (C) 2014 René Bertin &lt;rjvbertin@gmail.com&gt;
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published by
+@@ -21,6 +22,7 @@
+ #include &lt;Security/Security.h&gt;

+ #include &lt;QtCore/qplugin.h&gt;
++#include &lt;QtCore/QtCore&gt;

+ namespace KAuth
+ {
+@@ -34,14 +36,35 @@
+     if (!s_authRef) {
+         AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &amp;s_authRef);
+     }
+-
+     return s_authRef;
+ }

++static OSStatus GetActionRights(const QString &amp;action, AuthorizationFlags flags, AuthorizationRef auth=NULL)
++{
++    AuthorizationItem item;
++    item.name = action.toUtf8();
++    item.valueLength = 0;
++    item.value = NULL;
++    item.flags = 0;
++
++    AuthorizationRights rights;
++    rights.count = 1;
++    rights.items = &amp;item;
++
++    OSStatus result = AuthorizationCopyRights( (auth)? auth : authRef(),
++                                              &amp;rights,
++                                              kAuthorizationEmptyEnvironment,
++                                              flags, NULL);
++    return result;
++}
++
++// On OS X, the suggestion is to make the helper grant the actual privilege. The app does instead a
++// &quot;pre-authorization&quot;, that's equivalent to look at isCallerAuthorized() in policykit.
++// RJVB: grab the privilege from here, the client.
+ AuthServicesBackend::AuthServicesBackend()
+     : AuthBackend()
+ {
+-    setCapabilities(AuthorizeFromHelperCapability | CheckActionExistenceCapability);
++    setCapabilities(AuthorizeFromClientCapability | CheckActionExistenceCapability);
+ }

+ void AuthServicesBackend::setupAction(const QString&amp;)
+@@ -51,29 +74,24 @@

+ // On OS X, the suggestion is to make the helper grant the actual privilege. The app does instead a
+ // &quot;pre-authorization&quot;, that's equivalent to look at isCallerAuthorized() in policykit.
++// RJVB: grab the privilege from here, the client.
+ Action::AuthStatus AuthServicesBackend::authorizeAction(const QString &amp;action)
+ {
+-    return actionStatus(action);
++    OSStatus result = GetActionRights( action, kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed );
++//    qWarning() &lt;&lt; &quot;AuthServicesBackend::authorizeAction(&quot; &lt;&lt; action &lt;&lt; &quot;) AuthorizationCopyRights returned&quot; &lt;&lt; result;
++    switch (result) {
++        case errAuthorizationSuccess:
++            return Action::Authorized;
++        case errAuthorizationInteractionNotAllowed:
++        default:
++            return Action::Denied;
++    }
+ }

+ Action::AuthStatus AuthServicesBackend::actionStatus(const QString &amp;action)
+ {
+-    AuthorizationItem item;
+-    item.name = action.toUtf8();
+-    item.valueLength = 0;
+-    item.value = NULL;
+-    item.flags = 0;
+-
+-    AuthorizationRights rights;
+-    rights.count = 1;
+-    rights.items = &amp;item;
+-
+-    OSStatus result = AuthorizationCopyRights(authRef(),
+-                      &amp;rights,
+-                      kAuthorizationEmptyEnvironment,
+-                      kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize,
+-                      NULL);
+-
++    OSStatus result = GetActionRights( action, kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize );
++//    qWarning() &lt;&lt; &quot;AuthServicesBackend::actionStatus(&quot; &lt;&lt; action &lt;&lt; &quot;) AuthorizationCopyRights returned&quot; &lt;&lt; result;
+     switch (result) {
+     case errAuthorizationSuccess:
+         return Action::Authorized;
+@@ -101,35 +119,28 @@

+     AuthorizationRef auth;

+-    if (AuthorizationCreateFromExternalForm(&amp;ext, &amp;auth) != noErr)
++    if (AuthorizationCreateFromExternalForm(&amp;ext, &amp;auth) != noErr){
++//        qWarning() &lt;&lt; &quot;AuthorizationCreateFromExternalForm(&quot; &lt;&lt; action &lt;&lt; &quot;,&quot; &lt;&lt; callerID.constData() &lt;&lt; &quot;) failed&quot;;
+         return false;
++    }

+-    AuthorizationItem item;
+-    item.name = action.toUtf8();
+-    item.valueLength = 0;
+-    item.value = NULL;
+-    item.flags = 0;
+-
+-    AuthorizationRights rights;
+-    rights.count = 1;
+-    rights.items = &amp;item;
+-
+-    OSStatus result = AuthorizationCopyRights(auth,
+-                      &amp;rights,
+-                      kAuthorizationEmptyEnvironment,
+-                      kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed,
+-                      NULL);
++    OSStatus result = GetActionRights( action, kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed,
++                      auth);

+     AuthorizationFree(auth, kAuthorizationFlagDefaults);
++//    qWarning() &lt;&lt; &quot;AuthServicesBackend::isCallerAuthorized(&quot; &lt;&lt; action &lt;&lt; &quot;,&quot; &lt;&lt; callerID.constData() &lt;&lt; &quot;) AuthorizationCopyRights returned&quot; &lt;&lt; result;

+     return result == errAuthorizationSuccess;
+ }

++// RJVB: OS X doesn't distinguish between &quot;action doesn't exist&quot; and &quot;action not allowed&quot;. So the
++// best thing we can do is return true and hope that the action will be created if it didn't exist...
+ bool AuthServicesBackend::actionExists(const QString&amp; action)
+ {
+     OSStatus exists = AuthorizationRightGet(action.toUtf8(), NULL);
++//    qWarning() &lt;&lt; &quot;AuthServicesBackend::actionExists(&quot; &lt;&lt; action &lt;&lt; &quot;) AuthorizationRightGet returned&quot; &lt;&lt; exists;

+-    return exists == errAuthorizationSuccess;
++    return true;//exists == errAuthorizationSuccess;
+ }

+ }; // namespace KAuth
+diff -urN kdelibs-4.13.3-orig/kdecore/auth/kauthaction.cpp kdelibs-4.13.3/kdecore/auth/kauthaction.cpp
+--- kdelibs-4.13.3-orig/kdecore/auth/kauthaction.cpp        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kdecore/auth/kauthaction.cpp        2014-09-22 19:46:01.000000000 +0900
+@@ -356,6 +356,13 @@
+         return executeActions(QList&lt;Action&gt;() &lt;&lt; *this, NULL, helperID) ?
+             ActionReply::SuccessReply : ActionReply::AuthorizationDeniedReply;
+     } else {
++#if defined(Q_OS_MACX) || defined(__APPLE__) || defined(__MACH__)
++        if( BackendsManager::authBackend()-&gt;capabilities() &amp; KAuth::AuthBackend::AuthorizeFromClientCapability ){
++            // RJVB: authorisation through DBus seems to be flaky (at least when using the OSX keychain ... maybe because DBus
++            // isn't built with Keychain support in MacPorts?)
++            return ActionReply::SuccessReply;
++        }
++#endif //APPLE
+         if (hasHelper()) {
+             // Perform the pre auth here
+             if (BackendsManager::authBackend()-&gt;capabilities() &amp; KAuth::AuthBackend::PreAuthActionCapability) {
+diff -urN kdelibs-4.13.3-orig/kdeui/CMakeLists.txt kdelibs-4.13.3/kdeui/CMakeLists.txt
+--- kdelibs-4.13.3-orig/kdeui/CMakeLists.txt        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kdeui/CMakeLists.txt        2014-09-22 19:46:10.000000000 +0900
+@@ -309,11 +309,12 @@

+ if (Q_WS_MAC AND MAC_USE_OSXKEYCHAIN)
+     FIND_LIBRARY(SECURITY_LIBRARY Security)
+-    set(kdeui_LIB_SRCS ${kdeui_LIB_SRCS} util/kwallet_mac.cpp)
++        set(kdeui_LIB_SRCS ${kdeui_LIB_SRCS} util/kwallet_mac.cpp util/qosxkeychain.cpp)
++           add_definitions(-DMAC_USE_OSXKEYCHAIN)
++    else(Q_WS_MAC AND MAC_USE_OSXKEYCHAIN)
++         set(kdeui_LIB_SRCS ${kdeui_LIB_SRCS} util/kwallet.cpp)
+ else(Q_WS_MAC AND MAC_USE_OSXKEYCHAIN)
+-     set(kdeui_LIB_SRCS ${kdeui_LIB_SRCS} util/kwallet.cpp)
+-else(Q_WS_MAC AND MAC_USE_OSXKEYCHAIN)
+-  set(kdeui_LIB_SRCS ${kdeui_LIB_SRCS} util/kwallet.cpp)
++    set(kdeui_LIB_SRCS ${kdeui_LIB_SRCS} util/kwallet.cpp)
+ endif(Q_WS_MAC AND MAC_USE_OSXKEYCHAIN)

+ if(NOT WINCE)
+diff -urN kdelibs-4.13.3-orig/kdeui/tests/CMakeLists.txt kdelibs-4.13.3/kdeui/tests/CMakeLists.txt
+--- kdelibs-4.13.3-orig/kdeui/tests/CMakeLists.txt        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kdeui/tests/CMakeLists.txt        2014-09-22 19:46:28.000000000 +0900
+@@ -7,6 +7,7 @@
+ # The alternative (which requires Qt&gt;=4.6) is #include &lt;QTestGui&gt;
+ add_definitions(-DQT_GUI_LIB)

++option(MAC_USE_OSXKEYCHAIN &quot;On OS X, use the keychain as backend for kwallet, instead of kwalletd.&quot;)

+ MACRO(KDEUI_UNIT_TESTS)
+        FOREACH(_testname ${ARGN})
+@@ -154,6 +155,11 @@
+   kpixmapsequenceoverlaypaintertest
+ )

++if (Q_WS_MAC AND MAC_USE_OSXKEYCHAIN)
++  set_source_files_properties(kwallettest.cpp PROPERTIES 
++                               COMPILE_FLAGS -DMAC_USE_OSXKEYCHAIN)
++endif(Q_WS_MAC AND MAC_USE_OSXKEYCHAIN)
++
+ if (NOT KDE_NO_DEPRECATED)
+ KDEUI_EXECUTABLE_TESTS(
+   keditlistboxtest
+diff -urN kdelibs-4.13.3-orig/kdeui/tests/kwallettest.cpp kdelibs-4.13.3/kdeui/tests/kwallettest.cpp
+--- kdelibs-4.13.3-orig/kdeui/tests/kwallettest.cpp        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kdeui/tests/kwallettest.cpp        2014-09-22 19:46:28.000000000 +0900
+@@ -32,11 +32,12 @@

+ void KWalletTest::testWallet()
+ {
+-  QString testWallet = &quot;kdewallet&quot;;
++  QString testWallet = &quot;kwallettestWallet&quot;;
+   QString testFolder = &quot;wallettestfolder&quot;;
+   QString testKeys[] = { &quot;testKey&quot;, &quot;account-302948&quot;, &quot;\\&quot;, &quot;/abc&quot;,
+                          &quot;a@b.c&quot; };
+   QByteArray testValues[] = { &quot;test&quot;, &quot;@(!§\&quot;%&amp;&quot;, &quot;&quot;, &quot;.test&quot;, &quot;\\&quot; };
++  QMap&lt;QString,QString&gt; pwmap;
+   int numTests = 5;

+   // Start kdeinit4, so that the wallet damon is started in the background
+@@ -49,15 +50,24 @@

+   // open
+   Wallet *wallet = Wallet::openWallet( testWallet, w-&gt;winId(), Wallet::Synchronous );
+-  if ( wallet == 0 )
+-    kDebug() &lt;&lt; &quot;Couldn't open the wallet. Maybe the wallet daemon is not running?&quot;;
++  if ( wallet == 0 ){
++    kWarning() &lt;&lt; &quot;Couldn't open the wallet. Maybe the wallet daemon is not running?&quot;;
++  }
++  else{
++    kWarning() &lt;&lt; &quot;Opened wallet&quot; &lt;&lt; wallet-&gt;walletName();
++  }
+   QVERIFY( wallet != 0 );
+   QVERIFY( Wallet::isOpen( testWallet ) );
++  kWarning() &lt;&lt; &quot;Wallet list:&quot; &lt;&lt; Wallet::walletList();
++
++  // check on a couple of existing items, preferably at least 1 &quot;internet account&quot; and 1 &quot;application password&quot;
++  // OSXKeychain::readEntry( &quot;existing name&quot;, &quot;existing account&quot;, &amp;value, NULL, NULL )

+   // create folder
+   wallet-&gt;createFolder( testFolder );
+   QVERIFY( wallet-&gt;hasFolder( testFolder ) );
+   wallet-&gt;setFolder( testFolder );
++  kWarning() &lt;&lt; &quot;Wallet's folder list:&quot; &lt;&lt; wallet-&gt;folderList();
+   QVERIFY( wallet-&gt;currentFolder() == testFolder );
+   QVERIFY( wallet-&gt;folderList().contains( testFolder ) );

+@@ -70,10 +80,36 @@
+     QVERIFY( readEntry == testValues[i] );
+   }

++  pwmap[QString(&quot;Bugzilla_login&quot;)] = QString(&quot;bugs@kde.org&quot;);
++  pwmap[QString(&quot;Bugzilla_password&quot;)] = QString(&quot;buggyPassw0rd&quot;);
++  kWarning() &lt;&lt; &quot;pwmap=&quot; &lt;&lt; pwmap;
++
++  QMap&lt;QString,QString&gt; v;
++  QVERIFY( !wallet-&gt;writeMap( &quot;https://bugs.kde.org/#&quot;, pwmap ) );
++  QVERIFY( wallet-&gt;hasEntry(&quot;https://bugs.kde.org/#&quot;) );
++  QVERIFY( !wallet-&gt;readMap( &quot;https://bugs.kde.org/#&quot;, v ) );
++  QVERIFY( v == pwmap );
++  // do it again
++  QVERIFY( !wallet-&gt;writeMap( &quot;https://bugs.kde.org/#&quot;, pwmap ) );
++  QVERIFY( wallet-&gt;hasEntry(&quot;https://bugs.kde.org/#&quot;) );
++  QVERIFY( !wallet-&gt;readMap( &quot;https://bugs.kde.org/#&quot;, v ) );
++  QVERIFY( v == pwmap );
++
++  QVERIFY( wallet-&gt;entryType( testKeys[0] ) == Wallet::Stream );
++  QVERIFY( wallet-&gt;entryType( &quot;https://bugs.kde.org/#&quot; ) == Wallet::Map );
++
++  QVERIFY( !wallet-&gt;renameEntry( &quot;https://bugs.kde.org/#&quot;, &quot;kdeBugs&quot; ) );
++  QVERIFY( wallet-&gt;hasEntry(&quot;kdeBugs&quot;) );
++  QVERIFY( !wallet-&gt;readMap( &quot;kdeBugs&quot;, v ) );
++  QVERIFY( v == pwmap );
++
+   // close
+   wallet-&gt;sync();
+-  Wallet::closeWallet( &quot;kdewallet&quot;, true );
+-  QVERIFY( !Wallet::isOpen( &quot;kdewallet&quot; ) );
++  QStringList l = wallet-&gt;entryList();
++  kWarning() &lt;&lt; &quot;Entry list:&quot; &lt;&lt; l;
++  QVERIFY( l.size() == 6 );
++  Wallet::closeWallet( testWallet, true );
++  QVERIFY( !Wallet::isOpen( testWallet ) );

+   // test for key - closed wallet
+   for ( int i = 0; i &lt; 5; i++ ) {
+@@ -108,13 +144,21 @@
+     QVERIFY( readEntry == testValues[i] );
+   }

++  // remove those many test keys
++  for ( int i = 0; i &lt; numTests; i++ ) {
++    QVERIFY( !wallet-&gt;removeEntry( testKeys[i] ) );
++  }
++
++#ifndef MAC_USE_OSXKEYCHAIN
+   // delete folder
+   wallet-&gt;removeFolder( testFolder );
+   QVERIFY( !wallet-&gt;hasFolder( testFolder ) );
++#endif

+   // close
+-  Wallet::closeWallet( &quot;kdewallet&quot;, true );
+-  QVERIFY( !Wallet::isOpen( &quot;kdewallet&quot; ) );
++  Wallet::closeWallet( testWallet, true );
++  QVERIFY( !Wallet::isOpen( testWallet ) );
++  QVERIFY( !Wallet::deleteWallet( testWallet ) );
+ }

+ QTEST_KDEMAIN(KWalletTest, GUI)
+diff -urN kdelibs-4.13.3-orig/kdeui/util/kwallet_mac.cpp kdelibs-4.13.3/kdeui/util/kwallet_mac.cpp
+--- kdelibs-4.13.3-orig/kdeui/util/kwallet_mac.cpp        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kdeui/util/kwallet_mac.cpp        2014-09-22 19:46:50.000000000 +0900
+@@ -1,8 +1,10 @@
+-/* This file is part of the KDE project
++/* @file kwallet_mac.cpp
++ * This file is part of the KDE project
+  *
+  * Copyright (C) 2002-2004 George Staikos &lt;staikos@kde.org&gt;
+  * Copyright (C) 2008 Michael Leupold &lt;lemma@confuego.org&gt;
+  * Copyright (C) 2010 Frank Osterfeld &lt;osterfeld@kde.org&gt;
++ * Copyright (C) 2014 René Bertin &lt;rjvbertin@gmail.com&gt;
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -26,7 +28,9 @@
+ #include &lt;kdeversion.h&gt;
+ #include &lt;QtGui/QApplication&gt;
+ #include &lt;QtCore/QPointer&gt;
++#include &lt;QtCore/QSharedMemory&gt;
+ #include &lt;QtGui/QWidget&gt;
++#include &lt;QtCore/QTimer&gt;
+ #include &lt;ktoolinvocation.h&gt;

+ #include &lt;kglobal.h&gt;
+@@ -36,11 +40,13 @@

+ #include &lt;cassert&gt;

+-#include &lt;Carbon/Carbon.h&gt;
+-#include &lt;Security/Security.h&gt;
+-#include &lt;Security/SecKeychain.h&gt;
++#include &lt;sys/param.h&gt;

+-using namespace KWallet;
++#include &quot;qosxkeychain.h&quot;
++
++#ifdef USE_KWALLETD
++#   include &quot;kwallet_interface.h&quot;
++#endif

+ typedef QMap&lt;QString, QString&gt; StringStringMap;
+ Q_DECLARE_METATYPE(StringStringMap)
+@@ -49,30 +55,151 @@
+ typedef QMap&lt;QString, QByteArray&gt; StringByteArrayMap;
+ Q_DECLARE_METATYPE(StringByteArrayMap)

+-namespace {
+-    template &lt;typename T&gt;
+-    struct CFReleaser {
+-        explicit CFReleaser( const T&amp; r ) : ref( r ) {}
+-        ~CFReleaser() { CFRelease( ref ); }
+-        T ref;
+-    };
+-}
++#include &lt;mach/mach.h&gt;
++#include &lt;mach/mach_time.h&gt;
++#include &lt;mach/mach_init.h&gt;
++#include &lt;sys/sysctl.h&gt;

+-static QString asQString( CFStringRef sr ) {
+-    return QString::fromLatin1( CFStringGetCStringPtr( sr, NULL ) ); //TODO Latin1 correct?
+-}
++#define IDLETIMER_DEBUG

+-static QString errorString( OSStatus s ) {
+-    const CFReleaser&lt;CFStringRef&gt; ref( SecCopyErrorMessageString( s, NULL ) );
+-    return asQString( ref.ref );
++template &lt;typename T&gt;
++class QSharedValue : public QSharedMemory
++{
++public:
++    virtual bool attachOrCreate(QSharedMemory::AccessMode mode=QSharedMemory::ReadWrite)
++    {   bool ret = attach(mode);
++        if( !ret ){
++            ret = create( sizeof(T), mode );
++        }
++        return ret;
++    }
++    virtual bool attachOrCreate(QString &amp;key, QSharedMemory::AccessMode mode=QSharedMemory::ReadWrite)
++    {
++        setKey(key);
++        bool ret = attach(mode);
++        if( !ret ){
++            ret = create( sizeof(T), mode );
++        }
++        return ret;
++    }
++    virtual bool attachOrCreate(QString &amp;key, T *initVal, QSharedMemory::AccessMode mode=QSharedMemory::ReadWrite)
++    {
++        setKey(key);
++        bool ret = attach(mode);
++        if( !ret ){
++            ret = create( sizeof(T), mode );
++            if( ret ){
++                setValue(initVal);
++            }
++        }
++        return ret;
++    }
++    virtual bool attachOrCreate(QString &amp;key, T initVal, QSharedMemory::AccessMode mode=QSharedMemory::ReadWrite)
++    {
++        return attachOrCreate( key, &amp;initVal, mode );
++    }
++    virtual bool getValue(T &amp;val)
++    {
++        if( lock() ){
++            val = *((T*)data());
++            return unlock();
++        }
++        else{
++            return false;
++        }
++    }
++    virtual bool setValue(T *newVal)
++    {
++        if( lock() ){
++            *((T*)data()) = *newVal;
++            return unlock();
++        }
++        else{
++            return false;
++        }
++    }
++    virtual bool setValue(T newVal)
++    {
++        return setValue(&amp;newVal);
++    }
++};
++
++static mach_timebase_info_data_t sTimebaseInfo;
++static double calibrator= 0, startTime = 0;
++static QSharedValue&lt;double&gt; sharedStartTime;
++
++double HRTime_Time()
++{
++    return mach_absolute_time() * calibrator - startTime;
+ }

+-static bool isError( OSStatus s, QString* errMsg ) {
+-    if ( errMsg )
+-        *errMsg = errorString( s );
+-    return s != 0;
++void init_HRTime()
++{
++    if( !calibrator ){
++        mach_timebase_info(&amp;sTimebaseInfo);
++        /* go from absolute time units to seconds (the timebase is calibrated in nanoseconds): */
++        calibrator= 1e-9 * sTimebaseInfo.numer / sTimebaseInfo.denom;
++        QString key = &quot;kwalletWallClockStartTime&quot;;
++        sharedStartTime.attachOrCreate( key, HRTime_Time() );
++        sharedStartTime.getValue(startTime);
++        qDebug() &lt;&lt; &quot;init_HRTime(): connected to kwalletWallClock at t=&quot; &lt;&lt; HRTime_Time();
++    }
+ }

++namespace KWallet
++{
++
++#ifdef USE_KWALLETD
++class KWalletDLauncher
++{
++public:
++    KWalletDLauncher();
++    ~KWalletDLauncher();
++    org::kde::KWallet &amp;getInterface();
++
++    org::kde::KWallet *m_wallet;
++    KConfigGroup m_cgroup;
++};
++
++K_GLOBAL_STATIC(KWalletDLauncher, walletLauncher)
++static const char s_kwalletdServiceName[] = &quot;org.kde.kwalletd&quot;;
++
++#else
++
++/**
++ * maps wallet name to a map of app name to &lt;wallet,pid&gt; instances
++ */
++// deserialising the WalletUsersList from a QDataStream works only for a few WalletInstancePtr types
++// We could store the Wallet* in a QByteArray, but that would make it impossible to dump the WalletUsersList
++// to the console for debugging. So we use a QVariant.
++typedef QVariant WalletInstancePtr;
++// typedef QList&lt;QPair&lt;WalletInstancePtr,pid_t&gt; &gt; WalletUsersListEntryData;
++class WalletUsersListEntryData : public QList&lt;QPair&lt;WalletInstancePtr,pid_t&gt; &gt;
++{
++public:
++    static WalletUsersListEntryData create(QPair&lt;WalletInstancePtr,pid_t&gt; &amp;head)
++    {
++        WalletUsersListEntryData self;
++        self.clear();
++        self.append(head);
++        return self;
++    }
++    static WalletUsersListEntryData create(QPair&lt;WalletInstancePtr,pid_t&gt; head)
++    {
++        WalletUsersListEntryData self;
++        self.clear();
++        self.append(head);
++        return self;
++    }
++};
++
++typedef QMap&lt;QString,WalletUsersListEntryData&gt; WalletUsersListEntry;
++typedef QMap&lt;QString,WalletUsersListEntry&gt; WalletUsersList;
++static WalletUsersList walletUsers;
++
++#endif //USE_KWALLETD
++
++
+ static QString appid()
+ {
+     KComponentData cData = KGlobal::mainComponent();
+@@ -86,27 +213,8 @@
+     return qApp-&gt;applicationName();
+ }

+-static OSStatus removeEntryImplementation(const QString&amp; walletName, const QString&amp; key) {
+-    const QByteArray serviceName( walletName.toUtf8() );
+-    const QByteArray accountName( key.toUtf8() );
+-    SecKeychainItemRef itemRef;
+-    QString errMsg;
+-    OSStatus result = SecKeychainFindGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), NULL, NULL, &amp;itemRef );
+-    if ( isError( result, &amp;errMsg ) ) {
+-        qWarning() &lt;&lt; &quot;Could not retrieve password:&quot;  &lt;&lt; qPrintable(errMsg);
+-        return result;
+-    }
+-    const CFReleaser&lt;SecKeychainItemRef&gt; itemReleaser( itemRef );
+-    result = SecKeychainItemDelete( itemRef );
+-    if ( isError( result, &amp;errMsg ) ) {
+-        qWarning() &lt;&lt; &quot;Could not delete password:&quot;  &lt;&lt; qPrintable(errMsg);
+-        return result;
+-    }
+-    return result;
+-}
+-
+-
+-const QString Wallet::LocalWallet() {
++/*static*/ const QString Wallet::LocalWallet()
++{
+     KConfigGroup cfg(KSharedConfig::openConfig(&quot;kwalletrc&quot;)-&gt;group(&quot;Wallet&quot;));
+     if (!cfg.readEntry(&quot;Use One Wallet&quot;, true)) {
+         QString tmp = cfg.readEntry(&quot;Local Wallet&quot;, &quot;localwallet&quot;);
+@@ -123,7 +231,8 @@
+     return tmp;
+ }

+-const QString Wallet::NetworkWallet() {
++/*static*/ const QString Wallet::NetworkWallet()
++{
+     KConfigGroup cfg(KSharedConfig::openConfig(&quot;kwalletrc&quot;)-&gt;group(&quot;Wallet&quot;));

+     QString tmp = cfg.readEntry(&quot;Default Wallet&quot;, &quot;kdewallet&quot;);
+@@ -133,132 +242,440 @@
+     return tmp;
+ }

+-const QString Wallet::PasswordFolder() {
++/*static*/ const QString Wallet::PasswordFolder()
++{
+     return &quot;Passwords&quot;;
+ }

+-const QString Wallet::FormDataFolder() {
++/*static*/ const QString Wallet::FormDataFolder()
++{
+     return &quot;Form Data&quot;;
+ }

+-class Wallet::WalletPrivate
++static QStringList getUsersFromRegistry(QString &amp;name)
++{   QString app = appid();
++    QStringList users;
++    users.clear();
++    if( walletUsers.contains(name) ){
++        WalletUsersListEntry entry = walletUsers[name];
++        for( WalletUsersListEntry::const_iterator it = entry.constBegin() ; it != entry.constEnd() ; ++it ){
++            if( !it.value().isEmpty() ){
++                users.append(it.key());
++            }
++        }
++    }
++    return users;
++}
++
++static void removeFromRegistry( QString app, QString &amp;name, WalletUsersListEntryData &amp;entries )
++{
++    for( WalletUsersListEntryData::const_iterator it = entries.constBegin() ; it != entries.constEnd() ; ++it ){
++        QPair&lt;WalletInstancePtr,pid_t&gt; wdat = *it;
++        if( walletUsers.contains(name) &amp;&amp; walletUsers[name].contains(app) ){
++            WalletUsersListEntry entry = walletUsers[name];
++            WalletUsersListEntryData appInstances = entry[app];
++            if( appInstances.contains(wdat) ){
++                appInstances.removeAll(wdat);
++                qDebug() &lt;&lt; &quot;removing application instance&quot; &lt;&lt; wdat &lt;&lt; &quot;from registry&quot;;
++            }
++            if( appInstances.isEmpty() ){
++                entry.remove(app);
++                qDebug() &lt;&lt; &quot;removing application&quot; &lt;&lt; app &lt;&lt; &quot;from registry&quot;;
++            }
++            else{
++                entry[app] = appInstances;
++            }
++            if( entry[app].isEmpty() ){
++                walletUsers.remove(name);
++                qDebug() &lt;&lt; &quot;removing wallet&quot; &lt;&lt; name &lt;&lt; &quot;from registry&quot;;
++            }
++            else{
++                walletUsers[name] = entry;
++            }
++        }
++    }
++}
++
++#pragma mark ==== Wallet::WalletPrivate ====
++class Wallet::WalletPrivate : public OSXKeychain
+ {
+ public:
+-    explicit WalletPrivate(const QString &amp;n)
+-     : name(n)
+-    {}
++    explicit WalletPrivate(Wallet *wallet, const QString &amp;n, int h)
++        : OSXKeychain(n, &amp;isNew), q(wallet), handle(h)
++        , idleTimer(NULL), idleTimerTriggered(0), lastConfigCheckTime(-1)
++    {
++        isKDEChain = ( n == LocalWallet() || n == NetworkWallet() || n.contains( &quot;wallet&quot;, Qt::CaseInsensitive ) );
++        if( !calibrator ){
++            init_HRTime();
++        }
++        if( isKDEChain ){
++            if( !lastAccessTime.attachOrCreate( (QString&amp;)n, QSharedMemory::ReadWrite) ){
++                qDebug() &lt;&lt; &quot;Couldn't create shared lastAccessTime member for wallet&quot; &lt;&lt; n
++                    &lt;&lt; &quot;; idle timeouts will be per-client. Error&quot; &lt;&lt; lastAccessTime.errorString();
++            }
++            handleIdleTiming(__FUNCTION__);
++        }
++    }
++    virtual ~WalletPrivate()
++    {
++        removeFromRegistry();
++        deleteIdleTimer();
++    }
++
++    void addToRegistry()
++    {   QString app = appid();
++        QPair&lt;WalletInstancePtr,pid_t&gt; wdat = qMakePair(QVariant((qulonglong)q),getpid());
++        if( !walletUsers.contains(name) ){
++            // Unknown wallet name, so there ought not be an existing QMap&lt;appName,walletInstanceList&gt;
++            WalletUsersListEntryData detail;
++            detail.clear();
++            detail.append(wdat);
++            WalletUsersListEntry entry;
++            entry.clear();
++            entry[app] = detail;
++            walletUsers[name] = entry;
++        }
++        else{
++            WalletUsersListEntry entry = walletUsers[name];
++            WalletUsersListEntryData detail;
++            if( entry.contains(app) ){
++                detail = entry[app];
++            }
++            else{
++                detail.clear();
++            }
++            detail.append(wdat);
++            entry[app] = detail;
++            walletUsers[name] = entry;
++        }
++        QByteArray mapData;
++        QDataStream ds(&amp;mapData, QIODevice::WriteOnly);
++        ds &lt;&lt; walletUsers;
++        qDebug() &lt;&lt; &quot;@@@&quot; &lt;&lt; HRTime_Time() &lt;&lt; &quot;Added&quot; &lt;&lt; wdat &lt;&lt; &quot;for app&quot; &lt;&lt; app &lt;&lt; &quot;to wallet&quot; &lt;&lt; name &lt;&lt; &quot;in registry of len=&quot; &lt;&lt; mapData.length() &lt;&lt; walletUsers;
++    }
++
++    void removeFromRegistry()
++    {
++        WalletUsersListEntryData entries = WalletUsersListEntryData::create(qMakePair(QVariant((qulonglong)q),getpid()));
++        KWallet::removeFromRegistry( appid(), name, entries );
++    }
++    QStringList getUsersFromRegistry()
++    {
++        return KWallet::getUsersFromRegistry(name);
++    }
++
++    virtual void close()
++    {
++//         // close the keychain wallet but only if we get here through the kwalletmanager
++//         // or TODO if wallets should be closed when the last client disconnects
++//         // and we are the last client.
++//         if( appid() == &quot;KDE Wallet Manager&quot; ){
++            deleteIdleTimer();
++            OSXKeychain::close();
++//         }
++    }
++    OSStatus lock()
++    {
++        if( idleTimer ){
++            idleTimer-&gt;stop();
++        }
++        return Lock(reference());
++    }

+-    // needed for compilation reasons
+-    void walletServiceUnregistered() {
++    void walletServiceUnregistered()
++    {
++#ifdef USE_KWALLETD
++        if( handle &gt;= 0 ){
++            q-&gt;slotWalletClosed(handle);
++        }
++#endif
+     }

+-    QString name;
+-    QString folder;
++    void deleteIdleTimer()
++    {
++        if( idleTimer ){
++            idleTimer-&gt;stop();
++            idleTimer-&gt;deleteLater();
++            idleTimer = NULL;
++        }
++    }
++    // This function is to be called at every operation that is supposed to launch or reset
++    // the idle timing.
++    void handleIdleTiming(const char *caller=&quot;&quot;, bool touchAccessTime=true)
++    {
++        if( !isKDEChain ){
++            return;
++        }
++        double now = HRTime_Time();
++        if( lastConfigCheckTime &lt; 0 || (now - lastConfigCheckTime &gt;= 10) ){
++            lastConfigCheckTime = now;
++            KConfigGroup cfg(KSharedConfig::openConfig(&quot;kwalletrc&quot;)-&gt;group(&quot;Wallet&quot;));
++            if (cfg.readEntry(&quot;Close When Idle&quot;, true)) {
++                timeOut = cfg.readEntry( &quot;Idle Timeout&quot;, ((int)0) );
++                if( caller &amp;&amp; idleTimer ){
++                    qDebug() &lt;&lt; &quot;###&quot; &lt;&lt; caller &lt;&lt; &quot;-&gt;handleIdleTiming: setting&quot; &lt;&lt; idleTimer &lt;&lt; &quot;for wallet&quot; &lt;&lt; name &lt;&lt; &quot;handle&quot; &lt;&lt; handle &lt;&lt; &quot;timeout to&quot; &lt;&lt; timeOut;
++                }
++            }
++            else{
++                timeOut = -1;
++            }
++        }
++        if( timeOut &gt;= 0 ){
++            if( !idleTimer ){
++                idleTimer = new QTimer(0);
++                connect( idleTimer, SIGNAL(timeout()), this, SLOT(slotIdleTimedOut()), Qt::DirectConnection );
++            }
++            else{
++                idleTimer-&gt;stop();
++            }
++            // when the idle timer fires, the wallet is supposed to be closed. There is thus
++            // no reason to use a repeating timer.
++            idleTimer-&gt;setSingleShot(true);
++            if( touchAccessTime ){
++                if( !lastAccessTime.setValue(HRTime_Time()) ){
++                    qDebug() &lt;&lt; &quot;Cannot set new lastAccessTime for wallet&quot; &lt;&lt; name &lt;&lt; &quot;error&quot; &lt;&lt; lastAccessTime.errorString();
++                }
++            }
++            idleTimer-&gt;start( timeOut * 60 * 1000 );
++        }
++        else{
++            timeOut = -1;
++            deleteIdleTimer();
++        }
++    }
++
++    void slotIdleTimedOut()
++    {   double lastTime = 0;
++        // check the last time anyone accessed this wallet:
++        if( !lastAccessTime.getValue(lastTime) ){
++            qDebug() &lt;&lt; &quot;Cannot get lastAccessTime for wallet&quot; &lt;&lt; name &lt;&lt; &quot;error&quot; &lt;&lt; lastAccessTime.errorString();
++        }
++        // the time elapsed since that last access, in minutes:
++        double elapsed = (HRTime_Time() - lastTime) / 60;
++    #ifdef IDLETIMER_DEBUG
++        idleTimerTriggered += 1;
++        qDebug() &lt;&lt; &quot;###&quot; &lt;&lt; HRTime_Time() &lt;&lt; appid() &lt;&lt; &quot;Idle timeout&quot; &lt;&lt; timeOut &lt;&lt; &quot;min. for&quot; &lt;&lt; q &lt;&lt; name &lt;&lt; &quot;handle&quot; &lt;&lt; handle
++            &lt;&lt; &quot;; elapsed minutes=&quot; &lt;&lt; elapsed &lt;&lt; &quot;timer&quot; &lt;&lt; idleTimer &lt;&lt; &quot;triggered&quot; &lt;&lt; idleTimerTriggered &lt;&lt; &quot;times&quot;;
++    #endif //IDLETIMER_DEBUG
++        if( elapsed &gt;= timeOut ){
++            // we have a true timeout, i.e. we didn't access the wallet in timeOut minutes, and no one else did either.
++            q-&gt;slotWalletClosed(handle);
++        }
++        else{
++            // false alarm, reset the timer, but there's no need to count this as an access!
++            handleIdleTiming(__FUNCTION__, false);
++        }
++    }
++
++public:
++    Wallet *q;
++    int handle;
++    bool isNew;
++    //! idle timeout in minutes
++    int timeOut;
++    QTimer *idleTimer;
++#ifdef IDLETIMER_DEBUG
++    size_t idleTimerTriggered;
++#endif
++    double lastConfigCheckTime;
++    QSharedValue&lt;double&gt; lastAccessTime;
+ };

+ Wallet::Wallet(int handle, const QString&amp; name)
+-    : QObject(0L), d(new WalletPrivate(name)) {
+-    Q_UNUSED(handle);
++    : QObject(0L), d(new WalletPrivate(this, name, handle))
++{
++#ifdef USE_KWALLETD
++    QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QString::fromLatin1(s_kwalletdServiceName), QDBusConnection::sessionBus(),
++                                                           QDBusServiceWatcher::WatchForUnregistration, this);
++    connect(watcher, SIGNAL(serviceUnregistered(QString)),
++            this, SLOT(walletServiceUnregistered()));
++
++    connect(&amp;walletLauncher-&gt;getInterface(), SIGNAL(walletClosed(int)), SLOT(slotWalletClosed(int)));
++    connect(&amp;walletLauncher-&gt;getInterface(), SIGNAL(folderListUpdated(QString)), SLOT(slotFolderListUpdated(QString)));
++    connect(&amp;walletLauncher-&gt;getInterface(), SIGNAL(folderUpdated(QString,QString)), SLOT(slotFolderUpdated(QString,QString)));
++    connect(&amp;walletLauncher-&gt;getInterface(), SIGNAL(applicationDisconnected(QString,QString)), SLOT(slotApplicationDisconnected(QString,QString)));
++#else
++    d-&gt;addToRegistry();
++#endif // USE_KWALLETD
++    if( d-&gt;handle != handle ){
++        qDebug() &lt;&lt; &quot;Wallet::Wallet(&quot; &lt;&lt; name &lt;&lt; &quot;) handle changed from&quot; &lt;&lt; handle &lt;&lt; &quot;to&quot; &lt;&lt; d-&gt;handle;
++    }
+ }

+-Wallet::~Wallet() {
++Wallet::~Wallet()
++{
+     delete d;
+ }

+-
+-QStringList Wallet::walletList() {
++/*static*/ QStringList Wallet::walletList()
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     return walletLauncher-&gt;getInterface().wallets();
+ #else
+-    return QStringList();
++    // RJVB: Mac OS X's Keychain supports multiple keychains, but they can only be accesses by full path, not
++    // found by name. That makes it cumbersome to map to multiple wallets when using only the wallet name.
++    // However, it would be perfectly possible to create OS X Keychains called Wallet::LocalWallet() and
++    // Wallet::NetworkWallet() in the equivalent of ~/.kde/share/apps/kwallet .
++    QStringList l;
++    OSXKeychain::KeychainList(l);
++    return l;
+ #endif
+ }


+-void Wallet::changePassword(const QString&amp; name, WId w) {
++/*static*/ void Wallet::changePassword(const QString&amp; name, WId w)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     if( w == 0 )
+         kDebug(285) &lt;&lt; &quot;Pass a valid window to KWallet::Wallet::changePassword().&quot;;
+     walletLauncher-&gt;getInterface().changePassword(name, (qlonglong)w, appid());
++#else
++    Q_UNUSED(w);
++    kWarning() &lt;&lt; &quot;Wallet::changePassword unimplemented '&quot; &lt;&lt; name &lt;&lt; &quot;'&quot;;
+ #endif
+ }


+-bool Wallet::isEnabled() {
++/*static*/ bool Wallet::isEnabled()
++{
+     //PENDING(frank) check
+     return true;
+ }


+-bool Wallet::isOpen(const QString&amp; name) {
++/*static*/ bool Wallet::isOpen(const QString&amp; name)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     return walletLauncher-&gt;getInterface().isOpen(name); // default is false
+ #else
+-    return true;
++#ifdef USE_KWALLETD
++    walletLauncher-&gt;getInterface().isOpen(name);
++#endif // USE_KWALLETD
++    return OSXKeychain::IsOpen(name);
++#endif
++}
++
++bool Wallet::isOpen() const
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    return d-&gt;handle != -1;
++#else
++    d-&gt;handleIdleTiming(__FUNCTION__);
++
++#ifdef USE_KWALLETD
++    QDBusReply&lt;bool&gt; r = walletLauncher-&gt;getInterface().isOpen(d-&gt;name);
++#endif // USE_KWALLETD
++    return d-&gt;isOpen();
+ #endif
+ }


+-int Wallet::closeWallet(const QString&amp; name, bool force) {
++/*static*/ int Wallet::closeWallet(const QString&amp; name, bool force)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     QDBusReply&lt;int&gt; r = walletLauncher-&gt;getInterface().close(name, force);
+     return r.isValid() ? r : -1;
+ #else
+-    return 0;
++    Q_UNUSED(force);
++#ifdef USE_KWALLETD
++    QDBusReply&lt;int&gt; r = walletLauncher-&gt;getInterface().close(name, force);
++#endif // USE_KWALLETD
++    // emit a signal that we just closed the wallet
++    Wallet(0, name).slotWalletClosed(0);
++    return OSXKeychain::IsOpen(name);
+ #endif
+ }


+-int Wallet::deleteWallet(const QString&amp; name) {
++/*static*/ int Wallet::deleteWallet(const QString&amp; name)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     QDBusReply&lt;int&gt; r = walletLauncher-&gt;getInterface().deleteWallet(name);
+     return r.isValid() ? r : -1;
+ #else
+-    return -1;
++    return OSXKeychain::Destroy(name);
+ #endif
+ }


+-Wallet *Wallet::openWallet(const QString&amp; name, WId w, OpenType ot) {
++/*static*/ Wallet *Wallet::openWallet(const QString&amp; name, WId w, OpenType ot)
++{
+     Q_UNUSED(w);
+     Q_UNUSED(ot);
+-    Wallet *wallet = new Wallet(-1, name);
+-    QMetaObject::invokeMethod( wallet, &quot;emitWalletOpened&quot;, Qt::QueuedConnection );
++    Wallet *wallet = new Wallet((int)w, name);
++    if( wallet ){
++#ifdef USE_KWALLETD
++        // connect the daemon's opened signal to the slot filtering the
++        // signals we need
++        connect(&amp;walletLauncher-&gt;getInterface(), SIGNAL(walletAsyncOpened(int,int)),
++                wallet, SLOT(walletAsyncOpened(int,int)));
++#endif
++        OSStatus err = wallet-&gt;d-&gt;unLock();
++        if( !err &amp;&amp; wallet-&gt;d-&gt;isKDEChain &amp;&amp; wallet-&gt;d-&gt;isNew ){
++            wallet-&gt;d-&gt;setLockSettings( false, 0 );
++        }
++        kDebug() &lt;&lt; &quot;Opened wallet '&quot; &lt;&lt; name &lt;&lt; &quot;': &quot; &lt;&lt; wallet &lt;&lt; &quot; error=&quot; &lt;&lt; err;
++#ifdef USE_KWALLETD
++        wallet-&gt;emitWalletOpened();
++#else
++        QMetaObject::invokeMethod( wallet, &quot;emitWalletOpened&quot;, Qt::QueuedConnection );
++#endif
++    }
+     return wallet;
+ }


+-bool Wallet::disconnectApplication(const QString&amp; wallet, const QString&amp; app) {
++/*static*/ bool Wallet::disconnectApplication(const QString&amp; wallet, const QString&amp; app)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     return walletLauncher-&gt;getInterface().disconnectApplication(wallet, app); // default is false
+ #else
+-    return true;
++    kWarning() &lt;&lt; &quot;Wallet::disconnectApplication unimplemented, '&quot; &lt;&lt; app &lt;&lt; &quot;' from '&quot; &lt;&lt; wallet &lt;&lt; &quot;'&quot;
++#ifdef USE_KWALLETD
++        &lt;&lt; walletLauncher-&gt;getInterface().disconnectApplication(wallet, app)
++#endif // USE_KWALLETD
++        ;
++    // app disconnect is done/possible only when the app in question closes its wallet.
++    return false;
+ #endif
+ }


+-QStringList Wallet::users(const QString&amp; name) {
++/*static*/ QStringList Wallet::users(const QString&amp; name)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     return walletLauncher-&gt;getInterface().users(name); // default is QStringList()
+ #else
+-    return QStringList();
++#ifdef USE_KWALLETD
++    QStringList ul = walletLauncher-&gt;getInterface().users(name);
++    kWarning() &lt;&lt; &quot;Wallet::users unimplemented, '&quot; &lt;&lt; name &lt;&lt; &quot;'&quot; &lt;&lt; ul;
++    return ul;
++#else
++    return KWallet::getUsersFromRegistry((QString&amp;)name);
++#endif // USE_KWALLETD
+ #endif
+ }


+-int Wallet::sync() {
++int Wallet::sync()
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     if (d-&gt;handle == -1) {
+         return -1;
+     }

+-    walletLauncher-&gt;getInterface().sync(d-&gt;handle, appid());
+ #endif
++    d-&gt;handleIdleTiming(__FUNCTION__);
++
++#ifdef USE_KWALLETD
++    walletLauncher-&gt;getInterface().sync(d-&gt;handle, appid());
++#endif // USE_KWALLETD
+     return 0;
+ }


+-int Wallet::lockWallet() {
++int Wallet::lockWallet()
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     if (d-&gt;handle == -1) {
+         return -1;
+@@ -271,26 +688,25 @@
+     if (r.isValid()) {
+         return r;
+     }
++#else
++    d-&gt;currentService.clear();
++    d-&gt;handle = -1;
+ #endif
+-    return -1;
++    d-&gt;lock();
++    emit walletClosed();
++    return 1;
+ }


+-const QString&amp; Wallet::walletName() const {
++const QString&amp; Wallet::walletName() const
++{
++    d-&gt;handleIdleTiming(__FUNCTION__);
+     return d-&gt;name;
+ }


+-bool Wallet::isOpen() const {
+-#ifdef OSX_KEYCHAIN_PORT_DISABLED
+-    return d-&gt;handle != -1;
+-#else
+-    return true;
+-#endif
+-}
+-
+-
+-void Wallet::requestChangePassword(WId w) {
++void Wallet::requestChangePassword(WId w)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     if( w == 0 )
+         kDebug(285) &lt;&lt; &quot;Pass a valid window to KWallet::Wallet::requestChangePassword().&quot;;
+@@ -299,11 +715,16 @@
+     }

+     walletLauncher-&gt;getInterface().changePassword(d-&gt;name, (qlonglong)w, appid());
++#else
++    Q_UNUSED(w);
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    kWarning() &lt;&lt; &quot;Wallet::requestChangePassword unimplemented '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
+ #endif
+ }


+-void Wallet::slotWalletClosed(int handle) {
++void Wallet::slotWalletClosed(int handle)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     if (d-&gt;handle == handle) {
+         d-&gt;handle = -1;
+@@ -311,11 +732,25 @@
+         d-&gt;name.clear();
+         emit walletClosed();
+     }
++#else
++//     kWarning() &lt;&lt; &quot;Wallet::slotWalletClosed unimplemented '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++    if( d-&gt;handle == handle ){
++        d-&gt;handle = -1;
++        d-&gt;currentService.clear();
++        kDebug() &lt;&lt; &quot;Wallet::slotWalletClosed '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++        // TODO remove ourselves from the WalletUsersList here!
++        d-&gt;close();
++        emit walletClosed();
++    }
++    else{
++        qDebug() &lt;&lt; &quot;Wallet::slotWalletClosed '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;' ignored because handle&quot; &lt;&lt; d-&gt;handle &lt;&lt; &quot;!=&quot; &lt;&lt; handle;
++    }
+ #endif
+ }


+-QStringList Wallet::folderList() {
++QStringList Wallet::folderList()
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     if (d-&gt;handle == -1) {
+         return QStringList();
+@@ -324,12 +759,14 @@
+     QDBusReply&lt;QStringList&gt; r = walletLauncher-&gt;getInterface().folderList(d-&gt;handle, appid());
+     return r;
+ #else
+-    return QStringList();
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    return QStringList(d-&gt;folderList());
+ #endif
+ }


+-QStringList Wallet::entryList() {
++QStringList Wallet::entryList()
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     if (d-&gt;handle == -1) {
+         return QStringList();
+@@ -338,12 +775,17 @@
+     QDBusReply&lt;QStringList&gt; r = walletLauncher-&gt;getInterface().entryList(d-&gt;handle, d-&gt;folder, appid());
+     return r;
+ #else
+-    return QStringList();
++    d-&gt;handleIdleTiming(__FUNCTION__);
++
++    QStringList r = QStringList();
++    d-&gt;itemList(r);
++    return r;
+ #endif
+ }


+-bool Wallet::hasFolder(const QString&amp; f) {
++bool Wallet::hasFolder(const QString&amp; f)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     if (d-&gt;handle == -1) {
+         return false;
+@@ -352,12 +794,15 @@
+     QDBusReply&lt;bool&gt; r = walletLauncher-&gt;getInterface().hasFolder(d-&gt;handle, f, appid());
+     return r; // default is false
+ #else
+-    return true;
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    d-&gt;folderList();
++    return d-&gt;serviceList.contains(f);
+ #endif
+ }


+-bool Wallet::createFolder(const QString&amp; f) {
++bool Wallet::createFolder(const QString&amp; f)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     if (d-&gt;handle == -1) {
+         return false;
+@@ -370,12 +815,14 @@

+     return true;                                // folder already exists
+ #else
+-    return true;
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    return setFolder(f);
+ #endif
+ }


+-bool Wallet::setFolder(const QString&amp; f) {
++bool Wallet::setFolder(const QString &amp;f)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     bool rc = false;

+@@ -397,12 +844,22 @@

+     return rc;
+ #else
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    // act as if we just changed folders even if we have no such things; the property
++    // is stored as the ServiceItemAttr (which shows up as the &quot;Where&quot; field in the Keychain Utility).
++    if( f.size() == 0 ){
++        d-&gt;currentService.clear();
++    }
++    else{
++        d-&gt;currentService = QString(f);
++    }
+     return true;
+ #endif
+ }


+-bool Wallet::removeFolder(const QString&amp; f) {
++bool Wallet::removeFolder(const QString&amp; f)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     if (d-&gt;handle == -1) {
+         return false;
+@@ -415,34 +872,38 @@

+     return r;                                        // default is false
+ #else
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    kWarning() &lt;&lt; &quot;Wallet::removeFolder unimplemented (returns true) '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++    if( d-&gt;currentService == f ){
++        d-&gt;currentService.clear();
++    }
+     return true;
+ #endif
+ }


+-const QString&amp; Wallet::currentFolder() const {
++const QString&amp; Wallet::currentFolder() const
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
+     return d-&gt;folder;
++#else
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    return d-&gt;currentService;
++#endif
+ }


+-int Wallet::readEntry(const QString&amp; key, QByteArray&amp; value) {
+-    const QByteArray serviceName( walletName().toUtf8() );
+-    const QByteArray accountName( key.toUtf8() );
+-    UInt32 passwordSize = 0;
+-    void* passwordData = 0;
+-    QString errMsg;
+-    if ( isError( SecKeychainFindGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), &amp;passwordSize, &amp;passwordData, NULL ), &amp;errMsg ) ) {
+-        qWarning() &lt;&lt; &quot;Could not retrieve password:&quot;  &lt;&lt; qPrintable(errMsg);
+-        return -1;
+-    }
+-
+-    value = QByteArray( reinterpret_cast&lt;const char*&gt;( passwordData ), passwordSize );
+-    SecKeychainItemFreeContent( NULL, passwordData );
+-    return 0;
++int Wallet::readEntry(const QString &amp;key, QByteArray &amp;value)
++{   OSStatus err;
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    err = d-&gt;readItem( key, &amp;value, NULL );
++    kDebug() &lt;&lt; &quot;Wallet::readEntry '&quot; &lt;&lt; key &lt;&lt; &quot;' from wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ((err)? -1 : 0);
++    return (err)? -1 : 0;
+ }


+-int Wallet::readEntryList(const QString&amp; key, QMap&lt;QString, QByteArray&gt;&amp; value) {
++int Wallet::readEntryList(const QString&amp; key, QMap&lt;QString, QByteArray&gt;&amp; value)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     registerTypes();

+@@ -464,12 +925,17 @@

+     return rc;
+ #else
++    Q_UNUSED(key);
++    Q_UNUSED(value);
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    kWarning() &lt;&lt; &quot;Wallet::readEntryList unimplemented (returns -1) '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
+     return -1;
+ #endif
+ }


+-int Wallet::renameEntry(const QString&amp; oldName, const QString&amp; newName) {
++int Wallet::renameEntry(const QString&amp; oldName, const QString&amp; newName)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     int rc = -1;

+@@ -484,25 +950,33 @@

+     return rc;
+ #else
+-    return -1;
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    return d-&gt;renameItem( oldName, newName );
+ #endif
+ }


+-int Wallet::readMap(const QString&amp; key, QMap&lt;QString,QString&gt;&amp; value) {
++int Wallet::readMap(const QString &amp;key, QMap&lt;QString,QString&gt; &amp;value)
++{
++    d-&gt;handleIdleTiming(__FUNCTION__);
++
+     QByteArray v;
+-    const int ret = readEntry( key, v );
+-    if ( ret != 0 )
++    const int ret = (d-&gt;readItem( key, &amp;v, NULL ))? -1 : 0;
++    if( ret != 0 ){
+         return ret;
+-    if ( !v.isEmpty() ) {
+-        QDataStream ds( &amp;v, QIODevice::ReadOnly );
++    }
++    if( !v.isEmpty() ){
++        QByteArray w = QByteArray::fromBase64(v);
++        QDataStream ds( &amp;w, QIODevice::ReadOnly );
+         ds &gt;&gt; value;
+     }
++    kDebug() &lt;&lt; &quot;Wallet::readMap '&quot; &lt;&lt; key &lt;&lt; &quot;' from wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=0&quot;;
+     return 0;
+ }


+-int Wallet::readMapList(const QString&amp; key, QMap&lt;QString, QMap&lt;QString, QString&gt; &gt;&amp; value) {
++int Wallet::readMapList(const QString&amp; key, QMap&lt;QString, QMap&lt;QString, QString&gt; &gt;&amp; value)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     registerTypes();

+@@ -530,81 +1004,119 @@

+     return rc;
+ #else
++    Q_UNUSED(key);
++    Q_UNUSED(value);
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    kWarning() &lt;&lt; &quot;Wallet::readMapList unimplemented (returns -1) '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
+     return -1;
+ #endif
+ }


+-int Wallet::readPassword(const QString&amp; key, QString&amp; value) {
++int Wallet::readPassword(const QString&amp; key, QString&amp; value)
++{
++    d-&gt;handleIdleTiming(__FUNCTION__);
++
+     QByteArray ba;
+-    const int ret = readEntry( key, ba );
+-    if ( ret == 0 )
++    const int ret = (d-&gt;readItem( key, &amp;ba, NULL ))? -1 : 0;
++    if ( ret == 0 ){
+         value = QString::fromUtf8( ba.constData() );
++    }
++    kDebug() &lt;&lt; &quot;Wallet::readPassword '&quot; &lt;&lt; key &lt;&lt; &quot;' from wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
+     return ret;
+ }


+-int Wallet::readPasswordList(const QString&amp; key, QMap&lt;QString, QString&gt;&amp; value) {
++int Wallet::readPasswordList(const QString&amp; key, QMap&lt;QString, QString&gt;&amp; value)
++{
++    Q_UNUSED(key);
++    Q_UNUSED(value);
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    kWarning() &lt;&lt; &quot;Wallet::readPasswordList unimplemented (returns -1) '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
+     return -1;
+ }

+-static OSStatus writeEntryImplementation( const QString&amp; walletName, const QString&amp; key, const QByteArray&amp; value ) {
+-    const QByteArray serviceName( walletName.toUtf8() );
+-    const QByteArray accountName( key.toUtf8() );
+-    QString errMsg;
+-    OSStatus err = SecKeychainAddGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), value.size(), value.constData(), NULL );
+-    if (err == errSecDuplicateItem) {
+-        err = removeEntryImplementation( walletName, key );
+-        if ( isError( err, &amp;errMsg ) ) {
+-            kWarning() &lt;&lt; &quot;Could not delete old key in keychain for replacing: &quot; &lt;&lt; qPrintable(errMsg);
+-            return err;
+-        }
+-    }
+-    if ( isError( err, &amp;errMsg ) ) {
+-        kWarning() &lt;&lt; &quot;Could not store password in keychain: &quot; &lt;&lt; qPrintable(errMsg);
+-        return err;
+-    }
+-    kDebug() &lt;&lt; &quot;Succesfully written out key:&quot; &lt;&lt; key;
+-    return err;
+-
+-}
+-
+-int Wallet::writeEntry(const QString&amp; key, const QByteArray&amp; password, EntryType entryType) {
+-    Q_UNUSED( entryType )
+-    return writeEntryImplementation( walletName(), key, password );
++int Wallet::writeEntry(const QString&amp; key, const QByteArray&amp; password )
++{   int ret;
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    ret = d-&gt;writeItem( key, password );
++    kDebug() &lt;&lt; &quot;wrote entry '&quot; &lt;&lt; key &lt;&lt; &quot;' to wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
+ }

++int Wallet::writeEntry(const QString&amp; key, const QByteArray&amp; password, EntryType entryType)
++{
++    d-&gt;handleIdleTiming(__FUNCTION__);

+-int Wallet::writeEntry(const QString&amp; key, const QByteArray&amp; value) {
+-    return writeEntryImplementation( walletName(), key, value );
++    OSXKeychain::EntryType entryCode;
++        switch( entryType ){
++                case Wallet::Password:
++                        entryCode = OSXKeychain::Password;
++                        break;
++                case Wallet::Map:
++                        entryCode = OSXKeychain::Map;
++                        break;
++        case Wallet::Stream:
++            entryCode = OSXKeychain::Stream;
++            break;
++                default:
++                        entryCode = OSXKeychain::Unknown;
++                        break;
++        }
++        int ret = d-&gt;writeItem( key, password, &amp;entryCode );
++    kDebug() &lt;&lt; &quot;wrote entry '&quot; &lt;&lt; key &lt;&lt; &quot;' of type=&quot; &lt;&lt; (int) entryType &lt;&lt; &quot;to wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
+ }

++int Wallet::writeMap(const QString&amp; key, const QMap&lt;QString,QString&gt;&amp; value)
++{
++    d-&gt;handleIdleTiming(__FUNCTION__);

+-int Wallet::writeMap(const QString&amp; key, const QMap&lt;QString,QString&gt;&amp; value) {
+     QByteArray mapData;
+     QDataStream ds(&amp;mapData, QIODevice::WriteOnly);
+     ds &lt;&lt; value;
+-    return writeEntry( key, mapData );
++    OSXKeychain::EntryType etype = OSXKeychain::Map;
++    int ret = d-&gt;writeItem( key, mapData.toBase64(),
++                           &quot;This is a KDE Wallet::Map item. Its password\n&quot;
++                           &quot;cannot be read in the OS X Keychain Utility.\n&quot;
++                           &quot;Use KDE's own kwalletmanager for that.&quot;, &amp;etype );
++    kDebug() &lt;&lt; &quot;wrote map '&quot; &lt;&lt; key &lt;&lt; &quot;' to wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
+ }


+-int Wallet::writePassword(const QString&amp; key, const QString&amp; value) {
+-    return writeEntry( key, value.toUtf8() );
++int Wallet::writePassword(const QString &amp;key, const QString&amp; value)
++{   OSXKeychain::EntryType etype;
++
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    etype = OSXKeychain::Password;
++    int ret = d-&gt;writeItem( key, value.toUtf8(), &amp;etype );
++    kDebug() &lt;&lt; &quot;wrote password '&quot; &lt;&lt; key &lt;&lt; &quot;' to wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
+ }


+-bool Wallet::hasEntry(const QString&amp; key) {
+-    const QByteArray serviceName( walletName().toUtf8() );
+-    const QByteArray accountName( key.toUtf8() );
+-    return !isError( SecKeychainFindGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), NULL, NULL, NULL ), 0 );
++bool Wallet::hasEntry(const QString &amp;key)
++{   bool ret;
++
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    ret = d-&gt;hasItem( key, NULL );
++    kDebug() &lt;&lt; &quot;wallet '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot; &lt;&lt; ((ret)? &quot; has&quot; : &quot; does not have&quot;) &lt;&lt; &quot; entry '&quot; &lt;&lt; key &lt;&lt; &quot;'&quot;;
++    return ret;
+ }

+-int Wallet::removeEntry(const QString&amp; key) {
+-    return removeEntryImplementation( walletName(), key );
++int Wallet::removeEntry(const QString&amp; key)
++{   int ret;
++
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    ret = d-&gt;removeItem( key );
++    kDebug() &lt;&lt; &quot;removed entry '&quot; &lt;&lt; key &lt;&lt; &quot;' from wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
+ }


+-Wallet::EntryType Wallet::entryType(const QString&amp; key) {
++Wallet::EntryType Wallet::entryType(const QString&amp; key)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     int rc = 0;

+@@ -619,94 +1131,208 @@

+     return static_cast&lt;EntryType&gt;(rc);
+ #else
++    d-&gt;handleIdleTiming(NULL);
++
++    // RJVB: a priori, entries are always 'password' on OS X, but since we also do use them for storing
++    // maps, it may be best to return Wallet::Unknown to leave some uncertainty and not mislead our caller.
++    OSXKeychain::EntryType etype;
++    if( !d-&gt;itemType( key, &amp;etype ) ){
++        switch( etype ){
++            case OSXKeychain::Password:
++                return Wallet::Password;
++                break;
++            case OSXKeychain::Map:
++                return Wallet::Map;
++                break;
++            case OSXKeychain::Stream:
++                return Wallet::Stream;
++                break;
++        }
++    }
+     return Wallet::Unknown;
+ #endif
+ }


+-void Wallet::slotFolderUpdated(const QString&amp; wallet, const QString&amp; folder) {
++void Wallet::slotFolderUpdated(const QString&amp; wallet, const QString&amp; folder)
++{
+     if (d-&gt;name == wallet) {
++        kDebug() &lt;&lt; &quot;emit folderUpdated&quot; &lt;&lt; folder;
+         emit folderUpdated(folder);
+     }
+ }


+-void Wallet::slotFolderListUpdated(const QString&amp; wallet) {
++void Wallet::slotFolderListUpdated(const QString&amp; wallet)
++{
+     if (d-&gt;name == wallet) {
++        kDebug() &lt;&lt; &quot;emit foldeListrUpdated&quot; &lt;&lt; wallet;
+         emit folderListUpdated();
+     }
+ }


+-void Wallet::slotApplicationDisconnected(const QString&amp; wallet, const QString&amp; application) {
+-#ifdef OSX_KEYCHAIN_PORT_DISABLED
+-    if (d-&gt;handle &gt;= 0
++void Wallet::slotApplicationDisconnected(const QString&amp; wallet, const QString&amp; application)
++{
++#ifdef USE_KWALLETD
++    qDebug() &lt;&lt; &quot;slotApplicationDisconnected(&quot; &lt;&lt; wallet &lt;&lt; &quot;,&quot; &lt;&lt; application &lt;&lt; &quot;); handle=&quot;
++        &lt;&lt; d-&gt;handle &lt;&lt; &quot;name=&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;appid=&quot; &lt;&lt; appid();
++    if( d-&gt;handle &gt;= 0
+         &amp;&amp; d-&gt;name == wallet
+-        &amp;&amp; application == appid()) {
++        &amp;&amp; application == appid()
++    ){
+         slotWalletClosed(d-&gt;handle);
+     }
+-#endif
++#else
++    Q_UNUSED(wallet);
++    Q_UNUSED(application);
++#endif //USE_KWALLETD
+ }

+-void Wallet::walletAsyncOpened(int tId, int handle) {
++void Wallet::walletAsyncOpened(int tId, int handle)
++{
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     // ignore responses to calls other than ours
+     if (d-&gt;transactionId != tId || d-&gt;handle != -1) {
+         return;
+     }
+-    
++
+     // disconnect the async signal
+     disconnect(this, SLOT(walletAsyncOpened(int,int)));
+-    
++
+     d-&gt;handle = handle;
+     emit walletOpened(handle &gt; 0);
++#else
++    Q_UNUSED(tId);
++    d-&gt;handleIdleTiming(__FUNCTION__);
++#ifdef USE_KWALLETD
++    // disconnect the async signal
++    disconnect(this, SLOT(walletAsyncOpened(int,int)));
++    qDebug() &lt;&lt; &quot;walletAsyncOpened: emit walletOpened(true), handle=&quot; &lt;&lt; handle;
++    emit walletOpened(true);
++#endif // USE_KWALLETD
++    d-&gt;handle = handle;
+ #endif
+ }

+-void Wallet::emitWalletAsyncOpenError() {
++void Wallet::emitWalletAsyncOpenError()
++{
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    kDebug() &lt;&lt; &quot;emitWalletAsyncOpenError: emit walletOpened(false)&quot;;
+     emit walletOpened(false);
+ }

+-void Wallet::emitWalletOpened() {
+-  emit walletOpened(true);
++void Wallet::emitWalletOpened()
++{
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    kDebug() &lt;&lt; &quot;emitWalletOpened: emit walletOpened(true)&quot;;
++    emit walletOpened(true);
+ }


+-bool Wallet::folderDoesNotExist(const QString&amp; wallet, const QString&amp; folder)
++/*static*/ bool Wallet::folderDoesNotExist(const QString&amp; wallet, const QString&amp; folder)
+ {
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     QDBusReply&lt;bool&gt; r = walletLauncher-&gt;getInterface().folderDoesNotExist(wallet, folder);
+     return r;
+ #else
+-    return false;
++    bool ret = true;
++    if( Wallet::walletList().contains(wallet) ){
++        ret = !Wallet(-1, wallet).hasFolder(folder);
++    }
++    return ret;
+ #endif
+ }


+-bool Wallet::keyDoesNotExist(const QString&amp; wallet, const QString&amp; folder, const QString&amp; key)
++/*static*/ bool Wallet::keyDoesNotExist(const QString&amp; wallet, const QString&amp; folder, const QString&amp; key)
+ {
+ #ifdef OSX_KEYCHAIN_PORT_DISABLED
+     QDBusReply&lt;bool&gt; r = walletLauncher-&gt;getInterface().keyDoesNotExist(wallet, folder, key);
+     return r;
+ #else
+-    return false;
++    bool ret = true;
++    if( Wallet::walletList().contains(wallet) ){
++        Wallet w(-1, wallet);
++        if( w.hasFolder(folder) ){
++            ret = !w.hasEntry(key);
++        }
++    }
++    return ret;
+ #endif
+ }

+ void Wallet::slotCollectionStatusChanged(int status)
+ {
++    Q_UNUSED(status);
++    d-&gt;handleIdleTiming(__FUNCTION__);
++    kWarning() &lt;&lt; &quot;Wallet::slotCollectionStatusChanged unimplemented '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;' status=&quot; &lt;&lt; status;
+ }

+ void Wallet::slotCollectionDeleted()
+ {
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
+     d-&gt;folder.clear();
+-    d-&gt;name.clear();
++#else
++    d-&gt;currentService.clear();
++#endif
++    kDebug() &lt;&lt; &quot;Wallet::slotCollectionDeleted: closing private data '&quot; &lt;&lt; d-&gt;name;
++    // TODO remove ourselves from the WalletUsersList here!
++    d-&gt;close();
+     emit walletClosed();
+ }


+-void Wallet::virtual_hook(int, void*) {
++void Wallet::virtual_hook(int, void*)
++{
+     //BASE::virtual_hook( id, data );
+ }

++#ifdef USE_KWALLETD
++KWalletDLauncher::KWalletDLauncher()
++    : m_wallet(0),
++    m_cgroup(KSharedConfig::openConfig(&quot;kwalletrc&quot;, KConfig::NoGlobals)-&gt;group(&quot;Wallet&quot;))
++{
++    m_wallet = new org::kde::KWallet(QString::fromLatin1(s_kwalletdServiceName), &quot;/modules/kwalletd&quot;, QDBusConnection::sessionBus());
++}
++
++KWalletDLauncher::~KWalletDLauncher()
++{
++    delete m_wallet;
++}
++
++org::kde::KWallet &amp;KWalletDLauncher::getInterface()
++{
++    Q_ASSERT(m_wallet != 0);
++
++    // check if kwalletd is already running
++    if (!QDBusConnection::sessionBus().interface()-&gt;isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName)))
++    {
++        // not running! check if it is enabled.
++        bool walletEnabled = m_cgroup.readEntry(&quot;Enabled&quot;, true);
++        if (walletEnabled) {
++            // wallet is enabled! try launching it
++            QString error;
++            int ret = KToolInvocation::startServiceByDesktopPath(&quot;kwalletd.desktop&quot;, QStringList(), &amp;error);
++            if (ret &gt; 0){
++                kError(285) &lt;&lt; &quot;Couldn't start kwalletd: &quot; &lt;&lt; error &lt;&lt; endl;
++            }
++
++            if (!QDBusConnection::sessionBus().interface()-&gt;isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName))) {
++                kDebug(285) &lt;&lt; &quot;The kwalletd service is still not registered&quot;;
++            } else {
++                kDebug(285) &lt;&lt; &quot;The kwalletd service has been registered&quot;;
++            }
++        } else {
++            kError(285) &lt;&lt; &quot;The kwalletd service has been disabled&quot;;
++        }
++    }
++
++    return *m_wallet;
++}
++#endif //USE_KWALLETD
++
++} // namespace KWallet
++
++#include &quot;qosxkeychain.moc&quot;
+ #include &quot;kwallet.moc&quot;
+diff -urN kdelibs-4.13.3-orig/kdeui/util/kwallet_mac.cpp.orig kdelibs-4.13.3/kdeui/util/kwallet_mac.cpp.orig
+--- kdelibs-4.13.3-orig/kdeui/util/kwallet_mac.cpp.orig        1970-01-01 09:00:00.000000000 +0900
++++ kdelibs-4.13.3/kdeui/util/kwallet_mac.cpp.orig        2014-09-22 19:46:10.000000000 +0900
+@@ -0,0 +1,809 @@
++/* @file kwallet_mac.cpp
++ * This file is part of the KDE project
++ *
++ * Copyright (C) 2002-2004 George Staikos &lt;staikos@kde.org&gt;
++ * Copyright (C) 2008 Michael Leupold &lt;lemma@confuego.org&gt;
++ * Copyright (C) 2010 Frank Osterfeld &lt;osterfeld@kde.org&gt;
++ * Copyright (C) 2014 René Bertin &lt;rjvbertin@gmail.com&gt;
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB.  If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#include &quot;kwallet.h&quot;
++#include &lt;ksharedconfig.h&gt;
++#include &lt;kdebug.h&gt;
++#include &lt;kdeversion.h&gt;
++#include &lt;QtGui/QApplication&gt;
++#include &lt;QtCore/QPointer&gt;
++#include &lt;QtGui/QWidget&gt;
++#include &lt;ktoolinvocation.h&gt;
++
++#include &lt;kglobal.h&gt;
++#include &lt;kcomponentdata.h&gt;
++#include &lt;kaboutdata.h&gt;
++#include &lt;kconfiggroup.h&gt;
++
++#include &lt;cassert&gt;
++
++#include &lt;sys/param.h&gt;
++
++#include &quot;qosxkeychain.h&quot;
++
++using namespace KWallet;
++
++typedef QMap&lt;QString, QString&gt; StringStringMap;
++Q_DECLARE_METATYPE(StringStringMap)
++typedef QMap&lt;QString, StringStringMap&gt; StringToStringStringMapMap;
++Q_DECLARE_METATYPE(StringToStringStringMapMap)
++typedef QMap&lt;QString, QByteArray&gt; StringByteArrayMap;
++Q_DECLARE_METATYPE(StringByteArrayMap)
++
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++static QString appid()
++{
++    KComponentData cData = KGlobal::mainComponent();
++    if (cData.isValid()) {
++        const KAboutData* aboutData = cData.aboutData();
++        if (aboutData) {
++            return aboutData-&gt;programName();
++        }
++        return cData.componentName();
++    }
++    return qApp-&gt;applicationName();
++}
++#endif
++
++/*static*/ const QString Wallet::LocalWallet()
++{
++    KConfigGroup cfg(KSharedConfig::openConfig(&quot;kwalletrc&quot;)-&gt;group(&quot;Wallet&quot;));
++    if (!cfg.readEntry(&quot;Use One Wallet&quot;, true)) {
++        QString tmp = cfg.readEntry(&quot;Local Wallet&quot;, &quot;localwallet&quot;);
++        if (tmp.isEmpty()) {
++            return &quot;localwallet&quot;;
++        }
++        return tmp;
++    }
++
++    QString tmp = cfg.readEntry(&quot;Default Wallet&quot;, &quot;kdewallet&quot;);
++    if (tmp.isEmpty()) {
++        return &quot;kdewallet&quot;;
++    }
++    return tmp;
++}
++
++/*static*/ const QString Wallet::NetworkWallet()
++{
++    KConfigGroup cfg(KSharedConfig::openConfig(&quot;kwalletrc&quot;)-&gt;group(&quot;Wallet&quot;));
++
++    QString tmp = cfg.readEntry(&quot;Default Wallet&quot;, &quot;kdewallet&quot;);
++    if (tmp.isEmpty()) {
++        return &quot;kdewallet&quot;;
++    }
++    return tmp;
++}
++
++/*static*/ const QString Wallet::PasswordFolder()
++{
++    return &quot;Passwords&quot;;
++}
++
++/*static*/ const QString Wallet::FormDataFolder()
++{
++    return &quot;Form Data&quot;;
++}
++
++#pragma mark ==== Wallet::WalletPrivate ====
++class Wallet::WalletPrivate : public OSXKeychain
++{
++public:
++    explicit WalletPrivate(const QString &amp;n)
++        : OSXKeychain(n)
++    {
++        isKDEChain = ( n == LocalWallet() || n == NetworkWallet() || n.contains( &quot;wallet&quot;, Qt::CaseInsensitive ) );
++    }
++
++    // needed for compilation reasons
++    void walletServiceUnregistered()
++    {
++    }
++};
++
++Wallet::Wallet(int handle, const QString&amp; name)
++    : QObject(0L), d(new WalletPrivate(name))
++{
++    Q_UNUSED(handle);
++}
++
++Wallet::~Wallet()
++{
++    delete d;
++}
++
++/*static*/ QStringList Wallet::walletList()
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    return walletLauncher-&gt;getInterface().wallets();
++#else
++    // RJVB: Mac OS X's Keychain supports multiple keychains, but they can only be accesses by full path, not
++    // found by name. That makes it cumbersome to map to multiple wallets when using only the wallet name.
++    // However, it would be perfectly possible to create OS X Keychains called Wallet::LocalWallet() and
++    // Wallet::NetworkWallet() in the equivalent of ~/.kde/share/apps/kwallet .
++    QStringList l;
++    OSXKeychain::KeychainList(l);
++    return l;
++#endif
++}
++
++
++/*static*/ void Wallet::changePassword(const QString&amp; name, WId w)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if( w == 0 )
++        kDebug(285) &lt;&lt; &quot;Pass a valid window to KWallet::Wallet::changePassword().&quot;;
++    walletLauncher-&gt;getInterface().changePassword(name, (qlonglong)w, appid());
++#else
++    Q_UNUSED(w);
++    kWarning() &lt;&lt; &quot;Wallet::changePassword unimplemented '&quot; &lt;&lt; name &lt;&lt; &quot;'&quot;;
++#endif
++}
++
++
++/*static*/ bool Wallet::isEnabled()
++{
++    //PENDING(frank) check
++    return true;
++}
++
++
++/*static*/ bool Wallet::isOpen(const QString&amp; name)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    return walletLauncher-&gt;getInterface().isOpen(name); // default is false
++#else
++    return OSXKeychain::IsOpen(name);
++#endif
++}
++
++bool Wallet::isOpen() const
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    return d-&gt;handle != -1;
++#else
++    return d-&gt;isOpen();
++#endif
++}
++
++
++/*static*/ int Wallet::closeWallet(const QString&amp; name, bool force)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    QDBusReply&lt;int&gt; r = walletLauncher-&gt;getInterface().close(name, force);
++    return r.isValid() ? r : -1;
++#else
++    Q_UNUSED(force);
++    return OSXKeychain::Lock(name);
++#endif
++}
++
++
++/*static*/ int Wallet::deleteWallet(const QString&amp; name)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    QDBusReply&lt;int&gt; r = walletLauncher-&gt;getInterface().deleteWallet(name);
++    return r.isValid() ? r : -1;
++#else
++    return OSXKeychain::Destroy(name);
++#endif
++}
++
++
++/*static*/ Wallet *Wallet::openWallet(const QString&amp; name, WId w, OpenType ot)
++{
++    Q_UNUSED(w);
++    Q_UNUSED(ot);
++    Wallet *wallet = new Wallet(-1, name);
++    QMetaObject::invokeMethod( wallet, &quot;emitWalletOpened&quot;, Qt::QueuedConnection );
++    OSStatus err = wallet-&gt;d-&gt;unLock();
++    kDebug() &lt;&lt; &quot;Opened wallet '&quot; &lt;&lt; name &lt;&lt; &quot;': &quot; &lt;&lt; wallet &lt;&lt; &quot; error=&quot; &lt;&lt; err;
++    return wallet;
++}
++
++
++/*static*/ bool Wallet::disconnectApplication(const QString&amp; wallet, const QString&amp; app)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    return walletLauncher-&gt;getInterface().disconnectApplication(wallet, app); // default is false
++#else
++    kWarning() &lt;&lt; &quot;Wallet::disconnectApplication unimplemented, '&quot; &lt;&lt; app &lt;&lt; &quot;' from '&quot; &lt;&lt; wallet &lt;&lt; &quot;'&quot;;
++    return true;
++#endif
++}
++
++
++/*static*/ QStringList Wallet::users(const QString&amp; name)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    return walletLauncher-&gt;getInterface().users(name); // default is QStringList()
++#else
++    kWarning() &lt;&lt; &quot;Wallet::users unimplemented, '&quot; &lt;&lt; name &lt;&lt; &quot;'&quot;;
++    return QStringList();
++#endif
++}
++
++
++int Wallet::sync()
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if (d-&gt;handle == -1) {
++        return -1;
++    }
++
++    walletLauncher-&gt;getInterface().sync(d-&gt;handle, appid());
++#endif
++    return 0;
++}
++
++
++int Wallet::lockWallet()
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if (d-&gt;handle == -1) {
++        return -1;
++    }
++
++    QDBusReply&lt;int&gt; r = walletLauncher-&gt;getInterface().close(d-&gt;handle, true, appid());
++    d-&gt;handle = -1;
++    d-&gt;folder.clear();
++    d-&gt;name.clear();
++    if (r.isValid()) {
++        return r;
++    }
++#else
++    d-&gt;currentService.clear();
++#endif
++    return d-&gt;lock();
++}
++
++
++const QString&amp; Wallet::walletName() const
++{
++    return d-&gt;name;
++}
++
++
++void Wallet::requestChangePassword(WId w)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if( w == 0 )
++        kDebug(285) &lt;&lt; &quot;Pass a valid window to KWallet::Wallet::requestChangePassword().&quot;;
++    if (d-&gt;handle == -1) {
++        return;
++    }
++
++    walletLauncher-&gt;getInterface().changePassword(d-&gt;name, (qlonglong)w, appid());
++#else
++    Q_UNUSED(w);
++    kWarning() &lt;&lt; &quot;Wallet::requestChangePassword unimplemented '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++#endif
++}
++
++
++void Wallet::slotWalletClosed(int handle)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if (d-&gt;handle == handle) {
++        d-&gt;handle = -1;
++        d-&gt;folder.clear();
++        d-&gt;name.clear();
++        emit walletClosed();
++    }
++#else
++    Q_UNUSED(handle);
++    kWarning() &lt;&lt; &quot;Wallet::slotWalletClosed unimplemented '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++    d-&gt;currentService.clear();
++#endif
++}
++
++
++QStringList Wallet::folderList()
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if (d-&gt;handle == -1) {
++        return QStringList();
++    }
++
++    QDBusReply&lt;QStringList&gt; r = walletLauncher-&gt;getInterface().folderList(d-&gt;handle, appid());
++    return r;
++#else
++    return QStringList(d-&gt;folderList());
++#endif
++}
++
++
++QStringList Wallet::entryList()
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if (d-&gt;handle == -1) {
++        return QStringList();
++    }
++
++    QDBusReply&lt;QStringList&gt; r = walletLauncher-&gt;getInterface().entryList(d-&gt;handle, d-&gt;folder, appid());
++    return r;
++#else
++    QStringList r = QStringList();
++    d-&gt;itemList(r);
++    return r;
++#endif
++}
++
++
++bool Wallet::hasFolder(const QString&amp; f)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if (d-&gt;handle == -1) {
++        return false;
++    }
++
++    QDBusReply&lt;bool&gt; r = walletLauncher-&gt;getInterface().hasFolder(d-&gt;handle, f, appid());
++    return r; // default is false
++#else
++    d-&gt;folderList();
++    return d-&gt;serviceList.contains(f);
++#endif
++}
++
++
++bool Wallet::createFolder(const QString&amp; f)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if (d-&gt;handle == -1) {
++        return false;
++    }
++
++    if (!hasFolder(f)) {
++        QDBusReply&lt;bool&gt; r = walletLauncher-&gt;getInterface().createFolder(d-&gt;handle, f, appid());
++        return r;
++    }
++
++    return true;                                // folder already exists
++#else
++    return setFolder(f);
++#endif
++}
++
++
++bool Wallet::setFolder(const QString &amp;f)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    bool rc = false;
++
++    if (d-&gt;handle == -1) {
++        return rc;
++    }
++
++    // Don't do this - the folder could have disappeared?
++#if 0
++    if (f == d-&gt;folder) {
++        return true;
++    }
++#endif
++
++    if (hasFolder(f)) {
++        d-&gt;folder = f;
++        rc = true;
++    }
++
++    return rc;
++#else
++    // act as if we just changed folders even if we have no such things; the property
++    // is stored as the ServiceItemAttr (which shows up as the &quot;Where&quot; field in the Keychain Utility).
++    if( f.size() == 0 ){
++        d-&gt;currentService.clear();
++    }
++    else{
++        d-&gt;currentService = QString(f);
++    }
++    return true;
++#endif
++}
++
++
++bool Wallet::removeFolder(const QString&amp; f)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if (d-&gt;handle == -1) {
++        return false;
++    }
++
++    QDBusReply&lt;bool&gt; r = walletLauncher-&gt;getInterface().removeFolder(d-&gt;handle, f, appid());
++    if (d-&gt;folder == f) {
++        setFolder(QString());
++    }
++
++    return r;                                        // default is false
++#else
++    kWarning() &lt;&lt; &quot;Wallet::removeFolder unimplemented (returns true) '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++    if( d-&gt;currentService == f ){
++        d-&gt;currentService.clear();
++    }
++    return true;
++#endif
++}
++
++
++const QString&amp; Wallet::currentFolder() const
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    return d-&gt;folder;
++#else
++    return d-&gt;currentService;
++#endif
++}
++
++
++int Wallet::readEntry(const QString &amp;key, QByteArray &amp;value)
++{   OSStatus err = d-&gt;readItem( key, &amp;value, NULL );
++    kDebug() &lt;&lt; &quot;Wallet::readEntry '&quot; &lt;&lt; key &lt;&lt; &quot;' from wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ((err)? -1 : 0);
++    return (err)? -1 : 0;
++}
++
++
++int Wallet::readEntryList(const QString&amp; key, QMap&lt;QString, QByteArray&gt;&amp; value)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    registerTypes();
++
++    int rc = -1;
++
++    if (d-&gt;handle == -1) {
++        return rc;
++    }
++
++    QDBusReply&lt;QVariantMap&gt; r = walletLauncher-&gt;getInterface().readEntryList(d-&gt;handle, d-&gt;folder, key, appid());
++    if (r.isValid()) {
++        rc = 0;
++        // convert &lt;QString, QVariant&gt; to &lt;QString, QByteArray&gt;
++        const QVariantMap val = r.value();
++        for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
++            value.insert(it.key(), it.value().toByteArray());
++        }
++    }
++
++    return rc;
++#else
++    Q_UNUSED(key);
++    Q_UNUSED(value);
++    kWarning() &lt;&lt; &quot;Wallet::readEntryList unimplemented (returns -1) '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++    return -1;
++#endif
++}
++
++
++int Wallet::renameEntry(const QString&amp; oldName, const QString&amp; newName)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    int rc = -1;
++
++    if (d-&gt;handle == -1) {
++        return rc;
++    }
++
++    QDBusReply&lt;int&gt; r = walletLauncher-&gt;getInterface().renameEntry(d-&gt;handle, d-&gt;folder, oldName, newName, appid());
++    if (r.isValid()) {
++        rc = r;
++    }
++
++    return rc;
++#else
++    return d-&gt;renameItem( oldName, newName );
++#endif
++}
++
++
++int Wallet::readMap(const QString &amp;key, QMap&lt;QString,QString&gt; &amp;value)
++{
++    QByteArray v;
++    const int ret = (d-&gt;readItem( key, &amp;v, NULL ))? -1 : 0;
++    if( ret != 0 ){
++        return ret;
++    }
++    if( !v.isEmpty() ){
++        QByteArray w = QByteArray::fromBase64(v);
++        QDataStream ds( &amp;w, QIODevice::ReadOnly );
++        ds &gt;&gt; value;
++    }
++    kDebug() &lt;&lt; &quot;Wallet::readMap '&quot; &lt;&lt; key &lt;&lt; &quot;' from wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=0&quot;;
++    return 0;
++}
++
++
++int Wallet::readMapList(const QString&amp; key, QMap&lt;QString, QMap&lt;QString, QString&gt; &gt;&amp; value)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    registerTypes();
++
++    int rc = -1;
++
++    if (d-&gt;handle == -1) {
++        return rc;
++    }
++
++    QDBusReply&lt;QVariantMap&gt; r =
++        walletLauncher-&gt;getInterface().readMapList(d-&gt;handle, d-&gt;folder, key, appid());
++    if (r.isValid()) {
++        rc = 0;
++        const QVariantMap val = r.value();
++        for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
++            QByteArray mapData = it.value().toByteArray();
++            if (!mapData.isEmpty()) {
++                QDataStream ds(&amp;mapData, QIODevice::ReadOnly);
++                QMap&lt;QString,QString&gt; v;
++                ds &gt;&gt; v;
++                value.insert(it.key(), v);
++            }
++        }
++    }
++
++    return rc;
++#else
++    Q_UNUSED(key);
++    Q_UNUSED(value);
++    kWarning() &lt;&lt; &quot;Wallet::readMapList unimplemented (returns -1) '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++    return -1;
++#endif
++}
++
++
++int Wallet::readPassword(const QString&amp; key, QString&amp; value)
++{
++    QByteArray ba;
++    const int ret = (d-&gt;readItem( key, &amp;ba, NULL ))? -1 : 0;
++    if ( ret == 0 ){
++        value = QString::fromUtf8( ba.constData() );
++    }
++    kDebug() &lt;&lt; &quot;Wallet::readPassword '&quot; &lt;&lt; key &lt;&lt; &quot;' from wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
++}
++
++
++int Wallet::readPasswordList(const QString&amp; key, QMap&lt;QString, QString&gt;&amp; value)
++{
++    Q_UNUSED(key);
++    Q_UNUSED(value);
++    kWarning() &lt;&lt; &quot;Wallet::readPasswordList unimplemented (returns -1) '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++    return -1;
++}
++
++int Wallet::writeEntry(const QString&amp; key, const QByteArray&amp; password )
++{   int ret = d-&gt;writeItem( key, password );
++    kDebug() &lt;&lt; &quot;wrote entry '&quot; &lt;&lt; key &lt;&lt; &quot;' to wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
++}
++
++int Wallet::writeEntry(const QString&amp; key, const QByteArray&amp; password, EntryType entryType)
++{
++    OSXKeychain::EntryType entryCode;
++        switch( entryType ){
++                case Wallet::Password:
++                        entryCode = OSXKeychain::Password;
++                        break;
++                case Wallet::Map:
++                        entryCode = OSXKeychain::Map;
++                        break;
++        case Wallet::Stream:
++            entryCode = OSXKeychain::Stream;
++            break;
++                default:
++                        entryCode = OSXKeychain::Unknown;
++                        break;
++        }
++        int ret = d-&gt;writeItem( key, password, &amp;entryCode );
++    kDebug() &lt;&lt; &quot;wrote entry '&quot; &lt;&lt; key &lt;&lt; &quot;' of type=&quot; &lt;&lt; (int) entryType &lt;&lt; &quot;to wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
++}
++
++int Wallet::writeMap(const QString&amp; key, const QMap&lt;QString,QString&gt;&amp; value)
++{
++    QByteArray mapData;
++    QDataStream ds(&amp;mapData, QIODevice::WriteOnly);
++    ds &lt;&lt; value;
++    OSXKeychain::EntryType etype = OSXKeychain::Map;
++    int ret = d-&gt;writeItem( key, mapData.toBase64(),
++                           &quot;This is a KDE Wallet::Map item. Its password\n&quot;
++                           &quot;cannot be read in the OS X Keychain Utility.\n&quot;
++                           &quot;Use KDE's own kwalletmanager for that.&quot;, &amp;etype );
++    kDebug() &lt;&lt; &quot;wrote map '&quot; &lt;&lt; key &lt;&lt; &quot;' to wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
++}
++
++
++int Wallet::writePassword(const QString &amp;key, const QString&amp; value)
++{   OSXKeychain::EntryType etype = OSXKeychain::Password;
++    int ret = d-&gt;writeItem( key, value.toUtf8(), &amp;etype );
++    kDebug() &lt;&lt; &quot;wrote password '&quot; &lt;&lt; key &lt;&lt; &quot;' to wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
++}
++
++
++bool Wallet::hasEntry(const QString &amp;key)
++{   bool ret = d-&gt;hasItem( key, NULL );
++    kDebug() &lt;&lt; &quot;wallet '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot; &lt;&lt; ((ret)? &quot; has&quot; : &quot; does not have&quot;) &lt;&lt; &quot; entry '&quot; &lt;&lt; key &lt;&lt; &quot;'&quot;;
++    return ret;
++}
++
++int Wallet::removeEntry(const QString&amp; key)
++{   int ret = d-&gt;removeItem( key );
++    kDebug() &lt;&lt; &quot;removed entry '&quot; &lt;&lt; key &lt;&lt; &quot;' from wallet &quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;, error=&quot; &lt;&lt; ret;
++    return ret;
++}
++
++
++Wallet::EntryType Wallet::entryType(const QString&amp; key)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    int rc = 0;
++
++    if (d-&gt;handle == -1) {
++        return Wallet::Unknown;
++    }
++
++    QDBusReply&lt;int&gt; r = walletLauncher-&gt;getInterface().entryType(d-&gt;handle, d-&gt;folder, key, appid());
++    if (r.isValid()) {
++        rc = r;
++    }
++
++    return static_cast&lt;EntryType&gt;(rc);
++#else
++    // RJVB: a priori, entries are always 'password' on OS X, but since we also do use them for storing
++    // maps, it may be best to return Wallet::Unknown to leave some uncertainty and not mislead our caller.
++    OSXKeychain::EntryType etype;
++    if( !d-&gt;itemType( key, &amp;etype ) ){
++        switch( etype ){
++            case OSXKeychain::Password:
++                return Wallet::Password;
++                break;
++            case OSXKeychain::Map:
++                return Wallet::Map;
++                break;
++            case OSXKeychain::Stream:
++                return Wallet::Stream;
++                break;
++        }
++    }
++    return Wallet::Unknown;
++#endif
++}
++
++
++void Wallet::slotFolderUpdated(const QString&amp; wallet, const QString&amp; folder)
++{
++    if (d-&gt;name == wallet) {
++        emit folderUpdated(folder);
++    }
++}
++
++
++void Wallet::slotFolderListUpdated(const QString&amp; wallet)
++{
++    if (d-&gt;name == wallet) {
++        emit folderListUpdated();
++    }
++}
++
++
++void Wallet::slotApplicationDisconnected(const QString&amp; wallet, const QString&amp; application)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    if (d-&gt;handle &gt;= 0
++        &amp;&amp; d-&gt;name == wallet
++        &amp;&amp; application == appid()) {
++        slotWalletClosed(d-&gt;handle);
++    }
++#else
++    Q_UNUSED(wallet);
++    Q_UNUSED(application);
++        kWarning() &lt;&lt; &quot;Wallet::slotApplicationDisconnected unimplemented '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++#endif
++}
++
++void Wallet::walletAsyncOpened(int tId, int handle)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    // ignore responses to calls other than ours
++    if (d-&gt;transactionId != tId || d-&gt;handle != -1) {
++        return;
++    }
++
++    // disconnect the async signal
++    disconnect(this, SLOT(walletAsyncOpened(int,int)));
++
++    d-&gt;handle = handle;
++    emit walletOpened(handle &gt; 0);
++#else
++    Q_UNUSED(tId);
++    Q_UNUSED(handle);
++        kWarning() &lt;&lt; &quot;Wallet::walletAsyncOpened unimplemented '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;'&quot;;
++#endif
++}
++
++void Wallet::emitWalletAsyncOpenError()
++{
++    emit walletOpened(false);
++}
++
++void Wallet::emitWalletOpened()
++{
++  emit walletOpened(true);
++}
++
++
++bool Wallet::folderDoesNotExist(const QString&amp; wallet, const QString&amp; folder)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    QDBusReply&lt;bool&gt; r = walletLauncher-&gt;getInterface().folderDoesNotExist(wallet, folder);
++    return r;
++#else
++    bool ret = true;
++    if( Wallet::walletList().contains(wallet) ){
++        ret = !Wallet(-1, wallet).hasFolder(folder);
++    }
++    return ret;
++#endif
++}
++
++
++bool Wallet::keyDoesNotExist(const QString&amp; wallet, const QString&amp; folder, const QString&amp; key)
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    QDBusReply&lt;bool&gt; r = walletLauncher-&gt;getInterface().keyDoesNotExist(wallet, folder, key);
++    return r;
++#else
++    bool ret = true;
++    if( Wallet::walletList().contains(wallet) ){
++        Wallet w(-1, wallet);
++        if( w.hasFolder(folder) ){
++            ret = !w.hasEntry(key);
++        }
++    }
++    return ret;
++#endif
++}
++
++void Wallet::slotCollectionStatusChanged(int status)
++{
++    Q_UNUSED(status);
++        kWarning() &lt;&lt; &quot;Wallet::slotCollectionStatusChanged unimplemented '&quot; &lt;&lt; d-&gt;name &lt;&lt; &quot;' status=&quot; &lt;&lt; status;
++}
++
++void Wallet::slotCollectionDeleted()
++{
++#ifdef OSX_KEYCHAIN_PORT_DISABLED
++    d-&gt;folder.clear();
++#else
++    d-&gt;currentService.clear();
++#endif
++    kDebug() &lt;&lt; &quot;Wallet::slotCollectionDeleted: closing private data '&quot; &lt;&lt; d-&gt;name;
++    d-&gt;close();
++    emit walletClosed();
++}
++
++
++void Wallet::virtual_hook(int, void*)
++{
++    //BASE::virtual_hook( id, data );
++}
++
++#include &quot;kwallet.moc&quot;
+diff -urN kdelibs-4.13.3-orig/kdeui/util/qosxkeychain.cpp kdelibs-4.13.3/kdeui/util/qosxkeychain.cpp
+--- kdelibs-4.13.3-orig/kdeui/util/qosxkeychain.cpp        1970-01-01 09:00:00.000000000 +0900
++++ kdelibs-4.13.3/kdeui/util/qosxkeychain.cpp        2014-09-22 19:46:57.000000000 +0900
+@@ -0,0 +1,776 @@
++/*
++ *  @file qosxkeychain.cpp
++ *  This file is part of the KDE project
++ *
++ *  Created by René J.V. Bertin on 20140809.
++ * Copyright (C) 2014 René Bertin &lt;rjvbertin@gmail.com&gt;
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB.  If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#include &lt;cassert&gt;
++#include &lt;sys/param.h&gt;
++
++#include &lt;QtGui/QApplication&gt;
++#include &lt;QtCore/QtCore&gt;
++#include &lt;QtCore/QPointer&gt;
++#include &lt;QtGui/QWidget&gt;
++
++#include &quot;kwallet.h&quot;
++#include &lt;kdebug.h&gt;
++using namespace KWallet;
++#include &quot;qosxkeychain.h&quot;
++
++#include &lt;CoreServices/CoreServices.h&gt;
++
++//! Define INTERNET_TOO=1 in order to build read-access to the kSecInternetPasswordItemClass items
++#define INTERNET_TOO    0
++
++// #undef kWarning
++// #undef kDebug
++// #define kWarning    qWarning
++// #define kDebug      qDebug
++
++// returns the textual representation of a FourCharCode (e.g. 'JPEG')
++static QString OSTStr( FourCharCode etype )
++{   union OSTStr {
++        struct {
++            char startquote;
++            uint32_t four;
++            char endquote;
++        } __attribute__ ((packed)) value;
++        char representation[7];
++    }  __attribute__ ((packed)) ltype;
++    ltype.value.four = EndianU32_BtoN(etype);
++    ltype.representation[0] = ltype.representation[5] = '\'';
++    ltype.representation[6] = '\0';
++    return QString::fromAscii(ltype.representation);
++}
++
++static SecKeychainRef defaultChain()
++{   QString errMsg;
++    SecKeychainRef keychain;
++    if( isError( SecKeychainCopyDefault(&amp;keychain), &amp;errMsg ) ){
++        kWarning() &lt;&lt; &quot;Could not retrieve reference to default keychain:&quot;  &lt;&lt; qPrintable(errMsg);
++        keychain = NULL;
++    }
++    return keychain;
++}
++
++/*! Return a name for @p keychain, and possibly the full path to its file
++ * The name  will be the equivalent of the `basename path .keychain` shell
++ * command.
++ */
++static QString keyChainName( SecKeychainRef keychain, QString *path=NULL )
++{   QFileInfo keyFile;
++    QString p = OSXKeychain::Path(keychain);
++    int ext = p.lastIndexOf(&quot;.keychain&quot;);
++    keyFile = QFileInfo( ((ext &gt; 0)? p.left(ext) : p) );
++    if( path ){
++        *path = QString(p);
++    }
++    return keyFile.fileName();
++}
++
++/*! Open an OS X keychain with name @p n.
++ * OS X keychains can be created without a full path (say, &quot;kdewallet&quot;), in which case they
++ * are stored e.g. as ~/Library/Keychains/kdewallet . However, opening a preexisting keychain like &quot;login&quot;
++ * without using the full path seems to fail even if e.g. ~/Library/Keychains/login exists.
++ * We try to work around that issue by matching @p n against the known keychain names.
++ */
++static OSStatus openKeychain( const QString &amp;n, SecKeychainRef *keychain )
++{   OSStatus err;
++    CFArrayRef list = NULL;
++
++    *keychain = NULL;
++    err = SecKeychainCopySearchList( &amp;list );
++    if( !err &amp;&amp; list ){
++        CFIndex len = CFArrayGetCount(list), i;
++        for( i = 0 ; i &lt; len &amp;&amp; !*keychain ; ++i ){
++            SecKeychainRef kr = (SecKeychainRef) CFArrayGetValueAtIndex( list, i );
++            QString path, name = keyChainName( kr, &amp;path );
++            if( name == n ){
++                // a hit, try to open it!
++                err = SecKeychainOpen( path.toUtf8(), keychain );
++                if( err ){
++                    kWarning() &lt;&lt; &quot;openKeychain(&quot; &lt;&lt; n &lt;&lt; &quot;) error&quot; &lt;&lt; err &lt;&lt; &quot;opening matching&quot; &lt;&lt; path;
++                }
++                else{
++                    kDebug() &lt;&lt; &quot;openKeychain(&quot; &lt;&lt; n &lt;&lt; &quot;) opened matching&quot; &lt;&lt; path;
++                }
++            }
++        }
++        CFRelease(list);
++    }
++    if( !*keychain ){
++        err = SecKeychainOpen( n.toUtf8(), keychain );
++    }
++    // we actually need to query the keychain's status to know if we succeeded
++    // in opening an existing keychain!
++    if( !err ){
++        SecKeychainStatus status;
++        err = SecKeychainGetStatus( *keychain, &amp;status );
++    }
++    return err;
++}
++
++static OSStatus basicWriteItem( const QByteArray *serviceName, const QByteArray &amp;accountName, const QByteArray &amp;value,
++                               const SecKeychainRef keychain, SecKeychainItemRef *itemRef=NULL )
++{   OSStatus err;
++    QString errMsg;
++    if( serviceName ){
++        err = SecKeychainAddGenericPassword( keychain, serviceName-&gt;size(), serviceName-&gt;constData(),
++                                                     accountName.size(), accountName.constData(),
++                                                     value.size(), value.constData(), itemRef );
++    }
++    else{
++        err = SecKeychainAddGenericPassword( keychain, 0, NULL,
++                                                     accountName.size(), accountName.constData(),
++                                                     value.size(), value.constData(), itemRef );
++    }
++    if( err != errSecDuplicateItem &amp;&amp; isError( err, &amp;errMsg ) ){
++        kWarning() &lt;&lt; &quot;Could not store password in keychain: &quot; &lt;&lt; qPrintable(errMsg);
++    }
++    return err;
++}
++
++OSXKeychain::OSXKeychain()
++    : name(&quot;default&quot;)
++{ QString errMsg;
++    keyChainRef = defaultChain();
++    if( keyChainRef ){
++        keyChainPath = OSXKeychain::Path(keyChainRef);
++        kDebug() &lt;&lt; &quot;Retrieved reference to default keychain&quot; &lt;&lt; (void*) keyChainRef &lt;&lt; &quot;in &quot; &lt;&lt; keyChainPath;
++        name = keyChainName(keyChainRef);
++        isDefaultKeychain = true;
++    }
++    else{
++        keyChainPath = QString::fromUtf8(&quot;&lt;undefined&gt;&quot;);
++    }
++    serviceList.clear();
++    serviceList.append(&quot;&quot;);
++}
++
++OSXKeychain::OSXKeychain(const QString &amp;n, bool *isNew)
++    : name(n)
++{   QString errMsg;
++    OSStatus err = openKeychain( n, &amp;keyChainRef );
++
++    if( err == errSecNoSuchKeychain ){
++        kWarning() &lt;&lt; &quot;Keychain '&quot; &lt;&lt; n &lt;&lt; &quot;' does not exist: attempting to create it&quot;;
++        err = SecKeychainCreate( n.toUtf8(), 0, NULL, true, NULL, &amp;keyChainRef );
++        isKDEChain = true;
++        if( !err &amp;&amp; isNew ){
++            *isNew = true;
++        }
++    }
++    else if( !err &amp;&amp; isNew ){
++        *isNew = false;
++    }
++
++    if( isError( err, &amp;errMsg ) ){
++        // the protocol cannot handle failure to open a keychain, so we have to return the default.
++        keyChainRef = defaultChain();
++        kWarning() &lt;&lt; &quot;Error opening keychain '&quot; &lt;&lt; n &lt;&lt; &quot;' (falling back to default keychain): &quot; &lt;&lt; qPrintable(errMsg);
++        name = keyChainName(keyChainRef);
++        isDefaultKeychain = true;
++    }
++    else{
++        isDefaultKeychain = false;
++    }
++
++    if( keyChainRef ){
++        keyChainPath = OSXKeychain::Path(keyChainRef);
++        kDebug() &lt;&lt; &quot;Retrieved reference to keychain&quot; &lt;&lt; name &lt;&lt; (void*) keyChainRef &lt;&lt; &quot;in &quot; &lt;&lt; keyChainPath;
++    }
++    else{
++        keyChainPath = QString::fromUtf8(&quot;&lt;undefined&gt;&quot;);
++    }
++    serviceList.clear();
++    serviceList.append(&quot;&quot;);
++}
++
++void OSXKeychain::close()
++{
++    if( keyChainRef ){
++        Lock(keyChainRef);
++        CFRelease(keyChainRef);
++        keyChainRef = NULL;
++        serviceList.clear();
++    }
++}
++
++OSXKeychain::~OSXKeychain()
++{
++    if( keyChainRef ){
++        CFRelease(keyChainRef);
++        keyChainRef = NULL;
++    }
++    serviceList.clear();
++}
++
++OSStatus OSXKeychain::lockSettings(int &amp;closeWhenIdle, unsigned int &amp;idleTimeoutMin)
++{   QString errMsg;
++    SecKeychainSettings kcSettings= { SEC_KEYCHAIN_SETTINGS_VERS1, 0, 0, INT_MAX };
++    OSStatus err = SecKeychainCopySettings( keyChainRef, &amp;kcSettings );
++    if( isError( err, &amp;errMsg ) ){
++        kWarning() &lt;&lt; &quot;Error getting settings for&quot; &lt;&lt; name &lt;&lt; err &lt;&lt; &quot;=&quot; &lt;&lt; qPrintable(errMsg);
++    }
++    else{
++        closeWhenIdle = kcSettings.useLockInterval;
++        idleTimeoutMin = (int)(kcSettings.lockInterval / 60 + 0.5);
++    }
++    return err;
++}
++
++OSStatus OSXKeychain::setLockSettings(int closeWhenIdle, unsigned int idleTimeoutMin)
++{   QString errMsg;
++    SecKeychainSettings kcSettings = { SEC_KEYCHAIN_SETTINGS_VERS1, 0, 0, INT_MAX };
++    OSStatus err;
++
++    // to switch (or keep) off idle timeout locking set useLockInterval=false and lockInterval=INT_MAX
++    // if lockInterval has any other value, SecKeychainSetSettings() will force useLockInterval=true
++    if( closeWhenIdle ){
++        kcSettings.useLockInterval = 1;
++        kcSettings.lockInterval = idleTimeoutMin * 60;
++    }
++    err = SecKeychainSetSettings( keyChainRef, &amp;kcSettings );
++//     if( !err ){
++//         SecKeychainSettings ks = { SEC_KEYCHAIN_SETTINGS_VERS1, 0, 0, INT_MAX };
++//         ks.useLockInterval = !closeWhenIdle;
++//         SecKeychainCopySettings( keyChainRef, &amp;ks );
++//         qDebug() &lt;&lt; &quot;Keychain settings set to useLockInterval=&quot; &lt;&lt; ks.useLockInterval &lt;&lt; &quot;lockInterval=&quot; &lt;&lt; ks.lockInterval;
++//     }
++//     else{
++//         qDebug() &lt;&lt; &quot;Error setting keychain settings:&quot; &lt;&lt; err;
++//     }
++    return err;
++}
++
++OSStatus OSXKeychain::renameItem(const QString &amp;currentKey, const QString &amp;newKey)
++{   OSStatus err;
++    SecKeychainItemRef itemRef = NULL;
++    err = ReadItem( currentKey, NULL, keyChainRef, &amp;itemRef, this );
++    if( !err &amp;&amp; itemRef ){
++        const QByteArray accountName( newKey.toUtf8() );
++        // store the new key in the account and label attributes
++        SecKeychainAttribute attr[] = { { kSecAccountItemAttr, accountName.size(), (void*) accountName.constData() },
++                                        { kSecLabelItemAttr, accountName.size(), (void*) accountName.constData() } };
++        SecKeychainAttributeList attrList = { 2, &amp;attr[0] };
++        QString errMsg;
++        if( isError( (err = SecKeychainItemModifyAttributesAndData( itemRef, &amp;attrList, 0, NULL )), &amp;errMsg ) ){
++            kWarning() &lt;&lt; &quot;OSXKeychain::renameItem(&quot; &lt;&lt; currentKey &lt;&lt; &quot;) couldn't change name &amp; label to&quot; &lt;&lt; accountName
++            &lt;&lt; &quot;:&quot; &lt;&lt; err &lt;&lt; &quot;=&quot; &lt;&lt; qPrintable(errMsg);
++        }
++        CFRelease(itemRef);
++    }
++    return err;
++}
++
++#pragma mark ========= static member functions =========
++
++OSStatus OSXKeychain::KeychainList(QStringList &amp;theList)
++{   CFArrayRef list = NULL;
++    OSStatus err = SecKeychainCopySearchList( &amp;list );
++    theList.clear();
++    if( !err &amp;&amp; list ){
++        CFIndex len = CFArrayGetCount(list), i;
++        for( i = 0 ; i &lt; len ; ++i ){
++            SecKeychainRef keychain = (SecKeychainRef) CFArrayGetValueAtIndex( list, i );
++            QString name = keyChainName(keychain);
++            if( name.size() &gt; 0 ){
++                theList.append(name);
++            }
++        }
++        CFRelease(list);
++    }
++    return err;
++}
++
++QString OSXKeychain::Path(const SecKeychainRef keychain)
++{   char pathName[MAXPATHLEN];
++    UInt32 plen = MAXPATHLEN;
++    if( SecKeychainGetPath( (keychain)? keychain : OSXKeychain().reference(), &amp;plen, pathName ) == errSecSuccess ){
++        return QString::fromUtf8(pathName);
++    }
++    else{
++        return QString();
++    }
++}
++
++bool OSXKeychain::IsOpen(const SecKeychainRef keychain)
++{   bool isOpen = false;
++    SecKeychainStatus status;
++    QString errMsg;
++    if( isError( SecKeychainGetStatus( keychain, &amp;status ), &amp;errMsg ) ){
++        if( keychain ){
++            kDebug() &lt;&lt; &quot;Could not get the status of keychain&quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot;:&quot;  &lt;&lt; qPrintable(errMsg);
++        }
++        else{
++            kWarning() &lt;&lt; &quot;Could not get the default keychain's status:&quot;  &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    else{
++        if( (status &amp; kSecUnlockStateStatus) &amp;&amp; (status &amp; kSecReadPermStatus) ){
++            isOpen = true;
++        }
++        else{
++            kDebug() &lt;&lt; &quot;Keychain&quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot; has status&quot; &lt;&lt; status;
++        }
++    }
++    return isOpen;
++}
++
++bool OSXKeychain::IsOpen(const QString &amp;walletName)
++{   SecKeychainRef keychain = NULL;
++    OSStatus err = openKeychain( walletName.toUtf8(), &amp;keychain );
++    bool ret = false;
++    if( !err &amp;&amp; keychain ){
++        ret = IsOpen(keychain);
++        CFRelease(keychain);
++    }
++    return ret;
++}
++
++OSStatus OSXKeychain::UnLock(const SecKeychainRef keychain)
++{   QString errMsg;
++    OSStatus err;
++    err = SecKeychainUnlock( keychain, 0, NULL, false );
++    if( isError( err, &amp;errMsg ) ){
++        if( keychain ){
++            kDebug() &lt;&lt; &quot;Could not unlock the keychain at '&quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot;': &quot; &lt;&lt; qPrintable(errMsg);
++        }
++        else{
++            kDebug() &lt;&lt; &quot;Could not unlock the default keychain:&quot;  &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    return err;
++}
++
++OSStatus OSXKeychain::Lock(const SecKeychainRef keychain)
++{   QString errMsg;
++    OSStatus err;
++    if( keychain ){
++        err = SecKeychainLock(keychain);
++        if( isError( err, &amp;errMsg ) ){
++            kDebug() &lt;&lt; &quot;Could not lock the keychain at '&quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot;': &quot; &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    else{
++        err = SecKeychainLockAll();
++        if( isError( err, &amp;errMsg ) ){
++            kDebug() &lt;&lt; &quot;Could not lock all keychains:&quot; &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    return err;
++}
++
++OSStatus OSXKeychain::Lock(const QString &amp;walletName)
++{   SecKeychainRef keychain = NULL;
++    OSStatus err = openKeychain( walletName, &amp;keychain );
++    if( !err &amp;&amp; keychain ){
++        err = Lock(keychain);
++        CFRelease(keychain);
++    }
++    return err;
++}
++
++/** use the keychain search functions to find the first matching item, if any, @return returning True if found.
++ The OS X error code is returned through @p errReturn when not NULL, the item itself through @p itemRef.
++ This reference will have to be released with CFRelease() when done with it (when @p itemRef==NULL the
++ function does this release itself).
++ */
++bool OSXKeychain::HasItem(const QString &amp;key,
++                     const SecKeychainRef keychain, OSStatus *errReturn, SecKeychainItemRef *itemRef)
++{   const QByteArray accountName( key.toUtf8() );
++    OSStatus err;
++    SecKeychainSearchRef searchRef;
++    SecKeychainAttribute attrs = { kSecAccountItemAttr, accountName.size(), (void*) accountName.constData() };
++    SecKeychainAttributeList attrList = { 1, &amp;attrs };
++    err = SecKeychainSearchCreateFromAttributes( keychain, kSecGenericPasswordItemClass,
++                                                (const SecKeychainAttributeList*) &amp;attrList, &amp;searchRef );
++    const CFReleaser&lt;SecKeychainSearchRef&gt; releaseSR(searchRef);
++    bool found;
++    SecKeychainItemRef item;
++    QString errMsg;
++    if( err ){
++        found = false;
++        errMsg = errorString(err);
++        kDebug() &lt;&lt; &quot;OSXKeychain::HasItem(&quot; &lt;&lt; key &lt;&lt; &quot;,&quot; &lt;&lt; (void*) keychain &lt;&lt; &quot;): SecKeychainSearchCreateFromAttributes failed&quot;;
++    }
++    else{
++            if( !(err = SecKeychainSearchCopyNext( searchRef, &amp;item )) ){
++                found = true;
++                if( itemRef ){
++                    *itemRef = item;
++                }
++                else if( item ){
++                    CFRelease(item);
++                }
++                errMsg = QString();
++            }
++            else{
++                found = false;
++                errMsg = errorString(err);
++            }
++            if( errReturn ){
++                *errReturn = err;
++            }
++    }
++    kDebug() &lt;&lt; &quot;item '&quot; &lt;&lt; key &lt;&lt; ((found)? &quot;found&quot; : &quot;not found&quot;) &lt;&lt; &quot;' in keychain &quot; &lt;&lt; (void*) keychain &lt;&lt; &quot;, error=&quot; &lt;&lt; err &lt;&lt; &quot; &quot; &lt;&lt; qPrintable(errMsg);
++    return found;
++}
++
++OSStatus OSXKeychain::ReadItem(const QString &amp;key, QByteArray *value,
++                          const SecKeychainRef keychain, SecKeychainItemRef *itemRef, OSXKeychain *osxKeyChain)
++{   const QByteArray accountName( key.toUtf8() );
++    UInt32 passwordSize = 0;
++    void* passwordData = 0;
++    QString errMsg;
++    SecKeychainItemRef theItem;
++    OSStatus err = SecKeychainFindGenericPassword( keychain, 0, NULL,
++                                                  accountName.size(), accountName.constData(),
++                                                  &amp;passwordSize, &amp;passwordData, &amp;theItem );
++    if( isError( err, &amp;errMsg ) ){
++        kDebug() &lt;&lt; &quot;Error&quot; &lt;&lt; err &lt;&lt; &quot;retrieving password for '&quot; &lt;&lt; accountName &lt;&lt; &quot;' :&quot; &lt;&lt; qPrintable(errMsg);
++#if INTERNET_TOO
++        if( SecKeychainFindInternetPassword( keychain, 0, NULL,
++                                                      0, NULL,
++                                                      accountName.size(), accountName.constData(),
++                                                      0, NULL, 0,
++                                                      kSecProtocolTypeAny, kSecAuthenticationTypeDefault,
++                                                      &amp;passwordSize, &amp;passwordData, &amp;theItem ) ){
++            // just to be sure:
++            theItem = NULL;
++        }
++        else{
++            err = 0;
++            errMsg = QString();
++        }
++#else
++        theItem = NULL;
++#endif
++    }
++    if( !err &amp;&amp; theItem ){
++        if( value ){
++            *value = QByteArray( reinterpret_cast&lt;const char*&gt;( passwordData ), passwordSize );
++        }
++        SecKeychainItemFreeContent( NULL, passwordData );
++        if( osxKeyChain &amp;&amp; osxKeyChain-&gt;isKDEChain ){
++            SecKeychainAttribute attr = { kSecServiceItemAttr, 0, NULL };
++            SecKeychainAttributeList attrList = { 1, &amp;attr };
++            UInt32 len = 0;
++            // try to fetch the item's ServiceItem attribute
++            if( !SecKeychainItemCopyContent( theItem, NULL, &amp;attrList, &amp;len, NULL ) ){
++                if( attr.length &gt; 0 ){
++                    osxKeyChain-&gt;lastReadService.clear();
++                    osxKeyChain-&gt;lastReadService = QString::fromUtf8( (char*)attr.data, attr.length );
++                }
++                SecKeychainItemFreeContent( &amp;attrList, NULL );
++            }
++        }
++        if( itemRef ){
++            *itemRef = theItem;
++        }
++        else if( theItem ){
++            CFRelease(theItem);
++        }
++    }
++    kDebug() &lt;&lt; &quot;OSXKeychain::ReadItem '&quot; &lt;&lt; key &lt;&lt; &quot;' from keychain &quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot;, error=&quot; &lt;&lt; err;
++    return err;
++}
++
++OSStatus OSXKeychain::ItemType(const QString &amp;key, EntryType *entryType,
++                          const SecKeychainRef keychain)
++{   const QByteArray accountName( key.toUtf8() );
++    QString errMsg;
++    EntryType etype = (EntryType) 0;
++    SecKeychainItemRef itemRef;
++#if INTERNET_TOO
++    bool isInternetPW = false;
++#endif
++    OSStatus err = SecKeychainFindGenericPassword( keychain, 0, NULL,
++                                                  accountName.size(), accountName.constData(),
++                                                  NULL, NULL, &amp;itemRef );
++    if( isError( err, &amp;errMsg ) ){
++        kDebug() &lt;&lt; &quot;Error&quot; &lt;&lt; err &lt;&lt; &quot;retrieving type for '&quot; &lt;&lt; accountName &lt;&lt; &quot;' :&quot; &lt;&lt; qPrintable(errMsg);
++#if INTERNET_TOO
++        if( SecKeychainFindInternetPassword( keychain, 0, NULL,
++                                            0, NULL,
++                                            accountName.size(), accountName.constData(),
++                                            0, NULL, 0,
++                                            kSecProtocolTypeAny, kSecAuthenticationTypeDefault,
++                                            0, NULL, &amp;itemRef ) ){
++            // just to be sure:
++            itemRef = NULL;
++        }
++        else{
++            isInternetPW = true;
++            err = 0;
++            errMsg = QString();
++        }
++#else
++        itemRef = NULL;
++#endif
++    }
++    if( itemRef ){
++                UInt32 tags[] = { kSecTypeItemAttr };
++                UInt32 formats[] = { CSSM_DB_ATTRIBUTE_FORMAT_STRING };
++        SecKeychainAttributeInfo attrGet = { 1, tags, formats };
++        SecKeychainAttributeList *attrList = NULL;
++        err = SecKeychainItemCopyAttributesAndData( itemRef, &amp;attrGet, NULL, &amp;attrList, NULL, NULL );
++        if( !err ){
++            if( attrList-&gt;attr[0].length == sizeof(EntryType) ){
++                memcpy( &amp;etype, attrList-&gt;attr[0].data, sizeof(EntryType) );
++            }
++            else if( attrList-&gt;attr[0].length ){
++                kDebug() &lt;&lt; &quot;Error: key&quot; &lt;&lt; key &lt;&lt; &quot;item type retrieved is of size&quot; &lt;&lt; attrList-&gt;attr[0].length &lt;&lt; &quot;!=&quot; &lt;&lt; sizeof(EntryType);
++            }
++#if INTERNET_TOO
++            else if( isInternetPW ){
++                // this is just a wild guess ...
++                etype = Password;
++            }
++#endif
++            if( entryType ){
++                *entryType = etype;
++            }
++        }
++        SecKeychainItemFreeAttributesAndData( attrList, NULL );
++        CFRelease(itemRef);
++    }
++    kDebug() &lt;&lt; &quot;OSXKeychain::ItemType '&quot; &lt;&lt; key &lt;&lt; &quot;' from keychain &quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot;=&quot; &lt;&lt; OSTStr(etype) &lt;&lt; &quot;, error=&quot; &lt;&lt; err;
++    return err;
++}
++
++OSStatus OSXKeychain::RemoveItem(const QString &amp;key, const SecKeychainRef keychain)
++{   const QByteArray accountName( key.toUtf8() );
++    SecKeychainItemRef itemRef;
++    QString errMsg;
++    OSStatus result = SecKeychainFindGenericPassword( keychain, 0, NULL,
++                                                     accountName.size(), accountName.constData(), NULL, NULL, &amp;itemRef );
++    if( isError( result, &amp;errMsg ) ){
++        kDebug() &lt;&lt; &quot;Could not find entry&quot; &lt;&lt; key &lt;&lt; &quot;:&quot;  &lt;&lt; qPrintable(errMsg);
++    }
++    else{
++        const CFReleaser&lt;SecKeychainItemRef&gt; itemReleaser(itemRef);
++        result = SecKeychainItemDelete(itemRef);
++        if( isError( result, &amp;errMsg ) ){
++            kWarning() &lt;&lt; &quot;Could not delete entry&quot; &lt;&lt; key &lt;&lt; &quot;:&quot;  &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    return result;
++}
++
++OSStatus OSXKeychain::WriteItem( const QString &amp;key, const QByteArray &amp;value,
++                                                   const SecKeychainRef keychain, SecKeychainItemRef *itemRef, EntryType *entryType, OSXKeychain *osxKeyChain )
++{   const QByteArray accountName( key.toUtf8() );
++    OSStatus err;
++    QString errMsg;
++    SecKeychainItemRef theItem = NULL;
++    bool saveLabel;
++    if( osxKeyChain &amp;&amp; osxKeyChain-&gt;currentService.size() ){
++        const QByteArray serviceName( osxKeyChain-&gt;currentService.toUtf8() );
++        // save the &quot;GenericPassword&quot; item using the service name, which appears to be the only way to write
++        // to the &quot;Where&quot; field shown in the Keychain Utility.
++        err = basicWriteItem( &amp;serviceName, accountName, value, keychain, &amp;theItem );
++        // the service (folder!) string will also appear on the &quot;Name&quot; field, which however can be changed
++        // independently, via the Label attribute.
++        saveLabel = true;
++    }
++    else{
++        err = basicWriteItem( NULL, accountName, value, keychain, &amp;theItem );
++        saveLabel = false;
++    }
++    if( err == errSecDuplicateItem ){
++        // RJVB: the previous implementation was wrong. errSecDuplicateItem means the write failed because of an existing item.
++        // So we have to find that item, and modify it.
++        if( !(err = ReadItem( key, NULL, keychain, &amp;theItem )) ){
++            err = SecKeychainItemModifyAttributesAndData( theItem, NULL, value.size(), value.constData() );
++            if( isError( err, &amp;errMsg ) ){
++                kDebug() &lt;&lt; &quot;Key '&quot; &lt;&lt; key
++                    &lt;&lt; &quot;'already exists in keychain but error modifying the existing item: &quot; &lt;&lt; qPrintable(errMsg);
++            }
++        }
++        if( !err ){
++            kDebug() &lt;&lt; &quot;Key '&quot; &lt;&lt; key &lt;&lt; &quot;'already existed in keychain: modified the existing item&quot;;
++        }
++    }
++    if( !err &amp;&amp; saveLabel ){
++        // store the desired text in the label attribute
++        SecKeychainAttribute attr = { kSecLabelItemAttr, accountName.size(), (void*) accountName.constData() };
++        SecKeychainAttributeList attrList = { 1, &amp;attr };
++        QString errMsg;
++        if( isError( (err = SecKeychainItemModifyAttributesAndData( theItem, &amp;attrList, 0, NULL )), &amp;errMsg ) ){
++            kWarning() &lt;&lt; &quot;OSXKeychain::WriteItem(&quot; &lt;&lt; key &lt;&lt; &quot;) couldn't set the desired name/label&quot; &lt;&lt; accountName
++                &lt;&lt; &quot;:&quot; &lt;&lt; err &lt;&lt; &quot;=&quot; &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    if( !err ){
++        EntryType defType = Stream;
++        if( !entryType ){
++            entryType = &amp;defType;
++        }
++        SecKeychainAttribute attr = { kSecTypeItemAttr, sizeof(EntryType), (void*) entryType };
++        SecKeychainAttributeList attrList = { 1, &amp;attr };
++        QString errMsg;
++        if( isError( (err = SecKeychainItemModifyAttributesAndData( theItem, &amp;attrList, 0, NULL )), &amp;errMsg ) ){
++            kWarning() &lt;&lt; &quot;OSXKeychain::WriteItem(&quot; &lt;&lt; key &lt;&lt; &quot;) couldn't set type to&quot; &lt;&lt; OSTStr(*entryType)
++                &lt;&lt; &quot;:&quot; &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    if( itemRef ){
++        *itemRef = theItem;
++    }
++    else if( theItem ){
++        CFRelease(theItem);
++    }
++    kDebug() &lt;&lt; &quot;OSXKeychain::WriteItem '&quot; &lt;&lt; key &lt;&lt; &quot;' to keychain &quot; &lt;&lt; (void*) keychain &lt;&lt; &quot;, error=&quot; &lt;&lt; err;
++    return err;
++}
++
++OSStatus OSXKeychain::WriteItem( const QString &amp;key, const QByteArray &amp;value,
++                                 const QString &amp;comment, const SecKeychainRef keychain, EntryType *entryType, OSXKeychain *osxKeyChain )
++{   SecKeychainItemRef itemRef = NULL;
++    OSStatus err = WriteItem( key, value, keychain, &amp;itemRef, entryType, osxKeyChain );
++    if( !err &amp;&amp; itemRef ){
++        const QByteArray commentString(comment.toUtf8());
++        if( commentString.size() ){
++            SecKeychainAttribute attr = { kSecCommentItemAttr, commentString.size(), (void*) commentString.constData() };
++            SecKeychainAttributeList attrList = { 1, &amp;attr };
++            QString errMsg;
++            if( isError( (err = SecKeychainItemModifyAttributesAndData( itemRef, &amp;attrList, 0, NULL )), &amp;errMsg ) ){
++                kWarning() &lt;&lt; &quot;OSXKeychain::WriteItem(&quot; &lt;&lt; key &lt;&lt; &quot;) couldn't add comment&quot; &lt;&lt; comment
++                    &lt;&lt; &quot;:&quot; &lt;&lt; qPrintable(errMsg);
++            }
++        }
++        CFRelease(itemRef);
++    }
++    return err;
++}
++
++// returns the kSecAccountItemAttr's of all items in the keychain
++OSStatus OSXKeychain::ItemList( SecKeychainRef keychain, QStringList &amp;keyList, OSXKeychain *osxKeyChain )
++{   OSStatus err;
++    SecKeychainSearchRef searchRef[2];
++    bool generateFolderList = ( osxKeyChain &amp;&amp; osxKeyChain-&gt;isKDEChain &amp;&amp; osxKeyChain-&gt;generateFolderList );
++
++    keyList.clear();
++    if( generateFolderList ){
++        osxKeyChain-&gt;serviceList.clear();
++        if( osxKeyChain-&gt;currentService.size() &gt; 0 ){
++            osxKeyChain-&gt;serviceList.append(osxKeyChain-&gt;currentService);
++        }
++    }
++
++    err = SecKeychainSearchCreateFromAttributes( keychain, kSecGenericPasswordItemClass, NULL, &amp;searchRef[0] );
++#if INTERNET_TOO
++    if( SecKeychainSearchCreateFromAttributes( keychain, kSecInternetPasswordItemClass, NULL, &amp;searchRef[1] ) ){
++        searchRef[1] = NULL;
++    }
++#else
++    searchRef[1] = NULL;
++#endif
++    SecKeychainItemRef item;
++    QString errMsg;
++    if( isError(err, &amp;errMsg) ){
++        kDebug() &lt;&lt; &quot;OSXKeychain::ItemList(&quot; &lt;&lt; (void*) keychain &lt;&lt; &quot;): SecKeychainSearchCreateFromAttributes failed&quot; &lt;&lt; qPrintable(errMsg);
++    }
++    else{
++        for( size_t i = 0 ; i &lt; sizeof(searchRef)/sizeof(SecKeychainSearchRef) &amp;&amp; !err ; ++i ){
++            if( searchRef[i] ){
++                while( !(err = SecKeychainSearchCopyNext( searchRef[i], &amp;item )) ){
++                    if( item ){
++                        // whether the item will be listed in the keyList we return: by default it is
++                        // (better an item shows up multiple times than not at all).
++                        bool listItem = true;
++                        SecKeychainAttribute attr = { kSecAccountItemAttr, 0, NULL };
++                        SecKeychainAttributeList attrList = { 1, &amp;attr };
++                        UInt32 len = 0;
++                        if( osxKeyChain &amp;&amp; osxKeyChain-&gt;isKDEChain ){
++                            // try to fetch the item's ServiceItem attribute
++                            attr.tag = kSecServiceItemAttr;
++                            if( !SecKeychainItemCopyContent( item, NULL, &amp;attrList, &amp;len, NULL ) ){
++                                QString lbl = QString::fromUtf8( (char*)attr.data, attr.length );
++                                // we got a service item attribute, which is where we store the kwallet folder info.
++                                // If we disallow empty attributes, keychain items without service item attribute will
++                                // appear in each folder that has a non-empty name. In other words, we allow a folder without name.
++                                if( generateFolderList ){
++                                    // add the &quot;folder&quot; to the list if not already listed
++                                    if( !osxKeyChain-&gt;serviceList.contains(lbl) ){
++                                        osxKeyChain-&gt;serviceList.append(lbl);
++                                    }
++                                }
++                                else{
++                                    // only list the item if it's in the current &quot;folder&quot;
++                                    listItem = (lbl == osxKeyChain-&gt;currentService);
++                                }
++                                SecKeychainItemFreeContent( &amp;attrList, NULL );
++                            }
++                        }
++                        else{
++                            // errors retrieving the service item attribute are ignored
++                        }
++                        if( listItem ){
++                            attr.tag = kSecAccountItemAttr;
++                            if( !(err = SecKeychainItemCopyContent( item, NULL, &amp;attrList, &amp;len, NULL )) ){
++                                if( attr.length &gt; 0 ){
++                                    keyList.append(QString::fromUtf8( (char*)attr.data, attr.length ));
++                                }
++                                SecKeychainItemFreeContent( &amp;attrList, NULL );
++                            }
++                            else{
++                                errMsg = errorString(err);
++                                kDebug() &lt;&lt; &quot;SecKeychainItemCopyContent returned&quot; &lt;&lt; err &lt;&lt; &quot;=&quot; &lt;&lt; qPrintable(errMsg);
++                            }
++                        }
++                        CFRelease(item);
++                    }
++                }
++                if( err ){
++                    errMsg = errorString(err);
++                }
++                CFRelease(searchRef[i]);
++            }
++        }
++    }
++    return err;
++}
++
++OSStatus OSXKeychain::Destroy( SecKeychainRef *keychain )
++{   OSStatus err = SecKeychainDelete(*keychain);
++    QString errMsg;
++    if( isError( err, &amp;errMsg ) ){
++        kWarning() &lt;&lt; &quot;OSXKeychain::Destroy &quot; &lt;&lt; (void*) *keychain &lt;&lt; &quot;, error &quot; &lt;&lt; qPrintable(errMsg);
++    }
++    else{
++        kWarning() &lt;&lt; &quot;OSXKeychain::Destroy &quot; &lt;&lt; (void*) *keychain &lt;&lt; &quot;, error=&quot; &lt;&lt; err;
++    }
++    if( keychain ){
++        CFRelease(*keychain);
++        *keychain = NULL;
++    }
++    return err;
++}
++
++OSStatus OSXKeychain::Destroy( const QString &amp;walletName )
++{   SecKeychainRef keychain;
++    OSStatus err = openKeychain( walletName, &amp;keychain );
++    if( !err &amp;&amp; keychain ){
++        err = Destroy(&amp;keychain);
++    }
++    return err;
++}
+diff -urN kdelibs-4.13.3-orig/kdeui/util/qosxkeychain.cpp.orig kdelibs-4.13.3/kdeui/util/qosxkeychain.cpp.orig
+--- kdelibs-4.13.3-orig/kdeui/util/qosxkeychain.cpp.orig        1970-01-01 09:00:00.000000000 +0900
++++ kdelibs-4.13.3/kdeui/util/qosxkeychain.cpp.orig        2014-09-22 19:46:10.000000000 +0900
+@@ -0,0 +1,726 @@
++/*
++ *  @file qosxkeychain.cpp
++ *  This file is part of the KDE project
++ *
++ *  Created by René J.V. Bertin on 20140809.
++ * Copyright (C) 2014 René Bertin &lt;rjvbertin@gmail.com&gt;
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB.  If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#include &lt;cassert&gt;
++#include &lt;sys/param.h&gt;
++
++#include &lt;QtGui/QApplication&gt;
++#include &lt;QtCore/QtCore&gt;
++#include &lt;QtCore/QPointer&gt;
++#include &lt;QtGui/QWidget&gt;
++
++#include &quot;kwallet.h&quot;
++#include &lt;kdebug.h&gt;
++using namespace KWallet;
++#include &quot;qosxkeychain.h&quot;
++
++#include &lt;CoreServices/CoreServices.h&gt;
++
++//! Define INTERNET_TOO=1 in order to build read-access to the kSecInternetPasswordItemClass items
++#define INTERNET_TOO    0
++
++// #undef kWarning
++// #undef kDebug
++// #define kWarning    qWarning
++// #define kDebug      qDebug
++
++// returns the textual representation of a FourCharCode (e.g. 'JPEG')
++static QString OSTStr( FourCharCode etype )
++{   union OSTStr {
++        struct {
++            char startquote;
++            uint32_t four;
++            char endquote;
++        } __attribute__ ((packed)) value;
++        char representation[7];
++    }  __attribute__ ((packed)) ltype;
++    ltype.value.four = EndianU32_BtoN(etype);
++    ltype.representation[0] = ltype.representation[5] = '\'';
++    ltype.representation[6] = '\0';
++    return QString::fromAscii(ltype.representation);
++}
++
++static SecKeychainRef defaultChain()
++{   QString errMsg;
++    SecKeychainRef keychain;
++    if( isError( SecKeychainCopyDefault(&amp;keychain), &amp;errMsg ) ){
++        kWarning() &lt;&lt; &quot;Could not retrieve reference to default keychain:&quot;  &lt;&lt; qPrintable(errMsg);
++        keychain = NULL;
++    }
++    return keychain;
++}
++
++/*! Return a name for @p keychain, and possibly the full path to its file
++ * The name  will be the equivalent of the `basename path .keychain` shell
++ * command.
++ */
++static QString keyChainName( SecKeychainRef keychain, QString *path=NULL )
++{   QFileInfo keyFile;
++    QString p = OSXKeychain::Path(keychain);
++    int ext = p.lastIndexOf(&quot;.keychain&quot;);
++    keyFile = QFileInfo( ((ext &gt; 0)? p.left(ext) : p) );
++    if( path ){
++        *path = QString(p);
++    }
++    return keyFile.fileName();
++}
++
++/*! Open an OS X keychain with name @p n.
++ * OS X keychains can be created without a full path (say, &quot;kdewallet&quot;), in which case they
++ * are stored e.g. as ~/Library/Keychains/kdewallet . However, opening a preexisting keychain like &quot;login&quot;
++ * without using the full path seems to fail even if e.g. ~/Library/Keychains/login exists.
++ * We try to work around that issue by matching @p n against the known keychain names.
++ */
++static OSStatus openKeychain( const QString &amp;n, SecKeychainRef *keychain )
++{   OSStatus err;
++    CFArrayRef list = NULL;
++
++    *keychain = NULL;
++    err = SecKeychainCopySearchList( &amp;list );
++    if( !err &amp;&amp; list ){
++        CFIndex len = CFArrayGetCount(list), i;
++        for( i = 0 ; i &lt; len &amp;&amp; !*keychain ; ++i ){
++            SecKeychainRef kr = (SecKeychainRef) CFArrayGetValueAtIndex( list, i );
++            QString path, name = keyChainName( kr, &amp;path );
++            if( name == n ){
++                // a hit, try to open it!
++                err = SecKeychainOpen( path.toUtf8(), keychain );
++                if( err ){
++                    kWarning() &lt;&lt; &quot;openKeychain(&quot; &lt;&lt; n &lt;&lt; &quot;) error&quot; &lt;&lt; err &lt;&lt; &quot;opening matching&quot; &lt;&lt; path;
++                }
++                else{
++                    kDebug() &lt;&lt; &quot;openKeychain(&quot; &lt;&lt; n &lt;&lt; &quot;) opened matching&quot; &lt;&lt; path;
++                }
++            }
++        }
++        CFRelease(list);
++    }
++    if( !*keychain ){
++        err = SecKeychainOpen( n.toUtf8(), keychain );
++    }
++    // we actually need to query the keychain's status to know if we succeeded
++    // in opening an existing keychain!
++    if( !err ){
++        SecKeychainStatus status;
++        err = SecKeychainGetStatus( *keychain, &amp;status );
++    }
++    return err;
++}
++
++static OSStatus basicWriteItem( const QByteArray *serviceName, const QByteArray &amp;accountName, const QByteArray &amp;value,
++                               const SecKeychainRef keychain, SecKeychainItemRef *itemRef=NULL )
++{   OSStatus err;
++    QString errMsg;
++    if( serviceName ){
++        err = SecKeychainAddGenericPassword( keychain, serviceName-&gt;size(), serviceName-&gt;constData(),
++                                                     accountName.size(), accountName.constData(),
++                                                     value.size(), value.constData(), itemRef );
++    }
++    else{
++        err = SecKeychainAddGenericPassword( keychain, 0, NULL,
++                                                     accountName.size(), accountName.constData(),
++                                                     value.size(), value.constData(), itemRef );
++    }
++    if( err != errSecDuplicateItem &amp;&amp; isError( err, &amp;errMsg ) ){
++        kWarning() &lt;&lt; &quot;Could not store password in keychain: &quot; &lt;&lt; qPrintable(errMsg);
++    }
++    return err;
++}
++
++OSXKeychain::OSXKeychain()
++    : name(&quot;default&quot;)
++{ QString errMsg;
++    keyChainRef = defaultChain();
++    if( keyChainRef ){
++        keyChainPath = OSXKeychain::Path(keyChainRef);
++        kDebug() &lt;&lt; &quot;Retrieved reference to default keychain&quot; &lt;&lt; (void*) keyChainRef &lt;&lt; &quot;in &quot; &lt;&lt; keyChainPath;
++        name = keyChainName(keyChainRef);
++        isDefaultKeychain = true;
++    }
++    else{
++        keyChainPath = QString::fromUtf8(&quot;&lt;undefined&gt;&quot;);
++    }
++    serviceList.clear();
++    serviceList.append(&quot;&quot;);
++}
++
++OSXKeychain::OSXKeychain(const QString &amp;n)
++    : name(n)
++{   QString errMsg;
++    OSStatus err = openKeychain( n, &amp;keyChainRef );
++
++    if( err == errSecNoSuchKeychain ){
++        kWarning() &lt;&lt; &quot;Keychain '&quot; &lt;&lt; n &lt;&lt; &quot;' does not exist: attempting to create it&quot;;
++        err = SecKeychainCreate( n.toUtf8(), 0, NULL, true, NULL, &amp;keyChainRef );
++        isKDEChain = true;
++    }
++
++    if( isError( err, &amp;errMsg ) ){
++        // the protocol cannot handle failure to open a keychain, so we have to return the default.
++        keyChainRef = defaultChain();
++        kWarning() &lt;&lt; &quot;Error opening keychain '&quot; &lt;&lt; n &lt;&lt; &quot;' (falling back to default keychain): &quot; &lt;&lt; qPrintable(errMsg);
++        name = keyChainName(keyChainRef);
++        isDefaultKeychain = true;
++    }
++    else{
++        isDefaultKeychain = false;
++    }
++
++    if( keyChainRef ){
++        keyChainPath = OSXKeychain::Path(keyChainRef);
++        kDebug() &lt;&lt; &quot;Retrieved reference to keychain&quot; &lt;&lt; name &lt;&lt; (void*) keyChainRef &lt;&lt; &quot;in &quot; &lt;&lt; keyChainPath;
++    }
++    else{
++        keyChainPath = QString::fromUtf8(&quot;&lt;undefined&gt;&quot;);
++    }
++    serviceList.clear();
++    serviceList.append(&quot;&quot;);
++}
++
++void OSXKeychain::close()
++{
++    if( keyChainRef ){
++        CFRelease(keyChainRef);
++        keyChainRef = NULL;
++    }
++}
++
++OSXKeychain::~OSXKeychain()
++{
++    close();
++}
++
++OSStatus OSXKeychain::renameItem(const QString &amp;currentKey, const QString &amp;newKey)
++{   OSStatus err;
++    SecKeychainItemRef itemRef = NULL;
++    err = ReadItem( currentKey, NULL, keyChainRef, &amp;itemRef, this );
++    if( !err &amp;&amp; itemRef ){
++        const QByteArray accountName( newKey.toUtf8() );
++        // store the new key in the account and label attributes
++        SecKeychainAttribute attr[] = { { kSecAccountItemAttr, accountName.size(), (void*) accountName.constData() },
++                                        { kSecLabelItemAttr, accountName.size(), (void*) accountName.constData() } };
++        SecKeychainAttributeList attrList = { 2, &amp;attr[0] };
++        QString errMsg;
++        if( isError( (err = SecKeychainItemModifyAttributesAndData( itemRef, &amp;attrList, 0, NULL )), &amp;errMsg ) ){
++            kWarning() &lt;&lt; &quot;OSXKeychain::renameItem(&quot; &lt;&lt; currentKey &lt;&lt; &quot;) couldn't change name &amp; label to&quot; &lt;&lt; accountName
++            &lt;&lt; &quot;:&quot; &lt;&lt; err &lt;&lt; &quot;=&quot; &lt;&lt; qPrintable(errMsg);
++        }
++        CFRelease(itemRef);
++    }
++    return err;
++}
++
++#pragma mark ========= static member functions =========
++
++OSStatus OSXKeychain::KeychainList(QStringList &amp;theList)
++{   CFArrayRef list = NULL;
++    OSStatus err = SecKeychainCopySearchList( &amp;list );
++    theList.clear();
++    if( !err &amp;&amp; list ){
++        CFIndex len = CFArrayGetCount(list), i;
++        for( i = 0 ; i &lt; len ; ++i ){
++            SecKeychainRef keychain = (SecKeychainRef) CFArrayGetValueAtIndex( list, i );
++            QString name = keyChainName(keychain);
++            if( name.size() &gt; 0 ){
++                theList.append(name);
++            }
++        }
++        CFRelease(list);
++    }
++    return err;
++}
++
++QString OSXKeychain::Path(const SecKeychainRef keychain)
++{   char pathName[MAXPATHLEN];
++    UInt32 plen = MAXPATHLEN;
++    if( SecKeychainGetPath( (keychain)? keychain : OSXKeychain().reference(), &amp;plen, pathName ) == errSecSuccess ){
++        return QString::fromUtf8(pathName);
++    }
++    else{
++        return QString();
++    }
++}
++
++bool OSXKeychain::IsOpen(const SecKeychainRef keychain)
++{   bool isOpen = false;
++    SecKeychainStatus status;
++    QString errMsg;
++    if( isError( SecKeychainGetStatus( keychain, &amp;status ), &amp;errMsg ) ){
++        if( keychain ){
++            kDebug() &lt;&lt; &quot;Could not get the status of keychain&quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot;:&quot;  &lt;&lt; qPrintable(errMsg);
++        }
++        else{
++            kWarning() &lt;&lt; &quot;Could not get the default keychain's status:&quot;  &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    else{
++        if( (status &amp; kSecUnlockStateStatus) &amp;&amp; (status &amp; kSecReadPermStatus) ){
++            isOpen = true;
++        }
++        else{
++            kDebug() &lt;&lt; &quot;Keychain&quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot; has status&quot; &lt;&lt; status;
++        }
++    }
++    return isOpen;
++}
++
++bool OSXKeychain::IsOpen(const QString &amp;walletName)
++{   SecKeychainRef keychain = NULL;
++    OSStatus err = openKeychain( walletName.toUtf8(), &amp;keychain );
++    bool ret = false;
++    if( !err &amp;&amp; keychain ){
++        ret = IsOpen(keychain);
++        CFRelease(keychain);
++    }
++    return ret;
++}
++
++OSStatus OSXKeychain::UnLock(const SecKeychainRef keychain)
++{   QString errMsg;
++    OSStatus err;
++    err = SecKeychainUnlock( keychain, 0, NULL, false );
++    if( isError( err, &amp;errMsg ) ){
++        if( keychain ){
++            kDebug() &lt;&lt; &quot;Could not unlock the keychain at '&quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot;': &quot; &lt;&lt; qPrintable(errMsg);
++        }
++        else{
++            kDebug() &lt;&lt; &quot;Could not unlock the default keychain:&quot;  &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    return err;
++}
++
++OSStatus OSXKeychain::Lock(const SecKeychainRef keychain)
++{   QString errMsg;
++    OSStatus err;
++    if( keychain ){
++        err = SecKeychainLock(keychain);
++        if( isError( err, &amp;errMsg ) ){
++            kDebug() &lt;&lt; &quot;Could not lock the keychain at '&quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot;': &quot; &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    else{
++        err = SecKeychainLockAll();
++        if( isError( err, &amp;errMsg ) ){
++            kDebug() &lt;&lt; &quot;Could not lock all keychains:&quot; &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    return err;
++}
++
++OSStatus OSXKeychain::Lock(const QString &amp;walletName)
++{   SecKeychainRef keychain = NULL;
++    OSStatus err = openKeychain( walletName, &amp;keychain );
++    if( !err &amp;&amp; keychain ){
++        err = Lock(keychain);
++           CFRelease(keychain);
++    }
++    return err;
++}
++
++/** use the keychain search functions to find the first matching item, if any, @return returning True if found.
++ The OS X error code is returned through @p errReturn when not NULL, the item itself through @p itemRef.
++ This reference will have to be released with CFRelease() when done with it (when @p itemRef==NULL the
++ function does this release itself).
++ */
++bool OSXKeychain::HasItem(const QString &amp;key,
++                     const SecKeychainRef keychain, OSStatus *errReturn, SecKeychainItemRef *itemRef)
++{   const QByteArray accountName( key.toUtf8() );
++    OSStatus err;
++    SecKeychainSearchRef searchRef;
++    SecKeychainAttribute attrs = { kSecAccountItemAttr, accountName.size(), (void*) accountName.constData() };
++    SecKeychainAttributeList attrList = { 1, &amp;attrs };
++    err = SecKeychainSearchCreateFromAttributes( keychain, kSecGenericPasswordItemClass,
++                                                (const SecKeychainAttributeList*) &amp;attrList, &amp;searchRef );
++    const CFReleaser&lt;SecKeychainSearchRef&gt; releaseSR(searchRef);
++    bool found;
++    SecKeychainItemRef item;
++    QString errMsg;
++    if( err ){
++        found = false;
++        errMsg = errorString(err);
++        kDebug() &lt;&lt; &quot;OSXKeychain::HasItem(&quot; &lt;&lt; key &lt;&lt; &quot;,&quot; &lt;&lt; (void*) keychain &lt;&lt; &quot;): SecKeychainSearchCreateFromAttributes failed&quot;;
++    }
++    else{
++            if( !(err = SecKeychainSearchCopyNext( searchRef, &amp;item )) ){
++                found = true;
++                if( itemRef ){
++                    *itemRef = item;
++                }
++                else if( item ){
++                    CFRelease(item);
++                }
++                errMsg = QString();
++            }
++            else{
++                found = false;
++                errMsg = errorString(err);
++            }
++            if( errReturn ){
++                *errReturn = err;
++            }
++    }
++    kDebug() &lt;&lt; ((found)? &quot;Found&quot; : &quot;Did not find&quot;) &lt;&lt; &quot;item '&quot; &lt;&lt; key &lt;&lt; &quot;' in keychain &quot; &lt;&lt; (void*) keychain &lt;&lt; &quot;, error=&quot; &lt;&lt; err &lt;&lt; &quot; &quot; &lt;&lt; qPrintable(errMsg);
++    return found;
++}
++
++OSStatus OSXKeychain::ReadItem(const QString &amp;key, QByteArray *value,
++                          const SecKeychainRef keychain, SecKeychainItemRef *itemRef, OSXKeychain *osxKeyChain)
++{   const QByteArray accountName( key.toUtf8() );
++    UInt32 passwordSize = 0;
++    void* passwordData = 0;
++    QString errMsg;
++    SecKeychainItemRef theItem;
++    OSStatus err = SecKeychainFindGenericPassword( keychain, 0, NULL,
++                                                  accountName.size(), accountName.constData(),
++                                                  &amp;passwordSize, &amp;passwordData, &amp;theItem );
++    if( isError( err, &amp;errMsg ) ){
++        kDebug() &lt;&lt; &quot;Error&quot; &lt;&lt; err &lt;&lt; &quot;retrieving password for '&quot; &lt;&lt; accountName &lt;&lt; &quot;' :&quot; &lt;&lt; qPrintable(errMsg);
++#if INTERNET_TOO
++        if( SecKeychainFindInternetPassword( keychain, 0, NULL,
++                                                      0, NULL,
++                                                      accountName.size(), accountName.constData(),
++                                                      0, NULL, 0,
++                                                      kSecProtocolTypeAny, kSecAuthenticationTypeDefault,
++                                                      &amp;passwordSize, &amp;passwordData, &amp;theItem ) ){
++            // just to be sure:
++            theItem = NULL;
++        }
++        else{
++            err = 0;
++            errMsg = QString();
++        }
++#else
++        theItem = NULL;
++#endif
++    }
++    if( !err &amp;&amp; theItem ){
++        if( value ){
++            *value = QByteArray( reinterpret_cast&lt;const char*&gt;( passwordData ), passwordSize );
++        }
++        SecKeychainItemFreeContent( NULL, passwordData );
++        if( osxKeyChain &amp;&amp; osxKeyChain-&gt;isKDEChain ){
++            SecKeychainAttribute attr = { kSecServiceItemAttr, 0, NULL };
++            SecKeychainAttributeList attrList = { 1, &amp;attr };
++            UInt32 len = 0;
++            // try to fetch the item's ServiceItem attribute
++            if( !SecKeychainItemCopyContent( theItem, NULL, &amp;attrList, &amp;len, NULL ) ){
++                if( attr.length &gt; 0 ){
++                    osxKeyChain-&gt;lastReadService.clear();
++                    osxKeyChain-&gt;lastReadService = QString::fromUtf8( (char*)attr.data, attr.length );
++                }
++                SecKeychainItemFreeContent( &amp;attrList, NULL );
++            }
++        }
++        if( itemRef ){
++            *itemRef = theItem;
++        }
++        else if( theItem ){
++            CFRelease(theItem);
++        }
++    }
++    kDebug() &lt;&lt; &quot;OSXKeychain::ReadItem '&quot; &lt;&lt; key &lt;&lt; &quot;' from keychain &quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot;, error=&quot; &lt;&lt; err;
++    return err;
++}
++
++OSStatus OSXKeychain::ItemType(const QString &amp;key, EntryType *entryType,
++                          const SecKeychainRef keychain)
++{   const QByteArray accountName( key.toUtf8() );
++    QString errMsg;
++    EntryType etype = (EntryType) 0;
++    SecKeychainItemRef itemRef;
++#if INTERNET_TOO
++    bool isInternetPW = false;
++#endif
++    OSStatus err = SecKeychainFindGenericPassword( keychain, 0, NULL,
++                                                  accountName.size(), accountName.constData(),
++                                                  NULL, NULL, &amp;itemRef );
++    if( isError( err, &amp;errMsg ) ){
++        kDebug() &lt;&lt; &quot;Error&quot; &lt;&lt; err &lt;&lt; &quot;retrieving type for '&quot; &lt;&lt; accountName &lt;&lt; &quot;' :&quot; &lt;&lt; qPrintable(errMsg);
++#if INTERNET_TOO
++        if( SecKeychainFindInternetPassword( keychain, 0, NULL,
++                                            0, NULL,
++                                            accountName.size(), accountName.constData(),
++                                            0, NULL, 0,
++                                            kSecProtocolTypeAny, kSecAuthenticationTypeDefault,
++                                            0, NULL, &amp;itemRef ) ){
++            // just to be sure:
++            itemRef = NULL;
++        }
++        else{
++            isInternetPW = true;
++            err = 0;
++            errMsg = QString();
++        }
++#else
++        itemRef = NULL;
++#endif
++    }
++    if( itemRef ){
++                UInt32 tags[] = { kSecTypeItemAttr };
++                UInt32 formats[] = { CSSM_DB_ATTRIBUTE_FORMAT_STRING };
++        SecKeychainAttributeInfo attrGet = { 1, tags, formats };
++        SecKeychainAttributeList *attrList = NULL;
++        err = SecKeychainItemCopyAttributesAndData( itemRef, &amp;attrGet, NULL, &amp;attrList, NULL, NULL );
++        if( !err ){
++            if( attrList-&gt;attr[0].length == sizeof(EntryType) ){
++                memcpy( &amp;etype, attrList-&gt;attr[0].data, sizeof(EntryType) );
++            }
++            else if( attrList-&gt;attr[0].length ){
++                kDebug() &lt;&lt; &quot;Error: key&quot; &lt;&lt; key &lt;&lt; &quot;item type retrieved is of size&quot; &lt;&lt; attrList-&gt;attr[0].length &lt;&lt; &quot;!=&quot; &lt;&lt; sizeof(EntryType);
++            }
++#if INTERNET_TOO
++            else if( isInternetPW ){
++                // this is just a wild guess ...
++                etype = Password;
++            }
++#endif
++            if( entryType ){
++                *entryType = etype;
++            }
++        }
++        SecKeychainItemFreeAttributesAndData( attrList, NULL );
++        CFRelease(itemRef);
++    }
++    kDebug() &lt;&lt; &quot;OSXKeychain::ItemType '&quot; &lt;&lt; key &lt;&lt; &quot;' from keychain &quot; &lt;&lt; OSXKeychain::Path(keychain) &lt;&lt; &quot;=&quot; &lt;&lt; OSTStr(etype) &lt;&lt; &quot;, error=&quot; &lt;&lt; err;
++    return err;
++}
++
++OSStatus OSXKeychain::RemoveItem(const QString &amp;key, const SecKeychainRef keychain)
++{   const QByteArray accountName( key.toUtf8() );
++    SecKeychainItemRef itemRef;
++    QString errMsg;
++    OSStatus result = SecKeychainFindGenericPassword( keychain, 0, NULL,
++                                                     accountName.size(), accountName.constData(), NULL, NULL, &amp;itemRef );
++    if( isError( result, &amp;errMsg ) ){
++        kDebug() &lt;&lt; &quot;Could not find entry&quot; &lt;&lt; key &lt;&lt; &quot;:&quot;  &lt;&lt; qPrintable(errMsg);
++    }
++    else{
++        const CFReleaser&lt;SecKeychainItemRef&gt; itemReleaser(itemRef);
++        result = SecKeychainItemDelete(itemRef);
++        if( isError( result, &amp;errMsg ) ){
++            kWarning() &lt;&lt; &quot;Could not delete entry&quot; &lt;&lt; key &lt;&lt; &quot;:&quot;  &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    return result;
++}
++
++OSStatus OSXKeychain::WriteItem( const QString &amp;key, const QByteArray &amp;value,
++                                                   const SecKeychainRef keychain, SecKeychainItemRef *itemRef, EntryType *entryType, OSXKeychain *osxKeyChain )
++{   const QByteArray accountName( key.toUtf8() );
++    OSStatus err;
++    QString errMsg;
++    SecKeychainItemRef theItem = NULL;
++    bool saveLabel;
++    if( osxKeyChain &amp;&amp; osxKeyChain-&gt;currentService.size() ){
++        const QByteArray serviceName( osxKeyChain-&gt;currentService.toUtf8() );
++        // save the &quot;GenericPassword&quot; item using the service name, which appears to be the only way to write
++        // to the &quot;Where&quot; field shown in the Keychain Utility.
++        err = basicWriteItem( &amp;serviceName, accountName, value, keychain, &amp;theItem );
++        // the service (folder!) string will also appear on the &quot;Name&quot; field, which however can be changed
++        // independently, via the Label attribute.
++        saveLabel = true;
++    }
++    else{
++        err = basicWriteItem( NULL, accountName, value, keychain, &amp;theItem );
++        saveLabel = false;
++    }
++    if( err == errSecDuplicateItem ){
++        // RJVB: the previous implementation was wrong. errSecDuplicateItem means the write failed because of an existing item.
++        // So we have to find that item, and modify it.
++        if( !(err = ReadItem( key, NULL, keychain, &amp;theItem )) ){
++            err = SecKeychainItemModifyAttributesAndData( theItem, NULL, value.size(), value.constData() );
++            if( isError( err, &amp;errMsg ) ){
++                kDebug() &lt;&lt; &quot;Key '&quot; &lt;&lt; key
++                    &lt;&lt; &quot;'already exists in keychain but error modifying the existing item: &quot; &lt;&lt; qPrintable(errMsg);
++            }
++        }
++        if( !err ){
++            kDebug() &lt;&lt; &quot;Key '&quot; &lt;&lt; key &lt;&lt; &quot;'already existed in keychain: modified the existing item&quot;;
++        }
++    }
++    if( !err &amp;&amp; saveLabel ){
++        // store the desired text in the label attribute
++        SecKeychainAttribute attr = { kSecLabelItemAttr, accountName.size(), (void*) accountName.constData() };
++        SecKeychainAttributeList attrList = { 1, &amp;attr };
++        QString errMsg;
++        if( isError( (err = SecKeychainItemModifyAttributesAndData( theItem, &amp;attrList, 0, NULL )), &amp;errMsg ) ){
++            kWarning() &lt;&lt; &quot;OSXKeychain::WriteItem(&quot; &lt;&lt; key &lt;&lt; &quot;) couldn't set the desired name/label&quot; &lt;&lt; accountName
++                &lt;&lt; &quot;:&quot; &lt;&lt; err &lt;&lt; &quot;=&quot; &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    if( !err ){
++        EntryType defType = Stream;
++        if( !entryType ){
++            entryType = &amp;defType;
++        }
++        SecKeychainAttribute attr = { kSecTypeItemAttr, sizeof(EntryType), (void*) entryType };
++        SecKeychainAttributeList attrList = { 1, &amp;attr };
++        QString errMsg;
++        if( isError( (err = SecKeychainItemModifyAttributesAndData( theItem, &amp;attrList, 0, NULL )), &amp;errMsg ) ){
++            kWarning() &lt;&lt; &quot;OSXKeychain::WriteItem(&quot; &lt;&lt; key &lt;&lt; &quot;) couldn't set type to&quot; &lt;&lt; OSTStr(*entryType)
++                &lt;&lt; &quot;:&quot; &lt;&lt; qPrintable(errMsg);
++        }
++    }
++    if( itemRef ){
++        *itemRef = theItem;
++    }
++    else if( theItem ){
++        CFRelease(theItem);
++    }
++    kDebug() &lt;&lt; &quot;OSXKeychain::WriteItem '&quot; &lt;&lt; key &lt;&lt; &quot;' to keychain &quot; &lt;&lt; (void*) keychain &lt;&lt; &quot;, error=&quot; &lt;&lt; err;
++    return err;
++}
++
++OSStatus OSXKeychain::WriteItem( const QString &amp;key, const QByteArray &amp;value,
++                                 const QString &amp;comment, const SecKeychainRef keychain, EntryType *entryType, OSXKeychain *osxKeyChain )
++{   SecKeychainItemRef itemRef = NULL;
++    OSStatus err = WriteItem( key, value, keychain, &amp;itemRef, entryType, osxKeyChain );
++    if( !err &amp;&amp; itemRef ){
++        const QByteArray commentString(comment.toUtf8());
++        if( commentString.size() ){
++            SecKeychainAttribute attr = { kSecCommentItemAttr, commentString.size(), (void*) commentString.constData() };
++            SecKeychainAttributeList attrList = { 1, &amp;attr };
++            QString errMsg;
++            if( isError( (err = SecKeychainItemModifyAttributesAndData( itemRef, &amp;attrList, 0, NULL )), &amp;errMsg ) ){
++                kWarning() &lt;&lt; &quot;OSXKeychain::WriteItem(&quot; &lt;&lt; key &lt;&lt; &quot;) couldn't add comment&quot; &lt;&lt; comment
++                    &lt;&lt; &quot;:&quot; &lt;&lt; qPrintable(errMsg);
++            }
++        }
++        CFRelease(itemRef);
++    }
++    return err;
++}
++
++// returns the kSecAccountItemAttr's of all items in the keychain
++OSStatus OSXKeychain::ItemList( SecKeychainRef keychain, QStringList &amp;keyList, OSXKeychain *osxKeyChain )
++{   OSStatus err;
++    SecKeychainSearchRef searchRef[2];
++    bool generateFolderList = ( osxKeyChain &amp;&amp; osxKeyChain-&gt;isKDEChain &amp;&amp; osxKeyChain-&gt;generateFolderList );
++
++    keyList.clear();
++    if( generateFolderList ){
++        osxKeyChain-&gt;serviceList.clear();
++        if( osxKeyChain-&gt;currentService.size() &gt; 0 ){
++            osxKeyChain-&gt;serviceList.append(osxKeyChain-&gt;currentService);
++        }
++    }
++
++    err = SecKeychainSearchCreateFromAttributes( keychain, kSecGenericPasswordItemClass, NULL, &amp;searchRef[0] );
++#if INTERNET_TOO
++    if( SecKeychainSearchCreateFromAttributes( keychain, kSecInternetPasswordItemClass, NULL, &amp;searchRef[1] ) ){
++        searchRef[1] = NULL;
++    }
++#else
++    searchRef[1] = NULL;
++#endif
++    SecKeychainItemRef item;
++    QString errMsg;
++    if( isError(err, &amp;errMsg) ){
++        kDebug() &lt;&lt; &quot;OSXKeychain::ItemList(&quot; &lt;&lt; (void*) keychain &lt;&lt; &quot;): SecKeychainSearchCreateFromAttributes failed&quot; &lt;&lt; qPrintable(errMsg);
++    }
++    else{
++        for( size_t i = 0 ; i &lt; sizeof(searchRef)/sizeof(SecKeychainSearchRef) &amp;&amp; !err ; ++i ){
++            if( searchRef[i] ){
++                while( !(err = SecKeychainSearchCopyNext( searchRef[i], &amp;item )) ){
++                    if( item ){
++                        // whether the item will be listed in the keyList we return: by default it is
++                        // (better an item shows up multiple times than not at all).
++                        bool listItem = true;
++                        SecKeychainAttribute attr = { kSecAccountItemAttr, 0, NULL };
++                        SecKeychainAttributeList attrList = { 1, &amp;attr };
++                        UInt32 len = 0;
++                        if( osxKeyChain &amp;&amp; osxKeyChain-&gt;isKDEChain ){
++                            // try to fetch the item's ServiceItem attribute
++                            attr.tag = kSecServiceItemAttr;
++                            if( !SecKeychainItemCopyContent( item, NULL, &amp;attrList, &amp;len, NULL ) ){
++                                QString lbl = QString::fromUtf8( (char*)attr.data, attr.length );
++                                // we got a service item attribute, which is where we store the kwallet folder info.
++                                // If we disallow empty attributes, keychain items without service item attribute will
++                                // appear in each folder that has a non-empty name. In other words, we allow a folder without name.
++                                if( generateFolderList ){
++                                    // add the &quot;folder&quot; to the list if not already listed
++                                    if( !osxKeyChain-&gt;serviceList.contains(lbl) ){
++                                        osxKeyChain-&gt;serviceList.append(lbl);
++                                    }
++                                }
++                                else{
++                                    // only list the item if it's in the current &quot;folder&quot;
++                                    listItem = (lbl == osxKeyChain-&gt;currentService);
++                                }
++                                SecKeychainItemFreeContent( &amp;attrList, NULL );
++                            }
++                        }
++                        else{
++                            // errors retrieving the service item attribute are ignored
++                        }
++                        if( listItem ){
++                            attr.tag = kSecAccountItemAttr;
++                            if( !(err = SecKeychainItemCopyContent( item, NULL, &amp;attrList, &amp;len, NULL )) ){
++                                if( attr.length &gt; 0 ){
++                                    keyList.append(QString::fromUtf8( (char*)attr.data, attr.length ));
++                                }
++                                SecKeychainItemFreeContent( &amp;attrList, NULL );
++                            }
++                            else{
++                                errMsg = errorString(err);
++                                kDebug() &lt;&lt; &quot;SecKeychainItemCopyContent returned&quot; &lt;&lt; err &lt;&lt; &quot;=&quot; &lt;&lt; qPrintable(errMsg);
++                            }
++                        }
++                        CFRelease(item);
++                    }
++                }
++                if( err ){
++                    errMsg = errorString(err);
++                }
++                CFRelease(searchRef[i]);
++            }
++        }
++    }
++    return err;
++}
++
++OSStatus OSXKeychain::Destroy( SecKeychainRef *keychain )
++{   OSStatus err = SecKeychainDelete(*keychain);
++    QString errMsg;
++    if( isError( err, &amp;errMsg ) ){
++        kWarning() &lt;&lt; &quot;OSXKeychain::Destroy &quot; &lt;&lt; (void*) *keychain &lt;&lt; &quot;, error &quot; &lt;&lt; qPrintable(errMsg);
++    }
++    else{
++        kWarning() &lt;&lt; &quot;OSXKeychain::Destroy &quot; &lt;&lt; (void*) *keychain &lt;&lt; &quot;, error=&quot; &lt;&lt; err;
++    }
++    if( keychain ){
++        CFRelease(*keychain);
++        *keychain = NULL;
++    }
++    return err;
++}
++
++OSStatus OSXKeychain::Destroy( const QString &amp;walletName )
++{   SecKeychainRef keychain;
++    OSStatus err = openKeychain( walletName, &amp;keychain );
++    if( !err &amp;&amp; keychain ){
++        err = Destroy(&amp;keychain);
++    }
++    return err;
++}
+diff -urN kdelibs-4.13.3-orig/kdeui/util/qosxkeychain.h kdelibs-4.13.3/kdeui/util/qosxkeychain.h
+--- kdelibs-4.13.3-orig/kdeui/util/qosxkeychain.h        1970-01-01 09:00:00.000000000 +0900
++++ kdelibs-4.13.3/kdeui/util/qosxkeychain.h        2014-09-22 19:47:04.000000000 +0900
+@@ -0,0 +1,278 @@
++/*
++ *  @file qosxkeychain.h
++ *  This file is part of the KDE project
++ *
++ *  Created by René J.V. Bertin on 20140809.
++ *  Copyright 2014 RJVB.
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB.  If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#ifndef _QOSXKEYCHAIN_H
++
++#include &lt;Security/Security.h&gt;
++#include &lt;Security/SecKeychain.h&gt;
++
++namespace {
++    template &lt;typename T&gt;
++    struct CFReleaser {
++        explicit CFReleaser( const T&amp; r ) : ref( r ) {}
++        ~CFReleaser() { if( ref ){ CFRelease( ref ); } }
++        T ref;
++    };
++
++    template &lt;typename T&gt;
++    struct CPPDeleter {
++        explicit CPPDeleter( const T&amp; r ) : ptr( r ) {}
++        ~CPPDeleter() { if( ptr ){ delete ptr; } }
++        T ptr;
++    };
++
++    template &lt;typename T&gt;
++    struct CPPArrayDeleter {
++        explicit CPPArrayDeleter( const T&amp; r ) : ptr( r ) {}
++        ~CPPArrayDeleter() { if( ptr ){ delete[] ptr; } }
++        T ptr;
++    };
++
++    template &lt;typename T&gt;
++    struct CacheOldValue {
++        explicit CacheOldValue( T &amp;var, const T newVal )
++            : oldVal(var), varRef(var)
++        {
++            var = newVal;
++        }
++        ~CacheOldValue()
++        {
++            varRef = oldVal;
++        }
++        T oldVal, &amp;varRef;
++    };
++}
++
++static inline QString asQString( CFStringRef sr )
++{
++    if( sr ){
++        CFIndex len = CFStringGetLength(sr)*2;
++        const CPPArrayDeleter&lt;char*&gt; buff(new char[len]);
++        if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingUTF8 ) ){
++            return QString::fromUtf8(buff.ptr); //RJVB: use UTF8
++        }
++        else if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingNonLossyASCII ) ){
++            return QString::fromLocal8Bit(buff.ptr);
++        }
++        else{
++            CFStringGetCString( sr, buff.ptr, len, NULL );
++            return QString::fromLatin1(buff.ptr);
++        }
++    }
++    else{
++        return QString();
++    }
++}
++
++static inline QString errorString( OSStatus s )
++{
++    const CFReleaser&lt;CFStringRef&gt; ref( SecCopyErrorMessageString( s, NULL ) );
++    return asQString( ref.ref );
++}
++
++static inline bool isError( OSStatus s, QString *errMsg )
++{
++    if( errMsg ){
++        *errMsg = errorString(s);
++    }
++    return s != 0;
++}
++
++class OSXKeychain : public QObject
++{
++    Q_OBJECT
++private:
++    SecKeychainRef keyChainRef;
++    QString keyChainPath;
++    bool isDefaultKeychain, generateFolderList;
++
++public:
++        enum EntryType { Unknown='K\?\?\?', Password='KPWD', Map='KMAP', Stream='KSTR' };
++    QString name;
++    QString currentService, lastReadService;
++    QStringList serviceList;
++    bool isKDEChain;
++
++    OSXKeychain();
++    OSXKeychain(const QString &amp;name, bool *isNew=NULL);
++    virtual ~OSXKeychain();
++
++    inline SecKeychainRef reference()
++    {
++        return keyChainRef;
++    }
++    inline QString &amp;path()
++    {
++        return keyChainPath;
++    }
++    inline bool isDefault()
++    {
++            return isDefaultKeychain;
++    }
++    inline bool isOpen()
++    {
++        // we're either a KDE wallet/keychain and we have a valid keyChainRef,
++        // or we're not KDE and IsOpen will return the state of the default
++        // keychain if keyChainRef==NULL.
++        if( !isKDEChain || keyChainRef ){
++            return IsOpen(keyChainRef);
++        }
++        else{
++            return false;
++        }
++    }
++    inline OSStatus lock()
++    {
++        if( !isKDEChain || keyChainRef ){
++            return Lock(keyChainRef);
++        }
++        else{
++            return 0;
++        }
++    }
++    inline OSStatus unLock()
++    {
++        if( !isKDEChain || keyChainRef ){
++            return UnLock(keyChainRef);
++        }
++        else{
++            return 0;
++        }
++    }
++    virtual void close();
++    OSStatus lockSettings(int &amp;closeWhenIdle, unsigned int &amp;idleTimeoutMin);
++    OSStatus setLockSettings(int closeWhenIdle, unsigned int idleTimeoutMin);
++    inline bool hasItem(const QString &amp;key, OSStatus *errReturn, SecKeychainItemRef *itemRef=NULL)
++    {
++        if( !isKDEChain || keyChainRef ){
++            return OSXKeychain::HasItem( key, keyChainRef, errReturn, itemRef );
++        }
++        else{
++            return false;
++        }
++    }
++    inline OSStatus readItem(const QString &amp;key, QByteArray *value, SecKeychainItemRef *itemRef=NULL)
++    {
++        if( !isKDEChain || keyChainRef ){
++            return ReadItem( key, value, keyChainRef, itemRef, this );
++        }
++        else{
++            return 0;
++        }
++    }
++    inline OSStatus itemType(const QString &amp;key, EntryType *entryType)
++    {
++        if( !isKDEChain || keyChainRef ){
++            return ItemType( key, entryType, keyChainRef );
++        }
++        else{
++            return 0;
++        }
++    }
++    inline OSStatus removeItem(const QString &amp;key)
++    {
++        if( !isKDEChain || keyChainRef ){
++            return RemoveItem( key, keyChainRef );
++        }
++        else{
++            return 0;
++        }
++    }
++    inline OSStatus writeItem( const QString &amp;key, const QByteArray &amp;value, EntryType *entryType=NULL )
++    {
++        if( !isKDEChain || keyChainRef ){
++            return WriteItem( key, value, keyChainRef, NULL, entryType, this );
++        }
++        else{
++            return 0;
++        }
++    }
++    inline OSStatus writeItem( const QString &amp;key, const QByteArray &amp;value, const QString &amp;comment,
++                               EntryType *entryType=NULL )
++    {
++        if( !isKDEChain || keyChainRef ){
++            return WriteItem( key, value, comment, keyChainRef, entryType, this );
++        }
++        else{
++            return 0;
++        }
++    }
++    inline OSStatus itemList( QStringList &amp;keyList )
++    {
++        if( !isKDEChain || keyChainRef ){
++            return ItemList( keyChainRef, keyList, this );
++        }
++        else{
++            return 0;
++        }
++    }
++    inline QStringList folderList()
++    {
++        if( !isKDEChain || keyChainRef ){
++            QStringList r;
++            CacheOldValue&lt;bool&gt; gFL(generateFolderList, true);
++            ItemList( keyChainRef, r, this );
++            r.clear();
++            return serviceList;
++        }
++        else{
++            return QStringList();
++        }
++    }
++    OSStatus renameItem(const QString &amp;currentKey, const QString &amp;newKey);
++
++#pragma mark ==== class methods aka static member functions ====
++    static OSStatus KeychainList(QStringList &amp;theList);
++    static QString Path(const SecKeychainRef keychain);
++    static bool IsOpen(const SecKeychainRef keychain);
++    static bool IsOpen(const QString&amp; name);
++    static OSStatus UnLock(const SecKeychainRef keychain);
++    static OSStatus Lock(const SecKeychainRef keychain);
++    static OSStatus Lock(const QString &amp;walletName);
++    /** use the keychain search functions to find the first matching item, if any, returning True if found.
++     The OS X error code is returned through @p errReturn when not NULL, the item itself through @p itemRef.
++     This reference will have to be released with CFRelease() when done with it (when @p itemRef==NULL the
++     function does this release itself).
++     */
++    static bool HasItem(const QString &amp;key,
++                         const SecKeychainRef keychain, OSStatus *errReturn, SecKeychainItemRef *itemRef);
++    static OSStatus ReadItem(const QString &amp;key, QByteArray *value,
++                              const SecKeychainRef keychain, SecKeychainItemRef *itemRef=NULL, OSXKeychain *osxKeyChain=NULL);
++    static OSStatus ItemType(const QString &amp;key, EntryType *entryType,
++                               const SecKeychainRef keychain);
++    static OSStatus RemoveItem(const QString &amp;key, const SecKeychainRef keychain);
++    static OSStatus WriteItem( const QString &amp;key, const QByteArray &amp;value,
++                               const SecKeychainRef keychain, SecKeychainItemRef *itemRef=NULL, EntryType *entryType=NULL, OSXKeychain *osxKeyChain=NULL );
++    static OSStatus WriteItem( const QString&amp; key, const QByteArray&amp; value,
++                               const QString&amp; comment, const SecKeychainRef keychain, EntryType *entryType, OSXKeychain *osxKeyChain=NULL );
++    static OSStatus ItemList( const SecKeychainRef keychain, QStringList &amp;keyList, OSXKeychain *osxKeyChain=NULL );
++    static OSStatus Destroy( SecKeychainRef *keychain );
++    static OSStatus Destroy( const QString &amp;walletName );
++
++private Q_SLOTS:
++    virtual void slotIdleTimedOut()
++    {}
++};
++
++#define _QOSXKEYCHAIN_H
++#endif
+\ No newline at end of file
+diff -urN kdelibs-4.13.3-orig/kdeui/util/qosxkeychain.h.orig kdelibs-4.13.3/kdeui/util/qosxkeychain.h.orig
+--- kdelibs-4.13.3-orig/kdeui/util/qosxkeychain.h.orig        1970-01-01 09:00:00.000000000 +0900
++++ kdelibs-4.13.3/kdeui/util/qosxkeychain.h.orig        2014-09-22 19:46:10.000000000 +0900
+@@ -0,0 +1,203 @@
++/*
++ *  @file qosxkeychain.h
++ *  This file is part of the KDE project
++ *
++ *  Created by René J.V. Bertin on 20140809.
++ *  Copyright 2014 RJVB.
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB.  If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#include &lt;Security/Security.h&gt;
++#include &lt;Security/SecKeychain.h&gt;
++
++namespace {
++    template &lt;typename T&gt;
++    struct CFReleaser {
++        explicit CFReleaser( const T&amp; r ) : ref( r ) {}
++        ~CFReleaser() { if( ref ){ CFRelease( ref ); } }
++        T ref;
++    };
++
++    template &lt;typename T&gt;
++    struct CPPDeleter {
++        explicit CPPDeleter( const T&amp; r ) : ptr( r ) {}
++        ~CPPDeleter() { if( ptr ){ delete ptr; } }
++        T ptr;
++    };
++
++    template &lt;typename T&gt;
++    struct CPPArrayDeleter {
++        explicit CPPArrayDeleter( const T&amp; r ) : ptr( r ) {}
++        ~CPPArrayDeleter() { if( ptr ){ delete[] ptr; } }
++        T ptr;
++    };
++
++    template &lt;typename T&gt;
++    struct CacheOldValue {
++        explicit CacheOldValue( T &amp;var, const T newVal )
++            : oldVal(var), varRef(var)
++        {
++            var = newVal;
++        }
++        ~CacheOldValue()
++        {
++            varRef = oldVal;
++        }
++        T oldVal, &amp;varRef;
++    };
++}
++
++static inline QString asQString( CFStringRef sr )
++{   CFIndex len = CFStringGetLength(sr)*2;
++    const CPPArrayDeleter&lt;char*&gt; buff(new char[len]);
++    if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingUTF8 ) ){
++        return QString::fromUtf8(buff.ptr); //RJVB: use UTF8
++    }
++    else if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingNonLossyASCII ) ){
++        return QString::fromLocal8Bit(buff.ptr);
++    }
++    else{
++        CFStringGetCString( sr, buff.ptr, len, NULL );
++        return QString::fromLatin1(buff.ptr);
++    }
++}
++
++static inline QString errorString( OSStatus s )
++{
++    const CFReleaser&lt;CFStringRef&gt; ref( SecCopyErrorMessageString( s, NULL ) );
++    return asQString( ref.ref );
++}
++
++static inline bool isError( OSStatus s, QString *errMsg )
++{
++    if( errMsg ){
++        *errMsg = errorString(s);
++    }
++    return s != 0;
++}
++
++class OSXKeychain
++{
++private:
++    SecKeychainRef keyChainRef;
++    QString keyChainPath;
++    bool isDefaultKeychain, generateFolderList;
++
++public:
++        enum EntryType { Unknown='K\?\?\?', Password='KPWD', Map='KMAP', Stream='KSTR' };
++    QString name;
++    QString currentService, lastReadService;
++    QStringList serviceList;
++    bool isKDEChain;
++
++    OSXKeychain();
++    OSXKeychain(const QString &amp;name);
++    virtual ~OSXKeychain();
++
++    inline SecKeychainRef reference()
++    {
++        return keyChainRef;
++    }
++    inline QString &amp;path()
++    {
++        return keyChainPath;
++    }
++    inline bool isDefault()
++    {
++            return isDefaultKeychain;
++    }
++    inline bool isOpen()
++    {
++        return IsOpen(keyChainRef);
++    }
++    inline OSStatus lock()
++    {
++        return Lock(keyChainRef);
++    }
++    inline OSStatus unLock()
++    {
++        return UnLock(keyChainRef);
++    }
++    void close();
++    inline bool hasItem(const QString &amp;key, OSStatus *errReturn, SecKeychainItemRef *itemRef=NULL)
++    {
++            // qDebug() &lt;&lt; &quot;OSXKeychain::hasItem(&quot; &lt;&lt; key &lt;&lt; &quot;): scanning '&quot; &lt;&lt; name &lt;&lt; &quot;'=&quot; &lt;&lt; (void*) keyChainRef;
++            return OSXKeychain::HasItem( key, keyChainRef, errReturn, itemRef );
++    }
++    inline OSStatus readItem(const QString &amp;key, QByteArray *value, SecKeychainItemRef *itemRef=NULL)
++    {
++        return ReadItem( key, value, keyChainRef, itemRef, this );
++    }
++    inline OSStatus itemType(const QString &amp;key, EntryType *entryType)
++    {
++        return ItemType( key, entryType, keyChainRef );
++    }
++    inline OSStatus removeItem(const QString &amp;key)
++    {
++        return RemoveItem( key, keyChainRef );
++    }
++    inline OSStatus writeItem( const QString &amp;key, const QByteArray &amp;value, EntryType *entryType=NULL )
++    {
++        return WriteItem( key, value, keyChainRef, NULL, entryType, this );
++    }
++    inline OSStatus writeItem( const QString &amp;key, const QByteArray &amp;value, const QString &amp;comment,
++                               EntryType *entryType=NULL )
++    {
++        return WriteItem( key, value, comment, keyChainRef, entryType, this );
++    }
++    inline OSStatus itemList( QStringList &amp;keyList )
++    {
++        return ItemList( keyChainRef, keyList, this );
++    }
++    inline QStringList folderList()
++    {
++        QStringList r;
++        CacheOldValue&lt;bool&gt; gFL(generateFolderList, true);
++        ItemList( keyChainRef, r, this );
++        r.clear();
++        return serviceList;
++    }
++    OSStatus renameItem(const QString &amp;currentKey, const QString &amp;newKey);
++
++#pragma mark ==== class methods aka static member functions ====
++    static OSStatus KeychainList(QStringList &amp;theList);
++    static QString Path(const SecKeychainRef keychain);
++    static bool IsOpen(const SecKeychainRef keychain);
++    static bool IsOpen(const QString&amp; name);
++    static OSStatus UnLock(const SecKeychainRef keychain);
++    static OSStatus Lock(const SecKeychainRef keychain);
++    static OSStatus Lock(const QString &amp;walletName);
++    /** use the keychain search functions to find the first matching item, if any, returning True if found.
++     The OS X error code is returned through @p errReturn when not NULL, the item itself through @p itemRef.
++     This reference will have to be released with CFRelease() when done with it (when @p itemRef==NULL the
++     function does this release itself).
++     */
++    static bool HasItem(const QString &amp;key,
++                         const SecKeychainRef keychain, OSStatus *errReturn, SecKeychainItemRef *itemRef);
++    static OSStatus ReadItem(const QString &amp;key, QByteArray *value,
++                              const SecKeychainRef keychain, SecKeychainItemRef *itemRef=NULL, OSXKeychain *osxKeyChain=NULL);
++    static OSStatus ItemType(const QString &amp;key, EntryType *entryType,
++                               const SecKeychainRef keychain);
++    static OSStatus RemoveItem(const QString &amp;key, const SecKeychainRef keychain);
++    static OSStatus WriteItem( const QString &amp;key, const QByteArray &amp;value,
++                               const SecKeychainRef keychain, SecKeychainItemRef *itemRef=NULL, EntryType *entryType=NULL, OSXKeychain *osxKeyChain=NULL );
++    static OSStatus WriteItem( const QString&amp; key, const QByteArray&amp; value,
++                               const QString&amp; comment, const SecKeychainRef keychain, EntryType *entryType, OSXKeychain *osxKeyChain=NULL );
++    static OSStatus ItemList( const SecKeychainRef keychain, QStringList &amp;keyList, OSXKeychain *osxKeyChain=NULL );
++    static OSStatus Destroy( SecKeychainRef *keychain );
++    static OSStatus Destroy( const QString &amp;walletName );
++};
</ins></span></pre></div>
<a id="trunkdportskdekdelibs4filespatchcmakemodulesKDE4Macroscmakediff"></a>
<div class="delfile"><h4>Deleted: trunk/dports/kde/kdelibs4/files/patch-cmake-modules-KDE4Macros.cmake.diff (126339 => 126340)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/dports/kde/kdelibs4/files/patch-cmake-modules-KDE4Macros.cmake.diff        2014-10-08 10:38:21 UTC (rev 126339)
+++ trunk/dports/kde/kdelibs4/files/patch-cmake-modules-KDE4Macros.cmake.diff        2014-10-08 11:03:41 UTC (rev 126340)
</span><span class="lines">@@ -1,14 +0,0 @@
</span><del>---- kdelibs-4.12.5/cmake/modules/KDE4Macros.cmake.orig        2014-04-28 13:37:51.000000000 +0900
-+++ kdelibs-4.12.5/cmake/modules/KDE4Macros.cmake        2014-05-16 21:32:41.000000000 +0900
-@@ -829,9 +829,9 @@

-       if (Q_WS_MAC)
-               list(FIND _SRCS *.icns _icon_position)
--              if(NOT _res_position EQUAL -1)
-+              if(NOT _icon_position EQUAL -1)
-                       list(GET _SRCS ${_icon_position} _resourcefile)
--              endif(NOT _res_position EQUAL -1)
-+              endif(NOT _icon_position EQUAL -1)
-       endif (Q_WS_MAC)
-       kde4_add_executable(${_target_NAME} &quot;${_nogui}&quot; ${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_dummy.cpp ${_resourcefile})
-       target_link_libraries(${_target_NAME} kdeinit_${_target_NAME})
</del></span></pre></div>
<a id="trunkdportskdekdelibs4filespatchfixKCrashdiff"></a>
<div class="addfile"><h4>Added: trunk/dports/kde/kdelibs4/files/patch-fixKCrash.diff (0 => 126340)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/dports/kde/kdelibs4/files/patch-fixKCrash.diff                                (rev 0)
+++ trunk/dports/kde/kdelibs4/files/patch-fixKCrash.diff        2014-10-08 11:03:41 UTC (rev 126340)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+diff -ur kdelibs-4.13.3-orig/kdeui/util/kcrash.cpp kdelibs-4.13.3/kdeui/util/kcrash.cpp
+--- kdelibs-4.13.3-orig/kdeui/util/kcrash.cpp        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kdeui/util/kcrash.cpp        2014-09-20 15:20:58.000000000 +0900
+@@ -313,7 +313,13 @@
+         crashRecursionCounter++;
+     }

+-#if !defined(Q_OS_WIN)
++    // On Apple OS X, closing all FDs now will cause a second (SIGILL) crash,
++    // ending with &quot;Unable to start Dr. Konqi&quot;. This is because the libdispatch
++    // library, which can manage multi-threading, has some FDs of its own.
++    //
++    // Note: KCrash closes FDs unconditionally later on if it forks to Dr Konqi
++    //       and this program's FDs do not matter if kdeinit starts Dr Konqi.
++#if !defined(Q_OS_WIN) and !defined(Q_OS_MAC)
+     if (!(s_flags &amp; KeepFDs))
+         closeAllFDs();
+ # if defined(Q_WS_X11)
+@@ -520,9 +526,12 @@
+     // This is done because it is dangerous to use fork() in the crash handler
+     // (there can be functions registered to be performed before fork(), for example handling
+     // of malloc locking, which doesn't work when malloc crashes because of heap corruption).
++#ifndef Q_OS_MAC
++    // Fails on Apple OSX+KDE4, because kdeinit4 is using the wrong socket name.
+     if (!(s_flags &amp; AlwaysDirectly)) {
+         startDirectly = !startProcessInternal(argc, argv, waitAndExit, false);
+     }
++#endif

+     // If we can't reach kdeinit, we can still at least try to fork()
+     if (startDirectly) {
+@@ -805,7 +814,8 @@

+   server.sun_family = AF_UNIX;
+   strcpy(server.sun_path, sock_file);
+-  printf(&quot;sock_file=%s\n&quot;, sock_file);
++  // Use stderr, to make the message visible on the Apple OS X Console log.
++  fprintf(stderr, &quot;KCrash: Connect sock_file=%s\n&quot;, sock_file);
+   socklen = sizeof(server);
+   if(connect(s, (struct sockaddr *)&amp;server, socklen) == -1)
+   {
</ins></span></pre></div>
<a id="trunkdportskdekdelibs4filespatchnativeDialogsdiff"></a>
<div class="addfile"><h4>Added: trunk/dports/kde/kdelibs4/files/patch-nativeDialogs.diff (0 => 126340)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/dports/kde/kdelibs4/files/patch-nativeDialogs.diff                                (rev 0)
+++ trunk/dports/kde/kdelibs4/files/patch-nativeDialogs.diff        2014-10-08 11:03:41 UTC (rev 126340)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+diff -ur kdelibs-4.13.3-orig/kdeui/widgets/kmainwindow.cpp kdelibs-4.13.3/kdeui/widgets/kmainwindow.cpp
+--- kdelibs-4.13.3-orig/kdeui/widgets/kmainwindow.cpp        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kdeui/widgets/kmainwindow.cpp        2014-09-20 18:52:54.000000000 +0900
+@@ -241,6 +241,8 @@

+     q-&gt;setAttribute( Qt::WA_DeleteOnClose );

++    q-&gt;setUnifiedTitleAndToolBarOnMac(true);
++
+     // We handle this functionality (quitting the app) ourselves, with KGlobal::ref/deref.
+     // This makes apps stay alive even if they only have a systray icon visible, or
+     // a progress widget with &quot;keep open&quot; checked, for instance.
+diff -ur kdelibs-4.13.3-orig/kio/kfile/kfiledialog.cpp kdelibs-4.13.3/kio/kfile/kfiledialog.cpp
+--- kdelibs-4.13.3-orig/kio/kfile/kfiledialog.cpp        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kio/kfile/kfiledialog.cpp        2014-09-20 18:52:54.000000000 +0900
+@@ -44,8 +44,8 @@
+ #include &quot;krecentdirs.h&quot;
+ #include &quot;kservice.h&quot;

+-/** File dialogs are native by default on Windows. */
+-#if defined(Q_WS_WIN) || defined(Q_WS_MAEMO_5)
++/** File dialogs are native by default on Windows and Mac. */
++#if defined(Q_WS_WIN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAC)
+ const bool NATIVE_FILEDIALOGS_BY_DEFAULT = true;
+ #else
+ const bool NATIVE_FILEDIALOGS_BY_DEFAULT = false;
+@@ -252,7 +252,7 @@

+ KFileDialog::KFileDialog( const KUrl&amp; startDir, const QString&amp; filter,
+                           QWidget *parent, QWidget* customWidget)
+-#ifdef Q_WS_WIN
++#if (defined Q_WS_WIN || defined Q_WS_MAC )
+     : KDialog( parent , Qt::WindowMinMaxButtonsHint),
+ #else
+     : KDialog( parent ),
+@@ -312,8 +312,8 @@
+     connect(fileQWidget, SIGNAL(accepted()), SLOT(accept()));
+     //connect(fileQWidget, SIGNAL(canceled()), SLOT(slotCancel()));

+-    if (customWidget)
+-     d-&gt;w-&gt;setCustomWidget(QString(), customWidget);
++    if (customWidget){}
++     //d-&gt;w-&gt;setCustomWidget(QString(), customWidget);
+ }


+@@ -961,7 +961,7 @@
+     return d-&gt;w;
+ }

+-#ifdef Q_WS_WIN
++#if (defined Q_WS_WIN || defined Q_WS_MAC)
+ int KFileDialog::exec()
+ {
+     if (!d-&gt;native || !KFileDialogPrivate::Native::s_allowNative) {
+@@ -1051,7 +1051,7 @@

+     return res;
+ }
+-#endif // Q_WS_WIN
++#endif // Q_WS_WIN || Q_WS_MAC

+ #ifdef Q_WS_WIN
+ #define KF_EXTERN extern __declspec(dllimport)
+diff -ur kdelibs-4.13.3-orig/kio/kfile/kfiledialog.h kdelibs-4.13.3/kio/kfile/kfiledialog.h
+--- kdelibs-4.13.3-orig/kio/kfile/kfiledialog.h        2014-07-11 15:42:13.000000000 +0900
++++ kdelibs-4.13.3/kio/kfile/kfiledialog.h        2014-09-20 18:52:54.000000000 +0900
+@@ -749,7 +749,8 @@
+      */
+     static void setStartDir( const KUrl&amp; directory );

+-#ifdef Q_WS_WIN
++#if (defined Q_WS_WIN || defined Q_WS_MAC )
++    /** File dialogs are native by default on Windows and MAC. */
+ public Q_SLOTS:
+     int exec();
+ #endif
</ins></span></pre>
</div>
</div>

</body>
</html>