kmplot.cpp 8.74 KB
Newer Older
1
2
3
/*
* KmPlot - a math. function plotter for the KDE-Desktop
*
4
* Copyright (C) 2004  Fredrik Edemar <f_edemar@linux.se>
Stephan Kulow's avatar
Stephan Kulow committed
5
*
6
7
8
9
10
11
12
* This file is part of the KDE Project.
* KmPlot is part of the KDE-EDU Project.
*
* 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.
Stephan Kulow's avatar
Stephan Kulow committed
13
*
14
15
16
17
* 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.
Stephan Kulow's avatar
Stephan Kulow committed
18
*
19
20
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
Dirk Mueller's avatar
Dirk Mueller committed
21
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22
23
24
25
26
*
*/

#include "kmplot.h"

27
#include <QFileDialog>
28
29
30
#include <QLabel>
#include <QStatusBar>
#include <QUrl>
31

32
33
34
#include <KActionCollection>
#include <KConfig>
#include <KConfigGroup>
35
#include <KDialogJobUiDelegate>
36
37
38
39
40
41
#include <KLocalizedString>
#include <KMessageBox>
#include <KPluginLoader>
#include <KShortcutsDialog>
#include <KStandardAction>
#include <KToggleFullScreenAction>
42
#include <KIO/CommandLauncherJob>
43
44
45

#include "maindlg.h"
#include <kmplotprogress.h>
46
#include "kmplotadaptor.h"
47
#include "view.h"
48

49
50
51
52
53
54
55
56
57
58
59
60
static QUrl urlFromArg(const QString &arg)
{
#if QT_VERSION >= 0x050400
    return QUrl::fromUserInput(arg, QDir::currentPath(), QUrl::AssumeLocalFile);
#else
    // Logic from QUrl::fromUserInput(QString, QString, UserInputResolutionOptions)
    return (QUrl(arg, QUrl::TolerantMode).isRelative() && !QDir::isAbsolutePath(arg))
           ? QUrl::fromLocalFile(QDir::current().absoluteFilePath(arg))
           : QUrl::fromUserInput(arg);
#endif
}

61
KmPlot::KmPlot( const QCommandLineParser& parser )
62
		: KParts::MainWindow()
63
{
Laurent Montel's avatar
Laurent Montel committed
64
	setObjectName( QStringLiteral("KmPlot") );
Stephan Kulow's avatar
Stephan Kulow committed
65

66
	// set the shell's ui resource file
Laurent Montel's avatar
Laurent Montel committed
67
	setXMLFile(QStringLiteral("kmplot_shell.rc"));
68
69
	// then, setup our actions
	setupActions();
Stephan Kulow's avatar
Stephan Kulow committed
70

71
72
	// setup the status bar
	setupStatusBar();
Stephan Kulow's avatar
Stephan Kulow committed
73

74
75
76
	// this routine will find and load our Part.  it finds the Part by
	// name which is a bad idea usually.. but it's alright in this
	// case since our Part is made for this Shell
77
    KPluginFactory *factory = KPluginLoader(QStringLiteral("kf5/parts/kmplotpart")).factory();
78
79
	if (factory)
	{
80
		// ask the factory to create an instance of the part
81
		// our hands on it
82
        m_part = factory->create<KParts::ReadWritePart>(this);
83
84
85
86
87
88
		if (m_part)
		{
			// tell the KParts::MainWindow that this is indeed the main widget
			setCentralWidget(m_part->widget());
			//m_part->widget()->setFocus();
			// and integrate the part's GUI with the shell's
89
			setupGUI(Keys | ToolBar | Save);
90
91
92
93
94
95
96
			createGUI(m_part);
		}
	}
	else
	{
		// if we couldn't find our Part, we exit since the Shell by
		// itself can't do anything useful
97
		KMessageBox::error(this, i18n("Could not find KmPlot's part."));
98
99
		qApp->quit();
		// we return here, cause qApp->quit() only means "exit the
100
101
102
103
104
105
106
107
108
		// next time we enter the event loop...
		return;
	}

	// apply the saved mainwindow settings, if any, and ask the mainwindow
	// to automatically save settings if changed: window size, toolbar
	// position, icon size, etc.
	setAutoSaveSettings();
	{
109
		bool exit = false;
110
111
112
		bool first = true;
		const auto arguments = parser.positionalArguments();
		for (const QString& arg : arguments)
113
		{
114
			QUrl url = urlFromArg(arg);
115
			if (first)
116
			{
117
				exit = !load(url);
118
			}
119
			else
120
				openFileInNewWindow( url );
121
		}
122
		if (exit)
123
			deleteLater(); // couldn't open the file, and therefore exit
124
		first = false;
125
	}
Stephan Kulow's avatar
Stephan Kulow committed
126

David Saxton's avatar
David Saxton committed
127
	show();
128

129
    new KmPlotAdaptor(this);
Laurent Montel's avatar
Laurent Montel committed
130
    QDBusConnection::sessionBus().registerObject(QStringLiteral("/kmplot"), this);
131

Laurent Montel's avatar
Laurent Montel committed
132
    if ( parser.isSet(QStringLiteral("function")) )
Fredrik Edemar's avatar
Fredrik Edemar committed
133
    {
Laurent Montel's avatar
Laurent Montel committed
134
135
        QString f = parser.value(QStringLiteral("function"));
        QDBusReply<bool> reply = QDBusInterface( QDBusConnection::sessionBus().baseService(), QStringLiteral("/parser"), QStringLiteral("org.kde.kmplot.Parser")).call( QDBus::BlockWithGui, QStringLiteral("addFunction"), f, "" );
Fredrik Edemar's avatar
Fredrik Edemar committed
136
    }
137
138
139
140
141
142
143
144
145
}

