Make it possible to use a distinct selection model in the foldertreewidget.
[kdepim.git] / kleopatra / main.cpp
blobb76a185eb45577b0e4ecb3dcf0193c4992837187
1 /*
2 main.cpp
4 This file is part of Kleopatra, the KDE keymanager
5 Copyright (c) 2001,2002,2004,2008 Klar�vdalens Datakonsult AB
7 Kleopatra is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 Kleopatra is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 In addition, as a special exception, the copyright holders give
22 permission to link the code of this program with any edition of
23 the Qt library by Trolltech AS, Norway (or with modified versions
24 of Qt that use the same license as Qt), and distribute linked
25 combinations including the two. You must obey the GNU General
26 Public License in all respects for all of the code used other than
27 Qt. If you modify this file, you may extend this exception to
28 your version of the file, but you are not obligated to do so. If
29 you do not wish to do so, delete this exception statement from
30 your version.
33 #include <config-kleopatra.h>
35 #include "aboutdata.h"
36 #include "kleopatraapplication.h"
37 #include "mainwindow.h"
39 #include <commands/reloadkeyscommand.h>
40 #include <commands/selftestcommand.h>
42 #include <utils/gnupg-helper.h>
44 #ifdef HAVE_USABLE_ASSUAN
45 # include <uiserver/uiserver.h>
46 # include <uiserver/assuancommand.h>
47 # include <uiserver/echocommand.h>
48 # include <uiserver/decryptcommand.h>
49 # include <uiserver/verifycommand.h>
50 # include <uiserver/decryptverifyfilescommand.h>
51 # include <uiserver/decryptfilescommand.h>
52 # include <uiserver/verifyfilescommand.h>
53 # include <uiserver/prepencryptcommand.h>
54 # include <uiserver/prepsigncommand.h>
55 # include <uiserver/encryptcommand.h>
56 # include <uiserver/signcommand.h>
57 # include <uiserver/signencryptfilescommand.h>
58 # include <uiserver/selectcertificatecommand.h>
59 # include <uiserver/importfilescommand.h>
60 # include <uiserver/createchecksumscommand.h>
61 # include <uiserver/verifychecksumscommand.h>
62 #else
63 namespace Kleo {
64 class UiServer;
66 #endif
68 #include <kcmdlineargs.h>
69 #include <klocale.h>
70 #include <kiconloader.h>
71 #include <ksplashscreen.h>
72 #include <kmessagebox.h>
74 #include <QTextDocument> // for Qt::escape
75 #include <QStringList>
76 #include <QMessageBox>
77 #include <QTimer>
78 #include <QTime>
79 #include <QEventLoop>
80 #include <QThreadPool>
81 #include <QDebug>
83 #include <gpgme++/global.h>
84 #include <gpgme++/error.h>
86 #include <boost/shared_ptr.hpp>
88 #include <cassert>
90 using namespace boost;
92 static const int SPLASHSCREEN_TIMEOUT = 5000; // 5s
94 namespace {
95 template <typename T>
96 boost::shared_ptr<T> make_shared_ptr( T * t ) {
97 return t ? boost::shared_ptr<T>( t ) : boost::shared_ptr<T>() ;
101 static QPixmap UserIcon_nocached( const char * name ) {
102 // KIconLoader insists on caching all pixmaps. Since the splash
103 // screen is a particularly large 'icon' and used only once,
104 // caching is unneccesary and just hurts startup performance.
105 KIconLoader * const il = KIconLoader::global();
106 assert( il );
107 const QString iconPath = il->iconPath( QLatin1String( name ), KIconLoader::User );
108 return iconPath.isEmpty() ? il->unknown() : QPixmap( iconPath ) ;
111 class SplashScreen : public KSplashScreen {
112 QBasicTimer m_timer;
113 public:
114 SplashScreen()
115 : KSplashScreen( UserIcon_nocached( "kleopatra_splashscreen" ), Qt::WindowStaysOnTopHint ),
116 m_timer()
118 m_timer.start( SPLASHSCREEN_TIMEOUT, this );
121 protected:
122 void timerEvent( QTimerEvent * ev ) {
123 if ( ev->timerId() == m_timer.timerId() ) {
124 m_timer.stop();
125 hide();
126 } else {
127 KSplashScreen::timerEvent( ev );
133 static bool selfCheck( KSplashScreen & splash ) {
134 splash.showMessage( i18n("Performing Self-Check...") );
135 Kleo::Commands::SelfTestCommand cmd( 0 );
136 cmd.setAutoDelete( false );
137 cmd.setAutomaticMode( true );
138 cmd.setSplashScreen( &splash );
139 QEventLoop loop;
140 QObject::connect( &cmd, SIGNAL(finished()), &loop, SLOT(quit()) );
141 QObject::connect( &cmd, SIGNAL(info(QString)), &splash, SLOT(showMessage(QString)) );
142 QTimer::singleShot( 0, &cmd, SLOT(start()) ); // start() may emit finished()...
143 loop.exec();
144 if ( cmd.isCanceled() ) {
145 splash.showMessage( i18nc("did not pass", "Self-Check Failed") );
146 return false;
147 } else {
148 splash.showMessage( i18n("Self-Check Passed") );
149 return true;
153 static void fillKeyCache( KSplashScreen * splash, Kleo::UiServer * server ) {
155 QEventLoop loop;
156 Kleo::ReloadKeysCommand * cmd = new Kleo::ReloadKeysCommand( 0 );
157 QObject::connect( cmd, SIGNAL(finished()), &loop, SLOT(quit()) );
158 #ifdef HAVE_USABLE_ASSUAN
159 QObject::connect( cmd, SIGNAL(finished()), server, SLOT(enableCryptoCommands()) );
160 #else
161 Q_UNUSED( server );
162 #endif
163 splash->showMessage( i18n("Loading certificate cache...") );
164 cmd->start();
165 loop.exec();
166 splash->showMessage( i18n("Certificate cache loaded.") );
169 int main( int argc, char** argv )
171 QTime timer;
172 timer.start();
174 const GpgME::Error gpgmeInitError = GpgME::initializeLibrary(0);
177 const unsigned int threads = QThreadPool::globalInstance()->maxThreadCount();
178 QThreadPool::globalInstance()->setMaxThreadCount( qMax( 2U, threads ) );
181 AboutData aboutData;
183 KCmdLineArgs::init(argc, argv, &aboutData);
185 KCmdLineArgs::addCmdLineOptions( KleopatraApplication::commandLineOptions() );
187 qDebug() << "Statup timing:" << timer.elapsed() << "ms elapsed: Command line args created";
189 KleopatraApplication app;
191 qDebug() << "Startup timing:" << timer.elapsed() << "ms elapsed: Application created";
193 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
195 if ( gpgmeInitError ) {
196 KMessageBox::sorry( 0, i18nc("@info",
197 "<para>The version of the <application>GpgME</application> library you are running against "
198 "is older than the one that the <application>GpgME++</application> library was built against.</para>"
199 "<para><application>Kleopatra</application> will not function in this setting.</para>"
200 "<para>Please ask your administrator for help in resolving this issue.</para>"),
201 i18nc("@title", "GpgME Too Old") );
202 return EXIT_FAILURE;
205 SplashScreen splash;
207 int rc;
208 #ifdef HAVE_USABLE_ASSUAN
209 try {
210 Kleo::UiServer server( args->getOption("uiserver-socket") );
212 qDebug() << "Startup timing:" << timer.elapsed() << "ms elapsed: UiServer created";
214 QObject::connect( &server, SIGNAL(startKeyManagerRequested()),
215 &app, SLOT(openOrRaiseMainWindow()) );
217 QObject::connect( &server, SIGNAL(startConfigDialogRequested()),
218 &app, SLOT(openOrRaiseConfigDialog()) );
220 #define REGISTER( Command ) server.registerCommandFactory( boost::shared_ptr<Kleo::AssuanCommandFactory>( new Kleo::GenericAssuanCommandFactory<Kleo::Command> ) )
221 REGISTER( CreateChecksumsCommand );
222 REGISTER( DecryptCommand );
223 REGISTER( DecryptFilesCommand );
224 REGISTER( DecryptVerifyFilesCommand );
225 REGISTER( EchoCommand );
226 REGISTER( EncryptCommand );
227 REGISTER( EncryptFilesCommand );
228 REGISTER( EncryptSignFilesCommand );
229 REGISTER( ImportFilesCommand );
230 REGISTER( PrepEncryptCommand );
231 REGISTER( PrepSignCommand );
232 REGISTER( SelectCertificateCommand );
233 REGISTER( SignCommand );
234 REGISTER( SignEncryptFilesCommand );
235 REGISTER( SignFilesCommand );
236 REGISTER( VerifyChecksumsCommand );
237 REGISTER( VerifyCommand );
238 REGISTER( VerifyFilesCommand );
239 #undef REGISTER
241 server.start();
242 qDebug() << "Startup timing:" << timer.elapsed() << "ms elapsed: UiServer started";
243 #endif
245 const bool daemon = args->isSet("daemon");
247 if ( !daemon )
248 splash.show();
249 if ( !selfCheck( splash ) )
250 return 1;
251 qDebug() << "Startup timing:" << timer.elapsed() << "ms elapsed: SelfCheck completed";
253 #ifdef HAVE_USABLE_ASSUAN
254 fillKeyCache( &splash, &server );
255 #else
256 fillKeyCache( &splash, 0 );
257 #endif
258 qDebug() << "Startup timing:" << timer.elapsed() << "ms elapsed: KeyCache loaded";
260 app.startMonitoringSmartCard();
262 app.setIgnoreNewInstance( false );
264 if ( !daemon ) {
265 app.newInstance();
266 qDebug() << "Startup timing:" << timer.elapsed() << "ms elapsed: new instance created";
267 splash.finish( app.mainWindow() );
270 rc = app.exec();
272 #ifdef HAVE_USABLE_ASSUAN
273 app.setIgnoreNewInstance( true );
274 QObject::disconnect( &server, SIGNAL(startKeyManagerRequested()),
275 &app, SLOT(openOrRaiseMainWindow()) );
276 QObject::disconnect( &server, SIGNAL(startConfigDialogRequested()),
277 &app, SLOT(openOrRaiseConfigDialog()) );
279 server.stop();
280 server.waitForStopped();
281 } catch ( const std::exception & e ) {
282 QMessageBox::information( 0, i18n("GPG UI Server Error"),
283 i18n("<qt>The Kleopatra GPG UI Server Module could not be initialized.<br/>"
284 "The error given was: <b>%1</b><br/>"
285 "You can use Kleopatra as a certificate manager, but cryptographic plugins that "
286 "rely on a GPG UI Server being present might not work correctly, or at all.</qt>",
287 Qt::escape( QString::fromUtf8( e.what() ) ) ));
288 app.startMonitoringSmartCard();
289 app.setIgnoreNewInstance( false );
290 rc = app.exec();
291 app.setIgnoreNewInstance( true );
293 #endif
295 return rc;