File indexing completed on 2024-05-19 05:14:38

0001 /*
0002   This file is part of KAddressBook.
0003 
0004   SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
0005 
0006   SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "mainwindow.h"
0010 #include "mainwidget.h"
0011 #include "settings.h"
0012 #include <KAboutData>
0013 #include <KActionCollection>
0014 #include <KConfigGroup>
0015 #include <KEditToolBar>
0016 #include <KLocalizedString>
0017 #include <KMessageBox>
0018 #include <KSharedConfig>
0019 #include <KShortcutsDialog>
0020 #include <KStandardAction>
0021 #include <KToggleFullScreenAction>
0022 #include <KToolBar>
0023 #include <QAction>
0024 #include <QFontDatabase>
0025 #include <QMenuBar>
0026 #include <QPointer>
0027 #include <QVBoxLayout>
0028 
0029 // signal handler for SIGINT & SIGTERM
0030 #ifdef Q_OS_UNIX
0031 #include <KSignalHandler>
0032 #include <signal.h>
0033 #include <unistd.h>
0034 #endif
0035 
0036 #ifdef WITH_KUSERFEEDBACK
0037 #include "userfeedback/userfeedbackmanager.h"
0038 #include <KUserFeedback/NotificationPopup>
0039 #include <KUserFeedback/Provider>
0040 #endif
0041 
0042 #include <PimCommon/NeedUpdateVersionUtils>
0043 #include <PimCommon/NeedUpdateVersionWidget>
0044 
0045 MainWindow::MainWindow()
0046     : KXmlGuiWindow(nullptr)
0047     , mMainWidget(new MainWidget(this, this))
0048 {
0049 #ifdef Q_OS_UNIX
0050     /**
0051      * Set up signal handler for SIGINT and SIGTERM
0052      */
0053     KSignalHandler::self()->watchSignal(SIGINT);
0054     KSignalHandler::self()->watchSignal(SIGTERM);
0055     connect(KSignalHandler::self(), &KSignalHandler::signalReceived, this, [this](int signal) {
0056         if (signal == SIGINT || signal == SIGTERM) {
0057             printf("Shutting down...\n");
0058             if (mMainWidget->canClose()) {
0059                 close();
0060             }
0061         }
0062     });
0063 #endif
0064     auto mainWidget = new QWidget(this);
0065     auto mainWidgetLayout = new QVBoxLayout(mainWidget);
0066     mainWidgetLayout->setContentsMargins({});
0067     mainWidgetLayout->setSpacing(0);
0068     if (PimCommon::NeedUpdateVersionUtils::checkVersion()) {
0069         const auto status = PimCommon::NeedUpdateVersionUtils::obsoleteVersionStatus(KAboutData::applicationData().version(), QDate::currentDate());
0070         if (status != PimCommon::NeedUpdateVersionUtils::ObsoleteVersion::NotObsoleteYet) {
0071             auto needUpdateVersionWidget = new PimCommon::NeedUpdateVersionWidget(this);
0072             mainWidgetLayout->addWidget(needUpdateVersionWidget);
0073             needUpdateVersionWidget->setObsoleteVersion(status);
0074         }
0075     }
0076     mainWidgetLayout->addWidget(mMainWidget);
0077 
0078     setCentralWidget(mainWidget);
0079 
0080     setStandardToolBarMenuEnabled(true);
0081 
0082     toolBar()->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
0083 
0084     initActions();
0085     setupGUI(Save | Create, QStringLiteral("kaddressbookui.rc"));
0086 
0087     setAutoSaveSettings();
0088 
0089     mShowMenuBarAction->setChecked(Settings::self()->showMenuBar());
0090     slotToggleMenubar(true);
0091 #ifdef WITH_KUSERFEEDBACK
0092     auto userFeedBackNotificationPopup = new KUserFeedback::NotificationPopup(this);
0093     userFeedBackNotificationPopup->setFeedbackProvider(UserFeedBackManager::self()->userFeedbackProvider());
0094 #endif
0095 }
0096 
0097 MainWindow::~MainWindow() = default;
0098 
0099 MainWidget *MainWindow::mainWidget() const
0100 {
0101     return mMainWidget;
0102 }
0103 
0104 void MainWindow::initActions()
0105 {
0106     KStandardAction::quit(this, &MainWindow::close, actionCollection());
0107     mShowMenuBarAction = KStandardAction::showMenubar(this, &MainWindow::slotToggleMenubar, actionCollection());
0108 
0109     QAction *action = KStandardAction::keyBindings(this, &MainWindow::configureKeyBindings, actionCollection());
0110     action->setWhatsThis(i18nc("@info:whatsthis",
0111                                "You will be presented with a dialog where you can configure "
0112                                "the application-wide shortcuts."));
0113     KStandardAction::configureToolbars(this, &MainWindow::configureToolbars, actionCollection());
0114     KStandardAction::preferences(this, &MainWindow::configure, actionCollection());
0115     if (menuBar()) {
0116         mHamburgerMenu = KStandardAction::hamburgerMenu(nullptr, nullptr, actionCollection());
0117         mHamburgerMenu->setShowMenuBarAction(mShowMenuBarAction);
0118         mHamburgerMenu->setMenuBar(menuBar());
0119         connect(mHamburgerMenu, &KHamburgerMenu::aboutToShowMenu, this, [this]() {
0120             updateHamburgerMenu();
0121             // Immediately disconnect. We only need to run this once, but on demand.
0122             // NOTE: The nullptr at the end disconnects all connections between
0123             // q and mHamburgerMenu's aboutToShowMenu signal.
0124             disconnect(mHamburgerMenu, &KHamburgerMenu::aboutToShowMenu, this, nullptr);
0125         });
0126     }
0127     mShowFullScreenAction = KStandardAction::fullScreen(nullptr, nullptr, this, actionCollection());
0128     actionCollection()->setDefaultShortcut(mShowFullScreenAction, Qt::Key_F11);
0129     connect(mShowFullScreenAction, &QAction::toggled, this, &MainWindow::slotFullScreen);
0130 }
0131 
0132 void MainWindow::slotFullScreen(bool t)
0133 {
0134     KToggleFullScreenAction::setFullScreen(this, t);
0135     QMenuBar *mb = menuBar();
0136     if (t) {
0137         auto b = new QToolButton(mb);
0138         b->setDefaultAction(mShowFullScreenAction);
0139         b->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Ignored));
0140         b->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
0141         mb->setCornerWidget(b, Qt::TopRightCorner);
0142         b->setVisible(true);
0143         b->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
0144     } else {
0145         QWidget *w = mb->cornerWidget(Qt::TopRightCorner);
0146         if (w) {
0147             w->deleteLater();
0148         }
0149     }
0150 }
0151 
0152 void MainWindow::updateHamburgerMenu()
0153 {
0154     auto menu = new QMenu(this);
0155     menu->addAction(actionCollection()->action(QStringLiteral("akonadi_resource_create")));
0156     menu->addSeparator();
0157 
0158     menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Print)));
0159     menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::PrintPreview)));
0160     menu->addSeparator();
0161 
0162     menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Quit)));
0163     mHamburgerMenu->setMenu(menu);
0164 }
0165 
0166 void MainWindow::configure()
0167 {
0168     mMainWidget->configure();
0169 }
0170 
0171 void MainWindow::configureKeyBindings()
0172 {
0173     auto dlg = new KShortcutsDialog(this);
0174     dlg->setAttribute(Qt::WA_DeleteOnClose);
0175     dlg->setModal(false);
0176     dlg->addCollection(actionCollection());
0177 
0178     connect(dlg, &KShortcutsDialog::saved, this, [this]() {
0179         mMainWidget->updateQuickSearchText();
0180     });
0181 
0182     dlg->configure(true /* save settings on accept*/);
0183 }
0184 
0185 void MainWindow::configureToolbars()
0186 {
0187     KConfigGroup grp = KSharedConfig::openConfig()->group(QStringLiteral("MainWindow"));
0188     saveMainWindowSettings(grp);
0189 
0190     QPointer<KEditToolBar> dlg = new KEditToolBar(factory());
0191     connect(dlg.data(), &KEditToolBar::newToolBarConfig, this, &MainWindow::newToolbarConfig);
0192     dlg->exec();
0193     delete dlg;
0194 }
0195 
0196 void MainWindow::newToolbarConfig()
0197 {
0198     createGUI(QStringLiteral("kaddressbookui.rc"));
0199 
0200     applyMainWindowSettings(KSharedConfig::openConfig()->group(QStringLiteral("MainWindow")));
0201 }
0202 
0203 void MainWindow::slotToggleMenubar(bool dontShowWarning)
0204 {
0205     if (menuBar()) {
0206         if (mShowMenuBarAction->isChecked()) {
0207             menuBar()->show();
0208         } else {
0209             if (!dontShowWarning && (!toolBar()->isVisible() || !toolBar()->actions().contains(mHamburgerMenu))) {
0210                 const QString accel = mShowMenuBarAction->shortcut().toString();
0211                 KMessageBox::information(this,
0212                                          i18n("<qt>This will hide the menu bar completely."
0213                                               " You can show it again by typing %1.</qt>",
0214                                               accel),
0215                                          i18n("Hide menu bar"),
0216                                          QStringLiteral("HideMenuBarWarning"));
0217             }
0218             menuBar()->hide();
0219         }
0220         Settings::self()->setShowMenuBar(mShowMenuBarAction->isChecked());
0221     }
0222 }
0223 
0224 #include "moc_mainwindow.cpp"