KmPlot::~KmPlot()
{}

void KmPlot::slotUpdateFullScreen( bool checked)
{
	if (checked)
	{
Eckhart Wörner's avatar
Eckhart Wörner committed
146
		KToggleFullScreenAction::setFullScreen( this, true );
Anne-Marie Mahfouf's avatar
build    
Anne-Marie Mahfouf committed
147
		//m_fullScreen->plug( toolBar( "mainToolBar" ) ); deprecated annma 2006-03-01
148
149
150
	}
	else
	{
Eckhart Wörner's avatar
Eckhart Wörner committed
151
		KToggleFullScreenAction::setFullScreen( this, false );
Anne-Marie Mahfouf's avatar
build    
Anne-Marie Mahfouf committed
152
		//m_fullScreen->unplug( toolBar( "mainToolBar" ) ); deprecated annma 2006-03-01
153
154
155
	}
}

Inge Wallin's avatar
Inge Wallin committed
156
bool KmPlot::load(const QUrl& url)
157
{
158
159
160
	m_part->openUrl( url );
	if (m_part->url().isEmpty())
		return false;
161
	setWindowTitle(url.toDisplayString());
162
	return true;
163
164
165
166
}

void KmPlot::setupActions()
{
Aaron J. Seigo's avatar
Aaron J. Seigo committed
167
168
	KStandardAction::openNew(this, SLOT(fileNew()), actionCollection());
	KStandardAction::open(this, SLOT(fileOpen()), actionCollection());
Christoph Feck's avatar
Christoph Feck committed
169
	KStandardAction::quit(this, SLOT(close()), actionCollection());
170

171
172
	createStandardStatusBarAction();
	setStandardToolBarMenuEnabled(true);
Stephan Kulow's avatar
Stephan Kulow committed
173

174
	m_fullScreen = KStandardAction::fullScreen( NULL, NULL, this, actionCollection());
Laurent Montel's avatar
Laurent Montel committed
175
	actionCollection()->addAction(QStringLiteral("fullscreen"), m_fullScreen);
Laurent Montel's avatar
Laurent Montel committed
176
	connect(m_fullScreen, &KToggleFullScreenAction::toggled, this, &KmPlot::slotUpdateFullScreen);
177
178
179
180
}

