text: // Copyright (c) 2011-2015 The Bitcoin Core developers
  // Copyright (c) 2014-2019 The Kanchan Core developers
  // Distributed under the MIT software license, see the accompanying
  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  
  #if defined(HAVE_CONFIG_H)
  #include "config/kanchan-config.h"
  #endif
  
  #include "splashscreen.h"
  
  #include "guiutil.h"
  #include "networkstyle.h"
  
  #include "clientversion.h"
  #include "init.h"
  #include "util.h"
  #include "ui_interface.h"
  #include "version.h"
  #ifdef ENABLE_WALLET
  #include "wallet/wallet.h"
  #endif
  
  #include <QApplication>
  #include <QCloseEvent>
  #include <QDesktopWidget>
  #include <QPainter>
  
  SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) :
      QWidget(0, f), curAlignment(0)
  {
  
      // transparent background
      setAttribute(Qt::WA_TranslucentBackground);
      setStyleSheet("background:transparent;");
  
      // no window decorations
      setWindowFlags(Qt::FramelessWindowHint);
  
      // set reference point, paddings
      int paddingLeft             = 14;
      int paddingTop              = 470;
      int titleVersionVSpace      = 17;
      int titleCopyrightVSpace    = 22;
  
      float fontFactor            = 1.0;
  
      // define text to place
      QString titleText       = tr(PACKAGE_NAME);
      QString versionText     = QString(tr("Version %1")).arg(QString::fromStdString(FormatFullVersion()));
      QString copyrightText   = QString::fromUtf8(CopyrightHolders("\xc2\xA9", 2014, COPYRIGHT_YEAR).c_str());
      QString titleAddText    = networkStyle->getTitleAddText();
  
      QString font = QApplication::font().toString();
  
      // load the bitmap for writing some text over it
      pixmap = networkStyle->getSplashImage();
  
      QPainter pixPaint(&pixmap);
      pixPaint.setPen(QColor(100,100,100));
  
      // check font size and drawing with
      pixPaint.setFont(QFont(font, 28*fontFactor));
      QFontMetrics fm = pixPaint.fontMetrics();
      int titleTextWidth = fm.width(titleText);
      if (titleTextWidth > 160) {
          fontFactor = 0.75;
      }
  
      pixPaint.setFont(QFont(font, 28*fontFactor));
      fm = pixPaint.fontMetrics();
      titleTextWidth  = fm.width(titleText);
      pixPaint.drawText(paddingLeft,paddingTop,titleText);
  
      pixPaint.setFont(QFont(font, 15*fontFactor));
      pixPaint.drawText(paddingLeft,paddingTop+titleVersionVSpace,versionText);
  
      // draw copyright stuff
      {
          pixPaint.setFont(QFont(font, 10*fontFactor));
          const int x = paddingLeft;
          const int y = paddingTop+titleCopyrightVSpace;
          QRect copyrightRect(x, y, pixmap.width() - x, pixmap.height() - y);
          pixPaint.drawText(copyrightRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, copyrightText);
      }
  
      // draw additional text if special network
      if(!titleAddText.isEmpty()) {
          QFont boldFont = QFont(font, 10*fontFactor);
          boldFont.setWeight(QFont::Bold);
          pixPaint.setFont(boldFont);
          fm = pixPaint.fontMetrics();
          int titleAddTextWidth  = fm.width(titleAddText);
          pixPaint.drawText(pixmap.width()-titleAddTextWidth-10,pixmap.height()-25,titleAddText);
      }
  
      pixPaint.end();
  
      // Resize window and move to center of desktop, disallow resizing
      QRect r(QPoint(), pixmap.size());
      resize(r.size());
      setFixedSize(r.size());
      move(QApplication::desktop()->screenGeometry().center() - r.center());
  
      subscribeToCoreSignals();
      installEventFilter(this);
  }
  
  SplashScreen::~SplashScreen()
  {
      unsubscribeFromCoreSignals();
  }
  
  bool SplashScreen::eventFilter(QObject * obj, QEvent * ev) {
      if (ev->type() == QEvent::KeyPress) {
          QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
          if(keyEvent->text()[0] == 'q' && breakAction != nullptr) {
              breakAction();
          }
      }
      return QObject::eventFilter(obj, ev);
  }
  
  void SplashScreen::slotFinish(QWidget *mainWin)
  {
      Q_UNUSED(mainWin);
  
      /* If the window is minimized, hide() will be ignored. */
      /* Make sure we de-minimize the splashscreen window before hiding */
      if (isMinimized())
          showNormal();
      hide();
      deleteLater(); // No more need for this
  }
  
  static void InitMessage(SplashScreen *splash, const std::string &message)
  {
      QMetaObject::invokeMethod(splash, "showMessage",
          Qt::QueuedConnection,
          Q_ARG(QString, QString::fromStdString(message)),
          Q_ARG(int, Qt::AlignBottom|Qt::AlignHCenter),
          Q_ARG(QColor, QColor(55,55,55)));
  }
  
  static void ShowProgress(SplashScreen *splash, const std::string &title, int nProgress)
  {
      InitMessage(splash, title + strprintf("%d", nProgress) + "%");
  }
  
  void SplashScreen::setBreakAction(const std::function<void(void)> &action)
  {
      breakAction = action;
  }
  
  static void SetProgressBreakAction(SplashScreen *splash, const std::function<void(void)> &action)
  {
      QMetaObject::invokeMethod(splash, "setBreakAction",
          Qt::QueuedConnection,
          Q_ARG(std::function<void(void)>, action));
  }
  
  #ifdef ENABLE_WALLET
  void SplashScreen::ConnectWallet(CWallet* wallet)
  {
      wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
      connectedWallets.push_back(wallet);
  }
  #endif
  
  void SplashScreen::subscribeToCoreSignals()
  {
      // Connect signals to client
      uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1));
      uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
      uiInterface.SetProgressBreakAction.connect(boost::bind(SetProgressBreakAction, this, _1));
  #ifdef ENABLE_WALLET
      uiInterface.LoadWallet.connect(boost::bind(&SplashScreen::ConnectWallet, this, _1));
  #endif
  }
  
  void SplashScreen::unsubscribeFromCoreSignals()
  {
      // Disconnect signals from client
      uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, _1));
      uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
  #ifdef ENABLE_WALLET
      for (CWallet* const & pwallet : connectedWallets) {
          pwallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
      }
  #endif
  }
  
  void SplashScreen::showMessage(const QString &message, int alignment, const QColor &color)
  {
      curMessage = message;
      curAlignment = alignment;
      curColor = color;
      update();
  }
  
  void SplashScreen::paintEvent(QPaintEvent *event)
  {
      QPainter painter(this);
      painter.drawPixmap(0, 0, pixmap);
      QRect r = rect().adjusted(5, 5, -5, -5);
      painter.setPen(curColor);
      painter.drawText(r, curAlignment, curMessage);
  }
  
  void SplashScreen::closeEvent(QCloseEvent *event)
  {
      StartShutdown(); // allows an "emergency" shutdown during startup
      event->ignore();
  }
  