Warning, file /education/kmplot/kmplot/kmplot.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 KmPlot - a math. function plotter for the KDE-Desktop 0003 0004 SPDX-FileCopyrightText: 2004 Fredrik Edemar <f_edemar@linux.se> 0005 0006 This file is part of the KDE Project. 0007 KmPlot is part of the KDE-EDU Project. 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 0011 */ 0012 0013 #include "kmplot.h" 0014 0015 #include <QFileDialog> 0016 #include <QLabel> 0017 #include <QStatusBar> 0018 #include <QUrl> 0019 0020 #include <KActionCollection> 0021 #include <KConfig> 0022 #include <KConfigGroup> 0023 #include <KDialogJobUiDelegate> 0024 #include <KIO/CommandLauncherJob> 0025 #include <KLocalizedString> 0026 #include <KMessageBox> 0027 #include <KPluginFactory> 0028 #include <KShortcutsDialog> 0029 #include <KStandardAction> 0030 #include <KToggleFullScreenAction> 0031 0032 #include "kmplotadaptor.h" 0033 #include "maindlg.h" 0034 #include "view.h" 0035 #include <kmplotprogress.h> 0036 0037 static QUrl urlFromArg(const QString &arg) 0038 { 0039 return QUrl::fromUserInput(arg, QDir::currentPath(), QUrl::AssumeLocalFile); 0040 } 0041 0042 KmPlot::KmPlot(const QCommandLineParser &parser) 0043 : KParts::MainWindow() 0044 { 0045 setObjectName(QStringLiteral("KmPlot")); 0046 0047 // set the shell's ui resource file 0048 setXMLFile(QStringLiteral("kmplot_shell.rc")); 0049 // then, setup our actions 0050 setupActions(); 0051 0052 // setup the status bar 0053 setupStatusBar(); 0054 0055 // this routine will find and load our Part. it finds the Part by 0056 // name which is a bad idea usually.. but it's alright in this 0057 // case since our Part is made for this Shell 0058 const auto result = 0059 KPluginFactory::instantiatePlugin<KParts::ReadWritePart>(KPluginMetaData(QStringLiteral("kf" QT_STRINGIFY(QT_VERSION_MAJOR) "/parts/kmplotpart")), 0060 this); 0061 if (result) { 0062 m_part = result.plugin; 0063 // tell the KParts::MainWindow that this is indeed the main widget 0064 setCentralWidget(m_part->widget()); 0065 // m_part->widget()->setFocus(); 0066 // and integrate the part's GUI with the shell's 0067 setupGUI(Keys | ToolBar | Save); 0068 createGUI(m_part); 0069 } else { 0070 // if we couldn't find our Part, we exit since the Shell by 0071 // itself can't do anything useful 0072 KMessageBox::error(this, i18n("Could not find KmPlot's part.")); 0073 qApp->quit(); 0074 // we return here, cause qApp->quit() only means "exit the 0075 // next time we enter the event loop... 0076 return; 0077 } 0078 0079 // apply the saved mainwindow settings, if any, and ask the mainwindow 0080 // to automatically save settings if changed: window size, toolbar 0081 // position, icon size, etc. 0082 setAutoSaveSettings(); 0083 { 0084 bool exit = false; 0085 bool first = true; 0086 const auto arguments = parser.positionalArguments(); 0087 for (const QString &arg : arguments) { 0088 QUrl url = urlFromArg(arg); 0089 if (first) { 0090 exit = !load(url); 0091 } else 0092 openFileInNewWindow(url); 0093 } 0094 if (exit) 0095 deleteLater(); // couldn't open the file, and therefore exit 0096 first = false; 0097 } 0098 0099 show(); 0100 0101 new KmPlotAdaptor(this); 0102 QDBusConnection::sessionBus().registerObject(QStringLiteral("/kmplot"), this); 0103 0104 if (parser.isSet(QStringLiteral("function"))) { 0105 QString f = parser.value(QStringLiteral("function")); 0106 QDBusReply<bool> reply = QDBusInterface(QDBusConnection::sessionBus().baseService(), QStringLiteral("/parser"), QStringLiteral("org.kde.kmplot.Parser")) 0107 .call(QDBus::BlockWithGui, QStringLiteral("addFunction"), f, ""); 0108 } 0109 } 0110 0111 KmPlot::~KmPlot() 0112 { 0113 } 0114 0115 void KmPlot::slotUpdateFullScreen(bool checked) 0116 { 0117 if (checked) { 0118 KToggleFullScreenAction::setFullScreen(this, true); 0119 // m_fullScreen->plug( toolBar( "mainToolBar" ) ); deprecated annma 2006-03-01 0120 } else { 0121 KToggleFullScreenAction::setFullScreen(this, false); 0122 // m_fullScreen->unplug( toolBar( "mainToolBar" ) ); deprecated annma 2006-03-01 0123 } 0124 } 0125 0126 bool KmPlot::load(const QUrl &url) 0127 { 0128 m_part->openUrl(url); 0129 if (m_part->url().isEmpty()) 0130 return false; 0131 setWindowTitle(url.toDisplayString()); 0132 return true; 0133 } 0134 0135 void KmPlot::setupActions() 0136 { 0137 KStandardAction::openNew(this, SLOT(fileNew()), actionCollection()); 0138 KStandardAction::open(this, SLOT(fileOpen()), actionCollection()); 0139 KStandardAction::quit(this, SLOT(close()), actionCollection()); 0140 0141 createStandardStatusBarAction(); 0142 setStandardToolBarMenuEnabled(true); 0143 0144 m_fullScreen = KStandardAction::fullScreen(NULL, NULL, this, actionCollection()); 0145 actionCollection()->addAction(QStringLiteral("fullscreen"), m_fullScreen); 0146 connect(m_fullScreen, &KToggleFullScreenAction::toggled, this, &KmPlot::slotUpdateFullScreen); 0147 } 0148 0149 void KmPlot::fileNew() 0150 { 0151 // About this function, the style guide 0152 // says that it should open a new window if the document is _not_ 0153 // in its initial state. This is what we do here... 0154 if (!m_part->url().isEmpty() || isModified()) { 0155 KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(QStringLiteral("kmplot"), this); 0156 job->setUiDelegate(new KDialogJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this)); 0157 job->start(); 0158 } 0159 } 0160 0161 void KmPlot::applyNewToolbarConfig() 0162 { 0163 applyMainWindowSettings(KSharedConfig::openConfig()->group(QString())); 0164 } 0165 0166 void KmPlot::fileOpen() 0167 { 0168 // this slot is called whenever the File->Open menu is selected, 0169 // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar 0170 // button is clicked 0171 QUrl const url = QFileDialog::getOpenFileUrl(this, i18n("Open"), QUrl::fromLocalFile(QDir::currentPath()), i18n("KmPlot Files (*.fkt);;All Files (*)")); 0172 0173 if (!url.isEmpty()) { 0174 // About this function, the style guide 0175 // says that it should open a new window if the document is _not_ 0176 // in its initial state. This is what we do here.. 0177 if (m_part->url().isEmpty() && !isModified()) 0178 load(url); // we open the file in this window... 0179 else 0180 openFileInNewWindow(url); // we open the file in a new window... 0181 } 0182 } 0183 0184 void KmPlot::fileOpen(const QUrl &url) 0185 { 0186 if (!url.isEmpty()) { 0187 // About this function, the style guide 0188 // says that it should open a new window if the document is _not_ 0189 // in its initial state. This is what we do here.. 0190 if (m_part->url().isEmpty() && !isModified()) 0191 load(url); // we open the file in this window... 0192 else 0193 openFileInNewWindow(url); // we open the file in a new window... 0194 } 0195 } 0196 0197 void KmPlot::openFileInNewWindow(const QUrl &url) 0198 { 0199 KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(QStringLiteral("kmplot"), {url.url()}, this); 0200 job->setUiDelegate(new KDialogJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this)); 0201 job->start(); 0202 } 0203 0204 bool KmPlot::isModified() 0205 { 0206 QDBusReply<bool> reply = QDBusInterface(QDBusConnection::sessionBus().baseService(), QStringLiteral("/maindlg"), QStringLiteral("org.kde.kmplot.MainDlg")) 0207 .call(QDBus::BlockWithGui, QStringLiteral("isModified")); 0208 return reply.value(); 0209 } 0210 0211 bool KmPlot::queryClose() 0212 { 0213 return m_part->queryClose(); 0214 } 0215 0216 void KmPlot::setStatusBarText(const QString &text, int id) 0217 { 0218 static_cast<QLabel *>(statusBarLabels.at(id))->setText(text); 0219 } 0220 0221 void KmPlot::setupStatusBar() 0222 { 0223 QStatusBar *statusBar = new QStatusBar(this); 0224 setStatusBar(statusBar); 0225 0226 for (int i = 0; i < View::SectionCount; ++i) { 0227 QLabel *label = new QLabel(statusBar); 0228 label->setFixedHeight(label->fontMetrics().height() + 2); 0229 /// Labels for coordinates should be of fixed width 16 chars to be the same as for good old KmPlot 0230 if (i < 2) { 0231 label->setFixedWidth(label->fontMetrics().boundingRect(QLatin1Char('8')).width() * 16); 0232 label->setAlignment(Qt::AlignCenter); 0233 } else { 0234 label->setAlignment(Qt::AlignLeft); 0235 } 0236 0237 statusBar->addWidget(label); 0238 statusBarLabels.append(label); 0239 } 0240 0241 m_progressBar = new KmPlotProgress(statusBar); 0242 m_progressBar->setMaximumHeight(statusBar->height() - 10); 0243 connect(m_progressBar, &KmPlotProgress::cancelDraw, this, &KmPlot::cancelDraw); 0244 statusBar->addWidget(m_progressBar); 0245 } 0246 0247 void KmPlot::setDrawProgress(double progress) 0248 { 0249 m_progressBar->setProgress(progress); 0250 } 0251 0252 void KmPlot::cancelDraw() 0253 { 0254 QDBusInterface(QDBusConnection::sessionBus().baseService(), QStringLiteral("/kmplot"), QStringLiteral("org.kde.kmplot.KmPlot")) 0255 .call(QDBus::NoBlock, QStringLiteral("stopDrawing")); 0256 }