void KmPlot::fileNew()
{
181
	// About this function, the style guide
182
	// says that it should open a new window if the document is _not_
183
	// in its initial state.  This is what we do here...
184
185
186
187
188
	if ( !m_part->url().isEmpty() || isModified() ) {
		KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(QStringLiteral("kmplot"), this);
		job->setUiDelegate(new KDialogJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
		job->start();
	}
189
190
191
192
}

void KmPlot::applyNewToolbarConfig()
{
Laurent Montel's avatar
Laurent Montel committed
193
	applyMainWindowSettings(KSharedConfig::openConfig()->group( QString() ));
194
195
196
197
198
199
200
}

void KmPlot::fileOpen()
{
	// this slot is called whenever the File->Open menu is selected,
	// the Open shortcut is pressed (usually CTRL+O) or the Open toolbar
	// button is clicked
201
	QUrl const url = QFileDialog::getOpenFileUrl(this, i18n( "Open" ), QUrl::fromLocalFile(QDir::currentPath()), i18n( "KmPlot Files (*.fkt);;All Files (*)"));
202
203
204

	if ( !url.isEmpty())
	{
205
		// About this function, the style guide
206
207
208
209
210
211
212
213
214
		// says that it should open a new window if the document is _not_
		// in its initial state.  This is what we do here..
		if ( m_part->url().isEmpty() && !isModified() )
			load( url ); // we open the file in this window...
		else
			openFileInNewWindow(url); // we open the file in a new window...
	}
}

Inge Wallin's avatar
Inge Wallin committed
215
void KmPlot::fileOpen(const QUrl &url)
216
217
218
{
	if ( !url.isEmpty())
	{
219
		// About this function, the style guide
220
221
222
		// says that it should open a new window if the document is _not_
		// in its initial state.  This is what we do here..
		if ( m_part->url().isEmpty() && !isModified() )
223
         load(url); // we open the file in this window...
224
		else
225
         openFileInNewWindow(url); // we open the file in a new window...
Stephan Kulow's avatar
Stephan Kulow committed
226
	}
227
228
229
}


Inge Wallin's avatar
Inge Wallin committed
230
void KmPlot::openFileInNewWindow(const QUrl &url)
231
{
232
233
234
	KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(QStringLiteral("kmplot"), {url.url()}, this);
	job->setUiDelegate(new KDialogJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
	job->start();
235
236
237
238
}

bool KmPlot::isModified()
{
Laurent Montel's avatar
Laurent Montel committed
239
	QDBusReply<bool> reply = QDBusInterface( QDBusConnection::sessionBus().baseService(), QStringLiteral("/maindlg"), QStringLiteral("org.kde.kmplot.MainDlg")).call( QDBus::BlockWithGui, QStringLiteral("isModified") );
David Saxton's avatar
David Saxton committed
240
    return reply.value();
241
242
243
244
}

bool KmPlot::queryClose()
{
245
	return m_part->queryClose();
246
247
248
249
}

void KmPlot::setStatusBarText(const QString &text, int id)
{
250
	static_cast<QLabel *>(statusBarLabels.at(id))->setText(text);
251
252
253
254
255
}


void KmPlot::setupStatusBar()
{
256
	QStatusBar *statusBar = new QStatusBar(this);
Christoph Feck's avatar
Christoph Feck committed
257
258
	setStatusBar(statusBar);

259
260
261
262
263
264
	for (int i = 0; i < View::SectionCount; ++i)
	{
		QLabel *label = new QLabel (statusBar);
		label->setFixedHeight (label->fontMetrics ().height () + 2);
		/// Labels for coordinates should be of fixed width 16 chars to be the same as for good old KmPlot
		if ( i < 2) {
265
			label->setFixedWidth ( label->fontMetrics().boundingRect(QLatin1Char('8')).width() * 16 );
266
267
268
269
270
271
272
273
274
			label->setAlignment( Qt::AlignCenter );
		}
		else {
			label->setAlignment( Qt::AlignLeft );
		}

		statusBar->addWidget (label);
		statusBarLabels.append (label);
	}
Christoph Feck's avatar
Christoph Feck committed
275
276
277

	m_progressBar = new KmPlotProgress( statusBar );
	m_progressBar->setMaximumHeight( statusBar->height()-10 );
Laurent Montel's avatar
Laurent Montel committed
278
	connect(m_progressBar, &KmPlotProgress::cancelDraw, this, &KmPlot::cancelDraw);
Christoph Feck's avatar
Christoph Feck committed
279
	statusBar->addWidget(m_progressBar);
280
281
282
283
284
285
286
287
288
289
290
}


void KmPlot::setDrawProgress( double progress )
{
	m_progressBar->setProgress( progress );
}


void KmPlot::cancelDraw()
{
Laurent Montel's avatar
Laurent Montel committed
291
	QDBusInterface( QDBusConnection::sessionBus().baseService(), QStringLiteral("/kmplot"), QStringLiteral("org.kde.kmplot.KmPlot") ).call( QDBus::NoBlock, QStringLiteral("stopDrawing") );
292
}