Ticket #44882: patchset-RJVB-20141009-against-9ed4f721.diff

File patchset-RJVB-20141009-against-9ed4f721.diff, 51.4 KB (added by RJVB (René Bertin), 10 years ago)

full patchset of all my current changes to kdelibs 4.14 git/kde4.14.2 (including the Keychain mods), on the brink of tagging for 4.14.3

  • cmake/modules/KDE4Macros.cmake

    diff --git cmake/modules/KDE4Macros.cmake cmake/modules/KDE4Macros.cmake
    index 073d726..ac58d58 100644
    macro (KDE4_ADD_KDEINIT_EXECUTABLE _target_NAME ) 
    836836      kde4_add_executable(${_target_NAME} "${_nogui}" ${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_dummy.cpp ${_resourcefile})
    837837      target_link_libraries(${_target_NAME} kdeinit_${_target_NAME})
    838838   endif(WIN32)
     839   if(_nogui)
     840      set_target_properties(kdeinit_${_target_NAME} PROPERTIES COMPILE_FLAGS -DKDE_WITHOUT_GUI)
     841      message(STATUS "Building \"kdeinit_${_target_NAME}\" with -DKDE_WITHOUT_GUI because \"${_nogui}\"")
     842   endif(_nogui)
    839843
    840844endmacro (KDE4_ADD_KDEINIT_EXECUTABLE)
    841845
    macro (KDE4_ADD_EXECUTABLE _target_NAME) 
    10101014      add_executable(${_target_NAME} ${_add_executable_param} ${_SRCS})
    10111015   endif (KDE4_ENABLE_FINAL)
    10121016
     1017    if(_nogui)
     1018        set_target_properties(${_target_NAME} PROPERTIES COMPILE_FLAGS -DKDE_WITHOUT_GUI)
     1019        message(STATUS "Building \"${_target_NAME}\" with -DKDE_WITHOUT_GUI because \"${_nogui}\"")
     1020    endif(_nogui)
     1021
    10131022   IF (KDE4_ENABLE_UAC_MANIFEST)
    10141023       _kde4_add_manifest(${_target_NAME})
    10151024   ENDIF(KDE4_ENABLE_UAC_MANIFEST)
  • kdeui/actions/kaction.cpp

    diff --git kdeui/actions/kaction.cpp kdeui/actions/kaction.cpp
    index 9e8f7fb..54088d2 100644
    KAction::KAction(QObject *parent) 
    140140  : QWidgetAction(parent), d(new KActionPrivate)
    141141{
    142142  d->init(this);
     143  setMenuRole(QAction::NoRole);
    143144}
    144145
    145146KAction::KAction(const QString &text, QObject *parent)
    KAction::KAction(const QString &text, QObject *parent) 
    147148{
    148149  d->init(this);
    149150  setText(text);
     151  setMenuRole(QAction::NoRole);
    150152}
    151153
    152154KAction::KAction(const KIcon &icon, const QString &text, QObject *parent)
    KAction::KAction(const KIcon &icon, const QString &text, QObject *parent) 
    155157  d->init(this);
    156158  setIcon(icon);
    157159  setText(text);
     160  setMenuRole(QAction::NoRole);
    158161}
    159162
    160163KAction::~KAction()
  • kdeui/kernel/kapplication.cpp

    diff --git kdeui/kernel/kapplication.cpp kdeui/kernel/kapplication.cpp
    index b093034..ec1455f 100644
    static int kde_x_errhandler( Display *dpy, XErrorEvent *err ) 
    138138void KApplication_init_windows();
    139139#endif
    140140
     141#ifdef KDE_WITHOUT_GUI
     142#define GUIENABLED false
     143#else
     144#define GUIENABLED true
     145#endif //KDE_WITHOUT_GUI
     146
    141147/*
    142148  Private data to make keeping binary compatibility easier
    143149 */
    public: 
    205211  void _k_slot_KToolInvocation_hook(QStringList&, QByteArray&);
    206212
    207213  QString sessionConfigName() const;
    208   void init(bool GUIenabled=true);
     214  void init(bool GUIenabled=GUIENABLED);
    209215  void parseCommandLine( ); // Handle KDE arguments (Using KCmdLineArgs)
     216#ifdef Q_OS_MAC
     217  static void preqapplicationhack(bool GUIenabled = GUIENABLED);
     218#else
    210219  static void preqapplicationhack();
     220#endif
    211221  static void preread_app_startup_id();
    212222  void read_app_startup_id();
    213223
    static SmcConn mySmcConnection = 0; 
    342352#endif
    343353
    344354KApplication::KApplication(bool GUIenabled)
     355#ifdef Q_OS_MAC
     356    : QApplication((KApplicationPrivate::preqapplicationhack(GUIenabled),KCmdLineArgs::qtArgc()), KCmdLineArgs::qtArgv(), GUIenabled),
     357#else
    345358    : QApplication((KApplicationPrivate::preqapplicationhack(),KCmdLineArgs::qtArgc()), KCmdLineArgs::qtArgv(), GUIenabled),
     359#endif
    346360    d(new KApplicationPrivate(this))
    347361{
    348362    d->read_app_startup_id();
  • kdeui/kernel/kapplication.h

    diff --git kdeui/kernel/kapplication.h kdeui/kernel/kapplication.h
    index fa2ab26..ff17f26 100644
    public: 
    9797   *  <li>Call KGlobal::locale(), if using multiple threads.</li>
    9898   * </ul>
    9999   */
     100#ifdef KDE_WITHOUT_GUI
     101  explicit KApplication(bool GUIenabled = false);
     102#else
    100103  explicit KApplication(bool GUIenabled = true);
     104#endif // KDE_WITHOUT_GUI
    101105
    102106#ifdef Q_WS_X11
    103107  /**
    public: 
    134138   *
    135139   * @param GUIenabled Set to false to disable all GUI stuff.
    136140   */
     141#ifdef KDE_WITHOUT_GUI
     142  KApplication(Display *display, int& argc, char** argv, const QByteArray& rAppName,
     143               bool GUIenabled=false);
     144#else
    137145  KApplication(Display *display, int& argc, char** argv, const QByteArray& rAppName,
    138146               bool GUIenabled=true);
     147#endif // KDE_WITHOUT_GUI
    139148#endif
    140149
    141150  virtual ~KApplication();
  • kdeui/kernel/kuniqueapplication.h

    diff --git kdeui/kernel/kuniqueapplication.h kdeui/kernel/kuniqueapplication.h
    index e05dcd7..97fd942 100644
    public: 
    6565   *                 depend on the value of the "MultipleInstances"
    6666   *                 key in the "KDE" group of the application config file.
    6767   */
     68#ifdef KDE_WITHOUT_GUI
     69  explicit KUniqueApplication( bool GUIenabled=false,
     70                               bool configUnique=false);
     71#else
    6872  explicit KUniqueApplication( bool GUIenabled=true,
    6973                               bool configUnique=false);
     74#endif //KDE_WITHOUT_GUI
    7075
    7176#ifdef Q_WS_X11
    7277  /**
  • kdeui/notifications/kstatusnotifieritem.cpp

    diff --git kdeui/notifications/kstatusnotifieritem.cpp kdeui/notifications/kstatusnotifieritem.cpp
    index 1b15d40..1ed7de3 100644
    bool KStatusNotifierItemPrivate::checkVisibility(QPoint pos, bool perform) 
    683683
    684684        return false;
    685685    }
     686#else
     687    Q_UNUSED(pos);
     688    Q_UNUSED(perform);
    686689#endif
    687690
    688691    return true;
    void KStatusNotifierItemPrivate::init(const QString &extraId) 
    745748
    746749    //create a default menu, just like in KSystemtrayIcon
    747750    KMenu *m = new KMenu(associatedWidget);
     751#ifdef Q_OS_MAC
     752    // emulate addTitle/setTitle by adding an inactive menu item.
     753    titleAction = m->addAction( qApp->windowIcon(), KGlobal::mainComponent().aboutData()->programName() );
     754    titleAction->setEnabled(false);
     755    titleAction->setIconVisibleInMenu(true);
     756    m->addAction( titleAction );
     757    m->addSeparator();
     758    kDebug() << "### Added SystemTray titleAction=" << titleAction;
     759    kDebug() << "### SystemTray for app" << qApp << "=" << KGlobal::mainComponent().aboutData()->programName()
     760        << "/" << KGlobal::caption() << "with icon" << qApp->windowIcon().name();
     761#else
    748762    titleAction = m->addTitle(qApp->windowIcon(), KGlobal::caption());
    749763    m->setTitle(KGlobal::mainComponent().aboutData()->programName());
     764#endif
    750765    q->setContextMenu(m);
    751766
    752767    KStandardAction::quit(q, SLOT(maybeQuit()), actionCollection);
  • kdeui/util/kwallet.h

    diff --git kdeui/util/kwallet.h kdeui/util/kwallet.h
    index d7f703f..895868a 100644
    class KDEUI_EXPORT Wallet : public QObject 
    481481                 *  @param success True if the wallet was opened successfully.
    482482                 */
    483483                void walletOpened(bool success);
    484 
    485484        private Q_SLOTS:
    486485                /**
    487486                 *  @internal
  • kdeui/util/kwallet_mac.cpp

    diff --git kdeui/util/kwallet_mac.cpp kdeui/util/kwallet_mac.cpp
    index 8344ebb..3d9c5a8 100644
     
    2727#include <kdeversion.h>
    2828#include <QtGui/QApplication>
    2929#include <QtCore/QPointer>
     30#include <QtCore/QSharedMemory>
    3031#include <QtGui/QWidget>
     32#include <QtCore/QTimer>
    3133#include <ktoolinvocation.h>
    3234
    3335#include <kglobal.h>
     
    3941
    4042#include <sys/param.h>
    4143
     44#define IDLETIMER_DEBUG
     45#undef USE_KWALLETD
     46
    4247#include "qosxkeychain.h"
    4348
    44 using namespace KWallet;
     49#ifdef USE_KWALLETD
     50#   include "kwallet_interface.h"
     51#endif
     52
     53#include "kwallet_mac.h"
    4554
    4655typedef QMap<QString, QString> StringStringMap;
    4756Q_DECLARE_METATYPE(StringStringMap)
    Q_DECLARE_METATYPE(StringToStringStringMapMap) 
    5059typedef QMap<QString, QByteArray> StringByteArrayMap;
    5160Q_DECLARE_METATYPE(StringByteArrayMap)
    5261
    53 #ifdef OSX_KEYCHAIN_PORT_DISABLED
     62#include <mach/mach.h>
     63#include <mach/mach_time.h>
     64#include <mach/mach_init.h>
     65#include <sys/sysctl.h>
     66
     67static mach_timebase_info_data_t sTimebaseInfo;
     68static double calibrator= 0, startTime = 0;
     69static QSharedValue<double> sharedStartTime;
     70
     71double HRTime_Time()
     72{
     73    return mach_absolute_time() * calibrator - startTime;
     74}
     75
     76void init_HRTime()
     77{
     78    if( !calibrator ){
     79        mach_timebase_info(&sTimebaseInfo);
     80        /* go from absolute time units to seconds (the timebase is calibrated in nanoseconds): */
     81        calibrator= 1e-9 * sTimebaseInfo.numer / sTimebaseInfo.denom;
     82        QString key = "kwalletWallClockStartTime";
     83        sharedStartTime.attachOrCreate( key, HRTime_Time() );
     84        sharedStartTime.getValue(startTime);
     85        qDebug() << "init_HRTime(): connected to kwalletWallClock at t=" << HRTime_Time();
     86    }
     87}
     88
     89namespace KWallet
     90{
     91
     92#ifdef USE_KWALLETD
     93class KWalletDLauncher
     94{
     95public:
     96    KWalletDLauncher();
     97    ~KWalletDLauncher();
     98    org::kde::KWallet &getInterface();
     99
     100    org::kde::KWallet *m_wallet;
     101    KConfigGroup m_cgroup;
     102};
     103
     104K_GLOBAL_STATIC(KWalletDLauncher, walletLauncher)
     105static const char s_kwalletdServiceName[] = "org.kde.kwalletd";
     106
     107#else
     108
     109/**
     110 * maps wallet name to a map of app name to <wallet,pid> instances
     111 */
     112// deserialising the WalletUsersList from a QDataStream works only for a few WalletInstancePtr types
     113// We could store the Wallet* in a QByteArray, but that would make it impossible to dump the WalletUsersList
     114// to the console for debugging. So we use a QVariant.
     115typedef QVariant WalletInstancePtr;
     116// typedef QList<QPair<WalletInstancePtr,pid_t> > WalletUsersListEntryData;
     117class WalletUsersListEntryData : public QList<QPair<WalletInstancePtr,pid_t> >
     118{
     119public:
     120    static WalletUsersListEntryData create(QPair<WalletInstancePtr,pid_t> &head)
     121    {
     122        WalletUsersListEntryData self;
     123        self.clear();
     124        self.append(head);
     125        return self;
     126    }
     127    static WalletUsersListEntryData create(QPair<WalletInstancePtr,pid_t> head)
     128    {
     129        WalletUsersListEntryData self;
     130        self.clear();
     131        self.append(head);
     132        return self;
     133    }
     134};
     135
     136typedef QMap<QString,WalletUsersListEntryData> WalletUsersListEntry;
     137typedef QMap<QString,WalletUsersListEntry> WalletUsersList;
     138static WalletUsersList walletUsers;
     139
     140#endif //USE_KWALLETD
     141
     142
    54143static QString appid()
    55144{
    56145    KComponentData cData = KGlobal::mainComponent();
    static QString appid() 
    63152    }
    64153    return qApp->applicationName();
    65154}
    66 #endif
    67155
    68156/*static*/ const QString Wallet::LocalWallet()
    69157{
    static QString appid() 
    104192    return "Form Data";
    105193}
    106194
     195#ifndef USE_KWALLETD
     196static QStringList getUsersFromRegistry(QString &name)
     197{   QString app = appid();
     198    QStringList users;
     199    users.clear();
     200    if( walletUsers.contains(name) ){
     201        WalletUsersListEntry entry = walletUsers[name];
     202        for( WalletUsersListEntry::const_iterator it = entry.constBegin() ; it != entry.constEnd() ; ++it ){
     203            if( !it.value().isEmpty() ){
     204                users.append(it.key());
     205            }
     206        }
     207    }
     208    return users;
     209}
     210
     211static void removeFromRegistry( QString app, QString &name, WalletUsersListEntryData &entries )
     212{
     213    for( WalletUsersListEntryData::const_iterator it = entries.constBegin() ; it != entries.constEnd() ; ++it ){
     214        QPair<WalletInstancePtr,pid_t> wdat = *it;
     215        if( walletUsers.contains(name) && walletUsers[name].contains(app) ){
     216            WalletUsersListEntry entry = walletUsers[name];
     217            WalletUsersListEntryData appInstances = entry[app];
     218            if( appInstances.contains(wdat) ){
     219                appInstances.removeAll(wdat);
     220                qDebug() << "removing application instance" << wdat << "from registry";
     221            }
     222            if( appInstances.isEmpty() ){
     223                entry.remove(app);
     224                qDebug() << "removing application" << app << "from registry";
     225            }
     226            else{
     227                entry[app] = appInstances;
     228            }
     229            if( entry[app].isEmpty() ){
     230                walletUsers.remove(name);
     231                qDebug() << "removing wallet" << name << "from registry";
     232            }
     233            else{
     234                walletUsers[name] = entry;
     235            }
     236        }
     237    }
     238}
     239#endif //USE_KWALLETD
     240
    107241#pragma mark ==== Wallet::WalletPrivate ====
    108 class Wallet::WalletPrivate : public OSXKeychain
     242Wallet::WalletPrivate::WalletPrivate(Wallet *wallet, const QString &n, int h)
     243    : OSXKeychain(n, &isNew), q(wallet), handle(h)
     244    , idleTimer(NULL)
     245#ifdef IDLETIMER_DEBUG
     246    , idleTimerTriggered(0)
     247#endif
     248    , lastConfigCheckTime(-1)
    109249{
    110 public:
    111     explicit WalletPrivate(const QString &n)
    112         : OSXKeychain(n)
    113     {
    114         isKDEChain = ( n == LocalWallet() || n == NetworkWallet() || n.contains( "wallet", Qt::CaseInsensitive ) );
     250    isKDEChain = ( n == LocalWallet() || n == NetworkWallet() || n.contains( "wallet", Qt::CaseInsensitive ) );
     251    if( !calibrator ){
     252        init_HRTime();
     253    }
     254    if( isKDEChain ){
     255        if( !lastAccessTime.attachOrCreate( (QString&)n, QSharedMemory::ReadWrite) ){
     256            qDebug() << "Couldn't create shared lastAccessTime member for wallet" << n
     257                << "; idle timeouts will be per-client. Error" << lastAccessTime.errorString();
     258        }
     259        handleIdleTiming(__FUNCTION__);
    115260    }
     261}
     262Wallet::WalletPrivate::~WalletPrivate()
     263{
     264#ifndef USE_KWALLETD
     265    removeFromRegistry();
     266#endif //USE_KWALLETD
     267    deleteIdleTimer();
     268}
    116269
    117     // needed for compilation reasons
    118     void walletServiceUnregistered()
    119     {
     270#ifndef USE_KWALLETD
     271void Wallet::WalletPrivate::addToRegistry()
     272{   QString app = appid();
     273    QPair<WalletInstancePtr,pid_t> wdat = qMakePair(QVariant((qulonglong)q),getpid());
     274    if( !walletUsers.contains(name) ){
     275        // Unknown wallet name, so there ought not be an existing QMap<appName,walletInstanceList>
     276        WalletUsersListEntryData detail;
     277        detail.clear();
     278        detail.append(wdat);
     279        WalletUsersListEntry entry;
     280        entry.clear();
     281        entry[app] = detail;
     282        walletUsers[name] = entry;
    120283    }
    121 };
     284    else{
     285        WalletUsersListEntry entry = walletUsers[name];
     286        WalletUsersListEntryData detail;
     287        if( entry.contains(app) ){
     288            detail = entry[app];
     289        }
     290        else{
     291            detail.clear();
     292        }
     293        detail.append(wdat);
     294        entry[app] = detail;
     295        walletUsers[name] = entry;
     296    }
     297    QByteArray mapData;
     298    QDataStream ds(&mapData, QIODevice::WriteOnly);
     299    ds << walletUsers;
     300    qDebug() << "@@@" << HRTime_Time() << "Added" << wdat << "for app" << app << "to wallet" << name << "in registry of len=" << mapData.length() << walletUsers;
     301}
     302
     303void Wallet::WalletPrivate::removeFromRegistry()
     304{
     305    WalletUsersListEntryData entries = WalletUsersListEntryData::create(qMakePair(QVariant((qulonglong)q),getpid()));
     306    KWallet::removeFromRegistry( appid(), name, entries );
     307}
     308
     309QStringList Wallet::WalletPrivate::getUsersFromRegistry()
     310{
     311    return KWallet::getUsersFromRegistry(name);
     312}
     313#endif //USE_KWALLETD
     314
     315void Wallet::WalletPrivate::close()
     316{
     317//     // close the keychain wallet but only if we get here through the kwalletmanager
     318//     // or TODO if wallets should be closed when the last client disconnects
     319//     // and we are the last client.
     320//     if( appid() == "KDE Wallet Manager" ){
     321        deleteIdleTimer();
     322        OSXKeychain::close();
     323//     }
     324}
     325
     326OSStatus Wallet::WalletPrivate::lock()
     327{
     328    if( idleTimer ){
     329        idleTimer->stop();
     330    }
     331    return Lock(reference());
     332}
     333
     334void Wallet::WalletPrivate::walletServiceUnregistered()
     335{
     336#ifdef USE_KWALLETD
     337    if( handle >= 0 ){
     338        q->slotWalletClosed(handle);
     339    }
     340#endif
     341}
     342
     343void Wallet::WalletPrivate::deleteIdleTimer()
     344{
     345    if( idleTimer ){
     346        idleTimer->stop();
     347        idleTimer->deleteLater();
     348        idleTimer = NULL;
     349    }
     350}
     351
     352// This function is to be called at every operation that is supposed to launch or reset
     353// the idle timing.
     354void Wallet::WalletPrivate::handleIdleTiming(const char *caller, bool touchAccessTime)
     355{
     356    if( !isKDEChain ){
     357        return;
     358    }
     359    double now = HRTime_Time();
     360    if( lastConfigCheckTime < 0 || (now - lastConfigCheckTime >= 10) ){
     361        lastConfigCheckTime = now;
     362        KConfigGroup cfg(KSharedConfig::openConfig("kwalletrc")->group("Wallet"));
     363        if (cfg.readEntry("Close When Idle", true)) {
     364            timeOut = cfg.readEntry( "Idle Timeout", ((int)0) );
     365            if( caller && idleTimer ){
     366                qDebug() << "###" << caller << "->handleIdleTiming: setting" << idleTimer << "for wallet" << name << "handle" << handle << "timeout to" << timeOut;
     367            }
     368        }
     369        else{
     370            timeOut = -1;
     371        }
     372    }
     373    if( timeOut >= 0 ){
     374        if( !idleTimer ){
     375            idleTimer = new QTimer(0);
     376            connect( idleTimer, SIGNAL(timeout()), this, SLOT(slotIdleTimedOut()), Qt::DirectConnection );
     377        }
     378        else{
     379            idleTimer->stop();
     380        }
     381        // when the idle timer fires, the wallet is supposed to be closed. There is thus
     382        // no reason to use a repeating timer.
     383        idleTimer->setSingleShot(true);
     384        if( touchAccessTime ){
     385            if( !lastAccessTime.setValue(HRTime_Time()) ){
     386                qDebug() << "Cannot set new lastAccessTime for wallet" << name << "error" << lastAccessTime.errorString();
     387            }
     388        }
     389        idleTimer->start( timeOut * 60 * 1000 );
     390    }
     391    else{
     392        timeOut = -1;
     393        deleteIdleTimer();
     394    }
     395}
     396
     397void Wallet::WalletPrivate::slotIdleTimedOut()
     398{   double lastTime = 0;
     399    // check the last time anyone accessed this wallet:
     400    if( !lastAccessTime.getValue(lastTime) ){
     401        qDebug() << "Cannot get lastAccessTime for wallet" << name << "error" << lastAccessTime.errorString();
     402    }
     403    // the time elapsed since that last access, in minutes:
     404    double elapsed = (HRTime_Time() - lastTime) / 60;
     405#ifdef IDLETIMER_DEBUG
     406    idleTimerTriggered += 1;
     407    qDebug() << "###" << HRTime_Time() << appid() << "Idle timeout" << timeOut << "min. for" << q << name << "handle" << handle
     408        << "; elapsed minutes=" << elapsed << "timer" << idleTimer << "triggered" << idleTimerTriggered << "times";
     409#endif //IDLETIMER_DEBUG
     410    if( elapsed >= timeOut ){
     411        // we have a true timeout, i.e. we didn't access the wallet in timeOut minutes, and no one else did either.
     412        q->slotWalletClosed(handle);
     413    }
     414    else{
     415        // false alarm, reset the timer, but there's no need to count this as an access!
     416        handleIdleTiming(__FUNCTION__, false);
     417    }
     418}
    122419
    123420Wallet::Wallet(int handle, const QString& name)
    124     : QObject(0L), d(new WalletPrivate(name))
     421    : QObject(0L), d(new WalletPrivate(this, name, handle))
    125422{
    126     Q_UNUSED(handle);
     423#ifdef USE_KWALLETD
     424    QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QString::fromLatin1(s_kwalletdServiceName), QDBusConnection::sessionBus(),
     425                                                           QDBusServiceWatcher::WatchForUnregistration, this);
     426    connect(watcher, SIGNAL(serviceUnregistered(QString)),
     427            d, SLOT(walletServiceUnregistered()));
     428
     429    connect(&walletLauncher->getInterface(), SIGNAL(walletClosed(int)), SLOT(slotWalletClosed(int)));
     430    connect(&walletLauncher->getInterface(), SIGNAL(folderListUpdated(QString)), SLOT(slotFolderListUpdated(QString)));
     431    connect(&walletLauncher->getInterface(), SIGNAL(folderUpdated(QString,QString)), SLOT(slotFolderUpdated(QString,QString)));
     432    connect(&walletLauncher->getInterface(), SIGNAL(applicationDisconnected(QString,QString)), SLOT(slotApplicationDisconnected(QString,QString)));
     433#else
     434    d->addToRegistry();
     435#endif // USE_KWALLETD
     436    if( d->handle != handle ){
     437        qDebug() << "Wallet::Wallet(" << name << ") handle changed from" << handle << "to" << d->handle;
     438    }
    127439}
    128440
    129441Wallet::~Wallet()
    Wallet::~Wallet() 
    172484#ifdef OSX_KEYCHAIN_PORT_DISABLED
    173485    return walletLauncher->getInterface().isOpen(name); // default is false
    174486#else
     487#ifdef USE_KWALLETD
     488    walletLauncher->getInterface().isOpen(name);
     489#endif // USE_KWALLETD
    175490    return OSXKeychain::IsOpen(name);
    176491#endif
    177492}
    bool Wallet::isOpen() const 
    181496#ifdef OSX_KEYCHAIN_PORT_DISABLED
    182497    return d->handle != -1;
    183498#else
     499    d->handleIdleTiming(__FUNCTION__);
     500
     501#ifdef USE_KWALLETD
     502    QDBusReply<bool> r = walletLauncher->getInterface().isOpen(d->name);
     503#endif // USE_KWALLETD
    184504    return d->isOpen();
    185505#endif
    186506}
    bool Wallet::isOpen() const 
    193513    return r.isValid() ? r : -1;
    194514#else
    195515    Q_UNUSED(force);
    196     return OSXKeychain::Lock(name);
     516#ifdef USE_KWALLETD
     517    QDBusReply<int> r = walletLauncher->getInterface().close(name, force);
     518#endif // USE_KWALLETD
     519    // emit a signal that we just closed the wallet
     520    Wallet(0, name).slotWalletClosed(0);
     521    return OSXKeychain::IsOpen(name);
    197522#endif
    198523}
    199524
    bool Wallet::isOpen() const 
    213538{
    214539    Q_UNUSED(w);
    215540    Q_UNUSED(ot);
    216     Wallet *wallet = new Wallet(-1, name);
    217     QMetaObject::invokeMethod( wallet, "emitWalletOpened", Qt::QueuedConnection );
    218     OSStatus err = wallet->d->unLock();
    219     kDebug() << "Opened wallet '" << name << "': " << wallet << " error=" << err;
     541    Wallet *wallet = new Wallet((int)w, name);
     542    if( wallet ){
     543#ifdef USE_KWALLETD
     544        // connect the daemon's opened signal to the slot filtering the
     545        // signals we need
     546        connect(&walletLauncher->getInterface(), SIGNAL(walletAsyncOpened(int,int)),
     547                wallet, SLOT(walletAsyncOpened(int,int)));
     548#endif
     549        OSStatus err = wallet->d->unLock();
     550        if( !err && wallet->d->isKDEChain && wallet->d->isNew ){
     551            wallet->d->setLockSettings( false, 0 );
     552        }
     553        kDebug() << "Opened wallet '" << name << "': " << wallet << " error=" << err;
     554#ifdef USE_KWALLETD
     555        wallet->emitWalletOpened();
     556#else
     557        QMetaObject::invokeMethod( wallet, "emitWalletOpened", Qt::QueuedConnection );
     558#endif
     559    }
    220560    return wallet;
    221561}
    222562
    bool Wallet::isOpen() const 
    226566#ifdef OSX_KEYCHAIN_PORT_DISABLED
    227567    return walletLauncher->getInterface().disconnectApplication(wallet, app); // default is false
    228568#else
    229     kWarning() << "Wallet::disconnectApplication unimplemented, '" << app << "' from '" << wallet << "'";
    230     return true;
     569    kWarning() << "Wallet::disconnectApplication unimplemented, '" << app << "' from '" << wallet << "'"
     570#ifdef USE_KWALLETD
     571        << walletLauncher->getInterface().disconnectApplication(wallet, app)
     572#endif // USE_KWALLETD
     573        ;
     574    // app disconnect is done/possible only when the app in question closes its wallet.
     575    return false;
    231576#endif
    232577}
    233578
    bool Wallet::isOpen() const 
    237582#ifdef OSX_KEYCHAIN_PORT_DISABLED
    238583    return walletLauncher->getInterface().users(name); // default is QStringList()
    239584#else
    240     kWarning() << "Wallet::users unimplemented, '" << name << "'";
    241     return QStringList();
     585#ifdef USE_KWALLETD
     586    QStringList ul = walletLauncher->getInterface().users(name);
     587    kWarning() << "Wallet::users unimplemented, '" << name << "'" << ul;
     588    return ul;
     589#else
     590    return KWallet::getUsersFromRegistry((QString&)name);
     591#endif // USE_KWALLETD
    242592#endif
    243593}
    244594
    int Wallet::sync() 
    250600        return -1;
    251601    }
    252602
    253     walletLauncher->getInterface().sync(d->handle, appid());
    254603#endif
     604    d->handleIdleTiming(__FUNCTION__);
     605
     606#ifdef USE_KWALLETD
     607    walletLauncher->getInterface().sync(d->handle, appid());
     608#endif // USE_KWALLETD
    255609    return 0;
    256610}
    257611
    int Wallet::lockWallet() 
    272626    }
    273627#else
    274628    d->currentService.clear();
     629    d->handle = -1;
    275630#endif
    276     return d->lock();
     631    d->lock();
     632    emit walletClosed();
     633    return 1;
    277634}
    278635
    279636
    280637const QString& Wallet::walletName() const
    281638{
     639    d->handleIdleTiming(__FUNCTION__);
    282640    return d->name;
    283641}
    284642
    void Wallet::requestChangePassword(WId w) 
    295653    walletLauncher->getInterface().changePassword(d->name, (qlonglong)w, appid());
    296654#else
    297655    Q_UNUSED(w);
     656    d->handleIdleTiming(__FUNCTION__);
    298657    kWarning() << "Wallet::requestChangePassword unimplemented '" << d->name << "'";
    299658#endif
    300659}
    void Wallet::slotWalletClosed(int handle) 
    310669        emit walletClosed();
    311670    }
    312671#else
    313     Q_UNUSED(handle);
    314     kWarning() << "Wallet::slotWalletClosed unimplemented '" << d->name << "'";
    315     d->currentService.clear();
     672//     kWarning() << "Wallet::slotWalletClosed unimplemented '" << d->name << "'";
     673    if( d->handle == handle ){
     674        d->handle = -1;
     675        d->currentService.clear();
     676        kDebug() << "Wallet::slotWalletClosed '" << d->name << "'";
     677        // TODO remove ourselves from the WalletUsersList here!
     678        d->close();
     679        emit walletClosed();
     680    }
     681    else{
     682        qDebug() << "Wallet::slotWalletClosed '" << d->name << "' ignored because handle" << d->handle << "!=" << handle;
     683    }
    316684#endif
    317685}
    318686
    QStringList Wallet::folderList() 
    327695    QDBusReply<QStringList> r = walletLauncher->getInterface().folderList(d->handle, appid());
    328696    return r;
    329697#else
     698    d->handleIdleTiming(__FUNCTION__);
    330699    return QStringList(d->folderList());
    331700#endif
    332701}
    QStringList Wallet::entryList() 
    342711    QDBusReply<QStringList> r = walletLauncher->getInterface().entryList(d->handle, d->folder, appid());
    343712    return r;
    344713#else
     714    d->handleIdleTiming(__FUNCTION__);
     715
    345716    QStringList r = QStringList();
    346717    d->itemList(r);
    347718    return r;
    bool Wallet::hasFolder(const QString& f) 
    359730    QDBusReply<bool> r = walletLauncher->getInterface().hasFolder(d->handle, f, appid());
    360731    return r; // default is false
    361732#else
     733    d->handleIdleTiming(__FUNCTION__);
    362734    d->folderList();
    363735    return d->serviceList.contains(f);
    364736#endif
    bool Wallet::createFolder(const QString& f) 
    379751
    380752    return true;                                // folder already exists
    381753#else
     754    d->handleIdleTiming(__FUNCTION__);
    382755    return setFolder(f);
    383756#endif
    384757}
    bool Wallet::setFolder(const QString &f) 
    407780
    408781    return rc;
    409782#else
     783    d->handleIdleTiming(__FUNCTION__);
    410784    // act as if we just changed folders even if we have no such things; the property
    411785    // is stored as the ServiceItemAttr (which shows up as the "Where" field in the Keychain Utility).
    412786    if( f.size() == 0 ){
    bool Wallet::removeFolder(const QString& f) 
    434808
    435809    return r;                                   // default is false
    436810#else
     811    d->handleIdleTiming(__FUNCTION__);
    437812    kWarning() << "Wallet::removeFolder unimplemented (returns true) '" << d->name << "'";
    438813    if( d->currentService == f ){
    439814        d->currentService.clear();
    const QString& Wallet::currentFolder() const 
    448823#ifdef OSX_KEYCHAIN_PORT_DISABLED
    449824    return d->folder;
    450825#else
     826    d->handleIdleTiming(__FUNCTION__);
    451827    return d->currentService;
    452828#endif
    453829}
    454830
    455831
    456832int Wallet::readEntry(const QString &key, QByteArray &value)
    457 {   OSStatus err = d->readItem( key, &value, NULL );
     833{   OSStatus err;
     834    d->handleIdleTiming(__FUNCTION__);
     835    err = d->readItem( key, &value, NULL );
    458836    kDebug() << "Wallet::readEntry '" << key << "' from wallet " << d->name << ", error=" << ((err)? -1 : 0);
    459837    return (err)? -1 : 0;
    460838}
    int Wallet::readEntryList(const QString& key, QMap<QString, QByteArray>& value) 
    485863#else
    486864    Q_UNUSED(key);
    487865    Q_UNUSED(value);
     866    d->handleIdleTiming(__FUNCTION__);
    488867    kWarning() << "Wallet::readEntryList unimplemented (returns -1) '" << d->name << "'";
    489868    return -1;
    490869#endif
    int Wallet::renameEntry(const QString& oldName, const QString& newName) 
    507886
    508887    return rc;
    509888#else
     889    d->handleIdleTiming(__FUNCTION__);
    510890    return d->renameItem( oldName, newName );
    511891#endif
    512892}
    int Wallet::renameEntry(const QString& oldName, const QString& newName) 
    514894
    515895int Wallet::readMap(const QString &key, QMap<QString,QString> &value)
    516896{
     897    d->handleIdleTiming(__FUNCTION__);
     898
    517899    QByteArray v;
    518900    const int ret = (d->readItem( key, &v, NULL ))? -1 : 0;
    519901    if( ret != 0 ){
    int Wallet::readMapList(const QString& key, QMap<QString, QMap<QString, QString> 
    560942#else
    561943    Q_UNUSED(key);
    562944    Q_UNUSED(value);
     945    d->handleIdleTiming(__FUNCTION__);
    563946    kWarning() << "Wallet::readMapList unimplemented (returns -1) '" << d->name << "'";
    564947    return -1;
    565948#endif
    int Wallet::readMapList(const QString& key, QMap<QString, QMap<QString, QString> 
    568951
    569952int Wallet::readPassword(const QString& key, QString& value)
    570953{
     954    d->handleIdleTiming(__FUNCTION__);
     955
    571956    QByteArray ba;
    572957    const int ret = (d->readItem( key, &ba, NULL ))? -1 : 0;
    573958    if ( ret == 0 ){
    int Wallet::readPasswordList(const QString& key, QMap<QString, QString>& value) 
    582967{
    583968    Q_UNUSED(key);
    584969    Q_UNUSED(value);
     970    d->handleIdleTiming(__FUNCTION__);
    585971    kWarning() << "Wallet::readPasswordList unimplemented (returns -1) '" << d->name << "'";
    586972    return -1;
    587973}
    588974
    589975int Wallet::writeEntry(const QString& key, const QByteArray& password )
    590 {   int ret = d->writeItem( key, password );
     976{   int ret;
     977    d->handleIdleTiming(__FUNCTION__);
     978    ret = d->writeItem( key, password );
    591979    kDebug() << "wrote entry '" << key << "' to wallet " << d->name << ", error=" << ret;
    592980    return ret;
    593981}
    594982
    595983int Wallet::writeEntry(const QString& key, const QByteArray& password, EntryType entryType)
    596984{
     985    d->handleIdleTiming(__FUNCTION__);
     986
    597987    OSXKeychain::EntryType entryCode;
    598988        switch( entryType ){
    599989                case Wallet::Password:
    int Wallet::writeEntry(const QString& key, const QByteArray& password, EntryType 
    6161006
    6171007int Wallet::writeMap(const QString& key, const QMap<QString,QString>& value)
    6181008{
     1009    d->handleIdleTiming(__FUNCTION__);
     1010
    6191011    QByteArray mapData;
    6201012    QDataStream ds(&mapData, QIODevice::WriteOnly);
    6211013    ds << value;
    int Wallet::writeMap(const QString& key, const QMap<QString,QString>& value) 
    6301022
    6311023
    6321024int Wallet::writePassword(const QString &key, const QString& value)
    633 {   OSXKeychain::EntryType etype = OSXKeychain::Password;
     1025{   OSXKeychain::EntryType etype;
     1026
     1027    d->handleIdleTiming(__FUNCTION__);
     1028    etype = OSXKeychain::Password;
    6341029    int ret = d->writeItem( key, value.toUtf8(), &etype );
    6351030    kDebug() << "wrote password '" << key << "' to wallet " << d->name << ", error=" << ret;
    6361031    return ret;
    int Wallet::writePassword(const QString &key, const QString& value) 
    6381033
    6391034
    6401035bool Wallet::hasEntry(const QString &key)
    641 {   bool ret = d->hasItem( key, NULL );
     1036{   bool ret;
     1037
     1038    d->handleIdleTiming(__FUNCTION__);
     1039    ret = d->hasItem( key, NULL );
    6421040    kDebug() << "wallet '" << d->name << "'" << ((ret)? " has" : " does not have") << " entry '" << key << "'";
    6431041    return ret;
    6441042}
    6451043
    6461044int Wallet::removeEntry(const QString& key)
    647 {   int ret = d->removeItem( key );
     1045{   int ret;
     1046
     1047    d->handleIdleTiming(__FUNCTION__);
     1048    ret = d->removeItem( key );
    6481049    kDebug() << "removed entry '" << key << "' from wallet " << d->name << ", error=" << ret;
    6491050    return ret;
    6501051}
    Wallet::EntryType Wallet::entryType(const QString& key) 
    6661067
    6671068    return static_cast<EntryType>(rc);
    6681069#else
     1070    d->handleIdleTiming(NULL);
     1071
    6691072    // RJVB: a priori, entries are always 'password' on OS X, but since we also do use them for storing
    6701073    // maps, it may be best to return Wallet::Unknown to leave some uncertainty and not mislead our caller.
    6711074    OSXKeychain::EntryType etype;
    Wallet::EntryType Wallet::entryType(const QString& key) 
    6901093void Wallet::slotFolderUpdated(const QString& wallet, const QString& folder)
    6911094{
    6921095    if (d->name == wallet) {
     1096        kDebug() << "emit folderUpdated" << folder;
    6931097        emit folderUpdated(folder);
    6941098    }
    6951099}
    void Wallet::slotFolderUpdated(const QString& wallet, const QString& folder) 
    6981102void Wallet::slotFolderListUpdated(const QString& wallet)
    6991103{
    7001104    if (d->name == wallet) {
     1105        kDebug() << "emit foldeListrUpdated" << wallet;
    7011106        emit folderListUpdated();
    7021107    }
    7031108}
    void Wallet::slotFolderListUpdated(const QString& wallet) 
    7051110
    7061111void Wallet::slotApplicationDisconnected(const QString& wallet, const QString& application)
    7071112{
    708 #ifdef OSX_KEYCHAIN_PORT_DISABLED
    709     if (d->handle >= 0
     1113#ifdef USE_KWALLETD
     1114    qDebug() << "slotApplicationDisconnected(" << wallet << "," << application << "); handle="
     1115        << d->handle << "name=" << d->name << "appid=" << appid();
     1116    if( d->handle >= 0
    7101117        && d->name == wallet
    711         && application == appid()) {
     1118        && application == appid()
     1119    ){
    7121120        slotWalletClosed(d->handle);
    7131121    }
    7141122#else
    7151123    Q_UNUSED(wallet);
    7161124    Q_UNUSED(application);
    717         kWarning() << "Wallet::slotApplicationDisconnected unimplemented '" << d->name << "'";
    718 #endif
     1125#endif //USE_KWALLETD
    7191126}
    7201127
    7211128void Wallet::walletAsyncOpened(int tId, int handle)
    void Wallet::walletAsyncOpened(int tId, int handle) 
    7331140    emit walletOpened(handle > 0);
    7341141#else
    7351142    Q_UNUSED(tId);
    736     Q_UNUSED(handle);
    737         kWarning() << "Wallet::walletAsyncOpened unimplemented '" << d->name << "'";
     1143    d->handleIdleTiming(__FUNCTION__);
     1144#ifdef USE_KWALLETD
     1145    // disconnect the async signal
     1146    disconnect(this, SLOT(walletAsyncOpened(int,int)));
     1147    qDebug() << "walletAsyncOpened: emit walletOpened(true), handle=" << handle;
     1148    emit walletOpened(true);
     1149#endif // USE_KWALLETD
     1150    d->handle = handle;
    7381151#endif
    7391152}
    7401153
    7411154void Wallet::emitWalletAsyncOpenError()
    7421155{
     1156    d->handleIdleTiming(__FUNCTION__);
     1157    kDebug() << "emitWalletAsyncOpenError: emit walletOpened(false)";
    7431158    emit walletOpened(false);
    7441159}
    7451160
    7461161void Wallet::emitWalletOpened()
    7471162{
    748   emit walletOpened(true);
     1163    d->handleIdleTiming(__FUNCTION__);
     1164    kDebug() << "emitWalletOpened: emit walletOpened(true)";
     1165    emit walletOpened(true);
    7491166}
    7501167
    7511168
    752 bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder)
     1169/*static*/ bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder)
    7531170{
    7541171#ifdef OSX_KEYCHAIN_PORT_DISABLED
    7551172    QDBusReply<bool> r = walletLauncher->getInterface().folderDoesNotExist(wallet, folder);
    bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder) 
    7641181}
    7651182
    7661183
    767 bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const QString& key)
     1184/*static*/ bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const QString& key)
    7681185{
    7691186#ifdef OSX_KEYCHAIN_PORT_DISABLED
    7701187    QDBusReply<bool> r = walletLauncher->getInterface().keyDoesNotExist(wallet, folder, key);
    bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const 
    7841201void Wallet::slotCollectionStatusChanged(int status)
    7851202{
    7861203    Q_UNUSED(status);
    787         kWarning() << "Wallet::slotCollectionStatusChanged unimplemented '" << d->name << "' status=" << status;
     1204    d->handleIdleTiming(__FUNCTION__);
     1205    kWarning() << "Wallet::slotCollectionStatusChanged unimplemented '" << d->name << "' status=" << status;
    7881206}
    7891207
    7901208void Wallet::slotCollectionDeleted()
    void Wallet::slotCollectionDeleted() 
    7951213    d->currentService.clear();
    7961214#endif
    7971215    kDebug() << "Wallet::slotCollectionDeleted: closing private data '" << d->name;
     1216    // TODO remove ourselves from the WalletUsersList here!
    7981217    d->close();
    7991218    emit walletClosed();
    8001219}
    void Wallet::virtual_hook(int, void*) 
    8051224    //BASE::virtual_hook( id, data );
    8061225}
    8071226
     1227#ifdef USE_KWALLETD
     1228KWalletDLauncher::KWalletDLauncher()
     1229    : m_wallet(0),
     1230    m_cgroup(KSharedConfig::openConfig("kwalletrc", KConfig::NoGlobals)->group("Wallet"))
     1231{
     1232    m_wallet = new org::kde::KWallet(QString::fromLatin1(s_kwalletdServiceName), "/modules/kwalletd", QDBusConnection::sessionBus());
     1233}
     1234
     1235KWalletDLauncher::~KWalletDLauncher()
     1236{
     1237    delete m_wallet;
     1238}
     1239
     1240org::kde::KWallet &KWalletDLauncher::getInterface()
     1241{
     1242    Q_ASSERT(m_wallet != 0);
     1243
     1244    // check if kwalletd is already running
     1245    if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName)))
     1246    {
     1247        // not running! check if it is enabled.
     1248        bool walletEnabled = m_cgroup.readEntry("Enabled", true);
     1249        if (walletEnabled) {
     1250            // wallet is enabled! try launching it
     1251            QString error;
     1252            int ret = KToolInvocation::startServiceByDesktopPath("kwalletd.desktop", QStringList(), &error);
     1253            if (ret > 0){
     1254                kError(285) << "Couldn't start kwalletd: " << error << endl;
     1255            }
     1256
     1257            if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName))) {
     1258                kDebug(285) << "The kwalletd service is still not registered";
     1259            } else {
     1260                kDebug(285) << "The kwalletd service has been registered";
     1261            }
     1262        } else {
     1263            kError(285) << "The kwalletd service has been disabled";
     1264        }
     1265    }
     1266
     1267    return *m_wallet;
     1268}
     1269#endif //USE_KWALLETD
     1270
     1271} // namespace KWallet
     1272
     1273#include "kwallet_mac.moc"
    8081274#include "kwallet.moc"
  • kdeui/util/qosxkeychain.cpp

    diff --git kdeui/util/qosxkeychain.cpp kdeui/util/qosxkeychain.cpp
    index 7cb9a22..708c728 100644
    OSXKeychain::OSXKeychain() 
    161161    serviceList.append("");
    162162}
    163163
    164 OSXKeychain::OSXKeychain(const QString &n)
     164OSXKeychain::OSXKeychain(const QString &n, bool *isNew)
    165165    : name(n)
    166166{   QString errMsg;
    167167    OSStatus err = openKeychain( n, &keyChainRef );
    OSXKeychain::OSXKeychain(const QString &n) 
    170170        kWarning() << "Keychain '" << n << "' does not exist: attempting to create it";
    171171        err = SecKeychainCreate( n.toUtf8(), 0, NULL, true, NULL, &keyChainRef );
    172172        isKDEChain = true;
     173        if( !err && isNew ){
     174            *isNew = true;
     175        }
     176    }
     177    else if( !err && isNew ){
     178        *isNew = false;
    173179    }
    174180
    175181    if( isError( err, &errMsg ) ){
    OSXKeychain::OSXKeychain(const QString &n) 
    197203void OSXKeychain::close()
    198204{
    199205    if( keyChainRef ){
     206        Lock(keyChainRef);
    200207        CFRelease(keyChainRef);
    201208        keyChainRef = NULL;
     209        serviceList.clear();
    202210    }
    203211}
    204212
    205213OSXKeychain::~OSXKeychain()
    206214{
    207     close();
     215    if( keyChainRef ){
     216        CFRelease(keyChainRef);
     217        keyChainRef = NULL;
     218    }
     219    serviceList.clear();
     220}
     221
     222OSStatus OSXKeychain::lockSettings(int &closeWhenIdle, unsigned int &idleTimeoutMin)
     223{   QString errMsg;
     224    SecKeychainSettings kcSettings= { SEC_KEYCHAIN_SETTINGS_VERS1, 0, 0, INT_MAX };
     225    OSStatus err = SecKeychainCopySettings( keyChainRef, &kcSettings );
     226    if( isError( err, &errMsg ) ){
     227        kWarning() << "Error getting settings for" << name << err << "=" << qPrintable(errMsg);
     228    }
     229    else{
     230        closeWhenIdle = kcSettings.useLockInterval;
     231        idleTimeoutMin = (int)(kcSettings.lockInterval / 60 + 0.5);
     232    }
     233    return err;
     234}
     235
     236OSStatus OSXKeychain::setLockSettings(int closeWhenIdle, unsigned int idleTimeoutMin)
     237{   QString errMsg;
     238    SecKeychainSettings kcSettings = { SEC_KEYCHAIN_SETTINGS_VERS1, 0, 0, INT_MAX };
     239    OSStatus err;
     240
     241    // to switch (or keep) off idle timeout locking set useLockInterval=false and lockInterval=INT_MAX
     242    // if lockInterval has any other value, SecKeychainSetSettings() will force useLockInterval=true
     243    if( closeWhenIdle ){
     244        kcSettings.useLockInterval = 1;
     245        kcSettings.lockInterval = idleTimeoutMin * 60;
     246    }
     247    err = SecKeychainSetSettings( keyChainRef, &kcSettings );
     248//     if( !err ){
     249//         SecKeychainSettings ks = { SEC_KEYCHAIN_SETTINGS_VERS1, 0, 0, INT_MAX };
     250//         ks.useLockInterval = !closeWhenIdle;
     251//         SecKeychainCopySettings( keyChainRef, &ks );
     252//         qDebug() << "Keychain settings set to useLockInterval=" << ks.useLockInterval << "lockInterval=" << ks.lockInterval;
     253//     }
     254//     else{
     255//         qDebug() << "Error setting keychain settings:" << err;
     256//     }
     257    return err;
    208258}
    209259
    210260OSStatus OSXKeychain::renameItem(const QString &currentKey, const QString &newKey)
    OSStatus OSXKeychain::Lock(const QString &walletName) 
    330380    OSStatus err = openKeychain( walletName, &keychain );
    331381    if( !err && keychain ){
    332382        err = Lock(keychain);
    333            CFRelease(keychain);
     383        CFRelease(keychain);
    334384    }
    335385    return err;
    336386}
    bool OSXKeychain::HasItem(const QString &key, 
    377427                *errReturn = err;
    378428            }
    379429    }
    380     kDebug() << ((found)? "Found" : "Did not find") << "item '" << key << "' in keychain " << (void*) keychain << ", error=" << err << " " << qPrintable(errMsg);
     430    kDebug() << "item '" << key << ((found)? "found" : "not found") << "' in keychain " << (void*) keychain << ", error=" << err << " " << qPrintable(errMsg);
    381431    return found;
    382432}
    383433
  • kdeui/util/qosxkeychain.h

    diff --git kdeui/util/qosxkeychain.h kdeui/util/qosxkeychain.h
    index d0934e6..7370418 100644
     
    1818 * Boston, MA 02110-1301, USA.
    1919 */
    2020
     21#ifndef _QOSXKEYCHAIN_H
     22
    2123#include <Security/Security.h>
    2224#include <Security/SecKeychain.h>
    2325
    namespace { 
    5961}
    6062
    6163static inline QString asQString( CFStringRef sr )
    62 {   CFIndex len = CFStringGetLength(sr)*2;
    63     const CPPArrayDeleter<char*> buff(new char[len]);
    64     if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingUTF8 ) ){
    65         return QString::fromUtf8(buff.ptr); //RJVB: use UTF8
    66     }
    67     else if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingNonLossyASCII ) ){
    68         return QString::fromLocal8Bit(buff.ptr);
     64{
     65    if( sr ){
     66        CFIndex len = CFStringGetLength(sr)*2;
     67        const CPPArrayDeleter<char*> buff(new char[len]);
     68        if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingUTF8 ) ){
     69            return QString::fromUtf8(buff.ptr); //RJVB: use UTF8
     70        }
     71        else if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingNonLossyASCII ) ){
     72            return QString::fromLocal8Bit(buff.ptr);
     73        }
     74        else{
     75            CFStringGetCString( sr, buff.ptr, len, NULL );
     76            return QString::fromLatin1(buff.ptr);
     77        }
    6978    }
    7079    else{
    71         CFStringGetCString( sr, buff.ptr, len, NULL );
    72         return QString::fromLatin1(buff.ptr);
     80        return QString();
    7381    }
    7482}
    7583
    static inline bool isError( OSStatus s, QString *errMsg ) 
    8795    return s != 0;
    8896}
    8997
    90 class OSXKeychain
     98class OSXKeychain //: protected QObject
    9199{
     100//    Q_OBJECT
    92101private:
    93102    SecKeychainRef keyChainRef;
    94103    QString keyChainPath;
    public: 
    102111    bool isKDEChain;
    103112
    104113    OSXKeychain();
    105     OSXKeychain(const QString &name);
     114    OSXKeychain(const QString &name, bool *isNew=NULL);
    106115    virtual ~OSXKeychain();
    107116
    108117    inline SecKeychainRef reference()
    public: 
    119128    }
    120129    inline bool isOpen()
    121130    {
    122         return IsOpen(keyChainRef);
     131        // we're either a KDE wallet/keychain and we have a valid keyChainRef,
     132        // or we're not KDE and IsOpen will return the state of the default
     133        // keychain if keyChainRef==NULL.
     134        if( !isKDEChain || keyChainRef ){
     135            return IsOpen(keyChainRef);
     136        }
     137        else{
     138            return false;
     139        }
    123140    }
    124141    inline OSStatus lock()
    125142    {
    126         return Lock(keyChainRef);
     143        if( !isKDEChain || keyChainRef ){
     144            return Lock(keyChainRef);
     145        }
     146        else{
     147            return 0;
     148        }
    127149    }
    128150    inline OSStatus unLock()
    129151    {
    130         return UnLock(keyChainRef);
     152        if( !isKDEChain || keyChainRef ){
     153            return UnLock(keyChainRef);
     154        }
     155        else{
     156            return 0;
     157        }
    131158    }
    132     void close();
     159    virtual void close();
     160    OSStatus lockSettings(int &closeWhenIdle, unsigned int &idleTimeoutMin);
     161    OSStatus setLockSettings(int closeWhenIdle, unsigned int idleTimeoutMin);
    133162    inline bool hasItem(const QString &key, OSStatus *errReturn, SecKeychainItemRef *itemRef=NULL)
    134163    {
    135             // qDebug() << "OSXKeychain::hasItem(" << key << "): scanning '" << name << "'=" << (void*) keyChainRef;
    136             return OSXKeychain::HasItem( key, keyChainRef, errReturn, itemRef );
     164        if( !isKDEChain || keyChainRef ){
     165            return OSXKeychain::HasItem( key, keyChainRef, errReturn, itemRef );
     166        }
     167        else{
     168            return false;
     169        }
    137170    }
    138171    inline OSStatus readItem(const QString &key, QByteArray *value, SecKeychainItemRef *itemRef=NULL)
    139172    {
    140         return ReadItem( key, value, keyChainRef, itemRef, this );
     173        if( !isKDEChain || keyChainRef ){
     174            return ReadItem( key, value, keyChainRef, itemRef, this );
     175        }
     176        else{
     177            return 0;
     178        }
    141179    }
    142180    inline OSStatus itemType(const QString &key, EntryType *entryType)
    143181    {
    144         return ItemType( key, entryType, keyChainRef );
     182        if( !isKDEChain || keyChainRef ){
     183            return ItemType( key, entryType, keyChainRef );
     184        }
     185        else{
     186            return 0;
     187        }
    145188    }
    146189    inline OSStatus removeItem(const QString &key)
    147190    {
    148         return RemoveItem( key, keyChainRef );
     191        if( !isKDEChain || keyChainRef ){
     192            return RemoveItem( key, keyChainRef );
     193        }
     194        else{
     195            return 0;
     196        }
    149197    }
    150198    inline OSStatus writeItem( const QString &key, const QByteArray &value, EntryType *entryType=NULL )
    151199    {
    152         return WriteItem( key, value, keyChainRef, NULL, entryType, this );
     200        if( !isKDEChain || keyChainRef ){
     201            return WriteItem( key, value, keyChainRef, NULL, entryType, this );
     202        }
     203        else{
     204            return 0;
     205        }
    153206    }
    154207    inline OSStatus writeItem( const QString &key, const QByteArray &value, const QString &comment,
    155208                               EntryType *entryType=NULL )
    156209    {
    157         return WriteItem( key, value, comment, keyChainRef, entryType, this );
     210        if( !isKDEChain || keyChainRef ){
     211            return WriteItem( key, value, comment, keyChainRef, entryType, this );
     212        }
     213        else{
     214            return 0;
     215        }
    158216    }
    159217    inline OSStatus itemList( QStringList &keyList )
    160218    {
    161         return ItemList( keyChainRef, keyList, this );
     219        if( !isKDEChain || keyChainRef ){
     220            return ItemList( keyChainRef, keyList, this );
     221        }
     222        else{
     223            return 0;
     224        }
    162225    }
    163226    inline QStringList folderList()
    164227    {
    165         QStringList r;
    166         CacheOldValue<bool> gFL(generateFolderList, true);
    167         ItemList( keyChainRef, r, this );
    168         r.clear();
    169         return serviceList;
     228        if( !isKDEChain || keyChainRef ){
     229            QStringList r;
     230            CacheOldValue<bool> gFL(generateFolderList, true);
     231            ItemList( keyChainRef, r, this );
     232            r.clear();
     233            return serviceList;
     234        }
     235        else{
     236            return QStringList();
     237        }
    170238    }
    171239    OSStatus renameItem(const QString &currentKey, const QString &newKey);
    172240
    public: 
    197265    static OSStatus ItemList( const SecKeychainRef keychain, QStringList &keyList, OSXKeychain *osxKeyChain=NULL );
    198266    static OSStatus Destroy( SecKeychainRef *keychain );
    199267    static OSStatus Destroy( const QString &walletName );
     268
     269// private Q_SLOTS:
     270//     virtual void slotIdleTimedOut()
     271//     {}
    200272};
     273
     274#define _QOSXKEYCHAIN_H
     275#endif
     276 No newline at end of file
  • kdeui/widgets/kmenu.cpp

    diff --git kdeui/widgets/kmenu.cpp kdeui/widgets/kmenu.cpp
    index 7dab149..9b64236 100644
     
    4242#include <klocale.h>
    4343#include <kacceleratormanager.h>
    4444
     45#ifdef Q_OS_MAC
     46#include <kmainwindow.h>
     47#include <kmenubar.h>
     48#endif //Q_OS_MAC
     49
    4550static const char KMENU_TITLE[] = "kmenu_title";
    4651
    4752class KMenu::KMenuPrivate
    QAction* KMenu::addTitle(const QString &text, QAction* before) 
    172177    return addTitle(QIcon(), text, before);
    173178}
    174179
     180#ifdef Q_OS_MAC
     181static bool isMenubarMenu(QMenu *m)
     182{   bool ret = false;
     183        static int level = -1;
     184    QList<QMenu*> checkList;
     185    level += 1;
     186    if (m && m->menuAction()) {
     187        QAction *mAct = m->menuAction();
     188        qDebug() << "##" << level << "isMenubarMenu(" << m << m->title() << ") menuAction=" << mAct << mAct->text();
     189        foreach (QWidget *w, mAct->associatedWidgets()) {
     190            if (w == m) {
     191                goto done;
     192            }
     193            qDebug() << "###" << level << "associated widget" << w << w->windowTitle() << "parent=" << w->parentWidget();
     194            if (QMenuBar *mb = qobject_cast<QMenuBar*>(w)) {
     195                qDebug() << "#### widget is QMenuBar" << mb << mb->windowTitle() << "with parent" << mb->parentWidget();
     196                ret = true;
     197                goto done;
     198            }
     199            else if (QMenu *mm = qobject_cast<QMenu*>(w)) {
     200                if (checkList.contains(mm)) {
     201                    continue;
     202                }
     203                checkList.append(mm);
     204                qDebug() << "####" << level << "widget is QMenu" << mm << mm->title() << "with parent" << mm->parentWidget();
     205                if (isMenubarMenu(mm)) {
     206                    ret = true;
     207                    goto done;
     208                }
     209            }
     210        }
     211    }
     212done:;
     213    level -= 1;
     214    return ret;
     215}
     216#endif
     217
    175218QAction* KMenu::addTitle(const QIcon &icon, const QString &text, QAction* before)
    176219{
    177     QAction *buttonAction = new QAction(this);
    178     QFont font = buttonAction->font();
    179     font.setBold(true);
    180     buttonAction->setFont(font);
    181     buttonAction->setText(text);
    182     buttonAction->setIcon(icon);
    183 
    184     QWidgetAction *action = new QWidgetAction(this);
    185     action->setObjectName(KMENU_TITLE);
    186     QToolButton *titleButton = new QToolButton(this);
    187     titleButton->installEventFilter(d); // prevent clicks on the title of the menu
    188     titleButton->setDefaultAction(buttonAction);
    189     titleButton->setDown(true); // prevent hover style changes in some styles
    190     titleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
    191     action->setDefaultWidget(titleButton);
    192 
    193     insertAction(before, action);
     220#ifdef Q_OS_MAC
     221    bool isMacMenuBar = isMenubarMenu(this);
     222#else
     223    bool isMacMenuBar = false;
     224#endif // Q_OS_MAC
     225    QAction *action = new QAction(this);
     226    action->setText(text);
     227    action->setIcon(icon);
     228#ifdef Q_OS_MAC
     229    if (isMacMenuBar) {
     230        action->setEnabled(false);
     231        if (before && actions().contains(before)) {
     232            QAction *sepLow = new QAction(this);
     233            sepLow->setSeparator(true);
     234            insertAction(before, sepLow);
     235            insertAction(sepLow, action);
     236            if (!actions().startsWith(action)) {
     237                QAction *sepHigh = new QAction(this);
     238                sepHigh->setSeparator(true);
     239                insertAction(action,sepHigh);
     240                qDebug() << "#### inserted high separator before" << action << action->text() << "before low separator before" << before;
     241            }
     242            else{
     243                qDebug() << "#### inserted" << action << action->text() << "before low separator before" << before;
     244            }
     245        }
     246        else{
     247            if (actions().size()) {
     248                addSeparator();
     249            }
     250            addAction(action);
     251            addSeparator();
     252            qDebug() << "#### appended low separator after" << action << action->text() << "after existing" << actions().size()-2 << "items (before=" << before;
     253        }
     254    }
     255    else
     256#endif // Q_OS_MAC
     257    {
     258        QFont font = action->font();
     259        font.setBold(true);
     260        action->setFont(font);
     261
     262        QWidgetAction *styledAction = new QWidgetAction(this);
     263        styledAction->setObjectName(KMENU_TITLE);
     264        QToolButton *titleButton = new QToolButton(this);
     265        titleButton->installEventFilter(d); // prevent clicks on the title of the menu
     266        titleButton->setDefaultAction(action);
     267        titleButton->setDown(true); // prevent hover style changes in some styles
     268        titleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
     269        styledAction->setDefaultWidget(titleButton);
     270
     271        insertAction(before, styledAction );
     272        action = styledAction;
     273    }
    194274    return action;
    195275}
    196276