diff options
author | Slávek Banko <slavek.banko@axis.cz> | 2016-04-09 15:59:57 +0200 |
---|---|---|
committer | Slávek Banko <slavek.banko@axis.cz> | 2016-04-09 15:59:57 +0200 |
commit | ee0c9d4bc3e25a409b3127be2876079f69719978 (patch) | |
tree | 04d895b486c04df1fe2e5dedb7cd5705eff06a9b /src/qalculateresultdisplay.cpp | |
download | qalculate-tde-ee0c9d4bc3e25a409b3127be2876079f69719978.tar.gz qalculate-tde-ee0c9d4bc3e25a409b3127be2876079f69719978.zip |
Initial import of qalculate-kde 0.9.7
Diffstat (limited to 'src/qalculateresultdisplay.cpp')
-rw-r--r-- | src/qalculateresultdisplay.cpp | 495 |
1 files changed, 495 insertions, 0 deletions
diff --git a/src/qalculateresultdisplay.cpp b/src/qalculateresultdisplay.cpp new file mode 100644 index 0000000..91f5667 --- /dev/null +++ b/src/qalculateresultdisplay.cpp @@ -0,0 +1,495 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateresultdisplay.h" + +#include "qalculate_kde_utils.h" +#include "kqalculate.h" +#include <kpopupmenu.h> +#include <kxmlguifactory.h> +#include <kxmlguiclient.h> +#include <kaction.h> +#include <kmessagebox.h> +#include <qwhatsthis.h> +#include <qtooltip.h> +#include <klocale.h> +#include <kapplication.h> +#include <qsimplerichtext.h> + +extern vector<mode_struct> modes; + +extern QString parsed_text; +extern KQalculate *mainWin; +extern MathStructure *mstruct; +extern PrintOptions printops; +extern EvaluationOptions evalops; + +QString linkInfo(const MathStructure *m, QWidget *w, bool full_length = false) { + QString str; + if(m) { + if(m->isSymbolic()) { + str = "\""; + str += m->symbol().c_str(); + str += "\""; + } else if(m->isVector()) { + if(m->isMatrix()) { + str = i18n("a matrix"); + } else { + str = i18n("a vector"); + } + str += "\n"; + str += i18n("double-click to view/edit"); + } else if(m->isVariable()) { + if(m->variable()->subtype() == SUBTYPE_UNKNOWN_VARIABLE) { + str = i18n("Unknown variable"); + } else { + str = i18n("Variable"); + } + str += ": "; + str += m->variable()->title(true).c_str(); + } else if(m->isUnit()) { + str = i18n("Unit"); + str += ": "; + str += m->unit()->title(true).c_str(); + if(m->prefix() && m->prefix() != CALCULATOR->decimal_null_prefix && m->prefix() != CALCULATOR->binary_null_prefix) { + str += "\n"; + str += i18n("Prefix"); + str += ": "; + QString pstr; + switch(m->prefix()->type()) { + case PREFIX_DECIMAL: { + QTextOStream(&pstr) << m->prefix()->name(false, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) w).c_str() << " (10e" << ((DecimalPrefix*) m->prefix())->exponent() << ")"; + break; + } + case PREFIX_BINARY: { + QTextOStream(&pstr) << m->prefix()->name(false, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) w).c_str() << " (2e" << ((BinaryPrefix*) m->prefix())->exponent() << ")"; + break; + } + case PREFIX_NUMBER: { + QTextOStream(&pstr) << m->prefix()->name(false, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) w).c_str(); + break; + } + } + str += pstr; + } + } else if(m->isFunction()) { + str = i18n("Function"); + str += ": "; + str += m->function()->title(true).c_str(); + Argument default_arg; + MathFunction *f = m->function(); + str += "<br>"; + const ExpressionName *ename = &f->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) w); + str += "<i><b>"; + str += ename->name.c_str(); + str += "</b>"; + int iargs = f->maxargs(); + if(iargs < 0) { + iargs = f->minargs() + 1; + } + str += "("; + if(iargs != 0) { + for(int i2 = 1; i2 <= iargs; i2++) { + if(i2 > f->minargs()) { + str += "["; + } + if(i2 > 1) { + str += CALCULATOR->getComma().c_str(); + str += " "; + } + Argument *arg = f->getArgumentDefinition(i2); + if(arg && !arg->name().empty()) { + str += arg->name().c_str(); + } else { + str += i18n("argument"); + str += " "; + str += QString::number(i2); + } + if(i2 > f->minargs()) { + str += "]"; + } + } + if(f->maxargs() < 0) { + str += CALCULATOR->getComma().c_str(); + str += " ..."; + } + } + str += ")"; + str += "</i>"; + if(full_length) { + str += "<i>"; + for(size_t i2 = 1; i2 <= f->countNames(); i2++) { + if(&f->getName(i2) != ename) { + str += "<br>"; + str += f->getName(i2).name.c_str(); + } + } + str += "</i>"; + if(f->subtype() == SUBTYPE_DATA_SET) { + str += "<br>"; + str += "<br>"; + QString str2; + str2.sprintf(i18n("Retrieves data from the %s data set for a given object and property. If \"info\" is typed as property, a dialog window will pop up with all properties of the object."), f->title().c_str()); + str2.replace("<", "<"); + str2.replace(">", ">"); + str += str2; + } + if(!f->description().empty()) { + str += "<br>"; + str += "<br>"; + QString str2 = f->description().c_str(); + str2.replace("<", "<"); + str2.replace(">", ">"); + str += str2; + } + } + } + } + return str; +} + + +QString linkInfo(const QString &link, QWidget *w, bool full_length = false) { + if(!link.isEmpty() && link[0] == '+') { + QString str = link; + str.remove(0, 1); + return str; + } else { + return linkInfo(mainWin->getResultPart(link.toInt()), w, full_length); + } +} + +class QalculateExpressionToolTip : public QToolTip { + +public: + + QalculateResultDisplay *qrd; + + QalculateExpressionToolTip(QalculateResultDisplay *parent, QToolTipGroup *group = 0) : QToolTip(parent->viewport(), group) { + qrd = parent; + } + virtual ~QalculateExpressionToolTip() {} + +protected: + + void maybeTip(const QPoint &p) { + int cx = qrd->contentsX(); + int cy = qrd->contentsY(); + QString str = qrd->anchorAt(qrd->viewportToContents(p), Qt::AnchorName); + if(str.isEmpty()) return; + int w = 5; + while(p.x() + w < qrd->visibleWidth() && qrd->anchorAt(QPoint(p.x() + cx + w, p.y() + cy), Qt::AnchorName) == str) { + w += 5; + } + int x = p.x() - 5; + w += 5; + while(x > 0 && qrd->anchorAt(QPoint(x + cx, p.y() + cy), Qt::AnchorName) == str) { + x -= 5; + w += 5; + } + if(x < 0) x = 0; + if(w + x > qrd->visibleWidth()) w = qrd->visibleWidth() - x; + int h = 5; + while(p.y() + h < qrd->visibleHeight() && qrd->anchorAt(QPoint(p.x() + cx, p.y() + cy + h), Qt::AnchorName) == str) { + h += 5; + } + int y = p.y() - 5; + h += 5; + while(y > 0 && qrd->anchorAt(QPoint(p.x() + cx, y + cy), Qt::AnchorName) == str) { + y -= 5; + h += 5; + } + if(y < 0) y = 0; + if(h + y > qrd->visibleHeight()) h = qrd->visibleHeight() - y; + tip(QRect(x, y, w, h), linkInfo(str, qrd, true)); + } + +}; + +QalculateResultDisplay::QalculateResultDisplay(QWidget *parent, const char *name): QTextBrowser(parent, name) { + + setResizePolicy(AutoOneFit); + setVScrollBarMode(Auto); + setHScrollBarMode(Auto); + setTextFormat(Qt::RichText); + setFrameStyle(QFrame::NoFrame); + //setFocusPolicy(QWidget::TabFocus); + paletteChanged(); + m_under_pointer = NULL; + + QToolTipGroup *tgroup = new QToolTipGroup(viewport()); + tooltip = new QalculateExpressionToolTip(this, tgroup); + + //connect(this, SIGNAL(anchorClicked(const QString&, const QString&)), this, SLOT(onAnchorClicked(const QString&, const QString&))); + connect(this, SIGNAL(doubleClicked(int, int)), this, SLOT(onDoubleClicked(int, int))); + if(kapp) { + connect(kapp, SIGNAL(kdisplayPaletteChanged()), this, SLOT(paletteChanged())); + } + +} + +QalculateResultDisplay::~QalculateResultDisplay() {} + +void QalculateResultDisplay::setRightMargin(int i_margin) { + setMargins(0, 0, i_margin, 0); +} + +void QalculateResultDisplay::onAnchorClicked(const QString&, const QString&) { + /*if(name.isEmpty()) return; + QWhatsThis::display(linkInfo(name, this, true));*/ +} + +QPopupMenu *QalculateResultDisplay::createPopupMenu(const QPoint &pos) { + + m_under_pointer = NULL; + + QPopupMenu *menu = QTextBrowser::createPopupMenu(pos); + menu->insertSeparator(); + mainWin->ActionStoreResult->plug(menu); + mainWin->ActionSaveAsImage->plug(menu); + menu->insertSeparator(); + if(mstruct && mstruct->containsType(STRUCT_ADDITION)) { + if(evalops.structuring != STRUCTURING_FACTORIZE) { + mainWin->ActionFactorize->plug(menu); + } + if(evalops.structuring != STRUCTURING_SIMPLIFY) { + mainWin->ActionSimplify->plug(menu); + } + } else if(mstruct && mstruct->isNumber() && mstruct->number().isInteger() && !mstruct->number().isZero()) { + mainWin->ActionFactorize->plug(menu); + menu->insertSeparator(); + } + if(mstruct && mstruct->containsUnknowns()) { + mainWin->ActionSetUnknowns->plug(menu); + } + if(mstruct && (mstruct->containsType(STRUCT_ADDITION) || mstruct->containsUnknowns())) { + menu->insertSeparator(); + } + if(mstruct && mstruct->containsDivision()) { + mainWin->ActionNonZeroDenominators->plug(menu); + menu->insertSeparator(); + } + int id = menu->insertItem(i18n("Normal")); + if(printops.min_exp == EXP_PRECISION) menu->setItemChecked(id, true); + else menu->connectItem(id, this, SLOT(displayNormal())); + id = menu->insertItem(i18n("Engineering")); + if(printops.min_exp == EXP_BASE_3) menu->setItemChecked(id, true); + else menu->connectItem(id, this, SLOT(displayEngineering())); + id = menu->insertItem(i18n("Scientific")); + if(printops.min_exp == EXP_SCIENTIFIC) menu->setItemChecked(id, true); + else menu->connectItem(id, this, SLOT(displayScientific())); + /*mainWin->ActionNumericalDisplayNormal->plug(menu); + mainWin->ActionNumericalDisplayEngineering->plug(menu); + mainWin->ActionNumericalDisplayScientific->plug(menu);*/ + if(!mstruct || !mstruct->containsType(STRUCT_UNIT)) { + menu->insertSeparator(); + mainWin->ActionNumberBaseBinary->plug(menu); + mainWin->ActionNumberBaseOctal->plug(menu); + mainWin->ActionNumberBaseDecimal->plug(menu); + mainWin->ActionNumberBaseHexadecimal->plug(menu); + menu->insertSeparator(); + mainWin->ActionFractionalDisplayDecimal->plug(menu); + mainWin->ActionFractionalDisplayDecimalTryExact->plug(menu); + mainWin->ActionFractionalDisplayFraction->plug(menu); + mainWin->ActionFractionalDisplayCombined->plug(menu); + } + menu->insertSeparator(); + mainWin->ActionAbbreviateNames->plug(menu); + if(mstruct && mstruct->containsType(STRUCT_UNIT)) { + menu->insertSeparator(); + mainWin->ActionConvertToUnitExpression->plug(menu); + mainWin->ActionConvertToBaseUnits->plug(menu); + mainWin->ActionConvertToBestUnit->plug(menu); + menu->insertSeparator(); + mainWin->ActionEnablePrefixes->plug(menu); + mainWin->ActionEnableUseOfAllPrefixes->plug(menu); + mainWin->ActionEnableDenominatorPrefixes->plug(menu); + } + menu->insertSeparator(); + QPopupMenu *modes_menu = new QPopupMenu(menu); + QObject::connect(modes_menu, SIGNAL(activated(int)), mainWin, SLOT(loadMode(int))); + for(size_t i = 0; i < modes.size(); i++) { + modes_menu->insertItem(modes[i].name, i, i); + } + modes_menu->insertSeparator(); + mainWin->ActionSaveModeAs->plug(modes_menu); + mainWin->ActionDeleteMode->plug(modes_menu); + menu->insertItem(i18n("Meta Modes"), modes_menu); + if(parsed_text.isEmpty()) return menu; + menu->insertSeparator(); + menu->insertItem(i18n("Show Parsed Expression"), this, SLOT(showParsedExpression())); + QString str = anchorAt(pos, Qt::AnchorName); + if(!str.isEmpty()) { + if(str[0] == '+') { + name_under_pointer = str; + name_under_pointer.remove(0, 1); + menu->insertItem(i18n("Show Object Info"), this, SLOT(showInfo())); + } else { + m_under_pointer = mainWin->getResultPart(str.toInt()); + if(m_under_pointer) { + if(m_under_pointer->isVector()) { + if(m_under_pointer->isMatrix()) { + menu->insertItem(i18n("View/Edit Matrix"), this, SLOT(editMatrix())); + } else { + menu->insertItem(i18n("View/Edit Vector"), this, SLOT(editVector())); + } + } else { + menu->insertItem(i18n("Show Object Info"), this, SLOT(showInfo())); + } + } + } + } + curpos = viewport()->mapToGlobal(pos); + return menu; + +} + +void QalculateResultDisplay::displayNormal() { + printops.negative_exponents = false; + printops.sort_options.minus_last = true; + mainWin->ActionNumericalDisplayNormal->activate(); + mainWin->ActionNegativeExponents->setChecked(false); + mainWin->ActionSortMinusLast->setChecked(true); +} +void QalculateResultDisplay::displayEngineering() { + mainWin->ActionNumericalDisplayEngineering->activate(); +} +void QalculateResultDisplay::displayScientific() { + printops.negative_exponents = true; + printops.sort_options.minus_last = false; + mainWin->ActionNumericalDisplayScientific->activate(); + mainWin->ActionNegativeExponents->setChecked(true); + mainWin->ActionSortMinusLast->setChecked(false); +} + +void QalculateResultDisplay::showParsedExpression() { + QString str = i18n("Parsed expression:"); + str += "\n"; + str += parsed_text; + QWhatsThis::display(str, curpos); +} +void QalculateResultDisplay::showInfo() { + if(m_under_pointer) { + QWhatsThis::display(linkInfo(m_under_pointer, this, true), curpos); + } else { + QWhatsThis::display(linkInfo(name_under_pointer, this, true), curpos); + } +} +void QalculateResultDisplay::editVector() { + mainWin->insertMatrixVector(m_under_pointer, true, false, true); +} +void QalculateResultDisplay::editMatrix() { + mainWin->insertMatrixVector(m_under_pointer, false, false, true); +} + +void QalculateResultDisplay::paletteChanged() { + QPalette p = kapp ? kapp->palette() : palette(); + p.setBrush(QColorGroup::Base, p.brush(QPalette::Normal, QColorGroup::Background)); + p.setColor(QColorGroup::Text, p.color(QPalette::Normal, QColorGroup::Foreground)); + setPalette(p); +} + +void QalculateResultDisplay::virtual_hook(int, void*) { +} + +void QalculateResultDisplay::focusInEvent(QFocusEvent* fe) { + QTextBrowser::focusInEvent(fe); + if(fe->reason() == QFocusEvent::Tab || fe->reason() == QFocusEvent::Backtab) + selectAll(true); +} + +void QalculateResultDisplay::focusOutEvent(QFocusEvent* fe) { + QTextBrowser::focusOutEvent(fe); + if(fe->reason() == QFocusEvent::Tab || fe->reason() == QFocusEvent::Backtab) + selectAll(false); +} + +void QalculateResultDisplay::onDoubleClicked(int, int) { + curpos = QCursor::pos(); + QString str = anchorAt(viewportToContents(viewport()->mapFromGlobal(curpos)), Qt::AnchorName); + if(!str.isEmpty()) { + if(str[0] == '+') { + selectAll(false); + name_under_pointer = str; + name_under_pointer.remove(0, 1); + showInfo(); + } else { + m_under_pointer = mainWin->getResultPart(str.toInt()); + if(m_under_pointer) { + selectAll(false); + if(m_under_pointer->isVector()) { + if(m_under_pointer->isMatrix()) { + editMatrix(); + } else { + editVector(); + } + } else { + showInfo(); + } + } + } + } +} + +void QalculateResultDisplay::keyPressEvent(QKeyEvent *e) { + + switch (e->key()) { + case Key_Down: + case Key_Up: + case Key_Left: + case Key_Right: + // jump over QTextEdit's key navigation breakage. + // we're not interested in keyboard navigation within the text + QWidget::keyPressEvent(e); + break; + default: + QTextBrowser::keyPressEvent(e); + } + +} + +QSize QalculateResultDisplay::minimumSizeHint() const { + + QSize ms = minimumSize(); + if((ms.width() > 0) && (ms.height() > 0)) + return ms; + + int w = 100; + if(ms.width() > 0) + w = ms.width(); + + QSimpleRichText rt("<font size=6>X</font>", font()); + rt.setWidth(100); + QSimpleRichText rt2("<font size=2>X</font>", font()); + rt2.setWidth(100); + int h2 = (int) (rt2.height() / 1.5); + h2 += h2 % 2; + int h = rt.height() * 2 + h2 + 2 * frameWidth(); + if(h < ms.height()) + h = ms.height(); + + return QSize(w, h); +} + +QSize QalculateResultDisplay::sizeHint() const { + return minimumSizeHint(); +} + + +#include "qalculateresultdisplay.moc" |