/* Copyright (c) 2008-2018 Jan W. Krieger () This file is part of QuickFit 3 (http://www.dkfz.de/Macromol/quickfit). 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 . */ /** \file jkqtptools.cpp * \ingroup jkqtptools */ #include "jkqtplottertools/jkqtptools.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include std::string jkqtp_tolower(const std::string& s){ std::string d; d=""; std::locale loc; if (s.length()>0) { for (unsigned long i=0; i0) { for (unsigned long i=0; i=1024.0) res=jkqtp_format(form,data/1024.0)+" k"; if (fabs(data)>=1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0))+" M"; if (fabs(data)>=1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0))+" "; if (fabs(data)>=1024.0*1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0*1024.0))+" G"; if (fabs(data)>=1024.0*1024.0*1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0*1024.0*1024.0))+" T"; if (fabs(data)>=1024.0*1024.0*1024.0*1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0*1024.0*1024.0*1024.0))+" E"; if (fabs(data)==0) res="0 "; return res+"Bytes"; } std::string jkqtp_inttostr(long data){ return jkqtp_format("%ld", data); }; std::string jkqtp_inttohex(long data){ return jkqtp_format("%lX", data); }; std::string jkqtp_uinttostr(unsigned long data){ std::ostringstream ost; ost<0) { if (fabs(data)=0) { //std::cout<=1e3) { u="k"; factor=1e3; } if (data>=1e6) { u="M"; factor=1e6; } if (data>=1e9) { u="G"; factor=1e9; } if (data>=1e12) { u="T"; factor=1e12; } if (data>=1e15) { u="P"; factor=1e15; } if (data>=1e18) { u="E"; factor=1e18; } if (data<1) {u="m"; factor=1e-3; } if (data<1e-3) {u="u"; factor=1e-6; } if (data<1e-6) {u="n"; factor=1e-9; } if (data<1e-9) {u="p"; factor=1e-12; } if (data<1e-12) {u="f"; factor=1e-15; } if (data<1e-15) {u="a"; factor=1e-18; } return jkqtp_floattostr(dataa/factor)+u+unitname; }; std::string jkqtp_floattounitstr(double data, int past_comma, bool remove_trail0){ if (data==0) return "0"; std::string form="%."+jkqtp_inttostr(past_comma)+"lf"; std::string res=jkqtp_format(form,data); if (fabs(data)>=1e3) res=jkqtp_format(form,data/1e3)+"k"; if (fabs(data)>=1e6) res=jkqtp_format(form,data/1e6)+"M"; if (fabs(data)>=1e9) res=jkqtp_format(form,data/1e9)+"G"; if (fabs(data)>=1e12) res=jkqtp_format(form,data/1e12)+"T"; if (fabs(data)>=1e15) res=jkqtp_format(form,data/1e15)+"P"; if (fabs(data)<1) res=jkqtp_format(form,data/1e-3)+"m"; if (fabs(data)<1e-3) res=jkqtp_format(form,data/1e-6)+"u"; if (fabs(data)<1e-6) res=jkqtp_format(form,data/1e-9)+"n"; if (fabs(data)<1e-9) res=jkqtp_format(form,data/1e-12)+"f"; if (fabs(data)==0) res=jkqtp_format(form,data); if (remove_trail0) { if (data==0) return "0"; if (res.find('.')==std::string::npos) return res; size_t i=res.size()-1; while (i>0 && res[i]=='0') { i--; } if (res[i]=='.') i--; // remove decimal divider return res.erase(i+1); } return res; } std::string jkqtp_floattolatexstr(double data, int past_comma, bool remove_trail0, double belowIsZero, double minNoExponent, double maxNoExponent){ if ((belowIsZero>0) && (fabs(data)0) && (fabs(data)")+jkqtp_inttostr(exp)+""; else result=std::string("10")+jkqtp_inttostr(exp)+""; } //std::cout<<"floattohtmlstr("< lines; lines< lines; lines< lines; lines< lines; QPainterPath path; for (int i=0; i JKQTPdrawEllipse(double x, double y, double a, double b, double angle_start, double angle_end, double alpha, int controlPoints, QPointF* x_start, QPointF* x_end) { QVector result; double start=angle_start*M_PI/180.0; double stop=angle_end*M_PI/180.0; double step=(stop-start)/(double)controlPoints; while (fabs(stop-start)/step<10) step=step/2.0; double sina=sin(1.0*alpha/180.0*M_PI); double cosa=cos(1.0*alpha/180.0*M_PI); QPointF xp(x+a*cos(start)*cosa-b*sin(start)*sina, y+a*cos(start)*sina+b*sin(start)*cosa); result.append(xp); if (x_start) *x_start = xp; double t=start+step; for (int i=1; i(i), JKQTPgraphSymbols2NameString(static_cast(i))); } setCurrentIndex(0); } JKQTPgraphSymbols JKQTPSymbolComboBox::getSymbol() const { return String2JKQTPgraphSymbols(itemData(currentIndex()).toString()); } void JKQTPSymbolComboBox::setSymbol(JKQTPgraphSymbols symbol) { int i=findData(JKQTPgraphSymbols2String(symbol)); if (i>=0) setCurrentIndex(i); } void JKQTPSymbolComboBox::setCurrentSymbol(JKQTPgraphSymbols symbol) { setSymbol(symbol); } void JKQTPSymbolComboBox::addSymbol(JKQTPgraphSymbols symbol, const QString &name) { QPixmap pix(12,12); pix.fill(Qt::transparent); JKQTPEnhancedPainter p; p.begin(&pix); p.setRenderHint(JKQTPEnhancedPainter::Antialiasing); p.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing); JKQTPplotSymbol(p, 6,6,symbol,10,1,QColor("blue"), QColor("blue").lighter()); p.end(); addItem(QIcon(pix), name, JKQTPgraphSymbols2String(symbol)); } JKQTPLinePlotStyleComboBox::JKQTPLinePlotStyleComboBox(QWidget *parent): QComboBox(parent) { setEditable(false); defaultSymbol=JKQTPcross; refill(); setCurrentIndex(0); } void JKQTPLinePlotStyleComboBox::setDefaultSymbol(JKQTPgraphSymbols symbol) { defaultSymbol=symbol; refill(); } void JKQTPLinePlotStyleComboBox::addUsedSymbol(JKQTPgraphSymbols symbol) { if (!symbols.contains(symbol)) symbols.append(symbol); refill(); } JKQTPgraphSymbols JKQTPLinePlotStyleComboBox::getSymbol() const { bool ok=true; int idx=itemData(currentIndex()).toInt(&ok); if (idx==-2) return JKQTPnoSymbol; if (idx>=0&&ok) return symbols.value(idx, defaultSymbol); return defaultSymbol; } bool JKQTPLinePlotStyleComboBox::getDrawLine() const { return currentIndex()%2==0; } void JKQTPLinePlotStyleComboBox::refill() { QString txt=currentText(); setUpdatesEnabled(false); clear(); addSymbol(JKQTPnoSymbol, true, tr("line"), -2); addSymbol(defaultSymbol, false, JKQTPgraphSymbols2NameString(defaultSymbol), -1); addSymbol(defaultSymbol, true, JKQTPgraphSymbols2NameString(defaultSymbol)+tr("+line"), -1); for (int i=0; i=0) setCurrentIndex(idx); else setCurrentIndex(0); setUpdatesEnabled(true); } void JKQTPLinePlotStyleComboBox::addSymbol(JKQTPgraphSymbols symbol, bool line, const QString &name, const QVariant &data) { QPixmap pix(12,12); pix.fill(Qt::transparent); JKQTPEnhancedPainter p; p.begin(&pix); p.setRenderHint(JKQTPEnhancedPainter::Antialiasing); p.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing); JKQTPplotSymbol(p, 6,6,symbol,7,1,QColor("blue"), QColor("blue").lighter()); p.setPen(QColor("blue")); if (line) p.drawLine(0,6,12,6); p.end(); addItem(QIcon(pix), name, data); } JKQTPerrorPlotstyleComboBox::JKQTPerrorPlotstyleComboBox(QWidget *parent): QComboBox(parent) { setEditable(false); addSymbol(JKQTPnoError, tr("none"), QIcon(":/JKQTPlotter/jkqtp_enone.png")); addSymbol(JKQTPerrorLines, tr("error lines"), QIcon(":/JKQTPlotter/jkqtp_elines.png")); addSymbol(JKQTPerrorBars, tr("error bars"), QIcon(":/JKQTPlotter/jkqtp_ebars.png")); addSymbol(JKQTPerrorSimpleBars, tr("simple error bars"), QIcon(":/JKQTPlotter/jkqtp_esbars.png")); addSymbol(JKQTPerrorPolygons, tr("error polygons"), QIcon(":/JKQTPlotter/jkqtp_epoly.png")); addSymbol(JKQTPerrorBarsLines, tr("bars + lines"), QIcon(":/JKQTPlotter/jkqtp_elinesbars.png")); addSymbol(JKQTPerrorBarsPolygons, tr("bars + polygons"), QIcon(":/JKQTPlotter/jkqtp_epolybars.png")); addSymbol(JKQTPerrorSimpleBarsLines, tr("simple bars + lines"), QIcon(":/JKQTPlotter/jkqtp_elinessbars.png")); addSymbol(JKQTPerrorSimpleBarsPolygons, tr("simple bars + polygons"), QIcon(":/JKQTPlotter/jkqtp_epolysbars.png")); addSymbol(JKQTPerrorBoxes, tr("boxes"), QIcon(":/JKQTPlotter/jkqtp_eboxes.png")); addSymbol(JKQTPerrorEllipses, tr("ellipses"), QIcon(":/JKQTPlotter/jkqtp_eellipses.png")); setCurrentIndex(2); } JKQTPerrorPlotstyle JKQTPerrorPlotstyleComboBox::getErrorStyle() const { return String2JKQTPerrorPlotstyle(itemData(currentIndex()).toString()); } void JKQTPerrorPlotstyleComboBox::setSymbol(JKQTPerrorPlotstyle symbol) { int i=findData(JKQTPerrorPlotstyle2String(symbol)); if (i>=0) setCurrentIndex(i); } void JKQTPerrorPlotstyleComboBox::setCurrentErrorStyle(JKQTPerrorPlotstyle symbol) { int i=findData(JKQTPerrorPlotstyle2String(symbol)); if (i>=0) setCurrentIndex(i); } void JKQTPerrorPlotstyleComboBox::addSymbol(JKQTPerrorPlotstyle symbol, const QString &name, const QIcon& icon) { addItem(icon, name, JKQTPerrorPlotstyle2String(symbol)); } JKQTPkeyPositionComboBox::JKQTPkeyPositionComboBox(QWidget *parent): QComboBox(parent) { setEditable(false); addPosition(JKQTPkeyInsideTopRight, tr("inside, top-right"), QIcon(":/JKQTPlotter/jkqtp_key_itr.png")); addPosition(JKQTPkeyInsideTopLeft, tr("inside, top-left"), QIcon(":/JKQTPlotter/jkqtp_key_itl.png")); addPosition(JKQTPkeyInsideBottomLeft, tr("inside, bottom-left"), QIcon(":/JKQTPlotter/jkqtp_key_ibl.png")); addPosition(JKQTPkeyInsideBottomRight, tr("inside, bottom-right"), QIcon(":/JKQTPlotter/jkqtp_key_ibr.png")); addPosition(JKQTPkeyOutsideTopRight, tr("outside, top-right"), QIcon(":/JKQTPlotter/jkqtp_key_otr.png")); addPosition(JKQTPkeyOutsideTopLeft, tr("outside, top-left"), QIcon(":/JKQTPlotter/jkqtp_key_otl.png")); addPosition(JKQTPkeyOutsideLeftTop, tr("outside, left-top"), QIcon(":/JKQTPlotter/jkqtp_key_olt.png")); addPosition(JKQTPkeyOutsideLeftBottom, tr("outside, left-bottom"), QIcon(":/JKQTPlotter/jkqtp_key_olb.png")); addPosition(JKQTPkeyOutsideBottomRight, tr("outside, bottom-right"), QIcon(":/JKQTPlotter/jkqtp_key_obr.png")); addPosition(JKQTPkeyOutsideBottomLeft, tr("outside, bottom-left"), QIcon(":/JKQTPlotter/jkqtp_key_obl.png")); addPosition(JKQTPkeyOutsideRightTop, tr("outside, right-top"), QIcon(":/JKQTPlotter/jkqtp_key_ort.png")); addPosition(JKQTPkeyOutsideRightBottom, tr("outside, right-bottom"), QIcon(":/JKQTPlotter/jkqtp_key_orb.png")); setCurrentIndex(0); connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(posChanged(int))); } JKQTPkeyPosition JKQTPkeyPositionComboBox::getPosition() const { return String2JKQTPkeyPosition(itemData(currentIndex()).toString()); } void JKQTPkeyPositionComboBox::setPosition(JKQTPkeyPosition position) { int i=findData(JKQTPkeyPosition2String(position)); if (i>=0) setCurrentIndex(i); } void JKQTPkeyPositionComboBox::addPosition(JKQTPkeyPosition position, const QString &name, const QIcon &icon) { addItem(icon, name, JKQTPkeyPosition2String(position)); } void JKQTPkeyPositionComboBox::posChanged(int index) { emit currentPositionChanged(String2JKQTPkeyPosition(itemData(index).toString())); } JKQTPkeyLayoutComboBox::JKQTPkeyLayoutComboBox(QWidget *parent): QComboBox(parent) { setEditable(false); addKeyLayout(JKQTPkeyLayoutOneColumn, tr("one column")); addKeyLayout(JKQTPkeyLayoutOneRow, tr("one row")); addKeyLayout(JKQTPkeyLayoutMultiColumn, tr("multiple columns")); setCurrentIndex(0); connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(currentIndexChangedP(int))); } JKQTPkeyLayout JKQTPkeyLayoutComboBox::getKeyLayout() const { return String2JKQTPkeyLayout(itemData(currentIndex()).toString()); } void JKQTPkeyLayoutComboBox::setKeyLayout(JKQTPkeyLayout position) { int i=findData(JKQTPkeyLayout2String(position)); if (i>=0) setCurrentIndex(i); } void JKQTPkeyLayoutComboBox::addKeyLayout(JKQTPkeyLayout position, const QString &name) { addItem(name, JKQTPkeyLayout2String(position)); } void JKQTPkeyLayoutComboBox::currentIndexChangedP(int index) { emit currentLayoutChanged(String2JKQTPkeyLayout(itemData(index).toString())); } JKQTPlabelPositionComboBox::JKQTPlabelPositionComboBox(QWidget *parent): QComboBox(parent) { setEditable(false); addPosition(JKQTPlabelCenter, tr("center")); addPosition(JKQTPlabelMin, tr("left")); addPosition(JKQTPlabelMax, tr("right")); setCurrentIndex(0); } JKQTPlabelPosition JKQTPlabelPositionComboBox::getPosition() const { return String2JKQTPlabelPosition(itemData(currentIndex()).toString()); } void JKQTPlabelPositionComboBox::setPosition(JKQTPlabelPosition position) { int i=findData(JKQTPlabelPosition2String(position)); if (i>=0) setCurrentIndex(i); } void JKQTPlabelPositionComboBox::addPosition(JKQTPlabelPosition position, const QString &name, const QIcon &icon) { addItem(icon, name, JKQTPlabelPosition2String(position)); } JKQTPCAlabelTypeComboBox::JKQTPCAlabelTypeComboBox(QWidget *parent): QComboBox(parent) { setEditable(false); addLabelType(JKQTPCALTexponent, tr("exponent"), QIcon(":/JKQTPlotter/jkqtp_ticks_exp.png")); addLabelType(JKQTPCALTdefault, tr("default"), QIcon(":/JKQTPlotter/jkqtp_ticks_default.png")); addLabelType(JKQTPCALTexponentCharacter, tr("character"), QIcon(":/JKQTPlotter/jkqtp_ticks_expchar.png")); addLabelType(JKQTPCALTtime, tr("time"), QIcon(":/JKQTPlotter/jkqtp_ticks_time.png")); addLabelType(JKQTPCALTdate, tr("date"), QIcon(":/JKQTPlotter/jkqtp_ticks_date.png")); addLabelType(JKQTPCALTdatetime, tr("datetime"), QIcon(":/JKQTPlotter/jkqtp_ticks_datetime.png")); setCurrentIndex(0); } JKQTPCAlabelType JKQTPCAlabelTypeComboBox::getLabelType() const { return String2JKQTPCAlabelType(itemData(currentIndex()).toString()); } void JKQTPCAlabelTypeComboBox::setLabelType(JKQTPCAlabelType position) { int i=findData(JKQTPCAlabelType2String(position)); if (i>=0) setCurrentIndex(i); } void JKQTPCAlabelTypeComboBox::addLabelType(JKQTPCAlabelType position, const QString &name, const QIcon& icon) { addItem(icon, name, JKQTPCAlabelType2String(position)); } JKQTPCAdrawModeComboBox::JKQTPCAdrawModeComboBox(QWidget *parent): QComboBox(parent) { setEditable(false); addDrawMode(JKQTPCADMcomplete, tr("complete"), QIcon(":/JKQTPlotter/jkqtp_axis_complete.png")); addDrawMode(JKQTPCADMticksAndLabels, tr("tick+lab."), QIcon(":/JKQTPlotter/jkqtp_axis_ticksandlabels.png")); addDrawMode(JKQTPCADMticks, tr("tick"), QIcon(":/JKQTPlotter/jkqtp_axis_ticks.png")); addDrawMode(JKQTPCADMline, tr("line"), QIcon(":/JKQTPlotter/jkqtp_axis_line.png")); addDrawMode(JKQTPCADMnone, tr("none"), QIcon(":/JKQTPlotter/jkqtp_axis_none.png")); setCurrentIndex(0); } JKQTPCAdrawMode JKQTPCAdrawModeComboBox::getDrawMode() const { return String2JKQTPCAdrawMode(itemData(currentIndex()).toString()); } void JKQTPCAdrawModeComboBox::setDrawMode(JKQTPCAdrawMode position) { int i=findData(JKQTPCAdrawMode2String(position)); if (i>=0) setCurrentIndex(i); } void JKQTPCAdrawModeComboBox::addDrawMode(JKQTPCAdrawMode position, const QString &name, const QIcon &icon) { addItem(icon, name, JKQTPCAdrawMode2String(position)); } JKQTPEnhancedTableView::JKQTPEnhancedTableView(QWidget *parent): QTableView(parent) { setContextMenuPolicy(Qt::ActionsContextMenu); QAction* act; act=new QAction(QIcon(":/JKQTPlotter/jkqtp_copy16.png"), tr("Copy Selection to Clipboard (for Excel ...)"), this); connect(act, SIGNAL(triggered()), this, SLOT(copySelectionToExcel())); addAction(act); act=new QAction(QIcon(":/JKQTPlotter/jkqtp_copy16_nohead.png"), tr("Copy Selection to clipboard (for Excel ...) without header row/column"), this); connect(act, SIGNAL(triggered()), this, SLOT(copySelectionToExcelNoHead())); addAction(act); act=new QAction(QIcon(":/JKQTPlotter/jkqtp_copy16.png"), tr("Copy Selection to Clipboard (as CSV)"), this); connect(act, SIGNAL(triggered()), this, SLOT(copySelectionToCSV())); addAction(act); act=new QAction(QIcon(":/JKQTPlotter/jkqtp_copy16_nohead.png"), tr("Copy Selection to clipboard (as CSV ...) without header row/column"), this); connect(act, SIGNAL(triggered()), this, SLOT(copySelectionToCSVNoHead())); addAction(act); act=new QAction(QIcon(":/JKQTPlotter/jkqtp_printtable.png"), tr("Print Table"), this); connect(act, SIGNAL(triggered()), this, SLOT(print())); addAction(act); printAction=act; } JKQTPEnhancedTableView::~JKQTPEnhancedTableView() { } QString JKQTPEnhancedTableView::toHtml(int borderWidth, bool /*non_breaking*/, int fontSizePt) const { if (!model()) return ""; QString fsstyle=""; if (fontSizePt>0) { fsstyle=QString(" font-size: %1pt;").arg(fontSizePt); } QString html=QString("").arg(borderWidth); for (int row=-1; rowrowCount(); row++) { html+=""; if (row==-1) { for (int col=-1; colcolumnCount(); col++) { html+=QString(""; } } else { for (int col=-1; colcolumnCount(); col++) { if (col==-1) { html+=QString(""; } else { QModelIndex index=model()->index(row, col); QVariant check=index.data(Qt::CheckStateRole); QBrush back=index.data(Qt::BackgroundRole).value(); QString style=fsstyle+"white-space: nowrap; "; //qDebug()<<"r="<").arg(fsstyle); else html+=QString(""; } } } html+=""; } html+="
").arg(fsstyle); if (col>=0) { html+=model()->headerData(col, Qt::Horizontal).toString(); } html+="").arg(fsstyle); html+=model()->headerData(row, Qt::Vertical).toString(); html+="").arg(style); if (check.isValid()) { if (check.toInt()!=0) { html+= QString("|×|  "); } else { html+= QString("| |  "); } } html+=index.data().toString(); html+="
"; return html; } void JKQTPEnhancedTableView::copySelectionToExcel(int copyrole, bool storeHead) { if (!model()) return; if (!selectionModel()) return; QModelIndexList sel=selectionModel()->selectedIndexes(); QLocale loc=QLocale::system(); loc.setNumberOptions(QLocale::OmitGroupSeparator); if (sel.size()==1) { QVariant vdata=sel[0].data(copyrole); QString txt=""; switch (vdata.type()) { case QVariant::Int: case QVariant::LongLong: case QVariant::UInt: case QVariant::ULongLong: case QVariant::Bool: txt=vdata.toString(); break; case QVariant::Double: txt=loc.toString(vdata.toDouble()); break; case QVariant::PointF: txt=loc.toString(vdata.toPointF().x()); break; default: txt=QString("\"%1\"").arg(vdata.toString().replace('"', "''").replace('\n', "\\n ").replace('\r', "\\r ").replace('\t', " ")); break; } QApplication::clipboard()->setText(txt); } else { QSet rows, cols; int colmin=0; int rowmin=0; for (int i=0; i rowlist=QList::fromSet(rows); qSort(rowlist.begin(), rowlist.end()); QList collist=QList::fromSet(cols); qSort(collist.begin(), collist.end()); int rowcnt=rowlist.size(); int colcnt=collist.size(); QList data; // header row: // // | | | ... QStringList hrow; if (storeHead) { hrow.append(""); // empty header for first column (vertical headers!) for (int c=0; cheaderData(collist[c], Qt::Horizontal).toString().replace('"', "''").replace('\n', "\\n ").replace('\r', "\\r ").replace('\t', " "))); } data.append(hrow); } // now add dta rows: // // <~~~~~~~~~ colcnt times ~~~~~~~~~~> // | | | ... | for (int r=0; rheaderData(rowlist[r], Qt::Vertical).toString().replace('"', "''").replace('\n', "\\n ").replace('\r', "\\r ").replace('\t', " "))); // vertical header for (int c=0; c=0) && (c>=0) && (r<=data.size()) && (c<=colcnt))data[r+shift][c+shift]=txt; } QString result=""; for (int r=0; rsetText(result); } } void JKQTPEnhancedTableView::copySelectionToExcelNoHead(int copyrole) { copySelectionToExcel(copyrole, false); } void JKQTPEnhancedTableView::copySelectionToCSV(int copyrole, bool storeHead, const QString &separator, const QChar &decimalpoint) { if (!model()) return; if (!selectionModel()) return; QModelIndexList sel=selectionModel()->selectedIndexes(); QLocale loc=QLocale::c(); loc.setNumberOptions(QLocale::OmitGroupSeparator); if (sel.size()==1) { QVariant vdata=sel[0].data(copyrole); QString txt=""; switch (vdata.type()) { case QVariant::Int: case QVariant::LongLong: case QVariant::UInt: case QVariant::ULongLong: case QVariant::Bool: txt=vdata.toString(); break; case QVariant::Double: txt=JKQTPDoubleToQString(vdata.toDouble(), 15, 'g', decimalpoint); break; case QVariant::PointF: txt=JKQTPDoubleToQString(vdata.toPointF().x(), 15, 'g', decimalpoint); break; default: txt=QString("\"%1\"").arg(vdata.toString().replace('"', "''").replace('\n', "\\n ").replace('\r', "\\r ").replace('\t', " ")); break; } QApplication::clipboard()->setText(txt); } else { QSet rows, cols; int colmin=0; int rowmin=0; for (int i=0; i rowlist=QList::fromSet(rows); qSort(rowlist.begin(), rowlist.end()); QList collist=QList::fromSet(cols); qSort(collist.begin(), collist.end()); int rowcnt=rowlist.size(); int colcnt=collist.size(); QList data; // header row: // // | | | ... QStringList hrow; if (storeHead) { hrow.append(""); // empty header for first column (vertical headers!) for (int c=0; cheaderData(collist[c], Qt::Horizontal).toString().replace('"', "''").replace('\n', "\\n ").replace('\r', "\\r ").replace('\t', " "))); } data.append(hrow); } // now add dta rows: // // <~~~~~~~~~ colcnt times ~~~~~~~~~~> // | | | ... | for (int r=0; rheaderData(rowlist[r], Qt::Vertical).toString().replace('"', "''").replace('\n', "\\n ").replace('\r', "\\r ").replace('\t', " "))); // vertical header for (int c=0; c=0) && (c>=0) && (r<=data.size()) && (c<=colcnt))data[r+shift][c+shift]=txt; } QString result=""; for (int r=0; rsetText(result); } } void JKQTPEnhancedTableView::copySelectionToCSVNoHead(int copyrole, const QString &separator, const QChar &decimalpoint) { copySelectionToCSV(copyrole, false, separator, decimalpoint); } void JKQTPEnhancedTableView::keyPressEvent(QKeyEvent *event) { if (event->matches(QKeySequence::Copy)) { copySelectionToExcel(Qt::EditRole, false); event->accept(); } else if (event->matches(QKeySequence::Print)) { print(); event->accept(); } else QTableView::keyPressEvent(event); emit keyPressed(event->key(), event->modifiers(), event->text()); } void JKQTPEnhancedTableView::print() { QPrinter* tablePrinter=getPrinter(nullptr); if (tablePrinter) { QDialog* dlg=new QDialog(this); dlg->setWindowTitle(tr("Table print options ...")); QGridLayout* lay=new QGridLayout(); dlg->setLayout(lay); lay->addWidget(new QLabel(tr("scaling:")), 0,0); QCheckBox* chk1Wide=new QCheckBox(tr("one page wide"), dlg); QCheckBox* chk1High=new QCheckBox(tr("one page high"), dlg); lay->addWidget(chk1Wide, 0, 1); lay->addWidget(chk1High, 1, 1); QDialogButtonBox* btns=new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel,Qt::Horizontal,dlg); connect(btns, SIGNAL(accepted()), dlg, SLOT(accept())); connect(btns, SIGNAL(rejected()), dlg, SLOT(reject())); lay->addWidget(btns, 2, 0,1,2); if (dlg->exec()) { print(tablePrinter, chk1Wide->isChecked(), chk1High->isChecked()); } delete dlg; delete tablePrinter; } } void JKQTPEnhancedTableView::print(QPrinter *printer, bool onePageWide, bool onePageHigh) { QPrinter* p=printer; //p->setPageMargins(10,10,10,10,QPrinter::Millimeter); /*if (width()>height()) { p->setOrientation(QPrinter::Landscape); } else { p->setOrientation(QPrinter::Portrait); }*/ clearSelection(); /// PRINT HERE ////////////////////////////////////////////////////////////////////////////////// // calculate the total width/height table would need without scaling const int rows = model()->rowCount(); const int cols = model()->columnCount(); double vhw=verticalHeader()->width()+8; double totalWidth = vhw; double minWidth=1e33; double maxWidth=0; for (int c = -1; c < cols; ++c) { double w=columnWidth(c); totalWidth += w; if (wmaxWidth) maxWidth=w; } double hhh=horizontalHeader()->height()+8; double totalHeight = hhh; double minHeight=1e33; double maxHeight=0; for (int r = 0; r < rows; ++r) { double h=rowHeight(r); totalHeight += h; if (hmaxHeight) maxHeight=h; } double scale=1.0; // adjust scale, so the widest/highest column fits on one page /*if (maxWidth*scale>p->pageRect().width()) scale=p->pageRect().width()/maxWidth; if (maxHeight*scale>p->pageRect().height()) scale=p->pageRect().height()/maxHeight;*/ if (onePageWide) { if (totalWidth>p->pageRect().width()) scale=p->pageRect().width()/totalWidth; } if (onePageHigh) { if (totalHeight>p->pageRect().height()) scale=qMin(scale, p->pageRect().height()/totalHeight); } //qDebug()< pageCols, pageRows; pageCols<<0; pageRows<<0; { // find number of pages needed double x=vhw, x0=vhw; if (!onePageWide) { for (int c=0; cp->pageRect().width()/scale) { pagesWide++; x=0; pageCols<0 && cols>pageCols.last()) pageCols<p->pageRect().height()/scale) { pagesHigh++; pageRows<0 && rows>pageRows.last()) pageRows<width()+8; double hhh=horizontalHeader()->height()+8; double scaleX=size.width()/double(pageRec.width()); double scaleY=size.height()/double(pageRec.height()); double scale=qMin(scaleX, scaleY); QListpageCols, pageRows; pageCols<<0<columnCount(); pageRows<<0<rowCount(); paint(painter, scale, -1, hhh, vhw, pageCols, pageRows); painter.restore(); } QSizeF JKQTPEnhancedTableView::getTotalSize() const { const int rows = model()->rowCount(); const int cols = model()->columnCount(); double vhw=verticalHeader()->width()+8; double totalWidth = vhw; for (int c = -1; c < cols; ++c) { double w=columnWidth(c); totalWidth += w; } double hhh=horizontalHeader()->height()+8; double totalHeight = hhh; for (int r = 0; r < rows; ++r) { double h=rowHeight(r); totalHeight += h; } return QSizeF((totalWidth), (totalHeight)); } void JKQTPEnhancedTableView::paint(QPainter &painter, double scale, int page, double hhh, double vhw, const QList& pageCols, const QList& pageRows, QPrinter* p) { painter.save(); QStyleOptionViewItem option = viewOptions(); painter.scale(scale, scale); QPen headerPen("black"); headerPen.setWidth(2); QPen cellPen("gray"); cellPen.setWidth(1); QFont headerFont=horizontalHeader()->font(); headerFont.setBold(true); int pagesWide=pageCols.size()-1; int pagesHigh=pageRows.size()-1; //painter.translate(p->pageRect().topLeft()); int pageCnt=0; for (int ph=0; phpageRect().topLeft(), pic); double y=0; if (ph==0) { y=hhh; } //qDebug()<<" rows = "<itemDelegate()->paint(&painter, option, model()->index(r, c, QModelIndex())); x=vhw; } for (int c=pageCols[pw]; cpaint(&painter, option, model()->index(r, c, QModelIndex())); painter.setPen(cellPen); painter.drawRect(option.rect); x=x+cw; } y=y+rh; } if (ph==0) { y=0; int x=0; if (pw%pagesWide==0) x=vhw; painter.setPen(headerPen); for (int c=pageCols[pw]; cheaderData(c, Qt::Horizontal).toString()); painter.drawRect(rec); //if (x==vhw &&) painter.drawLine(rec.topLeft(), QPoint(rec.left(), p->pageRect().height())); x=x+columnWidth(c); } } if (pw%pagesWide==0) { y=0; int x=0; if (ph==0) y=hhh; for (int r=pageRows[ph]; rheaderData(r, Qt::Vertical).toString()); painter.drawRect(rec); //if (x==vhw &&) painter.drawLine(rec.topLeft(), QPoint(rec.left(), p->pageRect().height())); y=y+rowHeight(r); } } if (p && pwnewPage(); } pageCnt++; } if (p && phnewPage(); } painter.restore(); } QPrinter *JKQTPEnhancedTableView::getPrinter(QPrinter *printerIn, bool *localPrinter) { QPrinter* p=printerIn; if (p==nullptr) { p=new QPrinter(); if (localPrinter) *localPrinter=true; } QPrintDialog *dialog = new QPrintDialog(p, nullptr); dialog->setWindowTitle(tr("Print Table")); if (dialog->exec() != QDialog::Accepted) { if (localPrinter && *localPrinter) delete p; delete dialog; return printerIn; } p=dialog->printer(); delete dialog; return p; } JKQTPLinePlotStyleWithSymbolSizeComboBox::JKQTPLinePlotStyleWithSymbolSizeComboBox(QWidget *parent): QComboBox(parent) { setEditable(false); defaultSymbol=JKQTPcross; defaultSize=10; refill(); setCurrentIndex(0); } void JKQTPLinePlotStyleWithSymbolSizeComboBox::setDefaultSymbol(JKQTPgraphSymbols symbol, double size) { defaultSymbol=symbol; defaultSize=size; refill(); } void JKQTPLinePlotStyleWithSymbolSizeComboBox::addUsedSymbol(JKQTPgraphSymbols symbol, double symbolSize, bool line) { styleData d; d.symbol=symbol; d.symbolSize=symbolSize; d.line=line; if (!symbols.contains(d)) symbols.append(d); refill(); } JKQTPgraphSymbols JKQTPLinePlotStyleWithSymbolSizeComboBox::getSymbol() const { QVariant idxV=itemData(currentIndex()); bool ok=false; int idx=idxV.toInt(&ok); if (idxV.isValid() && ok) { if (idx>=0 && idx=0 && idx=0 && idx=0) setCurrentIndex(idx); else setCurrentIndex(0); setUpdatesEnabled(true); } void JKQTPLinePlotStyleWithSymbolSizeComboBox::addSymbol(JKQTPgraphSymbols symbol, bool line, double symbolSize, const QString &name, const QVariant &data) { int pixSize=qMax(16.0, 1.2*symbolSize); QPixmap pix(pixSize, pixSize); pix.fill(Qt::transparent); JKQTPEnhancedPainter p; p.begin(&pix); p.setRenderHint(JKQTPEnhancedPainter::Antialiasing); p.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing); JKQTPplotSymbol(p, double(pixSize)/2.0,double(pixSize)/2.0,symbol,symbolSize,1,QColor("blue"), QColor("blue").lighter()); p.setPen(QColor("blue")); if (line) p.drawLine(QLineF(0,double(pixSize)/2.0,pixSize,double(pixSize)/2.0)); p.end(); addItem(QIcon(pix), name, data); } bool JKQTPLinePlotStyleWithSymbolSizeComboBox::styleData::operator==(const JKQTPLinePlotStyleWithSymbolSizeComboBox::styleData &other) const { return (symbol==other.symbol && symbolSize==other.symbolSize && line==other.line); } JKQTPEnhancedDoubleSpinBox::JKQTPEnhancedDoubleSpinBox(QWidget *parent): QDoubleSpinBox(parent) { connect(this, SIGNAL(editingFinished()), this, SLOT(intEditingFinished())); } JKQTPEnhancedDoubleSpinBox::~JKQTPEnhancedDoubleSpinBox() { disconnect(this, SIGNAL(editingFinished()), this, SLOT(intEditingFinished())); } void JKQTPEnhancedDoubleSpinBox::intEditingFinished() { emit editingFinished(value()); } JKQTPEnhancedSpinBox::JKQTPEnhancedSpinBox(QWidget *parent): QSpinBox(parent) { connect(this, SIGNAL(editingFinished()), this, SLOT(intEditingFinished())); } JKQTPEnhancedSpinBox::~JKQTPEnhancedSpinBox() { disconnect(this, SIGNAL(editingFinished()), this, SLOT(intEditingFinished())); } void JKQTPEnhancedSpinBox::intEditingFinished() { emit editingFinished(value()); } JKQTPEnhancedPainter::JKQTPEnhancedPainter(QPaintDevice *device): QPainter(device) { initQEnhacedPainter(); } JKQTPEnhancedPainter::JKQTPEnhancedPainter(): QPainter() { initQEnhacedPainter(); } JKQTPEnhancedPainter::~JKQTPEnhancedPainter() { } //void JKQTPEnhancedPainter::drawLines(const QLineF *lines, int lineCount) //{ //} //void JKQTPEnhancedPainter::drawLines(const QPointF *lines, int lineCount) //{ //} //void JKQTPEnhancedPainter::drawLines(const QLine *lines, int lineCount) //{ //} //void JKQTPEnhancedPainter::drawLines(const QPoint *lines, int lineCount) //{ //} void JKQTPEnhancedPainter::initQEnhacedPainter() { } QPolygonF jkqtpRotateRect(QRectF r, double angle) { QPolygonF p; QMatrix m; m.rotate(angle); p.append(m.map(r.bottomLeft())); p.append(m.map(r.bottomRight())); p.append(m.map(r.topRight())); p.append(m.map(r.topLeft())); return p; } std::string jkqtp_booltostr(bool data){ if (data) return "true"; return "false"; } #ifdef rgb # undef rgb #endif #define rgb(r,g,b) (0xff000000 | (r << 16) | (g << 8) | b) static const struct RGBData { const char *name; unsigned int value; } rgbTbl[] = { { "aliceblue", rgb(240, 248, 255) }, { "antiquewhite", rgb(250, 235, 215) }, { "aqua", rgb( 0, 255, 255) }, { "aquamarine", rgb(127, 255, 212) }, { "azure", rgb(240, 255, 255) }, { "beige", rgb(245, 245, 220) }, { "bisque", rgb(255, 228, 196) }, { "black", rgb( 0, 0, 0) }, { "blanchedalmond", rgb(255, 235, 205) }, { "blue", rgb( 0, 0, 255) }, { "blueviolet", rgb(138, 43, 226) }, { "brown", rgb(165, 42, 42) }, { "burlywood", rgb(222, 184, 135) }, { "cadetblue", rgb( 95, 158, 160) }, { "chartreuse", rgb(127, 255, 0) }, { "chocolate", rgb(210, 105, 30) }, { "coral", rgb(255, 127, 80) }, { "cornflowerblue", rgb(100, 149, 237) }, { "cornsilk", rgb(255, 248, 220) }, { "crimson", rgb(220, 20, 60) }, { "cyan", rgb( 0, 255, 255) }, { "darkblue", rgb( 0, 0, 139) }, { "darkcyan", rgb( 0, 139, 139) }, { "darkgoldenrod", rgb(184, 134, 11) }, { "darkgray", rgb(169, 169, 169) }, { "darkgreen", rgb( 0, 100, 0) }, { "darkgrey", rgb(169, 169, 169) }, { "darkkhaki", rgb(189, 183, 107) }, { "darkmagenta", rgb(139, 0, 139) }, { "darkolivegreen", rgb( 85, 107, 47) }, { "darkorange", rgb(255, 140, 0) }, { "darkorchid", rgb(153, 50, 204) }, { "darkred", rgb(139, 0, 0) }, { "darksalmon", rgb(233, 150, 122) }, { "darkseagreen", rgb(143, 188, 143) }, { "darkslateblue", rgb( 72, 61, 139) }, { "darkslategray", rgb( 47, 79, 79) }, { "darkslategrey", rgb( 47, 79, 79) }, { "darkturquoise", rgb( 0, 206, 209) }, { "darkviolet", rgb(148, 0, 211) }, { "deeppink", rgb(255, 20, 147) }, { "deepskyblue", rgb( 0, 191, 255) }, { "dimgray", rgb(105, 105, 105) }, { "dimgrey", rgb(105, 105, 105) }, { "dodgerblue", rgb( 30, 144, 255) }, { "firebrick", rgb(178, 34, 34) }, { "floralwhite", rgb(255, 250, 240) }, { "forestgreen", rgb( 34, 139, 34) }, { "fuchsia", rgb(255, 0, 255) }, { "gainsboro", rgb(220, 220, 220) }, { "ghostwhite", rgb(248, 248, 255) }, { "gold", rgb(255, 215, 0) }, { "goldenrod", rgb(218, 165, 32) }, { "gray", rgb(128, 128, 128) }, { "green", rgb( 0, 128, 0) }, { "greenyellow", rgb(173, 255, 47) }, { "grey", rgb(128, 128, 128) }, { "honeydew", rgb(240, 255, 240) }, { "hotpink", rgb(255, 105, 180) }, { "indianred", rgb(205, 92, 92) }, { "indigo", rgb( 75, 0, 130) }, { "ivory", rgb(255, 255, 240) }, { "khaki", rgb(240, 230, 140) }, { "lavender", rgb(230, 230, 250) }, { "lavenderblush", rgb(255, 240, 245) }, { "lawngreen", rgb(124, 252, 0) }, { "lemonchiffon", rgb(255, 250, 205) }, { "lightblue", rgb(173, 216, 230) }, { "lightcoral", rgb(240, 128, 128) }, { "lightcyan", rgb(224, 255, 255) }, { "lightgoldenrodyellow", rgb(250, 250, 210) }, { "lightgray", rgb(211, 211, 211) }, { "lightgreen", rgb(144, 238, 144) }, { "lightgrey", rgb(211, 211, 211) }, { "lightpink", rgb(255, 182, 193) }, { "lightsalmon", rgb(255, 160, 122) }, { "lightseagreen", rgb( 32, 178, 170) }, { "lightskyblue", rgb(135, 206, 250) }, { "lightslategray", rgb(119, 136, 153) }, { "lightslategrey", rgb(119, 136, 153) }, { "lightsteelblue", rgb(176, 196, 222) }, { "lightyellow", rgb(255, 255, 224) }, { "lime", rgb( 0, 255, 0) }, { "limegreen", rgb( 50, 205, 50) }, { "linen", rgb(250, 240, 230) }, { "magenta", rgb(255, 0, 255) }, { "maroon", rgb(128, 0, 0) }, { "mediumaquamarine", rgb(102, 205, 170) }, { "mediumblue", rgb( 0, 0, 205) }, { "mediumorchid", rgb(186, 85, 211) }, { "mediumpurple", rgb(147, 112, 219) }, { "mediumseagreen", rgb( 60, 179, 113) }, { "mediumslateblue", rgb(123, 104, 238) }, { "mediumspringgreen", rgb( 0, 250, 154) }, { "mediumturquoise", rgb( 72, 209, 204) }, { "mediumvioletred", rgb(199, 21, 133) }, { "midnightblue", rgb( 25, 25, 112) }, { "mintcream", rgb(245, 255, 250) }, { "mistyrose", rgb(255, 228, 225) }, { "moccasin", rgb(255, 228, 181) }, { "navajowhite", rgb(255, 222, 173) }, { "navy", rgb( 0, 0, 128) }, { "oldlace", rgb(253, 245, 230) }, { "olive", rgb(128, 128, 0) }, { "olivedrab", rgb(107, 142, 35) }, { "orange", rgb(255, 165, 0) }, { "orangered", rgb(255, 69, 0) }, { "orchid", rgb(218, 112, 214) }, { "palegoldenrod", rgb(238, 232, 170) }, { "palegreen", rgb(152, 251, 152) }, { "paleturquoise", rgb(175, 238, 238) }, { "palevioletred", rgb(219, 112, 147) }, { "papayawhip", rgb(255, 239, 213) }, { "peachpuff", rgb(255, 218, 185) }, { "peru", rgb(205, 133, 63) }, { "pink", rgb(255, 192, 203) }, { "plum", rgb(221, 160, 221) }, { "powderblue", rgb(176, 224, 230) }, { "purple", rgb(128, 0, 128) }, { "red", rgb(255, 0, 0) }, { "rosybrown", rgb(188, 143, 143) }, { "royalblue", rgb( 65, 105, 225) }, { "saddlebrown", rgb(139, 69, 19) }, { "salmon", rgb(250, 128, 114) }, { "sandybrown", rgb(244, 164, 96) }, { "seagreen", rgb( 46, 139, 87) }, { "seashell", rgb(255, 245, 238) }, { "sienna", rgb(160, 82, 45) }, { "silver", rgb(192, 192, 192) }, { "skyblue", rgb(135, 206, 235) }, { "slateblue", rgb(106, 90, 205) }, { "slategray", rgb(112, 128, 144) }, { "slategrey", rgb(112, 128, 144) }, { "snow", rgb(255, 250, 250) }, { "springgreen", rgb( 0, 255, 127) }, { "steelblue", rgb( 70, 130, 180) }, { "tan", rgb(210, 180, 140) }, { "teal", rgb( 0, 128, 128) }, { "thistle", rgb(216, 191, 216) }, { "tomato", rgb(255, 99, 71) }, { "transparent", 0 }, { "turquoise", rgb( 64, 224, 208) }, { "violet", rgb(238, 130, 238) }, { "wheat", rgb(245, 222, 179) }, { "white", rgb(255, 255, 255) }, { "whitesmoke", rgb(245, 245, 245) }, { "yellow", rgb(255, 255, 0) }, { "yellowgreen", rgb(154, 205, 50) } }; static const int rgbTblSize = sizeof(rgbTbl) / sizeof(RGBData); std::string jkqtp_rgbtostring(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { if (a==255) {// only for non-transparent colors for (int i=0; i0)) out=out+input[i]; if ((input[i]=='_')&&(out.size()>0)) out=out+input[i]; } return out; } int JKQTPAutoOutputTimer::global_indent=0; JKQTPAutoOutputTimer::JKQTPAutoOutputTimer(const QString& message) : QElapsedTimer() { this->indent=QString(global_indent, QLatin1Char(' ')); global_indent+=4; this->message=message; #if QT_VERSION >= 0x040800 qDebug()<indent<<"TIMER_START: "<indent<<"TIMER_START: "<= 0x040800 qDebug()<indent<<"TIMER_END: "<indent<<"TIMER_END: "<= 0x040800 qDebug()<indent<<"TIMER_MESSAGE: "<message<<" "<indent<<"TIMER_MESSAGE: "<message<<" "<=0) setCurrentIndex(i); } void JKQTPstepTypeComboBox::setCurrentStepType(JKQTPstepType step) { setStepType(step); } void JKQTPstepTypeComboBox::addStep(JKQTPstepType step, const QString &name, const QIcon &icon) { addItem(icon, name, JKQTPstepType2String(step)); } QString JKQTPstepType2String(JKQTPstepType pos) { switch(pos) { case JKQTPstepLeft: return "step_left"; case JKQTPstepCenter: return "step_center"; case JKQTPstepRight: return "step_right"; } return ""; } JKQTPstepType String2JKQTPstepType(QString pos) { QString s=pos.trimmed().toLower(); if (s=="step_left"||s=="left"||s=="l") return JKQTPstepLeft; if (s=="step_center"||s=="center"||s=="c") return JKQTPstepCenter; if (s=="step_right"||s=="right"||s=="r") return JKQTPstepRight; return JKQTPstepLeft; }