diff --git a/skgbasegui/skgmainpanel.cpp b/skgbasegui/skgmainpanel.cpp
index 5a86c685b..d3cb875ad 100644
--- a/skgbasegui/skgmainpanel.cpp
+++ b/skgbasegui/skgmainpanel.cpp
@@ -1,2740 +1,2740 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* This program 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. *
* *
* This program 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, see *
***************************************************************************/
/** @file
* This file defines classes skgmainpanel.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgmainpanel.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef KActivities_FOUND
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include // std::sort
#include "skgdefine.h"
#include "skginterfaceplugin.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgtreeview.h"
#include "skgwebview.h"
#include "skgzoomselector.h"
struct doublePointer {
void* p1;
void* p2;
};
struct historyPage {
SKGTabPage::SKGPageHistoryItem current;
SKGTabPage::SKGPageHistoryItemList next;
SKGTabPage::SKGPageHistoryItemList previous;
};
struct actionDetails {
QPointer action;
QStringList tables;
int min{};
int max{};
int ranking{};
bool focus{};
};
class SKGMainPanelPrivate
{
public:
Ui::skgmainpanel_base ui{};
Ui::skgmainpanel_pref uipref{};
SKGTabWidget* m_tabWidget;
QSplashScreen* m_splashScreen;
SKGDocument* m_currentDocument;
QList m_pluginsList;
QMap m_registeredGlogalAction;
QList m_historyClosedPages;
QMenu* m_contextMenu;
QAction* m_actHideContextItem;
QAction* m_actShowAllContextItems;
QAction* m_actDelete;
QAction* m_closePageAction;
QAction* m_closeAllOtherPagesAction;
QAction* m_switchPinState;
QAction* m_saveDefaultStateAction;
QAction* m_resetDefaultStateAction;
QAction* m_overwriteBookmarkStateAction;
QAction* m_configureAction;
QAction* m_enableEditorAction;
QAction* m_fullScreenAction;
QAction* m_actLock;
QAction* m_actUnLock;
QAction* m_reopenLastClosed;
KStatusNotifierItem* m_kSystemTrayIcon;
QLabel* m_kNormalMessage;
SKGZoomSelector* m_zoomSelector;
KToolBarPopupAction* m_previousAction;
KToolBarPopupAction* m_nextAction;
KToolBarPopupAction* m_buttonMenuAction;
KToggleAction* m_showMenuBarAction;
QMenu* m_previousMenu;
QMenu* m_nextMenu;
QMenu* m_buttonMenu;
QWidget* m_mainWidget;
QVBoxLayout* m_mainLayout{};
doublePointer m_progressObjects{};
bool m_middleClick;
bool m_saveOnClose;
QString m_fileName;
SKGWidget* m_widgetHavingSelection;
QStringList m_tipsOfTheDay;
#ifdef KActivities_FOUND
KActivities::ResourceInstance* m_activityResourceInstance;
#endif
static bool m_currentActionCanceled;
static SKGMainPanel* m_mainPanel;
SKGMainPanelPrivate()
{
m_actHideContextItem = nullptr; m_actShowAllContextItems = nullptr; m_actDelete = nullptr;
m_closePageAction = nullptr; m_closeAllOtherPagesAction = nullptr; m_switchPinState = nullptr; m_saveDefaultStateAction = nullptr;
m_resetDefaultStateAction = nullptr; m_overwriteBookmarkStateAction = nullptr; m_configureAction = nullptr; m_enableEditorAction = nullptr; m_fullScreenAction = nullptr; m_actLock = nullptr;
m_actUnLock = nullptr;
m_kSystemTrayIcon = nullptr;
m_kNormalMessage = nullptr; m_zoomSelector = nullptr; m_previousAction = nullptr; m_nextAction = nullptr; m_buttonMenuAction = nullptr;
m_mainWidget = nullptr; m_mainLayout = nullptr; m_middleClick = false; m_saveOnClose = false;
m_widgetHavingSelection = nullptr;
m_tabWidget = nullptr; m_splashScreen = nullptr; m_currentDocument = nullptr;
m_contextMenu = nullptr;
m_reopenLastClosed = nullptr;
m_showMenuBarAction = nullptr;
m_previousMenu = nullptr;
m_nextMenu = nullptr;
m_buttonMenu = nullptr;
m_progressObjects.p1 = nullptr;
m_progressObjects.p2 = nullptr;
#ifdef KActivities_FOUND
m_activityResourceInstance = nullptr;
#endif
}
static int progressBarCallBack(int iPos, qint64 iTime, const QString& iName, void* iProgressBar)
{
Q_UNUSED(iTime)
QProgressBar* progressBar = nullptr;
QPushButton* button = nullptr;
auto* pointers = static_cast(iProgressBar);
if (pointers != nullptr) {
progressBar = static_cast(pointers->p1);
button = static_cast(pointers->p2);
}
bool visible = (iPos > 0 && iPos <= 100);
if (progressBar != nullptr) {
QString commonFormat = QStringLiteral("%p%");
/*if (iPos > 0) {
* qint64 estimatedTime = 100 * iTime / iPos;
* qint64 remainingTime = estimatedTime - iTime;
* commonFormat = commonFormat % " - " % i18nc("To print a remaining time (in seconde) / estimated time (in second)", "%1s / %2s",
* SKGServices::intToString(remainingTime / 1000),
* SKGServices::intToString(estimatedTime / 1000));
}*/
progressBar->setFormat(iName.isEmpty() ? commonFormat : commonFormat % '\n' % iName);
progressBar->setValue(iPos);
progressBar->setVisible(visible);
if (iPos == 100) {
QTimer::singleShot(300, Qt::CoarseTimer, progressBar, &QProgressBar::hide);
}
progressBar->setToolTip(iName);
QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/org/") + KAboutData::applicationData().componentName() + QLatin1String("/UnityLauncher"),
QStringLiteral("com.canonical.Unity.LauncherEntry"),
QStringLiteral("Update"));
message << "application://org.kde.skrooge.desktop";
QVariantMap setProperty;
if (iPos == 100) {
setProperty.insert(QStringLiteral("progress"), 0.0);
setProperty.insert(QStringLiteral("progress-visible"), false);
} else {
setProperty.insert(QStringLiteral("progress"), static_cast(iPos / 100.0));
setProperty.insert(QStringLiteral("progress-visible"), true);
}
message << setProperty;
QDBusConnection::sessionBus().send(message);
}
if (button != nullptr) {
button->setVisible(visible);
if (iPos == 100) {
QTimer::singleShot(300, Qt::CoarseTimer, button, &QPushButton::hide);
}
}
SKGMainPanelPrivate::m_currentActionCanceled = false;
if (iPos != 0 && iPos != 100) {
qApp->processEvents(QEventLoop::AllEvents, 500);
}
return (SKGMainPanelPrivate::m_currentActionCanceled ? 1 : 0);
}
static bool adviceLessThan(const SKGAdvice& s1, const SKGAdvice& s2)
{
if (s1.getPriority() == s2.getPriority()) {
return (s1.getShortMessage() > s2.getShortMessage());
}
return (s1.getPriority() > s2.getPriority());
}
static void setAttribute(QDomElement& iRoot, const QString& iPath, const QString& iValue)
{
int pos = iPath.indexOf('.');
if (pos == -1) {
iRoot.setAttribute(iPath, iValue);
} else {
QString newElementName = iPath.left(pos);
QString newAttribue = iPath.right(iPath.count() - pos - 1);
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iRoot.attribute(newElementName));
QDomElement root = doc.documentElement();
if (root.isNull()) {
root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
}
setAttribute(root, newAttribue, iValue);
iRoot.setAttribute(newElementName, doc.toString());
}
}
void refreshTabPosition()
{
m_tabWidget->setTabPosition(static_cast(skgbasegui_settings::main_tabs_position()));
}
void rebuildSystemTray()
{
if (skgbasegui_settings::icon_in_system_tray()) {
if (m_kSystemTrayIcon == nullptr) {
m_kSystemTrayIcon = new KStatusNotifierItem(m_mainPanel);
m_kSystemTrayIcon->setStandardActionsEnabled(true);
m_kSystemTrayIcon->setAssociatedWidget(m_mainPanel);
KAboutData about = KAboutData::applicationData();
m_kSystemTrayIcon->setIconByName(about.programIconName());
}
} else {
if (m_kSystemTrayIcon != nullptr) {
delete m_kSystemTrayIcon;
m_kSystemTrayIcon = nullptr;
}
}
}
};
bool SKGMainPanelPrivate::m_currentActionCanceled = false;
SKGMainPanel* SKGMainPanelPrivate::m_mainPanel = nullptr;
SKGMainPanel::SKGMainPanel(QSplashScreen* iSplashScreen, SKGDocument* iDocument)
: d(new SKGMainPanelPrivate)
{
SKGTRACEINFUNC(1)
d->m_tabWidget = new SKGTabWidget(this);
d->m_splashScreen = iSplashScreen;
d->m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg"), KAboutData::applicationData().displayName());
setObjectName(qApp->applicationDisplayName());
// Set main panel
SKGMainPanelPrivate::m_mainPanel = this;
auto w = new QScrollArea(this);
w->setFrameShape(QFrame::NoFrame);
w->setFocusPolicy(Qt::NoFocus);
d->m_mainLayout = new QVBoxLayout(w);
d->m_mainLayout->setSpacing(0);
d->m_mainLayout->setContentsMargins(0, 0, 0, 0);
d->m_mainLayout->addWidget(d->m_tabWidget);
d->ui.setupUi(this);
// setMainWidget(new QLabel("hello"));
// Initialize settings
KSharedConfigPtr config = KSharedConfig::openConfig();
KConfigGroup prefskg = config->group("Main Panel");
int option = prefskg.readEntry("update_modified_contexts", 100);
if (option == 100) {
// First call, we set default values
prefskg.writeEntry("update_modified_contexts", 2, KConfigBase::Normal);
// NEVER: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateContextOnClose"), KMessageBox::No);
SKGTRACEL(1) << "update_modified_contexts set to NEVER" << endl;
SKGTRACEL(1) << "updateContextOnClose set to No" << endl;
}
option = prefskg.readEntry("update_modified_bookmarks", 100);
if (option == 100) {
// First call, we set default values
prefskg.writeEntry("update_modified_bookmarks", 2, KConfigBase::Normal);
// NEVER: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateBookmarkOnClose"), KMessageBox::No);
SKGTRACEL(1) << "update_modified_bookmarks set to NEVER" << endl;
SKGTRACEL(1) << "updateBookmarkOnClose set to No" << endl;
}
// Search plugins
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("SKG GUI/Plugin"));
// Load plugins
int nb = offers.count();
SKGTRACEL(1) << nb << " plugins found" << endl;
if (d->m_splashScreen != nullptr) {
d->m_splashScreen->showMessage(i18nc("Splash screen message", "Loading plugins..."), Qt::AlignLeft, QColor(221, 130, 8)); // krazy:exclude=qmethods
}
SKGError err;
QStringList listAuthors;
QStringList listTasks;
QStringList listEmails;
QStringList listOscs;
for (int i = 0; i < nb; ++i) {
KService::Ptr service = offers.at(i);
QString name = service->name();
QString version = service->property(QStringLiteral("X-KDE-PluginInfo-Version"), QVariant::String).toString();
QString id = service->property(QStringLiteral("X-Krunner-ID"), QVariant::String).toString();
QString msg = i18nc("Splash screen message", "Loading plugin %1/%2: %3...", i + 1, nb, name);
SKGTRACEL(1) << msg << endl;
if (d->m_splashScreen != nullptr) {
d->m_splashScreen->showMessage(msg, Qt::AlignLeft, QColor(221, 130, 8)); // krazy:exclude=qmethods
}
KPluginLoader loader(service->library());
if (version.isEmpty() || SKGServices::stringToDouble(version) < 1) {
SKGTRACE << "WARNING: plugin [" << name << "] not loaded because of version too old (<1)" << endl;
} else {
KPluginFactory* factory2 = loader.factory();
if (factory2 != nullptr) {
auto* pluginInterface = factory2->create (this);
if (pluginInterface != nullptr) {
if (pluginInterface->isEnabled() && pluginInterface->setupActions(getDocument())) {
// Add plugin in about
QStringList listOfAuthors;
QStringList listOfEmails;
QStringList listOfPlugins;
QString author = service->property(QStringLiteral("X-KDE-PluginInfo-Author"), QVariant::String).toString();
QString email = service->property(QStringLiteral("X-KDE-PluginInfo-Email"), QVariant::String).toString();
if (!author.isEmpty()) {
listOfAuthors.push_back(author);
listOfEmails.push_back(email);
listOfPlugins.push_back(name);
}
const auto subPlugins = pluginInterface->subPlugins();
for (const QString& subPlugin : subPlugins) {
KService::List subOffers = KServiceTypeTrader::self()->query(subPlugin);
int nbSubOffers = subOffers.count();
for (int j = 0; j < nbSubOffers; ++j) {
KService::Ptr subService = subOffers.at(j);
QString author2 = subService->property(QStringLiteral("X-KDE-PluginInfo-Author"), QVariant::String).toString();
QString email2 = subService->property(QStringLiteral("X-KDE-PluginInfo-Email"), QVariant::String).toString();
if (!author2.isEmpty()) {
listOfAuthors.push_back(author2);
listOfEmails.push_back(email2);
listOfPlugins.push_back(subService->name());
}
}
}
int nbAuthors = listOfAuthors.count();
for (int j = 0; j < nbAuthors; ++j) {
QString authorId;
QString author = listOfAuthors.at(j);
QStringList authors = SKGServices::splitCSVLine(author, ',');
if (authors.count() == 2) {
author = authors.at(0);
authorId = authors.at(1);
}
int pos2 = listAuthors.indexOf(author);
if (pos2 == -1) {
listAuthors.push_back(author);
listTasks.push_back(i18n("Developer of plugin '%1'", listOfPlugins.at(j)));
listEmails.push_back(listOfEmails.at(j));
listOscs.push_back(authorId);
} else {
listTasks[pos2] += i18n(", '%1'", listOfPlugins.at(j));
}
}
// Store plugin
int nbplugin = d->m_pluginsList.count();
int pos3 = nbplugin;
for (int j = nbplugin - 1; j >= 0; --j) {
if (pluginInterface->getOrder() < d->m_pluginsList.at(j)->getOrder()) {
pos3 = j;
}
}
d->m_pluginsList.insert(pos3, pluginInterface);
pluginInterface->setObjectName(id);
// Add tips
d->m_tipsOfTheDay += pluginInterface->tips();
}
}
} else {
QString msg2 = i18nc("An information message", "Loading plugin %1 failed because the factory could not be found in %2: %3", id, service->library(), loader.errorString());
getDocument()->sendMessage(msg2);
SKGTRACEL(1) << "WARNING:" << msg2 << endl;
}
}
}
// Add credits
KAboutData about = KAboutData::applicationData();
nb = listAuthors.count();
for (int i = 0; i < nb; ++i) {
about.addCredit(listAuthors.at(i), listTasks.at(i), listEmails.at(i), QLatin1String(""), listOscs.at(i));
}
KAboutData::setApplicationData(about);
// accept dnd
setAcceptDrops(true);
// tell the KXmlGuiWindow that this is indeed the main widget
setCentralWidget(w);
d->refreshTabPosition();
d->m_tabWidget->setMovable(true);
d->m_tabWidget->setTabsClosable(true);
d->m_tabWidget->setUsesScrollButtons(true);
d->m_tabWidget->tabBar()->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
d->m_tabWidget->setDocumentMode(true);
d->m_tabWidget->show();
// System tray
d->rebuildSystemTray();
// then, setup our actions
setupActions();
displayErrorMessage(err);
// Add a status bar
statusBar()->show();
QPalette palette2 = QApplication::palette();
palette2.setColor(QPalette::Base, Qt::transparent);
d->ui.kContextList->setPalette(palette2);
QAction* toggle = d->ui.kDockContext->toggleViewAction();
QAction* panelAction = actionCollection()->addAction(QStringLiteral("view_context"));
registerGlobalAction(QStringLiteral("view_context"), panelAction);
panelAction->setCheckable(true);
panelAction->setChecked(toggle->isChecked());
panelAction->setText(toggle->text());
actionCollection()->setDefaultShortcut(panelAction, Qt::SHIFT + Qt::Key_F9);
connect(panelAction, &QAction::triggered, toggle, &QAction::trigger);
connect(toggle, &QAction::toggled, panelAction, &QAction::setChecked);
QAction* toggle2 = d->ui.kDockMessages->toggleViewAction();
QAction* panelAction2 = actionCollection()->addAction(QStringLiteral("view_messages"));
registerGlobalAction(QStringLiteral("view_messages"), panelAction2);
panelAction2->setCheckable(true);
panelAction2->setChecked(toggle2->isChecked());
panelAction2->setText(toggle2->text());
actionCollection()->setDefaultShortcut(panelAction2, Qt::SHIFT + Qt::Key_F8);
connect(panelAction2, &QAction::triggered, toggle2, &QAction::trigger);
connect(toggle2, &QAction::toggled, panelAction2, &QAction::setChecked);
auto contextMenu = new KSelectAction(SKGServices::fromTheme(QStringLiteral("tab-new")), i18nc("Noun", "Pages"), this);
registerGlobalAction(QStringLiteral("view_contextmenu"), contextMenu);
// Add plugin in client in right order
QList pageNotVisible;
KConfigGroup prefContextVisibility = config->group("Context Visibility");
int shortCutIndex = 0;
QString shortCutPrefix = QStringLiteral("Ctrl+");
int nbplugin = d->m_pluginsList.count();
QList contextActionList;
for (int j = 0; j < nbplugin; ++j) {
SKGInterfacePlugin* pluginInterface = d->m_pluginsList.at(j);
if (pluginInterface != nullptr) {
// Creation of the item
QString title = pluginInterface->title();
SKGTRACEL(1) << "Add plugin (" << pluginInterface->getOrder() << ") : " << title << endl;
if (!title.isEmpty()) {
// Add menu item with shortcuts
if (pluginInterface->isInPagesChooser()) {
bool visible = prefContextVisibility.readEntry(pluginInterface->objectName(), true);
QIcon icon = SKGServices::fromTheme(pluginInterface->icon());
auto contextItem = new QListWidgetItem(icon, title);
contextItem->setStatusTip(pluginInterface->statusTip());
contextItem->setToolTip(pluginInterface->toolTip());
contextItem->setData(12, j); // context item ==> plugin
int page2 = d->ui.kContextList->count();
pluginInterface->setProperty("contextItem", page2); // plugin ==> context item
d->ui.kContextList->addItem(contextItem);
QAction* newAction = contextMenu->addAction(icon, title);
if (newAction != nullptr) {
newAction->setCheckable(false);
newAction->setData(page2);
contextItem->setData(15, QVariant::fromValue(static_cast(newAction))); // context item ==> action
if (!shortCutPrefix.isEmpty()) {
++shortCutIndex;
if (shortCutIndex == 10) {
shortCutIndex = 0;
if (shortCutPrefix == QStringLiteral("Ctrl+")) {
shortCutPrefix += QStringLiteral("Alt+");
} else {
shortCutPrefix = QLatin1String("");
}
}
if (!shortCutPrefix.isEmpty()) {
actionCollection()->setDefaultShortcut(newAction, QString(shortCutPrefix % SKGServices::intToString(shortCutIndex)));
}
}
connect(newAction, &QAction::triggered, this, &SKGMainPanel::onOpenContext);
contextActionList.append(newAction);
if (!visible) {
pageNotVisible.push_back(contextItem);
}
// Register action
QString id = "page_" % pluginInterface->objectName();
registerGlobalAction(id, newAction);
registerGlobalAction(id, newAction);
}
}
// Create dock if needed
QDockWidget* dockWidget = pluginInterface->getDockWidget();
if (dockWidget != nullptr) {
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
tabifyDockWidget(d->ui.kDockContext, dockWidget);
tabifyDockWidget(dockWidget, d->ui.kDockContext);
}
}
}
}
// Lock docs if needed
KConfigGroup pref = getMainConfigGroup();
if (pref.readEntry("docks_locked", false)) {
onLockDocks();
}
if (!pref.readEntry("first_launch", false)) {
this->setWindowState(windowState() | Qt::WindowMaximized);
pref.writeEntry("first_launch", true);
}
// a call to KXmlGuiWindow::setupGUI() populates the GUI
// with actions, using KXMLGUI.
// It also applies the saved mainwindow settings, if any, and ask the
// mainwindow to automatically save settings if changed: window size,
// toolbar position, icon size, etc.
setupGUI(Default, QStringLiteral("skgmainpanel.rc"));
plugActionList(QStringLiteral("context_actionlist"), contextActionList);
for (int j = 0; j < nbplugin; ++j) {
SKGInterfacePlugin* pluginInterface = d->m_pluginsList.at(j);
if (pluginInterface != nullptr) {
QString title = pluginInterface->title();
SKGTRACEL(1) << "Add plugin client (" << pluginInterface->getOrder() << ") : " << title << endl;
guiFactory()->addClient(pluginInterface);
}
}
// Hide items in context
nb = pageNotVisible.count();
for (int i = 0; i < nb; ++i) {
setContextVisibility(pageNotVisible.at(i), false);
}
// Set status bar
d->m_kNormalMessage = new QLabel(this);
d->m_kNormalMessage->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred));
auto kProgressBar = new QProgressBar(this);
kProgressBar->setObjectName(QStringLiteral("kProgressBar"));
kProgressBar->setValue(0);
kProgressBar->setMinimumSize(100, 20);
QSizePolicy sizePolicyProgessBar(QSizePolicy::Fixed, QSizePolicy::Expanding);
kProgressBar->setSizePolicy(sizePolicyProgessBar);
kProgressBar->setToolTip(i18nc("Widget description", "Progress of the current action"));
QFont f = kProgressBar->font();
f.setPointSize(6.0);
kProgressBar->setFont(f);
kProgressBar->setVisible(false);
kProgressBar->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
kProgressBar->setRange(0, 100);
d->m_zoomSelector = new SKGZoomSelector(this);
d->m_zoomSelector->setSizePolicy(sizePolicyProgessBar);
connect(d->m_zoomSelector, &SKGZoomSelector::changed, this, &SKGMainPanel::onZoomChanged);
statusBar()->addWidget(d->m_kNormalMessage, 1);
statusBar()->addPermanentWidget(kProgressBar);
// Set Cancel button
auto kCancelButton = new QPushButton();
kCancelButton->setObjectName(QStringLiteral("kCancelButton"));
kCancelButton->setIcon(SKGServices::fromTheme(QStringLiteral("media-playback-stop")));
kCancelButton->setToolTip(i18nc("Widget description", "Cancel the current action"));
kCancelButton->setStatusTip(i18nc("Widget description", "Cancel the current action"));
kCancelButton->setVisible(false);
connect(kCancelButton, &QPushButton::clicked, this, &SKGMainPanel::onCancelCurrentAction);
//
d->ui.kClearMessageBtn->setIcon(SKGServices::fromTheme(QStringLiteral("edit-clear")));
connect(d->ui.kClearMessageBtn, &QPushButton::clicked, this, &SKGMainPanel::onClearMessages);
// Add special button in toolbar
KToolBar* tb = toolBar();
if (tb != nullptr) {
auto label = new QLabel(this);
QSizePolicy sizePolicyLabel(QSizePolicy::Expanding, QSizePolicy::Preferred);
sizePolicyLabel.setHorizontalStretch(0);
sizePolicyLabel.setVerticalStretch(0);
sizePolicyLabel.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
label->setSizePolicy(sizePolicyLabel);
tb->addWidget(label);
tb->addAction(d->m_buttonMenuAction);
}
statusBar()->addPermanentWidget(kCancelButton);
statusBar()->addPermanentWidget(d->m_zoomSelector);
// Set progress bar call back
if (getDocument() != nullptr) {
d->m_progressObjects.p1 = static_cast(kProgressBar);
d->m_progressObjects.p2 = static_cast(kCancelButton);
getDocument()->setProgressCallback(&SKGMainPanelPrivate::progressBarCallBack, static_cast(&d->m_progressObjects));
}
// Connection
if (getDocument() != nullptr) {
connect(getDocument(), &SKGDocument::transactionSuccessfullyEnded, this, &SKGMainPanel::refresh, Qt::QueuedConnection);
connect(getDocument(), &SKGDocument::transactionSuccessfullyEnded, this, &SKGMainPanel::notify, Qt::QueuedConnection);
}
connect(d->ui.kContextList, &QListWidget::itemPressed, this, &SKGMainPanel::onBeforeOpenContext);
connect(d->ui.kContextList, &QListWidget::itemPressed, this, &SKGMainPanel::onOpenContext);
connect(d->m_tabWidget->tabBar(), &QTabBar::tabCloseRequested, this, &SKGMainPanel::closePageByIndex);
connect(d->m_tabWidget->tabBar(), &QTabBar::tabBarClicked, this, [ = ](int index) {
if ((QApplication::mouseButtons() & Qt::MidButton) != 0u) {
closePageByIndex(index);
}
});
connect(d->m_tabWidget->tabBar(), &QTabBar::tabBarDoubleClicked, this, &SKGMainPanel::addTab);
connect(d->m_tabWidget->tabBar(), &QTabBar::currentChanged, this, &SKGMainPanel::currentPageChanged);
connect(this, &SKGMainPanel::currentPageChanged, this, &SKGMainPanel::refresh);
connect(this, &SKGMainPanel::currentPageChanged, this, &SKGMainPanel::selectionChanged);
// Refresh
refresh();
d->ui.kContextList->installEventFilter(this);
// Build contextual menu
d->ui.kContextList->setContextMenuPolicy(Qt::CustomContextMenu);
d->m_contextMenu = new QMenu(d->ui.kContextList);
d->m_actHideContextItem = d->m_contextMenu->addAction(SKGServices::fromTheme(QStringLiteral("layer-visible-off")), i18nc("Verb", "Hide"));
connect(d->m_actHideContextItem, &QAction::triggered, this, &SKGMainPanel::onHideContextItem);
d->m_actShowAllContextItems = d->m_contextMenu->addAction(SKGServices::fromTheme(QStringLiteral("layer-visible-on")), i18nc("Verb", "Show all"));
connect(d->m_actShowAllContextItems, &QAction::triggered, this, &SKGMainPanel::onShowAllContextItems);
d->m_contextMenu->addSeparator();
d->m_contextMenu->addAction(getGlobalAction(QStringLiteral("tab_savedefaultstate")));
d->m_contextMenu->addAction(getGlobalAction(QStringLiteral("tab_resetdefaultstate")));
connect(d->ui.kContextList, &QListWidget::customContextMenuRequested, this, &SKGMainPanel::showMenu);
#ifdef KActivities_FOUND
// Initialize kactivities resource instance
d->m_activityResourceInstance = new KActivities::ResourceInstance(window()->winId());
d->m_activityResourceInstance->setParent(this);
#endif
// Show menu bar and status bar
menuBar()->show();
statusBar()->show();
notify(); // Due to sendMessage not in a transaction
d->m_splashScreen = nullptr;
}
SKGMainPanel::~SKGMainPanel()
{
SKGTRACEINFUNC(1)
SKGMainPanelPrivate::m_mainPanel = nullptr;
disconnect(getDocument(), nullptr, this, nullptr);
// close plugins
int nb = d->m_pluginsList.count();
for (int i = 0; i < nb; ++i) {
getPluginByIndex(i)->close();
}
if (getDocument() != nullptr) {
getDocument()->close();
}
delete d;
}
void SKGMainPanel::showMenu(const QPoint iPos)
{
if (d->m_contextMenu != nullptr) {
d->m_contextMenu->popup(d->ui.kContextList->mapToGlobal(iPos));
}
}
void SKGMainPanel::setContextVisibility(QListWidgetItem* iItem, bool iVisibility)
{
if (iItem != nullptr) {
// Hide item in context
iItem->setHidden(!iVisibility);
// Hide corresponding action
QAction* act = static_cast< QAction* >(iItem->data(15).value());
if (act != nullptr) {
act->setVisible(iVisibility);
}
// Save state in settings
SKGInterfacePlugin* plugin = getPluginByIndex(iItem->data(12).toInt());
if (plugin != nullptr) {
KSharedConfigPtr config = KSharedConfig::openConfig();
KConfigGroup pref = config->group("Context Visibility");
pref.writeEntry(plugin->objectName(), iVisibility);
}
}
}
void SKGMainPanel::setContextVisibility(int iPage, bool iVisibility)
{
setContextVisibility(d->ui.kContextList->item(iPage), iVisibility);
}
void SKGMainPanel::onHideContextItem()
{
setContextVisibility(d->ui.kContextList->currentRow(), false);
}
void SKGMainPanel::onShowAllContextItems()
{
int nb = d->ui.kContextList->count();
for (int i = 0; i < nb; ++i) {
setContextVisibility(i, true);
}
}
SKGDocument* SKGMainPanel::getDocument() const
{
return d->m_currentDocument;
}
QStringList SKGMainPanel::processArguments(const QStringList& iArgument)
{
QStringList output = iArgument;
for (auto plugin : qAsConst(d->m_pluginsList)) {
if (plugin != nullptr) {
output = plugin->processArguments(output);
}
}
return output;
}
void SKGMainPanel::registerGlobalAction(const QString& iIdentifier, QAction* iAction, bool iAddInCollection,
const QStringList& iListOfTable, int iMinSelection, int iMaxSelection,
int iRanking, bool iSelectionMustHaveFocus)
{
if (iAction == nullptr) {
SKGTRACE << "WARNING: registerGlobalAction(" << iIdentifier << ",nullptr)" << endl;
} else {
QStringList keys = d->m_registeredGlogalAction.keys();
for (const auto& id : qAsConst(keys)) {
QPointer act = d->m_registeredGlogalAction.value(id).action;
if ((act != nullptr) && iIdentifier != id && act != iAction && !act->shortcut().isEmpty() && act->shortcut() == iAction->shortcut()) {
SKGTRACE << "WARNING: The actions [" << iAction->text() << " (" << iIdentifier << ")] and [" << act->text() << " (" << id << ")] has same shortcut [" << iAction->shortcut().toString() << "]" << endl;
}
}
actionDetails actDetails;
actDetails.action = iAction;
actDetails.tables = iListOfTable;
actDetails.min = iMinSelection;
actDetails.max = iMaxSelection;
actDetails.focus = iSelectionMustHaveFocus;
actDetails.ranking = (iRanking == -1 ? 10 * (d->m_registeredGlogalAction.count() + 1) : iRanking);
d->m_registeredGlogalAction[iIdentifier] = actDetails;
// This connect has not been migrated on new connect mechanism to avoid crash when leaving the application
connect(iAction, SIGNAL(destroyed(QObject*)), this, SLOT(unRegisterGlobalAction(QObject*))); // clazy:exclude=old-style-connect
if (iAddInCollection) {
QKeySequence shortCut = iAction->shortcut();
if (!shortCut.isEmpty()) {
iAction->setShortcut(QKeySequence());
}
actionCollection()->addAction(iIdentifier, iAction);
if (!shortCut.isEmpty()) {
actionCollection()->setDefaultShortcut(iAction, shortCut);
}
}
}
}
void SKGMainPanel::unRegisterGlobalAction(QObject* iAction)
{
auto* act = qobject_cast< QAction* >(iAction);
if (act != nullptr) {
const auto keys = d->m_registeredGlogalAction.keys();
for (const auto& id : keys) {
if (d->m_registeredGlogalAction.value(id).action == QPointer(act)) {
d->m_registeredGlogalAction.remove(id);
}
}
}
}
QPointer SKGMainPanel::getGlobalAction(const QString& iIdentifier, bool iWarnIfNotExist)
{
QAction* act = d->m_registeredGlogalAction.value(iIdentifier).action;
if (act == nullptr && iWarnIfNotExist) {
SKGTRACE << "WARNING: getGlobalAction(" << iIdentifier << ")=nullptr" << endl;
}
return act;
}
QList< QPointer< QAction > > SKGMainPanel::getActionsForContextualMenu(const QString& iTable)
{
// Filter action
QVector tmp;
for (const auto& actDetails : qAsConst(d->m_registeredGlogalAction)) {
if (actDetails.ranking > 0 && actDetails.min > 0) {
if (actDetails.tables.isEmpty() || actDetails.tables.contains(iTable)) {
tmp.push_back(actDetails);
} else if (actDetails.tables.count() == 1 && actDetails.tables.at(0).startsWith(QLatin1String("query:"))) {
// Dynamic mode
QStringList tmpListTable;
getDocument()->getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"), actDetails.tables.at(0).right(actDetails.tables.at(0).count() - 6), tmpListTable);
if (tmpListTable.contains(iTable)) {
tmp.push_back(actDetails);
}
}
}
}
// Sort
std::sort(tmp.begin(), tmp.end(), [&](const actionDetails & a, const actionDetails & b) {
return a.ranking < b.ranking;
});
// Generate output
int previousGroup = -1;
QList< QPointer< QAction > > output;
output.reserve(tmp.count());
for (const auto& actDetails : qAsConst(tmp)) {
int currentGroup = (actDetails.ranking) / 100;
if (currentGroup != previousGroup) {
output.push_back(nullptr);
previousGroup = currentGroup;
}
output.push_back(actDetails.action);
}
return output;
}
QMap > SKGMainPanel::getGlobalActions() const
{
QMap > map;
const auto keys = d->m_registeredGlogalAction.keys();
for (const auto& id : keys) {
map[id] = d->m_registeredGlogalAction[id].action;
}
return map;
}
SKGInterfacePlugin* SKGMainPanel::getPluginByIndex(int iIndex)
{
SKGInterfacePlugin* output = nullptr;
if (iIndex >= 0 && iIndex < d->m_pluginsList.count()) {
output = d->m_pluginsList.value(iIndex);
}
return output;
}
SKGInterfacePlugin* SKGMainPanel::getPluginByName(const QString& iName)
{
SKGInterfacePlugin* output = nullptr;
int nbplugin = d->m_pluginsList.count();
QString name = iName.toLower();
for (int j = 0; (output == nullptr) && j < nbplugin; ++j) {
QString namep = d->m_pluginsList.at(j)->objectName().toLower();
if (namep == name || namep.replace(' ', '_') == name) {
output = d->m_pluginsList.at(j);
}
}
return output;
}
void SKGMainPanel::setupActions()
{
SKGTRACEINFUNC(1)
// Std File
KStandardAction::quit(this, SLOT(onQuitAction()), actionCollection());
KStandardAction::configureNotifications(this, SLOT(onConfigureNotifications()), actionCollection());
// Preferences
KStandardAction::preferences(this, SLOT(optionsPreferences()), actionCollection());
// New Tab
auto actAddTab = new QAction(SKGServices::fromTheme(QStringLiteral("tab-new-background")), i18nc("Noun, user action", "New Tab"), this);
actionCollection()->setDefaultShortcut(actAddTab, Qt::CTRL + Qt::SHIFT + Qt::Key_W);
connect(actAddTab, &QAction::triggered, this, &SKGMainPanel::addTab);
registerGlobalAction(QStringLiteral("new_tab"), actAddTab, true, QStringList(), -1);
// Add new tab widget
auto addTabButton = new QToolButton(this);
addTabButton->setIcon(actAddTab->icon());
addTabButton->setAutoRaise(true);
addTabButton->raise();
addTabButton->setDefaultAction(actAddTab);
addTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
addTabButton->setFocusPolicy(Qt::NoFocus);
d->m_tabWidget->setCornerWidget(addTabButton);
d->m_actLock = new QAction(SKGServices::fromTheme(QStringLiteral("document-encrypt")), i18nc("Verb", "Lock panels"), this);
connect(d->m_actLock, &QAction::triggered, this, &SKGMainPanel::onLockDocks);
registerGlobalAction(QStringLiteral("view_lock"), d->m_actLock);
d->m_actUnLock = new QAction(SKGServices::fromTheme(QStringLiteral("document-decrypt")), i18nc("Verb", "Unlock panels"), this);
connect(d->m_actUnLock, &QAction::triggered, this, &SKGMainPanel::onUnlockDocks);
registerGlobalAction(QStringLiteral("view_unlock"), d->m_actUnLock);
d->m_switchPinState = new QAction(SKGServices::fromTheme(QStringLiteral("document-encrypt")), i18nc("Noun, user action", "Pin this page"), this);
connect(d->m_switchPinState, &QAction::triggered, this, [ = ] {this->switchPinPage(nullptr);});
registerGlobalAction(QStringLiteral("tab_switchpin"), d->m_switchPinState);
//
d->m_closePageAction = actionCollection()->addAction(KStandardAction::Close, QStringLiteral("tab_close"), this, SLOT(closeCurrentPage()));
registerGlobalAction(QStringLiteral("tab_close"), d->m_closePageAction);
//
auto actCloseAllPages = new QAction(SKGServices::fromTheme(QStringLiteral("window-close")), i18nc("Noun, user action", "Close All"), this);
actionCollection()->setDefaultShortcut(actCloseAllPages, Qt::ALT + Qt::Key_W);
connect(actCloseAllPages, &QAction::triggered, this, &SKGMainPanel::closeAllPages);
registerGlobalAction(QStringLiteral("tab_closeall"), actCloseAllPages, true, QStringList(), -1);
//
d->m_closeAllOtherPagesAction = new QAction(SKGServices::fromTheme(QStringLiteral("window-close")), i18nc("Noun, user action", "Close All Other"), this);
actionCollection()->setDefaultShortcut(d->m_closeAllOtherPagesAction, Qt::CTRL + Qt::ALT + Qt::Key_W);
connect(d->m_closeAllOtherPagesAction, &QAction::triggered, this, [ = ] {this->closeAllOtherPages(nullptr);});
registerGlobalAction(QStringLiteral("tab_closeallother"), d->m_closeAllOtherPagesAction);
//
d->m_saveDefaultStateAction = new QAction(SKGServices::fromTheme(QStringLiteral("document-save")), i18nc("Noun, user action", "Save page state"), this);
actionCollection()->setDefaultShortcut(d->m_saveDefaultStateAction, Qt::CTRL + Qt::ALT + Qt::Key_S);
connect(d->m_saveDefaultStateAction, &QAction::triggered, this, &SKGMainPanel::saveDefaultState);
registerGlobalAction(QStringLiteral("tab_savedefaultstate"), d->m_saveDefaultStateAction);
//
d->m_resetDefaultStateAction = new QAction(SKGServices::fromTheme(QStringLiteral("edit-clear")), i18nc("Noun, user action", "Reset page state"), this);
actionCollection()->setDefaultShortcut(d->m_resetDefaultStateAction, Qt::CTRL + Qt::ALT + Qt::Key_R);
connect(d->m_resetDefaultStateAction, &QAction::triggered, this, &SKGMainPanel::resetDefaultState);
registerGlobalAction(QStringLiteral("tab_resetdefaultstate"), d->m_resetDefaultStateAction);
//
d->m_reopenLastClosed = new QAction(SKGServices::fromTheme(QStringLiteral("tab-new")), i18nc("Noun, user action", "Reopen last page closed"), this);
actionCollection()->setDefaultShortcut(d->m_reopenLastClosed, Qt::CTRL + Qt::ALT + Qt::Key_T);
connect(d->m_reopenLastClosed, &QAction::triggered, this, &SKGMainPanel::onReopenLastClosed);
registerGlobalAction(QStringLiteral("tab_reopenlastclosed"), d->m_reopenLastClosed);
//
QStringList overlay;
overlay.push_back(QStringLiteral("bookmarks"));
d->m_overwriteBookmarkStateAction = new QAction(SKGServices::fromTheme(QStringLiteral("document-save"), overlay), i18nc("Noun, user action", "Overwrite bookmark state"), this);
connect(d->m_overwriteBookmarkStateAction, &QAction::triggered, this, &SKGMainPanel::overwriteBookmarkState);
actionCollection()->setDefaultShortcut(d->m_overwriteBookmarkStateAction, Qt::CTRL + Qt::ALT + Qt::Key_B);
registerGlobalAction(QStringLiteral("tab_overwritebookmark"), d->m_overwriteBookmarkStateAction);
//
d->m_configureAction = new QAction(SKGServices::fromTheme(QStringLiteral("configure")), i18nc("Noun, user action", "Configure..."), this);
connect(d->m_configureAction, &QAction::triggered, this, [ = ] {this->optionsPreferences();});
registerGlobalAction(QStringLiteral("tab_configure"), d->m_configureAction);
// Menu
d->m_buttonMenuAction = new KToolBarPopupAction(SKGServices::fromTheme(QStringLiteral("configure")), QLatin1String(""), this);
d->m_buttonMenuAction->setToolTip(i18nc("Noun, user action", "Menu"));
d->m_buttonMenu = d->m_buttonMenuAction->menu();
connect(d->m_buttonMenu, &QMenu::aboutToShow, this, &SKGMainPanel::onShowButtonMenu);
d->m_buttonMenuAction->setDelayed(false);
registerGlobalAction(QStringLiteral("view_menu"), d->m_buttonMenuAction);
d->m_showMenuBarAction = KStandardAction::showMenubar(this, SLOT(onShowMenuBar()), actionCollection());
KConfigGroup pref = getMainConfigGroup();
d->m_showMenuBarAction->setChecked(pref.readEntry("menubar_shown", true));
QTimer::singleShot(200, Qt::CoarseTimer, this, &SKGMainPanel::onShowMenuBar);
registerGlobalAction(QStringLiteral("options_show_menubar"), d->m_showMenuBarAction);
//
d->m_previousAction = new KToolBarPopupAction(SKGServices::fromTheme(QStringLiteral("go-previous")), i18nc("Noun, user action", "Previous"), this);
connect(d->m_previousAction, &QAction::triggered, this, &SKGMainPanel::onPrevious);
actionCollection()->setDefaultShortcut(d->m_previousAction, Qt::ALT + Qt::Key_Left);
d->m_previousAction->setPriority(QAction::LowPriority);
d->m_previousMenu = d->m_previousAction->menu();
connect(d->m_previousMenu, &QMenu::aboutToShow, this, &SKGMainPanel::onShowPreviousMenu);
d->m_previousAction->setStickyMenu(false);
d->m_previousAction->setData(0);
registerGlobalAction(QStringLiteral("go_previous"), d->m_previousAction);
//
d->m_nextAction = new KToolBarPopupAction(SKGServices::fromTheme(QStringLiteral("go-next")), i18nc("Noun, user action", "Next"), this);
connect(d->m_nextAction, &QAction::triggered, this, &SKGMainPanel::onNext);
actionCollection()->setDefaultShortcut(d->m_nextAction, Qt::ALT + Qt::Key_Right);
d->m_nextAction->setPriority(QAction::LowPriority);
d->m_nextMenu = d->m_nextAction->menu();
connect(d->m_nextMenu, &QMenu::aboutToShow, this, &SKGMainPanel::onShowNextMenu);
d->m_nextAction->setStickyMenu(false);
d->m_nextAction->setData(0);
registerGlobalAction(QStringLiteral("go_next"), d->m_nextAction);
//
d->m_fullScreenAction = actionCollection()->addAction(KStandardAction::FullScreen, QStringLiteral("fullscreen"), this, SLOT(onFullScreen()));
registerGlobalAction(QStringLiteral("fullscreen"), d->m_fullScreenAction);
//
d->m_enableEditorAction = new QAction(SKGServices::fromTheme(QStringLiteral("appointment-new")), i18nc("Noun, user action", "Enable editor"), this);
actionCollection()->setDefaultShortcut(d->m_enableEditorAction, Qt::CTRL + Qt::Key_Insert);
connect(d->m_enableEditorAction, &QAction::triggered, this, &SKGMainPanel::enableEditor);
registerGlobalAction(QStringLiteral("enable_editor"), d->m_enableEditorAction);
//
auto migrateSQLCipher = new QAction(SKGServices::fromTheme(QStringLiteral("run-build")), i18nc("Noun, user action", "Migrate to SQLCipher format"), this);
connect(migrateSQLCipher, &QAction::triggered, this, &SKGMainPanel::onMigrateToSQLCipher);
registerGlobalAction(QStringLiteral("migrate_sqlcipher"), migrateSQLCipher);
// Contextual menu
d->m_tabWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("new_tab")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_reopenlastclosed")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_close")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_closeall")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_closeallother")));
{
auto sep = new QAction(this);
sep->setSeparator(true);
d->m_tabWidget->insertAction(nullptr, sep);
}
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_switchpin")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_resetdefaultstate")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_savedefaultstate")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_overwritebookmark")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_configure")));
{
auto sep = new QAction(this);
sep->setSeparator(true);
d->m_tabWidget->insertAction(nullptr, sep);
}
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("fullscreen")));
}
void SKGMainPanel::enableEditor()
{
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
cPage->activateEditor();
}
}
void SKGMainPanel::onPrevious()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
// Get index in history of page to refresh
int indexPrevious = qobject_cast(sender())->data().toInt();
// Get lists
SKGTabPage::SKGPageHistoryItemList listPrevious = cPage->getPreviousPages();
if (indexPrevious < listPrevious.count()) {
SKGTabPage::SKGPageHistoryItemList listNext = cPage->getNextPages();
SKGTabPage::SKGPageHistoryItem current = currentPageHistoryItem();
// Get item to refresh
SKGTabPage::SKGPageHistoryItem item = listPrevious.at(indexPrevious);
// Open page
cPage = openPage(getPluginByName(item.plugin), currentPageIndex(), item.state, item.name, item.bookmarkID);
if (cPage != nullptr) {
cPage->setBookmarkID(item.bookmarkID);
// Update lists
listNext.insert(0, current);
listPrevious.removeAt(indexPrevious);
for (int i = 0; i < indexPrevious; ++i) {
SKGTabPage::SKGPageHistoryItem itemPrevious = listPrevious.at(0); // Because the list is modified
listNext.insert(0, itemPrevious);
listPrevious.removeAt(0);
}
// Set lists
cPage->setPreviousPages(listPrevious);
cPage->setNextPages(listNext);
}
refresh();
}
}
}
void SKGMainPanel::onShowPreviousMenu()
{
if (d->m_previousMenu != nullptr) {
d->m_previousMenu->clear();
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
SKGTabPage::SKGPageHistoryItemList list = cPage->getPreviousPages();
int nb = list.count();
for (int i = 0; i < nb; ++i) {
QAction* act = d->m_previousMenu->addAction(SKGServices::fromTheme(list.at(i).icon), list.at(i).name);
if (act != nullptr) {
act->setData(i);
connect(act, &QAction::triggered, this, &SKGMainPanel::onPrevious);
}
}
}
}
}
void SKGMainPanel::onShowMenuBar()
{
bool test = d->m_showMenuBarAction->isChecked();
menuBar()->setVisible(test);
d->m_buttonMenuAction->setVisible(!test);
KConfigGroup pref = getMainConfigGroup();
pref.writeEntry("menubar_shown", test);
}
void SKGMainPanel::onFullScreen()
{
auto* p = d->m_tabWidget;
if (p != nullptr) {
if (!d->m_fullScreenAction->isChecked()) {
// No Full screen
p->setWindowState(p->windowState() & ~Qt::WindowFullScreen); // reset
d->m_mainLayout->addWidget(d->m_tabWidget);
} else {
bool atLeastOnePageOpened = (d->m_tabWidget->count() > 0);
if (atLeastOnePageOpened) {
// Activate Full screen mode
p->setParent(nullptr);
p->setWindowFlags(p->windowFlags() | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
p->setWindowState(p->windowState() | Qt::WindowFullScreen); // set
p->show();
displayMessage(i18nc("Information message", "You can exit full screen mode with %1 or with the contextual menu", d->m_fullScreenAction->shortcut().toString()));
} else {
d->m_fullScreenAction->setChecked(false);
displayMessage(i18nc("Information message", "At least one page must be opened to enable full screen mode"), SKGDocument::Error);
}
}
}
}
void SKGMainPanel::onNext()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
// Get index in history of page to refresh
int posNext = qobject_cast(sender())->data().toInt();
// Get lists
SKGTabPage::SKGPageHistoryItemList listPrevious = cPage->getPreviousPages();
SKGTabPage::SKGPageHistoryItemList listNext = cPage->getNextPages();
SKGTabPage::SKGPageHistoryItem current = currentPageHistoryItem();
// Get item to refresh
SKGTabPage::SKGPageHistoryItem item = listNext.at(posNext);
// Open page
cPage = openPage(getPluginByName(item.plugin), currentPageIndex(), item.state, item.name, item.bookmarkID);
if (cPage != nullptr) {
cPage->setBookmarkID(item.bookmarkID);
// Update lists
listPrevious.insert(0, current);
listNext.removeAt(posNext);
for (int i = 0; i < posNext; ++i) {
SKGTabPage::SKGPageHistoryItem itemNext = listNext.at(0); // Because the list is modified
listPrevious.insert(0, itemNext);
listNext.removeAt(0);
}
// Set lists
cPage->setPreviousPages(listPrevious);
cPage->setNextPages(listNext);
}
refresh();
}
}
void SKGMainPanel::onReopenLastClosed()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTabPage::SKGPageHistoryItem current = currentPageHistoryItem();
// Get item to refresh
historyPage item = d->m_historyClosedPages.takeLast();
// Open page
SKGTabPage* cPage = openPage(getPluginByName(item.current.plugin), -1, item.current.state, item.current.name, item.current.bookmarkID);
if (cPage != nullptr) {
cPage->setBookmarkID(item.current.bookmarkID);
cPage->setNextPages(item.next);
cPage->setPreviousPages(item.previous);
}
refresh();
}
void SKGMainPanel::onLockDocks()
{
QObjectList cs = children();
for (auto c : qAsConst(cs)) {
auto* doc = qobject_cast(c);
if (doc != nullptr) {
doc->setFeatures(QDockWidget::NoDockWidgetFeatures);
}
}
KConfigGroup pref = getMainConfigGroup();
pref.writeEntry("docks_locked", true);
refresh();
}
void SKGMainPanel::onUnlockDocks()
{
QObjectList cs = children();
for (auto c : qAsConst(cs)) {
auto* doc = qobject_cast(c);
if (doc != nullptr) {
doc->setFeatures(QDockWidget::AllDockWidgetFeatures);
}
}
KConfigGroup pref = getMainConfigGroup();
pref.writeEntry("docks_locked", false);
refresh();
}
void SKGMainPanel::onConfigureNotifications()
{
KNotifyConfigWidget::configure(this);
}
void SKGMainPanel::onShowNextMenu()
{
if (d->m_nextMenu != nullptr) {
d->m_nextMenu->clear();
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
SKGTabPage::SKGPageHistoryItemList list = cPage->getNextPages();
int nb = list.count();
for (int i = 0; i < nb; ++i) {
QAction* act = d->m_nextMenu->addAction(SKGServices::fromTheme(list.at(i).icon), list.at(i).name);
if (act != nullptr) {
act->setData(i);
connect(act, &QAction::triggered, this, &SKGMainPanel::onNext);
}
}
}
}
}
void SKGMainPanel::onShowButtonMenu()
{
if (d->m_buttonMenu != nullptr) {
d->m_buttonMenu->clear();
QMenuBar* mb = menuBar();
if (mb != nullptr) {
d->m_buttonMenu->addActions(mb->actions());
}
}
}
bool SKGMainPanel::queryClose()
{
SKGTRACEINFUNC(1)
// Bug 2777697: To be sure that all page modifications are closed
closeAllPages();
// Bug 2777697:
bool output = queryFileClose();
// To be sure that the application is not closed in fullscreen mode
if (output) {
if (d->m_fullScreenAction->isChecked()) {
d->m_fullScreenAction->trigger();
}
}
return output;
}
void SKGMainPanel::setSaveOnClose(bool iSaveOnClose)
{
d->m_saveOnClose = iSaveOnClose;
}
bool SKGMainPanel::queryFileClose()
{
SKGTRACEINFUNC(1)
bool output = true;
if (getDocument()->getCurrentTransaction() != 0) {
displayMessage(i18nc("skgtestimportskg", "The application cannot be closed when an operation is running."), SKGDocument::Error);
output = false;
} else if (getDocument()->isFileModified()) {
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
int code = KMessageBox::Yes;
QString fileName = getDocument()->getCurrentFileName();
QAction* save = getGlobalAction(fileName.isEmpty() ? QStringLiteral("file_save_as") : QStringLiteral("file_save"));
if (save != nullptr) {
if (!d->m_saveOnClose) {
code = KMessageBox::questionYesNoCancel(this, i18nc("Question", "The document has been modified.\nDo you want to save it before closing?"),
QString(),
KGuiItem(fileName.isEmpty() ? i18nc("Question", "Save as") : i18nc("Question", "Save"),
SKGServices::fromTheme(fileName.isEmpty() ? QStringLiteral("document-save-as") : QStringLiteral("document-save"))),
KGuiItem(i18nc("Question", "Do not save")));
}
if (code == KMessageBox::Yes) {
save->trigger();
}
output = (code == KMessageBox::No || code == KMessageBox::Yes);
} else {
code = KMessageBox::questionYesNo(this, i18nc("Question", "Current modifications will not be saved.\nDo you want to continue?"));
output = (code == KMessageBox::Yes);
}
QApplication::restoreOverrideCursor();
}
return output;
}
SKGObjectBase SKGMainPanel::getFirstSelectedObject() const
{
SKGObjectBase selection;
SKGWidget* cPage = (d->m_widgetHavingSelection != nullptr ? d->m_widgetHavingSelection : currentPage());
if (cPage != nullptr) {
selection = cPage->getFirstSelectedObject();
}
return selection;
}
SKGObjectBase::SKGListSKGObjectBase SKGMainPanel::getSelectedObjects() const
{
SKGObjectBase::SKGListSKGObjectBase selection;
SKGWidget* cPage = (d->m_widgetHavingSelection != nullptr ? d->m_widgetHavingSelection : currentPage());
if (cPage != nullptr) {
selection = cPage->getSelectedObjects();
}
return selection;
}
int SKGMainPanel::getNbSelectedObjects() const
{
int nb = 0;
SKGWidget* cPage = (d->m_widgetHavingSelection != nullptr ? d->m_widgetHavingSelection : currentPage());
if (cPage != nullptr) {
nb = cPage->getNbSelectedObjects();
}
return nb;
}
bool SKGMainPanel::hasSelectionWithFocus()
{
bool output = false;
SKGWidget* cPage = (d->m_widgetHavingSelection != nullptr ? d->m_widgetHavingSelection : currentPage());
if (cPage != nullptr) {
output = cPage->hasSelectionWithFocus();
}
return output;
}
SKGAdviceList SKGMainPanel::getAdvice() const
{
SKGTRACEINFUNC(1)
// Get list of ignored advice
QString currentMonth = QDate::currentDate().toString(QStringLiteral("yyyy-MM"));
QStringList ignoredAdvice = getDocument()->getParameters(QStringLiteral("advice"), "t_value='I' OR t_value='I_" % currentMonth % '\'');
// Build the list of all advice by requesting all plugins
SKGAdviceList globalAdviceList;
int index = 0;
while (index >= 0) {
SKGInterfacePlugin* plugin = SKGMainPanel::getMainPanel()->getPluginByIndex(index);
if (plugin != nullptr) {
const auto list = plugin->advice(ignoredAdvice);
for (const auto& ad : list) {
if (!ignoredAdvice.contains(ad.getUUID()) && !ignoredAdvice.contains(SKGServices::splitCSVLine(ad.getUUID(), '|').at(0))) {
globalAdviceList.push_back(ad);
}
}
} else {
index = -2;
}
++index;
}
std::sort(globalAdviceList.begin(), globalAdviceList.end(), SKGMainPanelPrivate::adviceLessThan);
return globalAdviceList;
}
KConfigGroup SKGMainPanel::getMainConfigGroup()
{
KSharedConfigPtr config = KSharedConfig::openConfig();
return config->group("Main Panel");
}
void SKGMainPanel::optionsPreferences(const QString& iPluginName)
{
SKGTRACEINFUNC(1)
// Compute page
QString pluginName = iPluginName;
if (pluginName.isEmpty()) {
auto* act = qobject_cast(sender());
if (act != nullptr) {
pluginName = act->property("page").toString();
}
}
if (pluginName.isEmpty() && (this->currentPage() != nullptr)) {
pluginName = this->currentPage()->objectName();
}
SKGTRACEL(1) << "Open setting page: " << pluginName << endl;
// Synchronize setting with confirmation panel
if (skgbasegui_settings::update_modified_bookmarks() == 0) {
KMessageBox::ButtonCode confirm;
bool ask = KMessageBox::shouldBeShownYesNo(QStringLiteral("updateBookmarkOnClose"), confirm);
KConfigGroup pref = getMainConfigGroup();
if (ask) {
pref.writeEntry("update_modified_bookmarks", 0, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_bookmarks set to ASK" << endl;
} else if (confirm == KMessageBox::Yes) {
pref.writeEntry("update_modified_bookmarks", 1, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_bookmarks set to ALWAYS" << endl;
} else {
pref.writeEntry("update_modified_bookmarks", 2, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_bookmarks set to NEVER" << endl;
}
}
if (skgbasegui_settings::update_modified_contexts() == 0) {
KMessageBox::ButtonCode confirm;
bool ask = KMessageBox::shouldBeShownYesNo(QStringLiteral("updateContextOnClose"), confirm);
KConfigGroup pref = getMainConfigGroup();
if (ask) {
pref.writeEntry("update_modified_contexts", 0, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_contexts set to ASK" << endl;
} else if (confirm == KMessageBox::Yes) {
pref.writeEntry("update_modified_contexts", 1, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_contexts set to ALWAYS" << endl;
} else {
pref.writeEntry("update_modified_contexts", 2, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_contexts set to NEVER" << endl;
}
}
skgbasegui_settings::self()->load();
if (KConfigDialog::showDialog(QStringLiteral("settings"))) {
return;
}
auto dialog = new KConfigDialog(this, QStringLiteral("settings"), skgbasegui_settings::self());
// Add main
auto w = new QWidget();
d->uipref.setupUi(w);
d->uipref.kcfg_date_format->addItem(i18nc("Date format", "Short date (%1, %2)",
QLocale().toString(QDate::currentDate(), QLocale::ShortFormat),
QLocale().toString(QDate::currentDate().addDays(-10), QLocale::ShortFormat)));
d->uipref.kcfg_date_format->addItem(i18nc("Date format", "Long date (%1, %2)",
QLocale().toString(QDate::currentDate(), QLocale::LongFormat),
QLocale().toString(QDate::currentDate().addDays(-10), QLocale::LongFormat)));
d->uipref.kcfg_date_format->addItem(i18nc("Date format", "Fancy short date (%1, %2)",
KFormat().formatRelativeDate(QDate::currentDate(), QLocale::ShortFormat),
KFormat().formatRelativeDate(QDate::currentDate().addDays(-10), QLocale::ShortFormat)));
d->uipref.kcfg_date_format->addItem(i18nc("Date format", "Fancy long date (%1, %2)",
KFormat().formatRelativeDate(QDate::currentDate(), QLocale::LongFormat),
KFormat().formatRelativeDate(QDate::currentDate().addDays(-10), QLocale::LongFormat)));
d->uipref.kcfg_date_format->addItem(i18nc("Date format", "ISO date (%1, %2)",
QDate::currentDate().toString(Qt::ISODate),
QDate::currentDate().addDays(-10).toString(Qt::ISODate)));
dialog->addPage(w, skgbasegui_settings::self(), i18nc("Noun", "General"), QStringLiteral("preferences-other"));
// Add plugin in client in right order
int nbplugin = d->m_pluginsList.count();
for (int j = 0; j < nbplugin; ++j) {
SKGInterfacePlugin* pluginInterface = getPluginByIndex(j);
if (pluginInterface != nullptr) {
QWidget* w2 = pluginInterface->getPreferenceWidget();
if (w2 != nullptr) {
auto icon = SKGServices::fromTheme(pluginInterface->icon());
KPageWidgetItem* p = dialog->addPage(w2, pluginInterface->getPreferenceSkeleton(), pluginInterface->title(), icon.name());
if ((p != nullptr) && pluginName == pluginInterface->objectName()) {
dialog->setCurrentPage(p);
}
}
}
}
connect(dialog, &KConfigDialog::settingsChanged, this, &SKGMainPanel::onSettingsChanged);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
// Refresh
refresh();
}
void SKGMainPanel::onSettingsChanged()
{
SKGError err;
SKGTRACEINFUNCRC(1, err) {
int nb = d->m_pluginsList.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Save settings"), err, nb)
// Refresh plugins
for (int i = 0; !err && i < nb; ++i) {
err = getPluginByIndex(i)->savePreferences();
IFOKDO(err, getDocument()->stepForward(i + 1))
}
// Setting for tab position
d->refreshTabPosition();
// Setting for bookmarks modification
{
int option = skgbasegui_settings::update_modified_bookmarks();
if (option == 0) {
// ASK: remove following setting
KMessageBox::enableMessage(QStringLiteral("updateBookmarkOnClose"));
SKGTRACEL(1) << "updateBookmarkOnClose set to ASK" << endl;
} else if (option == 1) {
// ALWAYS: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateBookmarkOnClose"), KMessageBox::Yes);
SKGTRACEL(1) << "updateBookmarkOnClose set to Yes" << endl;
} else {
// NEVER: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateBookmarkOnClose"), KMessageBox::No);
SKGTRACEL(1) << "updateBookmarkOnClose set to No" << endl;
}
}
{
int option = skgbasegui_settings::update_modified_contexts();
if (option == 0) {
// ASK: remove following setting
KMessageBox::enableMessage(QStringLiteral("updateContextOnClose"));
SKGTRACEL(1) << "updateContextOnClose set to ASK" << endl;
} else if (option == 1) {
// ALWAYS: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateContextOnClose"), KMessageBox::Yes);
SKGTRACEL(1) << "updateContextOnClose set to Yes" << endl;
} else {
// NEVER: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateContextOnClose"), KMessageBox::No);
SKGTRACEL(1) << "updateContextOnClose set to No" << endl;
}
}
skgbasegui_settings::self()->load();
}
// Rebuild system tray
d->rebuildSystemTray();
emit settingsChanged();
// Display error
displayErrorMessage(err);
}
void SKGMainPanel::refresh()
{
SKGTRACEINFUNC(1)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Show/hide main widget
bool atLeastOnePageOpened = (d->m_tabWidget->count() > 0);
d->m_tabWidget->setVisible(atLeastOnePageOpened);
if (d->m_mainWidget != nullptr) {
d->m_mainWidget->setVisible(!atLeastOnePageOpened);
}
// Refresh actions
d->m_widgetHavingSelection = qobject_cast(sender());
SKGObjectBase selection = SKGMainPanel::getMainPanel()->getFirstSelectedObject();
int nbSelectedItems = SKGMainPanel::getMainPanel()->getNbSelectedObjects();
bool hasFocus = SKGMainPanel::getMainPanel()->hasSelectionWithFocus();
QString selectedTable = (nbSelectedItems > 0 ? selection.getRealTable() : QLatin1String(""));
for (const auto& actDetails : qAsConst(d->m_registeredGlogalAction)) {
QStringList tables = actDetails.tables;
if (tables.count() == 1 && tables.at(0).startsWith(QLatin1String("query:"))) {
// Dynamic mode
getDocument()->getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"), tables.at(0).right(tables.at(0).count() - 6), tables);
}
bool enabled = (tables.contains(selectedTable) || tables.isEmpty()) &&
(nbSelectedItems >= actDetails.min) &&
(nbSelectedItems <= actDetails.max || actDetails.max == -1) &&
(!actDetails.focus || hasFocus);
if (enabled && nbSelectedItems == 0 && (actDetails.min == 0 || actDetails.min == -1)) {
// Check if a page is opened
SKGTabPage* page = SKGMainPanel::getMainPanel()->currentPage();
if (page != nullptr) {
auto* view = qobject_cast(page->mainWidget());
enabled = (actDetails.min == -1 || view != nullptr);
} else {
enabled = false;
}
}
if (actDetails.action != nullptr) {
actDetails.action->setEnabled(enabled);
}
}
// Refresh plugins
int nb = d->m_pluginsList.count();
for (int i = 0; i < nb; ++i) {
getPluginByIndex(i)->refresh();
}
// Enable addTabeAction
SKGTabPage* toSave = currentPage();
if (d->m_switchPinState != nullptr) {
if ((toSave != nullptr) && toSave->isPin()) {
d->m_switchPinState->setText(i18nc("Noun, user action", "Unpin this page"));
} else {
d->m_switchPinState->setText(i18nc("Noun, user action", "Pin this page"));
}
}
if (d->m_closePageAction != nullptr) {
d->m_closePageAction->setEnabled(atLeastOnePageOpened && (toSave != nullptr) && !toSave->isPin());
}
if (d->m_switchPinState != nullptr) {
d->m_switchPinState->setEnabled(atLeastOnePageOpened);
}
if (d->m_closeAllOtherPagesAction != nullptr) {
d->m_closeAllOtherPagesAction->setEnabled(d->m_tabWidget->count() > 1);
}
if (d->m_reopenLastClosed != nullptr) {
d->m_reopenLastClosed->setEnabled(!d->m_historyClosedPages.isEmpty());
}
if (d->m_saveDefaultStateAction != nullptr) {
d->m_saveDefaultStateAction->setEnabled((toSave != nullptr) && !toSave->getDefaultStateAttribute().isEmpty());
}
if (d->m_resetDefaultStateAction != nullptr) {
d->m_resetDefaultStateAction->setEnabled((toSave != nullptr) && !toSave->getDefaultStateAttribute().isEmpty());
}
if (d->m_overwriteBookmarkStateAction != nullptr) {
d->m_overwriteBookmarkStateAction->setEnabled((toSave != nullptr) && !toSave->getBookmarkID().isEmpty());
}
if (d->m_enableEditorAction != nullptr) {
d->m_enableEditorAction->setEnabled((toSave != nullptr) && toSave->isEditor());
}
if (d->m_zoomSelector != nullptr) {
d->m_zoomSelector->setVisible((toSave != nullptr) && toSave->isZoomable());
if (toSave != nullptr) {
d->m_zoomSelector->setValue(toSave->zoomPosition());
QWidget* zoomWidget = toSave->zoomableWidget();
auto* treeView = qobject_cast(zoomWidget);
if (treeView != nullptr) {
disconnect(treeView, &SKGTreeView::zoomChanged, nullptr, nullptr);
connect(treeView, &SKGTreeView::zoomChanged, this, [ = ](int val) {
d->m_zoomSelector->setValue(val);
});
} else {
auto* webView = qobject_cast(zoomWidget);
if (webView != nullptr) {
disconnect(webView, &SKGWebView::zoomChanged, nullptr, nullptr);
connect(webView, &SKGWebView::zoomChanged, this, [ = ](int val) {
d->m_zoomSelector->setValue(val);
});
}
}
}
}
if (d->m_actLock != nullptr) {
d->m_actLock->setVisible(d->ui.kDockContext->features() == QDockWidget::AllDockWidgetFeatures);
}
if (d->m_actUnLock != nullptr) {
d->m_actUnLock->setVisible(d->ui.kDockContext->features() == QDockWidget::NoDockWidgetFeatures);
}
if (d->m_previousAction != nullptr) {
SKGTabPage::SKGPageHistoryItemList list;
if (toSave != nullptr) {
list = toSave->getPreviousPages();
}
d->m_previousAction->setEnabled(!list.isEmpty());
}
if (d->m_nextAction != nullptr) {
SKGTabPage::SKGPageHistoryItemList list;
if (toSave != nullptr) {
list = toSave->getNextPages();
}
d->m_nextAction->setEnabled(!list.isEmpty());
}
// Set current selection of context
d->ui.kContextList->clearSelection();
if (toSave != nullptr) {
// Get plugin of current page
SKGInterfacePlugin* plugin = getPluginByName(toSave->objectName());
int index = (plugin != nullptr ? plugin->property("contextItem").toInt() : -1);
if (index != -1) {
d->ui.kContextList->setCurrentItem(d->ui.kContextList->item(index));
}
}
// Set window title
QString modified;
if (getDocument()->isFileModified()) {
modified += i18nc("Noun, indicate that current document is modified", " [modified]");
}
if (getDocument()->isReadOnly()) {
modified += i18nc("Noun, indicate that current document is loaded in read only", " [read only]");
}
QString fileName = getDocument()->getCurrentFileName();
if (fileName.isEmpty()) {
fileName = i18nc("Noun, default name for a new document", "Untitled");
} else {
if (fileName != d->m_fileName) {
// The file name has been changed
onClearMessages();
d->m_fileName = fileName;
#ifdef KActivities_FOUND
if (!d->m_fileName.isEmpty()) {
d->m_activityResourceInstance->setUri(d->m_fileName);
}
#endif
}
}
setWindowTitle(i18nc("Title of the main window", "%1%2", fileName, modified));
QApplication::restoreOverrideCursor();
}
SKGTabPage::SKGPageHistoryItem SKGMainPanel::currentPageHistoryItem() const
{
SKGTabPage::SKGPageHistoryItem cpage;
int currentIndex = currentPageIndex();
SKGTabPage* cPage = currentPage();
if (currentIndex >= 0 && (cPage != nullptr)) {
cpage.plugin = cPage->objectName();
SKGInterfacePlugin* plugin = SKGMainPanel::getMainPanel()->getPluginByName(cpage.plugin);
if (plugin != nullptr) {
cpage.name = d->m_tabWidget->tabText(currentIndex);
cpage.icon = plugin->icon();
}
cpage.state = cPage->getState();
cpage.bookmarkID = cPage->getBookmarkID();
}
return cpage;
}
SKGTabPage* SKGMainPanel::openPage(SKGInterfacePlugin* plugin, int index, const QString& parameters, const QString& title, const QString& iID, bool iSetCurrent)
{
SKGTRACEINFUNC(1)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
bool previous = d->m_tabWidget->blockSignals(true);
// If the current page is pin, then open new page
SKGTabPage* cPage = currentPage();
if ((cPage != nullptr) && cPage->isPin()) {
index = -1;
iSetCurrent = true;
}
SKGTabPage* w = nullptr;
SKGTabPage::SKGPageHistoryItemList previousPages;
if (index != -1) {
int currentIndex = currentPageIndex();
if (currentIndex >= 0 && (cPage != nullptr)) {
previousPages = cPage->getPreviousPages();
previousPages.insert(0, currentPageHistoryItem());
d->m_tabWidget->removeTab(currentIndex);
closePage(cPage);
// Repair the history of closed page
if (!d->m_historyClosedPages.isEmpty()) {
d->m_historyClosedPages.removeLast();
}
}
}
if (plugin != nullptr) {
w = plugin->getWidget();
if (w != nullptr) {
// Title
QString title2 = (title.isEmpty() ? plugin->title() : title);
w->setObjectName(plugin->objectName());
if (!iID.isEmpty()) {
w->setBookmarkID(iID);
}
QString param = parameters;
if (param.isEmpty()) {
QString def = w->getDefaultStateAttribute();
if (!def.isEmpty()) {
param = getDocument()->getParameter(def);
}
}
SKGTRACEL(10) << "state=[" << param << "]" << endl;
w->setState(param);
connect(w, &SKGTabPage::selectionChanged, this, &SKGMainPanel::refresh);
connect(w, &SKGTabPage::selectionChanged, this, &SKGMainPanel::selectionChanged);
connect(w, &SKGTabPage::selectionFocusChanged, this, &SKGMainPanel::refresh);
if (index == -1) {
SKGTRACEINFUNC(20)
d->m_tabWidget->addTab(w, SKGServices::fromTheme(plugin->icon()), title2);
if (iSetCurrent) {
d->m_tabWidget->setCurrentWidget(w);
}
} else {
SKGTRACEINFUNC(20)
d->m_tabWidget->insertTab(index, w, SKGServices::fromTheme(plugin->icon()), title2);
if (iSetCurrent) {
d->m_tabWidget->setCurrentWidget(w);
}
w->setPreviousPages(previousPages);
SKGTabPage::SKGPageHistoryItemList empty;
w->setNextPages(empty);
}
SKGTRACEL(1) << "opening plugin [" << plugin->objectName() << ']' << endl;
Q_EMIT pageOpened();
}
} else {
getDocument()->sendMessage(i18nc("An information message", "Impossible to open the page because the plugin was not found"), SKGDocument::Error);
notify(); // Due to sendMessage not in a transaction
}
// Show/hide main widget
bool atLeastOnePageOpened = (d->m_tabWidget->count() > 0);
d->m_tabWidget->setVisible(atLeastOnePageOpened);
if (d->m_mainWidget != nullptr) {
d->m_mainWidget->setVisible(!atLeastOnePageOpened);
}
d->m_tabWidget->blockSignals(previous);
if (iSetCurrent) {
Q_EMIT currentPageChanged();
}
QApplication::restoreOverrideCursor();
return w;
}
int SKGMainPanel::currentPageIndex() const
{
return d->m_tabWidget->currentIndex();
}
SKGTabPage* SKGMainPanel::currentPage() const
{
return qobject_cast< SKGTabPage* >(d->m_tabWidget->currentWidget());
}
int SKGMainPanel::pageIndex(SKGTabPage* iPage) const
{
int nb = countPages();
for (int i = 0; i < nb; ++i) {
if (page(i) == iPage) {
return i;
}
}
return -1;
}
QSplashScreen* SKGMainPanel::splashScreen() const
{
return d->m_splashScreen;
}
int SKGMainPanel::countPages() const
{
return d->m_tabWidget->count();
}
SKGTabPage* SKGMainPanel::page(int iIndex) const
{
return qobject_cast(d->m_tabWidget->widget(iIndex));
}
void SKGMainPanel::setCurrentPage(int iIndex)
{
d->m_tabWidget->setCurrentIndex(iIndex);
}
void SKGMainPanel::onBeforeOpenContext()
{
d->m_middleClick = ((QApplication::mouseButtons() & Qt::MidButton) != 0u);
}
bool SKGMainPanel::openPage(const QUrl& iUrl, bool iNewPage)
{
const QUrl& url(iUrl);
if (url.scheme() == QStringLiteral("skg")) {
// Get plugin
SKGInterfacePlugin* plugin = getPluginByName(url.host());
if (plugin != nullptr) {
// Open special page
SKGTabPage* w = plugin->getWidget();
if (w != nullptr) {
// Create xml
QString path = url.path().remove('/');
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(getDocument()->getParameter(path.isEmpty() ? w->getDefaultStateAttribute() : path));
QDomElement root = doc.documentElement();
if (root.isNull()) {
root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
}
auto params = QUrlQuery(url).queryItems();
for (const auto& p : qAsConst(params)) {
QString value = QUrl::fromPercentEncoding(p.second.toUtf8());
SKGMainPanelPrivate::setAttribute(root, p.first, value);
}
// Open page
openPage(plugin, iNewPage ? -1 : currentPageIndex(), doc.toString());
return true;
}
} else {
// Trigger action
QAction* act = SKGMainPanel::getMainPanel()->getGlobalAction(url.host());
if (act != nullptr) {
auto params = QUrlQuery(url).queryItems();
for (const auto& p : qAsConst(params)) {
QString value = QUrl::fromPercentEncoding(p.second.toUtf8());
act->setProperty(p.first.toUtf8().data(), value);
}
act->trigger();
return true;
}
}
} else {
QDesktopServices::openUrl(iUrl);
return true;
}
displayErrorMessage(SKGError(ERR_ABORT, i18nc("Error message", "Unknown plugin or action [%1] in url [%2]", url.host(), iUrl.toString())));
return false;
}
bool SKGMainPanel::openPage()
{
return openPage(QString());
}
bool SKGMainPanel::openPage(const QString& iUrl, bool iNewPage)
{
// Get the url
QString urlString(iUrl);
if (urlString.isEmpty()) {
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
urlString = act->data().toString();
}
}
return openPage(QUrl(urlString), iNewPage);
}
SKGTabPage* SKGMainPanel::openPage(int iPage, bool iNewPage)
{
SKGTRACEINFUNC(1)
SKGTRACEL(1) << "iPage=" << iPage << endl;
int index = d->ui.kContextList->item(iPage)->data(12).toInt();
return openPage(getPluginByIndex(index), iNewPage ? -1 : currentPageIndex());
}
void SKGMainPanel::onOpenContext()
{
SKGTRACEINFUNC(1)
if (!(QApplication::mouseButtons() & Qt::RightButton)) {
int cpage = -1;
auto* s = qobject_cast(this->sender());
if (s != nullptr) {
cpage = s->data().toInt();
} else {
cpage = d->ui.kContextList->currentRow();
}
if (cpage != -1) {
openPage(cpage, ((QApplication::keyboardModifiers() &Qt::ControlModifier) != 0u) || d->m_middleClick || ((QGuiApplication::mouseButtons() & Qt::MidButton) != 0u));
}
}
d->m_middleClick = false;
}
void SKGMainPanel::switchPinPage(QWidget* iWidget)
{
auto* toSwitch = qobject_cast< SKGTabPage* >(iWidget);
if (toSwitch == nullptr) {
toSwitch = currentPage();
}
if (toSwitch != nullptr) {
toSwitch->setPin(!toSwitch->isPin());
Q_EMIT currentPageChanged();
}
}
void SKGMainPanel::closePageByIndex(int iIndex)
{
QWidget* w = nullptr;
if (iIndex >= 0) {
w = d->m_tabWidget->widget(iIndex);
} else {
w = d->m_tabWidget->currentWidget();
}
closePage(w);
}
void SKGMainPanel::closeCurrentPage()
{
closePage(nullptr);
}
void SKGMainPanel::closePage(QWidget* iWidget, bool iForce)
{
SKGTRACEINFUNC(1)
if (getDocument()->getCurrentTransaction() != 0) {
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
displayMessage(i18nc("Information message", "A page cannot be closed when an operation is running."), SKGDocument::Information);
QApplication::restoreOverrideCursor();
} else {
auto* toRemove = qobject_cast< SKGTabPage* >(iWidget);
if (toRemove == nullptr) {
toRemove = currentPage();
}
if ((toRemove != nullptr) && toRemove->close(iForce)) {
historyPage item;
item.current = currentPageHistoryItem();
item.next = toRemove->getNextPages();
item.previous = toRemove->getPreviousPages();
d->m_historyClosedPages.push_back(item);
delete toRemove;
emit pageClosed();
}
}
// Show/hide main widget
bool atLeastOnePageOpened = (d->m_tabWidget->count() > 0);
d->m_tabWidget->setVisible(atLeastOnePageOpened);
if (d->m_mainWidget != nullptr) {
d->m_mainWidget->setVisible(!atLeastOnePageOpened);
}
if (!atLeastOnePageOpened) {
d->m_fullScreenAction->setChecked(false);
onFullScreen();
}
}
void SKGMainPanel::closeAllPages(bool iForce)
{
SKGTRACEINFUNC(1)
bool previous = d->m_tabWidget->blockSignals(true);
int nb = d->m_tabWidget->count();
for (int i = nb - 1; i >= 0; --i) {
auto* w = qobject_cast< SKGTabPage* >(d->m_tabWidget->widget(i));
if ((w != nullptr) && (iForce || !w->isPin())) {
closePage(w, iForce);
}
}
d->m_tabWidget->blockSignals(previous);
KMessageBox::enableMessage(QStringLiteral("closepinnedpage"));
Q_EMIT currentPageChanged();
}
void SKGMainPanel::closeAllOtherPages(QWidget* iWidget)
{
SKGTRACEINFUNC(1)
bool previous = d->m_tabWidget->blockSignals(true);
QWidget* toKeep = iWidget;
if (toKeep == nullptr) {
toKeep = currentPage();
}
int nb = d->m_tabWidget->count();
for (int i = nb - 1; i >= 0; --i) {
auto* w = qobject_cast< SKGTabPage* >(d->m_tabWidget->widget(i));
if ((w != nullptr) && w != toKeep && !w->isPin()) {
closePage(w);
}
}
d->m_tabWidget->blockSignals(previous);
Q_EMIT currentPageChanged();
}
void SKGMainPanel::saveDefaultState()
{
SKGTRACEINFUNC(1)
SKGError err;
SKGTabPage* toSave = currentPage();
if (toSave != nullptr) {
// Get bookmarks uuid
QString uuid = toSave->getBookmarkID();
// Reset bookmarks uuid to overwrite page state
toSave->setBookmarkID(QLatin1String(""));
// Overwrite
toSave->overwrite(false);
// Set original bookmarks uuid
toSave->setBookmarkID(uuid);
}
}
void SKGMainPanel::overwriteBookmarkState()
{
SKGTRACEINFUNC(1)
SKGError err;
SKGTabPage* toSave = currentPage();
if (toSave != nullptr) {
// Get bookmarks uuid
QString uuid = toSave->getBookmarkID();
if (!uuid.isEmpty()) {
// Overwrite
toSave->overwrite(false);
}
}
}
void SKGMainPanel::resetDefaultState()
{
SKGTRACEINFUNC(1)
SKGError err;
SKGTabPage* toSave = currentPage();
if (toSave != nullptr) {
QString name = toSave->getDefaultStateAttribute();
if (!name.isEmpty()) {
SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Reset default state"), err)
IFOKDO(err, getDocument()->setParameter(name, QStringLiteral("")))
// Refresh panel
IFOK(err) toSave->setState(QLatin1String(""));
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Default state has been reset")))
displayErrorMessage(err);
}
void SKGMainPanel::addTab()
{
SKGTRACEINFUNC(1)
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
openPage(getPluginByName(cPage->objectName()));
}
}
bool SKGMainPanel::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iObject != nullptr) && (iEvent != nullptr) && iEvent->type() == QEvent::Resize) {
auto* rEvent = dynamic_cast(iEvent);
if (rEvent != nullptr) {
QSize newSize = rEvent->size();
// Compute icon size
int s = qMax(qMin(newSize.width() / 5, 64), 16);
d->ui.kContextList->setIconSize(QSize(s, s));
}
}
return KXmlGuiWindow::eventFilter(iObject, iEvent);
}
QStringList SKGMainPanel::getTipsOfDay() const
{
return d->m_tipsOfTheDay;
}
QString SKGMainPanel::getTipOfDay() const
{
auto tips = getTipsOfDay();
return SKGServices::htmlToString(tips.at(qrand() % tips.size()));
}
void SKGMainPanel::notify(int iTransaction)
{
SKGTRACEINFUNC(1)
SKGTRACEL(1) << "iTransaction=" << iTransaction << endl;
// Notify
SKGObjectBase transaction(getDocument(), QStringLiteral("doctransaction"), iTransaction);
if (iTransaction == 0 || transaction.getAttribute(QStringLiteral("t_mode")) != QStringLiteral("R")) {
SKGDocument::SKGMessageList msg;
getDocument()->getMessages(iTransaction, msg, false);
int nbMessages = msg.count();
if (nbMessages != 0) {
// Build list of types
SKGDocument::MessageType maxType = SKGDocument::Positive;
QList listGroups;
listGroups.reserve(nbMessages);
for (int i = 0; i < nbMessages; ++i) {
SKGDocument::SKGMessage m = msg.at(i);
// if the message has an action, it can not be grouped
if (!m.Action.isEmpty()) {
displayMessage(m.Text, m.Type, m.Action);
msg.removeAt(i);
i--;
nbMessages--;
} else {
if (listGroups.isEmpty() || m.Type != listGroups.at(listGroups.count() - 1)) {
listGroups.push_back(m.Type);
}
if (static_cast(m.Type) >= static_cast(maxType)) {
maxType = m.Type;
}
}
}
// Is the number of type acceptable?
bool modeGrouped = false;
if (listGroups.count() > 5 || nbMessages > 20) {
// Too many group ==> simplification
listGroups.clear();
listGroups.push_back(maxType);
modeGrouped = true;
}
// Build message
if (nbMessages != 0) {
QString message;
int indexGroup = 0;
for (int i = 0; i < nbMessages; ++i) {
auto m = msg.at(i);
auto t = m.Type;
if (modeGrouped) {
if (t == SKGDocument::Warning) {
m.Text = i18nc("Warning header", "Warning: %1", m.Text);
} else if (t == SKGDocument::Error) {
m.Text = i18nc("Error header", "Error: %1", m.Text);
} else if (t == SKGDocument::Information) {
m.Text = i18nc("Information header", "Information: %1", m.Text);
} else if (t == SKGDocument::Positive) {
m.Text = i18nc("Done header", "Done: %1", m.Text);
}
}
if (modeGrouped || t == listGroups.at(indexGroup)) {
// Same group
if (!message.isEmpty()) {
message += QStringLiteral("
");
}
message += m.Text;
} else {
// Different group
displayMessage(message, listGroups.at(indexGroup));
// Reset message
message = m.Text;
indexGroup++;
}
}
if (nbMessages < 21 || !SKGServices::getEnvVariable(QStringLiteral("SKGTEST")).isEmpty()) {
// Display a simple notification
/*auto notify = new KNotification(KAboutData::applicationData().componentName() % "_info_event" , this);
notify->setText(message);
notify->sendEvent();*/
displayMessage(message, listGroups.at(indexGroup));
} else {
// Too many message, display a warning panel
KMessageBox::information(SKGMainPanel::getMainPanel(), message, i18nc("Noun", "Notification"));
}
}
}
}
}
void SKGMainPanel::changeEvent(QEvent* e)
{
KXmlGuiWindow::changeEvent(e);
}
QLabel* SKGMainPanel::statusNormalMessage() const
{
return d->m_kNormalMessage;
}
KMessageWidget* SKGMainPanel::getMessageWidget(const QString& iMessage, SKGDocument::MessageType iType, const QString& iAction, bool iAutoKillOnClick)
{
KMessageWidget* msg = nullptr;
if (!iMessage.isEmpty()) {
msg = new KMessageWidget(this);
msg->setText(iMessage);
msg->setMessageType(static_cast(iType));
if (!iAction.isEmpty()) {
QUrl url(iAction);
if (url.scheme() == QStringLiteral("skg")) {
QAction* action = SKGMainPanel::getMainPanel()->getGlobalAction(url.host(), false);
QAction* act = nullptr;
if (action != nullptr) {
// This is an action
act = new QAction(action->icon(), action->text(), SKGMainPanel::getMainPanel());
} else {
// This is a default action
act = new QAction(SKGServices::fromTheme(QStringLiteral("open")), i18nc("Verb", "Open ..."), SKGMainPanel::getMainPanel());
}
act->setData(iAction);
msg->addAction(act);
connect(act, &QAction::triggered, this, [ = ] { openPage(QUrl(qobject_cast< QAction* >(sender())->data().toString()), true);});
if (iAutoKillOnClick) {
connect(act, &QAction::triggered, msg, &KMessageWidget::deleteLater, Qt::QueuedConnection);
}
}
}
}
return msg;
}
KMessageWidget* SKGMainPanel::displayMessage(const QString& iMessage, SKGDocument::MessageType iType, const QString& iAction)
{
// Create message widget
KMessageWidget* msg = nullptr;
if (!iMessage.isEmpty()) {
msg = getMessageWidget(iMessage, iType, iAction, true);
QTimer::singleShot(iType == SKGDocument::Positive ? 5000 : iType == SKGDocument::Information ? 10000 : 20000, Qt::CoarseTimer, msg, &KMessageWidget::deleteLater);
d->m_mainLayout->insertWidget(qMax(d->m_mainLayout->indexOf(d->m_mainWidget) - 1, 0), msg);
// Store message
auto msg2 = getMessageWidget(iMessage, iType, iAction, false);
auto* l = qobject_cast< QVBoxLayout* >(d->ui.kMessagesLayout->layout());
if (l != nullptr) {
l->insertWidget(0, msg2);
}
}
// Emit message
// [Event/error]
// [Event/neutral]
// [Event/positive]
auto notification = new KNotification(iType == SKGDocument::Error ? QStringLiteral("error") :
(iType == SKGDocument::Positive ? QStringLiteral("positive") :
(iType == SKGDocument::Warning ? QStringLiteral("negative") :
QStringLiteral("neutral"))), this);
notification->setText(iMessage);
notification->sendEvent();
// Alert
if (iType == SKGDocument::Error || iType == SKGDocument::Warning) {
qApp->alert(this);
}
return msg;
}
KMessageWidget* SKGMainPanel::displayErrorMessage(const QString& iMessage)
{
QString msg = iMessage;
if (msg.isEmpty()) {
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
msg = act->data().toString();
}
}
return displayMessage(msg, SKGDocument::Error);
}
KMessageWidget* SKGMainPanel::displayErrorMessage(const SKGError& iError, bool iNotifyIfNoError)
{
return displayErrorMessage(iError, nullptr, iNotifyIfNoError);
}
KMessageWidget* SKGMainPanel::displayErrorMessage(const SKGError& iError, QAction* iAction, bool iNotifyIfNoError)
{
SKGTRACEINFUNC(1)
KMessageWidget* msg = nullptr;
SKGMainPanel* parent = SKGMainPanel::getMainPanel();
if (parent != nullptr) {
if (iError) {
// Get the message
msg = parent->displayMessage(iError.getFullMessage(), SKGDocument::Error, iError.getAction());
// Add history action in case of
if (iError.getHistoricalSize() != 0) {
auto history = new QAction(i18nc("Noun", "History"), msg);
history->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-information")));
history->setData(iError.getFullMessageWithHistorical());
msg->addAction(history);
connect(history, &QAction::triggered, parent, [ = ] { parent->displayErrorMessage();});
connect(history, &QAction::triggered, msg, &KMessageWidget::deleteLater, Qt::QueuedConnection);
}
// Add the additional action
if (iAction != nullptr) {
iAction->setParent(msg);
msg->addAction(iAction);
connect(iAction, &QAction::triggered, msg, &KMessageWidget::deleteLater, Qt::QueuedConnection);
}
} else {
if (iNotifyIfNoError) {
auto notification = new KNotification(QStringLiteral("positive"), parent);
notification->setText(iError.getFullMessage());
notification->sendEvent();
}
// Status bar
QLabel* label = parent->statusNormalMessage();
QString message = iError.getMessage();
if ((label != nullptr) && !message.isEmpty()) {
label->setText(message);
}
}
}
return msg;
}
void SKGMainPanel::onCancelCurrentAction()
{
SKGMainPanelPrivate::m_currentActionCanceled = true;
}
void SKGMainPanel::onQuitAction()
{
// Bug 2777697: To be sure that all page modifications are closed
closeAllPages(true);
// Bug 2777697:
qApp->closeAllWindows();
}
QString SKGMainPanel::getSaveFileName(const QString& iStartDir, const QString& iFilter, QWidget* iParent, QString* iCodec)
{
QString fileName;
QString lastCodecUsed = QTextCodec::codecForLocale()->name();
KEncodingFileDialog::Result result = KEncodingFileDialog::getSaveUrlAndEncoding(lastCodecUsed, QUrl(iStartDir), iFilter, iParent);
if (!result.URLs.isEmpty()) {
fileName = result.URLs.at(0).toLocalFile();
}
if (iCodec != nullptr) {
*iCodec = result.encoding;
}
if (fileName.isEmpty()) {
return QLatin1String("");
}
QFile f(fileName);
if (f.exists() && KMessageBox::warningContinueCancel(iParent,
i18nc("Question", "File %1 already exists. Do you really want to overwrite it?", fileName),
i18nc("Question", "Warning"),
KGuiItem(i18nc("Verb", "Save"), SKGServices::fromTheme(QStringLiteral("document-save")))) != KMessageBox::Continue) {
return QLatin1String("");
}
return fileName;
}
void SKGMainPanel::fillWithDistinctValue(
const QList& iWidgets,
SKGDocument* iDoc,
const QString& iTable,
const QString& iAttribut,
const QString& iWhereClause,
bool iAddoperators)
{
SKGTRACEINFUNC(10)
if (iDoc != nullptr) {
{
// Get list
QStringList list;
{
SKGTRACEIN(10, "SKGMainPanel::fillWithDistinctValue-build list " % iTable % " " % iAttribut)
iDoc->getDistinctValues(iTable, iAttribut, iWhereClause, list);
if (!list.isEmpty() && !list.at(0).isEmpty()) {
list.insert(0, QLatin1String(""));
}
// Sorting list
{
SKGTRACEIN(10, "SKGMainPanel::fillWithDistinctValue-build list sorting " % iTable % " " % iAttribut)
// Correction bug 202341 vvv
QCollator c;
std::sort(list.begin(), list.end(), [&](const QString & a, const QString & b) {
return c.compare(a, b) < 0;
});
}
// Add operator
if (iAddoperators) {
list.push_back('=' % i18nc("Key word to modify a string into a field", "capitalize"));
list.push_back('=' % i18nc("Key word to modify a string into a field", "capwords"));
list.push_back('=' % i18nc("Key word to modify a string into a field", "lower"));
list.push_back('=' % i18nc("Key word to modify a string into a field", "trim"));
list.push_back('=' % i18nc("Key word to modify a string into a field", "upper"));
}
}
{
SKGTRACEIN(10, "SKGMainPanel::fillWithDistinctValue-fill " % iTable % " " % iAttribut)
SKGTRACEL(10) << "list.count()=" << list.count() << endl;
for (auto w : qAsConst(iWidgets)) {
auto comp = new QCompleter(list, w);
if (comp != nullptr) {
comp->setCaseSensitivity(Qt::CaseInsensitive);
comp->setFilterMode(Qt::MatchContains);
// Fill completion
auto* kcmb = qobject_cast (w);
if (kcmb != nullptr) {
// Fill combo
kcmb->clear();
kcmb->addItems(list);
- kcmb->setCompleter(comp);
+ if(kcmb->isEditable()) kcmb->setCompleter(comp);
} else {
auto* kline = qobject_cast (w);
if (kline != nullptr) {
kline->setClearButtonEnabled(true);
kline->setCompleter(comp);
}
}
}
}
}
}
}
}
SKGMainPanel* SKGMainPanel::getMainPanel()
{
return SKGMainPanelPrivate::m_mainPanel;
}
void SKGMainPanel::onZoomChanged()
{
SKGTabPage* toSave = currentPage();
if (toSave != nullptr) {
toSave->setZoomPosition(d->m_zoomSelector->value());
d->m_zoomSelector->setValue(toSave->zoomPosition()); // In case of a limit is reached
}
}
void SKGMainPanel::setMainWidget(QWidget* iWidget)
{
if (d->m_mainWidget == nullptr && d->m_mainLayout != nullptr && iWidget != nullptr) {
d->m_mainWidget = iWidget;
d->m_mainLayout->addWidget(d->m_mainWidget);
// Show/hide main widget
d->m_tabWidget->setVisible(d->m_tabWidget->count() != 0);
if (d->m_mainWidget != nullptr) {
d->m_mainWidget->setVisible(!d->m_tabWidget->isVisible());
}
}
}
SKGTabWidget* SKGMainPanel::getTabWidget() const
{
return d->m_tabWidget;
}
void SKGMainPanel::onClearMessages()
{
QLayout* l = d->ui.kMessagesLayout->layout();
if (l != nullptr) {
// Remove all item of the layout
while (l->count() > 1) {
QLayoutItem* child = l->takeAt(0);
if (child != nullptr) {
QWidget* w = child->widget();
delete w;
delete child;
}
}
}
}
void SKGMainPanel::onMigrateToSQLCipher()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (getDocument()->isFileModified()) {
err = SKGError(ERR_ABORT, i18nc("An information message", "The document must be saved to be migrated."), QStringLiteral("skg://file_save"));
} else {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Set parameters
QString input = getDocument()->getCurrentFileName();
QString tmp = input % ".sqlcipher";
QString output = input % "_migrated.skg";
output = output.replace(QStringLiteral(".skg_migrated"), QStringLiteral("_migrated"));
// Build argument
QStringList arg;
arg.push_back(QStringLiteral("--in"));
arg.push_back(input);
arg.push_back(QStringLiteral("--out"));
arg.push_back(tmp);
QString password = getDocument()->getPassword();
if (!password.isEmpty()) {
arg.push_back(QStringLiteral("--param"));
arg.push_back(QStringLiteral("password"));
arg.push_back(QStringLiteral("--value"));
arg.push_back(password);
password = " --param password --value \"" % password % "\"";
}
// Conversion skg => sqlcipher
QString cmd = "skroogeconvert --in \"" % input % "\" --out \"" % tmp % "\"" % password;
int rc = QProcess::execute(QStringLiteral("skroogeconvert"), arg);
if (rc != 0) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", cmd, rc));
} else {
cmd = "skroogeconvert --in \"" % tmp % "\" --out \"" % output % "\"" % password;
arg[1] = tmp;
arg[3] = output;
rc = QProcess::execute(QStringLiteral("skroogeconvert"), arg);
if (rc != 0) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", cmd, rc));
} else {
getDocument()->sendMessage(i18nc("Positive message", "You document has been migrated.\nHere is the new file:\n%1", output), SKGDocument::Positive, "skg://file_open/?filename=" % output);
notify();
}
}
QFile(tmp).remove();
QApplication::restoreOverrideCursor();
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
QString SKGMainPanel::dateToString(QDate iDate)
{
switch (skgbasegui_settings::date_format()) {
case 0:
return QLocale().toString(iDate, QLocale::ShortFormat);
case 1:
return QLocale().toString(iDate, QLocale::LongFormat);
case 3:
return KFormat().formatRelativeDate(iDate, QLocale::LongFormat);
case 4:
return iDate.toString(Qt::ISODate);
case 2:
default:
return KFormat().formatRelativeDate(iDate, QLocale::ShortFormat);
}
}