mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 01:51:49 +08:00
4481 lines
182 KiB
C++
4481 lines
182 KiB
C++
/*
|
||
Copyright (c) 2008-2018 Jan W. Krieger (<jan@jkrieger.de>, <j.krieger@dkfz.de>), German Cancer Research Center
|
||
|
||
|
||
|
||
This software is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License (LGPL) 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 Lesser General Public License (LGPL) for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
|
||
|
||
/** \file jkqtpbaseplotter.cpp
|
||
* \ingroup jkqtpbaseplotter
|
||
*/
|
||
#include <QFileInfo>
|
||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
|
||
#include <QtGlobal>
|
||
#include <QtWidgets>
|
||
#else
|
||
#include <QtGui>
|
||
#endif
|
||
#include <QSvgGenerator>
|
||
#include <QDebug>
|
||
#include <QElapsedTimer>
|
||
#include <QPrintPreviewWidget>
|
||
#include <QDialog>
|
||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||
#include "jkqtplotter/jkqtpplotsmodel.h"
|
||
#include <QPrinter>
|
||
#include <QPrinterInfo>
|
||
#include <QPrintDialog>
|
||
#include <QGridLayout>
|
||
#include <QCheckBox>
|
||
#include <QDialogButtonBox>
|
||
#include <QApplication>
|
||
#include <QFileDialog>
|
||
#include <QInputDialog>
|
||
#include <QVBoxLayout>
|
||
#ifdef QFWIDLIB_LIBRARY
|
||
# include "qftools.h"
|
||
#endif
|
||
#include "jkqtplotter/jkqtpboxplotelements.h"
|
||
#include "jkqtplotter/jkqtpbarchartelements.h"
|
||
#include "jkqtplotter/jkqtpfilledcurveelements.h"
|
||
#include "jkqtplotter/jkqtpimpulseselements.h"
|
||
|
||
static QString globalUserSettigsFilename="";
|
||
static QString globalUserSettigsPrefix="";
|
||
static QList<JKQtBasePlotter::JKQTPPaintDeviceAdapter*> jkqtpPaintDeviceAdapters;
|
||
static QList<JKQtBasePlotter::JKQTPSaveDataAdapter*> jkqtpSaveDataAdapters;
|
||
|
||
|
||
void initJKQtBasePlotterResources()
|
||
{
|
||
Q_INIT_RESOURCE(jkqtpbaseplotter);
|
||
initJKQtMathTextResources();
|
||
}
|
||
|
||
JKQtBasePlotter::JKQtBasePlotter()
|
||
{
|
||
initJKQtBasePlotterResources();
|
||
}
|
||
|
||
void JKQtBasePlotter::setDefaultJKQtBasePrinterUserSettings(QString userSettigsFilename, QString userSettigsPrefix)
|
||
{
|
||
globalUserSettigsFilename=userSettigsFilename;
|
||
globalUserSettigsPrefix=userSettigsPrefix;
|
||
}
|
||
|
||
void JKQtBasePlotter::registerPaintDeviceAdapter(JKQtBasePlotter::JKQTPPaintDeviceAdapter *adapter)
|
||
{
|
||
jkqtpPaintDeviceAdapters.append(adapter);
|
||
}
|
||
|
||
void JKQtBasePlotter::deregisterPaintDeviceAdapter(JKQtBasePlotter::JKQTPPaintDeviceAdapter *adapter)
|
||
{
|
||
if (jkqtpPaintDeviceAdapters.contains(adapter)) jkqtpPaintDeviceAdapters.removeAll(adapter);
|
||
}
|
||
|
||
bool JKQtBasePlotter::registerSaveDataAdapter(JKQtBasePlotter::JKQTPSaveDataAdapter *adapter)
|
||
{
|
||
if (adapter){
|
||
QString format=adapter->getFilter();
|
||
for (int i=0; i<jkqtpSaveDataAdapters.size(); i++) {
|
||
if (jkqtpSaveDataAdapters[i] && jkqtpSaveDataAdapters[i]->getFilter()==format) {
|
||
return false;
|
||
}
|
||
}
|
||
jkqtpSaveDataAdapters.append(adapter);
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool JKQtBasePlotter::deregisterSaveDataAdapter(JKQtBasePlotter::JKQTPSaveDataAdapter *adapter)
|
||
{
|
||
if (jkqtpSaveDataAdapters.contains(adapter)) jkqtpSaveDataAdapters.removeAll(adapter);
|
||
return true;
|
||
}
|
||
|
||
JKQtBasePlotter::textSizeData JKQtBasePlotter::getTextSizeDetail(const QFont &fm, const QString &text, QPainter& painter)
|
||
{
|
||
return getTextSizeDetail(fm.family(), fm.pointSizeF(), text, painter);
|
||
}
|
||
|
||
JKQtBasePlotter::textSizeData JKQtBasePlotter::getTextSizeDetail(const QString &fontName, double fontSize, const QString &text, QPainter& painter)
|
||
{
|
||
JKQtBasePlotter::textSizeKey dh(fontName, fontSize, text, painter.device());
|
||
if (tbrh.contains(dh)) return tbrh[dh];
|
||
JKQtBasePlotter::textSizeData d;
|
||
mathText.set_fontRoman(fontName);
|
||
mathText.set_fontSize(fontSize);
|
||
mathText.parse(text);
|
||
mathText.getSizeDetail(painter, d.width, d.ascent, d.descent, d.strikeoutPos);
|
||
tbrh[dh]=d;
|
||
//qDebug()<<"+++ textsize hash size: "<<tbrh.size();
|
||
return d;
|
||
}
|
||
|
||
void JKQtBasePlotter::getTextSizeDetail(const QString &fontName, double fontSize, const QString &text, QPainter &painter, double &width, double &ascent, double &descent, double &strikeoutPos)
|
||
{
|
||
JKQtBasePlotter::textSizeData d=getTextSizeDetail(fontName, fontSize, text, painter);
|
||
width=d.width;
|
||
ascent=d.ascent;
|
||
descent=d.descent;
|
||
strikeoutPos=d.strikeoutPos;
|
||
}
|
||
|
||
void JKQtBasePlotter::getTextSizeDetail(const QFont &fm, const QString &text, QPainter &painter, double &width, double &ascent, double &descent, double &strikeoutPos)
|
||
{
|
||
getTextSizeDetail(fm.family(), fm.pointSizeF(), text, painter, width, ascent, descent, strikeoutPos);
|
||
}
|
||
|
||
QSizeF JKQtBasePlotter::getTextSizeSize(const QFont &fm, const QString &text, QPainter &painter)
|
||
{
|
||
return getTextSizeSize(fm.family(), fm.pointSizeF(), text, painter);
|
||
}
|
||
|
||
QSizeF JKQtBasePlotter::getTextSizeSize(const QString &fontName, double fontSize, const QString &text, QPainter &painter)
|
||
{
|
||
JKQtBasePlotter::textSizeData d=getTextSizeDetail(fontName, fontSize, text, painter);
|
||
return QSizeF(d.width, d.ascent+d.descent);
|
||
}
|
||
|
||
|
||
// define this to get timing information about painting on the debug output
|
||
//#define JKQTBP_DEBUGTIMING
|
||
#undef JKQTBP_DEBUGTIMING
|
||
|
||
/**************************************************************************************************************************
|
||
* JKQtPlotterBase
|
||
**************************************************************************************************************************/
|
||
JKQtBasePlotter::JKQtBasePlotter(bool datastore_internal, QObject* parent, JKQTPdatastore* datast):
|
||
QObject(parent), m_plotsModel(nullptr), xAxis(nullptr), yAxis(nullptr)
|
||
{
|
||
|
||
dataColumnsListWidget=nullptr;
|
||
printMagnification=1.0;
|
||
printZoomFactor=1.0;
|
||
printSizeX_Millimeter=1.0;
|
||
printSizeY_Millimeter=1.0;
|
||
paintMagnification=1.0;
|
||
printDoUpdate=true;
|
||
|
||
emitPlotSignals=true;
|
||
masterPlotter=nullptr;
|
||
masterSynchronizeWidth=false;
|
||
masterSynchronizeHeight=false;
|
||
fontSizePrintMultiplier=1;
|
||
lineWidthPrintMultiplier=1;
|
||
fontSizeMultiplier=1;
|
||
lineWidthMultiplier=1;
|
||
userSettigsFilename=globalUserSettigsFilename;
|
||
userSettigsPrefix=globalUserSettigsPrefix;
|
||
currentPrinter=QPrinterInfo::defaultPrinter().printerName();
|
||
|
||
if (datastore_internal) {
|
||
datastore=new JKQTPdatastore();
|
||
datastoreInternal=true;
|
||
} else {
|
||
datastore=datast;
|
||
datastoreInternal=false;
|
||
}
|
||
|
||
xAxis=new JKQTPhorizontalAxis(this);
|
||
yAxis=new JKQTPverticalAxis(this);
|
||
m_plotsModel=new JKQTPPlotsModel(this);
|
||
connect(this, SIGNAL(plotUpdated()), m_plotsModel, SLOT(plotUpdated()));
|
||
|
||
|
||
emitSignals=false;
|
||
|
||
plot_minmaxcoorinate=1e10;
|
||
|
||
|
||
resize(400,300);
|
||
plotWidth=400;
|
||
plotHeight=300;
|
||
initSettings();
|
||
|
||
emitSignals=true;
|
||
|
||
actSavePlot=new QAction(QIcon(":/JKQTPlotter/jkqtp_saveplot.png"), "Save Plot", this);
|
||
actSavePlot->setToolTip("Save plot as image file (PDF, PS; PNG, ...).");
|
||
actSaveData=new QAction(QIcon(":/JKQTPlotter/jkqtp_savedata.png"), "Save Data", this);
|
||
actSaveData->setToolTip("Save Data of the plot as file (CSV, ...).");
|
||
actCopyData=new QAction(QIcon(":/JKQTPlotter/jkqtp_copydata.png"), "Copy Data", this);
|
||
actCopyData->setToolTip("Copy Data of the plot to the clipboard to be pasted into Excel etc.");
|
||
actCopyMatlab=new QAction(QIcon(":/JKQTPlotter/jkqtp_copymatlab.png"), "Copy Data to Matlab", this);
|
||
actCopyMatlab->setToolTip("Copy Data of the plot to the clipboard in Matlab script format.");
|
||
actCopyPixelImage=new QAction(QIcon(":/JKQTPlotter/jkqtp_copyimg.png"), "Copy Image", this);
|
||
actCopyPixelImage->setToolTip("Copy the plot as a pixel image to the clipboard");
|
||
|
||
|
||
actSavePDF=new QAction(QIcon(":/JKQTPlotter/jkqtp_savepdf.png"), "Save P&DF", this);
|
||
actSavePDF->setToolTip("Save as PDF");
|
||
//toolbar->addAction(actSavePDF);
|
||
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
|
||
actSavePS=new QAction(QIcon(":/JKQTPlotter/jkqtp_saveps.png"), "Save P&S", this);
|
||
actSavePS->setToolTip("Save as PostScript");
|
||
//toolbar->addAction(actSavePS);
|
||
#endif
|
||
actSaveSVG=new QAction(QIcon(":/JKQTPlotter/jkqtp_savesvg.png"), "Save S&VG", this);
|
||
actSaveSVG->setToolTip("Save as Scalable Vector Graphics (SVG)");
|
||
//toolbar->addAction(actSaveSVG);
|
||
actSavePix=new QAction(QIcon(":/JKQTPlotter/jkqtp_savepix.png"), "Save &Image", this);
|
||
actSavePix->setToolTip("Save as Pixel Image (PNG, JPEG, TIFF ...)");
|
||
//toolbar->addAction(actSavePix);
|
||
|
||
actPrint=new QAction(QIcon(":/JKQTPlotter/jkqtp_print.png"), "&Print", this);
|
||
actPrint->setToolTip("Print");
|
||
//toolbar->addSeparator();
|
||
actSaveCSV=new QAction(QIcon(":/JKQTPlotter/jkqtp_savecsv.png"), "Save &CSV", this);
|
||
actSaveCSV->setToolTip("Save the data which is used for the plot as Comma Separated Values (CSV)");
|
||
//toolbar->addAction(actSaveCSV);
|
||
//toolbar->addSeparator();
|
||
actZoomAll=new QAction(QIcon(":/JKQTPlotter/jkqtp_zoomall.png"), "Zoom &All", this);
|
||
actZoomAll->setToolTip("Zoom to view all data");
|
||
actZoomIn=new QAction(QIcon(":/JKQTPlotter/jkqtp_zoomin.png"), "Zoom &In", this);
|
||
actZoomIn->setToolTip("Zoom in around the center of the plot");
|
||
actZoomOut=new QAction(QIcon(":/JKQTPlotter/jkqtp_zoomout.png"), "Zoom &Out", this);
|
||
actZoomOut->setToolTip("Zoom out");
|
||
|
||
actShowPlotData=new QAction(QIcon(":/JKQTPlotter/jkqtp_showplotdata.png"), "&Show Plot Data", this);
|
||
actShowPlotData->setToolTip("opens a dialog that contains all data used for the plot in a table.");
|
||
|
||
|
||
|
||
connect(actSavePlot, SIGNAL(triggered()), this, SLOT(saveImage()));
|
||
connect(actSaveData, SIGNAL(triggered()), this, SLOT(saveData()));
|
||
connect(actCopyData, SIGNAL(triggered()), this, SLOT(copyData()));
|
||
connect(actCopyPixelImage, SIGNAL(triggered()), this, SLOT(copyPixelImage()));
|
||
connect(actCopyMatlab, SIGNAL(triggered()), this, SLOT(copyDataMatlab()));
|
||
connect(actShowPlotData, SIGNAL(triggered()), this, SLOT(showPlotData()));
|
||
|
||
connect(actSavePDF, SIGNAL(triggered()), this, SLOT(saveAsPDF()));
|
||
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
|
||
connect(actSavePS, SIGNAL(triggered()), this, SLOT(saveAsPS()));
|
||
#endif
|
||
connect(actSaveSVG, SIGNAL(triggered()), this, SLOT(saveAsSVG()));
|
||
connect(actSavePix, SIGNAL(triggered()), this, SLOT(saveAsPixelImage()));
|
||
|
||
connect(actPrint, SIGNAL(triggered()), this, SLOT(print()));
|
||
connect(actSaveCSV, SIGNAL(triggered()), this, SLOT(saveAsCSV()));
|
||
connect(actZoomAll, SIGNAL(triggered()), this, SLOT(zoomToFit()));
|
||
connect(actZoomIn, SIGNAL(triggered()), this, SLOT(zoomIn()));
|
||
connect(actZoomOut, SIGNAL(triggered()), this, SLOT(zoomOut()));
|
||
|
||
resize(400,300);
|
||
#ifdef USE_XITS_FONTS
|
||
mathText.useXITS();
|
||
#endif
|
||
}
|
||
|
||
JKQtBasePlotter::~JKQtBasePlotter(){
|
||
clearGraphs(false);
|
||
if (datastoreInternal && datastore!=nullptr) delete datastore;
|
||
delete xAxis;
|
||
delete yAxis;
|
||
}
|
||
|
||
void JKQtBasePlotter::setGrid(bool val) {
|
||
xAxis->set_drawGrid(val);
|
||
yAxis->set_drawGrid(val);
|
||
};
|
||
|
||
void JKQtBasePlotter::useExternalDatastore(JKQTPdatastore* newStore){
|
||
if (datastoreInternal && datastore!=nullptr) {
|
||
delete datastore;
|
||
datastore=nullptr;
|
||
}
|
||
datastore=newStore;
|
||
datastoreInternal=false;
|
||
};
|
||
|
||
void JKQtBasePlotter::useAsInternalDatastore(JKQTPdatastore* newStore){
|
||
if (datastoreInternal && datastore!=nullptr) {
|
||
delete datastore;
|
||
datastore=nullptr;
|
||
}
|
||
datastore=newStore;
|
||
datastoreInternal=true;
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::useInternalDatastore(){
|
||
if (!datastoreInternal) {
|
||
datastore=new JKQTPdatastore();
|
||
datastoreInternal=true;
|
||
}
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::forceInternalDatastore(){
|
||
if (datastoreInternal && datastore!=nullptr) {
|
||
delete datastore;
|
||
datastore=nullptr;
|
||
}
|
||
datastore=new JKQTPdatastore();
|
||
datastoreInternal=true;
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::initSettings() {
|
||
useClipping=true;
|
||
//doDrawing=true;
|
||
|
||
maintainAspectRatio=def_maintainAspectRatio=false;
|
||
aspectRatio=def_aspectRatio=1;
|
||
|
||
maintainAxisAspectRatio=def_maintainAxisAspectRatio=false;
|
||
axisAspectRatio=def_axisAspectRatio=1;
|
||
|
||
def_useAntiAliasingForSystem=false; useAntiAliasingForSystem=def_useAntiAliasingForSystem;
|
||
def_useAntiAliasingForGraphs=true; useAntiAliasingForGraphs=def_useAntiAliasingForGraphs;
|
||
def_useAntiAliasingForText=true; useAntiAliasingForText=def_useAntiAliasingForText;
|
||
|
||
gridPrinting=false;
|
||
gridPrintingList.clear();
|
||
gridPrintingCurrentX=0;
|
||
gridPrintingCurrentY=0;
|
||
|
||
|
||
def_plotBorderLeft=5; iplotBorderLeft_nographs=iplotBorderLeft=plotBorderLeft=def_plotBorderLeft;
|
||
def_plotBorderRight=5; iplotBorderRight_nographs=iplotBorderRight=plotBorderRight=def_plotBorderRight;
|
||
def_plotBorderTop=5; iplotBorderTop_nographs=iplotBorderTop=plotBorderTop=def_plotBorderTop;
|
||
def_plotBorderBottom=5; iplotBorderBottom_nographs=iplotBorderBottom=plotBorderBottom=def_plotBorderBottom;
|
||
|
||
//plotWidth=700;
|
||
//plotHeight=150;
|
||
|
||
xAxis->setRange(-10, 10);
|
||
yAxis->setRange(-10, 10);
|
||
|
||
def_keyFont="Arial"; keyFont=def_keyFont;
|
||
def_keyFontSize=9; keyFontSize=def_keyFontSize;
|
||
|
||
|
||
def_keyXOffset=0.5; keyXOffset=def_keyXOffset;
|
||
def_keyYOffset=0.5; keyYOffset=def_keyYOffset;
|
||
def_keyXSeparation=0.75; keyXSeparation=def_keyXSeparation;
|
||
def_keyYSeparation=0.75; keyYSeparation=def_keyYSeparation;
|
||
def_keyFrameColor=QColor("black"); keyFrameColor=def_keyFrameColor;
|
||
def_keyFrameWidth=1; keyFrameWidth=def_keyFrameWidth;
|
||
def_showKeyFrame=true; showKeyFrame=def_showKeyFrame;
|
||
def_keyBackgroundColor=QColor("white"); keyBackgroundColor=def_keyBackgroundColor;
|
||
def_showKey=true; showKey=def_showKey;
|
||
def_key_item_width=20; key_item_width=def_key_item_width;
|
||
def_key_item_height=2.2; key_item_height=def_key_item_height;
|
||
def_key_line_length=3; key_line_length=def_key_line_length;
|
||
def_keyXMargin=0.5; keyXMargin=def_keyXMargin;
|
||
def_keyYMargin=0.5; keyYMargin=def_keyYMargin;
|
||
def_keyPosition=JKQTPkeyInsideTopRight; keyPosition=def_keyPosition;
|
||
def_keyLayout=JKQTPkeyLayoutOneColumn; keyLayout=def_keyLayout;
|
||
def_keyAutosize=true; keyAutosize=def_keyAutosize;
|
||
|
||
def_exportBackgroundColor=QColor("white"); exportBackgroundColor=def_exportBackgroundColor;
|
||
def_backgroundColor=QColor("white"); backgroundColor=def_backgroundColor;
|
||
def_plotBackgroundColor=QColor("white"); plotBackgroundColor=def_plotBackgroundColor;
|
||
def_graphColor=QColor("red"); graphColor=def_graphColor;
|
||
manyGraphsColorCount=15;
|
||
def_manyGraphsColor[0]=graphColor;
|
||
def_manyGraphsColor[1]=QColor("green");
|
||
def_manyGraphsColor[2]=QColor("blue");
|
||
def_manyGraphsColor[3]=QColor("fuchsia");
|
||
def_manyGraphsColor[4]=QColor("darkorange");
|
||
def_manyGraphsColor[5]=QColor("navy");
|
||
def_manyGraphsColor[6]=QColor("firebrick");
|
||
def_manyGraphsColor[7]=QColor("darkgreen");
|
||
def_manyGraphsColor[8]=QColor("darkmagenta");
|
||
def_manyGraphsColor[9]=QColor("darkgreen");
|
||
def_manyGraphsColor[10]=QColor("darkslateblue");
|
||
def_manyGraphsColor[11]=QColor("maroon");
|
||
def_manyGraphsColor[12]=QColor("indianred");
|
||
def_manyGraphsColor[13]=QColor("darkolivegreen");
|
||
def_manyGraphsColor[14]=QColor("mediumpurple");
|
||
def_manyGraphsColor[15]=QColor("darkcyan");
|
||
for (int i=0; i<manyGraphsColorCount; i++) {
|
||
manyGraphsColor[i]=def_manyGraphsColor[i];
|
||
//std::cout<<manyGraphsColor[i].red()<<", "<<manyGraphsColor[i].green()<<", "<<manyGraphsColor[i].blue()<<" ";
|
||
//std::cout<<"init: manyGraphsColor["<<i<<"] = "<<JKQTP_QColor2String(manyGraphsColor[i]).toStdString()<<" = "<<manyGraphsColor[i].name().toStdString()<<std::endl;
|
||
//std::cout<<"init: def_manyGraphsColor["<<i<<"] = "<<JKQTP_QColor2String(def_manyGraphsColor[i]).toStdString()<<" = "<<def_manyGraphsColor[i].name().toStdString()<<std::endl;
|
||
}
|
||
def_manyGraphsStyle[0]=Qt::SolidLine;
|
||
def_manyGraphsStyle[1]=Qt::DashLine;
|
||
def_manyGraphsStyle[2]=Qt::DotLine;
|
||
def_manyGraphsStyle[3]=Qt::DashDotLine;
|
||
def_manyGraphsStyle[4]=Qt::DashDotDotLine;
|
||
for (int i=0; i<=4; i++) { manyGraphsStyle[i]=def_manyGraphsStyle[i]; }
|
||
def_graphWidth=2; graphWidth=def_graphWidth;
|
||
def_CSVdecimalSeparator="."; CSVdecimalSeparator=def_CSVdecimalSeparator;
|
||
def_CSVcommentInitializer="# "; CSVcommentInitializer=def_CSVcommentInitializer;
|
||
|
||
plotLabel="";
|
||
def_plotLabelFontname=plotLabelFontname=def_keyFont;
|
||
def_plotLabelFontSize=plotLabelFontSize=12;
|
||
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
void JKQtBasePlotter::zoomIn(double factor) {
|
||
//std::cout<<(double)event->delta()/120.0<<": "<<factor<<std::endl;
|
||
double xmin=p2x(static_cast<long>(round(static_cast<double>(plotWidth)/2.0-static_cast<double>(plotWidth)/(2.0*factor))));
|
||
double xmax=p2x(static_cast<long>(round(static_cast<double>(plotWidth)/2.0+static_cast<double>(plotWidth)/(2.0*factor))));
|
||
double ymin=p2y(static_cast<long>(round(static_cast<double>(plotHeight)/2.0+static_cast<double>(plotHeight)/(2.0*factor))));
|
||
double ymax=p2y(static_cast<long>(round(static_cast<double>(plotHeight)/2.0-static_cast<double>(plotHeight)/(2.0*factor))));
|
||
|
||
|
||
xAxis->setRange(xmin, xmax);
|
||
yAxis->setRange(ymin, ymax);
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
if (emitSignals) emit zoomChangedLocally(xAxis->getMin(), xAxis->getMax(), yAxis->getMin(), yAxis->getMax(), this);
|
||
}
|
||
|
||
void JKQtBasePlotter::zoom(double nxmin, double nxmax, double nymin, double nymax){
|
||
// only react on double clicks inside event
|
||
double xmin=nxmin;
|
||
double xmax=nxmax;
|
||
double ymin=nymin;
|
||
double ymax=nymax;
|
||
|
||
xAxis->setRange(xmin, xmax);
|
||
yAxis->setRange(ymin, ymax);
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
if (emitSignals) emit zoomChangedLocally(xAxis->getMin(), xAxis->getMax(), yAxis->getMin(), yAxis->getMax(), this);
|
||
}
|
||
void JKQtBasePlotter::resize(int wid, int heigh) {
|
||
widgetWidth=wid;
|
||
widgetHeight=heigh;
|
||
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::setWidth(int wid) {
|
||
widgetWidth=wid;
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::setHeight(int heigh) {
|
||
widgetHeight=heigh;
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveSettings(QSettings& settings, QString group){
|
||
QString g=group+"/";
|
||
if (group.isEmpty()) g="";
|
||
|
||
if (aspectRatio!=def_aspectRatio) settings.setValue(g+"apect_ratio", aspectRatio);
|
||
if (maintainAspectRatio!=def_maintainAspectRatio) settings.setValue(g+"maintain_apect_ratio", maintainAspectRatio);
|
||
if (axisAspectRatio!=def_axisAspectRatio) settings.setValue(g+"axis_apect_ratio", axisAspectRatio);
|
||
if (maintainAxisAspectRatio!=def_maintainAxisAspectRatio) settings.setValue(g+"maintain_axis_apect_ratio", maintainAxisAspectRatio);
|
||
if (CSVdecimalSeparator!=def_CSVdecimalSeparator) settings.setValue(g+"csv_decimal_separator", CSVdecimalSeparator);
|
||
if (CSVcommentInitializer!=def_CSVcommentInitializer) settings.setValue(g+"csv_comment_initializer", CSVcommentInitializer);
|
||
|
||
if (plotBorderLeft!=def_plotBorderLeft) settings.setValue(g+"plot_border_left", plotBorderLeft);
|
||
if (plotBorderRight!=def_plotBorderRight) settings.setValue(g+"plot_border_right", plotBorderRight);
|
||
if (plotBorderTop!=def_plotBorderTop) settings.setValue(g+"plot_border_top", plotBorderTop);
|
||
if (plotBorderBottom!=def_plotBorderBottom) settings.setValue(g+"plot_border_bottom", plotBorderBottom);
|
||
|
||
if (keyXOffset!=def_keyXOffset) settings.setValue(g+"key_xoffset", keyXOffset);
|
||
if (keyYOffset!=def_keyYOffset) settings.setValue(g+"key_yoffset", keyYOffset);
|
||
if (keyXMargin!=def_keyXMargin) settings.setValue(g+"key_xmargin", keyXMargin);
|
||
if (keyYMargin!=def_keyYMargin) settings.setValue(g+"key_ymargin", keyYMargin);
|
||
if (keyXSeparation!=def_keyXSeparation) settings.setValue(g+"key_xseparation", keyXSeparation);
|
||
if (keyYSeparation!=def_keyYSeparation) settings.setValue(g+"key_yseparation", keyYSeparation);
|
||
if (keyFrameColor!=def_keyFrameColor) settings.setValue(g+"key_frame_color", JKQTP_QColor2String(keyFrameColor));
|
||
if (keyFrameWidth!=def_keyFrameWidth) settings.setValue(g+"key_frame_width", keyFrameWidth);
|
||
if (showKeyFrame!=def_showKeyFrame) settings.setValue(g+"show_key_frame", showKeyFrame);
|
||
if (keyBackgroundColor!=def_keyBackgroundColor) settings.setValue(g+"key_background_color", JKQTP_QColor2String(keyBackgroundColor));
|
||
if (showKey!=def_showKey) settings.setValue(g+"show_key", showKey);
|
||
if (keyPosition!=def_keyPosition) settings.setValue(g+"key_position", JKQTPkeyPosition2String(keyPosition));
|
||
if (keyLayout!=def_keyLayout) settings.setValue(g+"key_layout", JKQTPkeyLayout2String(keyLayout));
|
||
|
||
if (useAntiAliasingForSystem!=def_useAntiAliasingForSystem) settings.setValue(g+"use_antialiasing_for_system", useAntiAliasingForSystem);
|
||
if (useAntiAliasingForGraphs!=def_useAntiAliasingForGraphs) settings.setValue(g+"use_antialiasing_for_graphs", useAntiAliasingForGraphs);
|
||
if (useAntiAliasingForText!=def_useAntiAliasingForText) settings.setValue(g+"use_antialiasing_for_text", useAntiAliasingForText);
|
||
|
||
if (backgroundColor!=def_backgroundColor) settings.setValue(g+"background_color", JKQTP_QColor2String(backgroundColor));
|
||
if (exportBackgroundColor!=def_exportBackgroundColor) settings.setValue(g+"exportBackgroundColor", JKQTP_QColor2String(exportBackgroundColor));
|
||
if (plotBackgroundColor!=def_plotBackgroundColor) settings.setValue(g+"plot_background_color", JKQTP_QColor2String(plotBackgroundColor));
|
||
if (graphColor!=def_graphColor) settings.setValue(g+"graph_color", JKQTP_QColor2String(graphColor));
|
||
if (graphWidth!=def_graphWidth) settings.setValue(g+"graph_linewidth", graphWidth);
|
||
|
||
|
||
if (keyFont!=def_keyFont) settings.setValue(g+"key_fontname", keyFont);
|
||
if (keyFontSize!=def_keyFontSize) settings.setValue(g+"key_fontsize", keyFontSize);
|
||
if (key_item_width!=def_key_item_width) settings.setValue(g+"key_item_width", key_item_width);
|
||
if (key_item_height!=def_key_item_height) settings.setValue(g+"key_item_height", key_item_height);
|
||
if (key_line_length!=def_key_line_length) settings.setValue(g+"key_line_width", key_line_length);
|
||
if (keyAutosize!=def_keyAutosize) settings.setValue(g+"key_autosize", keyAutosize);
|
||
|
||
if (plotLabelFontname!=def_plotLabelFontname) settings.setValue(g+"plotLabelFontname", plotLabelFontname);
|
||
if (plotLabelFontSize!=def_plotLabelFontSize) settings.setValue(g+"plotLabelFontSize", plotLabelFontSize);
|
||
|
||
bool palette_changed=false;
|
||
for (int cnt=0; cnt<manyGraphsColorCount; cnt++) {
|
||
if (manyGraphsColor[cnt]!=def_manyGraphsColor[cnt]) {
|
||
palette_changed=true;
|
||
break;
|
||
}
|
||
}
|
||
if (palette_changed) {
|
||
for (int cnt=0; cnt<manyGraphsColorCount; cnt++) {
|
||
settings.setValue(QString(g+"manygraphscolor%1").arg(cnt), JKQTP_QColor2String(manyGraphsColor[cnt]));
|
||
}
|
||
}
|
||
mathText.saveSettings(settings, g+"math_text.");
|
||
|
||
xAxis->saveSettings(settings, g+"xaxis_");
|
||
yAxis->saveSettings(settings, g+"yaxis_");
|
||
|
||
saveUserSettings();
|
||
|
||
}
|
||
|
||
void JKQtBasePlotter::loadUserSettings(QSettings &settings, QString group) {
|
||
currentSaveDirectory=settings.value(group+"currentSaveDirectory", currentSaveDirectory).toString();
|
||
currentFileFormat=settings.value(group+"currentFileFormat", currentFileFormat).toString();
|
||
currentDataFileFormat=settings.value(group+"currentDataFileFormat", currentFileFormat).toString();
|
||
printZoomFactor=settings.value(group+"printZoomFactor", printZoomFactor).toDouble();
|
||
printSizeX_Millimeter=settings.value(group+"printSizeX", printSizeX_Millimeter).toDouble();
|
||
printSizeY_Millimeter=settings.value(group+"printSizeY", printSizeY_Millimeter).toDouble();
|
||
printMagnification=settings.value(group+"printMagnification", printMagnification).toDouble();
|
||
printSetAbsolutePageSize=settings.value(group+"printSetAbsoluteSize", printSetAbsolutePageSize).toBool();
|
||
printAspect=settings.value(group+"printAspect", printAspect).toDouble();
|
||
fontSizePrintMultiplier=settings.value(group+"fontSizePrintMultiplier", fontSizePrintMultiplier).toDouble();
|
||
lineWidthPrintMultiplier=settings.value(group+"lineWidthPrintMultiplier", lineWidthPrintMultiplier).toDouble();
|
||
printKeepAspect=settings.value(group+"printKeepAspect", printKeepAspect).toBool();
|
||
exportUnitInMM=settings.value(group+"exportUnitInMM", exportUnitInMM).toBool();
|
||
currentPrinter=settings.value(group+"printer", currentPrinter).toString();
|
||
settings.beginGroup(group+"selections");
|
||
int count=settings.value("count", 0).toInt();
|
||
getDataColumnsByUserSaved.clear();
|
||
for (int i=0; i<count; i++) {
|
||
settings.beginGroup(QString("item%1").arg(i));
|
||
QString n=settings.value("name", "").toString();
|
||
QStringList item=settings.value("items", QStringList()).toStringList();
|
||
if (!n.isEmpty()) {
|
||
getDataColumnsByUserSaved[n]=item;
|
||
}
|
||
settings.endGroup();
|
||
}
|
||
settings.endGroup();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveUserSettings(QSettings &settings, QString group) {
|
||
settings.setValue(group+"printer", currentPrinter);
|
||
//qDebug()<<settings.fileName()<<group<<currentSaveDirectory<<QDir(currentSaveDirectory).absolutePath();
|
||
settings.setValue(group+"currentSaveDirectory", QDir(currentSaveDirectory).absolutePath());
|
||
settings.setValue(group+"currentFileFormat",currentFileFormat);
|
||
settings.setValue(group+"currentDataFileFormat",currentDataFileFormat);
|
||
settings.setValue(group+"printZoomFactor", printZoomFactor);
|
||
settings.setValue(group+"printSizeX", printSizeX_Millimeter);
|
||
settings.setValue(group+"printSizeY", printSizeY_Millimeter);
|
||
settings.setValue(group+"printMagnification", printMagnification);
|
||
settings.setValue(group+"printSetAbsoluteSize", printSetAbsolutePageSize);
|
||
settings.setValue(group+"printAspect", printAspect);
|
||
settings.setValue(group+"printKeepAspect", printKeepAspect);
|
||
settings.setValue(group+"fontSizePrintMultiplier", fontSizePrintMultiplier);
|
||
settings.setValue(group+"lineWidthPrintMultiplier", lineWidthPrintMultiplier);
|
||
settings.setValue(group+"exportUnitInMM", exportUnitInMM);
|
||
//settings.setValue(group+"", );
|
||
|
||
settings.beginGroup(group+"selections");
|
||
QStringList keys=getDataColumnsByUserSaved.keys();
|
||
settings.setValue("count", keys.size());
|
||
for (int i=0; i<keys.size(); i++) {
|
||
settings.beginGroup(QString("item%1").arg(i));
|
||
settings.setValue("name", keys[i]);
|
||
settings.setValue("items", getDataColumnsByUserSaved[keys[i]]);
|
||
settings.endGroup();
|
||
}
|
||
settings.endGroup();
|
||
}
|
||
|
||
void JKQtBasePlotter::loadSettings(QSettings& settings, QString group){
|
||
QString g=group+"/";
|
||
if (group.isEmpty()) g="";
|
||
|
||
aspectRatio=settings.value(g+"apect_ratio", aspectRatio).toDouble();
|
||
maintainAspectRatio=settings.value(g+"maintain_apect_ratio", maintainAspectRatio).toBool();
|
||
axisAspectRatio=settings.value(g+"axis_apect_ratio", axisAspectRatio).toDouble();
|
||
maintainAxisAspectRatio=settings.value(g+"maintain_axis_apect_ratio", maintainAxisAspectRatio).toBool();
|
||
|
||
|
||
CSVdecimalSeparator=settings.value(g+"csv_decimal_separator", CSVdecimalSeparator).toString();
|
||
CSVcommentInitializer=settings.value(g+"csv_comment_initializer", CSVcommentInitializer).toString();
|
||
|
||
plotBorderLeft=settings.value(g+"plot_border_left", plotBorderLeft).toInt();
|
||
plotBorderRight=settings.value(g+"plot_border_right", plotBorderRight).toInt();
|
||
plotBorderTop=settings.value(g+"plot_border_top", plotBorderTop).toInt();
|
||
plotBorderBottom=settings.value(g+"plot_border_bottom", plotBorderBottom).toInt();
|
||
|
||
|
||
keyXOffset=settings.value(g+"key_xoffset", keyXOffset).toInt();
|
||
keyYOffset=settings.value(g+"key_yoffset", keyYOffset).toInt();
|
||
keyXMargin=settings.value(g+"key_xmargin", keyXMargin).toInt();
|
||
keyYMargin=settings.value(g+"key_ymargin", keyYMargin).toInt();
|
||
keyXSeparation=settings.value(g+"key_xseparation", keyXSeparation).toInt();
|
||
keyYSeparation=settings.value(g+"key_yseparation", keyYSeparation).toInt();
|
||
keyFrameColor=QColor(settings.value(g+"key_frame_color", JKQTP_QColor2String(keyFrameColor)).toString());
|
||
keyFrameWidth=settings.value(g+"key_frame_width", keyFrameWidth).toDouble();
|
||
showKeyFrame=settings.value(g+"show_key_frame", showKeyFrame).toBool();
|
||
keyBackgroundColor=QColor(settings.value(g+"key_background_color", JKQTP_QColor2String(keyBackgroundColor)).toString());
|
||
showKey=settings.value(g+"show_key", showKey).toBool();
|
||
keyPosition=String2JKQTPkeyPosition(settings.value(g+"key_position", JKQTPkeyPosition2String(keyPosition)).toString());
|
||
keyLayout=JKQTPkeyLayoutOneColumn;
|
||
keyLayout=String2JKQTPkeyLayout(settings.value(g+"key_layout", JKQTPkeyLayout2String(keyLayout)).toString());
|
||
|
||
useAntiAliasingForSystem=settings.value(g+"use_antialiasing_for_system", useAntiAliasingForSystem).toBool();
|
||
useAntiAliasingForGraphs=settings.value(g+"use_antialiasing_for_graphs", useAntiAliasingForGraphs).toBool();
|
||
useAntiAliasingForText=settings.value(g+"use_antialiasing_for_text", useAntiAliasingForText).toBool();
|
||
|
||
backgroundColor=QColor(settings.value(g+"background_color", def_backgroundColor).toString());
|
||
exportBackgroundColor=QColor(settings.value(g+"exportBackgroundColor", def_exportBackgroundColor).toString());
|
||
plotBackgroundColor=QColor(settings.value(g+"plot_background_color", JKQTP_QColor2String(plotBackgroundColor)).toString());
|
||
graphColor=QColor(settings.value(g+"graph_color", JKQTP_QColor2String(graphColor)).toString());
|
||
graphWidth=settings.value(g+"graph_linewidth", graphWidth).toDouble();
|
||
|
||
keyFont=settings.value(g+"key_fontname", keyFont).toString();
|
||
keyFontSize=settings.value(g+"key_fontsize", keyFontSize).toInt();
|
||
key_item_width=settings.value(g+"key_item_width", key_item_width).toInt();
|
||
key_item_height=settings.value(g+"key_item_height", key_item_height).toInt();
|
||
key_line_length=settings.value(g+"key_line_width", key_line_length).toInt();
|
||
keyAutosize=settings.value(g+"key_autosize", keyAutosize).toBool();
|
||
|
||
plotLabelFontname=settings.value(g+"plotLabelFontname", plotLabelFontname).toString();
|
||
plotLabelFontSize=settings.value(g+"plotLabelFontSize", plotLabelFontSize).toDouble();
|
||
|
||
int cnt=0;
|
||
|
||
while (settings.contains(QString(g+"manygraphscolor%1").arg(cnt)) && cnt<50) {
|
||
QString col=settings.value(QString(g+"manygraphscolor%1").arg(cnt), "").toString();
|
||
manyGraphsColor[cnt]=QColor(col);
|
||
cnt++;
|
||
//std::cout<<"cnt="<<cnt<<std::endl;
|
||
}
|
||
if (cnt>0) {
|
||
manyGraphsColorCount=cnt;
|
||
}
|
||
|
||
mathText.loadSettings(settings, g+"math_text.");
|
||
#ifdef USE_XITS_FONTS
|
||
mathText.useXITS();
|
||
#endif
|
||
|
||
/*for (int i=0; i<manyGraphsColorCount; i++) {
|
||
std::cout<<"manyGraphsColor["<<i<<"] = "<<JKQTP_QColor2String(manyGraphsColor[i]).toStdString()<<std::endl;
|
||
std::cout<<"def_manyGraphsColor["<<i<<"] = "<<JKQTP_QColor2String(def_manyGraphsColor[i]).toStdString()<<std::endl;
|
||
}*/
|
||
xAxis->loadSettings(settings, g+"xaxis_");
|
||
yAxis->loadSettings(settings, g+"yaxis_");
|
||
|
||
loadUserSettings();
|
||
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
|
||
|
||
void JKQtBasePlotter::setXY(double xminn, double xmaxx, double yminn, double ymaxx){
|
||
xAxis->setRange(xminn, xmaxx);
|
||
yAxis->setRange(yminn, ymaxx);
|
||
if (maintainAxisAspectRatio) {
|
||
double mid=(yAxis->getMax()+yAxis->getMin())/2.0;
|
||
double w=fabs(xmaxx-xminn)/axisAspectRatio;
|
||
yAxis->setRange(mid-w/2.0, mid+w/2.0);
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::setX(double xminn, double xmaxx){
|
||
xAxis->setRange(xminn, xmaxx);
|
||
if (maintainAxisAspectRatio) {
|
||
double mid=(yAxis->getMax()+yAxis->getMin())/2.0;
|
||
double w=fabs(xmaxx-xminn)/axisAspectRatio;
|
||
yAxis->setRange(mid-w/2.0, mid+w/2.0);
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::setY(double yminn, double ymaxx){
|
||
yAxis->setRange(yminn, ymaxx);
|
||
if (maintainAxisAspectRatio) {
|
||
double mid=(xAxis->getMax()+xAxis->getMin())/2.0;
|
||
double w=fabs(ymaxx-yminn)*axisAspectRatio;
|
||
xAxis->setRange(mid-w/2.0, mid+w/2.0);
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::setAbsoluteX(double xminn, double xmaxx) {
|
||
xAxis->setAbsoluteRange(xminn, xmaxx);
|
||
}
|
||
|
||
void JKQtBasePlotter::setAbsoluteY(double yminn, double ymaxx) {
|
||
yAxis->setAbsoluteRange(yminn, ymaxx);
|
||
}
|
||
|
||
void JKQtBasePlotter::setAbsoluteXY(double xminn, double xmaxx, double yminn, double ymaxx) {
|
||
xAxis->setAbsoluteRange(xminn, xmaxx);
|
||
yAxis->setAbsoluteRange(yminn, ymaxx);
|
||
}
|
||
|
||
void JKQtBasePlotter::calcPlotScaling(JKQTPEnhancedPainter& painter){
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaat(QString("JKQtBasePlotter[%1]::calcPlotScaling()").arg(objectName()));
|
||
#endif
|
||
|
||
|
||
if (emitSignals) emit beforePlotScalingRecalculate();
|
||
//qDebug()<<"start JKQtPlotterBase::calcPlotScaling";
|
||
// if the key is plotted outside , then we have to add place for it (i.e. change the plotBorders
|
||
iplotBorderBottom=plotBorderBottom;
|
||
iplotBorderLeft=plotBorderLeft;
|
||
iplotBorderRight=plotBorderRight;
|
||
iplotBorderTop=plotBorderTop;
|
||
iTitleHeight=0;
|
||
|
||
|
||
if (!plotLabel.isEmpty()) {
|
||
/*JKQTmathText mt;
|
||
mt.set_fontSize(plotLabelFontSize*fontSizeMultiplier);
|
||
mt.set_fontRoman(plotLabelFontname);
|
||
#ifdef USE_XITS_FONTS
|
||
mt.useXITS();
|
||
#endif
|
||
mt.parse(plotLabel);
|
||
QSizeF s=mt.getSize(painter);*/
|
||
QSizeF s=getTextSizeSize(plotLabelFontname, plotLabelFontSize*fontSizeMultiplier, plotLabel, painter);
|
||
iplotBorderTop+=s.height()*1.2;
|
||
iTitleHeight=s.height()*1.2;
|
||
|
||
}
|
||
|
||
double keyWidth, keyHeight;
|
||
QFont f=painter.font();
|
||
f.setFamily(keyFont);
|
||
f.setPointSizeF(keyFontSize*fontSizeMultiplier);
|
||
QFontMetricsF kfm(f);
|
||
getKeyExtent(painter, &keyWidth, &keyHeight);
|
||
iplotKeyBorderTop=0;
|
||
iplotKeyBorderBottom=0;
|
||
iplotKeyBorderLeft=0;
|
||
iplotKeyBorderRight=0;
|
||
if (keyPosition==JKQTPkeyOutsideTopRight) {
|
||
iplotKeyBorderTop=keyHeight+2*keyYMargin*kfm.width('X')+ceil(2*keyFrameWidth)+keyYOffset*kfm.width('X')+2;
|
||
iplotBorderTop = iplotBorderTop + iplotKeyBorderTop;
|
||
} else if (keyPosition==JKQTPkeyOutsideTopLeft) {
|
||
iplotKeyBorderTop=keyHeight+2*keyYMargin*kfm.width('X')+ceil(2*keyFrameWidth)+keyYOffset*kfm.width('X')+2;
|
||
iplotBorderTop = iplotBorderTop + iplotKeyBorderTop;
|
||
} else if (keyPosition==JKQTPkeyOutsideLeftTop) {
|
||
iplotKeyBorderLeft=keyWidth+2*keyXMargin*kfm.width('X')+ceil(2*keyFrameWidth)+keyXOffset*kfm.width('X')+2;
|
||
iplotBorderLeft = iplotBorderLeft + iplotKeyBorderLeft;
|
||
} else if (keyPosition==JKQTPkeyOutsideLeftBottom) {
|
||
iplotKeyBorderLeft=keyWidth+2*keyXMargin*kfm.width('X')+ceil(2*keyFrameWidth)+keyXOffset*kfm.width('X')+2;
|
||
iplotBorderLeft = iplotBorderLeft + iplotKeyBorderLeft;
|
||
} else if (keyPosition==JKQTPkeyOutsideBottomRight) {
|
||
iplotKeyBorderBottom=keyHeight+2*keyYMargin*kfm.width('X')+ceil(2*keyFrameWidth)+keyYOffset*kfm.width('X')+2;
|
||
iplotBorderBottom = iplotBorderBottom + iplotKeyBorderBottom;
|
||
} else if (keyPosition==JKQTPkeyOutsideBottomLeft) {
|
||
iplotKeyBorderBottom=keyHeight+2*keyYMargin*kfm.width('X')+ceil(2*keyFrameWidth)+keyYOffset*kfm.width('X')+2;
|
||
iplotBorderBottom = iplotBorderBottom + iplotKeyBorderBottom;
|
||
} else if (keyPosition==JKQTPkeyOutsideRightTop) {
|
||
iplotKeyBorderRight = keyWidth+2*keyXMargin*kfm.width('X')+ceil(2*keyFrameWidth)+keyXOffset*kfm.width('X')+2;
|
||
iplotBorderRight = iplotBorderRight + iplotKeyBorderRight;
|
||
} else if (keyPosition==JKQTPkeyOutsideRightBottom) {
|
||
iplotKeyBorderRight = keyWidth+2*keyXMargin*kfm.width('X')+ceil(2*keyFrameWidth)+keyXOffset*kfm.width('X')+2;
|
||
iplotBorderRight = iplotBorderRight + iplotKeyBorderRight;
|
||
}
|
||
|
||
|
||
|
||
/*if (displayMousePosition) {
|
||
QFontMetrics fm=fontMetrics();
|
||
QString test="<22>Aquator";
|
||
int labelHeight=fm.size(Qt::TextSingleLine, test).height()*1.5;
|
||
//if (mousePosLabel!=nullptr) labelHeight=mousePosLabel->height();
|
||
iplotBorderTop=iplotBorderTop+(labelHeight-plotBorderTop)*1.1;
|
||
}*/
|
||
|
||
// read additional size required for coordinate axes
|
||
QSizeF s=xAxis->getSize1(painter);
|
||
iplotBorderBottom+=s.height();
|
||
s=xAxis->getSize2(painter);
|
||
iplotBorderTop+=s.height();
|
||
|
||
s=yAxis->getSize1(painter);
|
||
iplotBorderLeft+=s.width();
|
||
s=yAxis->getSize2(painter);
|
||
iplotBorderRight+=s.width();
|
||
|
||
iplotBorderTop_nographs=iplotBorderTop;
|
||
iplotBorderLeft_nographs=iplotBorderLeft;
|
||
iplotBorderBottom_nographs=iplotBorderBottom;
|
||
iplotBorderRight_nographs=iplotBorderRight;
|
||
|
||
|
||
|
||
|
||
|
||
// read additional space required by graphs
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
if (graphs[i]->get_visible()) {
|
||
int leftSpace, rightSpace, topSpace, bottomSpace;
|
||
graphs[i]->getOutsideSize(painter, leftSpace, rightSpace, topSpace, bottomSpace);
|
||
iplotBorderBottom+=bottomSpace;
|
||
iplotBorderTop+=topSpace;
|
||
iplotBorderLeft+=leftSpace;
|
||
iplotBorderRight+=rightSpace;
|
||
}
|
||
}
|
||
|
||
//qDebug()<<" end JKQtPlotterBase::calcPlotScaling";
|
||
|
||
|
||
// synchronize to a master-plotter
|
||
if (masterPlotter) {
|
||
if (masterSynchronizeWidth) {
|
||
iplotBorderLeft=masterPlotter->iplotBorderLeft;
|
||
iplotBorderRight=masterPlotter->iplotBorderRight;
|
||
}
|
||
if (masterSynchronizeHeight) {
|
||
iplotBorderTop=masterPlotter->iplotBorderTop;
|
||
iplotBorderBottom=masterPlotter->iplotBorderBottom;
|
||
}
|
||
}
|
||
|
||
// first we calculate the width and height of the plot from the widget dimensions and
|
||
// the supplied border sizes
|
||
plotWidth=widgetWidth/paintMagnification-iplotBorderLeft-iplotBorderRight;
|
||
plotHeight=widgetHeight/paintMagnification-iplotBorderTop-iplotBorderBottom;
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////
|
||
// ENSURE ASPECT RATIO (if activated)
|
||
////////////////////////////////////////////////////////////////////
|
||
if (maintainAspectRatio && (!xAxis->isLogAxis()) && (!xAxis->isLogAxis())) {
|
||
double currRatio=static_cast<double>(plotWidth)/static_cast<double>(plotHeight);
|
||
double newPlotWidth=plotWidth;
|
||
double newPlotHeight=plotHeight;
|
||
double dx=0;
|
||
double dy=0;
|
||
if (currRatio!=aspectRatio) {
|
||
if (aspectRatio>=currRatio) {
|
||
newPlotWidth=aspectRatio*static_cast<double>(plotHeight);
|
||
} else {
|
||
newPlotHeight=static_cast<double>(plotWidth)/aspectRatio;
|
||
}
|
||
dx=plotWidth-newPlotWidth;
|
||
dy=plotHeight-newPlotHeight;
|
||
if (dx<0) {
|
||
newPlotWidth=plotWidth;
|
||
newPlotHeight=static_cast<double>(plotWidth)/aspectRatio;
|
||
} else if (dy<0) {
|
||
newPlotWidth=aspectRatio*static_cast<double>(plotHeight);
|
||
newPlotHeight=plotHeight;
|
||
}
|
||
dx=plotWidth-newPlotWidth;
|
||
dy=plotHeight-newPlotHeight;
|
||
if ((dx<0)||(dy<0)) {
|
||
newPlotWidth=plotWidth;
|
||
newPlotHeight=plotHeight;
|
||
}
|
||
}
|
||
//if (newPlotWidth>widgetWidth-iplotBorderLeft-iplotBorderRight) newPlotWidth=widgetWidth-iplotBorderLeft-iplotBorderRight;
|
||
//if (newPlotHeight>widgetHeight-iplotBorderTop-iplotBorderBottom) newPlotHeight=widgetHeight-iplotBorderTop-iplotBorderBottom;
|
||
dx=plotWidth-newPlotWidth;
|
||
dy=plotHeight-newPlotHeight;
|
||
iplotBorderBottom+=dy/2.0;
|
||
iplotBorderTop+=dy/2.0;
|
||
iplotBorderLeft+=dx/2.0;
|
||
iplotBorderRight+=dx/2.0;
|
||
plotWidth=widgetWidth/paintMagnification-iplotBorderLeft-iplotBorderRight;
|
||
plotHeight=widgetHeight/paintMagnification-iplotBorderTop-iplotBorderBottom;
|
||
}
|
||
|
||
|
||
xAxis->calcPlotScaling(true);
|
||
yAxis->calcPlotScaling(true);
|
||
|
||
////////////////////////////////////////////////////////////////////
|
||
// ENSURE ASPECT RATIO OF PLOT 1x1 PIXELS (if activated)
|
||
////////////////////////////////////////////////////////////////////
|
||
if (maintainAxisAspectRatio && (!xAxis->isLogAxis()) && (!xAxis->isLogAxis())) {
|
||
double cplotWidth=fabs(xAxis->getMax()-xAxis->getMin());
|
||
double newPlotWidth=cplotWidth;
|
||
double xmid=(xAxis->getMax()+xAxis->getMin())/2.0;
|
||
double cplotHeight=fabs(yAxis->getMax()-yAxis->getMin());
|
||
double newPlotHeight=cplotHeight;
|
||
double ymid=(yAxis->getMax()+yAxis->getMin())/2.0;
|
||
double currRatio=fabs(cplotWidth/cplotHeight);
|
||
if (currRatio!=axisAspectRatio) {
|
||
//if (axisAspectRatio<=currRatio) {
|
||
newPlotWidth=axisAspectRatio*cplotHeight;
|
||
//} else {
|
||
// newPlotHeight=cplotWidth/axisAspectRatio;
|
||
//}
|
||
}
|
||
xAxis->setRange(xmid-newPlotWidth/2.0, xmid+newPlotWidth/2.0);
|
||
yAxis->setRange(ymid-newPlotHeight/2.0, ymid+newPlotHeight/2.0);
|
||
xAxis->calcPlotScaling(true);
|
||
yAxis->calcPlotScaling(true);
|
||
}
|
||
|
||
|
||
if (emitPlotSignals) emit plotScalingRecalculated();
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::plotSystemGrid(JKQTPEnhancedPainter& painter) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot("JKQtBasePlotter::plotSystemGrid");
|
||
#endif
|
||
//qDebug()<<"start JKQtPlotterBase::plotSystemGrid";
|
||
xAxis->drawGrids(painter);
|
||
yAxis->drawGrids(painter);
|
||
//qDebug()<<" end JKQtPlotterBase::plotSystemGrid";
|
||
}
|
||
|
||
void JKQtBasePlotter::plotSystemXAxis(JKQTPEnhancedPainter& painter) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot("JKQtBasePlotter::plotSystemXAxis");
|
||
#endif
|
||
//qDebug()<<"start JKQtPlotterBase::plotSystemXAxis";
|
||
xAxis->drawAxes(painter);
|
||
//qDebug()<<" end JKQtPlotterBase::plotSystemXAxis";
|
||
}
|
||
|
||
void JKQtBasePlotter::plotSystemYAxis(JKQTPEnhancedPainter& painter) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot("JKQtBasePlotter::plotSystemYAxis");
|
||
#endif
|
||
//qDebug()<<"start JKQtPlotterBase::plotSystemYAxis";
|
||
yAxis->drawAxes(painter);
|
||
//qDebug()<<" end JKQtPlotterBase::plotSystemYAxis";
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
JKQtBasePlotter::JKQTPPen JKQtBasePlotter::getPlotStyle(int i) const{
|
||
int colorI=-1;
|
||
int styleI=0;
|
||
for (int k=0; k<=i; k++) {
|
||
colorI++;
|
||
if (colorI>=manyGraphsColorCount) {
|
||
styleI++;
|
||
colorI=0;
|
||
if (styleI>=5) styleI=0;
|
||
}
|
||
}
|
||
JKQTPPen p;
|
||
//std::cout<<"plotstyle "<<i<<std::endl;
|
||
//std::cout<<"color "<<colorI<<std::endl;
|
||
//std::cout<<"style "<<styleI<<std::endl;
|
||
p.setColor(manyGraphsColor[colorI]);
|
||
p.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, graphWidth));
|
||
p.setStyle(manyGraphsStyle[styleI]);
|
||
return p;
|
||
}
|
||
|
||
int JKQtBasePlotter::getNextStyle() {
|
||
int res=0;
|
||
while (usedStyles.contains(res)) res++;
|
||
//std::cout<<res<<std::endl;
|
||
usedStyles.push_back(res);
|
||
return res;
|
||
};
|
||
|
||
void JKQtBasePlotter::plotKey(JKQTPEnhancedPainter& painter) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot("JKQtBasePlotter::plotKey");
|
||
#endif
|
||
//qDebug()<<"start JKQtPlotterBase::plotKey";
|
||
|
||
QFont kf(keyFont, keyFontSize*fontSizeMultiplier);
|
||
QFontMetricsF kfm(kf);
|
||
|
||
// get the size of the key and if keyWidth>0 && keyHeight>0 draw the frame and the contents
|
||
double keyWidth=0;
|
||
double keyHeight=0;
|
||
getKeyExtent(painter, &keyWidth, &keyHeight);
|
||
double keyrWidth=keyWidth+2.0*keyXMargin*kfm.width('X')+2.0*keyFrameWidth*lineWidthPrintMultiplier;
|
||
double keyrHeight=keyHeight+2.0*keyYMargin*kfm.width('X')+2.0*keyFrameWidth*lineWidthPrintMultiplier;
|
||
|
||
if ((keyWidth>0) && (keyHeight>0)) {
|
||
// key position
|
||
double x,y;
|
||
switch(keyPosition) {
|
||
case JKQTPkeyOutsideTopRight:
|
||
x=iplotBorderLeft+plotWidth+iplotBorderRight-keyrWidth-keyXOffset*kfm.width('X');
|
||
y=keyYOffset*kfm.width('X')+iTitleHeight;
|
||
break;
|
||
|
||
case JKQTPkeyOutsideTopLeft:
|
||
x=iplotBorderLeft+keyXOffset*kfm.width('X');
|
||
y=keyYOffset*kfm.width('X')+iTitleHeight;
|
||
break;
|
||
|
||
case JKQTPkeyOutsideBottomRight:
|
||
x=iplotBorderLeft+plotWidth-keyrWidth-keyXOffset*kfm.width('X');
|
||
y=iplotBorderTop+plotHeight+iplotBorderBottom-keyrHeight-keyYOffset*kfm.width('X');
|
||
break;
|
||
case JKQTPkeyOutsideBottomLeft:
|
||
x=iplotBorderLeft+keyXOffset*kfm.width('X');
|
||
y=iplotBorderTop+plotHeight+iplotBorderBottom-keyrHeight-keyYOffset*kfm.width('X');
|
||
break;
|
||
|
||
|
||
|
||
case JKQTPkeyOutsideRightTop:
|
||
x=iplotBorderLeft+plotWidth+iplotBorderRight-keyrWidth-keyXOffset*kfm.width('X');
|
||
y=iplotBorderTop+keyYOffset*kfm.width('X');
|
||
break;
|
||
case JKQTPkeyOutsideRightBottom:
|
||
x=iplotBorderLeft+plotWidth+iplotBorderRight-keyrWidth-keyXOffset*kfm.width('X');
|
||
y=iplotBorderTop+plotHeight-keyrHeight-keyYOffset*kfm.width('X');
|
||
break;
|
||
|
||
case JKQTPkeyOutsideLeftTop:
|
||
x=keyXOffset*kfm.width('X');
|
||
y=iplotBorderTop+keyYOffset*kfm.width('X');
|
||
break;
|
||
case JKQTPkeyOutsideLeftBottom:
|
||
x=keyXOffset*kfm.width('X');
|
||
y=iplotBorderTop+plotHeight-keyrHeight-keyYOffset*kfm.width('X');
|
||
break;
|
||
|
||
|
||
|
||
|
||
case JKQTPkeyInsideBottomRight:
|
||
x=iplotBorderLeft+plotWidth-keyrWidth-keyXOffset*kfm.width('X');
|
||
y=iplotBorderTop+plotHeight-keyrHeight-keyYOffset;
|
||
break;
|
||
case JKQTPkeyInsideBottomLeft:
|
||
x=iplotBorderLeft+keyXOffset*kfm.width('X');
|
||
y=iplotBorderTop+plotHeight-keyrHeight-keyYOffset*kfm.width('X');
|
||
break;
|
||
case JKQTPkeyInsideTopLeft:
|
||
x=iplotBorderLeft+keyXOffset*kfm.width('X');
|
||
y=iplotBorderTop+keyYOffset*kfm.width('X');
|
||
break;
|
||
case JKQTPkeyInsideTopRight:
|
||
default:
|
||
x=iplotBorderLeft+plotWidth-keyrWidth-keyXOffset*kfm.width('X');
|
||
y=iplotBorderTop+keyYOffset*kfm.width('X');
|
||
break;
|
||
}
|
||
|
||
// save old brushes and pens
|
||
painter.save();
|
||
QPen pf=painter.pen();
|
||
QBrush bf=painter.brush();
|
||
pf.setColor(keyFrameColor);
|
||
pf.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, pt2px(painter, keyFrameWidth*lineWidthMultiplier)));
|
||
pf.setStyle(Qt::SolidLine);
|
||
bf.setColor(keyBackgroundColor);
|
||
bf.setStyle(Qt::SolidPattern);
|
||
painter.setBrush(bf);
|
||
if (!showKeyFrame) {
|
||
QPen pff=pf;
|
||
pff.setColor(keyBackgroundColor);
|
||
pff.setWidthF(JKQTPLOTTER_ABS_MIN_LINEWIDTH);
|
||
painter.setPen(pff);
|
||
} else {
|
||
painter.setPen(pf);
|
||
}
|
||
|
||
|
||
painter.drawRect(QRectF(x,y,keyrWidth, keyrHeight));
|
||
y=y+keyYMargin*kfm.width('X')+keyFrameWidth*lineWidthMultiplier/2.0;
|
||
x=x+keyXMargin*kfm.width('X')+keyFrameWidth*lineWidthMultiplier/2.0;
|
||
|
||
painter.setPen(pf);
|
||
|
||
if (useClipping) {
|
||
QRegion cregion(x,y,keyrWidth, keyrHeight);
|
||
painter.setClipping(true);
|
||
painter.setClipRegion(cregion);
|
||
painter.setClipping(true);
|
||
}
|
||
|
||
plotKeyContents(painter, x, y, keyWidth, keyHeight);
|
||
|
||
if (useClipping) painter.setClipping(false);
|
||
painter.restore();
|
||
|
||
}
|
||
//qDebug()<<" end JKQtPlotterBase::plotKey";
|
||
}
|
||
|
||
void JKQtBasePlotter::plotOverlays(JKQTPEnhancedPainter &painter) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot("JKQtBasePlotter::plotOverlays");
|
||
#endif
|
||
if (overlays.isEmpty()) return;
|
||
if (useClipping) {
|
||
QRegion cregion(iplotBorderLeft, iplotBorderTop, plotWidth, plotHeight);
|
||
painter.setClipping(true);
|
||
painter.setClipRegion(cregion);
|
||
}
|
||
|
||
for (int j=0; j<overlays.size(); j++) {
|
||
JKQTPoverlayElement* g=overlays[j];
|
||
if (g->get_visible()) g->draw(painter);
|
||
}
|
||
|
||
if (useClipping) {
|
||
painter.setClipping(false);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void JKQtBasePlotter::paintPlot(JKQTPEnhancedPainter& painter, bool drawOverlays) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot("JKQtBasePlotter::paintPlot");
|
||
#endif
|
||
//qDebug()<<"start JKQtPlotterBase::paintPlot";
|
||
// draw background
|
||
painter.save();
|
||
painter.setPen(backgroundColor);
|
||
if (backgroundColor!=Qt::transparent) painter.fillRect(QRectF(0,0,widgetWidth/paintMagnification, widgetHeight/paintMagnification), QBrush(backgroundColor));
|
||
painter.fillRect(QRectF(iplotBorderLeft, iplotBorderTop, plotWidth, plotHeight), QBrush(plotBackgroundColor));
|
||
painter.restore();
|
||
painter.setRenderHint(JKQTPEnhancedPainter::NonCosmeticDefaultPen, true);
|
||
if (useAntiAliasingForSystem)
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing, true);
|
||
else
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing, false);
|
||
if (useAntiAliasingForText)
|
||
painter.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing, true);
|
||
else
|
||
painter.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing, false);
|
||
plotSystemGrid(painter);
|
||
|
||
if (!plotLabel.isEmpty()) {
|
||
mathText.set_fontSize(plotLabelFontSize*fontSizeMultiplier);
|
||
mathText.set_fontRoman(plotLabelFontname);
|
||
|
||
mathText.parse(plotLabel);
|
||
double a=0,d=0,so=0,w=0;
|
||
getTextSizeDetail(plotLabelFontname,plotLabelFontSize*fontSizeMultiplier,plotLabel, painter, w, a, d, so);
|
||
QSizeF s=QSizeF(w, a+d);
|
||
mathText.draw(painter, iplotBorderLeft+(plotWidth-s.width())/2.0,plotBorderTop+a*1.2);
|
||
}
|
||
|
||
if (useAntiAliasingForGraphs)
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing, true);
|
||
else
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing, false);
|
||
painter.save();
|
||
plotGraphs(painter);
|
||
painter.restore();
|
||
if (useAntiAliasingForSystem)
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing, true);
|
||
else
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing, false);
|
||
if (useAntiAliasingForText)
|
||
painter.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing, true);
|
||
else
|
||
painter.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing, false);
|
||
plotSystemXAxis(painter);
|
||
plotSystemYAxis(painter);
|
||
if (showKey) plotKey(painter);
|
||
if (drawOverlays) plotOverlays(painter);
|
||
//qDebug()<<" end JKQtPlotterBase::paintPlot";
|
||
}
|
||
|
||
void JKQtBasePlotter::paintOverlays(JKQTPEnhancedPainter &painter) {
|
||
painter.setRenderHint(JKQTPEnhancedPainter::NonCosmeticDefaultPen, true);
|
||
if (useAntiAliasingForGraphs)
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing, true);
|
||
else
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing, false);
|
||
painter.save();
|
||
plotOverlays(painter);
|
||
painter.restore();
|
||
}
|
||
|
||
void JKQtBasePlotter::gridPrintingCalc() {
|
||
gridPrintingRows.clear();
|
||
gridPrintingColumns.clear();
|
||
if (!gridPrinting) {
|
||
gridPrintingSize=QSize(widgetWidth/paintMagnification, widgetHeight/paintMagnification);
|
||
gridPrintingRows.push_back(widgetHeight/paintMagnification);
|
||
gridPrintingColumns.push_back(widgetWidth/paintMagnification);
|
||
} else {
|
||
// first find min and max columns/rows
|
||
size_t cmin=gridPrintingCurrentX;
|
||
size_t cmax=gridPrintingCurrentX;
|
||
size_t rmin=gridPrintingCurrentY;
|
||
size_t rmax=gridPrintingCurrentY;
|
||
for (int i=0; i< gridPrintingList.size(); i++) {
|
||
size_t c=gridPrintingList[i].x;
|
||
size_t r=gridPrintingList[i].y;
|
||
if (c<cmin) cmin=c;
|
||
if (c>cmax) cmax=c;
|
||
if (r<rmin) rmin=r;
|
||
if (r>rmax) rmax=r;
|
||
}
|
||
// fill gridPrintingRows and gridPrintingColumns
|
||
for (size_t i=0; i<=cmax; i++) { gridPrintingColumns.push_back(0); }
|
||
for (size_t i=0; i<=rmax; i++) { gridPrintingRows.push_back(0); }
|
||
gridPrintingColumns[gridPrintingCurrentX]=widgetWidth/paintMagnification;
|
||
gridPrintingRows[gridPrintingCurrentY]=widgetHeight/paintMagnification;
|
||
for (int i=0; i< gridPrintingList.size(); i++) {
|
||
int cw=gridPrintingList[i].plotter->widgetWidth/paintMagnification;
|
||
int ch=gridPrintingList[i].plotter->widgetHeight/paintMagnification;
|
||
size_t c=gridPrintingList[i].x;
|
||
size_t r=gridPrintingList[i].y;
|
||
if (cw>gridPrintingColumns[c]) gridPrintingColumns[c]=cw;
|
||
if (ch>gridPrintingRows[r]) gridPrintingRows[r]=ch;
|
||
}
|
||
int w=0;
|
||
int h=0;
|
||
for (int i=0; i<gridPrintingColumns.size(); i++) { w+=gridPrintingColumns[i]; };
|
||
for (int i=0; i<gridPrintingRows.size(); i++) { h+=gridPrintingRows[i]; };
|
||
gridPrintingSize=QSize(w, h);
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::gridPaint(JKQTPEnhancedPainter& painter, QSizeF pageRect, bool drawOverlays, bool scaleIfTooLarge, bool scaleIfTooSmall) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot("JKQtBasePlotter::gridPaint");
|
||
#endif
|
||
calcPlotScaling(painter);
|
||
|
||
if (!gridPrinting) {
|
||
double scale=(double)pageRect.width()/(double)widgetWidth*paintMagnification;
|
||
if (/*(scale*(double)widgetWidth>(double)pageRect.width()) ||*/ (scale*(double)widgetHeight/paintMagnification>(double)pageRect.height()) && scaleIfTooLarge) {
|
||
scale=(double)pageRect.height()/(double)widgetHeight*paintMagnification;
|
||
}
|
||
if (!scaleIfTooSmall && scale>1.0) scale=1.0;
|
||
if (!scaleIfTooLarge && !scaleIfTooSmall) scale=1.0;
|
||
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
||
qDebug()<<"gridPaint: scale="<<scale;
|
||
#endif
|
||
painter.save();
|
||
// scale the plot so it fits on the page
|
||
painter.scale(scale, scale);
|
||
paintPlot(painter, drawOverlays);
|
||
painter.restore();
|
||
} else {
|
||
|
||
QList<double> fsm, lwm, pm;
|
||
QList<QColor> backg;
|
||
for (int i=0; i< gridPrintingList.size(); i++) {
|
||
fsm.append(gridPrintingList[i].plotter->get_fontSizeMultiplier());
|
||
lwm.append(gridPrintingList[i].plotter->get_lineWidthMultiplier());
|
||
pm.append(gridPrintingList[i].plotter->get_paintMagnification());
|
||
backg.append(gridPrintingList[i].plotter->get_exportBackgroundColor());
|
||
gridPrintingList[i].plotter->set_fontSizeMultiplier(fontSizeMultiplier);
|
||
gridPrintingList[i].plotter->set_lineWidthMultiplier(lineWidthMultiplier);
|
||
gridPrintingList[i].plotter->set_paintMagnification(paintMagnification);
|
||
gridPrintingList[i].plotter->set_backgroundColor(gridPrintingList[i].plotter->get_exportBackgroundColor());
|
||
gridPrintingList[i].plotter->calcPlotScaling(painter);
|
||
}
|
||
gridPrintingCalc(); // ensure the grid plot has been calculated
|
||
// scale the plot so it fits on the page
|
||
double scale=(double)pageRect.width()/(double)gridPrintingSize.width();
|
||
if (/*(scale*(double)gridPrintingSize.width()>(double)pageRect.width()) ||*/ (scale*(double)gridPrintingSize.height()>(double)pageRect.height()) && scaleIfTooLarge) {
|
||
scale=(double)pageRect.height()/(double)gridPrintingSize.height();
|
||
}
|
||
if (!scaleIfTooSmall && scale>1.0) scale=1.0;
|
||
if (!scaleIfTooLarge && !scaleIfTooSmall) scale=1.0;
|
||
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
||
qDebug()<<"gridPaint: scale="<<scale;
|
||
#endif
|
||
painter.save();
|
||
painter.scale(scale, scale);
|
||
|
||
|
||
// plot this plotter
|
||
painter.save();
|
||
int t_x=0;
|
||
int t_y=0;
|
||
//std::cout<<"printing this ...\n";
|
||
for (size_t i=0; i<gridPrintingCurrentX; i++) { t_x+=gridPrintingColumns[i]; }
|
||
for (size_t i=0; i<gridPrintingCurrentY; i++) { t_y+=gridPrintingRows[i]; }
|
||
//std::cout<<"printing this @ "<<t_x<<", "<<t_y<<" ...\n";
|
||
painter.translate(t_x, t_y);
|
||
paintPlot(painter, drawOverlays);
|
||
painter.restore();
|
||
//std::cout<<"this printed ...\n";
|
||
|
||
// plot all the other plotters
|
||
for (int i=0; i< gridPrintingList.size(); i++) {
|
||
//std::cout<<"printing "<<i<<" ...\n";
|
||
painter.save();
|
||
int t_x=0;
|
||
int t_y=0;
|
||
//std::cout<<"printing "<<i<<" @g "<<gridPrintingList[i].x<<", "<<gridPrintingList[i].y<<" ...\n";
|
||
//std::cout<<"colrowlistsizes "<<gridPrintingColumns.size()<<", "<<gridPrintingRows.size()<<" ...\n";
|
||
for (size_t j=0; j<gridPrintingList[i].x; j++) { t_x+=gridPrintingColumns[j]; }
|
||
for (size_t j=0; j<gridPrintingList[i].y; j++) { t_y+=gridPrintingRows[j]; }
|
||
//std::cout<<"printing "<<i<<" @ "<<t_x<<", "<<t_y<<" ...\n";
|
||
painter.translate(t_x, t_y);
|
||
gridPrintingList[i].plotter->paintPlot(painter, drawOverlays);
|
||
painter.restore();
|
||
}
|
||
|
||
|
||
painter.restore();
|
||
for (int i=0; i< gridPrintingList.size(); i++) {
|
||
gridPrintingList[i].plotter->set_fontSizeMultiplier(fsm[i]);
|
||
gridPrintingList[i].plotter->set_lineWidthMultiplier(lwm[i]);
|
||
gridPrintingList[i].plotter->set_paintMagnification(pm[i]);
|
||
gridPrintingList[i].plotter->set_backgroundColor(backg[i]);
|
||
gridPrintingList[i].plotter->update_plot();
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::gridPaintOverlays(JKQTPEnhancedPainter &painter, QSizeF pageRect)
|
||
{
|
||
if (!gridPrinting) {
|
||
double scale=(double)pageRect.width()/(double)widgetWidth*paintMagnification;
|
||
if (/*(scale*(double)widgetWidth/paintMagnification>(double)pageRect.width()) ||*/ (scale*(double)widgetHeight>(double)pageRect.height())) {
|
||
scale=(double)pageRect.height()/(double)widgetHeight;
|
||
}
|
||
painter.save();
|
||
// scale the plot so it fits on the page
|
||
painter.scale(scale, scale);
|
||
paintOverlays(painter);
|
||
painter.restore();
|
||
} else {
|
||
gridPrintingCalc(); // ensure the grid plot has been calculated
|
||
// scale the plot so it fits on the page
|
||
double scale=(double)pageRect.width()/(double)gridPrintingSize.width();
|
||
if (/*(scale*(double)gridPrintingSize.width()>(double)pageRect.width()) ||*/ (scale*(double)gridPrintingSize.height()>(double)pageRect.height())) {
|
||
scale=(double)pageRect.height()/(double)gridPrintingSize.height();
|
||
}
|
||
painter.save();
|
||
painter.scale(scale, scale);
|
||
|
||
|
||
// plot this plotter
|
||
painter.save();
|
||
int t_x=0;
|
||
int t_y=0;
|
||
//std::cout<<"printing this ...\n";
|
||
for (size_t i=0; i<gridPrintingCurrentX; i++) { t_x+=gridPrintingColumns[i]; }
|
||
for (size_t i=0; i<gridPrintingCurrentY; i++) { t_y+=gridPrintingRows[i]; }
|
||
//std::cout<<"printing this @ "<<t_x<<", "<<t_y<<" ...\n";
|
||
painter.translate(t_x, t_y);
|
||
paintOverlays(painter);
|
||
painter.restore();
|
||
//std::cout<<"this printed ...\n";
|
||
|
||
// plot all the other plotters
|
||
for (int i=0; i< gridPrintingList.size(); i++) {
|
||
//std::cout<<"printing "<<i<<" ...\n";
|
||
painter.save();
|
||
int t_x=0;
|
||
int t_y=0;
|
||
//std::cout<<"printing "<<i<<" @g "<<gridPrintingList[i].x<<", "<<gridPrintingList[i].y<<" ...\n";
|
||
//std::cout<<"colrowlistsizes "<<gridPrintingColumns.size()<<", "<<gridPrintingRows.size()<<" ...\n";
|
||
for (size_t j=0; j<gridPrintingList[i].x; j++) { t_x+=gridPrintingColumns[j]; }
|
||
for (size_t j=0; j<gridPrintingList[i].y; j++) { t_y+=gridPrintingRows[j]; }
|
||
//std::cout<<"printing "<<i<<" @ "<<t_x<<", "<<t_y<<" ...\n";
|
||
painter.translate(t_x, t_y);
|
||
gridPrintingList[i].plotter->paintOverlays(painter);
|
||
painter.restore();
|
||
}
|
||
|
||
|
||
painter.restore();
|
||
|
||
}
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::print(QPrinter* printer, bool displayPreview) {
|
||
loadUserSettings();
|
||
QPrinter* p=printer;
|
||
bool delP=false;
|
||
|
||
|
||
// select a printer
|
||
if (p==nullptr) {
|
||
p=new QPrinter();
|
||
p->setPrinterName(currentPrinter);
|
||
delP=true;
|
||
|
||
QPrintDialog *dialog = new QPrintDialog(p, nullptr);
|
||
dialog->setWindowTitle(tr("Print Plot"));
|
||
if (dialog->exec() != QDialog::Accepted) {
|
||
delete p;
|
||
delete dialog;
|
||
return;
|
||
}
|
||
currentPrinter=p->printerName();
|
||
delete dialog;
|
||
}
|
||
|
||
p->setPageMargins(10,10,10,10,QPrinter::Millimeter);
|
||
|
||
if (widgetWidth>widgetHeight) {
|
||
p->setOrientation(QPrinter::Landscape);
|
||
} else {
|
||
p->setOrientation(QPrinter::Portrait);
|
||
}
|
||
|
||
printpreviewNew(p, false, -1.0, -1.0, displayPreview);
|
||
|
||
if (delP) delete p;
|
||
saveUserSettings();
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::printpreview(QPrinter *p, bool setabsolutesize) {
|
||
double lw=lineWidthMultiplier;
|
||
double fs=fontSizeMultiplier;
|
||
QColor bc=backgroundColor;
|
||
backgroundColor=exportBackgroundColor;
|
||
lineWidthMultiplier=lineWidthPrintMultiplier;
|
||
fontSizeMultiplier=fontSizePrintMultiplier;
|
||
exportPreviewLabel=nullptr;
|
||
printSizeX_Millimeter=widgetWidth;
|
||
printSizeY_Millimeter=widgetHeight;
|
||
printAspect=1;
|
||
printKeepAspect=false;
|
||
|
||
printSetAbsolutePageSize=setabsolutesize;
|
||
printKeepAbsoluteFontSizes=false;
|
||
printScaleToPagesize=true;
|
||
QDialog* dlg=new QDialog(nullptr, Qt::WindowMinMaxButtonsHint);
|
||
dlg->setSizeGripEnabled(true);
|
||
//printZoomFactor=0.95;
|
||
//printMagnification=1.5;
|
||
QGridLayout* layout=new QGridLayout();
|
||
dlg->setLayout(layout);
|
||
dlg->setWindowTitle(tr("Graph print/export preview ..."));
|
||
dlg->setWindowIcon(QIcon(":/JKQTPlotter/jkqtp_exportprintpreview.png"));
|
||
printPreview=new QPrintPreviewWidget(p, dlg);
|
||
connect(printPreview, SIGNAL(paintRequested(QPrinter*)), this, SLOT(printpreviewPaintRequested(QPrinter*)));
|
||
|
||
if (!setabsolutesize) {
|
||
JKQTPEnhancedDoubleSpinBox* spinZoom=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinZoom->setRange(0.0001,10000);
|
||
spinZoom->setValue(printZoomFactor*100.0);
|
||
spinZoom->setSingleStep(5);
|
||
spinZoom->setDecimals(0);
|
||
spinZoom->setSuffix(tr(" %"));
|
||
spinZoom->setToolTip(tr("use this setting to scale the plot)"));
|
||
connect(spinZoom, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetZoom(double)));
|
||
layout->addWidget(new QLabel(tr("size on paper: ")), 0,layout->columnCount());
|
||
layout->addWidget(spinZoom, 0,layout->columnCount());
|
||
} else {
|
||
printSizeX_Millimeter=100;
|
||
printAspect=double(widgetHeight)/double(widgetWidth);
|
||
|
||
if (gridPrinting) {
|
||
gridPrintingCalc();
|
||
printAspect=double(gridPrintingSize.height())/double(gridPrintingSize.width());
|
||
}
|
||
|
||
printSizeY_Millimeter=printSizeX_Millimeter*printAspect;
|
||
printKeepAspect=true;
|
||
|
||
JKQTPEnhancedDoubleSpinBox* spinSizeX=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinSizeX->setRange(1,10000);
|
||
spinSizeX->setValue(printSizeX_Millimeter);
|
||
spinSizeX->setSingleStep(10);
|
||
spinSizeX->setDecimals(1);
|
||
spinSizeX->setSuffix(tr(" mm"));
|
||
spinSizeX->setToolTip(tr("set the size of the output page"));
|
||
connect(spinSizeX, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetSizeX(double)));
|
||
spinSizeY=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinSizeY->setRange(1,10000);
|
||
spinSizeY->setValue(printSizeY_Millimeter);
|
||
spinSizeY->setSingleStep(10);
|
||
spinSizeY->setDecimals(1);
|
||
spinSizeY->setSuffix(tr(" mm"));
|
||
spinSizeY->setToolTip(tr("set the size of the output page"));
|
||
spinSizeY->setEnabled(false);
|
||
connect(spinSizeY, SIGNAL(valueChanged(double)), this, SLOT(printpreviewSetSizeY(double)));
|
||
QCheckBox* chkAspect=new QCheckBox(tr("keep aspect ratio"), dlg);
|
||
chkAspect->setChecked(true);
|
||
chkAspect->setToolTip(tr("choose whether to keep the aspect ratio for the print/export, as on the screen."));
|
||
connect(chkAspect, SIGNAL(toggled(bool)), spinSizeY, SLOT(setDisabled(bool)));
|
||
connect(chkAspect, SIGNAL(toggled(bool)), this, SLOT(printpreviewSetAspectRatio(bool)));
|
||
|
||
layout->addWidget(new QLabel(tr("page size: ")), 0,layout->columnCount());
|
||
layout->addWidget(spinSizeX, 0,layout->columnCount());
|
||
layout->addWidget(new QLabel(tr(" x ")), 0,layout->columnCount());
|
||
layout->addWidget(spinSizeY, 0,layout->columnCount());
|
||
layout->addWidget(chkAspect, 0,layout->columnCount());
|
||
}
|
||
|
||
JKQTPEnhancedDoubleSpinBox* spinMagnification=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinMagnification->setRange(1,1000);
|
||
spinMagnification->setValue(printMagnification*100.0);
|
||
spinMagnification->setSingleStep(10);
|
||
spinMagnification->setDecimals(0);
|
||
spinMagnification->setSuffix(tr(" %"));
|
||
spinMagnification->setToolTip(tr("use this to change the base size of the plot<br>"
|
||
"This will not change the size of the plot on<br>"
|
||
"the page, only it's appearance. A magn. of 100%<br>"
|
||
"will print the plot in the same proportions as<br>"
|
||
"on the screen, whereas 50% will use twice as much<br>"
|
||
"space for the plot, as on the screen. <i>This mainly<br>"
|
||
"influences the relative font size!</i>"));
|
||
connect(spinMagnification, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetMagnification(double)));
|
||
|
||
JKQTPEnhancedDoubleSpinBox* spinLineWidthMult=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinLineWidthMult->setRange(1,1000);
|
||
spinLineWidthMult->setValue(lineWidthPrintMultiplier*100.0);
|
||
spinLineWidthMult->setSingleStep(10);
|
||
spinLineWidthMult->setDecimals(0);
|
||
spinLineWidthMult->setSuffix(tr(" %"));
|
||
spinLineWidthMult->setToolTip(tr("use this to change the relative width of the lines\n"
|
||
"in the exported/printed plot."));
|
||
connect(spinLineWidthMult, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetLineWidthMultiplier(double)));
|
||
|
||
JKQTPEnhancedDoubleSpinBox* spinFontSizeMult=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinFontSizeMult->setRange(1,1000);
|
||
spinFontSizeMult->setValue(fontSizePrintMultiplier*100.0);
|
||
spinFontSizeMult->setSingleStep(10);
|
||
spinFontSizeMult->setDecimals(0);
|
||
spinFontSizeMult->setSuffix(tr(" %"));
|
||
spinFontSizeMult->setToolTip(tr("use this to change the relative size of the text fonts\n"
|
||
"in the exported/printed plot."));
|
||
connect(spinFontSizeMult, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetFontSizeMultiplier(double)));
|
||
|
||
|
||
//layout->addWidget(new QLabel(tr("magnification: ")), 0,layout->columnCount());
|
||
//layout->addWidget(spinMagnification, 0,layout->columnCount());
|
||
layout->addWidget(new QLabel(tr("linewidth mult.: ")), 0,layout->columnCount());
|
||
layout->addWidget(spinLineWidthMult, 0,layout->columnCount());
|
||
layout->addWidget(new QLabel(tr("font size mult.: ")), 0,layout->columnCount());
|
||
layout->addWidget(spinFontSizeMult, 0,layout->columnCount());
|
||
layout->addWidget(new QWidget(), 0,layout->columnCount());
|
||
layout->setColumnStretch(layout->columnCount()-1, 1);
|
||
layout->addWidget(printPreview, layout->rowCount(),0, 1, layout->columnCount());
|
||
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||
connect(buttonBox, SIGNAL(accepted()), dlg, SLOT(accept()));
|
||
connect(buttonBox, SIGNAL(rejected()), dlg, SLOT(reject()));
|
||
layout->addWidget(buttonBox, layout->rowCount(),0, 1, layout->columnCount());
|
||
dlg->resize(800,500);
|
||
|
||
if (dlg->exec()==QDialog::Accepted) {
|
||
printpreviewPaintRequested(p);
|
||
}
|
||
delete dlg;
|
||
printPreview=nullptr;
|
||
lineWidthMultiplier=lw;
|
||
fontSizeMultiplier=fs;
|
||
backgroundColor=bc;
|
||
|
||
}
|
||
|
||
bool JKQtBasePlotter::printpreviewNew(QPaintDevice* paintDevice, bool setAbsolutePaperSize, double printsizeX_inMM, double printsizeY_inMM, bool displayPreview) {
|
||
QPrinter *printer=dynamic_cast<QPrinter*>(paintDevice);
|
||
QSvgGenerator* svg=dynamic_cast<QSvgGenerator*>(paintDevice);
|
||
double lw=lineWidthMultiplier;
|
||
double fs=fontSizeMultiplier;
|
||
double oldP=paintMagnification;
|
||
QColor bc=backgroundColor;
|
||
backgroundColor=exportBackgroundColor;
|
||
lineWidthMultiplier=lineWidthPrintMultiplier;
|
||
fontSizeMultiplier=fontSizePrintMultiplier;
|
||
exportPreviewLabel=nullptr;
|
||
printMagnification=1.0;
|
||
paintMagnification=1.0;
|
||
gridPrintingCalc();
|
||
|
||
//double resolution=paintDevice->logicalDpiX();
|
||
//if (printer) resolution=printer->resolution();
|
||
|
||
printAspect=gridPrintingSize.height()/gridPrintingSize.width();
|
||
if (printer) printPageSizeMM=printer->pageRect(QPrinter::Millimeter).size();
|
||
else printPageSizeMM=QSizeF(paintDevice->widthMM(), paintDevice->heightMM());
|
||
printSizeX_Millimeter=double(gridPrintingSize.width())/96.0*25.4;//double(resolution)*25.4; // convert current widget size in pixels to millimeters, assuming 96dpi (default screen resolution)
|
||
printSizeY_Millimeter=double(gridPrintingSize.height())/96.0*25.4;//double(resolution)*25.4;
|
||
if (printsizeX_inMM>0) printSizeX_Millimeter=printsizeX_inMM;
|
||
if (printsizeY_inMM>0) printSizeY_Millimeter=printsizeY_inMM;
|
||
|
||
bool startWithMagnification=false;
|
||
if (!setAbsolutePaperSize) {
|
||
if (printSizeX_Millimeter>printPageSizeMM.width() || printSizeY_Millimeter>printPageSizeMM.height()) {
|
||
startWithMagnification=true;
|
||
printMagnification=qMin(printPageSizeMM.width()/printSizeX_Millimeter, printPageSizeMM.height()/printSizeY_Millimeter);
|
||
}
|
||
}
|
||
printKeepAspect=true;
|
||
|
||
printSetAbsolutePageSize=setAbsolutePaperSize;
|
||
printKeepAbsoluteFontSizes=true;
|
||
printScaleToPagesize=false;
|
||
QDialog* dlg=new QDialog(nullptr, Qt::WindowMinMaxButtonsHint);
|
||
dlg->setSizeGripEnabled(true);
|
||
//printZoomFactor=0.95;
|
||
//printMagnification=1.5;
|
||
QGridLayout* layout=new QGridLayout();
|
||
dlg->setLayout(layout);
|
||
dlg->setWindowTitle(tr("Graph print/export preview ..."));
|
||
dlg->setWindowIcon(QIcon(":/JKQTPlotter/jkqtp_exportprintpreview.png"));
|
||
|
||
bool delPrinter=false;
|
||
if (svg) {
|
||
printer=new QPrinter();
|
||
printer->setColorMode(QPrinter::Color);
|
||
printer->setOutputFormat(QPrinter::PdfFormat);
|
||
printer->setResolution(svg->logicalDpiX());
|
||
printer->setPageMargins(0,0,0,0,QPrinter::Millimeter);
|
||
printer->setColorMode(QPrinter::Color);
|
||
delPrinter=true;
|
||
} else if (!printer) {
|
||
printer=new QPrinter();
|
||
printer->setOutputFormat(QPrinter::PdfFormat);
|
||
printer->setResolution(paintDevice->logicalDpiX());
|
||
printer->setPageMargins(0,0,0,0,QPrinter::Millimeter);
|
||
printer->setColorMode(QPrinter::Color);
|
||
delPrinter=true;
|
||
}
|
||
|
||
|
||
printPreview=new QPrintPreviewWidget(printer, dlg);
|
||
connect(printPreview, SIGNAL(paintRequested(QPrinter*)), this, SLOT(printpreviewPaintRequestedNew(QPrinter*)));
|
||
|
||
|
||
|
||
spinSizeX=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinSizeX->setRange(10,100000);
|
||
spinSizeX->setValue(printSizeX_Millimeter);
|
||
spinSizeX->setSingleStep(10);
|
||
spinSizeX->setDecimals(1);
|
||
spinSizeX->setSuffix(tr(" mm"));
|
||
spinSizeX->setToolTip(tr("set the size of the output in millimeters"));
|
||
connect(spinSizeX, SIGNAL(valueChanged(double)), this, SLOT(printpreviewSetSizeXNew(double)));
|
||
connect(spinSizeX, SIGNAL(editingFinished()), this, SLOT(printpreviewUpdate()));
|
||
spinSizeY=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinSizeY->setRange(10,100000);
|
||
spinSizeY->setValue(printSizeY_Millimeter);
|
||
spinSizeY->setSingleStep(10);
|
||
spinSizeY->setDecimals(1);
|
||
spinSizeY->setSuffix(tr(" mm"));
|
||
spinSizeY->setToolTip(tr("set the size of the output in millimeters"));
|
||
spinSizeY->setEnabled(false);
|
||
connect(spinSizeY, SIGNAL(valueChanged(double)), this, SLOT(printpreviewSetSizeYNew(double)));
|
||
connect(spinSizeY, SIGNAL(editingFinished()), this, SLOT(printpreviewUpdate()));
|
||
QCheckBox* chkAspect=new QCheckBox(tr("keep aspect ratio"), dlg);
|
||
chkAspect->setChecked(true);
|
||
chkAspect->setToolTip(tr("choose whether to keep the aspect ratio for the print/export, as on the screen."));
|
||
connect(chkAspect, SIGNAL(toggled(bool)), spinSizeY, SLOT(setDisabled(bool)));
|
||
connect(chkAspect, SIGNAL(toggled(bool)), this, SLOT(printpreviewSetAspectRatio(bool)));
|
||
|
||
if (setAbsolutePaperSize) {
|
||
layout->addWidget(new QLabel(tr("paper/plot size: ")), 0,layout->columnCount());
|
||
} else if (printer && !svg) {
|
||
int y=layout->columnCount();
|
||
layout->addWidget(new QLabel(tr("plot size: ")), 0,y);
|
||
} else {
|
||
int y=layout->columnCount();
|
||
layout->addWidget(new QLabel(tr("paper size: ")), 1,y);
|
||
layout->addWidget(new QLabel(tr("plot size: ")), 0,y);
|
||
}
|
||
layout->addWidget(spinSizeX, 0,layout->columnCount());
|
||
layout->addWidget(new QLabel(tr(" x ")), 0,layout->columnCount());
|
||
layout->addWidget(spinSizeY, 0,layout->columnCount());
|
||
layout->addWidget(chkAspect, 0,layout->columnCount());
|
||
if (!setAbsolutePaperSize && printer && !svg) {
|
||
if (printer) layout->addWidget(new QLabel(tr("%1x%2 mm^2").arg(printer->pageRect(QPrinter::Millimeter).width()).arg(printer->pageRect(QPrinter::Millimeter).height())), 1,layout->columnCount()-4, 1, 4);
|
||
|
||
QCheckBox* chkSetMagnification=new QCheckBox(tr("set by magnification: "), dlg);
|
||
chkSetMagnification->setChecked(false);
|
||
spinMagnification=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinMagnification->setEnabled(false);
|
||
spinMagnification->setRange(1,1000);
|
||
spinMagnification->setValue(printMagnification*100.0);
|
||
spinMagnification->setSingleStep(10);
|
||
spinMagnification->setDecimals(0);
|
||
spinMagnification->setSuffix(tr(" %"));
|
||
spinMagnification->setToolTip(tr("use this to change the base size of the plot<br>"
|
||
"This will not change the size of the plot on<br>"
|
||
"the page, only it's appearance. A magn. of 100%<br>"
|
||
"will print the plot in the same proportions as<br>"
|
||
"on the screen, whereas 50% will use twice as much<br>"
|
||
"space for the plot, as on the screen. <i>This mainly<br>"
|
||
"influences the relative font size!</i>"));
|
||
connect(spinMagnification, SIGNAL(valueChanged(double)), this, SLOT(printpreviewSetMagnificationNew(double)));
|
||
connect(chkSetMagnification, SIGNAL(toggled(bool)), spinMagnification, SLOT(setEnabled(bool)));
|
||
connect(chkSetMagnification, SIGNAL(toggled(bool)), spinSizeX, SLOT(setDisabled(bool)));
|
||
connect(chkSetMagnification, SIGNAL(toggled(bool)), spinSizeY, SLOT(setDisabled(bool)));
|
||
connect(chkSetMagnification, SIGNAL(toggled(bool)), chkAspect, SLOT(setDisabled(bool)));
|
||
connect(spinMagnification, SIGNAL(editingFinished()), this, SLOT(printpreviewUpdate()));
|
||
connect(chkSetMagnification, SIGNAL(toggled(bool)), this, SLOT(printpreviewToggleMagnification(bool)));
|
||
spinMagnification->setEnabled(startWithMagnification);
|
||
chkSetMagnification->setChecked(startWithMagnification);
|
||
layout->addWidget(chkSetMagnification, 0,layout->columnCount());
|
||
layout->addWidget(spinMagnification, 0,layout->columnCount());
|
||
}
|
||
|
||
|
||
|
||
JKQTPEnhancedDoubleSpinBox* spinLineWidthMult=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinLineWidthMult->setRange(1,1000);
|
||
spinLineWidthMult->setValue(lineWidthPrintMultiplier*100.0);
|
||
spinLineWidthMult->setSingleStep(10);
|
||
spinLineWidthMult->setDecimals(0);
|
||
spinLineWidthMult->setSuffix(tr(" %"));
|
||
spinLineWidthMult->setToolTip(tr("use this to change the relative width of the lines\n"
|
||
"in the exported/printed plot."));
|
||
connect(spinLineWidthMult, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetLineWidthMultiplier(double)));
|
||
|
||
QCheckBox* chkKeepAbsoluteFontSize=new QCheckBox(tr("keep abs. fontsize"), dlg);
|
||
chkKeepAbsoluteFontSize->setChecked(true);
|
||
connect(chkKeepAbsoluteFontSize, SIGNAL(toggled(bool)), this, SLOT(printpreviewSetKeepAbsFontsize(bool)));
|
||
|
||
JKQTPEnhancedDoubleSpinBox* spinFontSizeMult=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinFontSizeMult->setEnabled(false);
|
||
spinFontSizeMult->setRange(1,1000);
|
||
spinFontSizeMult->setValue(fontSizePrintMultiplier*100.0);
|
||
spinFontSizeMult->setSingleStep(10);
|
||
spinFontSizeMult->setDecimals(0);
|
||
spinFontSizeMult->setSuffix(tr(" %"));
|
||
spinFontSizeMult->setToolTip(tr("use this to change the relative size of the text fonts\n"
|
||
"in the exported/printed plot."));
|
||
connect(spinFontSizeMult, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetFontSizeMultiplier(double)));
|
||
connect(chkKeepAbsoluteFontSize, SIGNAL(toggled(bool)), spinFontSizeMult, SLOT(setDisabled(bool)));
|
||
|
||
|
||
layout->addWidget(new QLabel(tr("linewidth mult.: ")), 0,layout->columnCount());
|
||
layout->addWidget(spinLineWidthMult, 0,layout->columnCount());
|
||
int gpos=layout->columnCount();
|
||
layout->addWidget(chkKeepAbsoluteFontSize, 0,gpos,1,2);
|
||
layout->addWidget(new QLabel(tr("font size mult.: ")), 1,gpos);
|
||
layout->addWidget(spinFontSizeMult, 1,gpos+1);
|
||
layout->addWidget(new QWidget(), 0,layout->columnCount());
|
||
layout->setColumnStretch(layout->columnCount()-1, 1);
|
||
layout->addWidget(printPreview, layout->rowCount(),0, 1, layout->columnCount());
|
||
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||
connect(buttonBox, SIGNAL(accepted()), dlg, SLOT(accept()));
|
||
connect(buttonBox, SIGNAL(rejected()), dlg, SLOT(reject()));
|
||
layout->addWidget(buttonBox, layout->rowCount(),0, 1, layout->columnCount());
|
||
dlg->resize(800,500);
|
||
|
||
bool res=false;
|
||
if (printer) {
|
||
if (!displayPreview || dlg->exec()==QDialog::Accepted) {
|
||
qDebug()<<svg<<printer<<delPrinter;
|
||
if (svg) {
|
||
printpreviewPaintRequestedNew(svg);
|
||
} else if (printer && !delPrinter) {
|
||
if (delPrinter) {
|
||
printpreviewPaintRequestedNew(paintDevice);
|
||
} else {
|
||
printpreviewPaintRequestedNew(printer);
|
||
}
|
||
} else {
|
||
printpreviewPaintRequestedNew(paintDevice);
|
||
}
|
||
res=true;
|
||
}
|
||
}
|
||
if ((svg||delPrinter) && printer) {
|
||
delete printer;
|
||
}
|
||
delete dlg;
|
||
printPreview=nullptr;
|
||
lineWidthMultiplier=lw;
|
||
fontSizeMultiplier=fs;
|
||
backgroundColor=bc;
|
||
paintMagnification=oldP;
|
||
|
||
mathText.set_useUnparsed(false);
|
||
|
||
return res;
|
||
|
||
}
|
||
|
||
bool JKQtBasePlotter::exportpreview(QSizeF pageSize, bool unitIsMM) {
|
||
printPreview=nullptr;
|
||
printSizeX_Millimeter=pageSize.width();
|
||
printSizeY_Millimeter=pageSize.height();
|
||
printAspect=1;
|
||
printKeepAspect=false;
|
||
exportUnitInMM=unitIsMM;
|
||
|
||
printSetAbsolutePageSize=true;
|
||
printScaleToPagesize=false;
|
||
printKeepAbsoluteFontSizes=true;
|
||
QDialog* dlg=new QDialog(nullptr, Qt::WindowMinMaxButtonsHint);
|
||
dlg->setSizeGripEnabled(true);
|
||
//printZoomFactor=0.95;
|
||
//printMagnification=1.5;
|
||
QGridLayout* layout=new QGridLayout();
|
||
dlg->setLayout(layout);
|
||
dlg->setWindowTitle(tr("Graph export preview ..."));
|
||
dlg->setWindowIcon(QIcon(":/JKQTPlotter/jkqtp_exportprintpreview.png"));
|
||
/*printPreview=new QPrintPreviewWidget(p, dlg);
|
||
connect(printPreview, SIGNAL(paintRequested(QPrinter*)), this, SLOT(printpreviewPaintRequested(QPrinter*)));*/
|
||
QScrollArea* scroll=new QScrollArea(dlg);
|
||
{
|
||
QPalette p(scroll->palette());
|
||
// Set background colour to black
|
||
p.setColor(QPalette::Background, Qt::darkGray);
|
||
scroll->setPalette(p);
|
||
}
|
||
exportPreviewLabel=new QLabel(scroll);
|
||
exportPreviewLabel->setMargin(10);
|
||
scroll->setWidget(exportPreviewLabel);
|
||
{
|
||
QPalette p(exportPreviewLabel->palette());
|
||
// Set background colour to black
|
||
p.setColor(QPalette::Background, Qt::darkGray);
|
||
exportPreviewLabel->setPalette(p);
|
||
}
|
||
|
||
|
||
|
||
printAspect=double(widgetHeight)/double(widgetWidth);
|
||
if (gridPrinting) {
|
||
gridPrintingCalc();
|
||
printAspect=double(gridPrintingSize.height())/double(gridPrintingSize.width());
|
||
}
|
||
printSizeY_Millimeter=printSizeX_Millimeter*printAspect;
|
||
printKeepAspect=true;
|
||
|
||
JKQTPEnhancedDoubleSpinBox* spinSizeX=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinSizeX->setRange(1,10000);
|
||
spinSizeX->setValue(printSizeX_Millimeter);
|
||
spinSizeX->setSingleStep(10);
|
||
if (unitIsMM) spinSizeX->setDecimals(1);
|
||
else spinSizeX->setDecimals(0);
|
||
if (unitIsMM) spinSizeX->setSuffix(tr(" mm"));
|
||
spinSizeX->setToolTip(tr("set the size of the output page"));
|
||
connect(spinSizeX, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetSizeX(double)));
|
||
spinSizeY=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinSizeY->setRange(1,10000);
|
||
spinSizeY->setValue(printSizeY_Millimeter);
|
||
spinSizeY->setSingleStep(10);
|
||
if (unitIsMM) spinSizeY->setDecimals(1);
|
||
else spinSizeY->setDecimals(0);
|
||
if (unitIsMM) spinSizeY->setSuffix(tr(" mm"));
|
||
spinSizeY->setToolTip(tr("set the size of the output page"));
|
||
spinSizeY->setEnabled(false);
|
||
connect(spinSizeY, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetSizeY(double)));
|
||
QCheckBox* chkAspect=new QCheckBox(tr("keep aspect ratio"), dlg);
|
||
chkAspect->setChecked(true);
|
||
chkAspect->setToolTip(tr("choose whether to keep the aspect ratio for the print/export, as on the screen."));
|
||
connect(chkAspect, SIGNAL(toggled(bool)), spinSizeY, SLOT(setDisabled(bool)));
|
||
connect(chkAspect, SIGNAL(toggled(bool)), this, SLOT(printpreviewSetAspectRatio(bool)));
|
||
|
||
layout->addWidget(new QLabel(tr("page size: ")), 0,layout->columnCount());
|
||
layout->addWidget(spinSizeX, 0,layout->columnCount());
|
||
layout->addWidget(new QLabel(tr(" x ")), 0,layout->columnCount());
|
||
layout->addWidget(spinSizeY, 0,layout->columnCount());
|
||
layout->addWidget(chkAspect, 0,layout->columnCount());
|
||
|
||
|
||
JKQTPEnhancedDoubleSpinBox* spinMagnification=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinMagnification->setRange(1,1000);
|
||
spinMagnification->setValue(printMagnification*100.0);
|
||
spinMagnification->setSingleStep(10);
|
||
spinMagnification->setDecimals(0);
|
||
spinMagnification->setSuffix(tr(" %"));
|
||
spinMagnification->setToolTip(tr("use this to change the base size of the plot<br>"
|
||
"This will not change the size of the plot on<br>"
|
||
"the page, only it's appearance. A magn. of 100%<br>"
|
||
"will print the plot in the same proportions as<br>"
|
||
"on the screen, whereas 50% will use twice as much<br>"
|
||
"space for the plot, as on the screen. <i>This mainly<br>"
|
||
"influences the relative font size!</i>"));
|
||
connect(spinMagnification, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetMagnification(double)));
|
||
|
||
layout->addWidget(new QLabel(tr("magnification: ")), 0,layout->columnCount());
|
||
layout->addWidget(spinMagnification, 0,layout->columnCount());
|
||
|
||
|
||
JKQTPEnhancedDoubleSpinBox* spinLineWidthMult=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinLineWidthMult->setRange(1,1000);
|
||
spinLineWidthMult->setValue(lineWidthPrintMultiplier*100.0);
|
||
spinLineWidthMult->setSingleStep(10);
|
||
spinLineWidthMult->setDecimals(0);
|
||
spinLineWidthMult->setSuffix(tr(" %"));
|
||
spinLineWidthMult->setToolTip(tr("use this to change the relative width of the lines\n"
|
||
"in the exported/printed plot."));
|
||
connect(spinLineWidthMult, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetLineWidthMultiplier(double)));
|
||
|
||
JKQTPEnhancedDoubleSpinBox* spinFontSizeMult=new JKQTPEnhancedDoubleSpinBox(dlg);
|
||
spinFontSizeMult->setRange(1,1000);
|
||
spinFontSizeMult->setValue(fontSizePrintMultiplier*100.0);
|
||
spinFontSizeMult->setSingleStep(10);
|
||
spinFontSizeMult->setDecimals(0);
|
||
spinFontSizeMult->setSuffix(tr(" %"));
|
||
spinFontSizeMult->setToolTip(tr("use this to change the relative size of the text fonts\n"
|
||
"in the exported/printed plot."));
|
||
connect(spinFontSizeMult, SIGNAL(editingFinished(double)), this, SLOT(printpreviewSetFontSizeMultiplier(double)));
|
||
|
||
layout->addWidget(new QLabel(tr("magnification: ")), 0,layout->columnCount());
|
||
layout->addWidget(spinMagnification, 0,layout->columnCount());
|
||
layout->addWidget(new QLabel(tr("linewidth mult.: ")), 0,layout->columnCount());
|
||
layout->addWidget(spinLineWidthMult, 0,layout->columnCount());
|
||
layout->addWidget(new QLabel(tr("font size mult.: ")), 0,layout->columnCount());
|
||
layout->addWidget(spinFontSizeMult, 0,layout->columnCount());
|
||
|
||
|
||
layout->addWidget(new QWidget(), 0,layout->columnCount());
|
||
layout->setColumnStretch(layout->columnCount()-1, 1);
|
||
layout->addWidget(scroll, layout->rowCount(),0, 1, layout->columnCount());
|
||
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||
connect(buttonBox, SIGNAL(accepted()), dlg, SLOT(accept()));
|
||
connect(buttonBox, SIGNAL(rejected()), dlg, SLOT(reject()));
|
||
layout->addWidget(buttonBox, layout->rowCount(),0, 1, layout->columnCount());
|
||
dlg->resize(800,500);
|
||
updatePreviewLabel();
|
||
|
||
bool result=false;
|
||
if (dlg->exec()==QDialog::Accepted) {
|
||
result=true;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
void JKQtBasePlotter::updatePreviewLabel() {
|
||
double factor=1;
|
||
if (exportUnitInMM) factor=600.0/double(printSizeX_Millimeter);
|
||
QImage pix(double(printSizeX_Millimeter)*factor*1.1, double(printSizeY_Millimeter)*factor*1.1, QImage::Format_ARGB32);
|
||
pix.fill(Qt::transparent);
|
||
JKQTPEnhancedPainter painter;
|
||
painter.begin(&pix);
|
||
exportpreviewPaintRequested(painter, QSize(double(printSizeX_Millimeter)*factor, double(printSizeY_Millimeter)*factor));
|
||
painter.end();
|
||
if (exportPreviewLabel) {
|
||
QPixmap pm;
|
||
pm.convertFromImage(pix);
|
||
exportPreviewLabel->setPixmap(pm);
|
||
exportPreviewLabel->resize(pm.size());
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewPaintRequested(QPrinter* printer) {
|
||
double lw=lineWidthMultiplier;
|
||
double fs=fontSizeMultiplier;
|
||
QColor bc=backgroundColor;
|
||
backgroundColor=exportBackgroundColor;
|
||
lineWidthMultiplier=lineWidthPrintMultiplier;
|
||
fontSizeMultiplier=fontSizePrintMultiplier;
|
||
|
||
bool oldEmitPlotSignals=emitPlotSignals;
|
||
emitPlotSignals=false;
|
||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||
QApplication::processEvents();
|
||
int oldWidgetWidth=widgetWidth;
|
||
int oldWidgetHeight=widgetHeight;
|
||
//widgetWidth=widgetWidth/printMagnification;
|
||
//widgetHeight=widgetHeight/printMagnification;
|
||
double oldpm=paintMagnification;
|
||
paintMagnification=printMagnification;
|
||
if (printSetAbsolutePageSize) {
|
||
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
||
qDebug()<<"set printing abs. size to "<<QSizeF(printSizeX_Millimeter, printSizeY_Millimeter)<<" mm^2";
|
||
#endif
|
||
//printer->setPaperSize(QPrinter::Custom);
|
||
printer->setOrientation(QPrinter::Portrait);
|
||
printer->setPaperSize(QSizeF(printSizeX_Millimeter, printSizeY_Millimeter), QPrinter::Millimeter);
|
||
if (!gridPrinting) widgetHeight=widgetWidth*printSizeY_Millimeter/printSizeX_Millimeter;
|
||
|
||
}
|
||
|
||
JKQTPEnhancedPainter painter;
|
||
painter.begin(printer);
|
||
if (!printSetAbsolutePageSize) {
|
||
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
||
qDebug()<<"scale printing to "<<printZoomFactor;
|
||
#endif
|
||
painter.scale(printZoomFactor, printZoomFactor);
|
||
}
|
||
|
||
if (printKeepAbsoluteFontSizes) {
|
||
if (printZoomFactor!=1.0) {
|
||
fontSizeMultiplier=1.0/printZoomFactor;
|
||
}
|
||
}
|
||
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
||
|
||
qDebug()<<"printSetAbsoluteSize = "<<printSetAbsolutePageSize;
|
||
qDebug()<<"printScaleToPagesize = "<<printScaleToPagesize;
|
||
qDebug()<<"printKeepAbsoluteFontSizes = "<<printKeepAbsoluteFontSizes;
|
||
qDebug()<<"print with widget size "<<widgetWidth<<widgetHeight;
|
||
qDebug()<<"print with paper size "<<printer->pageRect().size()<<" ";
|
||
QSizeF sl=QSizeF(QSizeF(printer->pageRect().size()).width()/printer->logicalDpiX()*25.4, QSizeF(printer->pageRect().size()).height()/printer->logicalDpiY()*25.4);
|
||
qDebug()<<"print with paper size "<<sl<<" mm^2";
|
||
qDebug()<<"paintMagnification = "<<paintMagnification;
|
||
qDebug()<<"lineWidthMultiplier = "<<lineWidthMultiplier;
|
||
qDebug()<<"fontSizeMultiplier = "<<fontSizeMultiplier;
|
||
qDebug()<<"printer resolution = "<<printer->resolution()<<" dpi";
|
||
qDebug()<<"\nplotLabelFontSize = "<<plotLabelFontSize<<" pt";
|
||
qDebug()<<"keyFontSize = "<<keyFontSize<<" pt";
|
||
qDebug()<<"x-axis label fontsize = "<<xAxis->get_labelFontSize()<<" pt";
|
||
qDebug()<<"y-axis label fontsize = "<<yAxis->get_labelFontSize()<<" pt";
|
||
#endif
|
||
gridPaint(painter, printer->pageRect().size(), true, printScaleToPagesize, printScaleToPagesize);
|
||
painter.end();
|
||
widgetWidth=oldWidgetWidth;
|
||
widgetHeight=oldWidgetHeight;
|
||
QApplication::restoreOverrideCursor();
|
||
QApplication::processEvents();
|
||
emitPlotSignals=oldEmitPlotSignals;
|
||
lineWidthMultiplier=lw;
|
||
fontSizeMultiplier=fs;
|
||
paintMagnification=oldpm;
|
||
backgroundColor=bc;
|
||
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::printpreviewPaintRequestedNew(QPrinter* printer) {
|
||
QPaintDevice* paintDevice=dynamic_cast<QPaintDevice*>(printer);
|
||
printpreviewPaintRequestedNew(paintDevice);
|
||
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewPaintRequestedNew(QPaintDevice *paintDevice)
|
||
{
|
||
//QPaintDevice* paintDevice=dynamic_cast<QPaintDevice*>(printer);
|
||
QPrinter* printer=dynamic_cast<QPrinter*>(paintDevice);
|
||
QSvgGenerator* svg=dynamic_cast<QSvgGenerator*>(paintDevice);
|
||
|
||
double lw=lineWidthMultiplier;
|
||
double fs=fontSizeMultiplier;
|
||
QColor bc=backgroundColor;
|
||
backgroundColor=exportBackgroundColor;
|
||
lineWidthMultiplier=lineWidthPrintMultiplier;
|
||
fontSizeMultiplier=fontSizePrintMultiplier;
|
||
|
||
bool oldEmitPlotSignals=emitPlotSignals;
|
||
emitPlotSignals=false;
|
||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||
QApplication::processEvents();
|
||
int oldWidgetWidth=widgetWidth;
|
||
int oldWidgetHeight=widgetHeight;
|
||
double oldpm=paintMagnification;
|
||
paintMagnification=1.0;
|
||
gridPrintingCalc();
|
||
if (printSetAbsolutePageSize) {
|
||
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
||
qDebug()<<"set printing abs. size to "<<QSizeF(printSizeX_Millimeter, printSizeY_Millimeter)<<" mm^2";
|
||
#endif
|
||
if (printer) {
|
||
printer->setOrientation(QPrinter::Portrait);
|
||
printer->setPaperSize(QSizeF(printSizeX_Millimeter, printSizeY_Millimeter), QPrinter::Millimeter);
|
||
} else if (svg) {
|
||
QRectF siz=QRectF(0,0,printSizeX_Millimeter,printSizeY_Millimeter);
|
||
svg->setSize(QSize(ceil(siz.width()*svg->resolution()/25.4), ceil(siz.height()*svg->resolution()/25.4)));
|
||
svg->setViewBox(QRect(0,0,-1,-1));//*25.4/double(svg->resolution()), printSizeY_Millimeter*25.4/double(svg->resolution())));
|
||
}
|
||
|
||
}
|
||
paintMagnification=gridPrintingSize.width()/(printSizeX_Millimeter/25.4*double(paintDevice->logicalDpiX()));
|
||
if (!gridPrinting) widgetHeight=widgetWidth*printSizeY_Millimeter/printSizeX_Millimeter;
|
||
|
||
JKQTPEnhancedPainter painter;
|
||
if (printer) painter.begin(printer);
|
||
else if (svg) painter.begin(svg);
|
||
else painter.begin(paintDevice);
|
||
|
||
if (printKeepAbsoluteFontSizes) {
|
||
fontSizeMultiplier=1.0;//1.0/paintMagnification;
|
||
}
|
||
|
||
if (svg) {
|
||
lineWidthMultiplier=lineWidthMultiplier*72.0/96.0;
|
||
fontSizeMultiplier=fontSizeMultiplier*72.0/96.0;
|
||
}
|
||
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
||
qDebug()<<"\n\n\n==========================================================================";
|
||
qDebug()<<"printAspect = "<<printAspect;
|
||
qDebug()<<"printKeepAspect = "<<printKeepAspect;
|
||
qDebug()<<"printSetAbsoluteSize = "<<printSetAbsolutePageSize;
|
||
qDebug()<<"printScaleToPagesize = "<<printScaleToPagesize;
|
||
qDebug()<<"printKeepAbsoluteFontSizes = "<<printKeepAbsoluteFontSizes;
|
||
qDebug()<<"print with widget size "<<widgetWidth<<widgetHeight;
|
||
if (printer) {
|
||
qDebug()<<"print with paper size "<<printer->pageRect().size()<<" ";
|
||
QSizeF sl=QSizeF(QSizeF(printer->pageRect().size()).width()/printer->logicalDpiX()*25.4, QSizeF(printer->pageRect().size()).height()/printer->logicalDpiY()*25.4);
|
||
qDebug()<<"print with paper size "<<sl<<" mm^2";
|
||
} else if (svg) {
|
||
qDebug()<<"print with paper size "<<svg->size()<<" ";
|
||
QSizeF sl=QSizeF(QSizeF(svg->viewBoxF().size()).width()/svg->resolution()*25.4, QSizeF(svg->size()).height()/svg->resolution()*25.4);
|
||
qDebug()<<"print with paper size "<<sl<<" mm^2";
|
||
}
|
||
qDebug()<<"plot size "<<printSizeX_Millimeter<<printSizeY_Millimeter<<" mm^2";
|
||
qDebug()<<"paintMagnification = "<<paintMagnification;
|
||
qDebug()<<"lineWidthMultiplier = "<<lineWidthMultiplier;
|
||
qDebug()<<"fontSizeMultiplier = "<<fontSizeMultiplier;
|
||
qDebug()<<"printer resolution = "<<paintDevice->logicalDpiX()<<" dpi";
|
||
qDebug()<<"\nplotLabelFontSize = "<<plotLabelFontSize<<" pt";
|
||
qDebug()<<"keyFontSize = "<<keyFontSize<<" pt";
|
||
qDebug()<<"x-axis label fontsize = "<<xAxis->get_labelFontSize()<<" pt";
|
||
qDebug()<<"y-axis label fontsize = "<<yAxis->get_labelFontSize()<<" pt";
|
||
#endif
|
||
if (printer) gridPaint(painter, printer->pageRect().size(), true, printScaleToPagesize, printScaleToPagesize);
|
||
else if (svg) gridPaint(painter, svg->size(), true, printScaleToPagesize, printScaleToPagesize);
|
||
else gridPaint(painter, QSizeF(paintDevice->width(), paintDevice->height()), true, printScaleToPagesize, printScaleToPagesize);
|
||
painter.end();
|
||
widgetWidth=oldWidgetWidth;
|
||
widgetHeight=oldWidgetHeight;
|
||
QApplication::restoreOverrideCursor();
|
||
QApplication::processEvents();
|
||
emitPlotSignals=oldEmitPlotSignals;
|
||
lineWidthMultiplier=lw;
|
||
fontSizeMultiplier=fs;
|
||
paintMagnification=oldpm;
|
||
backgroundColor=bc;
|
||
}
|
||
|
||
void JKQtBasePlotter::exportpreviewPaintRequested(JKQTPEnhancedPainter &painter, QSize size) {
|
||
double lw=lineWidthMultiplier;
|
||
double fs=fontSizeMultiplier;
|
||
QColor bc=backgroundColor;
|
||
backgroundColor=exportBackgroundColor;
|
||
lineWidthMultiplier=lineWidthPrintMultiplier;
|
||
fontSizeMultiplier=fontSizePrintMultiplier;
|
||
bool oldEmitPlotSignals=emitPlotSignals;
|
||
emitPlotSignals=false;
|
||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||
QApplication::processEvents();
|
||
int oldWidgetWidth=widgetWidth;
|
||
int oldWidgetHeight=widgetHeight;
|
||
widgetWidth=size.width();
|
||
widgetHeight=size.height();
|
||
|
||
gridPaint(painter, size);
|
||
widgetWidth=oldWidgetWidth;
|
||
widgetHeight=oldWidgetHeight;
|
||
QApplication::restoreOverrideCursor();
|
||
QApplication::processEvents();
|
||
emitPlotSignals=oldEmitPlotSignals;
|
||
lineWidthMultiplier=lw;
|
||
fontSizeMultiplier=fs;
|
||
backgroundColor=bc;
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewSetZoom(double value) {
|
||
printZoomFactor=value/100.0;
|
||
if (printPreview) printPreview->updatePreview();
|
||
if (exportPreviewLabel) updatePreviewLabel();
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewSetSizeX(double value) {
|
||
printSizeX_Millimeter=value;
|
||
if (printKeepAspect) {
|
||
printSizeY_Millimeter=printSizeX_Millimeter*printAspect;
|
||
spinSizeY->setValue(printSizeY_Millimeter);
|
||
}
|
||
if (printDoUpdate) {
|
||
if (printPreview) printPreview->updatePreview();
|
||
if (exportPreviewLabel) updatePreviewLabel();
|
||
}
|
||
}
|
||
void JKQtBasePlotter::printpreviewSetSizeY(double value) {
|
||
if (printKeepAspect) return;
|
||
printSizeY_Millimeter=value;
|
||
if (printDoUpdate) {
|
||
if (printPreview) printPreview->updatePreview();
|
||
if (exportPreviewLabel) updatePreviewLabel();
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewSetSizeXNew(double value) {
|
||
printSizeX_Millimeter=value;
|
||
if (printKeepAspect) {
|
||
printSizeY_Millimeter=printSizeX_Millimeter*printAspect;
|
||
spinSizeY->setValue(printSizeY_Millimeter);
|
||
}
|
||
|
||
}
|
||
void JKQtBasePlotter::printpreviewSetSizeYNew(double value) {
|
||
printSizeY_Millimeter=value;
|
||
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewSetMagnification(double value) {
|
||
printMagnification=value/100.0;
|
||
if (printPreview) printPreview->updatePreview();
|
||
if (exportPreviewLabel) updatePreviewLabel();
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::printpreviewSetMagnificationNew(double value)
|
||
{
|
||
printMagnification=value/100.0;
|
||
|
||
printDoUpdate=false;
|
||
if (spinSizeY) {
|
||
spinSizeY->setValue(printMagnification*printPageSizeMM.height());
|
||
}
|
||
if (spinSizeX) {
|
||
spinSizeX->setValue(printMagnification*printPageSizeMM.width());
|
||
}
|
||
printDoUpdate=true;
|
||
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewSetAspectRatio(bool checked) {
|
||
printKeepAspect=checked;
|
||
if (printKeepAspect) {
|
||
printSizeY_Millimeter=printSizeX_Millimeter*printAspect;
|
||
spinSizeY->setValue(printSizeY_Millimeter);
|
||
}
|
||
if (printPreview) printPreview->updatePreview();
|
||
if (exportPreviewLabel) updatePreviewLabel();
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewSetKeepAbsFontsize(bool checked)
|
||
{
|
||
printKeepAbsoluteFontSizes=checked;
|
||
if (printPreview) printPreview->updatePreview();
|
||
if (exportPreviewLabel) updatePreviewLabel();
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewToggleMagnification(bool checked)
|
||
{
|
||
if (checked) {
|
||
if (spinMagnification) printpreviewSetMagnificationNew(spinMagnification->value());
|
||
}
|
||
printpreviewUpdate();
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewSetLineWidthMultiplier(double value) {
|
||
lineWidthPrintMultiplier=value/100.0;
|
||
if (printPreview) printPreview->updatePreview();
|
||
if (exportPreviewLabel) updatePreviewLabel();
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewSetFontSizeMultiplier(double value) {
|
||
fontSizePrintMultiplier=value/100.0;
|
||
if (printPreview) printPreview->updatePreview();
|
||
if (exportPreviewLabel) updatePreviewLabel();
|
||
}
|
||
|
||
void JKQtBasePlotter::printpreviewUpdate()
|
||
{
|
||
if (printDoUpdate) {
|
||
if (printPreview) printPreview->updatePreview();
|
||
if (exportPreviewLabel) updatePreviewLabel();
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::draw(JKQTPEnhancedPainter& painter, QRect rect, bool drawOverlays) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot(QString("JKQtBasePlotter::draw(rect, %1)").arg(drawOverlays));
|
||
#endif
|
||
bool oldEmitPlotSignals=emitPlotSignals;
|
||
emitPlotSignals=false;
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
QString on=objectName();
|
||
if (on.isEmpty() && parent()) on=parent()->objectName();
|
||
qDebug()<<on<<"::draw ...";
|
||
QElapsedTimer timeAll;
|
||
timeAll.start();
|
||
#endif
|
||
//resize(rect.width(), rect.height());
|
||
painter.save();
|
||
painter.translate(rect.topLeft());
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
QElapsedTimer time;
|
||
time.start();
|
||
#endif
|
||
gridPaint(painter, rect.size(), drawOverlays);
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
qDebug()<<on<<"::draw ... gridPaint = " <<time.nsecsElapsed()/1000<<" usecs = "<<(double)time.nsecsElapsed()/1000000.0<<" msecs";
|
||
#endif
|
||
painter.restore();
|
||
emitPlotSignals=oldEmitPlotSignals;
|
||
}
|
||
|
||
void JKQtBasePlotter::drawOverlays(JKQTPEnhancedPainter &painter, QRect rect)
|
||
{
|
||
|
||
//resize(rect.width(), rect.height());
|
||
painter.save();
|
||
painter.translate(rect.topLeft());
|
||
|
||
gridPaintOverlays(painter, rect.size());
|
||
|
||
painter.restore();
|
||
}
|
||
|
||
void JKQtBasePlotter::draw(JKQTPEnhancedPainter& painter, QPoint pos, bool drawOverlays) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot(QString("JKQtBasePlotter::draw(pos, %1)").arg(drawOverlays));
|
||
#endif
|
||
bool oldEmitPlotSignals=emitPlotSignals;
|
||
emitPlotSignals=false;
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
QString on=objectName();
|
||
if (on.isEmpty() && parent()) on=parent()->objectName();
|
||
qDebug()<<on<<"::draw ...";
|
||
QElapsedTimer timeAll;
|
||
timeAll.start();
|
||
#endif
|
||
QRect rect=QRect(pos, QSize(widgetWidth/paintMagnification, widgetHeight/paintMagnification));
|
||
painter.save();
|
||
painter.translate(rect.topLeft());
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
QElapsedTimer time;
|
||
time.start();
|
||
#endif
|
||
gridPaint(painter, rect.size(), drawOverlays);
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
qDebug()<<on<<"::draw ... gridPaint = " <<time.nsecsElapsed()/1000<<" usecs = "<<(double)time.nsecsElapsed()/1000000.0<<" msecs";
|
||
#endif
|
||
painter.restore();
|
||
emitPlotSignals=oldEmitPlotSignals;
|
||
}
|
||
|
||
void JKQtBasePlotter::drawNonGrid(JKQTPEnhancedPainter& painter, QRect rect, bool drawOverlays) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot(QString("JKQtBasePlotter::drawNonGrid(rect, %1)").arg(drawOverlays));
|
||
#endif
|
||
bool oldEmitPlotSignals=emitPlotSignals;
|
||
emitPlotSignals=false;
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
QString on=objectName();
|
||
if (on.isEmpty() && parent()) on=parent()->objectName();
|
||
qDebug()<<on<<"::drawNonGrid ...";
|
||
QElapsedTimer timeAll;
|
||
timeAll.start();
|
||
#endif
|
||
painter.save();
|
||
painter.translate(rect.topLeft());
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
QElapsedTimer time;
|
||
time.start();
|
||
#endif
|
||
calcPlotScaling(painter);
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
qDebug()<<on<<"::drawNonGrid ... calcPlotScaling = " <<time.nsecsElapsed()/1000<<" usecs = "<<(double)time.nsecsElapsed()/1000000.0<<" msecs";
|
||
#endif
|
||
double scale=(double)rect.width()/(double)widgetWidth*paintMagnification;
|
||
if ((scale*(double)widgetWidth/paintMagnification>(double)rect.width()) || (scale*(double)widgetHeight/paintMagnification>(double)rect.height())) {
|
||
scale=(double)rect.height()/(double)widgetHeight*paintMagnification;
|
||
}
|
||
painter.save();
|
||
// scale the plot so it fits on the page
|
||
painter.scale(scale, scale);
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
time.start();
|
||
#endif
|
||
paintPlot(painter, drawOverlays);
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
qDebug()<<on<<"::drawNonGrid ... paintPlot = " <<time.nsecsElapsed()/1000<<" usecs = "<<(double)time.nsecsElapsed()/1000000.0<<" msecs";
|
||
#endif
|
||
painter.restore();
|
||
painter.restore();
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
qDebug()<<on<<"::drawNonGrid ... DONE = "<<timeAll.nsecsElapsed()/1000<<" usecs = "<<(double)timeAll.nsecsElapsed()/1000000.0<<" msecs";
|
||
#endif
|
||
emitPlotSignals=oldEmitPlotSignals;
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::drawNonGrid(JKQTPEnhancedPainter& painter, QPoint pos, bool drawOverlays) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot(QString("JKQtBasePlotter::drawNonGrid(pos, %1)").arg(drawOverlays));
|
||
#endif
|
||
bool oldEmitPlotSignals=emitPlotSignals;
|
||
emitPlotSignals=false;
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
QString on=objectName();
|
||
if (on.isEmpty() && parent()) on=parent()->objectName();
|
||
qDebug()<<on<<"::drawNonGrid ...";
|
||
QElapsedTimer timeAll;
|
||
timeAll.start();
|
||
#endif
|
||
QRect rect=QRect(pos, QSize(widgetWidth/paintMagnification, widgetHeight/paintMagnification));
|
||
painter.save();
|
||
painter.translate(rect.topLeft());
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
QElapsedTimer time;
|
||
time.start();
|
||
#endif
|
||
calcPlotScaling(painter);
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
qDebug()<<on<<"::drawNonGrid ... calcPlotScaling = " <<time.nsecsElapsed()/1000<<" usecs = "<<(double)time.nsecsElapsed()/1000000.0<<" msecs";
|
||
#endif
|
||
double scale=(double)rect.width()/(double)widgetWidth*paintMagnification;
|
||
if ((scale*(double)widgetWidth/paintMagnification>(double)rect.width()) || (scale*(double)widgetHeight/paintMagnification>(double)rect.height())) {
|
||
scale=(double)rect.height()/(double)widgetHeight*paintMagnification;
|
||
}
|
||
painter.save();
|
||
// scale the plot so it fits on the page
|
||
painter.scale(scale, scale);
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
time.start();
|
||
#endif
|
||
paintPlot(painter, drawOverlays);
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
qDebug()<<on<<"::drawNonGrid ... paintPlot = " <<time.nsecsElapsed()/1000<<" usecs = "<<(double)time.nsecsElapsed()/1000000.0<<" msecs";
|
||
#endif
|
||
painter.restore();
|
||
painter.restore();
|
||
#ifdef JKQTBP_DEBUGTIMING
|
||
qDebug()<<on<<"::drawNonGrid ... DONE = "<<timeAll.nsecsElapsed()/1000<<" usecs = "<<(double)timeAll.nsecsElapsed()/1000000.0<<" msecs";
|
||
#endif
|
||
emitPlotSignals=oldEmitPlotSignals;
|
||
}
|
||
|
||
void JKQtBasePlotter::drawNonGridOverlays(JKQTPEnhancedPainter& painter, QPoint pos) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot(QString("JKQtBasePlotter::drawNonGridOverlays(point)"));
|
||
#endif
|
||
QRect rect=QRect(pos, QSize(widgetWidth/paintMagnification, widgetHeight/paintMagnification));
|
||
painter.save();
|
||
painter.translate(rect.topLeft());
|
||
double scale=(double)rect.width()/(double)widgetWidth*paintMagnification;
|
||
if ((scale*(double)widgetWidth/paintMagnification>(double)rect.width()) || (scale*(double)widgetHeight/paintMagnification>(double)rect.height())) {
|
||
scale=(double)rect.height()/(double)widgetHeight*paintMagnification;
|
||
}
|
||
painter.save();
|
||
// scale the plot so it fits on the page
|
||
painter.scale(scale, scale);
|
||
paintOverlays(painter);
|
||
painter.restore();
|
||
painter.restore();
|
||
}
|
||
|
||
void JKQtBasePlotter::registerAdditionalAction(const QString &key, QAction *act)
|
||
{
|
||
if (!lstAdditionalPlotterActions.contains(key)) {
|
||
QList<QPointer<QAction> > l;
|
||
lstAdditionalPlotterActions.insert(key, l);
|
||
}
|
||
lstAdditionalPlotterActions[key].append(act);
|
||
|
||
AdditionalActionsMapIterator it(lstAdditionalPlotterActions);
|
||
while (it.hasNext()) {
|
||
it.next();
|
||
for (int i=it.value().size()-1; i>=0; i--) {
|
||
if (!it.value().at(i)) {
|
||
lstAdditionalPlotterActions[it.key()].removeAt(i);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::deregisterAdditionalAction(QAction *act)
|
||
{
|
||
AdditionalActionsMapIterator it(lstAdditionalPlotterActions);
|
||
while (it.hasNext()) {
|
||
it.next();
|
||
for (int i=it.value().size()-1; i>=0; i--) {
|
||
if (it.value().at(i)==act) {
|
||
lstAdditionalPlotterActions[it.key()].removeAt(i);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::copyData() {
|
||
loadUserSettings();
|
||
QString result="";
|
||
QString qfresult;
|
||
QSet<int> cols=getDataColumnsByUser();
|
||
{
|
||
QTextStream txt(&result);
|
||
QLocale loc=QLocale::system();
|
||
loc.setNumberOptions(QLocale::OmitGroupSeparator);
|
||
QChar dp=loc.decimalPoint();
|
||
QString sep="\t";
|
||
datastore->saveCSV(txt, cols, sep, QString(dp), " ", "\"");
|
||
txt.flush();
|
||
}
|
||
{
|
||
QTextStream txt(&qfresult);
|
||
datastore->saveCSV(txt, cols, ",", ".", "#!", "\"");
|
||
txt.flush();
|
||
}
|
||
QClipboard *clipboard = QApplication::clipboard();
|
||
QMimeData* mime=new QMimeData();
|
||
mime->setText(result);
|
||
mime->setData("jkqtplotter/csv", qfresult.toUtf8());
|
||
clipboard->setMimeData(mime);
|
||
//clipboard->setText(result);
|
||
saveUserSettings();
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::copyDataMatlab() {
|
||
loadUserSettings();
|
||
QString result="";
|
||
{
|
||
QTextStream txt(&result);
|
||
datastore->saveMatlab(txt, getDataColumnsByUser());
|
||
txt.flush();
|
||
}
|
||
QClipboard *clipboard = QApplication::clipboard();
|
||
clipboard->setText(result);
|
||
saveUserSettings();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveData(QString filename, QString format) {
|
||
loadUserSettings();
|
||
QStringList fileformats;
|
||
QStringList fileformatIDs;
|
||
fileformats<<tr("Comma Separated Values (*.csv *.dat)");
|
||
fileformatIDs<<"csv";
|
||
fileformats<<tr("Tab Separated Values (*.txt)");
|
||
fileformatIDs<<"tab";
|
||
fileformats<<tr("Semicolon Separated Values [German Excel] (*.csv *.dat *.txt)");
|
||
fileformatIDs<<"gex";
|
||
fileformats<<tr("Semicolon Separated Values (*.csv *.dat *.txt)");
|
||
fileformatIDs<<"sem";
|
||
fileformats<<tr("SYLK spreadsheet (*.slk)");
|
||
fileformatIDs<<"slk";
|
||
fileformats<<tr("DIF: Data Interchange Format (*.dif)");
|
||
fileformatIDs<<"dif";
|
||
fileformats<<tr("Matlab Script (*.m)");
|
||
fileformatIDs<<"m";
|
||
|
||
for (int i=0; i<jkqtpSaveDataAdapters.size(); i++) {
|
||
fileformats<<jkqtpSaveDataAdapters[i]->getFilter();
|
||
fileformatIDs<<QString("custom%1").arg(i);
|
||
}
|
||
|
||
|
||
|
||
QString fn=filename;
|
||
QString fmt=format.toLower();
|
||
if (fmt.isEmpty()) {
|
||
QString e=QFileInfo(filename).suffix().toLower();// jkqtp_tolower(extract_file_ext(fn.toStdString()));
|
||
if (e=="csv" || e=="dat") {
|
||
fmt="csv";
|
||
} else if (e=="txt") {
|
||
fmt="tab";
|
||
} else if ((e=="slk")||(e=="sylk")) {
|
||
fmt="slk";
|
||
} else if (e=="dif") {
|
||
fmt="dif";
|
||
} else if (e=="m") {
|
||
fmt="m";
|
||
}
|
||
}
|
||
if (fn.isEmpty()) {
|
||
QString selectedFilter=currentDataFileFormat;
|
||
//qDebug()<<"before: currentSaveDirectory="<<currentSaveDirectory;
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot Data"),
|
||
currentSaveDirectory,
|
||
fileformats.join(";;"),
|
||
&selectedFilter);
|
||
if (!fn.isEmpty()) {
|
||
currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
currentDataFileFormat=selectedFilter;
|
||
}
|
||
//qDebug()<<"after: currentSaveDirectory="<<currentSaveDirectory;
|
||
fmt="csv";
|
||
for (int i=0; i<fileformats.size(); i++) {
|
||
if (selectedFilter.contains(fileformats[i])) {
|
||
fmt=fileformatIDs[i] ;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
saveUserSettings();
|
||
if (!fn.isEmpty()) {
|
||
|
||
if (fmt=="csv") {
|
||
saveAsCSV(fn);
|
||
} else if (fmt=="tab") {
|
||
saveAsTabSV(fn);
|
||
} else if (fmt=="gex") {
|
||
saveAsGerExcelCSV(fn);
|
||
} else if (fmt=="sem") {
|
||
saveAsSemicolonSV(fn);
|
||
} else if (fmt=="slk") {
|
||
saveAsSYLK(fn);
|
||
} else if (fmt=="dif") {
|
||
saveAsDIF(fn);
|
||
} else if (fmt=="m") {
|
||
saveAsMatlab(fn);
|
||
} else if (fmt.startsWith("custom")) {
|
||
QString fidx=fmt;
|
||
fidx=fidx.remove(0,6);
|
||
int idx=fidx.toInt();
|
||
if (idx>=0 && idx<jkqtpSaveDataAdapters.size() && jkqtpSaveDataAdapters[idx]) {
|
||
QStringList cn;
|
||
QList<QVector<double> > dataset=datastore->getData(&cn);
|
||
jkqtpSaveDataAdapters[idx]->saveJKQTPData(fn, dataset, cn);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::saveAsCSV(QString filename) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
if (fn.isEmpty()) {
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot Data"),
|
||
currentSaveDirectory,
|
||
tr("Comma Separated Values (*.csv *.dat)"));
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
if (!fn.isEmpty()) {
|
||
datastore->saveCSV(fn, getDataColumnsByUser(), ", ", CSVdecimalSeparator, CSVcommentInitializer);
|
||
}
|
||
saveUserSettings();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveAsSYLK(QString filename) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
if (fn.isEmpty()) {
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot Data"),
|
||
currentSaveDirectory,
|
||
tr("SYLK spreadsheet (*.slk)"));
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
if (!fn.isEmpty()) {
|
||
datastore->saveSYLK(fn, getDataColumnsByUser());
|
||
}
|
||
saveUserSettings();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveAsMatlab(QString filename) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
if (fn.isEmpty()) {
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot Data"),
|
||
currentSaveDirectory,
|
||
tr("Matlab Script (*.m)"));
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
if (!fn.isEmpty()) {
|
||
datastore->saveMatlab(fn, getDataColumnsByUser());
|
||
}
|
||
saveUserSettings();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveAsDIF(QString filename) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
if (fn.isEmpty()) {
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot Data"),
|
||
currentSaveDirectory,
|
||
tr("DIF: Data Interchange Format (*.dif)"));
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
if (!fn.isEmpty()) {
|
||
datastore->saveDIF(fn, getDataColumnsByUser());
|
||
}
|
||
saveUserSettings();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveAsSemicolonSV(QString filename) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
if (fn.isEmpty()) {
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot Data"),
|
||
currentSaveDirectory,
|
||
tr("Comma Separated Values (*.csv *.dat)"));
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
if (!fn.isEmpty()) {
|
||
datastore->saveCSV(fn, getDataColumnsByUser(), ";", CSVdecimalSeparator, CSVcommentInitializer);
|
||
}
|
||
saveUserSettings();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveAsTabSV(QString filename) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
if (fn.isEmpty()) {
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot Data"),
|
||
currentSaveDirectory,
|
||
tr("Tabulator Separated Values (*.txt)"));
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
if (!fn.isEmpty()) {
|
||
datastore->saveCSV(fn, getDataColumnsByUser(), "\t", CSVdecimalSeparator, CSVcommentInitializer);
|
||
}
|
||
saveUserSettings();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveAsGerExcelCSV(QString filename) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
if (fn.isEmpty()) {
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot Data"),
|
||
currentSaveDirectory,
|
||
tr("Tabulator Separated Values (*.txt)"));
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
if (!fn.isEmpty()) {
|
||
datastore->saveCSV(fn, getDataColumnsByUser(), ";", ",", " ", "\"");
|
||
}
|
||
saveUserSettings();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveAsPDF(QString filename, bool displayPreview) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
if (fn.isEmpty()) {
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot"),
|
||
currentSaveDirectory,
|
||
tr("PDF File (*.pdf)"));
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
if (!fn.isEmpty()) {
|
||
QPrinter* printer=new QPrinter;
|
||
bool doLandscape=widgetWidth>widgetHeight;
|
||
if (gridPrinting) {
|
||
gridPrintingCalc();
|
||
doLandscape=gridPrintingSize.width()>gridPrintingSize.height();
|
||
}
|
||
if (doLandscape) {
|
||
printer->setOrientation(QPrinter::Landscape);
|
||
} else {
|
||
printer->setOrientation(QPrinter::Portrait);
|
||
}
|
||
printer->setOutputFormat(QPrinter::PdfFormat);
|
||
printer->setColorMode(QPrinter::Color);
|
||
printer->setOutputFileName(fn);
|
||
printer->setPageMargins(0,0,0,0,QPrinter::Millimeter);
|
||
printer->setColorMode(QPrinter::Color);
|
||
printpreviewNew(printer, true, -1.0, -1.0, displayPreview);
|
||
delete printer;
|
||
}
|
||
saveUserSettings();
|
||
}
|
||
|
||
void JKQtBasePlotter::saveAsPS(QString filename, bool displayPreview) {
|
||
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
if (fn.isEmpty()) {
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot"),
|
||
currentSaveDirectory,
|
||
tr("PostScript File (*.ps)"));
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
if (!fn.isEmpty()) {
|
||
QPrinter* printer=new QPrinter;
|
||
bool doLandscape=widgetWidth>widgetHeight;
|
||
if (gridPrinting) {
|
||
gridPrintingCalc();
|
||
doLandscape=gridPrintingSize.width()>gridPrintingSize.height();
|
||
}
|
||
if (doLandscape) {
|
||
printer->setOrientation(QPrinter::Landscape);
|
||
} else {
|
||
printer->setOrientation(QPrinter::Portrait);
|
||
}
|
||
printer->setOutputFormat(QPrinter::PostScriptFormat);
|
||
printer->setColorMode(QPrinter::Color);
|
||
printer->setOutputFileName(fn);
|
||
printer->setPageMargins(0,0,0,0,QPrinter::Millimeter);
|
||
printpreviewNew(printer, true, -1.0, -1.0, displayPreview);
|
||
delete printer;
|
||
}
|
||
saveUserSettings();
|
||
#else
|
||
saveAsPDF(filename+".pdf", displayPreview);
|
||
#endif
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::saveImage(QString filename, bool displayPreview) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
QStringList filt;
|
||
filt<<tr("Portable Document Format PDF [Qt] (*.pdf)");
|
||
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
|
||
filt<<tr("PostScript [Qt] (*.ps)");
|
||
#endif
|
||
filt<<tr("Scalable Vector Graphics [Qt] (*.svg)");
|
||
filt<<tr("PNG Image [Qt] (*.png)");
|
||
filt<<tr("BMP Image [Qt] (*.bmp)");
|
||
filt<<tr("TIFF Image [Qt] (*.tif *.tiff)");
|
||
filt<<tr("JPEG Image [Qt] (*.jpg *.jpeg)");
|
||
const int filtStartSize=filt.size();
|
||
for (int i=0; i<jkqtpPaintDeviceAdapters.size(); i++) {
|
||
filt<<jkqtpPaintDeviceAdapters[i]->getFilter();
|
||
}
|
||
int qtwritersidx=filt.size();
|
||
QList<QByteArray> writerformats=QImageWriter::supportedImageFormats();
|
||
for (int i=0; i<writerformats.size(); i++) {
|
||
filt<<QString("%1 Image (*.%2)").arg(QString(writerformats[i]).toUpper()).arg(QString(writerformats[i].toLower()));
|
||
}
|
||
/*filt<<tr("X11 Bitmap [Qt] (*.xbm)");
|
||
filt<<tr("X11 Pixmap [Qt] (*.xpm)");*/
|
||
QString selFormat="";
|
||
if (fn.isEmpty()) {
|
||
selFormat=currentFileFormat;
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot"),
|
||
currentSaveDirectory,
|
||
filt.join(";;"), &selFormat);
|
||
if (!fn.isEmpty()) {
|
||
currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
currentFileFormat=selFormat;
|
||
}
|
||
}
|
||
|
||
//qDebug()<<"fn="<<fn<<" selFormat="<<selFormat;
|
||
|
||
saveUserSettings();
|
||
if (!fn.isEmpty()) {
|
||
int filtID=filt.indexOf(selFormat);
|
||
bool isWithSpecialDeviceAdapter=filtID>=filtStartSize && filtID<filtStartSize+jkqtpPaintDeviceAdapters.size();
|
||
int adapterID=filtID-filtStartSize;
|
||
QString e=QFileInfo(filename).suffix().toLower();
|
||
if (!isWithSpecialDeviceAdapter) {
|
||
for (int i=0; i<jkqtpPaintDeviceAdapters.size(); i++) {
|
||
if (jkqtpPaintDeviceAdapters[i]->getFileExtension().contains(e)) {
|
||
adapterID=i;
|
||
isWithSpecialDeviceAdapter=true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
//qDebug()<<"filtID="<<filtID<<" isWithSpecialDeviceAdapter="<<isWithSpecialDeviceAdapter<<" adapterID="<<adapterID;
|
||
int ids=0;
|
||
if (filtID==ids++) {
|
||
saveAsPDF(fn, displayPreview);
|
||
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
|
||
} else if (filtID==ids++) {
|
||
saveAsPS(fn, displayPreview);
|
||
#endif
|
||
} else if (filtID==ids++) {
|
||
saveAsSVG(fn, displayPreview);
|
||
} else if (isWithSpecialDeviceAdapter && adapterID>=0 && adapterID<jkqtpPaintDeviceAdapters.size()) {
|
||
QString tempFM="";
|
||
if (QFile::exists(fn)) {
|
||
#ifdef QFWIDLIB_LIBRARY
|
||
QFTemporaryFile* tf=new QFTemporaryFile();
|
||
#else
|
||
QTemporaryFile* tf=new QTemporaryFile();
|
||
#endif
|
||
tf->open();
|
||
tempFM=tf->fileName();
|
||
tf->close();
|
||
delete tf;
|
||
QFile::copy(fn, tempFM);
|
||
}
|
||
|
||
mathText.set_useUnparsed(!jkqtpPaintDeviceAdapters[adapterID]->useLatexParser());
|
||
|
||
gridPrintingCalc();
|
||
QPaintDevice* svg=jkqtpPaintDeviceAdapters[adapterID]->createPaintdevice(fn, gridPrintingSize.width(), gridPrintingSize.height());
|
||
|
||
if (!printpreviewNew(svg, jkqtpPaintDeviceAdapters[adapterID]->getSetAbsolutePaperSize(), jkqtpPaintDeviceAdapters[adapterID]->getPrintSizeXInMM(), jkqtpPaintDeviceAdapters[adapterID]->getPrintSizeYInMM(), displayPreview)) {
|
||
delete svg;
|
||
|
||
|
||
if (QFile::exists(tempFM)) {
|
||
QFile::copy(tempFM, fn);
|
||
QFile::remove(tempFM);
|
||
}
|
||
} else {
|
||
delete svg;
|
||
svg=jkqtpPaintDeviceAdapters[adapterID]->createPaintdeviceMM(fn,printSizeX_Millimeter,printSizeY_Millimeter);
|
||
printpreviewPaintRequestedNew(svg);
|
||
delete svg;
|
||
}
|
||
|
||
} else {
|
||
saveAsPixelImage(fn, displayPreview, writerformats.value(filtID-qtwritersidx, QByteArray()));
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::saveAsPixelImage(QString filename, bool displayPreview, const QByteArray& outputFormat) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
QStringList filt;
|
||
QList<QByteArray> writerformats=QImageWriter::supportedImageFormats();
|
||
for (int i=0; i<writerformats.size(); i++) {
|
||
filt<<QString("%1 Image (*.%2)").arg(QString(writerformats[i]).toUpper()).arg(QString(writerformats[i].toLower()));
|
||
}
|
||
/*filt<<tr("PNG Image (*.png)");
|
||
filt<<tr("BMP Image (*.bmp)");
|
||
filt<<tr("TIFF Image (*.tif *.tiff)");
|
||
filt<<tr("JPEG Image (*.jpg *.jpeg)");
|
||
filt<<tr("X11 Bitmap (*.xbm)");
|
||
filt<<tr("X11 Pixmap (*.xpm)");*/
|
||
QString selFormat;
|
||
if (fn.isEmpty()) {
|
||
selFormat=currentFileFormat;
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot"),
|
||
currentSaveDirectory,
|
||
filt.join(";;"), &selFormat);
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
saveUserSettings();
|
||
if (!fn.isEmpty()) {
|
||
int filtID=filt.indexOf(selFormat);
|
||
//QString ext=tolower(extract_file_ext(fn.toStdString()));
|
||
QString form="NONE";
|
||
if (filtID>=0 && filtID<writerformats.size()) {
|
||
form=writerformats[filtID];
|
||
}
|
||
if (outputFormat.size()>0) {
|
||
form =outputFormat;
|
||
}
|
||
/*if (filtID==2 || ext=="tif" || ext=="tiff") { // currentFileFormat
|
||
form="TIFF";
|
||
} else if (filtID==0 || ext=="png") {
|
||
form="PNG";
|
||
} else if (filtID==1 || ext=="bmp") {
|
||
form="BMP";
|
||
} else if (filtID==3 || ext=="jpg" || ext=="jpeg") {
|
||
form="JPEG";
|
||
} else if (ext=="ppm") {
|
||
form="PPM";
|
||
} else if (filtID==4 || ext=="xbm") {
|
||
form="XBM";
|
||
} else if (filtID==5 || ext=="xpm") {
|
||
form="XPM";
|
||
}*/
|
||
|
||
|
||
gridPrintingCalc();
|
||
//std::cout<<gridPrintingSize.width()<<", "<<gridPrintingSize.height()<<std::endl;
|
||
|
||
if (!displayPreview) {
|
||
printSizeX_Millimeter=widgetWidth;
|
||
printSizeY_Millimeter=widgetHeight;
|
||
}
|
||
|
||
if (!displayPreview || exportpreview(gridPrintingSize, false)) {
|
||
|
||
QImage png(QSize(double(printSizeX_Millimeter)*1.1, double(printSizeY_Millimeter)*1.1), QImage::Format_ARGB32);
|
||
png.fill(Qt::transparent);
|
||
JKQTPEnhancedPainter painter;
|
||
painter.begin(&png);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::NonCosmeticDefaultPen, true);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::SmoothPixmapTransform);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::HighQualityAntialiasing);
|
||
|
||
/*calcPlotScaling(painter);
|
||
gridPaint(painter, png.rect().size());*/\
|
||
//qDebug()<<QSize(printSizeX_Millimeter, printSizeY_Millimeter);
|
||
exportpreviewPaintRequested(painter, QSize(printSizeX_Millimeter, printSizeY_Millimeter));
|
||
painter.end();
|
||
if (form=="NONE") png.save(fn);
|
||
else png.save(fn, form.toLatin1().data());
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::copyPixelImage() {
|
||
/*qDebug()<<gridPrintingSize.width()<<", "<<gridPrintingSize.height();
|
||
qDebug()<<widgetWidth<<", "<<widgetHeight;
|
||
qDebug()<<paintMagnification;*/
|
||
/* QImage png(gridPrintingSize, QImage::Format_ARGB32);
|
||
{
|
||
JKQTPEnhancedPainter painter;
|
||
painter.begin(&png);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::SmoothPixmapTransform);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::HighQualityAntialiasing);
|
||
//calcPlotScaling(painter);
|
||
gridPaint(painter, gridPrintingSize);
|
||
painter.end();
|
||
}
|
||
|
||
QClipboard *clipboard = QApplication::clipboard();
|
||
qDebug()<<"clipboard before adding content:\n"<<clipboard->mimeData()->formats();
|
||
clipboard->setImage(png);
|
||
qDebug()<<"clipboard after adding content:\n"<<clipboard->mimeData()->formats();
|
||
|
||
*/
|
||
|
||
gridPrintingCalc();
|
||
//std::cout<<gridPrintingSize.width()<<", "<<gridPrintingSize.height()<<std::endl;
|
||
printSizeX_Millimeter=gridPrintingSize.width();
|
||
printSizeY_Millimeter=gridPrintingSize.height();
|
||
|
||
if (exportpreview(gridPrintingSize, false)) {
|
||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||
|
||
//if (exportpreview(gridPrintingSize, false)) {
|
||
QImage png(QSize(double(printSizeX_Millimeter), double(printSizeY_Millimeter)), QImage::Format_ARGB32);
|
||
{
|
||
png.fill(Qt::transparent);
|
||
JKQTPEnhancedPainter painter;
|
||
painter.begin(&png);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::NonCosmeticDefaultPen, true);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::SmoothPixmapTransform);
|
||
painter.setRenderHint(JKQTPEnhancedPainter::HighQualityAntialiasing);
|
||
|
||
/*calcPlotScaling(painter);
|
||
gridPaint(painter, png.rect().size());*/
|
||
exportpreviewPaintRequested(painter, QSize(printSizeX_Millimeter, printSizeY_Millimeter));
|
||
painter.end();
|
||
}
|
||
QByteArray svgdata;
|
||
{
|
||
|
||
QBuffer buffer(&svgdata);
|
||
QSvgGenerator* svg=new QSvgGenerator;
|
||
svg->setResolution(96);
|
||
//svg->setResolution(300);
|
||
QSize size=QSize(printSizeX_Millimeter, printSizeX_Millimeter);
|
||
double factor=double(size.width())/double(widgetWidth)*paintMagnification;
|
||
// TODO: CORRECT THIS
|
||
//qDebug()<<size;
|
||
svg->setSize(size);
|
||
svg->setOutputDevice(&buffer);
|
||
JKQTPEnhancedPainter painter;
|
||
painter.begin(svg);
|
||
painter.scale(factor,factor);
|
||
printAspect=printSizeY_Millimeter/printSizeX_Millimeter;
|
||
exportpreviewPaintRequested(painter, QSize(widgetWidth/paintMagnification, widgetWidth/paintMagnification*printAspect));
|
||
painter.end();
|
||
delete svg;
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
QClipboard *clipboard = QApplication::clipboard();
|
||
//qDebug()<<"clipboard before adding content:\n"<<clipboard->mimeData()->formats();
|
||
//clipboard->setImage(png);
|
||
clipboard->clear();
|
||
clipboard->setPixmap(QPixmap::fromImage(png));
|
||
QMimeData* mime=new QMimeData();
|
||
mime->setImageData(QPixmap::fromImage(png));
|
||
QBuffer pngbuf;
|
||
png.save(&pngbuf, "png");
|
||
mime->setData("image/x-png", pngbuf.data());
|
||
png.save(&pngbuf, "bmp");
|
||
mime->setData("image/bmp", pngbuf.data());
|
||
mime->setData("image/svg+xml", svgdata);
|
||
clipboard->setMimeData(mime);
|
||
//qDebug()<<"clipboard after adding content:\n"<<clipboard->mimeData()->formats();
|
||
|
||
|
||
|
||
|
||
QApplication::restoreOverrideCursor();
|
||
|
||
//}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
void JKQtBasePlotter::saveAsSVG(QString filename, bool displayPreview) {
|
||
loadUserSettings();
|
||
QString fn=filename;
|
||
if (fn.isEmpty()) {
|
||
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot"),
|
||
currentSaveDirectory,
|
||
tr("SVG Image (*.svg)"));
|
||
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
||
}
|
||
|
||
if (!fn.isEmpty()) {
|
||
QString tempFM="";
|
||
if (QFile::exists(fn)) {
|
||
#ifdef QFWIDLIB_LIBRARY
|
||
QFTemporaryFile* tf=new QFTemporaryFile();
|
||
#else
|
||
QTemporaryFile* tf=new QTemporaryFile();
|
||
#endif
|
||
tf->open();
|
||
tempFM=tf->fileName();
|
||
tf->close();
|
||
delete tf;
|
||
QFile::copy(fn, tempFM);
|
||
}
|
||
|
||
gridPrintingCalc();
|
||
QSvgGenerator* svg=new QSvgGenerator;
|
||
svg->setResolution(96);
|
||
QSize size=QSize(gridPrintingSize.width()*25.4/svg->resolution(), gridPrintingSize.height()*25.4/svg->resolution());
|
||
svg->setSize(size);
|
||
svg->setFileName(fn);
|
||
|
||
if (!printpreviewNew(svg, true, -1.0, -1.0, displayPreview)) {
|
||
if (QFile::exists(tempFM)) {
|
||
QFile::copy(tempFM, fn);
|
||
QFile::remove(tempFM);
|
||
}
|
||
}
|
||
|
||
delete svg;
|
||
|
||
}
|
||
saveUserSettings();
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::setBorder(int left, int right, int top, int bottom){
|
||
plotBorderTop=top;
|
||
plotBorderLeft=left;
|
||
plotBorderBottom=bottom;
|
||
plotBorderRight=right;
|
||
//updateGeometry();
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::synchronizeToMaster(JKQtBasePlotter* master, bool synchronizeWidth, bool synchronizeHeight) {
|
||
if (!master) {
|
||
resetMasterSynchronization();
|
||
}
|
||
masterPlotter=master;
|
||
masterSynchronizeHeight=synchronizeHeight;
|
||
masterSynchronizeWidth=synchronizeWidth;
|
||
}
|
||
|
||
void JKQtBasePlotter::resetMasterSynchronization() {
|
||
masterPlotter=nullptr;
|
||
masterSynchronizeHeight=false;
|
||
masterSynchronizeWidth=false;
|
||
}
|
||
|
||
|
||
|
||
size_t JKQtBasePlotter::addGraph(size_t xColumn, size_t yColumn, QString title, JKQTPgraphPlotstyle graphStyle) {
|
||
if (graphStyle==JKQTPimpulsesHorizontal) {
|
||
JKQTPimpulsesVerticalGraph* gr=new JKQTPimpulsesVerticalGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPimpulsesVertical) {
|
||
JKQTPimpulsesHorizontalGraph* gr=new JKQTPimpulsesHorizontalGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPfilledCurveX) {
|
||
JKQTPfilledCurveXGraph* gr=new JKQTPfilledCurveXGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPfilledCurveY) {
|
||
JKQTPfilledCurveYGraph* gr=new JKQTPfilledCurveYGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPstepsX) {
|
||
JKQTPstepHorizontalGraph* gr=new JKQTPstepHorizontalGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPstepsY) {
|
||
JKQTPstepVerticalGraph* gr=new JKQTPstepVerticalGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
return addGraph(gr);
|
||
} else {
|
||
JKQTPxyLineGraph* gr=new JKQTPxyLineGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
if (graphStyle==JKQTPpoints) { gr->set_symbol(JKQTPplus); gr->set_drawLine(false); }
|
||
else if (graphStyle==JKQTPlinesPoints) gr->set_symbol(JKQTPplus);
|
||
return addGraph(gr);
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
size_t JKQtBasePlotter::addGraph(size_t xColumn, size_t yColumn, QString title, JKQTPgraphPlotstyle graphStyle, QColor color, JKQTPgraphSymbols symbol, Qt::PenStyle penstyle, double width) {
|
||
if (graphStyle==JKQTPimpulsesHorizontal) {
|
||
JKQTPimpulsesVerticalGraph* gr=new JKQTPimpulsesVerticalGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_color(color);
|
||
gr->set_lineWidth(width);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPimpulsesVertical) {
|
||
JKQTPimpulsesHorizontalGraph* gr=new JKQTPimpulsesHorizontalGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_color(color);
|
||
gr->set_lineWidth(width);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPfilledCurveX) {
|
||
JKQTPfilledCurveXGraph* gr=new JKQTPfilledCurveXGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_color(QColor("black"));
|
||
gr->set_lineWidth(width);
|
||
gr->set_style(penstyle);
|
||
gr->set_fillColor(color);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPfilledCurveY) {
|
||
JKQTPfilledCurveYGraph* gr=new JKQTPfilledCurveYGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_color(QColor("black"));
|
||
gr->set_lineWidth(width);
|
||
gr->set_style(penstyle);
|
||
gr->set_fillColor(color);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPstepsX) {
|
||
JKQTPstepHorizontalGraph* gr=new JKQTPstepHorizontalGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_color(QColor("black"));
|
||
gr->set_lineWidth(width);
|
||
gr->set_style(penstyle);
|
||
gr->set_fillColor(color);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPstepsY) {
|
||
JKQTPstepVerticalGraph* gr=new JKQTPstepVerticalGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_color(QColor("black"));
|
||
gr->set_lineWidth(width);
|
||
gr->set_style(penstyle);
|
||
gr->set_fillColor(color);
|
||
return addGraph(gr);
|
||
} else {
|
||
JKQTPxyLineGraph* gr=new JKQTPxyLineGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_lineWidth(width);
|
||
gr->set_style(penstyle);
|
||
gr->set_color(color);
|
||
gr->set_symbol(symbol);
|
||
if (graphStyle==JKQTPpoints) { gr->set_symbol(JKQTPplus); gr->set_drawLine(false); }
|
||
else if (graphStyle==JKQTPlinesPoints) gr->set_symbol(JKQTPplus);
|
||
return addGraph(gr);
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
size_t JKQtBasePlotter::addHorizontalBoxplot(QString title, int posColumn, int medianColumn, int minColumn, int maxColumn, int percentile25Column, int percentile75Column, int meanColumn) {
|
||
JKQTPboxplotHorizontalGraph* box=new JKQTPboxplotHorizontalGraph(this);
|
||
box->set_posColumn(posColumn);
|
||
box->set_medianColumn(medianColumn);
|
||
box->set_meanColumn(meanColumn);
|
||
box->set_minColumn(minColumn);
|
||
box->set_maxColumn(maxColumn);
|
||
box->set_percentile25Column(percentile25Column);
|
||
box->set_percentile75Column(percentile75Column);
|
||
box->set_title(title);
|
||
return addGraph(box);
|
||
}
|
||
|
||
size_t JKQtBasePlotter::addVerticalBoxplot(QString title, int posColumn, int medianColumn, int minColumn, int maxColumn, int percentile25Column, int percentile75Column, int meanColumn) {
|
||
JKQTPboxplotVerticalGraph* box=new JKQTPboxplotVerticalGraph(this);
|
||
box->set_posColumn(posColumn);
|
||
box->set_medianColumn(medianColumn);
|
||
box->set_meanColumn(meanColumn);
|
||
box->set_minColumn(minColumn);
|
||
box->set_maxColumn(maxColumn);
|
||
box->set_percentile25Column(percentile25Column);
|
||
box->set_percentile75Column(percentile75Column);
|
||
box->set_title(title);
|
||
return addGraph(box);
|
||
}
|
||
|
||
void JKQtBasePlotter::addHorizontalBargraph(size_t xColumn, QVector<size_t> yColumns, QStringList titles) {
|
||
double w=0.9;
|
||
double width=w/(double)yColumns.size();
|
||
double s=-1.0*w/2.0+width/2.0;
|
||
for (int i=0; i<yColumns.size(); i++) {
|
||
JKQTPbarVerticalGraph* g=new JKQTPbarVerticalGraph(this);
|
||
g->set_title(titles[i]);
|
||
g->set_xColumn(xColumn);
|
||
g->set_yColumn(yColumns[i]);
|
||
g->set_shift(s);
|
||
g->set_width(width);
|
||
//std::cout<<"shift="<<s<<" width="<<width<<std::endl;
|
||
s=s+width;
|
||
addGraph(g);
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::addVerticalBargraph(QVector<size_t> xColumns, size_t yColumn, QStringList titles) {
|
||
double w=0.9;
|
||
double width=w/(double)xColumns.size();
|
||
double s=-1.0*w/2.0+width/2.0;
|
||
for (int i=0; i<xColumns.size(); i++) {
|
||
JKQTPbarHorizontalGraph* g=new JKQTPbarHorizontalGraph(this);
|
||
g->set_title(titles[i]);
|
||
g->set_xColumn(xColumns[i]);
|
||
g->set_yColumn(yColumn);
|
||
g->set_shift(s);
|
||
g->set_width(width);
|
||
//std::cout<<"shift="<<s<<" width="<<width<<std::endl;
|
||
s=s+width;
|
||
addGraph(g);
|
||
}
|
||
}
|
||
|
||
size_t JKQtBasePlotter::addGraphWithXError(size_t xColumn, size_t yColumn, size_t xErrorColumn, QString title, JKQTPgraphPlotstyle graphStyle, JKQTPerrorPlotstyle errorStyle){
|
||
if (graphStyle==JKQTPimpulsesHorizontal) {
|
||
JKQTPimpulsesHorizontalErrorGraph* gr=new JKQTPimpulsesHorizontalErrorGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_xErrorStyle(errorStyle);
|
||
gr->set_xErrorColumn(xErrorColumn);
|
||
gr->set_errorColor(gr->get_color().darker());
|
||
QColor fc=gr->get_color();
|
||
fc.setAlphaF(0.5);
|
||
gr->set_errorFillColor(fc);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPfilledCurveY) {
|
||
JKQTPfilledCurveYErrorGraph* gr=new JKQTPfilledCurveYErrorGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_xErrorStyle(errorStyle);
|
||
gr->set_xErrorColumn(xErrorColumn);
|
||
gr->set_errorColor(gr->get_color());
|
||
QColor fc=gr->get_color();
|
||
fc.setAlphaF(0.5);
|
||
gr->set_errorFillColor(fc);
|
||
return addGraph(gr);
|
||
} else {
|
||
JKQTPxyLineErrorGraph* gr=new JKQTPxyLineErrorGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_yErrorColumn(xErrorColumn);
|
||
gr->set_yErrorStyle(errorStyle);
|
||
gr->set_xErrorStyle(JKQTPnoError);
|
||
gr->set_errorColor(gr->get_color());
|
||
QColor fc=gr->get_color();
|
||
fc.setAlphaF(0.5);
|
||
gr->set_errorFillColor(fc);
|
||
if (graphStyle==JKQTPpoints) { gr->set_symbol(JKQTPplus); gr->set_drawLine(false); }
|
||
else if (graphStyle==JKQTPlinesPoints) gr->set_symbol(JKQTPplus);
|
||
return addGraph(gr);
|
||
}
|
||
|
||
}
|
||
|
||
size_t JKQtBasePlotter::addGraphWithYError(size_t xColumn, size_t yColumn, size_t yErrorColumn, QString title, JKQTPgraphPlotstyle graphStyle, JKQTPerrorPlotstyle errorStyle){
|
||
if (graphStyle==JKQTPimpulsesVertical) {
|
||
JKQTPimpulsesVerticalErrorGraph* gr=new JKQTPimpulsesVerticalErrorGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_yErrorStyle(errorStyle);
|
||
gr->set_yErrorColumn(yErrorColumn);
|
||
gr->set_errorColor(gr->get_color().darker());
|
||
gr->set_errorWidth(gr->get_lineWidth()/3.0);
|
||
QColor fc=gr->get_color();
|
||
fc.setAlphaF(0.5);
|
||
gr->set_errorFillColor(fc);
|
||
return addGraph(gr);
|
||
} else if (graphStyle==JKQTPfilledCurveX) {
|
||
JKQTPfilledCurveXErrorGraph* gr=new JKQTPfilledCurveXErrorGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_yErrorStyle(errorStyle);
|
||
gr->set_yErrorColumn(yErrorColumn);
|
||
gr->set_errorColor(gr->get_color());
|
||
QColor fc=gr->get_color();
|
||
fc.setAlphaF(0.5);
|
||
gr->set_errorFillColor(fc);
|
||
return addGraph(gr);
|
||
} else {
|
||
JKQTPxyLineErrorGraph* gr=new JKQTPxyLineErrorGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_yErrorColumn(yErrorColumn);
|
||
gr->set_yErrorStyle(errorStyle);
|
||
gr->set_xErrorStyle(JKQTPnoError);
|
||
gr->set_errorColor(gr->get_color());
|
||
QColor fc=gr->get_color();
|
||
fc.setAlphaF(0.5);
|
||
gr->set_errorFillColor(fc);
|
||
if (graphStyle==JKQTPpoints) { gr->set_symbol(JKQTPplus); gr->set_drawLine(false); }
|
||
else if (graphStyle==JKQTPlinesPoints) gr->set_symbol(JKQTPplus);
|
||
return addGraph(gr);
|
||
}
|
||
}
|
||
|
||
size_t JKQtBasePlotter::addGraphWithXYError(size_t xColumn, size_t yColumn, size_t xErrorColumn, size_t yErrorColumn, QString title, JKQTPgraphPlotstyle graphStyle){
|
||
JKQTPxyLineErrorGraph* gr=new JKQTPxyLineErrorGraph(this);
|
||
gr->set_title(title);
|
||
gr->set_xColumn(xColumn);
|
||
gr->set_yColumn(yColumn);
|
||
gr->set_yErrorColumn(yErrorColumn);
|
||
gr->set_yErrorStyle(JKQTPerrorBars);
|
||
gr->set_xErrorColumn(xErrorColumn);
|
||
gr->set_xErrorStyle(JKQTPerrorBars);
|
||
gr->set_errorColor(gr->get_color());
|
||
QColor fc=gr->get_color();
|
||
fc.setAlphaF(0.5);
|
||
gr->set_errorFillColor(fc);
|
||
if (graphStyle==JKQTPpoints) { gr->set_symbol(JKQTPplus); gr->set_drawLine(false); }
|
||
else if (graphStyle==JKQTPlinesPoints) gr->set_symbol(JKQTPplus);
|
||
return addGraph(gr);
|
||
|
||
}
|
||
|
||
|
||
|
||
void JKQtBasePlotter::plotGraphs(JKQTPEnhancedPainter& painter){
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot(QString("JKQtBasePlotter::plotGraphs"));
|
||
#endif
|
||
if (datastore==nullptr || graphs.isEmpty()) return;
|
||
//qDebug()<<"start JKQtPlotterBase::plotGraphs()";
|
||
if (useClipping) {
|
||
QRegion cregion(iplotBorderLeft, iplotBorderTop, plotWidth, plotHeight);
|
||
painter.setClipping(true);
|
||
painter.setClipRegion(cregion);
|
||
}
|
||
|
||
int ibTop=iplotBorderTop_nographs-plotBorderTop;
|
||
int ibLeft=iplotBorderLeft_nographs-plotBorderLeft;
|
||
int ibBottom=iplotBorderBottom_nographs-plotBorderBottom;
|
||
int ibRight=iplotBorderRight_nographs-plotBorderRight;
|
||
|
||
|
||
for (int j=0; j<graphs.size(); j++) {
|
||
//int leftSpace, rightSpace, topSpace, bottomSpace;
|
||
JKQTPgraph* g=graphs[j];
|
||
//qDebug()<<" drawing JKQTPgraph"<<j<<g->get_title()<<g->metaObject()->className();
|
||
if (g->get_visible()) g->draw(painter);
|
||
}
|
||
|
||
if (useClipping) {
|
||
painter.setClipping(false);
|
||
}
|
||
|
||
for (int j=0; j<graphs.size(); j++) {
|
||
int leftSpace, rightSpace, topSpace, bottomSpace;
|
||
JKQTPgraph* g=graphs[j];
|
||
if (g->get_visible()) {
|
||
g->getOutsideSize(painter, leftSpace, rightSpace, topSpace, bottomSpace);
|
||
ibTop+=topSpace;
|
||
ibLeft+=leftSpace;
|
||
g->drawOutside(painter, QRect(iplotBorderLeft+iplotKeyBorderLeft-ibLeft, iplotBorderTop, leftSpace, plotHeight),
|
||
QRect(iplotBorderLeft+plotWidth+ibRight-iplotKeyBorderRight, iplotBorderTop, rightSpace, plotHeight),
|
||
QRect(iplotBorderLeft, iplotBorderTop-ibTop+iplotKeyBorderTop, plotWidth, topSpace),
|
||
QRect(iplotBorderLeft, iplotBorderTop+plotHeight+ibBottom, plotWidth, bottomSpace)
|
||
);
|
||
ibRight+=rightSpace;
|
||
ibBottom+=bottomSpace;
|
||
}
|
||
}
|
||
|
||
//qDebug()<<" end JKQtPlotterBase::plotGraphs()";
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::plotKeyContents(JKQTPEnhancedPainter& painter, double x, double y, double /*width*/, double /*height*/){
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot(QString("JKQtBasePlotter::plotKeyContents(%1, %2, %3, %4)").arg(x).arg(y).arg(width).arg(height));
|
||
#endif
|
||
painter.save();
|
||
|
||
double key_text_width=0;
|
||
double key_text_height=0;
|
||
double dw, dh;
|
||
int columns=1;
|
||
int lines=1;
|
||
getKeyExtent(painter, &dw, &dh, &key_text_width, &key_text_height, &columns, &lines);
|
||
|
||
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
||
qDebug()<<"key_item_height="<<key_item_height;
|
||
qDebug()<<"plotKey(): dw="<<dw<<" dh="<<dh<<" key_text_width="<<key_text_width<<" key_text_height="<<key_text_height<<" columns="<<columns<<" lines="<<lines<<" keyLayout="<<keyLayout;
|
||
#endif
|
||
QFont kf(keyFont, keyFontSize*fontSizeMultiplier);
|
||
QFontMetricsF kfm(kf);
|
||
|
||
if (keyLayout==JKQTPkeyLayoutOneColumn) {
|
||
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
JKQTPgraph* g=graphs[i];
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
jkaaot.write(QString("one-col: graph %1: %2").arg(i).arg(g->get_title()));
|
||
#endif
|
||
if (!g->get_title().isEmpty() && g->get_visible()) {
|
||
QSizeF fs=getTextSizeSize(keyFont,keyFontSize*fontSizeMultiplier,g->get_title(),painter);// mt.getSize(painter);
|
||
double itheight=qMax(key_item_height*kfm.width('X'), fs.height());
|
||
QRectF rect(x, y+1.5*lineWidthMultiplier, key_line_length*kfm.width('X'), itheight-3.0*lineWidthMultiplier);
|
||
g->drawKeyMarker(painter, rect);
|
||
mathText.set_fontColor(QColor("black"));
|
||
mathText.set_fontSize(keyFontSize*fontSizeMultiplier);
|
||
mathText.set_fontRoman(keyFont);
|
||
|
||
mathText.parse(g->get_title());
|
||
mathText.draw(painter, Qt::AlignLeft|Qt::AlignVCenter, QRectF(x+(key_line_length+keyXSeparation)*kfm.width('X'),y, key_text_width, itheight));
|
||
//if (itheight<key_item_height*kfm.height()) itheight=key_item_height*kfm.height();
|
||
//y=y+itheight+(keyYSeparation)*kfm.height();
|
||
y=y+key_text_height+(keyYSeparation)*kfm.width('X');
|
||
}
|
||
}
|
||
} else if (keyLayout==JKQTPkeyLayoutOneRow) {
|
||
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
JKQTPgraph* g=graphs[i];
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
jkaaot.write(QString("one-row: graph %1: %2").arg(i).arg(g->get_title()));
|
||
#endif
|
||
if (!g->get_title().isEmpty() && g->get_visible()) {
|
||
QSizeF fs=getTextSizeSize(keyFont,keyFontSize*fontSizeMultiplier,g->get_title(),painter);// mt.getSize(painter);
|
||
double itheight=qMax(key_item_height*kfm.width('X'), fs.height());
|
||
QRectF rect(x, y+1.5*lineWidthMultiplier, key_line_length*kfm.width('X'), itheight-3.0*lineWidthMultiplier);
|
||
g->drawKeyMarker(painter, rect);
|
||
mathText.set_fontColor(QColor("black"));
|
||
mathText.set_fontSize(keyFontSize*fontSizeMultiplier);
|
||
mathText.set_fontRoman(keyFont);
|
||
|
||
mathText.parse(g->get_title());
|
||
mathText.draw(painter, Qt::AlignLeft|Qt::AlignVCenter, QRectF(x+(key_line_length+keyXSeparation)*kfm.width('X'),y, fs.width(), itheight));
|
||
//if (itheight<key_item_height*kfm.height()) itheight=key_item_height*kfm.height();
|
||
//y=y+itheight+(keyYSeparation)*kfm.height();
|
||
x=x+fs.width()+(2.0*keyXSeparation+key_line_length)*kfm.width('X');
|
||
}
|
||
}
|
||
} else if (keyLayout==JKQTPkeyLayoutMultiColumn) {
|
||
//int columns=floor(static_cast<double>(plotWidth)/(double)(key_item_width*kfm.width('X')));
|
||
bool colfirst=true;
|
||
|
||
if (keyPosition==JKQTPkeyInsideTopLeft || keyPosition==JKQTPkeyInsideTopRight
|
||
|| keyPosition==JKQTPkeyOutsideTopLeft || keyPosition==JKQTPkeyOutsideTopRight) {
|
||
colfirst=false;
|
||
}
|
||
|
||
int l=1;
|
||
int c=1;
|
||
double xx=x;
|
||
double yy=y;
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
JKQTPgraph* g=graphs[i];
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
jkaaot.write(QString("multi-col: graph %1: %2").arg(i).arg(g->get_title()));
|
||
#endif
|
||
if (!g->get_title().isEmpty() && g->get_visible()) {
|
||
//QSizeF fs=getTextSizeSize(keyFont,keyFontSize*fontSizeMultiplier,g->get_title(),painter);// mt.getSize(painter);
|
||
double itheight=qMax(key_item_height*kfm.width('X'), key_text_height);
|
||
QRectF rect(xx, yy+1.5*lineWidthMultiplier, key_line_length*kfm.width('X'), itheight-3.0*lineWidthMultiplier);
|
||
g->drawKeyMarker(painter, rect);
|
||
mathText.set_fontColor(QColor("black"));
|
||
mathText.set_fontSize(keyFontSize*fontSizeMultiplier);
|
||
mathText.set_fontRoman(keyFont);
|
||
mathText.parse(g->get_title());
|
||
//QSizeF fs=mt.getSize(painter);
|
||
mathText.draw(painter, Qt::AlignLeft|Qt::AlignVCenter, QRectF(xx+(key_line_length+keyXSeparation)*kfm.width('X'),yy, key_text_width, key_text_height));
|
||
|
||
if (colfirst) {
|
||
yy=yy+key_text_height+(keyYSeparation)*kfm.width('X');
|
||
l++;
|
||
if (l>lines) {
|
||
l=1;
|
||
c++;
|
||
xx=xx+key_text_width+(key_line_length+2.0*keyXSeparation)*kfm.width('X');
|
||
/*if (keyAutosize) xx=xx+key_text_width+(key_line_length+3.0*keyXSeparation)*kfm.width('X');
|
||
else xx=xx+(key_item_width+2.0*keyXSeparation)*kfm.width('X');*/
|
||
yy=y;
|
||
}
|
||
} else {
|
||
/*if (keyAutosize) xx=xx+key_text_width+(key_line_length+3.0*keyXSeparation)*kfm.width('X');
|
||
else xx=xx+(key_item_width+2.0*keyXSeparation)*kfm.width('X');*/
|
||
xx=xx+key_text_width+(key_line_length+2.0*keyXSeparation)*kfm.width('X');
|
||
c++;
|
||
if (c>columns) {
|
||
c=1;
|
||
l++;
|
||
//yy=yy+(key_item_height+keyYSeparation)*kfm.height();
|
||
yy=yy+itheight+(keyYSeparation)*kfm.width('X');
|
||
xx=x;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/*painter.setPen(pold);
|
||
painter.setBrush(bold);*/
|
||
|
||
painter.restore();
|
||
}
|
||
|
||
void JKQtBasePlotter::getKeyExtent(JKQTPEnhancedPainter& painter, double* width, double* height, double* text_width, double* text_height, int* columns_count, int *lines_count) {
|
||
#ifdef JKQTBP_AUTOTIMER
|
||
JKQTPAutoOutputTimer jkaaot("JKQtBasePlotter::getKeyExtent");
|
||
#endif
|
||
QFont f=painter.font();
|
||
f.setFamily(keyFont);
|
||
f.setPointSizeF(keyFontSize*fontSizeMultiplier);
|
||
QFontMetricsF kfm(f);
|
||
if (text_height!=nullptr) *text_height=key_item_height*kfm.width('X');
|
||
if (keyLayout==JKQTPkeyLayoutOneColumn) {
|
||
int keyHeight=graphs.size();
|
||
double w=0;
|
||
double h=0;
|
||
painter.setFont(f);
|
||
if (text_height!=nullptr) *text_height=0;
|
||
|
||
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
if (graphs[i]->get_title().isEmpty() || !graphs[i]->get_visible()) {
|
||
keyHeight--;
|
||
} else {
|
||
//mt.parse(graphs[i]->get_title());
|
||
//QSizeF fs=mt.getSize(painter);
|
||
QSizeF fs=getTextSizeSize(keyFont, keyFontSize*fontSizeMultiplier, graphs[i]->get_title(), painter);
|
||
if (fs.width()>w) w=fs.width();
|
||
if (text_height && fs.height()>*text_height) *text_height=fs.height();
|
||
h=h+qMax(key_item_height*kfm.width('X'), fs.height())+keyYSeparation*kfm.width('X');
|
||
}
|
||
}
|
||
if (keyAutosize) {
|
||
if (width) *width=w+(key_line_length+2.0*keyXSeparation)*kfm.width('X');
|
||
if (text_width!=nullptr) *text_width=w+2.0*kfm.width('X');
|
||
} else {
|
||
if (width) *width=key_item_width*kfm.width('X');
|
||
if (text_width!=nullptr) *text_width=(key_item_width-(key_line_length+keyXSeparation))*kfm.width('X');
|
||
}
|
||
if (h>keyYSeparation*kfm.width('X')) h=h-keyYSeparation*kfm.width('X');
|
||
if (height) *height=h;//keyHeight*key_item_height*kfm.width('X');
|
||
if (columns_count) *columns_count=1;
|
||
if (lines_count) *lines_count=keyHeight;
|
||
} else if (keyLayout==JKQTPkeyLayoutOneRow) {
|
||
int keyWidth=graphs.size();
|
||
double w=0;
|
||
double h=0;
|
||
painter.setFont(f);
|
||
if (text_width!=nullptr) *text_width=0;
|
||
|
||
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
if (graphs[i]->get_title().isEmpty() || !graphs[i]->get_visible()) {
|
||
keyWidth--;
|
||
} else {
|
||
//mt.parse(graphs[i]->get_title());
|
||
//QSizeF fs=mt.getSize(painter);
|
||
QSizeF fs=getTextSizeSize(keyFont, keyFontSize*fontSizeMultiplier, graphs[i]->get_title(), painter);
|
||
if (fs.height()>h) h=fs.height();
|
||
if (text_width && fs.width()>*text_width) *text_width=fs.width();
|
||
w=w+fs.width()+(key_line_length+2.0*keyXSeparation)*kfm.width('X');
|
||
}
|
||
}
|
||
if (h<key_item_height*kfm.width('X')) h=key_item_height*kfm.width('X');
|
||
if (keyAutosize) {
|
||
if (height) *height=h;
|
||
if (text_height!=nullptr) *text_height=h;
|
||
} else {
|
||
if (height) *height=h;
|
||
if (text_height!=nullptr) *text_height=(key_item_height-(keyYSeparation))*kfm.width('X');
|
||
}
|
||
if (w>(keyXSeparation)*kfm.width('X')) w=w-(keyXSeparation)*kfm.width('X');
|
||
if (width) *width=w;//keyHeight*key_item_height*kfm.width('X');
|
||
if (columns_count) *columns_count=keyWidth;
|
||
if (lines_count) *lines_count=1;
|
||
} else if (keyLayout==JKQTPkeyLayoutMultiColumn) {
|
||
|
||
// copied code in plotKeyContents()!!!
|
||
double keyHeight=graphs.size();
|
||
double w=0;
|
||
double txtH=0;
|
||
QFont f=painter.font();
|
||
f.setFamily(keyFont);
|
||
f.setPointSizeF(keyFontSize*fontSizeMultiplier);
|
||
painter.setFont(f);
|
||
|
||
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
if (graphs[i]->get_title().isEmpty() || !graphs[i]->get_visible()) {
|
||
keyHeight--;
|
||
} else {
|
||
//mt.parse(graphs[i]->get_title());
|
||
//QSizeF fs=mt.getSize(painter);
|
||
QSizeF fs=getTextSizeSize(keyFont, keyFontSize*fontSizeMultiplier, graphs[i]->get_title(), painter);
|
||
if (fs.width()>w) w=fs.width();
|
||
if ( fs.height()>txtH) txtH=fs.height();
|
||
}
|
||
}
|
||
|
||
if (text_height) {
|
||
if (keyAutosize) *text_height=txtH;
|
||
else *text_height=key_item_height*kfm.width('X');
|
||
}
|
||
|
||
|
||
double columns=floor(double(plotWidth)/(w+(2.0*keyXSeparation+key_line_length)*kfm.width('X')));
|
||
if (!keyAutosize) columns=floor(double(plotWidth)/((key_item_width+2.0*keyXSeparation+key_line_length)*kfm.width('X')));
|
||
columns=qMin(columns, keyHeight);
|
||
int lines=(int)ceil((double)keyHeight/(double)columns);
|
||
lines=qMin((double)lines, keyHeight);
|
||
|
||
if (keyPosition==JKQTPkeyInsideTopLeft || keyPosition==JKQTPkeyInsideTopRight
|
||
|| keyPosition==JKQTPkeyOutsideTopLeft || keyPosition==JKQTPkeyOutsideTopRight) {
|
||
if (keyAutosize) {
|
||
lines=(int)floor(static_cast<double>(plotHeight)/(double)(txtH+(keyYSeparation)*kfm.width('X')));
|
||
} else {
|
||
lines=(int)floor(static_cast<double>(plotHeight)/(double)((key_item_height+keyYSeparation)*kfm.width('X')));
|
||
}
|
||
columns=(int)ceil((double)keyHeight/(double)lines);
|
||
lines=qMin((double)lines, keyHeight);
|
||
|
||
}
|
||
|
||
if (columns_count) *columns_count=columns;
|
||
if (lines_count) *lines_count=lines;
|
||
|
||
if (keyAutosize) {
|
||
if (width) *width=(w+(key_line_length+3.0*keyXSeparation)*kfm.width('X'))*columns;
|
||
if (height) *height=lines*(txtH+keyYSeparation*kfm.width('X'));
|
||
if (lines>0) *height=*height-keyYSeparation*kfm.width('X');
|
||
if (text_width!=nullptr) *text_width=w;
|
||
} else {
|
||
if (width) *width=(key_item_width+2.0*keyXSeparation)*kfm.width('X')*columns;
|
||
if (height) *height=lines*(key_item_height+keyYSeparation)*kfm.width('X');
|
||
if (lines>0) *height=*height-keyYSeparation*kfm.width('X');
|
||
if (text_width!=nullptr) *text_width=(key_item_width-(key_line_length+keyXSeparation))*kfm.width('X');
|
||
}
|
||
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
||
qDebug()<<"getKeyExtent(): mult-column: columns="<<columns<<" lines="<<lines;
|
||
#endif
|
||
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::loadUserSettings()
|
||
{
|
||
if (!userSettigsFilename.isEmpty()) {
|
||
QSettings set(userSettigsFilename, QSettings::IniFormat);
|
||
set.sync();
|
||
loadUserSettings(set, userSettigsPrefix);
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::saveUserSettings()
|
||
{
|
||
if (!userSettigsFilename.isEmpty()) {
|
||
QSettings set(userSettigsFilename, QSettings::IniFormat);
|
||
saveUserSettings(set, userSettigsPrefix);
|
||
set.sync();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void JKQtBasePlotter::getGraphsXMinMax(double& minx, double& maxx, double& smallestGreaterZero) {
|
||
bool start=true;
|
||
minx=0;
|
||
maxx=0;
|
||
smallestGreaterZero=0;
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
if (graphs[i]->get_visible()) {
|
||
double gminx=0;
|
||
double gmaxx=0;
|
||
double gsmallestGreaterZero=0;
|
||
if (graphs[i]->getXMinMax(gminx, gmaxx, gsmallestGreaterZero)) {
|
||
if ((gminx<minx) || start) minx=gminx;
|
||
if ((gmaxx>maxx) || start) maxx=gmaxx;
|
||
|
||
double xvsgz;
|
||
xvsgz=gsmallestGreaterZero; if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
||
xvsgz=gmaxx; if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
||
xvsgz=gminx; if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
||
|
||
//std::cout<<" i="<<i<<": gminx="<<gminx<<" gmaxx="<<gmaxx<<" minx="<<minx<<" maxx="<<maxx<<std::endl;
|
||
|
||
start=false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::getGraphsYMinMax(double& miny, double& maxy, double& smallestGreaterZero) {
|
||
bool start=true;
|
||
miny=0;
|
||
maxy=0;
|
||
smallestGreaterZero=0;
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
if (graphs[i]->get_visible()) {
|
||
double gminy=0;
|
||
double gmaxy=0;
|
||
double gsmallestGreaterZero=0;
|
||
if (graphs[i]->getYMinMax(gminy, gmaxy, gsmallestGreaterZero)) {
|
||
if ((gminy<miny) || start) miny=gminy;
|
||
if ((gmaxy>maxy) || start) maxy=gmaxy;
|
||
|
||
double xvsgz;
|
||
xvsgz=gsmallestGreaterZero; if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
||
xvsgz=gmaxy; if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
||
xvsgz=gminy; if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
||
|
||
start=false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::zoomToFit(bool zoomX, bool zoomY, bool includeX0, bool includeY0, double scaleX, double scaleY) {
|
||
//std::cout<<"JKQtPlotterBase::zoomToFit():\n";
|
||
double xxmin;
|
||
double xxmax;
|
||
double xsmallestGreaterZero;
|
||
if (graphs.size()<=0) return;
|
||
if (zoomX) {
|
||
getGraphsXMinMax(xxmin, xxmax, xsmallestGreaterZero);
|
||
//std::cout<<" xxmin="<<xxmin<<" xxmax="<<xxmax<<std::endl;
|
||
if (JKQTPIsOKFloat(xxmin) && JKQTPIsOKFloat(xxmax)) {
|
||
bool doScale=true;
|
||
if (fabs(xxmin-xxmax)<1e-305) {
|
||
xxmin=xAxis->getMin();
|
||
xxmax=xAxis->getMax();
|
||
doScale=false;
|
||
}
|
||
if (xAxis->isLogAxis()) {
|
||
if ((xxmin<=1e-305)&&(xxmax<=1e-305)) {xxmin=0.1; xxmax=1.0; }
|
||
else if ((xxmin<=1e-305)&&(xxmax>0)) {
|
||
if (xsmallestGreaterZero>10.0*DBL_MIN) xxmin=xsmallestGreaterZero;
|
||
else xxmin=xxmax/xAxis->get_logAxisBase();
|
||
}
|
||
if (doScale) {
|
||
double d=scaleX*(log(xxmax)-log(xxmin)); // new width
|
||
double c=(log(xxmax)+log(xxmin))/2.0; // center of interval
|
||
xxmin=exp(c-d/2.0);
|
||
xxmax=exp(c+d/2.0);
|
||
}
|
||
} else if (doScale) {
|
||
double d=scaleX*(xxmax-xxmin); // new width
|
||
double c=(xxmax+xxmin)/2.0; // center of interval
|
||
xxmin=c-d/2.0;
|
||
xxmax=c+d/2.0;
|
||
}
|
||
if (includeX0 && !xAxis->isLogAxis()) {
|
||
if (xxmin>0) xxmin=0;
|
||
else if (xxmax<0) xxmax=0;
|
||
}
|
||
//std::cout<<" => xxmin="<<xxmin<<" xxmax="<<xxmax<<std::endl;
|
||
if (JKQTPIsOKFloat(xxmin) && JKQTPIsOKFloat(xxmax)) {
|
||
setX(xxmin, xxmax);
|
||
} else if (!JKQTPIsOKFloat(xxmin) && JKQTPIsOKFloat(xxmax)) {
|
||
setX(getXMin(), xxmax);
|
||
} else if (JKQTPIsOKFloat(xxmin) && !JKQTPIsOKFloat(xxmax)) {
|
||
setX(xxmin, getXMax());
|
||
}
|
||
}
|
||
}
|
||
double yymin;
|
||
double yymax;
|
||
double ysmallestGreaterZero;
|
||
|
||
if (zoomY) {
|
||
getGraphsYMinMax(yymin, yymax, ysmallestGreaterZero);
|
||
//std::cout<<" yymin="<<yymin<<" yymax="<<yymax<<std::endl;
|
||
bool doScale=true;
|
||
if (fabs(yymin-yymax)<1e-305) {
|
||
yymin=yAxis->getMin();
|
||
yymax=yAxis->getMax();
|
||
doScale=false;
|
||
}
|
||
if (yAxis->get_logAxis()) {
|
||
if ((yymin<=1e-305)&&(yymax<=1e-305)) {yymin=0.1; yymax=1.0; }
|
||
else if ((yymin<=1e-305)&&(yymax>0)) {
|
||
if (ysmallestGreaterZero>10.0*DBL_MIN) yymin=ysmallestGreaterZero;
|
||
else yymin=yymax/yAxis->get_logAxisBase();
|
||
}
|
||
if (doScale) {
|
||
double d=scaleY*(log(yymax)-log(yymin)); // new width
|
||
double c=(log(yymax)+log(yymin))/2.0; // center of interval
|
||
yymin=exp(c-d/2.0);
|
||
yymax=exp(c+d/2.0);
|
||
}
|
||
} else if (doScale) {
|
||
double d=scaleY*(yymax-yymin); // new width
|
||
double c=(yymax+yymin)/2.0; // center of interval
|
||
yymin=c-d/2.0;
|
||
yymax=c+d/2.0;
|
||
}
|
||
if (includeY0 && !yAxis->get_logAxis()) {
|
||
if (yymin>0) yymin=0;
|
||
else if (yymax<0) yymax=0;
|
||
}
|
||
//std::cout<<" => yymin="<<yymin<<" yymax="<<yymax<<std::endl;
|
||
|
||
if (JKQTPIsOKFloat(yymin) && JKQTPIsOKFloat(yymax)) {
|
||
setY(yymin, yymax);
|
||
} else if (!JKQTPIsOKFloat(yymin) && JKQTPIsOKFloat(yymax)) {
|
||
setY(getYMin(), yymax);
|
||
} else if (JKQTPIsOKFloat(yymin) && !JKQTPIsOKFloat(yymax)) {
|
||
setY(yymin, getYMax());
|
||
}
|
||
|
||
}
|
||
//std::cout<<"end of zoomToFit\n";
|
||
//setXY(xxmin, xxmax, yymin, yymax);
|
||
if (emitSignals) emit zoomChangedLocally(xAxis->getMin(), xAxis->getMax(), yAxis->getMin(), yAxis->getMax(), this);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
JKQTPoverlayElement *JKQtBasePlotter::getOverlayElement(size_t i) {
|
||
return overlays[i];
|
||
}
|
||
|
||
size_t JKQtBasePlotter::getOverlayElementCount() {
|
||
return overlays.size();
|
||
}
|
||
|
||
void JKQtBasePlotter::deleteOverlayElement(size_t i, bool deletegraph) {
|
||
if (long(i)<0 || long(i)>=overlays.size()) return;
|
||
JKQTPoverlayElement* g=overlays[i];
|
||
overlays.removeAt(i);
|
||
if (deletegraph && g) delete g;
|
||
if (emitPlotSignals) emit overlaysUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::deleteOverlayElement(JKQTPoverlayElement *gr, bool deletegraph) {
|
||
int i=overlays.indexOf(gr);
|
||
while (i>=0) {
|
||
overlays.removeAt(i);
|
||
i=overlays.indexOf(gr);
|
||
}
|
||
|
||
if (deletegraph && gr) delete gr;
|
||
if (emitPlotSignals) emit overlaysUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::clearOverlayElement(bool deleteGraphs) {
|
||
for (int i=0; i<overlays.size(); i++) {
|
||
JKQTPoverlayElement* g=overlays[i];
|
||
if (g && deleteGraphs) delete g;
|
||
}
|
||
overlays.clear();
|
||
if (emitPlotSignals) emit overlaysUpdated();
|
||
}
|
||
|
||
size_t JKQtBasePlotter::addOverlayElement(JKQTPoverlayElement *gr) {
|
||
gr->setParent(this);
|
||
for (int i=0; i<overlays.size(); i++) {
|
||
if (overlays[i]==gr) return i;
|
||
}
|
||
overlays.push_back(gr);
|
||
if (emitPlotSignals) emit overlaysUpdated();
|
||
return overlays.size()-1;
|
||
}
|
||
|
||
bool JKQtBasePlotter::containsOverlayElement(JKQTPoverlayElement *gr) const {
|
||
for (int i=0; i<overlays.size(); i++) {
|
||
if (overlays[i]==gr) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
size_t JKQtBasePlotter::moveOverlayElementTop(JKQTPoverlayElement *gr) {
|
||
gr->setParent(this);
|
||
for (int i=0; i<overlays.size(); i++) {
|
||
if (overlays[i]==gr) {
|
||
if (i<overlays.size()-1) {
|
||
overlays.removeAt(i);
|
||
overlays.push_back(gr);
|
||
}
|
||
return overlays.size()-1;
|
||
}
|
||
}
|
||
overlays.push_back(gr);
|
||
if (emitPlotSignals) emit overlaysUpdated();
|
||
return overlays.size()-1;
|
||
}
|
||
|
||
void JKQtBasePlotter::addOverlayElements(const QList<JKQTPoverlayElement *> &gr) {
|
||
for (int i=0; i< gr.size(); i++) {
|
||
addOverlayElement(gr[i]);
|
||
}
|
||
}
|
||
|
||
QVector<QLineF> JKQtBasePlotter::getBoundingLinesX1Y1(QRectF* rect) const
|
||
{
|
||
QVector<QLineF> l;
|
||
const QPointF pmimi=QPointF(x2p(xAxis->getMin()), y2p(yAxis->getMin()));
|
||
const QPointF pmima=QPointF(x2p(xAxis->getMin()), y2p(yAxis->getMax()));
|
||
const QPointF pmami=QPointF(x2p(xAxis->getMax()), y2p(yAxis->getMin()));
|
||
const QPointF pmama=QPointF(x2p(xAxis->getMax()), y2p(yAxis->getMax()));
|
||
l.append(QLineF(pmimi, pmami));
|
||
l.append(QLineF(pmami, pmama));
|
||
l.append(QLineF(pmama, pmima));
|
||
l.append(QLineF(pmima, pmimi));
|
||
if (rect) *rect=QRectF(pmimi,pmama);
|
||
return l;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
JKQTPgraph* JKQtBasePlotter::getGraph(size_t i) {
|
||
return graphs[i];
|
||
};
|
||
|
||
size_t JKQtBasePlotter::getGraphCount() {
|
||
return graphs.size();
|
||
};
|
||
|
||
void JKQtBasePlotter::deleteGraph(size_t i, bool deletegraph) {
|
||
if (long(i)<0 || long(i)>=graphs.size()) return;
|
||
JKQTPgraph* g=graphs[i];
|
||
graphs.removeAt(i);
|
||
if (deletegraph && g) delete g;
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
};
|
||
|
||
void JKQtBasePlotter::deleteGraph(JKQTPgraph* gr, bool deletegraph) {
|
||
int i=graphs.indexOf(gr);
|
||
while (i>=0) {
|
||
graphs.removeAt(i);
|
||
i=graphs.indexOf(gr);
|
||
}
|
||
|
||
if (deletegraph && gr) delete gr;
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::clearGraphs(bool deleteGraphs) {
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
JKQTPgraph* g=graphs[i];
|
||
if (g && deleteGraphs) delete g;
|
||
}
|
||
graphs.clear();
|
||
usedStyles.clear();
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::setAllGraphsInvisible()
|
||
{
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
JKQTPgraph* g=graphs[i];
|
||
g->set_visible(false);
|
||
}
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::setAllGraphsVisible()
|
||
{
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
JKQTPgraph* g=graphs[i];
|
||
g->set_visible(true);
|
||
}
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::setGraphVisible(int i, bool visible)
|
||
{
|
||
JKQTPgraph* g=graphs.value(i, nullptr);
|
||
if (g) g->set_visible(visible);
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::setOnlyGraphVisible(int gr)
|
||
{
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
JKQTPgraph* g=graphs[i];
|
||
g->set_visible(false);
|
||
}
|
||
JKQTPgraph* g=graphs.value(gr, nullptr);
|
||
if (g) g->set_visible(true);
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
void JKQtBasePlotter::setOnlyNthGraphsVisible(int start, int n)
|
||
{
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
JKQTPgraph* g=graphs[i];
|
||
g->set_visible(false);
|
||
}
|
||
for (int i=start; i<graphs.size(); i+=n) {
|
||
JKQTPgraph* g=graphs.value(i, nullptr);
|
||
if (g) g->set_visible(true);
|
||
}
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
}
|
||
|
||
size_t JKQtBasePlotter::addGraph(JKQTPgraph* gr) {
|
||
gr->setParent(this);
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
if (graphs[i]==gr) return i;
|
||
}
|
||
graphs.push_back(gr);
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
return graphs.size()-1;
|
||
};
|
||
|
||
size_t JKQtBasePlotter::moveGraphTop(JKQTPgraph* gr) {
|
||
gr->setParent(this);
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
if (graphs[i]==gr) {
|
||
if (i<graphs.size()-1) {
|
||
graphs.removeAt(i);
|
||
graphs.push_back(gr);
|
||
}
|
||
return graphs.size()-1;
|
||
}
|
||
}
|
||
graphs.push_back(gr);
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
return graphs.size()-1;
|
||
}
|
||
|
||
size_t JKQtBasePlotter::moveGraphBottom(JKQTPgraph *gr)
|
||
{
|
||
gr->setParent(this);
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
if (graphs[i]==gr) {
|
||
if (i<graphs.size()-1) {
|
||
graphs.removeAt(i);
|
||
graphs.push_front(gr);
|
||
}
|
||
return 0;
|
||
}
|
||
}
|
||
graphs.push_front(gr);
|
||
if (emitPlotSignals) emit plotUpdated();
|
||
return graphs.size()-1;
|
||
};
|
||
|
||
bool JKQtBasePlotter::containsGraph(JKQTPgraph* gr) const {
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
if (graphs[i]==gr) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
|
||
void JKQtBasePlotter::setGraphsDataRange(long long datarange_start, long long datarange_end) {
|
||
for (int i=0; i<graphs.size(); i++) {
|
||
graphs[i]->set_datarange_start(datarange_start);
|
||
graphs[i]->set_datarange_end(datarange_end);
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::set_userSettigsFilename(const QString &filename, const QString &prefix)
|
||
{
|
||
userSettigsFilename=filename;
|
||
userSettigsPrefix=prefix;
|
||
}
|
||
|
||
void JKQtBasePlotter::set_userSettigsFilename(const QString &filename)
|
||
{
|
||
userSettigsFilename=filename;
|
||
}
|
||
|
||
void JKQtBasePlotter::set_userSettigsPrefix(const QString &prefix)
|
||
{
|
||
userSettigsPrefix=prefix;
|
||
}
|
||
|
||
QString JKQtBasePlotter::get_userSettigsFilename() const
|
||
{
|
||
return userSettigsFilename;
|
||
}
|
||
|
||
QString JKQtBasePlotter::get_userSettigsPrefix() const
|
||
{
|
||
return userSettigsPrefix;
|
||
}
|
||
|
||
QSet<int> JKQtBasePlotter::getDataColumnsByUser() {
|
||
loadUserSettings();
|
||
QSet<int> set;
|
||
|
||
QStringList cols=getDatastore()->getColumnNames();
|
||
|
||
QDialog* dlg=new QDialog(nullptr, Qt::WindowMinMaxButtonsHint);
|
||
dlg->setSizeGripEnabled(true);
|
||
//printZoomFactor=0.95;
|
||
//printMagnification=1.5;
|
||
QGridLayout* layout=new QGridLayout();
|
||
dlg->setLayout(layout);
|
||
dlg->setWindowTitle(tr("Select columns to export ..."));
|
||
dlg->setWindowIcon(QIcon());
|
||
|
||
QLabel* lab=new QLabel(tr("<center><b>Please check the columns that should be exported in the list!</b><br>"
|
||
"You may also save a selection to reuse it in future, by clicking \"Save\". "
|
||
"A stored selection can be used by selecting its name in the dropdown field "
|
||
"above the list widget.</center>"), dlg);
|
||
lab->setWordWrap(true);
|
||
layout->addWidget(lab,0,0,1,2);
|
||
|
||
dataColumnsCombobox=new QComboBox(dlg);
|
||
dataColumnsCombobox->addItems(getDataColumnsByUserSaved.keys());
|
||
connect(dataColumnsCombobox, SIGNAL(currentIndexChanged(QString)), this, SLOT(getDataColumnsByUserComboBoxSelected(QString)));
|
||
layout->addWidget(dataColumnsCombobox, 1,0);
|
||
QPushButton* btn=new QPushButton(tr("&save"), dlg);
|
||
connect(btn, SIGNAL(clicked()), this, SLOT(getDataColumnsByUserSave()));
|
||
layout->addWidget(btn, 1,1);
|
||
|
||
dataColumnsListWidget=new QListWidget(dlg);
|
||
for (int i=0; i<cols.size(); i++) {
|
||
QListWidgetItem* item=new QListWidgetItem(cols[i], dataColumnsListWidget);
|
||
item->setCheckState(Qt::Checked);
|
||
item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
|
||
dataColumnsListWidget->addItem(item);
|
||
}
|
||
connect(dataColumnsListWidget, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(getDataColumnsByUserItemChanged(QListWidgetItem*)));
|
||
layout->addWidget(dataColumnsListWidget, 2,0,5,1);
|
||
btn=new QPushButton(tr("select &all"), dlg);
|
||
connect(btn, SIGNAL(clicked()), this, SLOT(getDataColumnsByUserCheckAll()));
|
||
layout->addWidget(btn, 2,1);
|
||
btn=new QPushButton(tr("select &none"), dlg);
|
||
connect(btn, SIGNAL(clicked()), this, SLOT(getDataColumnsByUserCheckNone()));
|
||
layout->addWidget(btn, 3,1);
|
||
|
||
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||
connect(buttonBox, SIGNAL(accepted()), dlg, SLOT(accept()));
|
||
connect(buttonBox, SIGNAL(rejected()), dlg, SLOT(reject()));
|
||
layout->addWidget(buttonBox, layout->rowCount(),0, 1, layout->columnCount());
|
||
layout->setRowStretch(layout->rowCount()-2,1);
|
||
layout->setColumnStretch(0,1);
|
||
dlg->resize(350,500);
|
||
dataColumnsCombobox->setCurrentIndex(-1);
|
||
|
||
if (dlg->exec()==QDialog::Accepted) {
|
||
for (int i=0; i<dataColumnsListWidget->count(); i++) {
|
||
if (dataColumnsListWidget->item(i)->checkState()==Qt::Checked) {
|
||
set.insert(i);
|
||
}
|
||
}
|
||
|
||
}
|
||
delete dlg;
|
||
dataColumnsListWidget=nullptr;
|
||
|
||
saveUserSettings();
|
||
return set;
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::getDataColumnsByUserCheckAll() {
|
||
if (!dataColumnsListWidget) return;
|
||
for (int i=0; i<dataColumnsListWidget->count(); i++) {
|
||
dataColumnsListWidget->item(i)->setCheckState(Qt::Checked);
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::getDataColumnsByUserCheckNone() {
|
||
if (!dataColumnsListWidget) return;
|
||
for (int i=0; i<dataColumnsListWidget->count(); i++) {
|
||
dataColumnsListWidget->item(i)->setCheckState(Qt::Unchecked);
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::getDataColumnsByUserSave() {
|
||
if (!dataColumnsListWidget) return;
|
||
QString name=tr("my selection name");
|
||
QStringList items=getDataColumnsByUserSaved.keys();
|
||
items<<name;
|
||
bool ok=false;
|
||
name=QInputDialog::getItem(nullptr, tr("save columns selection"), tr("name for new selection:"), items, items.size()-1, true, &ok);
|
||
if (ok) {
|
||
QStringList data;
|
||
for (int i=0; i<dataColumnsListWidget->count(); i++) {
|
||
if (dataColumnsListWidget->item(i)->checkState()==Qt::Checked) data.append(dataColumnsListWidget->item(i)->text());
|
||
}
|
||
data.sort();
|
||
getDataColumnsByUserSaved[name]=data;
|
||
disconnect(dataColumnsCombobox, SIGNAL(currentIndexChanged(QString)), this, SLOT(getDataColumnsByUserComboBoxSelected(QString)));
|
||
dataColumnsCombobox->clear();
|
||
dataColumnsCombobox->addItems(getDataColumnsByUserSaved.keys());
|
||
dataColumnsCombobox->setCurrentIndex(dataColumnsCombobox->findText(name));
|
||
connect(dataColumnsCombobox, SIGNAL(currentIndexChanged(QString)), this, SLOT(getDataColumnsByUserComboBoxSelected(QString)));
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::getDataColumnsByUserComboBoxSelected(const QString &name) {
|
||
if (!dataColumnsListWidget) return;
|
||
QStringList newItems=getDataColumnsByUserSaved.value(name, QStringList());
|
||
if (getDataColumnsByUserSaved.contains(name)) {
|
||
for (int i=0; i<dataColumnsListWidget->count(); i++) {
|
||
if (newItems.contains(dataColumnsListWidget->item(i)->text()) && (!dataColumnsListWidget->item(i)->text().isEmpty())) {
|
||
dataColumnsListWidget->item(i)->setCheckState(Qt::Checked);
|
||
} else {
|
||
dataColumnsListWidget->item(i)->setCheckState(Qt::Unchecked);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void JKQtBasePlotter::getDataColumnsByUserItemChanged(QListWidgetItem * /*widgetitem*/) {
|
||
if (!dataColumnsListWidget) return;
|
||
QStringList data;
|
||
for (int i=0; i<dataColumnsListWidget->count(); i++) {
|
||
if (dataColumnsListWidget->item(i)->checkState()==Qt::Checked) data.append(dataColumnsListWidget->item(i)->text());
|
||
}
|
||
data.sort();
|
||
|
||
QMapIterator<QString, QStringList> it(getDataColumnsByUserSaved);
|
||
QString item="";
|
||
while (it.hasNext()) {
|
||
it.next();
|
||
QStringList ld=it.value();
|
||
ld.sort();
|
||
if (data==ld) {
|
||
item=it.key();
|
||
}
|
||
}
|
||
|
||
disconnect(dataColumnsCombobox, SIGNAL(currentIndexChanged(QString)), this, SLOT(getDataColumnsByUserComboBoxSelected(QString)));
|
||
dataColumnsCombobox->setCurrentIndex(dataColumnsCombobox->findText(item));
|
||
connect(dataColumnsCombobox, SIGNAL(currentIndexChanged(QString)), this, SLOT(getDataColumnsByUserComboBoxSelected(QString)));
|
||
}
|
||
|
||
void JKQtBasePlotter::showPlotData() {
|
||
QDialog* dlg=new QDialog(nullptr,Qt::Dialog|Qt::WindowCloseButtonHint|Qt::WindowMinMaxButtonsHint);
|
||
dlg->setWindowTitle(tr("Plot data table"));
|
||
dlg->setSizeGripEnabled(true);
|
||
|
||
QVBoxLayout* layout=new QVBoxLayout();
|
||
dlg->setLayout(layout);
|
||
QToolBar* tb=new QToolBar("toolbar", dlg);
|
||
QAction* actClose=new QAction(QIcon(":/JKQTPlotter/jkqtp_exit.png"), tr("&Close Window"), dlg);
|
||
connect(actClose, SIGNAL(triggered()), dlg, SLOT(accept()));
|
||
tb->addAction(actClose);
|
||
tb->addSeparator();
|
||
tb->addAction(actSaveData);
|
||
tb->addAction(actCopyData);
|
||
tb->addAction(actCopyMatlab);
|
||
layout->addWidget(tb);
|
||
|
||
JKQTPEnhancedTableView* tv=new JKQTPEnhancedTableView(dlg);
|
||
layout->addWidget(tv);
|
||
tb->addAction(tv->getPrintAction());
|
||
|
||
JKQTPdatastoreModel* model=new JKQTPdatastoreModel(getDatastore(), this);
|
||
tv->setModel(model);
|
||
tv->resizeColumnsToContents();
|
||
tv->resizeRowsToContents();
|
||
|
||
dlg->exec();
|
||
delete dlg;
|
||
}
|
||
|
||
|
||
void JKQtBasePlotter::set_emitSignals(bool enabled)
|
||
{
|
||
emitSignals=enabled;
|
||
xAxis->set_doUpdateScaling(enabled);
|
||
yAxis->set_doUpdateScaling(enabled);
|
||
}
|
||
|
||
|
||
QHash<JKQtBasePlotter::textSizeKey, JKQtBasePlotter::textSizeData> JKQtBasePlotter::tbrh=QHash<JKQtBasePlotter::textSizeKey, JKQtBasePlotter::textSizeData>();
|
||
|
||
JKQtBasePlotter::textSizeKey::textSizeKey(const QFont &f, const QString &text, QPaintDevice *pd)
|
||
{
|
||
this->text=text;
|
||
this->f=f;
|
||
if (pd) {
|
||
ldpiX=pd->logicalDpiX();
|
||
ldpiY=pd->logicalDpiY();
|
||
pdpiX=pd->physicalDpiX();
|
||
pdpiY=pd->physicalDpiY();
|
||
} else {
|
||
ldpiX=0;
|
||
ldpiY=0;
|
||
pdpiX=0;
|
||
pdpiY=0;
|
||
}
|
||
}
|
||
|
||
JKQtBasePlotter::textSizeKey::textSizeKey(const QString &fontName, double fontSize, const QString &text, QPaintDevice *pd)
|
||
{
|
||
QFont f;
|
||
f.setFamily(fontName);
|
||
f.setPointSizeF(fontSize);
|
||
this->text=text;
|
||
this->f=f;
|
||
if (pd) {
|
||
ldpiX=pd->logicalDpiX();
|
||
ldpiY=pd->logicalDpiY();
|
||
pdpiX=pd->physicalDpiX();
|
||
pdpiY=pd->physicalDpiY();
|
||
} else {
|
||
ldpiX=0;
|
||
ldpiY=0;
|
||
pdpiX=0;
|
||
pdpiY=0;
|
||
}
|
||
}
|
||
|
||
bool JKQtBasePlotter::textSizeKey::operator==(const JKQtBasePlotter::textSizeKey &other) const
|
||
{
|
||
return ldpiX==other.ldpiX && ldpiY==other.ldpiY && text==other.text && f==other.f;
|
||
}
|
||
|
||
|
||
JKQtBasePlotter::textSizeData::textSizeData()
|
||
{
|
||
ascent=0;
|
||
descent=0;
|
||
width=0;
|
||
strikeoutPos=0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
bool JKQtBasePlotter::JKQTPPaintDeviceAdapter::useLatexParser() const
|
||
{
|
||
return true;
|
||
}
|
||
|
||
QPaintDevice *JKQtBasePlotter::JKQTPPaintDeviceAdapter::createPaintdeviceMM(const QString &filename, double widthMM, double heightMM) const
|
||
{
|
||
return createPaintdevice(filename, widthMM/25.4*QApplication::desktop()->logicalDpiX(), heightMM/25.4*QApplication::desktop()->logicalDpiY());
|
||
}
|