1 /* GNUPLOT - QtGnuplotWindow.cpp */
2 
3 /*[
4  * Copyright 2009   Jérôme Lodewyck
5  *
6  * Permission to use, copy, and distribute this software and its
7  * documentation for any purpose with or without fee is hereby granted,
8  * provided that the above copyright notice appear in all copies and
9  * that both that copyright notice and this permission notice appear
10  * in supporting documentation.
11  *
12  * Permission to modify the software is granted, but not the right to
13  * distribute the complete modified source code.  Modifications are to
14  * be distributed as patches to the released version.  Permission to
15  * distribute binaries produced by compiling modified sources is granted,
16  * provided you
17  *   1. distribute the corresponding source modifications from the
18  *    released version in the form of a patch file along with the binaries,
19  *   2. add special version identification to distinguish your version
20  *    in addition to the base release version number,
21  *   3. provide your name and address as the primary contact for the
22  *    support of your modified version, and
23  *   4. retain our contact information in regard to use of the base
24  *    software.
25  * Permission to distribute the released version of the source code along
26  * with corresponding source modifications in the form of a patch file is
27  * granted with same provisions 2 through 4 for binary distributions.
28  *
29  * This software is provided "as is" without express or implied warranty
30  * to the extent permitted by applicable law.
31  *
32  *
33  * Alternatively, the contents of this file may be used under the terms of the
34  * GNU General Public License Version 2 or later (the "GPL"), in which case the
35  * provisions of GPL are applicable instead of those above. If you wish to allow
36  * use of your version of this file only under the terms of the GPL and not
37  * to allow others to use your version of this file under the above gnuplot
38  * license, indicate your decision by deleting the provisions above and replace
39  * them with the notice and other provisions required by the GPL. If you do not
40  * delete the provisions above, a recipient may use your version of this file
41  * under either the GPL or the gnuplot license.
42 ]*/
43 
44 #ifdef _WIN32
45 # define WIN32_LEAN_AND_MEAN
46 # include <windows.h>
47 #endif
48 
49 #include "QtGnuplotWindow.h"
50 #include "QtGnuplotWidget.h"
51 #include "QtGnuplotEvent.h"
52 
53 extern "C" {
54 #include "../mousecmn.h"
55 }
56 
57 #include <QtGui>
58 
QtGnuplotWindow(int id,QtGnuplotEventHandler * eventHandler,QWidget * parent)59 QtGnuplotWindow::QtGnuplotWindow(int id, QtGnuplotEventHandler* eventHandler, QWidget* parent)
60 	: QMainWindow(parent)
61 {
62 //	m_ctrl = false;
63 	m_eventHandler = eventHandler;
64 	m_id = id;
65 	m_pid = 0;
66 	setWindowIcon(QIcon(":/images/gnuplot"));
67 
68 //	Setting this attribute causes an error to be reported to the user if a plot
69 //	command is received after a plot command is closed.  Is this good or bad?
70 //		setAttribute(Qt::WA_DeleteOnClose);
71 
72 	// Register as the main event receiver if not already created
73 	if (m_eventHandler == 0)
74 		m_eventHandler = new QtGnuplotEventHandler(this,
75 		                 "qtgnuplot" + QString::number(QCoreApplication::applicationPid()));
76 
77 	// Central widget
78 	m_widget = new QtGnuplotWidget(m_id, m_eventHandler, this);
79 	connect(m_widget, SIGNAL(statusTextChanged(const QString&)), this, SLOT(on_setStatusText(const QString&)));
80 	setCentralWidget(m_widget);
81 
82 	// Bars
83 	m_toolBar = addToolBar("Main tool bar");
84 
85 	m_mouseToolBar = addToolBar("Mouse tool bar");
86 	m_mouseToolBarLabel = new QLabel();
87 	m_mouseToolBar->addWidget(m_mouseToolBarLabel);
88 
89 	m_statusBar = statusBar();
90 
91 	// Actions
92 	QAction* copyToClipboardAction = new QAction(QIcon(":/images/clipboard"   ), tr("Copy to clipboard"), this);
93 	QAction* printAction           = new QAction(QIcon(":/images/print"       ), tr("Print"            ), this);
94 	QAction* exportAction          = new QAction(QIcon(":/images/export"      ), tr("Export"           ), this);
95 	QAction* exportPdfAction       = new QAction(QIcon(":/images/exportPDF"   ), tr("Export to PDF"    ), this);
96 	QAction* exportEpsAction       = new QAction(QIcon(":/images/exportVector"), tr("Export to EPS"    ), this);
97 	QAction* exportSvgAction       = new QAction(QIcon(":/images/exportVector"), tr("Export to SVG"    ), this);
98 	QAction* exportPngAction       = new QAction(QIcon(":/images/exportRaster"), tr("Export to image"  ), this);
99 	QAction* settingsAction        = new QAction(QIcon(":/images/settings"    ), tr("Settings"         ), this);
100 	connect(copyToClipboardAction, SIGNAL(triggered()), m_widget, SLOT(copyToClipboard()));
101 	connect(printAction,           SIGNAL(triggered()), this, SLOT(print()));
102 	connect(exportPdfAction,       SIGNAL(triggered()), this, SLOT(exportToPdf()));
103 	connect(exportEpsAction,       SIGNAL(triggered()), m_widget, SLOT(exportToEps()));
104 	connect(exportSvgAction,       SIGNAL(triggered()), this, SLOT(exportToSvg()));
105 	connect(exportPngAction,       SIGNAL(triggered()), this, SLOT(exportToImage()));
106 	connect(settingsAction,        SIGNAL(triggered()), this, SLOT(showSettingsDialog()));
107 	QMenu* exportMenu = new QMenu(this);
108 	exportMenu->addAction(copyToClipboardAction);
109 	exportMenu->addAction(printAction);
110 	exportMenu->addAction(exportPdfAction);
111 //	exportMenu->addAction(exportEpsAction);
112 	exportMenu->addAction(exportSvgAction);
113 	exportMenu->addAction(exportPngAction);
114 	exportAction->setMenu(exportMenu);
115 	m_toolBar->addAction(exportAction);
116 	QWidget* exportWidget = m_toolBar->widgetForAction(exportAction);
117 	QToolButton* exportButton = qobject_cast<QToolButton*>(exportWidget);
118 	if (exportButton) {
119 		connect(exportAction, SIGNAL(triggered(bool)), exportButton, SLOT(showMenu()));
120 	}
121 	createAction(tr("Replot")       , 'e', ":/images/replot");
122 	createAction(tr("Show grid")    , 'g', ":/images/grid");
123 	createAction(tr("Previous zoom"), 'p', ":/images/zoomPrevious");
124 	createAction(tr("Next zoom")    , 'n', ":/images/zoomNext");
125 	createAction(tr("Autoscale")    , 'a', ":/images/autoscale");
126 	m_toolBar->addAction(settingsAction);
127 
128 	loadSettings();
129 }
130 
~QtGnuplotWindow()131 QtGnuplotWindow::~QtGnuplotWindow()
132 {
133 	saveSettings();
134 }
135 
createAction(const QString & name,int key,const QString & icon)136 void QtGnuplotWindow::createAction(const QString& name, int key, const QString& icon)
137 {
138 	QAction* action = new QAction(QIcon(icon), name, this);
139 	connect(action, SIGNAL(triggered()), this, SLOT(on_keyAction()));
140 	action->setData(key);
141 	m_toolBar->addAction(action);
142 }
143 
on_setStatusText(const QString & status)144 void QtGnuplotWindow::on_setStatusText(const QString& status)
145 {
146 	if (m_mouseToolBar->toggleViewAction()->isChecked())
147 		m_mouseToolBarLabel->setText(status);
148 	if (m_statusBar->isVisible())
149 		m_statusBar->showMessage(status);
150 }
151 
on_keyAction()152 void QtGnuplotWindow::on_keyAction()
153 {
154 	QAction* action = qobject_cast<QAction *>(sender());
155 	m_eventHandler->postTermEvent(GE_keypress, 0, 0, action->data().toInt(), 0, m_widget);
156 }
157 
print()158 void QtGnuplotWindow::print()
159 {
160 	QPrinter printer;
161 	printer.setDocName(tr("gnuplot-qt graph"));
162 	QPrintDialog dialog(&printer, this);
163 	dialog.setOption(QAbstractPrintDialog::PrintPageRange, false);
164 	if (dialog.exec() == QDialog::Accepted)
165 		m_widget->print(printer);
166 }
167 
exportToPdf()168 void QtGnuplotWindow::exportToPdf()
169 {
170 	QString fileName = QFileDialog::getSaveFileName(this, tr("Export to PDF"), "", tr("PDF files (*.pdf)"));
171 	if (fileName.isEmpty())
172 		return;
173 	if (!fileName.endsWith(".pdf", Qt::CaseInsensitive))
174 		fileName += ".pdf";
175 
176 	m_widget->exportToPdf(fileName);
177 }
178 
exportToImage()179 void QtGnuplotWindow::exportToImage()
180 {
181 	/// @todo other image formats supported by Qt
182 	QString fileName = QFileDialog::getSaveFileName(this, tr("Export to Image"), "",
183 	                       tr("Image files (*.png *.bmp)"));
184 	if (fileName.isEmpty())
185 		return;
186 	if (!fileName.endsWith(".png", Qt::CaseInsensitive) &&
187 	    !fileName.endsWith(".bmp", Qt::CaseInsensitive))
188 		fileName += ".png";
189 
190 	m_widget->exportToImage(fileName);
191 }
192 
exportToSvg()193 void QtGnuplotWindow::exportToSvg()
194 {
195 	QString fileName = QFileDialog::getSaveFileName(this, tr("Export to SVG"), "", tr("SVG files (*.svg)"));
196 	if (fileName.isEmpty())
197 		return;
198 	if (!fileName.endsWith(".svg", Qt::CaseInsensitive))
199 		fileName += ".svg";
200 
201 	m_widget->exportToSvg(fileName);
202 }
203 
204 #include "ui_QtGnuplotSettings.h"
205 
loadSettings()206 void QtGnuplotWindow::loadSettings()
207 {
208 	QSettings settings("gnuplot", "qtterminal");
209 	settings.beginGroup("view");
210 	m_widget->loadSettings(settings);
211 	m_statusBarActive = settings.value("statusBarActive", true).toBool();
212 	m_statusBar->setVisible(m_statusBarActive);
213 	bool mouseToolBarActive = settings.value("mouseToolBarActive", false).toBool();
214 	m_mouseToolBar->toggleViewAction()->setChecked(mouseToolBarActive);
215 	m_mouseToolBar->setVisible(mouseToolBarActive);
216 }
217 
saveSettings() const218 void QtGnuplotWindow::saveSettings() const
219 {
220 	QSettings settings("gnuplot", "qtterminal");
221 	settings.beginGroup("view");
222 	m_widget->saveSettings(settings);
223 	settings.setValue("statusBarActive", m_statusBarActive);
224 	settings.setValue("mouseToolBarActive", m_mouseToolBar->toggleViewAction()->isChecked());
225 }
226 
showSettingsDialog()227 void QtGnuplotWindow::showSettingsDialog()
228 {
229 	QDialog* settingsDialog = new QDialog(this);
230 	m_ui = new Ui_settingsDialog();
231 	m_ui->setupUi(settingsDialog);
232 	m_ui->antialiasCheckBox->setCheckState(m_widget->antialias() ? Qt::Checked : Qt::Unchecked);
233 	m_ui->roundedCheckBox->setCheckState(m_widget->rounded() ? Qt::Checked : Qt::Unchecked);
234 	m_ui->ctrlQCheckBox->setCheckState(m_widget->ctrlQ() ? Qt::Checked : Qt::Unchecked);
235 	m_ui->replotOnResizeCheckBox->setCheckState(m_widget->replotOnResize() ? Qt::Checked : Qt::Unchecked);
236 	if (m_statusBar->isVisible())
237 		m_ui->mouseLabelComboBox->setCurrentIndex(0);
238 	else if (m_mouseToolBar->toggleViewAction()->isChecked())
239 		m_ui->mouseLabelComboBox->setCurrentIndex(1);
240 	else if (m_widget->statusLabelActive())
241 		m_ui->mouseLabelComboBox->setCurrentIndex(2);
242 	else
243 		m_ui->mouseLabelComboBox->setCurrentIndex(3);
244 	QPixmap samplePixmap(m_ui->sampleColorLabel->size());
245 	samplePixmap.fill(m_widget->backgroundColor());
246 	m_ui->sampleColorLabel->setPixmap(samplePixmap);
247 	m_chosenBackgroundColor = m_widget->backgroundColor();
248 	connect(m_ui->backgroundButton, SIGNAL(clicked()), this, SLOT(settingsSelectBackgroundColor()));
249 	settingsDialog->exec();
250 
251 	if (settingsDialog->result() == QDialog::Accepted)
252 	{
253 		m_widget->setBackgroundColor(m_chosenBackgroundColor);
254 		m_widget->setAntialias(m_ui->antialiasCheckBox->checkState() == Qt::Checked);
255 		m_widget->setRounded(m_ui->roundedCheckBox->checkState() == Qt::Checked);
256 		m_widget->setCtrlQ(m_ui->ctrlQCheckBox->checkState() == Qt::Checked);
257 		m_widget->setReplotOnResize(m_ui->replotOnResizeCheckBox->checkState() == Qt::Checked);
258 		int statusIndex = m_ui->mouseLabelComboBox->currentIndex();
259 		m_statusBarActive = (statusIndex == 0);
260 		m_statusBar->setVisible(m_statusBarActive);
261 		m_mouseToolBar->toggleViewAction()->setChecked(statusIndex == 1);
262 		m_mouseToolBar->setVisible(statusIndex == 1);
263 		m_widget->setStatusLabelActive(statusIndex == 2);
264 		saveSettings();
265 	}
266 }
267 
settingsSelectBackgroundColor()268 void QtGnuplotWindow::settingsSelectBackgroundColor()
269 {
270 	m_chosenBackgroundColor = QColorDialog::getColor(m_chosenBackgroundColor, this);
271 	QPixmap samplePixmap(m_ui->sampleColorLabel->size());
272 	samplePixmap.fill(m_chosenBackgroundColor);
273 	m_ui->sampleColorLabel->setPixmap(samplePixmap);
274 }
275 
closeEvent(QCloseEvent * event)276 void QtGnuplotWindow::closeEvent(QCloseEvent *event)
277 {
278 	m_eventHandler->postTermEvent(GE_reset, 0, 0, 0, 0, m_widget);
279 	event->accept();
280 }
281 
processEvent(QtGnuplotEventType type,QDataStream & in)282 void QtGnuplotWindow::processEvent(QtGnuplotEventType type, QDataStream& in)
283 {
284 	if (type == GETitle)
285 	{
286 		QString title;
287 		in >> title;
288 		if (title.isEmpty())
289 			title = tr("Gnuplot window ") + QString::number(m_id);
290 		setWindowTitle(title);
291 	}
292 	else if (type == GERaise)
293 	{
294 #ifdef _WIN32
295 		SetForegroundWindow((HWND) winId());
296 		if (isMinimized())
297 			showNormal();
298 #endif
299 		raise();
300 	}
301 	else if (type == GESetCtrl)
302 	{
303 		in >> m_ctrl;
304 		m_widget->setCtrlQ(m_ctrl);
305 	}
306 	else if (type == GESetPosition)
307 	{
308 		QPoint pos;
309 		in >> pos;
310 		move(pos);
311 	}
312 	else if (type == GEPID)
313 		in >> m_pid;
314 	else
315 		m_widget->processEvent(type, in);
316 }
317 
keyPressEvent(QKeyEvent * event)318 void QtGnuplotWindow::keyPressEvent(QKeyEvent* event)
319 {
320 	if ((event->key() == 'Q') && ( !m_widget->ctrlQ() || (QApplication::keyboardModifiers() & Qt::ControlModifier) ))
321 		close();
322 
323 #ifdef _WIN32
324 #if !defined(DISABLE_SPACE_RAISES_CONSOLE)
325 	if ((event->key() == Qt::Key_Space) && ( !m_ctrl || (QApplication::keyboardModifiers() & Qt::ControlModifier) ))
326 	{
327 		AllowSetForegroundWindow(m_pid);
328 		m_eventHandler->postTermEvent(GE_raise, 0, 0, 0, 0, m_widget);
329 	}
330 #endif
331 #endif
332 
333 	QMainWindow::keyPressEvent(event);
334 }
335