1 | /* qeventloopinteractor.cpp |
2 | Copyright (C) 2003, 2007 Klarälvdalens Datakonsult AB |
3 | |
4 | This file is part of QGPGME. |
5 | |
6 | QGPGME is free software; you can redistribute it and/or modify it |
7 | under the terms of the GNU Library General Public License as published |
8 | by the Free Software Foundation; either version 2 of the License, or |
9 | (at your option) any later version. |
10 | |
11 | QGPGME is distributed in the hope that it will be useful, but |
12 | WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU Library General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Library General Public License |
17 | along with QGPGME; see the file COPYING.LIB. If not, write to the |
18 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. */ |
20 | |
21 | // -*- c++ -*- |
22 | |
23 | #include <qgpgme/eventloopinteractor.h> |
24 | #include <gpgme++/context.h> |
25 | |
26 | #include <QCoreApplication> |
27 | #include <QSocketNotifier> |
28 | #include <QPointer> |
29 | |
30 | using namespace GpgME; |
31 | |
32 | QGpgME::EventLoopInteractor::EventLoopInteractor( QObject * parent ) |
33 | : QObject( parent ), GpgME::EventLoopInteractor() |
34 | { |
35 | setObjectName( QLatin1String( "QGpgME::EventLoopInteractor::instance()" ) ); |
36 | if ( !parent ) { |
37 | if ( QCoreApplication * const app = QCoreApplication::instance() ) { |
38 | connect( app, SIGNAL(aboutToQuit()), SLOT(deleteLater()) ); |
39 | connect( app, SIGNAL(aboutToQuit()), SIGNAL(aboutToDestroy()) ); |
40 | } |
41 | } |
42 | mSelf = this; |
43 | } |
44 | |
45 | QGpgME::EventLoopInteractor::~EventLoopInteractor() { |
46 | emit aboutToDestroy(); |
47 | mSelf = 0; |
48 | } |
49 | |
50 | QGpgME::EventLoopInteractor * QGpgME::EventLoopInteractor::mSelf = 0; |
51 | |
52 | QGpgME::EventLoopInteractor * QGpgME::EventLoopInteractor::instance() { |
53 | if ( !mSelf ) { |
54 | #ifndef NDEBUG |
55 | if ( !QCoreApplication::instance() ) { |
56 | qWarning( "QGpgME::EventLoopInteractor: Need a Q(Core)Application object before calling instance()!" ); |
57 | } else { |
58 | #endif |
59 | (void)new EventLoopInteractor; |
60 | #ifndef NDEBUG |
61 | } |
62 | #endif |
63 | } |
64 | return mSelf; |
65 | } |
66 | |
67 | namespace { |
68 | |
69 | template <typename T_Enableable> |
70 | class QDisabler { |
71 | const QPointer<T_Enableable> o; |
72 | const bool wasEnabled; |
73 | public: |
74 | explicit QDisabler( T_Enableable * t ) : o( t ), wasEnabled( o && o->isEnabled() ) |
75 | { |
76 | if ( t ) { |
77 | t->setEnabled( false ); |
78 | } |
79 | } |
80 | ~QDisabler() |
81 | { |
82 | if ( o ) { |
83 | o->setEnabled( wasEnabled ); |
84 | } |
85 | } |
86 | }; |
87 | } |
88 | |
89 | void QGpgME::EventLoopInteractor::slotWriteActivity( int socket ) { |
90 | // Make sure to disable the notifier while we are processing the event, as |
91 | // it's easy to run into re-entrancy issues, if actOn causes things to return |
92 | // to the event loop in some way (such as showing the passphrase dialog). |
93 | // We use a qpointer as actOn will destroy the notifier, when it's done with the FD |
94 | const QDisabler<QSocketNotifier> disabled( qobject_cast<QSocketNotifier*>( sender() ) ); |
95 | actOn( socket , Write ); |
96 | } |
97 | |
98 | void QGpgME::EventLoopInteractor::slotReadActivity( int socket ) { |
99 | const QDisabler<QSocketNotifier> disabled( qobject_cast<QSocketNotifier*>( sender() ) ); |
100 | actOn( socket , Read ); |
101 | } |
102 | |
103 | void QGpgME::EventLoopInteractor::nextTrustItemEvent( GpgME::Context * context, const GpgME::TrustItem & item ) { |
104 | emit nextTrustItemEventSignal( context, item ); |
105 | } |
106 | |
107 | void QGpgME::EventLoopInteractor::nextKeyEvent( GpgME::Context * context, const GpgME::Key & key ) { |
108 | emit nextKeyEventSignal( context, key ); |
109 | } |
110 | |
111 | void QGpgME::EventLoopInteractor::operationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { |
112 | emit operationDoneEventSignal( context, e ); |
113 | } |
114 | |
115 | void QGpgME::EventLoopInteractor::operationStartEvent( GpgME::Context * context ) { |
116 | emit operationStartEventSignal( context ); |
117 | } |
118 | |
119 | |