Commit fe12ed2a authored by Andre Heinecke's avatar Andre Heinecke

Remove splashscreen and replace it with overlay

The startup should usually be quick enough that there is no
need for a splashscreen. If it takes longer we now show an
overlay over the keylistview and disable the keylistview.

This leaves the splashscreen in the repo / installtion
for now as there might be other uses for it.

Maniphest Tasks: T2240
parent 5484f6a9
......@@ -105,6 +105,7 @@ set(_kleopatra_SRCS
view/keytreeview.cpp
view/searchbar.cpp
view/tabwidget.cpp
view/keycacheoverlay.cpp
dialogs/certificateselectiondialog.cpp
dialogs/expirydialog.cpp
......
......@@ -312,6 +312,7 @@ QString KleopatraApplication::newInstance(const QCommandLineParser &parser,
if (query.isEmpty()) {
return i18n("No fingerprint argument specified for --query");
}
waitForKeyCache();
auto cmd = Command::commandForQuery(query);
cmd->setParentWId(parentId);
cmd->start();
......@@ -552,3 +553,15 @@ bool KleopatraApplication::ignoreNewInstance() const
{
return d->ignoreNewInstance;
}
void KleopatraApplication::waitForKeyCache() const
{
if (!KeyCache::instance()->initialized()) {
QEventLoop loop;
loop.connect(KeyCache::instance().get(), &KeyCache::keyListingDone,
&loop, &QEventLoop::quit);
qCDebug(KLEOPATRA_LOG) << "Waiting for keycache.";
loop.exec();
qCDebug(KLEOPATRA_LOG) << "Keycache available.";
}
}
......@@ -104,6 +104,10 @@ Q_SIGNALS:
* correct exitValue */
void setExitValue(int value);
private:
/** Blocks until the keycache is initalized. */
void waitForKeyCache() const;
private:
class Private;
kdtools::pimpl_ptr<Private> d;
......
......@@ -77,7 +77,6 @@ class UiServer;
#include <KLocalizedString>
#include <kiconloader.h>
#include <QSplashScreen>
#include <kmessagebox.h>
#include <QTextDocument> // for Qt::escape
......@@ -98,8 +97,6 @@ class UiServer;
using namespace boost;
static const int SPLASHSCREEN_TIMEOUT = 5000; // 5s
namespace
{
template <typename T>
......@@ -109,97 +106,31 @@ boost::shared_ptr<T> make_shared_ptr(T *t)
}
}
static QPixmap UserIcon_nocached(const char *name)
{
// KIconLoader insists on caching all pixmaps. Since the splash
// screen is a particularly large 'icon' and used only once,
// caching is unneccesary and just hurts startup performance.
KIconLoader *const il = KIconLoader::global();
assert(il);
const QString iconPath = il->iconPath(QLatin1String(name), KIconLoader::User);
return iconPath.isEmpty() ? il->unknown() : QPixmap(iconPath);
}
#ifndef QT_NO_SPLASHSCREEN
class SplashScreen : public QSplashScreen
{
QBasicTimer m_timer;
public:
SplashScreen()
: QSplashScreen(UserIcon_nocached("kleopatra_splashscreen"), Qt::WindowStaysOnTopHint),
m_timer()
{
m_timer.start(SPLASHSCREEN_TIMEOUT, this);
}
protected:
void timerEvent(QTimerEvent *ev) Q_DECL_OVERRIDE {
if (ev->timerId() == m_timer.timerId())
{
m_timer.stop();
hide();
} else {
QSplashScreen::timerEvent(ev);
}
}
};
#else
class SplashScreen {};
#endif // QT_NO_SPLASHSCREEN
static bool selfCheck(SplashScreen &splash)
static bool selfCheck()
{
#ifndef QT_NO_SPLASHSCREEN
splash.showMessage(i18n("Performing Self-Check..."));
#endif
Kleo::Commands::SelfTestCommand cmd(0);
cmd.setAutoDelete(false);
cmd.setAutomaticMode(true);
#ifndef QT_NO_SPLASHSCREEN
cmd.setSplashScreen(&splash);
#endif
QEventLoop loop;
QObject::connect(&cmd, &Kleo::Commands::SelfTestCommand::finished, &loop, &QEventLoop::quit);
#ifndef QT_NO_SPLASHSCREEN
QObject::connect(&cmd, SIGNAL(info(QString)), &splash, SLOT(showMessage(QString)));
#endif
QTimer::singleShot(0, &cmd, &Kleo::Command::start); // start() may Q_EMIT finished()...
loop.exec();
if (cmd.isCanceled()) {
#ifndef QT_NO_SPLASHSCREEN
splash.showMessage(i18nc("did not pass", "Self-Check Failed"));
#endif
return false;
} else {
#ifndef QT_NO_SPLASHSCREEN
splash.showMessage(i18n("Self-Check Passed"));
#endif
return true;
}
}
static void fillKeyCache(SplashScreen *splash, Kleo::UiServer *server)
static void fillKeyCache(Kleo::UiServer *server)
{
QEventLoop loop;
Kleo::ReloadKeysCommand *cmd = new Kleo::ReloadKeysCommand(0);
QObject::connect(cmd, &Kleo::Commands::SelfTestCommand::finished, &loop, &QEventLoop::quit);
#ifdef HAVE_USABLE_ASSUAN
QObject::connect(cmd, SIGNAL(finished()), server, SLOT(enableCryptoCommands()));
#else
Q_UNUSED(server);
#endif
#ifndef QT_NO_SPLASHSCREEN
splash->showMessage(i18n("Loading certificate cache..."));
#else
Q_UNUSED(splash);
#endif
cmd->start();
loop.exec();
#ifndef QT_NO_SPLASHSCREEN
splash->showMessage(i18n("Certificate cache loaded."));
#endif
}
int main(int argc, char **argv)
......@@ -256,8 +187,6 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
SplashScreen splash;
Kleo::ChecksumDefinition::setInstallPath(Kleo::gpg4winInstallPath());
Kleo::ArchiveDefinition::setInstallPath(Kleo::gnupgInstallPath());
......@@ -304,24 +233,16 @@ int main(int argc, char **argv)
app.restoreMainWindow();
}
#ifndef QT_NO_SPLASHSCREEN
// Don't show splash screen if daemon or session restore
if (!(daemon || app.isSessionRestored())) {
splash.show();
}
#endif
if (!selfCheck(splash)) {
if (!selfCheck()) {
return EXIT_FAILURE;
}
qCDebug(KLEOPATRA_LOG) << "Startup timing:" << timer.elapsed() << "ms elapsed: SelfCheck completed";
#ifdef HAVE_USABLE_ASSUAN
fillKeyCache(&splash, &server);
fillKeyCache(&server);
#else
fillKeyCache(&splash, 0);
fillKeyCache(Q_NULLPTR);
#endif
qCDebug(KLEOPATRA_LOG) << "Startup timing:" << timer.elapsed() << "ms elapsed: KeyCache loaded";
#ifndef QT_NO_SYSTEMTRAYICON
app.startMonitoringSmartCard();
#endif
......@@ -335,9 +256,6 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
qCDebug(KLEOPATRA_LOG) << "Startup timing:" << timer.elapsed() << "ms elapsed: new instance created";
#ifndef QT_NO_SPLASHSCREEN
splash.finish(app.mainWindow());
#endif // QT_NO_SPLASHSCREEN
}
rc = app.exec();
......
......@@ -41,6 +41,7 @@
#include "view/searchbar.h"
#include "view/tabwidget.h"
#include "view/keylistcontroller.h"
#include "view/keycacheoverlay.h"
#include "commands/selftestcommand.h"
#include "commands/importcrlcommand.h"
......@@ -252,6 +253,7 @@ MainWindow::Private::UI::UI(MainWindow *q)
vbox->addWidget(searchBar);
tabWidget.connectSearchBar(searchBar);
vbox->addWidget(&tabWidget);
new KeyCacheOverlay(mainWidget, q);
q->setCentralWidget(mainWidget);
}
......
/* keycacheoverlay.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2016 Intevation GmbH
Kleopatra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kleopatra 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
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#include "keycacheoverlay.h"
#include "models/keycache.h"
#include "kleopatra_debug.h"
#include <QVBoxLayout>
#include <QProgressBar>
#include <QLabel>
#include <QEvent>
#include <KLocalizedString>
using namespace Kleo;
KeyCacheOverlay::KeyCacheOverlay(QWidget *baseWidget, QWidget *parent)
: QWidget(parent), mBaseWidget(baseWidget)
{
const auto cache = KeyCache::instance();
if (cache->initialized()) {
// Cache initialized so we are not needed.
deleteLater();
return;
}
auto vLay = new QVBoxLayout;
auto bar = new QProgressBar;
auto label = new QLabel;
label->setText(QStringLiteral("<h3>%1</h3>").arg(i18n("Loading certificate cache...")));
bar->setRange(0, 0);
vLay->addStretch(1);
auto subLay1 = new QVBoxLayout;
auto subLay3 = new QHBoxLayout;
subLay3->addStretch(1);
subLay3->addWidget(label);
subLay3->addStretch(1);
subLay1->addLayout(subLay3);
subLay1->addWidget(bar);
auto subLay2 = new QHBoxLayout;
subLay2->addStretch(0.15);
subLay2->addLayout(subLay1, 0.7);
subLay2->addStretch(0.15);
vLay->addLayout(subLay2);
vLay->addStretch(1);
setLayout(vLay);
connect(cache.get(), &KeyCache::keyListingDone, this, &KeyCacheOverlay::hideOverlay);
mBaseWidget->installEventFilter(this);
mBaseWidget->setEnabled(false);
reposition();
}
bool KeyCacheOverlay::eventFilter(QObject *object, QEvent *event)
{
if (object == mBaseWidget &&
(event->type() == QEvent::Move || event->type() == QEvent::Resize ||
event->type() == QEvent::Show || event->type() == QEvent::Hide)) {
reposition();
}
return QWidget::eventFilter(object, event);
}
void KeyCacheOverlay::reposition()
{
if (parentWidget() != mBaseWidget->window()) {
setParent(mBaseWidget->window());
}
if (!KeyCache::instance()->initialized()) {
show();
}
const QPoint topLevelPos = mBaseWidget->mapTo(window(), QPoint(0, 0));
const QPoint parentPos = parentWidget()->mapFrom(window(), topLevelPos);
move(parentPos);
resize(mBaseWidget->size());
}
void KeyCacheOverlay::hideOverlay()
{
mBaseWidget->setEnabled(true);
hide();
mBaseWidget->removeEventFilter(this);
deleteLater();
}
/* keycacheoverlay.h
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2016 Intevation GmbH
Kleopatra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kleopatra 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
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#ifndef VIEW_KEYCACHEOVERLAY_H
#define VIEW_KEYCACHEOVERLAY_H
#include <QWidget>
namespace Kleo
{
/**
* @internal
* Overlay widget to block KeyCache-dependent widgets if the Keycache
* is not initialized.
*/
class KeyCacheOverlay: public QWidget
{
Q_OBJECT
public:
/**
* Create an overlay widget for @p baseWidget.
* @p baseWidget must not be null.
* @p parent must not be equal to @p baseWidget
*/
explicit KeyCacheOverlay(QWidget *baseWidget, QWidget *parent = 0);
protected:
bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE;
private:
void reposition();
private Q_SLOTS:
/** Hides the overlay and triggers deletion. */
void hideOverlay();
private:
QWidget *mBaseWidget;
};
} // namespace Kleo
#endif // VIEW_KEYCACHEOVERLAY_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment