Commit 110366c7 authored by Shubham  .'s avatar Shubham .
Browse files

Rebase on master

parents 9ecfa3cb 4d97fc8d
......@@ -18,6 +18,8 @@
Copyright (C) 2009 Alexander Rieder <alexanderrieder@gmail.com>
*/
#include <cassert>
#include <KActionCollection>
#include <KConfigDialog>
#include <KConfigGroup>
......@@ -48,8 +50,10 @@
#include "cantor.h"
#include "settings.h"
#include "ui_settings.h"
#include "backendchoosedialog.h"
#include <QMetaObject>
CantorShell::CantorShell() : KParts::MainWindow(), m_part(nullptr)
CantorShell::CantorShell() : KParts::MainWindow(), m_part(nullptr), m_panelHandler(nullptr)
{
// set the shell's ui resource file
setXMLFile(QLatin1String("cantor_shell.rc"));
......@@ -75,6 +79,8 @@ CantorShell::CantorShell() : KParts::MainWindow(), m_part(nullptr)
setDockOptions(QMainWindow::AnimatedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::VerticalTabs);
initPanels();
updateNewSubmenu();
}
......@@ -358,14 +364,14 @@ void CantorShell::addWorksheet(const QString& backendName)
{
connect(part, SIGNAL(setCaption(QString,QIcon)), this, SLOT(setTabCaption(QString,QIcon)));
connect(part, SIGNAL(worksheetSave(QUrl)), this, SLOT(onWorksheetSave(QUrl)));
connect(part, SIGNAL(requestOpenWorksheet(QUrl)), this, SLOT(load(QUrl)));
connect(part, SIGNAL(showHelp(QString)), this, SIGNAL(showHelp(QString)));
m_parts.append(part);
if (backend) // If backend empty (loading worksheet from file), then we connect to signal and wait
m_parts2Backends[part] = backend->id();
else
{
m_parts2Backends[part] = QString();
connect(part, SIGNAL(setBackendName(QString)), this, SLOT(updateBackendForPart(setBackendName)));
connect(part, SIGNAL(setBackendName(QString)), this, SLOT(updateBackendForPart(QString)));
}
int tab = m_tabWidget->addTab(part->widget(), i18n("Session %1", sessionCount++));
m_tabWidget->setCurrentIndex(tab);
......@@ -396,11 +402,7 @@ void CantorShell::addWorksheet(const QString& backendName)
void CantorShell::activateWorksheet(int index)
{
QObject* pluginHandler=m_part->findChild<QObject*>(QLatin1String("PanelPluginHandler"));
if (pluginHandler)
disconnect(pluginHandler,SIGNAL(pluginsChanged()), this, SLOT(updatePanel()));
// Save part state before change worksheet
// Save part panels states before change worksheet
if (m_part)
{
QStringList visiblePanelNames;
......@@ -410,6 +412,16 @@ void CantorShell::activateWorksheet(int index)
visiblePanelNames << doc->objectName();
}
m_pluginsVisibility[m_part] = visiblePanelNames;
Cantor::WorksheetAccessInterface* wa=m_part->findChild<Cantor::WorksheetAccessInterface*>(Cantor::WorksheetAccessInterface::Name);
assert(wa);
PanelStates states;
QList<Cantor::PanelPlugin*> plugins=m_panelHandler.plugins(wa->session());
for(Cantor::PanelPlugin* plugin : plugins)
{
states.insert(plugin->name(), plugin->saveState());
}
m_pluginsStates[m_part] = states;
}
m_part=findPart(m_tabWidget->widget(index));
......@@ -418,8 +430,6 @@ void CantorShell::activateWorksheet(int index)
createGUI(m_part);
updateWindowTitle(m_part->url().fileName());
QObject* pluginHandler=m_part->findChild<QObject*>(QLatin1String("PanelPluginHandler"));
connect(pluginHandler, SIGNAL(pluginsChanged()), this, SLOT(updatePanel()));
updatePanel();
}
else
......@@ -482,6 +492,7 @@ void CantorShell::closeTab(int index)
m_tabWidget->removeTab(index);
bool isCurrectPartClosed = m_part ? widget == m_part->widget() : false;
if(widget->objectName()==QLatin1String("ErrorMessage"))
{
widget->deleteLater();
......@@ -495,13 +506,16 @@ void CantorShell::closeTab(int index)
m_parts.removeAll(part);
m_pluginsVisibility.remove(part);
m_parts2Backends.remove(part);
m_pluginsStates.remove(part);
delete part;
}
}
if (m_tabWidget->count() == 0)
setCaption(QString());
updatePanel();
if (isCurrectPartClosed || m_part == nullptr)
updatePanel();
}
bool CantorShell::reallyClose(bool checkAllParts) {
......@@ -645,35 +659,46 @@ KParts::ReadWritePart* CantorShell::findPart(QWidget* widget)
return nullptr;
}
void CantorShell::updatePanel()
void CantorShell::initPanels()
{
unplugActionList(QLatin1String("view_show_panel_list"));
m_panelHandler.loadPlugins();
//remove all of the previous panels (but do not delete the widgets)
foreach(QDockWidget* dock, m_panels)
QList<Cantor::PanelPlugin*> plugins = m_panelHandler.allPlugins();
foreach(Cantor::PanelPlugin* plugin, plugins)
{
QWidget* widget=dock->widget();
if(widget!=nullptr)
if(plugin==nullptr)
{
widget->setParent(this);
widget->hide();
qDebug()<<"somethings wrong";
continue;
}
dock->deleteLater();
}
m_panels.clear();
QList<QAction*> panelActions;
qDebug()<<"adding panel for "<<plugin->name();
plugin->setParentWidget(this);
plugin->connectToShell(this);
QDockWidget* docker=new QDockWidget(plugin->name(), this);
docker->setObjectName(plugin->name());
docker->setWidget(plugin->widget());
addDockWidget ( Qt::RightDockWidgetArea, docker );
docker->hide();
connect(plugin, &Cantor::PanelPlugin::visibilityRequested, this, &CantorShell::pluginVisibilityRequested);
connect(plugin, &Cantor::PanelPlugin::requestRunCommand, this, &CantorShell::pluginCommandRunRequested);
m_panels.append(docker);
Cantor::PanelPluginHandler* handler=m_part->findChild<Cantor::PanelPluginHandler*>(QLatin1String("PanelPluginHandler"));
if(!handler)
{
qDebug()<<"no PanelPluginHandle found for this part";
return;
}
}
QDockWidget* last=nullptr;
bool isNewWorksheet = !m_pluginsVisibility.contains(m_part);
void CantorShell::updatePanel()
{
unplugActionList(QLatin1String("view_show_panel_list"));
QList<QAction*> panelActions;
bool isNewWorksheet = !m_pluginsVisibility.contains(m_part);
if (isNewWorksheet)
{
KConfigGroup panelStatusGroup(KSharedConfig::openConfig(), QLatin1String("PanelsStatus"));
......@@ -685,50 +710,86 @@ void CantorShell::updatePanel()
}
}
QList<Cantor::PanelPlugin*> plugins=handler->plugins();
foreach(Cantor::PanelPlugin* plugin, plugins)
Cantor::WorksheetAccessInterface* wa = nullptr;
if (m_part)
wa = m_part->findChild<Cantor::WorksheetAccessInterface*>(Cantor::WorksheetAccessInterface::Name);
// Worksheet interface can be missing on m_part clossing (and m_part on this moment can be nullptr)
QList<Cantor::PanelPlugin*> plugins;
if (wa)
{
if(plugin==nullptr)
QDockWidget* last=nullptr;
plugins = m_panelHandler.plugins(wa->session());
for(Cantor::PanelPlugin* plugin : plugins)
{
qDebug()<<"somethings wrong";
continue;
}
qDebug()<<"adding panel for "<<plugin->name();
plugin->setParentWidget(this);
if(plugin==nullptr)
{
qDebug()<<"somethings wrong";
continue;
}
QDockWidget* docker=new QDockWidget(plugin->name(), this);
docker->setObjectName(plugin->name());
docker->setWidget(plugin->widget());
addDockWidget ( Qt::RightDockWidgetArea, docker );
qDebug()<<"adding panel for "<<plugin->name();
// Set visibility for dock from saved info
if (isNewWorksheet)
{
if (plugin->showOnStartup())
docker->show();
if (m_pluginsStates.contains(m_part))
plugin->restoreState(m_pluginsStates[m_part][plugin->name()]);
else
docker->hide();
}
else
{
if (m_pluginsVisibility[m_part].contains(plugin->name()))
docker->show();
else
docker->hide();
}
{
Cantor::PanelPlugin::State initState;
initState.session = wa->session();
plugin->restoreState(initState);
}
if(last!=nullptr)
tabifyDockWidget(last, docker);
last=docker;
QDockWidget* foundDocker = nullptr;
for (QDockWidget* docker : m_panels)
if (docker->objectName() == plugin->name())
{
foundDocker = docker;
break;
}
connect(plugin, &Cantor::PanelPlugin::visibilityRequested, this, &CantorShell::pluginVisibilityRequested);
if (!foundDocker)
{
qDebug() << "something wrong: can't find panel for plugin \"" << plugin->name() << "\"";
continue;
}
m_panels.append(docker);
// Set visibility for dock from saved info
if (isNewWorksheet)
{
if (plugin->showOnStartup())
foundDocker->show();
else
foundDocker->hide();
}
else
{
if (m_pluginsVisibility[m_part].contains(plugin->name()))
foundDocker->show();
else
foundDocker->hide();
}
if(last!=nullptr)
tabifyDockWidget(last, foundDocker);
last = foundDocker;
//Create the action to show/hide this panel
panelActions<<docker->toggleViewAction();
//Create the action to show/hide this panel
panelActions<<foundDocker->toggleViewAction();
}
}
// Hide plugins, which don't supported on current session
QList<Cantor::PanelPlugin*> allPlugins=m_panelHandler.allPlugins();
for(Cantor::PanelPlugin* plugin : allPlugins)
{
if (plugins.indexOf(plugin) == -1)
for (QDockWidget* docker : m_panels)
if (docker->objectName() == plugin->name())
{
docker->hide();
break;
}
}
plugActionList(QLatin1String("view_show_panel_list"), panelActions);
......@@ -769,7 +830,7 @@ void CantorShell::pluginVisibilityRequested()
Cantor::PanelPlugin* plugin = static_cast<Cantor::PanelPlugin*>(sender());
for (QDockWidget* docker: m_panels)
{
if (plugin->name() == docker->windowTitle())
if (plugin->name() == docker->objectName())
{
if (docker->isHidden())
docker->show();
......@@ -812,5 +873,28 @@ void CantorShell::updateBackendForPart(const QString& backend)
{
KParts::ReadWritePart* part=dynamic_cast<KParts::ReadWritePart*>(sender());
if (part && m_parts2Backends.contains(part) && m_parts2Backends[part].isEmpty())
{
m_parts2Backends[part] = backend;
KConfigGroup panelStatusGroup(KSharedConfig::openConfig(), QLatin1String("PanelsStatus"));
if (m_part == part && panelStatusGroup.hasKey(backend))
{
const QStringList& plugins = panelStatusGroup.readEntry(m_parts2Backends[m_part]).split(QLatin1Char('\n'));
m_pluginsVisibility[m_part] = plugins;
for (QDockWidget* docker : m_panels)
if (m_pluginsVisibility[m_part].contains(docker->objectName()))
docker->show();
else
docker->hide();
}
}
}
void CantorShell::pluginCommandRunRequested(const QString& cmd)
{
if (m_part)
{
QMetaObject::invokeMethod(m_part, "runCommand", Qt::QueuedConnection, Q_ARG(QString, cmd));
}
}
......@@ -28,6 +28,9 @@
#include <QStringList>
#include <QMap>
#include "lib/panelpluginhandler.h"
#include "lib/panelplugin.h"
class QTabWidget;
class KRecentFilesAction;
......@@ -39,6 +42,8 @@ namespace KParts{
class ReadWritePart;
}
using PanelStates = QMap<QString, Cantor::PanelPlugin::State>;
/**
* This is the application "Shell". It has a menubar, toolbar, and
* statusbar but relies on the "Part" to do all the real work.
......@@ -74,6 +79,9 @@ protected:
*/
void readProperties(const KConfigGroup &) override;
Q_SIGNALS:
void showHelp(QString);
public Q_SLOTS:
void addWorksheet(const QString& backendName);
/// Use this method/slot to load whatever file/URL you have
......@@ -96,10 +104,12 @@ private Q_SLOTS:
void downloadExamples();
void openExample();
void initPanels();
void updatePanel();
void updateNewSubmenu();
void pluginVisibilityRequested();
void pluginCommandRunRequested(const QString& cmd);
private:
void setupActions();
......@@ -112,6 +122,7 @@ private:
private:
QMap<KParts::ReadWritePart*, QStringList> m_pluginsVisibility;
QMap<KParts::ReadWritePart*, PanelStates> m_pluginsStates;
QList<KParts::ReadWritePart *> m_parts;
QMap<KParts::ReadWritePart*, QString> m_parts2Backends;
KParts::ReadWritePart* m_part;
......@@ -120,6 +131,8 @@ private:
QList<QAction*> m_newBackendActions;
KRecentFilesAction* m_recentProjectsAction;
Cantor::PanelPluginHandler m_panelHandler;
// For better UX: set previous used filter in "Open" action as default filter
QString m_previousFilter;
};
......
......@@ -110,7 +110,6 @@ class WorksheetAccessInterfaceImpl : public Cantor::WorksheetAccessInterface
CantorPart::CantorPart( QWidget *parentWidget, QObject *parent, const QVariantList & args ): KParts::ReadWritePart(parent),
m_searchBar(nullptr),
m_panelHandler(new Cantor::PanelPluginHandler(this)),
m_initProgressDlg(nullptr),
m_showProgressDlg(true),
m_currectZoomAction(nullptr),
......@@ -118,8 +117,6 @@ CantorPart::CantorPart( QWidget *parentWidget, QObject *parent, const QVariantLi
m_statusBarBlocked(false),
m_sessionStatusCounter(0)
{
connect(m_panelHandler, &Cantor::PanelPluginHandler::pluginsChanged, this, &CantorPart::pluginsChanged);
QString backendName;
if(!args.isEmpty())
backendName = args.first().toString();
......@@ -699,7 +696,6 @@ void CantorPart::initialized()
connect(m_worksheet->session(), &Cantor::Session::error, this, &CantorPart::showSessionError);
loadAssistants();
m_panelHandler->setSession(m_worksheet->session());
adjustGuiToSession();
// Don't set modification flag, if we add command entry in empty worksheet
......@@ -779,12 +775,6 @@ void CantorPart::updateCaption()
emit setCaption(filename+QLatin1Char(' ') + i18n("[read-only]"), QIcon());
}
void CantorPart::pluginsChanged()
{
for (auto* plugin : m_panelHandler->plugins())
connect(plugin, &Cantor::PanelPlugin::requestRunCommand, this, &CantorPart::runCommand);
}
void CantorPart::loadAssistants()
{
qDebug()<<"loading assistants...";
......
......@@ -84,7 +84,6 @@ Q_SIGNALS:
void setCaption(const QString& caption, const QIcon& icon);
void showHelp(const QString& help);
void worksheetSave(const QUrl& url);
void requestOpenWorksheet(const QUrl& url);
void setBackendName(const QString& name);
void requestDocumentation(const QString& keyword);
......@@ -133,7 +132,6 @@ protected Q_SLOTS:
void worksheetSessionLoginDone();
void initialized();
void pluginsChanged();
void runCommand(const QString& value);
void runAssistant();
......@@ -169,7 +167,6 @@ private:
WorksheetView *m_worksheetview;
SearchBar *m_searchBar;
QPointer<ScriptEditorWidget> m_scriptEditor;
Cantor::PanelPluginHandler* m_panelHandler;
QProgressDialog* m_initProgressDlg;
bool m_showProgressDlg;
......
......@@ -75,18 +75,24 @@ QString PanelPlugin::name()
return d->name;
}
Session* PanelPlugin::session()
Cantor::PanelPlugin::State Cantor::PanelPlugin::saveState()
{
return d->session;
Cantor::PanelPlugin::State state;
state.session = d->session;
return state;
}
void PanelPlugin::setSession(Session* session)
void Cantor::PanelPlugin::restoreState(const Cantor::PanelPlugin::State& state)
{
d->session=session;
onSessionChanged();
d->session = state.session;
}
Cantor::Session * Cantor::PanelPlugin::session()
{
return d->session;
}
void PanelPlugin::onSessionChanged()
void Cantor::PanelPlugin::connectToShell(QObject* /* cantorShell */)
{
}
......
......@@ -40,6 +40,12 @@ class CANTOR_EXPORT PanelPlugin : public QObject
{
Q_OBJECT
public:
struct State {
Session* session{nullptr};
QVector<QVariant> inners;
};
/**
* Create a new PanelPlugin
* @param parent the parent Object @see QObject
......@@ -91,14 +97,21 @@ class CANTOR_EXPORT PanelPlugin : public QObject
QWidget* parentWidget();
/**
* sets the session this plugin operates on
* Save state of panel to storable form
*
**/
void setSession(Session* session);
virtual State saveState();
/**
* returns the session
* Restore state
* Can contains only session - this is init state from Cantor shell
*/
Session* session();
virtual void restoreState(const State& state);
/**
* For proper connection to Cantor shell. All connections should be done here
*/
virtual void connectToShell(QObject* cantorShell);
/**
* Show on worksheet startup or not
......@@ -106,13 +119,13 @@ class CANTOR_EXPORT PanelPlugin : public QObject
*/
virtual bool showOnStartup();
protected:
Session* session();
Q_SIGNALS:
void requestRunCommand(const QString& cmd);
void visibilityRequested();
protected:
virtual void onSessionChanged();
private:
PanelPluginPrivate* d;
};
......
......@@ -35,14 +35,12 @@ class Cantor::PanelPluginHandlerPrivate
{
public:
QList<Cantor::PanelPlugin*> plugins;
Cantor::Session* session;
};
PanelPluginHandler::PanelPluginHandler( QObject* parent ) : QObject(parent) ,
d(new PanelPluginHandlerPrivate)
{
setObjectName(QStringLiteral("PanelPluginHandler"));
d->session=nullptr;
}
PanelPluginHandler::~PanelPluginHandler()
......@@ -52,34 +50,28 @@ PanelPluginHandler::~PanelPluginHandler()
void PanelPluginHandler::loadPlugins()
{
if(d->session==nullptr)
return;
qDebug()<<"loading panel plugins for session of type "<<d->session->backend()->name();
QStringList panelDirs;
foreach(const QString &dir, QCoreApplication::libraryPaths()){
foreach(const QString &dir, QCoreApplication::libraryPaths()) {
panelDirs << dir + QDir::separator() + QLatin1String("cantor/panels");
}
QPluginLoader loader;
const Cantor::Backend::Capabilities capabilities = d->session->backend()->capabilities();
const QStringList& extensions = d->session->backend()->extensions();
foreach(const QString &dir, panelDirs){
qDebug() << "dir: " << dir;
QStringList panels;
QDir panelDir = QDir(dir);
panels = panelDir.entryList();
foreach (const QString &panel, panels){
foreach (const QString &panel, panels)
{
if (panel==QLatin1String(".") || panel==QLatin1String(".."))
continue;
loader.setFileName(dir + QDir::separator() + panel);
if (!loader.load()){
qDebug() << "Error while loading panel: " << panel;
qDebug() << "Error while loading panel" << panel << ": \"" << loader.errorString() << "\"";
continue;
}
......@@ -89,47 +81,50 @@ void PanelPluginHandler::loadPlugins()
KPluginMetaData info(loader);
plugin->setPluginInfo(info);
bool supported=true;
foreach(const QString& req, plugin->requiredExtensions()){
// FIXME: That req.isEmpty() is there just because Help Panel has req
// empty, returning FALSE when the comparison must to return TRUE.
supported = supported && (extensions.contains(req) || req.isEmpty());
}
// This set session to null inside plugin
Cantor::PanelPlugin::State emptyState;
plugin->restoreState(emptyState);
supported = supported && ( (capabilities & plugin->requiredCapabilities()) == plugin->requiredCapabilities());
if(supported)
{
qDebug() << "plugin " << info.name()<<" is supported, requires extensions " << plugin->requiredExtensions();
d->plugins.append(plugin);
plugin->setSession(d->session);
}else
{
qDebug() << "plugin " << info.name() <<" is not supported";
plugin->deleteLater();
}
d->plugins.append(plugin);
}
}