Add variables list and units list and conversion dialogs (files was missing in last commit); Add missing itemproxymodel source files; Add calendar conversion dialog; Add unknown edit dialog; Chain mode; Various improvements and fixes
This commit is contained in:
parent
b1aeea8a19
commit
0e7096c70c
@ -44,8 +44,8 @@ DEFINES += TRANSLATIONS_DIR=\\\"$$TRANSLATIONS_DIR\\\"
|
||||
DEFINES += ICON_DIR=\\\"$$ICON_DIR\\\"
|
||||
DEFINES += VERSION=\\\"$$VERSION\\\"
|
||||
|
||||
HEADERS += src/expressionedit.h src/fpconversiondialog.h src/functioneditdialog.h src/functionsdialog.h src/historyview.h src/itemproxymodel.h src/keypadwidget.h src/preferencesdialog.h src/qalculateqtsettings.h src/qalculatewindow.h src/unitsdialog.h src/variableeditdialog.h src/variablesdialog.h
|
||||
SOURCES += src/expressionedit.cpp src/fpconversiondialog.cpp src/functioneditdialog.cpp src/functionsdialog.cpp src/historyview.cpp src/itemproxymodel.cpp src/keypadwidget.cpp src/main.cpp src/preferencesdialog.cpp src/qalculateqtsettings.cpp src/qalculatewindow.cpp src/unitsdialog.cpp src/variableeditdialog.cpp src/variablesdialog.cpp
|
||||
HEADERS += src/calendarconversiondialog.h src/expressionedit.h src/fpconversiondialog.h src/functioneditdialog.h src/functionsdialog.h src/historyview.h src/itemproxymodel.h src/keypadwidget.h src/preferencesdialog.h src/qalculateqtsettings.h src/qalculatewindow.h src/unitsdialog.h src/unknowneditdialog.h src/variableeditdialog.h src/variablesdialog.h
|
||||
SOURCES += src/calendarconversiondialog.cpp src/expressionedit.cpp src/fpconversiondialog.cpp src/functioneditdialog.cpp src/functionsdialog.cpp src/historyview.cpp src/itemproxymodel.cpp src/keypadwidget.cpp src/main.cpp src/preferencesdialog.cpp src/qalculateqtsettings.cpp src/qalculatewindow.cpp src/unitsdialog.cpp src/unknowneditdialog.cpp src/variableeditdialog.cpp src/variablesdialog.cpp
|
||||
|
||||
unix:!equals(COMPILE_RESOURCES,"yes"):!android:!macx {
|
||||
|
||||
|
153
src/calendarconversiondialog.cpp
Normal file
153
src/calendarconversiondialog.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
Qalculate (QT UI)
|
||||
|
||||
Copyright (C) 2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
#include <QSpinBox>
|
||||
#include <QPushButton>
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
|
||||
#include "qalculateqtsettings.h"
|
||||
#include "calendarconversiondialog.h"
|
||||
|
||||
CalendarConversionDialog::CalendarConversionDialog(QWidget *parent) : QDialog(parent), block_calendar_conversion(false) {
|
||||
setWindowTitle(tr("Calendar Conversion"));
|
||||
QVBoxLayout *box = new QVBoxLayout(this);
|
||||
QGridLayout *grid = new QGridLayout();
|
||||
CalendarSystem cs; QString str;
|
||||
for(int i = 0; i < 10; i++) {
|
||||
switch(i) {
|
||||
case 0: {str = tr("Gregorian"); cs = CALENDAR_GREGORIAN; break;}
|
||||
case 1: {str = tr("Hebrew"); cs = CALENDAR_HEBREW; break;}
|
||||
case 2: {str = tr("Islamic (Hijri)"); cs = CALENDAR_ISLAMIC; break;}
|
||||
case 3: {str = tr("Persian (Solar Hijri)"); cs = CALENDAR_PERSIAN; break;}
|
||||
case 4: {str = tr("Indian (National)"); cs = CALENDAR_INDIAN; break;}
|
||||
case 5: {str = tr("Chinese"); cs = CALENDAR_CHINESE; break;}
|
||||
case 6: {str = tr("Julian"); cs = CALENDAR_JULIAN; break;}
|
||||
case 7: {str = tr("Revised Julian (Milanković)"); cs = CALENDAR_MILANKOVIC; break;}
|
||||
case 8: {str = tr("Coptic"); cs = CALENDAR_COPTIC; break;}
|
||||
case 9: {str = tr("Ethiopian"); cs = CALENDAR_ETHIOPIAN; break;}
|
||||
}
|
||||
grid->addWidget(new QLabel(str, this), i, 0);
|
||||
if(cs == CALENDAR_CHINESE) {
|
||||
chineseStemCombo = new QComboBox(this); chineseBranchCombo = new QComboBox(this);
|
||||
chineseStemCombo->setProperty("QALCULATE INDEX", i); chineseStemCombo->setProperty("QALCULATE CALENDAR", cs);
|
||||
chineseBranchCombo->setProperty("QALCULATE INDEX", i); chineseBranchCombo->setProperty("QALCULATE CALENDAR", cs);
|
||||
for(int i2 = 1; i2 <= 5; i2++) chineseStemCombo->addItem(QString::fromStdString(chineseStemName(i2 * 2)));
|
||||
for(int i2 = 1; i2 <= 12; i2++) chineseBranchCombo->addItem(QString::fromStdString(chineseBranchName(i2)));
|
||||
grid->addWidget(chineseStemCombo, i, 1); grid->addWidget(chineseBranchCombo, i, 2);
|
||||
connect(chineseStemCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateCalendars()));
|
||||
connect(chineseBranchCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateCalendars()));
|
||||
} else {
|
||||
yearEdit[i] = new QSpinBox(this); yearEdit[i]->setRange(INT_MIN, INT_MAX);
|
||||
yearEdit[i]->setProperty("QALCULATE INDEX", i); yearEdit[i]->setProperty("QALCULATE CALENDAR", cs);
|
||||
yearEdit[i]->setAlignment(Qt::AlignRight);
|
||||
grid->addWidget(yearEdit[i], i, 1, 1, 2);
|
||||
connect(yearEdit[i], SIGNAL(valueChanged(int)), this, SLOT(updateCalendars()));
|
||||
}
|
||||
monthCombo[i] = new QComboBox(this); dayCombo[i] = new QComboBox(this);
|
||||
for(int i2 = 1; i2 <= numberOfMonths(cs); i2++) monthCombo[i]->addItem(QString::fromStdString(monthName(i2, cs)));
|
||||
for(int i2 = 1; i2 <= 31; i2++) dayCombo[i]->addItem(QString::number(i2));
|
||||
monthCombo[i]->setProperty("QALCULATE INDEX", i); monthCombo[i]->setProperty("QALCULATE CALENDAR", cs);
|
||||
dayCombo[i]->setProperty("QALCULATE INDEX", i); dayCombo[i]->setProperty("QALCULATE CALENDAR", cs);
|
||||
grid->addWidget(monthCombo[i], i, 3); grid->addWidget(dayCombo[i], i, 4);
|
||||
connect(monthCombo[i], SIGNAL(currentIndexChanged(int)), this, SLOT(updateCalendars()));
|
||||
connect(dayCombo[i], SIGNAL(currentIndexChanged(int)), this, SLOT(updateCalendars()));
|
||||
}
|
||||
box->addLayout(grid);
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this);
|
||||
box->addWidget(buttonBox);
|
||||
connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject()));
|
||||
}
|
||||
CalendarConversionDialog::~CalendarConversionDialog() {}
|
||||
|
||||
void CalendarConversionDialog::updateCalendars() {
|
||||
if(block_calendar_conversion) return;
|
||||
block_calendar_conversion = true;
|
||||
int index = sender()->property("QALCULATE INDEX").toInt();
|
||||
CalendarSystem cs = (CalendarSystem) sender()->property("QALCULATE CALENDAR").toInt();
|
||||
long int y;
|
||||
if(cs == CALENDAR_CHINESE) {
|
||||
long int cy = chineseStemBranchToCycleYear((chineseStemCombo->currentIndex() * 2) + 1, chineseBranchCombo->currentIndex() + 1);
|
||||
if(cy <= 0) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("The selected Chinese year does not exist."));
|
||||
block_calendar_conversion = false;
|
||||
return;
|
||||
}
|
||||
y = chineseCycleYearToYear(79, cy);
|
||||
} else {
|
||||
y = yearEdit[index]->value();
|
||||
}
|
||||
long int m = monthCombo[index]->currentIndex() + 1;
|
||||
long int d = dayCombo[index]->currentIndex() + 1;
|
||||
QalculateDateTime date;
|
||||
if(!calendarToDate(date, y, m, d, cs)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Conversion to Gregorian calendar failed."));
|
||||
block_calendar_conversion = false;
|
||||
return;
|
||||
}
|
||||
QString failed_str;
|
||||
for(int i = 0; i < 10; i++) {
|
||||
switch(i) {
|
||||
case 0: {cs = CALENDAR_GREGORIAN; break;}
|
||||
case 1: {cs = CALENDAR_HEBREW; break;}
|
||||
case 2: {cs = CALENDAR_ISLAMIC; break;}
|
||||
case 3: {cs = CALENDAR_PERSIAN; break;}
|
||||
case 4: {cs = CALENDAR_INDIAN; break;}
|
||||
case 5: {cs = CALENDAR_CHINESE; break;}
|
||||
case 6: {cs = CALENDAR_JULIAN; break;}
|
||||
case 7: {cs = CALENDAR_MILANKOVIC; break;}
|
||||
case 8: {cs = CALENDAR_COPTIC; break;}
|
||||
case 9: {cs = CALENDAR_ETHIOPIAN; break;}
|
||||
}
|
||||
if(dateToCalendar(date, y, m, d, cs) && y <= INT_MAX && y >= INT_MIN && m <= numberOfMonths(cs) && d <= 31) {
|
||||
if(cs == CALENDAR_CHINESE) {
|
||||
long int cy, yc, st, br;
|
||||
chineseYearInfo(y, cy, yc, st, br);
|
||||
chineseStemCombo->setCurrentIndex((st - 1) / 2);
|
||||
chineseBranchCombo->setCurrentIndex(br - 1);
|
||||
} else {
|
||||
yearEdit[i]->setValue(y);
|
||||
}
|
||||
monthCombo[i]->setCurrentIndex(m - 1);
|
||||
dayCombo[i]->setCurrentIndex(d - 1);
|
||||
} else {
|
||||
if(!failed_str.isEmpty()) failed_str += ", ";
|
||||
switch(i) {
|
||||
case 0: {failed_str += tr("Gregorian"); break;}
|
||||
case 1: {failed_str += tr("Hebrew"); break;}
|
||||
case 2: {failed_str += tr("Islamic (Hijri)"); break;}
|
||||
case 3: {failed_str += tr("Persian (Solar Hijri)"); break;}
|
||||
case 4: {failed_str += tr("Indian (National)"); break;}
|
||||
case 5: {failed_str += tr("Chinese"); break;}
|
||||
case 6: {failed_str += tr("Julian"); break;}
|
||||
case 7: {failed_str += tr("Revised Julian (Milanković)"); break;}
|
||||
case 8: {failed_str += tr("Coptic"); break;}
|
||||
case 9: {failed_str += tr("Ethiopian"); break;}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!failed_str.isEmpty()) QMessageBox::warning(this, tr("Error"), tr("Calendar conversion failed for: %1.").arg(failed_str));
|
||||
block_calendar_conversion = false;
|
||||
}
|
||||
void CalendarConversionDialog::setDate(QalculateDateTime date) {
|
||||
block_calendar_conversion = true;
|
||||
yearEdit[0]->setValue(date.year());
|
||||
monthCombo[0]->setCurrentIndex(date.month() - 1);
|
||||
block_calendar_conversion = false;
|
||||
dayCombo[0]->setCurrentIndex(date.day() - 1);
|
||||
}
|
||||
|
48
src/calendarconversiondialog.h
Normal file
48
src/calendarconversiondialog.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Qalculate (QT UI)
|
||||
|
||||
Copyright (C) 2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef CALENDAR_CONVERSION_DIALOG_H
|
||||
#define CALENDAR_CONVERSION_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <libqalculate/qalculate.h>
|
||||
|
||||
class QComboBox;
|
||||
class QSpinBox;
|
||||
|
||||
class CalendarConversionDialog : public QDialog {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
|
||||
QSpinBox *yearEdit[10];
|
||||
QComboBox *monthCombo[10], *dayCombo[10], *chineseStemCombo, *chineseBranchCombo;
|
||||
bool block_calendar_conversion;
|
||||
|
||||
protected slots:
|
||||
|
||||
void updateCalendars();
|
||||
|
||||
public slots:
|
||||
|
||||
void setDate(QalculateDateTime date);
|
||||
|
||||
public:
|
||||
|
||||
CalendarConversionDialog(QWidget *parent = NULL);
|
||||
virtual ~CalendarConversionDialog();
|
||||
|
||||
};
|
||||
|
||||
#endif //CALENDAR_CONVERSION_DIALOG_H
|
||||
|
@ -1040,8 +1040,8 @@ void ExpressionEdit::updateCompletion() {
|
||||
COMPLETION_APPEND(str1, tr("Bijective base-26"), 290, NULL)
|
||||
COMPLETION_CONVERT_STRING("binary") str1 += " <i>"; str1 += "bin"; str1 += "</i>";
|
||||
COMPLETION_APPEND(str1, tr("Binary number"), 202, NULL)
|
||||
/*COMPLETION_CONVERT_STRING("calendars")
|
||||
COMPLETION_APPEND(str1, tr("Calendars"), 500, NULL)*/
|
||||
COMPLETION_CONVERT_STRING("calendars")
|
||||
COMPLETION_APPEND(str1, tr("Calendars"), 500, NULL)
|
||||
COMPLETION_CONVERT_STRING("cis")
|
||||
COMPLETION_APPEND(str1, tr("Complex cis form"), 401, NULL)
|
||||
COMPLETION_CONVERT_STRING("decimal") str1 += " <i>"; str1 += "dec"; str1 += "</i>";
|
||||
@ -1095,7 +1095,15 @@ void ExpressionEdit::updateCompletion() {
|
||||
}
|
||||
|
||||
void ExpressionEdit::setExpression(std::string str) {
|
||||
setPlainText(QString::fromStdString(str));
|
||||
setExpression(QString::fromStdString(str));
|
||||
}
|
||||
void ExpressionEdit::setExpression(const QString &str) {
|
||||
block_add_to_undo++;
|
||||
setCursorWidth(0);
|
||||
clear();
|
||||
block_add_to_undo--;
|
||||
insertPlainText(str);
|
||||
setCursorWidth(1);
|
||||
}
|
||||
std::string ExpressionEdit::expression() const {
|
||||
return toPlainText().toStdString();
|
||||
@ -1130,14 +1138,17 @@ void ExpressionEdit::keyPressEvent(QKeyEvent *event) {
|
||||
if(event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::GroupSwitchModifier || event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::KeypadModifier) {
|
||||
switch(event->key()) {
|
||||
case Qt::Key_Asterisk: {
|
||||
if(doChainMode(SIGN_MULTIPLICATION)) return;
|
||||
wrapSelection(SIGN_MULTIPLICATION);
|
||||
return;
|
||||
}
|
||||
case Qt::Key_Minus: {
|
||||
if(doChainMode(SIGN_MINUS)) return;
|
||||
wrapSelection(SIGN_MINUS);
|
||||
return;
|
||||
}
|
||||
case Qt::Key_Dead_Circumflex: {
|
||||
if(doChainMode(settings->caret_as_xor ? " xor " : "^")) return;
|
||||
wrapSelection(settings->caret_as_xor ? " xor " : "^");
|
||||
return;
|
||||
}
|
||||
@ -1146,14 +1157,17 @@ void ExpressionEdit::keyPressEvent(QKeyEvent *event) {
|
||||
return;
|
||||
}
|
||||
case Qt::Key_AsciiCircum: {
|
||||
if(doChainMode(settings->caret_as_xor ? " xor " : "^")) return;
|
||||
wrapSelection(settings->caret_as_xor ? " xor " : "^");
|
||||
return;
|
||||
}
|
||||
case Qt::Key_Plus: {
|
||||
if(doChainMode("+")) return;
|
||||
wrapSelection("+");
|
||||
return;
|
||||
}
|
||||
case Qt::Key_Slash: {
|
||||
if(doChainMode("/")) return;
|
||||
wrapSelection("/");
|
||||
return;
|
||||
}
|
||||
@ -1168,6 +1182,14 @@ void ExpressionEdit::keyPressEvent(QKeyEvent *event) {
|
||||
}
|
||||
if(event->modifiers() == Qt::ControlModifier || (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))) {
|
||||
switch(event->key()) {
|
||||
case Qt::Key_A: {
|
||||
if(event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) {
|
||||
if(doChainMode("∠")) return;
|
||||
insertPlainText("∠");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::Key_ParenLeft: {}
|
||||
case Qt::Key_ParenRight: {
|
||||
smartParentheses();
|
||||
@ -1235,8 +1257,8 @@ void ExpressionEdit::keyPressEvent(QKeyEvent *event) {
|
||||
blockParseStatus(true);
|
||||
setCursorWidth(0);
|
||||
if(history_index == -1 && current_history == toPlainText()) history_index = 0;
|
||||
if(history_index == -1) setPlainText(current_history);
|
||||
else setPlainText(QString::fromStdString(settings->expression_history[history_index]));
|
||||
if(history_index == -1) setExpression(current_history);
|
||||
else setExpression(QString::fromStdString(settings->expression_history[history_index]));
|
||||
blockParseStatus(false);
|
||||
blockCompletion(false);
|
||||
QTextCursor c = textCursor();
|
||||
@ -1276,10 +1298,10 @@ void ExpressionEdit::keyPressEvent(QKeyEvent *event) {
|
||||
blockParseStatus(true);
|
||||
setCursorWidth(0);
|
||||
if(history_index < 0) {
|
||||
if(history_index == -1 && current_history != toPlainText()) setPlainText(current_history);
|
||||
if(history_index == -1 && current_history != toPlainText()) setExpression(current_history);
|
||||
else clear();
|
||||
} else {
|
||||
setPlainText(QString::fromStdString(settings->expression_history[history_index]));
|
||||
setExpression(QString::fromStdString(settings->expression_history[history_index]));
|
||||
}
|
||||
QTextCursor c = textCursor();
|
||||
c.movePosition(QTextCursor::End);
|
||||
@ -1444,7 +1466,7 @@ void ExpressionEdit::blockUndo(bool b) {
|
||||
void ExpressionEdit::setStatusText(QString text) {
|
||||
if(completionView->isVisible() || text.isEmpty()) {
|
||||
QToolTip::hideText();
|
||||
} else {
|
||||
} else if(settings->display_expression_status) {
|
||||
if(text.length() >= 30) {
|
||||
text.replace("\n", "<br>");
|
||||
QToolTip::showText(mapToGlobal(cursorRect().bottomRight()), text.length() >= 60 ? ("<font size=\"-1\">" + text + "</font>") : ("<font size=\"+0\">" + text + "</font>"));
|
||||
@ -1455,6 +1477,7 @@ void ExpressionEdit::setStatusText(QString text) {
|
||||
}
|
||||
|
||||
bool ExpressionEdit::displayFunctionHint(MathFunction *f, int arg_index) {
|
||||
if(!settings->display_expression_status) return false;
|
||||
if(!f) return false;
|
||||
int iargs = f->maxargs();
|
||||
Argument *arg;
|
||||
@ -1540,7 +1563,6 @@ void ExpressionEdit::displayParseStatus(bool update, bool show_tooltip) {
|
||||
if(update) expression_has_changed2 = true;
|
||||
bool prev_func = cdata->current_function;
|
||||
cdata->current_function = NULL;
|
||||
if(!settings->display_expression_status) return;
|
||||
if(block_display_parse) return;
|
||||
QString qtext = toPlainText();
|
||||
std::string text = qtext.toStdString(), str_f;
|
||||
@ -1930,11 +1952,11 @@ void ExpressionEdit::displayParseStatus(bool update, bool show_tooltip) {
|
||||
if(had_errors || had_warnings) prev_parsed_expression = QString::fromStdString(parsed_expression_tooltip);
|
||||
else prev_parsed_expression = QString::fromStdString(parsed_expression);
|
||||
}
|
||||
if(!b_func && show_tooltip) setStatusText(prev_parsed_expression);
|
||||
if(!b_func && show_tooltip) setStatusText(settings->chain_mode ? "" : prev_parsed_expression);
|
||||
expression_has_changed2 = false;
|
||||
} else if(!b_func) {
|
||||
CALCULATOR->clearMessages();
|
||||
if(prev_func && show_tooltip) setStatusText(prev_parsed_expression);
|
||||
if(prev_func && show_tooltip) setStatusText(settings->chain_mode ? "" : prev_parsed_expression);
|
||||
}
|
||||
settings->evalops.parse_options.preserve_format = false;
|
||||
}
|
||||
@ -1985,6 +2007,7 @@ void ExpressionEdit::onTextChanged() {
|
||||
cdata->current_function = settings->f_answer;
|
||||
displayParseStatus();
|
||||
}
|
||||
if(document()->isEmpty()) expression_has_changed = false;
|
||||
}
|
||||
bool ExpressionEdit::expressionHasChanged() {
|
||||
return expression_has_changed && !document()->isEmpty() && !toPlainText().trimmed().isEmpty();
|
||||
@ -2813,7 +2836,7 @@ void ExpressionEdit::setCurrentObject() {
|
||||
l_to = current_object_text.length();
|
||||
pos = current_object_text.length();
|
||||
pos2 = pos;
|
||||
//if(current_object_text[0] == '/') return;
|
||||
if(l_to > 0 && current_object_text[0] == '/') return;
|
||||
for(size_t i = 0; i < l_to; i++) {
|
||||
if(current_object_text[i] == '#') {
|
||||
current_object_start = -1;
|
||||
@ -2895,3 +2918,59 @@ void ExpressionEdit::setCurrentObject() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ExpressionEdit::doChainMode(const QString &op) {
|
||||
if(expression_has_changed && !settings->rpn_mode && settings->chain_mode && !cdata->current_function && settings->evalops.parse_options.base != BASE_UNICODE && (settings->evalops.parse_options.base != BASE_CUSTOM || (CALCULATOR->customInputBase() <= 62 && CALCULATOR->customInputBase() >= -62))) {
|
||||
QTextCursor cur = textCursor();
|
||||
if(cur.hasSelection()) {
|
||||
if(cur.selectionStart() != 0 || cur.selectionEnd() != toPlainText().length()) return false;
|
||||
} else if(!cur.atEnd()) {
|
||||
return false;
|
||||
}
|
||||
std::string str = toPlainText().toStdString();
|
||||
remove_blanks(str);
|
||||
if(str.empty() || str[0] == '/' || CALCULATOR->hasToExpression(str, true, settings->evalops) || CALCULATOR->hasWhereExpression(str, settings->evalops) || last_is_operator(str)) return false;
|
||||
size_t par_n = 0, vec_n = 0;
|
||||
for(size_t i = 0; i < str.length(); i++) {
|
||||
if(str[i] == LEFT_PARENTHESIS_CH) par_n++;
|
||||
else if(par_n > 0 && str[i] == RIGHT_PARENTHESIS_CH) par_n--;
|
||||
else if(str[i] == LEFT_VECTOR_WRAP_CH) vec_n++;
|
||||
else if(vec_n > 0 && str[i] == RIGHT_VECTOR_WRAP_CH) vec_n--;
|
||||
}
|
||||
if(par_n > 0 || vec_n > 0) return false;
|
||||
MathStructure m;
|
||||
CALCULATOR->clearMessages();
|
||||
CALCULATOR->calculate(&m, CALCULATOR->unlocalizeExpression(str, settings->evalops.parse_options), 1000, settings->evalops, NULL, NULL, false);
|
||||
if(m.isAborted()) return false;
|
||||
PrintOptions po = settings->printops;
|
||||
po.allow_non_usable = false;
|
||||
po.is_approximate = NULL;
|
||||
po.can_display_unicode_string_arg = (void*) this;
|
||||
str = CALCULATOR->print(m, 1000, settings->printops);
|
||||
if(str == CALCULATOR->abortedMessage() || str.length() > 100) return false;
|
||||
std::string warnings;
|
||||
int message_n = 0;
|
||||
while(CALCULATOR->message()) {
|
||||
MessageType mtype = CALCULATOR->message()->type();
|
||||
if(mtype == MESSAGE_ERROR || mtype == MESSAGE_WARNING) {
|
||||
if(mtype == MESSAGE_ERROR) return false;
|
||||
if(message_n > 0) {
|
||||
if(message_n == 1) warnings.insert(0, "• ");
|
||||
warnings += "\n• ";
|
||||
}
|
||||
warnings += CALCULATOR->message()->message();
|
||||
}
|
||||
message_n++;
|
||||
CALCULATOR->nextMessage();
|
||||
}
|
||||
if(m.size() > 0 && !m.isFunction() && !m.isVector() && (((!m.isMultiplication() || op != SIGN_MULTIPLICATION) && (!m.isAddition() || (op != "+" && op != SIGN_MINUS)) && (!m.isBitwiseOr() || op != BITWISE_OR) && (!m.isBitwiseAnd() || op != BITWISE_AND)))) {
|
||||
str.insert(0, "(");
|
||||
str += ")";
|
||||
}
|
||||
setExpression(QString::fromStdString(str) + op);
|
||||
setStatusText(QString::fromStdString(warnings));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,7 @@ class ExpressionEdit : public QPlainTextEdit {
|
||||
QSize sizeHint() const;
|
||||
|
||||
void wrapSelection(const QString &text = QString(), bool insert_before = false, bool add_parentheses = false);
|
||||
bool doChainMode(const QString &op);
|
||||
bool expressionHasChanged();
|
||||
void setExpressionHasChanged(bool);
|
||||
void displayParseStatus(bool = false, bool = true);
|
||||
@ -120,6 +121,7 @@ class ExpressionEdit : public QPlainTextEdit {
|
||||
|
||||
void updateCompletion();
|
||||
void setExpression(std::string);
|
||||
void setExpression(const QString &str);
|
||||
void blockCompletion(bool = true);
|
||||
void blockParseStatus(bool = true);
|
||||
void blockUndo(bool = true);
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "fpconversiondialog.h"
|
||||
|
||||
FPConversionDialog::FPConversionDialog(QWidget *parent) : QDialog(parent) {
|
||||
setWindowTitle(tr("Floating point conversion (IEEE 754)"));
|
||||
setWindowTitle(tr("Floating Point Conversion (IEEE 754)"));
|
||||
QVBoxLayout *box = new QVBoxLayout(this);
|
||||
QGridLayout *grid = new QGridLayout();
|
||||
grid->addWidget(new QLabel(tr("Format"), this), 0, 0, Qt::AlignRight);
|
||||
|
@ -18,18 +18,66 @@
|
||||
#include <QLabel>
|
||||
#include <QRadioButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QKeyEvent>
|
||||
#include <QDebug>
|
||||
|
||||
#include "qalculateqtsettings.h"
|
||||
#include "functioneditdialog.h"
|
||||
|
||||
FunctionEditDialog::FunctionEditDialog(QWidget *parent) : QDialog(parent), read_only(false) {
|
||||
class MathTextEdit : public QPlainTextEdit {
|
||||
|
||||
public:
|
||||
|
||||
MathTextEdit(QWidget *parent) : QPlainTextEdit(parent) {
|
||||
setAttribute(Qt::WA_InputMethodEnabled, settings->enable_input_method);
|
||||
}
|
||||
~MathTextEdit() {}
|
||||
|
||||
protected:
|
||||
|
||||
void keyPressEvent(QKeyEvent *event) override {
|
||||
if(event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::GroupSwitchModifier || event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::KeypadModifier) {
|
||||
switch(event->key()) {
|
||||
case Qt::Key_Asterisk: {
|
||||
insertPlainText(SIGN_MULTIPLICATION);
|
||||
return;
|
||||
}
|
||||
case Qt::Key_Minus: {
|
||||
insertPlainText(SIGN_MINUS);
|
||||
return;
|
||||
}
|
||||
case Qt::Key_Dead_Circumflex: {
|
||||
insertPlainText(settings->caret_as_xor ? " xor " : "^");
|
||||
return;
|
||||
}
|
||||
case Qt::Key_Dead_Tilde: {
|
||||
insertPlainText("~");
|
||||
return;
|
||||
}
|
||||
case Qt::Key_AsciiCircum: {
|
||||
if(settings->caret_as_xor) {
|
||||
insertPlainText(" xor ");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(event->key() == Qt::Key_Asterisk && (event->modifiers() == Qt::ControlModifier || event->modifiers() == (Qt::ControlModifier | Qt::KeypadModifier) || event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))) {
|
||||
insertPlainText("^");
|
||||
return;
|
||||
}
|
||||
QPlainTextEdit::keyPressEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
FunctionEditDialog::FunctionEditDialog(QWidget *parent) : QDialog(parent) {
|
||||
QGridLayout *grid = new QGridLayout(this);
|
||||
grid->addWidget(new QLabel(tr("Name:"), this), 0, 0);
|
||||
nameEdit = new QLineEdit(this);
|
||||
grid->addWidget(nameEdit, 0, 1);
|
||||
grid->addWidget(new QLabel(tr("Expression:"), this), 1, 0, 1, 2);
|
||||
expressionEdit = new QPlainTextEdit(this);
|
||||
expressionEdit = new MathTextEdit(this);
|
||||
grid->addWidget(expressionEdit, 2, 0, 1, 2);
|
||||
QHBoxLayout *box = new QHBoxLayout();
|
||||
QButtonGroup *group = new QButtonGroup(this); group->setExclusive(true);
|
||||
@ -50,17 +98,24 @@ FunctionEditDialog::FunctionEditDialog(QWidget *parent) : QDialog(parent), read_
|
||||
}
|
||||
FunctionEditDialog::~FunctionEditDialog() {}
|
||||
|
||||
UserFunction *FunctionEditDialog::createFunction() {
|
||||
UserFunction *FunctionEditDialog::createFunction(MathFunction **replaced_item) {
|
||||
if(replaced_item) *replaced_item = NULL;
|
||||
MathFunction *func = NULL;
|
||||
if(CALCULATOR->functionNameTaken(nameEdit->text().trimmed().toStdString())) {
|
||||
if(QMessageBox::question(this, tr("Question"), tr("An function with the same name already exists.\nDo you want to overwrite it?")) != QMessageBox::Yes) {
|
||||
nameEdit->setFocus();
|
||||
return NULL;
|
||||
}
|
||||
if(replaced_item) {
|
||||
func = CALCULATOR->getActiveFunction(nameEdit->text().trimmed().toStdString());
|
||||
*replaced_item = func;
|
||||
}
|
||||
}
|
||||
UserFunction *f;
|
||||
MathFunction *func = CALCULATOR->getActiveFunction(nameEdit->text().trimmed().toStdString());
|
||||
if(func && func->isLocal() && func->subtype() == SUBTYPE_USER_FUNCTION) {
|
||||
f = (UserFunction*) func;
|
||||
if(f->countNames() > 1) f->clearNames();
|
||||
f->setHidden(false); f->setApproximate(false); f->setDescription(""); f->setCondition(""); f->setExample(""); f->clearArgumentDefinitions(); f->setTitle("");
|
||||
if(!modifyFunction(f)) return NULL;
|
||||
return f;
|
||||
}
|
||||
@ -70,19 +125,26 @@ UserFunction *FunctionEditDialog::createFunction() {
|
||||
gsub("y", "\\y", str);
|
||||
gsub("z", "\\z", str);
|
||||
}
|
||||
gsub(SIGN_MULTIPLICATION, "*", str);
|
||||
gsub(SIGN_MINUS, "-", str);
|
||||
f = new UserFunction("", nameEdit->text().trimmed().toStdString(), str);
|
||||
CALCULATOR->addFunction(f);
|
||||
return f;
|
||||
}
|
||||
bool FunctionEditDialog::modifyFunction(MathFunction *f) {
|
||||
bool FunctionEditDialog::modifyFunction(MathFunction *f, MathFunction **replaced_item) {
|
||||
if(replaced_item) *replaced_item = NULL;
|
||||
if(CALCULATOR->functionNameTaken(nameEdit->text().trimmed().toStdString(), f)) {
|
||||
if(QMessageBox::question(this, tr("Question"), tr("An function with the same name already exists.\nDo you want to overwrite it?")) != QMessageBox::Yes) {
|
||||
nameEdit->setFocus();
|
||||
return false;
|
||||
}
|
||||
if(replaced_item) {
|
||||
MathFunction *func = CALCULATOR->getActiveFunction(nameEdit->text().trimmed().toStdString());
|
||||
if(func != f) *replaced_item = func;
|
||||
}
|
||||
}
|
||||
f->setLocal(true);
|
||||
if(f->countNames() > 1) f->clearNames();
|
||||
if(f->countNames() > 1 && f->getName(1).name != nameEdit->text().trimmed().toStdString()) f->clearNames();
|
||||
f->setName(nameEdit->text().trimmed().toStdString());
|
||||
if(f->subtype() == SUBTYPE_USER_FUNCTION) {
|
||||
std::string str = CALCULATOR->unlocalizeExpression(expressionEdit->toPlainText().trimmed().toStdString(), settings->evalops.parse_options);
|
||||
@ -91,16 +153,21 @@ bool FunctionEditDialog::modifyFunction(MathFunction *f) {
|
||||
gsub("y", "\\y", str);
|
||||
gsub("z", "\\z", str);
|
||||
}
|
||||
gsub(SIGN_MULTIPLICATION, "*", str);
|
||||
gsub(SIGN_MINUS, "-", str);
|
||||
((UserFunction*) f)->setFormula(str);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void FunctionEditDialog::setFunction(MathFunction *f) {
|
||||
read_only = !f->isLocal();
|
||||
bool read_only = !f->isLocal();
|
||||
nameEdit->setText(QString::fromStdString(f->getName(1).name));
|
||||
if(f->subtype() == SUBTYPE_USER_FUNCTION) {
|
||||
expressionEdit->setEnabled(true);
|
||||
expressionEdit->setPlainText(QString::fromStdString(CALCULATOR->localizeExpression(((UserFunction*) f)->formula(), settings->evalops.parse_options)));
|
||||
std::string str = CALCULATOR->localizeExpression(((UserFunction*) f)->formula(), settings->evalops.parse_options);
|
||||
gsub("*", SIGN_MULTIPLICATION, str);
|
||||
gsub("-", SIGN_MINUS, str);
|
||||
expressionEdit->setPlainText(QString::fromStdString(str));
|
||||
} else {
|
||||
read_only = true;
|
||||
expressionEdit->setEnabled(false);
|
||||
@ -108,16 +175,18 @@ void FunctionEditDialog::setFunction(MathFunction *f) {
|
||||
}
|
||||
okButton->setEnabled(!read_only);
|
||||
nameEdit->setReadOnly(read_only);
|
||||
ref1Button->setEnabled(!read_only);
|
||||
ref2Button->setEnabled(!read_only);
|
||||
expressionEdit->setReadOnly(read_only);
|
||||
}
|
||||
void FunctionEditDialog::onNameEdited(const QString &str) {
|
||||
if(!read_only) okButton->setEnabled(!str.trimmed().isEmpty() && (!expressionEdit->isEnabled() || !expressionEdit->document()->isEmpty()));
|
||||
okButton->setEnabled(!str.trimmed().isEmpty() && (!expressionEdit->isEnabled() || !expressionEdit->document()->isEmpty()));
|
||||
if(!str.trimmed().isEmpty() && !CALCULATOR->functionNameIsValid(str.trimmed().toStdString())) {
|
||||
nameEdit->setText(QString::fromStdString(CALCULATOR->convertToValidFunctionName(str.trimmed().toStdString())));
|
||||
}
|
||||
}
|
||||
void FunctionEditDialog::onExpressionChanged() {
|
||||
if(!read_only) okButton->setEnabled((!expressionEdit->document()->isEmpty() || !expressionEdit->isEnabled()) && !nameEdit->text().trimmed().isEmpty());
|
||||
okButton->setEnabled((!expressionEdit->document()->isEmpty() || !expressionEdit->isEnabled()) && !nameEdit->text().trimmed().isEmpty());
|
||||
}
|
||||
void FunctionEditDialog::setExpression(const QString &str) {
|
||||
expressionEdit->setPlainText(str);
|
||||
@ -134,13 +203,13 @@ void FunctionEditDialog::setRefType(int i) {
|
||||
if(i == 1) ref1Button->setChecked(true);
|
||||
else if(i == 2) ref2Button->setChecked(true);
|
||||
}
|
||||
bool FunctionEditDialog::editFunction(QWidget *parent, MathFunction *f) {
|
||||
bool FunctionEditDialog::editFunction(QWidget *parent, MathFunction *f, MathFunction **replaced_item) {
|
||||
FunctionEditDialog *d = new FunctionEditDialog(parent);
|
||||
d->setRefType(2);
|
||||
d->setWindowTitle(tr("Edit Function"));
|
||||
d->setFunction(f);
|
||||
while(d->exec() == QDialog::Accepted) {
|
||||
if(d->modifyFunction(f)) {
|
||||
if(d->modifyFunction(f, replaced_item)) {
|
||||
d->deleteLater();
|
||||
return true;
|
||||
}
|
||||
@ -148,7 +217,7 @@ bool FunctionEditDialog::editFunction(QWidget *parent, MathFunction *f) {
|
||||
d->deleteLater();
|
||||
return false;
|
||||
}
|
||||
UserFunction* FunctionEditDialog::newFunction(QWidget *parent) {
|
||||
UserFunction* FunctionEditDialog::newFunction(QWidget *parent, MathFunction **replaced_item) {
|
||||
FunctionEditDialog *d = new FunctionEditDialog(parent);
|
||||
d->setWindowTitle(tr("New Function"));
|
||||
d->setRefType(1);
|
||||
@ -161,7 +230,7 @@ UserFunction* FunctionEditDialog::newFunction(QWidget *parent) {
|
||||
d->setName(QString::fromStdString(f_name));
|
||||
UserFunction *f = NULL;
|
||||
while(d->exec() == QDialog::Accepted) {
|
||||
f = d->createFunction();
|
||||
f = d->createFunction(replaced_item);
|
||||
if(f) break;
|
||||
}
|
||||
d->deleteLater();
|
||||
|
@ -32,8 +32,6 @@ class FunctionEditDialog : public QDialog {
|
||||
QPushButton *okButton;
|
||||
QRadioButton *ref1Button, *ref2Button;
|
||||
|
||||
bool read_only;
|
||||
|
||||
protected slots:
|
||||
|
||||
void onNameEdited(const QString&);
|
||||
@ -44,16 +42,16 @@ class FunctionEditDialog : public QDialog {
|
||||
FunctionEditDialog(QWidget *parent = NULL);
|
||||
virtual ~FunctionEditDialog();
|
||||
|
||||
UserFunction *createFunction();
|
||||
bool modifyFunction(MathFunction *f);
|
||||
UserFunction *createFunction(MathFunction **replaced_item = NULL);
|
||||
bool modifyFunction(MathFunction *f, MathFunction **replaced_item = NULL);
|
||||
void setFunction(MathFunction *f);
|
||||
void setExpression(const QString&);
|
||||
QString expression() const;
|
||||
void setName(const QString&);
|
||||
void setRefType(int);
|
||||
|
||||
static bool editFunction(QWidget *parent, MathFunction *f);
|
||||
static UserFunction* newFunction(QWidget *parent);
|
||||
static bool editFunction(QWidget *parent, MathFunction *f, MathFunction **replaced_item = NULL);
|
||||
static UserFunction* newFunction(QWidget *parent, MathFunction **replaced_item = NULL);
|
||||
|
||||
};
|
||||
|
||||
|
@ -136,14 +136,27 @@ void FunctionsDialog::searchChanged(const QString &str) {
|
||||
functionsView->selectionModel()->setCurrentIndex(functionsModel->index(0, 0), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
void FunctionsDialog::newClicked() {
|
||||
UserFunction *f = FunctionEditDialog::newFunction(this);
|
||||
MathFunction *replaced_item = NULL;
|
||||
UserFunction *f = FunctionEditDialog::newFunction(this, &replaced_item);
|
||||
if(f) {
|
||||
if(replaced_item && (replaced_item == f || !CALCULATOR->hasFunction(replaced_item))) {
|
||||
QModelIndexList list = sourceModel->match(sourceModel->index(0, 0), Qt::UserRole, QVariant::fromValue((void*) replaced_item), 1, Qt::MatchExactly);
|
||||
if(!list.isEmpty()) sourceModel->removeRow(list[0].row());
|
||||
}
|
||||
selected_item = f;
|
||||
QStandardItem *item = new QStandardItem(QString::fromStdString(f->title(true)));
|
||||
item->setEditable(false);
|
||||
item->setData(QVariant::fromValue((void*) f), Qt::UserRole);
|
||||
sourceModel->appendRow(item);
|
||||
functionsModel->invalidate();
|
||||
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + f->category()) {
|
||||
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
|
||||
if(!list.isEmpty()) {
|
||||
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
} else {
|
||||
functionsModel->invalidate();
|
||||
}
|
||||
sourceModel->sort(0);
|
||||
QModelIndex index = functionsModel->mapFromSource(item->index());
|
||||
if(index.isValid()) {
|
||||
functionsView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
@ -155,15 +168,28 @@ void FunctionsDialog::newClicked() {
|
||||
void FunctionsDialog::editClicked() {
|
||||
QModelIndex index = functionsView->selectionModel()->currentIndex();
|
||||
if(!index.isValid()) return;
|
||||
MathFunction *replaced_item = NULL;
|
||||
MathFunction *f = (MathFunction*) index.data(Qt::UserRole).value<void*>();
|
||||
if(f && FunctionEditDialog::editFunction(this, f)) {
|
||||
if(f && FunctionEditDialog::editFunction(this, f, &replaced_item)) {
|
||||
sourceModel->removeRow(functionsModel->mapToSource(functionsView->selectionModel()->currentIndex()).row());
|
||||
if(replaced_item && !CALCULATOR->hasFunction(replaced_item)) {
|
||||
QModelIndexList list = sourceModel->match(sourceModel->index(0, 0), Qt::UserRole, QVariant::fromValue((void*) replaced_item), 1, Qt::MatchExactly);
|
||||
if(!list.isEmpty()) sourceModel->removeRow(list[0].row());
|
||||
}
|
||||
QStandardItem *item = new QStandardItem(QString::fromStdString(f->title(true)));
|
||||
item->setEditable(false);
|
||||
item->setData(QVariant::fromValue((void*) f), Qt::UserRole);
|
||||
sourceModel->appendRow(item);
|
||||
selected_item = f;
|
||||
functionsModel->invalidate();
|
||||
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + f->category()) {
|
||||
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
|
||||
if(!list.isEmpty()) {
|
||||
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
} else {
|
||||
functionsModel->invalidate();
|
||||
}
|
||||
sourceModel->sort(0);
|
||||
QModelIndex index = functionsModel->mapFromSource(item->index());
|
||||
if(index.isValid()) {
|
||||
functionsView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
@ -563,7 +589,7 @@ void FunctionsDialog::setSearch(const QString &str) {
|
||||
searchChanged(str);
|
||||
}
|
||||
void FunctionsDialog::selectCategory(std::string str) {
|
||||
QList<QTreeWidgetItem*> list = categoriesView->findItems((str.empty() || str == "All") ? "All" : "/" + QString::fromStdString(str), Qt::MatchExactly, 1);
|
||||
QList<QTreeWidgetItem*> list = categoriesView->findItems((str.empty() || str == "All") ? "All" : "/" + QString::fromStdString(str), Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
|
||||
if(!list.isEmpty()) {
|
||||
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
|
92
src/itemproxymodel.cpp
Normal file
92
src/itemproxymodel.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
Qalculate (QT UI)
|
||||
|
||||
Copyright (C) 2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "itemproxymodel.h"
|
||||
|
||||
#include <libqalculate/qalculate.h>
|
||||
|
||||
ItemProxyModel::ItemProxyModel(QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
setSortLocaleAware(true);
|
||||
setDynamicSortFilter(false);
|
||||
}
|
||||
ItemProxyModel::~ItemProxyModel() {}
|
||||
|
||||
bool ItemProxyModel::filterAcceptsRow(int source_row, const QModelIndex&) const {
|
||||
QModelIndex index = sourceModel()->index(source_row, 0);
|
||||
if(!index.isValid()) return false;
|
||||
ExpressionItem *item = (ExpressionItem*) index.data(Qt::UserRole).value<void*>();
|
||||
if(cat.empty()) return false;
|
||||
if(cat == "All") {
|
||||
if(!item->isActive()) return false;
|
||||
} else if(cat == "Inactive") {
|
||||
if(item->isActive()) return false;
|
||||
} else if(cat == "Uncategorized") {
|
||||
if(!item->isActive() || !item->category().empty() || item->isLocal()) return false;
|
||||
} else if(cat == "User items") {
|
||||
if(!item->isActive() || !item->isLocal()) return false;
|
||||
} else {
|
||||
if(!item->isActive()) return false;
|
||||
if(!subcat.empty()) {
|
||||
size_t l1 = subcat.length(), l2;
|
||||
l2 = item->category().length();
|
||||
if((l2 != l1 && (l2 <= l1 || item->category()[l1] != '/')) || item->category().substr(0, l1) != subcat) return false;
|
||||
} else {
|
||||
if(item->category() != cat) return false;
|
||||
}
|
||||
}
|
||||
if(filter.empty()) return true;
|
||||
std::string title = item->title(true);
|
||||
remove_blank_ends(title);
|
||||
while(title.length() >= filter.length()) {
|
||||
if(equalsIgnoreCase(filter, title.substr(0, filter.length()))) {
|
||||
return true;
|
||||
}
|
||||
size_t i = title.find(' ');
|
||||
if(i == std::string::npos) break;
|
||||
title = title.substr(i + 1);
|
||||
remove_blank_ends(title);
|
||||
}
|
||||
for(size_t i2 = 1; i2 <= item->countNames(); i2++) {
|
||||
if(item->getName(i2).case_sensitive) {
|
||||
if(filter == item->getName(i2).name.substr(0, filter.length())) return true;
|
||||
} else {
|
||||
if(equalsIgnoreCase(filter, item->getName(i2).name.substr(0, filter.length()))) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void ItemProxyModel::setFilter(std::string scat, std::string sfilter) {
|
||||
remove_blank_ends(sfilter);
|
||||
if(cat != scat || filter != sfilter) {
|
||||
cat = scat;
|
||||
if(cat[0] == '/') subcat = cat.substr(1, cat.length() - 1);
|
||||
else subcat = "";
|
||||
filter = sfilter;
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
void ItemProxyModel::setSecondaryFilter(std::string sfilter) {
|
||||
remove_blank_ends(sfilter);
|
||||
if(filter != sfilter) {
|
||||
filter = sfilter;
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
std::string ItemProxyModel::currentFilter() const {
|
||||
return cat;
|
||||
}
|
||||
std::string ItemProxyModel::currentSecondaryFilter() const {
|
||||
return filter;
|
||||
}
|
||||
|
39
src/itemproxymodel.h
Normal file
39
src/itemproxymodel.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Qalculate (QT UI)
|
||||
|
||||
Copyright (C) 2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ITEM_PROXY_MODEL_H
|
||||
#define ITEM_PROXY_MODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class ItemProxyModel : public QSortFilterProxyModel {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
ItemProxyModel(QObject *parent = NULL);
|
||||
~ItemProxyModel();
|
||||
|
||||
void setFilter(std::string, std::string = "");
|
||||
void setSecondaryFilter(std::string);
|
||||
std::string currentFilter() const;
|
||||
std::string currentSecondaryFilter() const;
|
||||
|
||||
protected:
|
||||
|
||||
std::string cat, subcat, filter;
|
||||
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
|
||||
};
|
||||
|
||||
#endif //ITEM_PROXY_MODEL_H
|
@ -124,6 +124,8 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
settings->f_answer->setCategory(CALCULATOR->getFunctionById(FUNCTION_ID_WARNING)->category());
|
||||
|
||||
CALCULATOR->loadLocalDefinitions();
|
||||
|
||||
QalculateWindow *win = new QalculateWindow();
|
||||
|
@ -39,8 +39,15 @@ bool string_is_less(std::string str1, std::string str2) {
|
||||
if(b_uni) return QString::fromStdString(str1).compare(QString::fromStdString(str2)) < 0;
|
||||
return str1 < str2;
|
||||
}
|
||||
bool item_in_calculator(ExpressionItem *item) {
|
||||
if(!CALCULATOR->stillHasVariable((Variable*) item) || !CALCULATOR->stillHasFunction((MathFunction*) item) || !CALCULATOR->stillHasUnit((Unit*) item)) return false;
|
||||
if(item->type() == STRUCT_VARIABLE) return CALCULATOR->hasVariable((Variable*) item);
|
||||
if(item->type() == STRUCT_UNIT) return CALCULATOR->hasUnit((Unit*) item);
|
||||
if(item->type() == STRUCT_FUNCTION) return CALCULATOR->hasFunction((MathFunction*) item);
|
||||
return false;
|
||||
}
|
||||
|
||||
AnswerFunction::AnswerFunction() : MathFunction(QApplication::tr("answer").toStdString(), 1, 1, CALCULATOR->f_warning->category(), QApplication::tr("History Answer Value").toStdString()) {
|
||||
AnswerFunction::AnswerFunction() : MathFunction(QApplication::tr("answer").toStdString(), 1, 1, "", QApplication::tr("History Answer Value").toStdString()) {
|
||||
if(QApplication::tr("answer") != "answer") addName("answer");
|
||||
VectorArgument *arg = new VectorArgument(QApplication::tr("History Index(es)").toStdString());
|
||||
arg->addArgument(new IntegerArgument("", ARGUMENT_MIN_MAX_NONZERO, true, true, INTEGER_TYPE_SINT));
|
||||
@ -179,11 +186,12 @@ void QalculateQtSettings::loadPreferences() {
|
||||
dual_approximation = -1;
|
||||
auto_update_exchange_rates = 7;
|
||||
rpn_mode = false;
|
||||
rpn_keys = true;
|
||||
caret_as_xor = false;
|
||||
do_imaginary_j = false;
|
||||
color = 1;
|
||||
colorize_result = true;
|
||||
rpn_mode = false;
|
||||
chain_mode = false;
|
||||
enable_input_method = false;
|
||||
enable_completion = true;
|
||||
enable_completion2 = true;
|
||||
@ -235,8 +243,7 @@ void QalculateQtSettings::loadPreferences() {
|
||||
v = s2i(svalue);
|
||||
if(svar == "version") {
|
||||
parse_qalculate_version(svalue, version_numbers);
|
||||
/*} else if(svar == "allow_multiple_instances") {
|
||||
if(v == 0 && version_numbers[0] < 3) v = -1;
|
||||
} else if(svar == "allow_multiple_instances") {
|
||||
allow_multiple_instances = v;
|
||||
} else if(svar == "always_on_top") {
|
||||
always_on_top = v;
|
||||
@ -246,9 +253,9 @@ void QalculateQtSettings::loadPreferences() {
|
||||
save_mode_on_exit = v;
|
||||
} else if(svar == "save_definitions_on_exit") {
|
||||
save_defs_on_exit = v;
|
||||
} else if(svar == "clear_history_on_exit") {
|
||||
clear_history_on_exit = v;*/
|
||||
} else if(svar == "window_state") {
|
||||
}/* else if(svar == "clear_history_on_exit") {
|
||||
clear_history_on_exit = v;
|
||||
}*/ else if(svar == "window_state") {
|
||||
window_state = QByteArray::fromBase64(svalue.c_str());
|
||||
} else if(svar == "replace_expression") {
|
||||
replace_expression = v;
|
||||
@ -262,10 +269,6 @@ void QalculateQtSettings::loadPreferences() {
|
||||
functions_vsplitter_state = QByteArray::fromBase64(svalue.c_str());
|
||||
} else if(svar == "functions_hsplitter_state") {
|
||||
functions_hsplitter_state = QByteArray::fromBase64(svalue.c_str());
|
||||
} else if(svar == "keep_function_dialog_open") {
|
||||
keep_function_dialog_open = v;
|
||||
} else if(svar == "always_on_top") {
|
||||
always_on_top = v;
|
||||
} else if(svar == "style") {
|
||||
style = v;
|
||||
} else if(svar == "palette") {
|
||||
@ -490,16 +493,12 @@ void QalculateQtSettings::loadPreferences() {
|
||||
if(v >= INTERVAL_CALCULATION_NONE && v <= INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC) {
|
||||
evalops.interval_calculation = (IntervalCalculation) v;
|
||||
}
|
||||
/*} else if(svar == "chain_mode") {
|
||||
chain_mode = v;*/
|
||||
} else if(svar == "in_rpn_mode") {
|
||||
} else if(svar == "chain_mode") {
|
||||
chain_mode = v;
|
||||
} else if(svar == "rpn_mode") {
|
||||
rpn_mode = v;
|
||||
/*} else if(svar == "rpn_keys") {
|
||||
rpn_keys = v;*/
|
||||
} else if(svar == "rpn_syntax") {
|
||||
if(v) {
|
||||
evalops.parse_options.parsing_mode = PARSING_MODE_RPN;
|
||||
}
|
||||
} else if(svar == "rpn_keys") {
|
||||
rpn_keys = v;
|
||||
} else if(svar == "limit_implicit_multiplication") {
|
||||
evalops.parse_options.limit_implicit_multiplication = v;
|
||||
printops.limit_implicit_multiplication = v;
|
||||
@ -570,14 +569,14 @@ void QalculateQtSettings::loadPreferences() {
|
||||
updateMessagePrintOptions();
|
||||
|
||||
std::string ans_str = "ans";
|
||||
vans[0] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(CALCULATOR->temporaryCategory(), ans_str, m_undefined, QApplication::tr("Last Answer").toStdString(), false));
|
||||
vans[0] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(CALCULATOR->temporaryCategory(), ans_str, m_undefined, QApplication::tr("Last Answer").toStdString(), false, true));
|
||||
vans[0]->addName(QApplication::tr("answer").toStdString());
|
||||
vans[0]->addName(ans_str + "1");
|
||||
vans[1] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(CALCULATOR->temporaryCategory(), ans_str + "2", m_undefined, QApplication::tr("Answer 2").toStdString(), false));
|
||||
vans[2] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(CALCULATOR->temporaryCategory(), ans_str + "3", m_undefined, QApplication::tr("Answer 3").toStdString(), false));
|
||||
vans[3] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(CALCULATOR->temporaryCategory(), ans_str + "4", m_undefined, QApplication::tr("Answer 4").toStdString(), false));
|
||||
vans[4] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(CALCULATOR->temporaryCategory(), ans_str + "5", m_undefined, QApplication::tr("Answer 5").toStdString(), false));
|
||||
v_memory = new KnownVariable(CALCULATOR->temporaryCategory(), "", m_zero, QApplication::tr("Memory").toStdString(), true, true);
|
||||
vans[1] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(CALCULATOR->temporaryCategory(), ans_str + "2", m_undefined, QApplication::tr("Answer 2").toStdString(), false, true));
|
||||
vans[2] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(CALCULATOR->temporaryCategory(), ans_str + "3", m_undefined, QApplication::tr("Answer 3").toStdString(), false, true));
|
||||
vans[3] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(CALCULATOR->temporaryCategory(), ans_str + "4", m_undefined, QApplication::tr("Answer 4").toStdString(), false, true));
|
||||
vans[4] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(CALCULATOR->temporaryCategory(), ans_str + "5", m_undefined, QApplication::tr("Answer 5").toStdString(), false, true));
|
||||
v_memory = new KnownVariable(CALCULATOR->temporaryCategory(), "", m_zero, QApplication::tr("Memory").toStdString(), false, true);
|
||||
ExpressionName ename;
|
||||
ename.name = "MR";
|
||||
ename.case_sensitive = true;
|
||||
@ -656,6 +655,12 @@ void QalculateQtSettings::savePreferences(bool save_mode) {
|
||||
}
|
||||
fprintf(file, "\n[General]\n");
|
||||
fprintf(file, "version=%s\n", VERSION);
|
||||
fprintf(file, "ignore_locale=%i\n", ignore_locale);
|
||||
/*fprintf(file, "check_version=%i\n", check_version);
|
||||
if(check_version) {
|
||||
fprintf(file, "last_version_check=%s\n", last_version_check_date.toISOString().c_str());
|
||||
if(!last_found_version.empty()) fprintf(file, "last_found_version=%s\n", last_found_version.c_str());
|
||||
}*/
|
||||
fprintf(file, "window_state=%s\n", window_state.toBase64().data());
|
||||
fprintf(file, "window_geometry=%s\n", window_geometry.toBase64().data());
|
||||
fprintf(file, "splitter_state=%s\n", splitter_state.toBase64().data());
|
||||
@ -671,7 +676,9 @@ void QalculateQtSettings::savePreferences(bool save_mode) {
|
||||
if(!variables_hsplitter_state.isEmpty()) fprintf(file, "variables_hsplitter_state=%s\n", variables_hsplitter_state.toBase64().data());
|
||||
fprintf(file, "always_on_top=%i\n", always_on_top);
|
||||
if(title_type != TITLE_APP) fprintf(file, "window_title_mode=%i\n", title_type);
|
||||
fprintf(file, "ignore_locale=%i\n", ignore_locale);
|
||||
fprintf(file, "save_mode_on_exit=%i\n", save_mode_on_exit);
|
||||
fprintf(file, "save_definitions_on_exit=%i\n", save_defs_on_exit);
|
||||
//fprintf(file, "clear_history_on_exit=%i\n", clear_history_on_exit);
|
||||
fprintf(file, "enable_input_method=%i\n", enable_input_method);
|
||||
fprintf(file, "display_expression_status=%i\n", display_expression_status);
|
||||
fprintf(file, "enable_completion=%i\n", enable_completion);
|
||||
@ -695,6 +702,9 @@ void QalculateQtSettings::savePreferences(bool save_mode) {
|
||||
if(use_custom_keypad_font || save_custom_keypad_font) fprintf(file, "custom_keypad_font=%s\n", custom_keypad_font.c_str());
|
||||
if(use_custom_app_font || save_custom_app_font) fprintf(file, "custom_application_font=%s\n", custom_app_font.c_str());
|
||||
fprintf(file, "replace_expression=%i\n", replace_expression);
|
||||
fprintf(file, "rpn_keys=%i\n", rpn_keys);
|
||||
/*if(default_bits >= 0) fprintf(file, "bit_width=%i\n", default_bits);
|
||||
if(default_signed >= 0) fprintf(file, "signed_integer=%i\n", default_signed);*/
|
||||
fprintf(file, "spell_out_logical_operators=%i\n", printops.spell_out_logical_operators);
|
||||
fprintf(file, "caret_as_xor=%i\n", caret_as_xor);
|
||||
fprintf(file, "digit_grouping=%i\n", printops.digit_grouping);
|
||||
@ -703,8 +713,13 @@ void QalculateQtSettings::savePreferences(bool save_mode) {
|
||||
fprintf(file, "comma_as_separator=%i\n", evalops.parse_options.comma_as_separator);
|
||||
fprintf(file, "twos_complement=%i\n", printops.twos_complement);
|
||||
fprintf(file, "hexadecimal_twos_complement=%i\n", printops.hexadecimal_twos_complement);
|
||||
/*fprintf(file, "twos_complement_input=%i\n", twos_complement_in);
|
||||
fprintf(file, "hexadecimal_twos_complement_input=%i\n", hexadecimal_twos_complement_in);*/
|
||||
fprintf(file, "use_unicode_signs=%i\n", printops.use_unicode_signs);
|
||||
fprintf(file, "lower_case_numbers=%i\n", printops.lower_case_numbers);
|
||||
fprintf(file, "e_notation=%i\n", printops.lower_case_e);
|
||||
fprintf(file, "imaginary_j=%i\n", CALCULATOR->v_i->hasName("j") > 0);
|
||||
fprintf(file, "base_display=%i\n", printops.base_display);
|
||||
if(tc_set) fprintf(file, "temperature_calculation=%i\n", CALCULATOR->getTemperatureCalculationMode());
|
||||
fprintf(file, "auto_update_exchange_rates=%i\n", auto_update_exchange_rates);
|
||||
fprintf(file, "local_currency_conversion=%i\n", evalops.local_currency_conversion);
|
||||
@ -736,7 +751,6 @@ void QalculateQtSettings::savePreferences(bool save_mode) {
|
||||
fprintf(file, "place_units_separately=%i\n", printops.place_units_separately);
|
||||
fprintf(file, "auto_post_conversion=%i\n", evalops.auto_post_conversion);
|
||||
fprintf(file, "mixed_units_conversion=%i\n", evalops.mixed_units_conversion);
|
||||
fprintf(file, "local_currency_conversion=%i\n", evalops.local_currency_conversion);
|
||||
fprintf(file, "number_base=%i\n", printops.base);
|
||||
if(!CALCULATOR->customOutputBase().isZero()) fprintf(file, "custom_number_base=%s\n", CALCULATOR->customOutputBase().print(CALCULATOR->save_printoptions).c_str());
|
||||
fprintf(file, "number_base_expression=%i\n", evalops.parse_options.base);
|
||||
@ -763,6 +777,8 @@ void QalculateQtSettings::savePreferences(bool save_mode) {
|
||||
else if(dual_approximation > 0) fprintf(file, "approximation=%i\n", APPROXIMATION_APPROXIMATE + 1);
|
||||
else fprintf(file, "approximation=%i\n", evalops.approximation);
|
||||
fprintf(file, "interval_calculation=%i\n", evalops.interval_calculation);
|
||||
fprintf(file, "rpn_mode=%i\n", rpn_mode);
|
||||
fprintf(file, "chain_mode=%i\n", chain_mode);
|
||||
fprintf(file, "limit_implicit_multiplication=%i\n", evalops.parse_options.limit_implicit_multiplication);
|
||||
fprintf(file, "parsing_mode=%i\n", evalops.parse_options.parsing_mode);
|
||||
fprintf(file, "spacious=%i\n", printops.spacious);
|
||||
|
@ -32,6 +32,7 @@ std::string unhtmlize(std::string str);
|
||||
QIcon load_icon(const QString &str, QWidget*);
|
||||
bool last_is_operator(std::string str, bool allow_exp = false);
|
||||
bool string_is_less(std::string str1, std::string str2);
|
||||
bool item_in_calculator(ExpressionItem *item);
|
||||
|
||||
enum {
|
||||
TITLE_APP,
|
||||
@ -69,7 +70,7 @@ class QalculateQtSettings : QObject {
|
||||
|
||||
EvaluationOptions evalops;
|
||||
PrintOptions printops;
|
||||
bool complex_angle_form, dot_question_asked, adaptive_interval_display, tc_set, rpn_mode, caret_as_xor, ignore_locale, do_imaginary_j, fetch_exchange_rates_at_startup, always_on_top, display_expression_status, prefixes_default;
|
||||
bool complex_angle_form, dot_question_asked, adaptive_interval_display, tc_set, rpn_mode, chain_mode, caret_as_xor, ignore_locale, do_imaginary_j, fetch_exchange_rates_at_startup, always_on_top, display_expression_status, prefixes_default, rpn_keys, allow_multiple_instances;
|
||||
int decimal_comma, dual_fraction, dual_approximation, auto_update_exchange_rates, title_type;
|
||||
int completion_delay;
|
||||
int completion_min, completion_min2;
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "expressionedit.h"
|
||||
#include "historyview.h"
|
||||
#include "keypadwidget.h"
|
||||
#include "unknowneditdialog.h"
|
||||
#include "variableeditdialog.h"
|
||||
#include "functioneditdialog.h"
|
||||
#include "preferencesdialog.h"
|
||||
@ -55,6 +56,7 @@
|
||||
#include "variablesdialog.h"
|
||||
#include "unitsdialog.h"
|
||||
#include "fpconversiondialog.h"
|
||||
#include "calendarconversiondialog.h"
|
||||
|
||||
class ViewThread : public Thread {
|
||||
protected:
|
||||
@ -216,6 +218,7 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
|
||||
variablesDialog = NULL;
|
||||
unitsDialog = NULL;
|
||||
fpConversionDialog = NULL;
|
||||
calendarConversionDialog = NULL;
|
||||
|
||||
QVBoxLayout *topLayout = new QVBoxLayout(w_top);
|
||||
QHBoxLayout *hLayout = new QHBoxLayout();
|
||||
@ -237,16 +240,23 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
|
||||
menu2 = menu;
|
||||
menu = menu2->addMenu(tr("New"));
|
||||
menu->addAction(tr("Function"), this, SLOT(newFunction()));
|
||||
menu->addAction(tr("Variable"), this, SLOT(newVariable()));
|
||||
menu->addAction(tr("Variable/Constant"), this, SLOT(newVariable()));
|
||||
menu->addAction(tr("Unknown Variable"), this, SLOT(newUnknown()));
|
||||
menu = menu2;
|
||||
menu->addSeparator();
|
||||
menu->addAction(tr("Functions list"), this, SLOT(openFunctions()));
|
||||
menu->addAction(tr("Units list"), this, SLOT(openUnits()));
|
||||
menu->addAction(tr("Variables list"), this, SLOT(openVariables()));
|
||||
menu->addAction(tr("Functions List"), this, SLOT(openFunctions()), Qt::CTRL | Qt::Key_F);
|
||||
menu->addAction(tr("Variables and Constants List"), this, SLOT(openVariables()), Qt::CTRL | Qt::Key_M);
|
||||
menu->addAction(tr("Units List and Conversion"), this, SLOT(openUnits()), Qt::CTRL | Qt::Key_U);
|
||||
menu->addSeparator();
|
||||
menu->addAction(tr("Floating point conversion (IEEE 754)"), this, SLOT(openFPConversion()));
|
||||
menu->addAction(tr("Floating Point Conversion (IEEE 754)"), this, SLOT(openFPConversion()));
|
||||
menu->addAction(tr("Calendar Conversion"), this, SLOT(openCalendarConversion()));
|
||||
menu->addSeparator();
|
||||
menu->addAction(tr("Update exchange rates"), this, SLOT(fetchExchangeRates()));
|
||||
menu->addAction(tr("Update Exchange Rates"), this, SLOT(fetchExchangeRates()));
|
||||
menu->addSeparator();
|
||||
group = new QActionGroup(this); group->setExclusionPolicy(QActionGroup::ExclusionPolicy::Exclusive);
|
||||
action = menu->addAction(tr("Normal Mode"), this, SLOT(normalModeActivated())); action->setCheckable(true); group->addAction(action); action->setObjectName("action_normalmode"); if(!settings->rpn_mode && !settings->chain_mode) action->setChecked(true);
|
||||
action = menu->addAction(tr("RPN Mode"), this, SLOT(rpnModeActivated()), Qt::CTRL | Qt::Key_R); action->setCheckable(true); group->addAction(action); action->setObjectName("action_rpnmode"); if(settings->rpn_mode) action->setChecked(true);
|
||||
action = menu->addAction(tr("Chain Mode"), this, SLOT(chainModeActivated())); action->setCheckable(true); group->addAction(action); action->setObjectName("action_chainmode"); if(settings->chain_mode) action->setChecked(true);
|
||||
menu->addSeparator();
|
||||
menu->addAction(tr("Preferences"), this, SLOT(editPreferences()));
|
||||
menu->addSeparator();
|
||||
@ -459,7 +469,7 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
|
||||
toAction = new QAction(LOAD_ICON("convert"), tr("Convert"));
|
||||
connect(toAction, SIGNAL(triggered(bool)), this, SLOT(onToActivated()));
|
||||
tb->addAction(toAction);
|
||||
storeAction = new QAction(LOAD_ICON("document-save"), tr("Store"));
|
||||
storeAction = new QAction(LOAD_ICON("document-save"), tr("Store")); storeAction->setShortcut(QKeySequence::Save);
|
||||
connect(storeAction, SIGNAL(triggered(bool)), this, SLOT(onStoreActivated()));
|
||||
tb->addAction(storeAction);
|
||||
functionsAction = new QAction(LOAD_ICON("function"), tr("Functions"));
|
||||
@ -660,7 +670,7 @@ void QalculateWindow::onOperatorClicked(const QString &str) {
|
||||
if(expressionEdit->textCursor().hasSelection()) expressionEdit->wrapSelection(SIGN_MULTIPLICATION "10^");
|
||||
else expressionEdit->insertPlainText(settings->printops.lower_case_e ? "e" : str);
|
||||
} else {
|
||||
expressionEdit->wrapSelection(str);
|
||||
if(!expressionEdit->doChainMode(str)) expressionEdit->wrapSelection(str);
|
||||
}
|
||||
if(!expressionEdit->hasFocus()) expressionEdit->setFocus();
|
||||
if(do_exec) calculate();
|
||||
@ -679,11 +689,14 @@ void QalculateWindow::onFunctionClicked(MathFunction *f) {
|
||||
expressionEdit->blockParseStatus();
|
||||
QTextCursor cur = expressionEdit->textCursor();
|
||||
bool do_exec = false;
|
||||
if(cur.hasSelection()) {
|
||||
if(settings->chain_mode) {
|
||||
if(!expressionEdit->document()->isEmpty()) {
|
||||
expressionEdit->selectAll();
|
||||
do_exec = true;
|
||||
}
|
||||
} else if(cur.hasSelection()) {
|
||||
do_exec = cur.selectionStart() == 0 && cur.selectionEnd() == expressionEdit->toPlainText().length();
|
||||
} else if(last_is_number(expressionEdit->toPlainText().toStdString())) {
|
||||
expressionEdit->selectAll();
|
||||
do_exec = true;
|
||||
}
|
||||
expressionEdit->wrapSelection(f->referenceName() == "neg" ? SIGN_MINUS : QString::fromStdString(f->preferredInputName(settings->printops.abbreviate_names, settings->printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name), true, true);
|
||||
if(!expressionEdit->hasFocus()) expressionEdit->setFocus();
|
||||
@ -846,7 +859,7 @@ void QalculateWindow::socketReadyRead() {
|
||||
}
|
||||
}
|
||||
command = command.mid(1).trimmed();
|
||||
if(!command.isEmpty()) {expressionEdit->setPlainText(command); calculate();}
|
||||
if(!command.isEmpty()) {expressionEdit->setExpression(command); calculate();}
|
||||
}
|
||||
void QalculateWindow::onActivateRequested(const QStringList &arguments, const QString&) {
|
||||
if(!arguments.isEmpty()) {
|
||||
@ -858,7 +871,7 @@ void QalculateWindow::onActivateRequested(const QStringList &arguments, const QS
|
||||
command += args.at(i);
|
||||
}
|
||||
command = command.trimmed();
|
||||
if(!command.isEmpty()) {expressionEdit->setPlainText(command); calculate();}
|
||||
if(!command.isEmpty()) {expressionEdit->setExpression(command); calculate();}
|
||||
args.clear();
|
||||
}
|
||||
setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
|
||||
@ -872,7 +885,7 @@ void QalculateWindow::calculate() {
|
||||
calculateExpression();
|
||||
}
|
||||
void QalculateWindow::calculate(const QString &expression) {
|
||||
expressionEdit->setPlainText(expression);
|
||||
expressionEdit->setExpression(expression);
|
||||
calculate();
|
||||
}
|
||||
|
||||
@ -882,7 +895,7 @@ void QalculateWindow::setPreviousExpression() {
|
||||
} else {
|
||||
expressionEdit->blockCompletion();
|
||||
expressionEdit->blockParseStatus();
|
||||
expressionEdit->setPlainText(QString::fromStdString(previous_expression));
|
||||
expressionEdit->setExpression(QString::fromStdString(previous_expression));
|
||||
expressionEdit->selectAll();
|
||||
expressionEdit->setExpressionHasChanged(false);
|
||||
expressionEdit->blockCompletion(false);
|
||||
@ -1240,7 +1253,20 @@ void QalculateWindow::setOption(std::string str) {
|
||||
expressionFormatUpdated(false);
|
||||
}
|
||||
} else if(equalsIgnoreCase(svar, "rpn") && svalue.find(" ") == std::string::npos) {
|
||||
//SET_BOOL_MENU("menu_item_rpn_mode")
|
||||
bool b = settings->rpn_mode;
|
||||
SET_BOOL(b)
|
||||
if(b != settings->rpn_mode) {
|
||||
QAction *w = NULL;
|
||||
if(b) w = findChild<QAction*>("action_rpnmode");
|
||||
else w = findChild<QAction*>("action_normalmode");
|
||||
if(w) {
|
||||
w->blockSignals(true);
|
||||
w->setChecked(true);
|
||||
w->blockSignals(false);
|
||||
}
|
||||
if(b) rpnModeActivated();
|
||||
else normalModeActivated();
|
||||
}
|
||||
} else if(equalsIgnoreCase(svar, "short multiplication") || svar == "shortmul") SET_BOOL_D(settings->printops.short_multiplication)
|
||||
else if(equalsIgnoreCase(svar, "lowercase e") || svar == "lowe") SET_BOOL_D(settings->printops.lower_case_e)
|
||||
else if(equalsIgnoreCase(svar, "lowercase numbers") || svar == "lownum") SET_BOOL_D(settings->printops.lower_case_numbers)
|
||||
@ -1847,9 +1873,12 @@ void QalculateWindow::calculateExpression(bool force, bool do_mathoperation, Mat
|
||||
remove_blank_ends(str);
|
||||
if(equalsIgnoreCase(str, "mode")) {
|
||||
settings->savePreferences();
|
||||
if(current_expr) expressionEdit->clear();
|
||||
} else if(equalsIgnoreCase(str, "definitions")) {
|
||||
if(!CALCULATOR->saveDefinitions()) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Couldn't write definitions"), QMessageBox::Ok);
|
||||
} else {
|
||||
if(current_expr) expressionEdit->clear();
|
||||
}
|
||||
} else {
|
||||
std::string name = str, cat, title;
|
||||
@ -1920,6 +1949,8 @@ void QalculateWindow::calculateExpression(bool force, bool do_mathoperation, Mat
|
||||
}
|
||||
expressionEdit->updateCompletion();
|
||||
if(variablesDialog) variablesDialog->updateVariables();
|
||||
if(unitsDialog) unitsDialog->updateUnits();
|
||||
if(current_expr) expressionEdit->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1974,6 +2005,8 @@ void QalculateWindow::calculateExpression(bool force, bool do_mathoperation, Mat
|
||||
}
|
||||
expressionEdit->updateCompletion();
|
||||
if(variablesDialog) variablesDialog->updateVariables();
|
||||
if(unitsDialog) unitsDialog->updateUnits();
|
||||
if(current_expr) expressionEdit->clear();
|
||||
}
|
||||
} else if(equalsIgnoreCase(scom, "function")) {
|
||||
str = str.substr(ispace + 1, slen - (ispace + 1));
|
||||
@ -2030,6 +2063,7 @@ void QalculateWindow::calculateExpression(bool force, bool do_mathoperation, Mat
|
||||
}
|
||||
expressionEdit->updateCompletion();
|
||||
if(functionsDialog) functionsDialog->updateFunctions();
|
||||
if(current_expr) expressionEdit->clear();
|
||||
}
|
||||
} else if(equalsIgnoreCase(scom, "delete")) {
|
||||
str = str.substr(ispace + 1, slen - (ispace + 1));
|
||||
@ -2039,12 +2073,15 @@ void QalculateWindow::calculateExpression(bool force, bool do_mathoperation, Mat
|
||||
v->destroy();
|
||||
expressionEdit->updateCompletion();
|
||||
if(variablesDialog) variablesDialog->updateVariables();
|
||||
if(unitsDialog) unitsDialog->updateUnits();
|
||||
if(current_expr) expressionEdit->clear();
|
||||
} else {
|
||||
MathFunction *f = CALCULATOR->getActiveFunction(str);
|
||||
if(f && f->isLocal()) {
|
||||
f->destroy();
|
||||
expressionEdit->updateCompletion();
|
||||
if(functionsDialog) functionsDialog->updateFunctions();
|
||||
if(current_expr) expressionEdit->clear();
|
||||
} else {
|
||||
CALCULATOR->error(true, "No user-defined variable or function with the specified name (%s) exist.", str.c_str(), NULL);
|
||||
}
|
||||
@ -2264,12 +2301,16 @@ void QalculateWindow::calculateExpression(bool force, bool do_mathoperation, Mat
|
||||
variablesDialog->selectCategory("All");
|
||||
variablesDialog->setSearch(QString::fromStdString(str));
|
||||
}
|
||||
if(current_expr) expressionEdit->clear();
|
||||
} else {
|
||||
CALCULATOR->error(true, "No function, variable, or unit with the specified name (%s) was found.", str.c_str(), NULL);
|
||||
}
|
||||
} else {
|
||||
if(current_expr) expressionEdit->clear();
|
||||
}
|
||||
} else if(equalsIgnoreCase(str, "quit") || equalsIgnoreCase(str, "exit")) {
|
||||
qApp->closeAllWindows();
|
||||
return;
|
||||
} else {
|
||||
CALCULATOR->error(true, "Unknown command: %s.", str.c_str(), NULL);
|
||||
}
|
||||
@ -2473,7 +2514,7 @@ void QalculateWindow::calculateExpression(bool force, bool do_mathoperation, Mat
|
||||
if(from_str.empty()) {
|
||||
b_busy--;
|
||||
if(current_expr) setPreviousExpression();
|
||||
//on_popup_menu_item_calendarconversion_activate(NULL, NULL);
|
||||
openCalendarConversion();
|
||||
return;
|
||||
}
|
||||
do_calendars = true;
|
||||
@ -2986,7 +3027,7 @@ void QalculateWindow::calculateExpression(bool force, bool do_mathoperation, Mat
|
||||
setResult(NULL, true, stack_index == 0, true, "", stack_index);
|
||||
|
||||
if(do_bases) basesDock->show();
|
||||
//if(do_calendars) on_popup_menu_item_calendarconversion_activate(NULL, NULL);
|
||||
if(do_calendars) openCalendarConversion();
|
||||
|
||||
settings->evalops.complex_number_form = cnf_bak;
|
||||
settings->evalops.auto_post_conversion = save_auto_post_conversion;
|
||||
@ -3004,19 +3045,22 @@ void QalculateWindow::calculateExpression(bool force, bool do_mathoperation, Mat
|
||||
}
|
||||
expressionEdit->blockCompletion();
|
||||
expressionEdit->blockParseStatus();
|
||||
if(settings->replace_expression == CLEAR_EXPRESSION) {
|
||||
if(settings->chain_mode) {
|
||||
if(exact_text == "0" || result_text == "0") expressionEdit->clear();
|
||||
expressionEdit->setExpression(QString::fromStdString(unhtmlize(result_text)));
|
||||
} else if(settings->replace_expression == CLEAR_EXPRESSION) {
|
||||
expressionEdit->clear();
|
||||
} else if(settings->replace_expression == REPLACE_EXPRESSION_WITH_RESULT || settings->replace_expression == REPLACE_EXPRESSION_WITH_RESULT_IF_SHORTER) {
|
||||
if(settings->replace_expression == REPLACE_EXPRESSION_WITH_RESULT || (!exact_text.empty() && unicode_length(exact_text) < unicode_length(from_str))) {
|
||||
if(exact_text == "0") expressionEdit->clear();
|
||||
else if(exact_text.empty()) expressionEdit->setPlainText(QString::fromStdString(unhtmlize(result_text)));
|
||||
else expressionEdit->setPlainText(QString::fromStdString(exact_text));
|
||||
if(exact_text == "0" || result_text == "0") expressionEdit->clear();
|
||||
else if(exact_text.empty()) expressionEdit->setExpression(QString::fromStdString(unhtmlize(result_text)));
|
||||
else expressionEdit->setExpression(QString::fromStdString(exact_text));
|
||||
} else {
|
||||
if(!execute_str.empty()) {
|
||||
from_str = execute_str;
|
||||
CALCULATOR->separateToExpression(from_str, str, settings->evalops, true, true);
|
||||
}
|
||||
expressionEdit->setPlainText(QString::fromStdString(from_str));
|
||||
expressionEdit->setExpression(QString::fromStdString(from_str));
|
||||
}
|
||||
}
|
||||
if(!expressionEdit->hasFocus()) expressionEdit->setFocus();
|
||||
@ -3025,6 +3069,14 @@ void QalculateWindow::calculateExpression(bool force, bool do_mathoperation, Mat
|
||||
expressionEdit->blockParseStatus(false);
|
||||
expressionEdit->setExpressionHasChanged(false);
|
||||
}
|
||||
|
||||
if(CALCULATOR->checkSaveFunctionCalled()) {
|
||||
expressionEdit->updateCompletion();
|
||||
if(variablesDialog) variablesDialog->updateVariables();
|
||||
if(unitsDialog) unitsDialog->updateUnits();
|
||||
if(functionsDialog) functionsDialog->updateFunctions();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CommandThread::run() {
|
||||
@ -3907,6 +3959,7 @@ void QalculateWindow::onStoreActivated() {
|
||||
if(v) {
|
||||
expressionEdit->updateCompletion();
|
||||
if(variablesDialog) variablesDialog->updateVariables();
|
||||
if(unitsDialog) unitsDialog->updateUnits();
|
||||
}
|
||||
}
|
||||
void QalculateWindow::newVariable() {
|
||||
@ -3914,6 +3967,15 @@ void QalculateWindow::newVariable() {
|
||||
if(v) {
|
||||
expressionEdit->updateCompletion();
|
||||
if(variablesDialog) variablesDialog->updateVariables();
|
||||
if(unitsDialog) unitsDialog->updateUnits();
|
||||
}
|
||||
}
|
||||
void QalculateWindow::newUnknown() {
|
||||
UnknownVariable *v = UnknownEditDialog::newVariable(this);
|
||||
if(v) {
|
||||
expressionEdit->updateCompletion();
|
||||
if(variablesDialog) variablesDialog->updateVariables();
|
||||
if(unitsDialog) unitsDialog->updateUnits();
|
||||
}
|
||||
}
|
||||
void QalculateWindow::newFunction() {
|
||||
@ -4113,8 +4175,23 @@ void QalculateWindow::assumptionsSignActivated() {
|
||||
expressionCalculationUpdated();
|
||||
}
|
||||
void QalculateWindow::onAlwaysOnTopChanged() {
|
||||
if(settings->always_on_top) setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
else setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
||||
if(settings->always_on_top) {
|
||||
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
if(functionsDialog) functionsDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
if(variablesDialog) variablesDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
if(unitsDialog) unitsDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
if(fpConversionDialog) fpConversionDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
if(calendarConversionDialog) calendarConversionDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
if(preferencesDialog) preferencesDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
} else {
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
||||
if(functionsDialog) functionsDialog->setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
||||
if(variablesDialog) variablesDialog->setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
||||
if(unitsDialog) unitsDialog->setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
||||
if(fpConversionDialog) fpConversionDialog->setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
||||
if(calendarConversionDialog) calendarConversionDialog->setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
||||
if(preferencesDialog) preferencesDialog->setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
||||
}
|
||||
show();
|
||||
}
|
||||
void QalculateWindow::onTitleTypeChanged() {
|
||||
@ -4193,10 +4270,7 @@ void QalculateWindow::applyFunction(MathFunction *f) {
|
||||
str += ")";
|
||||
}
|
||||
expressionEdit->blockParseStatus();
|
||||
expressionEdit->blockUndo();
|
||||
expressionEdit->clear();
|
||||
expressionEdit->blockUndo(false);
|
||||
expressionEdit->setPlainText(str);
|
||||
expressionEdit->setExpression(str);
|
||||
expressionEdit->blockParseStatus(false);
|
||||
calculate();
|
||||
}
|
||||
@ -4213,8 +4287,13 @@ void QalculateWindow::openFunctions() {
|
||||
connect(functionsDialog, SIGNAL(applyFunctionRequest(MathFunction*)), this, SLOT(applyFunction(MathFunction*)));
|
||||
connect(functionsDialog, SIGNAL(insertFunctionRequest(MathFunction*)), this, SLOT(onInsertFunctionRequested(MathFunction*)));
|
||||
connect(functionsDialog, SIGNAL(calculateFunctionRequest(MathFunction*)), this, SLOT(onCalculateFunctionRequested(MathFunction*)));
|
||||
if(settings->always_on_top) functionsDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
functionsDialog->show();
|
||||
}
|
||||
void QalculateWindow::onUnitRemoved(Unit *u) {
|
||||
if(unitsDialog) unitsDialog->unitRemoved(u);
|
||||
expressionEdit->updateCompletion();
|
||||
}
|
||||
void QalculateWindow::openVariables() {
|
||||
if(variablesDialog) {
|
||||
variablesDialog->setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
|
||||
@ -4225,9 +4304,15 @@ void QalculateWindow::openVariables() {
|
||||
}
|
||||
variablesDialog = new VariablesDialog();
|
||||
connect(variablesDialog, SIGNAL(itemsChanged()), expressionEdit, SLOT(updateCompletion()));
|
||||
connect(variablesDialog, SIGNAL(unitRemoved(Unit*)), this, SLOT(onUnitRemoved(Unit*)));
|
||||
connect(variablesDialog, SIGNAL(insertVariableRequest(Variable*)), this, SLOT(onVariableClicked(Variable*)));
|
||||
if(settings->always_on_top) variablesDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
variablesDialog->show();
|
||||
}
|
||||
void QalculateWindow::onVariableRemoved(Variable *v) {
|
||||
if(variablesDialog) variablesDialog->variableRemoved(v);
|
||||
expressionEdit->updateCompletion();
|
||||
}
|
||||
void QalculateWindow::openUnits() {
|
||||
Unit *u = NULL;
|
||||
if(!expressionEdit->expressionHasChanged() && !settings->history_answer.empty()) {
|
||||
@ -4245,9 +4330,11 @@ void QalculateWindow::openUnits() {
|
||||
unitsDialog = new UnitsDialog();
|
||||
if(u && !u->category().empty()) unitsDialog->selectCategory(u->category());
|
||||
connect(unitsDialog, SIGNAL(itemsChanged()), expressionEdit, SLOT(updateCompletion()));
|
||||
connect(unitsDialog, SIGNAL(variableRemoved(Variable*)), this, SLOT(onVariableRemoved(Variable*)));
|
||||
connect(unitsDialog, SIGNAL(insertUnitRequest(Unit*)), this, SLOT(onUnitClicked(Unit*)));
|
||||
connect(unitsDialog, SIGNAL(convertToUnitRequest(Unit*)), this, SLOT(convertToUnit(Unit*)));
|
||||
connect(unitsDialog, SIGNAL(unitActivated(Unit*)), this, SLOT(onUnitActivated(Unit*)));
|
||||
if(settings->always_on_top) unitsDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
unitsDialog->show();
|
||||
}
|
||||
void QalculateWindow::onUnitActivated(Unit *u) {
|
||||
@ -4291,6 +4378,24 @@ void QalculateWindow::openFPConversion() {
|
||||
}
|
||||
fpConversionDialog->show();
|
||||
}
|
||||
void QalculateWindow::openCalendarConversion() {
|
||||
if(calendarConversionDialog) {
|
||||
if(settings->always_on_top) calendarConversionDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
if(mstruct && mstruct->isDateTime()) calendarConversionDialog->setDate(*mstruct->datetime());
|
||||
calendarConversionDialog->setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
|
||||
calendarConversionDialog->show();
|
||||
calendarConversionDialog->raise();
|
||||
calendarConversionDialog->activateWindow();
|
||||
return;
|
||||
}
|
||||
calendarConversionDialog = new CalendarConversionDialog(this);
|
||||
if(settings->always_on_top) calendarConversionDialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
QalculateDateTime dt;
|
||||
if(mstruct && mstruct->isDateTime()) dt.set(*mstruct->datetime());
|
||||
else dt.setToCurrentDate();
|
||||
calendarConversionDialog->setDate(dt);
|
||||
calendarConversionDialog->show();
|
||||
}
|
||||
|
||||
struct FunctionDialog {
|
||||
MathFunction *f;
|
||||
@ -5008,5 +5113,16 @@ void QalculateWindow::executeFromFile(const QString &file) {
|
||||
void QalculateWindow::convertToUnit(Unit *u) {
|
||||
executeCommand(COMMAND_CONVERT_UNIT, true, "", u);
|
||||
}
|
||||
|
||||
void QalculateWindow::normalModeActivated() {
|
||||
settings->rpn_mode = false;
|
||||
settings->chain_mode = false;
|
||||
}
|
||||
void QalculateWindow::rpnModeActivated() {
|
||||
settings->rpn_mode = true;
|
||||
settings->chain_mode = false;
|
||||
}
|
||||
void QalculateWindow::chainModeActivated() {
|
||||
settings->rpn_mode = false;
|
||||
settings->chain_mode = true;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ class FunctionsDialog;
|
||||
class VariablesDialog;
|
||||
class UnitsDialog;
|
||||
class FPConversionDialog;
|
||||
class CalendarConversionDialog;
|
||||
struct FunctionDialog;
|
||||
|
||||
class QalculateWindow : public QMainWindow {
|
||||
@ -68,6 +69,7 @@ class QalculateWindow : public QMainWindow {
|
||||
VariablesDialog *variablesDialog;
|
||||
UnitsDialog *unitsDialog;
|
||||
FPConversionDialog *fpConversionDialog;
|
||||
CalendarConversionDialog *calendarConversionDialog;
|
||||
|
||||
KeypadWidget *keypad;
|
||||
QDockWidget *keypadDock, *basesDock;
|
||||
@ -157,6 +159,7 @@ class QalculateWindow : public QMainWindow {
|
||||
void approximationActivated();
|
||||
void applyFunction(MathFunction*);
|
||||
void openFPConversion();
|
||||
void openCalendarConversion();
|
||||
void onInsertFunctionExec();
|
||||
void onInsertFunctionRPN();
|
||||
void onInsertFunctionInsert();
|
||||
@ -169,7 +172,11 @@ class QalculateWindow : public QMainWindow {
|
||||
void onCalculateFunctionRequested(MathFunction*);
|
||||
void onInsertFunctionRequested(MathFunction*);
|
||||
void onUnitActivated(Unit *u);
|
||||
|
||||
void onUnitRemoved(Unit*);
|
||||
void onVariableRemoved(Variable*);
|
||||
void normalModeActivated();
|
||||
void rpnModeActivated();
|
||||
void chainModeActivated();
|
||||
|
||||
public slots:
|
||||
|
||||
@ -188,6 +195,7 @@ class QalculateWindow : public QMainWindow {
|
||||
void expressionFormatUpdated(bool);
|
||||
void insertFunction(MathFunction*, QWidget* = NULL);
|
||||
void newVariable();
|
||||
void newUnknown();
|
||||
void newFunction();
|
||||
void convertToUnit(Unit*);
|
||||
|
||||
|
660
src/unitsdialog.cpp
Normal file
660
src/unitsdialog.cpp
Normal file
@ -0,0 +1,660 @@
|
||||
/*
|
||||
Qalculate (QT UI)
|
||||
|
||||
Copyright (C) 2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QSplitter>
|
||||
#include <QTextEdit>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTreeView>
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QPushButton>
|
||||
#include <QLineEdit>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
#include <QDebug>
|
||||
|
||||
#include "qalculateqtsettings.h"
|
||||
#include "unitsdialog.h"
|
||||
#include "itemproxymodel.h"
|
||||
//#include "uniteditdialog.h"
|
||||
|
||||
UnitsDialog::UnitsDialog(QWidget *parent) : QDialog(parent) {
|
||||
last_from = true;
|
||||
QVBoxLayout *topbox = new QVBoxLayout(this);
|
||||
setWindowTitle(tr("Units"));
|
||||
QHBoxLayout *hbox = new QHBoxLayout();
|
||||
topbox->addLayout(hbox);
|
||||
vsplitter = new QSplitter(Qt::Vertical, this);
|
||||
hbox->addWidget(vsplitter, 1);
|
||||
hsplitter = new QSplitter(Qt::Horizontal, this);
|
||||
categoriesView = new QTreeWidget(this);
|
||||
categoriesView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
categoriesView->setRootIsDecorated(false);
|
||||
categoriesView->headerItem()->setText(0, tr("Category"));
|
||||
categoriesView->setColumnCount(2);
|
||||
categoriesView->setColumnHidden(1, true);
|
||||
hsplitter->addWidget(categoriesView);
|
||||
QWidget *w = new QWidget(this);
|
||||
QVBoxLayout *vbox = new QVBoxLayout(w);
|
||||
vbox->setSpacing(0);
|
||||
vbox->setContentsMargins(0, 0, 0, 0);
|
||||
unitsView = new QTreeView(this);
|
||||
unitsView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
unitsView->setRootIsDecorated(false);
|
||||
unitsModel = new ItemProxyModel(this);
|
||||
sourceModel = new QStandardItemModel(this);
|
||||
unitsModel->setSourceModel(sourceModel);
|
||||
sourceModel->setColumnCount(1);
|
||||
sourceModel->setHorizontalHeaderItem(0, new QStandardItem(tr("Unit")));
|
||||
unitsView->setModel(unitsModel);
|
||||
selected_item = NULL;
|
||||
vbox->addWidget(unitsView, 1);
|
||||
searchEdit = new QLineEdit(this);
|
||||
searchEdit->addAction(LOAD_ICON("edit-find"), QLineEdit::LeadingPosition);
|
||||
vbox->addWidget(searchEdit, 0);
|
||||
hsplitter->addWidget(w);
|
||||
vsplitter->addWidget(hsplitter);
|
||||
descriptionView = new QTextEdit(this);
|
||||
descriptionView->setReadOnly(true);
|
||||
vsplitter->addWidget(descriptionView);
|
||||
vsplitter->setStretchFactor(0, 3);
|
||||
vsplitter->setStretchFactor(1, 1);
|
||||
hsplitter->setStretchFactor(0, 2);
|
||||
hsplitter->setStretchFactor(1, 3);
|
||||
QVBoxLayout *box = new QVBoxLayout();
|
||||
newButton = new QPushButton(tr("New"), this); box->addWidget(newButton); connect(newButton, SIGNAL(clicked()), this, SLOT(newClicked()));
|
||||
newButton->setEnabled(false);
|
||||
editButton = new QPushButton(tr("Edit"), this); box->addWidget(editButton); connect(editButton, SIGNAL(clicked()), this, SLOT(editClicked()));
|
||||
delButton = new QPushButton(tr("Delete"), this); box->addWidget(delButton); connect(delButton, SIGNAL(clicked()), this, SLOT(delClicked()));
|
||||
deactivateButton = new QPushButton(tr("Deactivate"), this); box->addWidget(deactivateButton); connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateClicked()));
|
||||
box->addSpacing(24);
|
||||
convertButton = new QPushButton(tr("Convert"), this); box->addWidget(convertButton); connect(convertButton, SIGNAL(clicked()), this, SLOT(convertClicked()));
|
||||
insertButton = new QPushButton(tr("Insert"), this); box->addWidget(insertButton); connect(insertButton, SIGNAL(clicked()), this, SLOT(insertClicked()));
|
||||
insertButton->setDefault(true);
|
||||
box->addStretch(1);
|
||||
hbox->addLayout(box, 0);
|
||||
QGridLayout *grid = new QGridLayout();
|
||||
equalsLabel = new QLabel("=", this);
|
||||
equalsLabel->setAlignment(Qt::AlignRight);
|
||||
QFontMetrics fm(equalsLabel->font());
|
||||
equalsLabel->setMinimumWidth(fm.boundingRect(SIGN_ALMOST_EQUAL).width());
|
||||
equalsLabel->setMinimumHeight(fm.boundingRect(SIGN_ALMOST_EQUAL).height());
|
||||
grid->addWidget(equalsLabel, 1, 0);
|
||||
fromEdit = new MathLineEdit(this);
|
||||
fromEdit->setText("1");
|
||||
fromEdit->setAlignment(Qt::AlignRight);
|
||||
grid->addWidget(fromEdit, 0, 1);
|
||||
toEdit = new MathLineEdit(this);
|
||||
toEdit->setText("1");
|
||||
toEdit->setAlignment(Qt::AlignRight);
|
||||
grid->addWidget(toEdit, 1, 1);
|
||||
fromLabel = new QLabel(this);
|
||||
grid->addWidget(fromLabel, 0, 2);
|
||||
toCombo = new QComboBox(this);
|
||||
toModel = new ItemProxyModel(this);
|
||||
toSourceModel = new QStandardItemModel(this);
|
||||
toSourceModel->setColumnCount(1);
|
||||
toModel->setSourceModel(toSourceModel);
|
||||
toCombo->setModel(toModel);
|
||||
grid->addWidget(toCombo, 1, 2);
|
||||
topbox->addLayout(grid);
|
||||
topbox->addSpacing(topbox->spacing() * 2);
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this);
|
||||
topbox->addWidget(buttonBox);
|
||||
selected_category = "All";
|
||||
updateUnits();
|
||||
unitsModel->setFilter("All");
|
||||
toModel->setFilter("All");
|
||||
connect(searchEdit, SIGNAL(textEdited(const QString&)), this, SLOT(searchChanged(const QString&)));
|
||||
connect(fromEdit, SIGNAL(textEdited(const QString&)), this, SLOT(fromChanged()));
|
||||
connect(toEdit, SIGNAL(textEdited(const QString&)), this, SLOT(toChanged()));
|
||||
connect(toCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(toUnitChanged()));
|
||||
connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(categoriesView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(selectedCategoryChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
|
||||
connect(unitsView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(selectedUnitChanged(const QModelIndex&, const QModelIndex&)));
|
||||
connect(unitsView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(onUnitActivated(const QModelIndex&)));
|
||||
selectedUnitChanged(QModelIndex(), QModelIndex());
|
||||
if(!settings->units_geometry.isEmpty()) restoreGeometry(settings->units_geometry);
|
||||
else resize(900, 800);
|
||||
if(!settings->units_vsplitter_state.isEmpty()) vsplitter->restoreState(settings->units_vsplitter_state);
|
||||
if(!settings->units_hsplitter_state.isEmpty()) hsplitter->restoreState(settings->units_hsplitter_state);
|
||||
}
|
||||
UnitsDialog::~UnitsDialog() {}
|
||||
|
||||
void UnitsDialog::convert(bool from) {
|
||||
QModelIndex index = unitsView->selectionModel()->currentIndex();
|
||||
if(!index.isValid() || toCombo->currentIndex() < 0) {toEdit->clear(); return;}
|
||||
last_from = from;
|
||||
Unit *from_u, *to_u;
|
||||
std::string str;
|
||||
if(from) {
|
||||
str = fromEdit->text().trimmed().toStdString();
|
||||
if(str == CALCULATOR->timedOutString()) return;
|
||||
from_u = (Unit*) index.data(Qt::UserRole).value<void*>();
|
||||
to_u = (Unit*) toCombo->currentData(Qt::UserRole).value<void*>();
|
||||
if(from_u == to_u || str.empty()) {toEdit->setText(fromEdit->text().trimmed()); return;}
|
||||
} else {
|
||||
str = toEdit->text().trimmed().toStdString();
|
||||
if(str == CALCULATOR->timedOutString()) return;
|
||||
to_u = (Unit*) index.data(Qt::UserRole).value<void*>();
|
||||
from_u = (Unit*) toCombo->currentData(Qt::UserRole).value<void*>();
|
||||
if(from_u == to_u || str.empty()) {fromEdit->setText(toEdit->text().trimmed()); return;}
|
||||
}
|
||||
bool b = false;
|
||||
EvaluationOptions eo;
|
||||
eo.approximation = APPROXIMATION_APPROXIMATE;
|
||||
eo.parse_options = settings->evalops.parse_options;
|
||||
eo.parse_options.base = 10;
|
||||
if(eo.parse_options.parsing_mode == PARSING_MODE_RPN || eo.parse_options.parsing_mode == PARSING_MODE_CHAIN) eo.parse_options.parsing_mode = PARSING_MODE_ADAPTIVE;
|
||||
eo.parse_options.read_precision = DONT_READ_PRECISION;
|
||||
PrintOptions po;
|
||||
po.is_approximate = &b;
|
||||
po.number_fraction_format = FRACTION_DECIMAL;
|
||||
po.interval_display = INTERVAL_DISPLAY_SIGNIFICANT_DIGITS;
|
||||
CALCULATOR->resetExchangeRatesUsed();
|
||||
CALCULATOR->beginTemporaryStopMessages();
|
||||
MathStructure v_mstruct = CALCULATOR->convert(CALCULATOR->unlocalizeExpression(str, eo.parse_options), from_u, to_u, 1500, eo);
|
||||
if(!v_mstruct.isAborted() && settings->checkExchangeRates(this)) v_mstruct = CALCULATOR->convert(CALCULATOR->unlocalizeExpression(str, eo.parse_options), from_u, to_u, 1500, eo);
|
||||
if(v_mstruct.isAborted()) {
|
||||
str = CALCULATOR->timedOutString();
|
||||
} else {
|
||||
str = CALCULATOR->print(v_mstruct, 300, po);
|
||||
}
|
||||
if(from) toEdit->setText(QString::fromStdString(str));
|
||||
else fromEdit->setText(QString::fromStdString(str));
|
||||
b = b || v_mstruct.isApproximate();
|
||||
if(b) equalsLabel->setText(SIGN_ALMOST_EQUAL);
|
||||
else equalsLabel->setText("=");
|
||||
CALCULATOR->endTemporaryStopMessages();
|
||||
}
|
||||
void UnitsDialog::fromChanged() {
|
||||
convert(true);
|
||||
}
|
||||
void UnitsDialog::toChanged() {
|
||||
convert(false);
|
||||
}
|
||||
void UnitsDialog::toUnitChanged() {
|
||||
convert(last_from);
|
||||
}
|
||||
void UnitsDialog::fromUnitChanged() {
|
||||
convert(last_from);
|
||||
}
|
||||
void UnitsDialog::keyPressEvent(QKeyEvent *event) {
|
||||
if(event->matches(QKeySequence::Find)) {
|
||||
searchEdit->setFocus();
|
||||
return;
|
||||
}
|
||||
if(event->key() == Qt::Key_Escape && searchEdit->hasFocus()) {
|
||||
searchEdit->clear();
|
||||
unitsView->setFocus();
|
||||
return;
|
||||
}
|
||||
if(event->key() == Qt::Key_Escape && (fromEdit->hasFocus() || toEdit->hasFocus())) {
|
||||
fromEdit->clear();
|
||||
toEdit->clear();
|
||||
return;
|
||||
}
|
||||
if(event->key() == Qt::Key_Return && unitsView->hasFocus()) {
|
||||
QModelIndex index = unitsView->selectionModel()->currentIndex();
|
||||
if(index.isValid()) {
|
||||
onUnitActivated(index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
QDialog::keyPressEvent(event);
|
||||
}
|
||||
void UnitsDialog::onUnitActivated(const QModelIndex &index) {
|
||||
if(!index.isValid()) return;
|
||||
Unit *u = (Unit*) index.data(Qt::UserRole).value<void*>();
|
||||
if(u) emit unitActivated(u);
|
||||
}
|
||||
void UnitsDialog::closeEvent(QCloseEvent *e) {
|
||||
settings->units_geometry = saveGeometry();
|
||||
settings->units_vsplitter_state = vsplitter->saveState();
|
||||
settings->units_hsplitter_state = hsplitter->saveState();
|
||||
QDialog::closeEvent(e);
|
||||
}
|
||||
void UnitsDialog::reject() {
|
||||
settings->units_geometry = saveGeometry();
|
||||
settings->units_vsplitter_state = vsplitter->saveState();
|
||||
settings->units_hsplitter_state = hsplitter->saveState();
|
||||
QDialog::reject();
|
||||
}
|
||||
void UnitsDialog::searchChanged(const QString &str) {
|
||||
unitsModel->setSecondaryFilter(str.toStdString());
|
||||
unitsView->selectionModel()->setCurrentIndex(unitsModel->index(0, 0), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
void UnitsDialog::newClicked() {
|
||||
/*Unit *u = UnitEditDialog::newUnit(this);
|
||||
if(u) {
|
||||
selected_item = u;
|
||||
QStandardItem *item = new QStandardItem(QString::fromStdString(f->title(true)));
|
||||
item->setEditable(false);
|
||||
item->setData(QVariant::fromValue((void*) u), Qt::UserRole);
|
||||
sourceModel->appendRow(item);
|
||||
unitsModel->invalidate();
|
||||
QModelIndex index = unitsModel->mapFromSource(item->index());
|
||||
if(index.isValid()) {
|
||||
unitsView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
unitsView->scrollTo(index);
|
||||
}
|
||||
emit itemsChanged();
|
||||
}*/
|
||||
}
|
||||
void UnitsDialog::unitRemoved(Unit *u) {
|
||||
QModelIndexList list = sourceModel->match(sourceModel->index(0, 0), Qt::UserRole, QVariant::fromValue((void*) u), 1, Qt::MatchExactly);
|
||||
if(!list.isEmpty()) sourceModel->removeRow(list[0].row());
|
||||
}
|
||||
void UnitsDialog::editClicked() {
|
||||
/*QModelIndex index = unitsView->selectionModel()->currentIndex();
|
||||
if(!index.isValid()) return;
|
||||
Unit *u = (Unit*) index.data(Qt::UserRole).value<void*>();
|
||||
if(u && UnitEditDialog::editUnit(this, u)) {
|
||||
sourceModel->removeRow(unitsModel->mapToSource(unitsView->selectionModel()->currentIndex()).row());
|
||||
QStandardItem *item = new QStandardItem(QString::fromStdString(f->title(true)));
|
||||
item->setEditable(false);
|
||||
item->setData(QVariant::fromValue((void*) u), Qt::UserRole);
|
||||
sourceModel->appendRow(item);
|
||||
selected_item = u;
|
||||
unitsModel->invalidate();
|
||||
QModelIndex index = unitsModel->mapFromSource(item->index());
|
||||
if(index.isValid()) {
|
||||
unitsView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
unitsView->scrollTo(index);
|
||||
}
|
||||
emit itemsChanged();
|
||||
}*/
|
||||
}
|
||||
void UnitsDialog::delClicked() {
|
||||
QModelIndex index = unitsView->selectionModel()->currentIndex();
|
||||
if(!index.isValid()) return;
|
||||
Unit *u = (Unit*) index.data(Qt::UserRole).value<void*>();
|
||||
if(u && u->isLocal()) {
|
||||
sourceModel->removeRow(unitsModel->mapToSource(unitsView->selectionModel()->currentIndex()).row());
|
||||
selected_item = NULL;
|
||||
u->destroy();
|
||||
emit itemsChanged();
|
||||
}
|
||||
}
|
||||
void UnitsDialog::convertClicked() {
|
||||
QModelIndex index = unitsView->selectionModel()->currentIndex();
|
||||
if(!index.isValid()) return;
|
||||
Unit *u = (Unit*) index.data(Qt::UserRole).value<void*>();
|
||||
if(u) {
|
||||
emit convertToUnitRequest(u);
|
||||
}
|
||||
}
|
||||
void UnitsDialog::insertClicked() {
|
||||
QModelIndex index = unitsView->selectionModel()->currentIndex();
|
||||
if(!index.isValid()) return;
|
||||
Unit *u = (Unit*) index.data(Qt::UserRole).value<void*>();
|
||||
if(u) {
|
||||
emit insertUnitRequest(u);
|
||||
}
|
||||
}
|
||||
void UnitsDialog::deactivateClicked() {
|
||||
QModelIndex index = unitsView->selectionModel()->currentIndex();
|
||||
if(!index.isValid()) return;
|
||||
Unit *u = (Unit*) index.data(Qt::UserRole).value<void*>();
|
||||
if(u) {
|
||||
u->setActive(!u->isActive());
|
||||
unitsModel->invalidate();
|
||||
emit itemsChanged();
|
||||
}
|
||||
}
|
||||
void UnitsDialog::selectedUnitChanged(const QModelIndex &index, const QModelIndex&) {
|
||||
if(index.isValid()) {
|
||||
Unit *u = (Unit*) index.data(Qt::UserRole).value<void*>();
|
||||
if(CALCULATOR->stillHasUnit(u)) {
|
||||
selected_item = u;
|
||||
std::string str;
|
||||
const ExpressionName *ename = &u->preferredName(false, settings->printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) descriptionView);
|
||||
str = "<b>";
|
||||
str += ename->name;
|
||||
str += "</b>";
|
||||
for(size_t i2 = 1; i2 <= u->countNames(); i2++) {
|
||||
if(&u->getName(i2) != ename) {
|
||||
str += ", ";
|
||||
str += u->getName(i2).name;
|
||||
}
|
||||
}
|
||||
str += "<br><br>";
|
||||
bool is_approximate = false;
|
||||
PrintOptions po = settings->printops;
|
||||
po.can_display_unicode_string_arg = (void*) descriptionView;
|
||||
po.is_approximate = &is_approximate;
|
||||
po.allow_non_usable = true;
|
||||
po.interval_display = INTERVAL_DISPLAY_PLUSMINUS;
|
||||
po.base = 10;
|
||||
po.number_fraction_format = FRACTION_DECIMAL_EXACT;
|
||||
po.use_unit_prefixes = false;
|
||||
if(u->subtype() == SUBTYPE_ALIAS_UNIT) {
|
||||
AliasUnit *au = (AliasUnit*) u;
|
||||
MathStructure m(1, 1, 0), mexp(1, 1, 0);
|
||||
if(au->hasNonlinearExpression()) {
|
||||
m.set("x");
|
||||
if(au->expression().find("\\y") != std::string::npos) mexp.set("y");
|
||||
str += "<i>x</i> ";
|
||||
str += u->preferredDisplayName(settings->printops.abbreviate_names, settings->printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) descriptionView).name;
|
||||
str += " ";
|
||||
if(au->expression().find("\\y") != std::string::npos) str += "<sup><i>y</i></sup>";
|
||||
}
|
||||
au->convertToFirstBaseUnit(m, mexp);
|
||||
m.multiply(au->firstBaseUnit());
|
||||
if(!mexp.isOne()) m.last() ^= mexp;
|
||||
if(m.isApproximate() || is_approximate) str += SIGN_ALMOST_EQUAL " ";
|
||||
else str += "= ";
|
||||
m.format(po);
|
||||
str += m.print(po, true, false, TAG_TYPE_HTML);
|
||||
if(au->hasNonlinearExpression() && !au->inverseExpression().empty()) {
|
||||
str += "<br>";
|
||||
m.set("x");
|
||||
if(au->inverseExpression().find("\\y") != std::string::npos) mexp.set("y");
|
||||
else mexp.set(1, 1, 0);
|
||||
str += "<i>x</i> ";
|
||||
str += au->firstBaseUnit()->preferredDisplayName(settings->printops.abbreviate_names, settings->printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) descriptionView).name;
|
||||
str += " ";
|
||||
if(au->inverseExpression().find("\\y") != std::string::npos) str += "<sup><i>y</i></sup>";
|
||||
au->convertFromFirstBaseUnit(m, mexp);
|
||||
m.multiply(au);
|
||||
if(!mexp.isOne()) m.last() ^= mexp;
|
||||
if(m.isApproximate() || is_approximate) str += SIGN_ALMOST_EQUAL " ";
|
||||
else str += "= ";
|
||||
m.format(po);
|
||||
str += m.print(po, true, false, TAG_TYPE_HTML);
|
||||
}
|
||||
} else if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
|
||||
str += "= ";
|
||||
MathStructure m(((CompositeUnit*) u)->generateMathStructure());
|
||||
m.format(po);
|
||||
str += m.print(po, true, false, TAG_TYPE_HTML);
|
||||
}
|
||||
if(!u->description().empty()) {
|
||||
if(u->subtype() != SUBTYPE_BASE_UNIT) str += "<br>";
|
||||
str += "<br>";
|
||||
str += u->description();
|
||||
}
|
||||
if(u->isActive() != (deactivateButton->text() == tr("Deactivate"))) {
|
||||
deactivateButton->setMinimumWidth(deactivateButton->width());
|
||||
if(u->isActive()) {
|
||||
deactivateButton->setText(tr("Deactivate"));
|
||||
} else {
|
||||
deactivateButton->setText(tr("Activate"));
|
||||
}
|
||||
}
|
||||
//editButton->setEnabled(!u->isBuiltin());
|
||||
insertButton->setEnabled(u->isActive());
|
||||
convertButton->setEnabled(u->isActive());
|
||||
delButton->setEnabled(u->isLocal());
|
||||
deactivateButton->setEnabled(true);
|
||||
descriptionView->setHtml(QString::fromStdString(str));
|
||||
std::string to_filter;
|
||||
if(u->category().empty()) {
|
||||
if(u->isLocal()) to_filter = "Uncategorized";
|
||||
else to_filter = "User items";
|
||||
} else {
|
||||
to_filter = "/"; to_filter += u->category();
|
||||
}
|
||||
bool change_index = false;
|
||||
if(u->baseUnit()->referenceName() == "m" && u->baseExponent() == 3) {
|
||||
size_t i = to_filter.find("/", 1);
|
||||
if(i != std::string::npos) to_filter = to_filter.substr(0, i);
|
||||
}
|
||||
if(to_filter != toModel->currentFilter()) {
|
||||
toModel->setFilter(to_filter);
|
||||
toModel->sort(0);
|
||||
change_index = toCombo->count() > 0;
|
||||
} else if(toCombo->currentIndex() >= 0 && toCombo->currentData(Qt::UserRole).value<void*>() == u) {
|
||||
change_index = true;
|
||||
}
|
||||
if(change_index) {
|
||||
if(toCombo->itemData(0, Qt::UserRole).value<void*>() == u && toCombo->count() >= 2) toCombo->setCurrentIndex(1);
|
||||
else toCombo->setCurrentIndex(0);
|
||||
}
|
||||
fromEdit->setEnabled(u->isActive());
|
||||
toEdit->setEnabled(u->isActive());
|
||||
toCombo->setEnabled(u->isActive());
|
||||
QString qstr;
|
||||
if(u->isCurrency()) qstr = QString::fromStdString(u->referenceName());
|
||||
else qstr = QString::fromStdString(u->print(true, true, settings->printops.use_unicode_signs, &can_display_unicode_string_function, (void*) fromLabel));
|
||||
if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
|
||||
qstr.replace("^-1", "⁻" SIGN_POWER_1);
|
||||
qstr.replace("^-2", "⁻" SIGN_POWER_2);
|
||||
qstr.replace("^-3", "⁻" SIGN_POWER_3);
|
||||
qstr.replace("^-4", "⁻" SIGN_POWER_4);
|
||||
qstr.replace("^4", SIGN_POWER_4);
|
||||
qstr.remove("_unit");
|
||||
}
|
||||
fromLabel->setText(qstr);
|
||||
fromUnitChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
fromUnitChanged();
|
||||
fromEdit->setEnabled(false);
|
||||
toEdit->setEnabled(false);
|
||||
toCombo->setEnabled(false);
|
||||
fromLabel->setText(QString());
|
||||
editButton->setEnabled(false);
|
||||
insertButton->setEnabled(false);
|
||||
convertButton->setEnabled(false);
|
||||
delButton->setEnabled(false);
|
||||
deactivateButton->setEnabled(false);
|
||||
descriptionView->clear();
|
||||
selected_item = NULL;
|
||||
}
|
||||
void UnitsDialog::selectedCategoryChanged(QTreeWidgetItem *iter, QTreeWidgetItem*) {
|
||||
if(!iter) selected_category = "";
|
||||
else selected_category = iter->text(1).toStdString();
|
||||
searchEdit->clear();
|
||||
unitsModel->setFilter(selected_category);
|
||||
QModelIndex index = unitsView->selectionModel()->currentIndex();
|
||||
if(index.isValid()) {
|
||||
selectedUnitChanged(index, QModelIndex());
|
||||
unitsView->scrollTo(index);
|
||||
} else if(selected_category != "All" && selected_category != "Inactive" && selected_category != toModel->currentFilter()) {
|
||||
toModel->setFilter(selected_category);
|
||||
toModel->sort(0);
|
||||
if(toCombo->count()) toCombo->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
struct tree_struct {
|
||||
std::string item;
|
||||
std::list<tree_struct> items;
|
||||
std::list<tree_struct>::iterator it;
|
||||
std::list<tree_struct>::reverse_iterator rit;
|
||||
|
||||
tree_struct *parent;
|
||||
void sort() {
|
||||
items.sort();
|
||||
for(std::list<tree_struct>::iterator it = items.begin(); it != items.end(); ++it) {
|
||||
it->sort();
|
||||
}
|
||||
}
|
||||
bool operator < (const tree_struct &s1) const {
|
||||
return string_is_less(item, s1.item);
|
||||
}
|
||||
};
|
||||
void UnitsDialog::updateUnits() {
|
||||
|
||||
size_t cat_i, cat_i_prev;
|
||||
bool b;
|
||||
std::string str, cat, cat_sub;
|
||||
QString qstr;
|
||||
tree_struct unit_cats;
|
||||
unit_cats.parent = NULL;
|
||||
bool has_inactive = false, has_uncat = false;
|
||||
std::list<tree_struct>::iterator it;
|
||||
|
||||
sourceModel->clear();
|
||||
sourceModel->setColumnCount(1);
|
||||
sourceModel->setHorizontalHeaderItem(0, new QStandardItem(tr("Unit")));
|
||||
|
||||
toSourceModel->clear();
|
||||
toSourceModel->setColumnCount(1);
|
||||
|
||||
for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
|
||||
Unit *u = CALCULATOR->units[i];
|
||||
if(!u->isActive()) {
|
||||
has_inactive = true;
|
||||
} else {
|
||||
tree_struct *item = &unit_cats;
|
||||
if(!u->category().empty()) {
|
||||
cat = u->category();
|
||||
cat_i = cat.find("/"); cat_i_prev = 0;
|
||||
b = false;
|
||||
while(true) {
|
||||
if(cat_i == std::string::npos) {
|
||||
cat_sub = cat.substr(cat_i_prev, cat.length() - cat_i_prev);
|
||||
} else {
|
||||
cat_sub = cat.substr(cat_i_prev, cat_i - cat_i_prev);
|
||||
}
|
||||
b = false;
|
||||
for(it = item->items.begin(); it != item->items.end(); ++it) {
|
||||
if(cat_sub == it->item) {
|
||||
item = &*it;
|
||||
b = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!b) {
|
||||
tree_struct cat;
|
||||
item->items.push_back(cat);
|
||||
it = item->items.end();
|
||||
--it;
|
||||
it->parent = item;
|
||||
item = &*it;
|
||||
item->item = cat_sub;
|
||||
}
|
||||
if(cat_i == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
cat_i_prev = cat_i + 1;
|
||||
cat_i = cat.find("/", cat_i_prev);
|
||||
}
|
||||
} else if(!u->isLocal()) {
|
||||
has_uncat = true;
|
||||
}
|
||||
}
|
||||
QStandardItem *item = new QStandardItem(QString::fromStdString(u->title(true)));
|
||||
item->setEditable(false);
|
||||
item->setData(QVariant::fromValue((void*) u), Qt::UserRole);
|
||||
sourceModel->appendRow(item);
|
||||
if(u == selected_item) unitsView->selectionModel()->setCurrentIndex(unitsModel->mapFromSource(item->index()), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
|
||||
if(u->isCurrency()) qstr = QString::fromStdString(u->referenceName());
|
||||
else qstr = QString::fromStdString(u->print(true, true, settings->printops.use_unicode_signs, &can_display_unicode_string_function, (void*) toCombo));
|
||||
if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
|
||||
qstr.replace("^-1", "⁻" SIGN_POWER_1);
|
||||
qstr.replace("^-2", "⁻" SIGN_POWER_2);
|
||||
qstr.replace("^-3", "⁻" SIGN_POWER_3);
|
||||
qstr.replace("^-4", "⁻" SIGN_POWER_4);
|
||||
qstr.replace("^4", SIGN_POWER_4);
|
||||
qstr.remove("_unit");
|
||||
}
|
||||
item = new QStandardItem(qstr);
|
||||
item->setEditable(false);
|
||||
item->setData(QVariant::fromValue((void*) u), Qt::UserRole);
|
||||
toSourceModel->appendRow(item);
|
||||
}
|
||||
sourceModel->sort(0);
|
||||
toSourceModel->sort(0);
|
||||
unit_cats.sort();
|
||||
|
||||
categoriesView->clear();
|
||||
QTreeWidgetItem *iter, *iter2, *iter3;
|
||||
QStringList l;
|
||||
l << tr("All", "All units"); l << "All";
|
||||
iter3 = new QTreeWidgetItem(categoriesView, l);
|
||||
tree_struct *item, *item2;
|
||||
unit_cats.it = unit_cats.items.begin();
|
||||
if(unit_cats.it != unit_cats.items.end()) {
|
||||
item = &*unit_cats.it;
|
||||
++unit_cats.it;
|
||||
item->it = item->items.begin();
|
||||
} else {
|
||||
item = NULL;
|
||||
}
|
||||
str = "";
|
||||
iter2 = iter3;
|
||||
while(item) {
|
||||
str += "/";
|
||||
str += item->item;
|
||||
l.clear(); l << QString::fromStdString(item->item); l << QString::fromStdString(str);
|
||||
iter = new QTreeWidgetItem(iter2, l);
|
||||
if(str == selected_category) {
|
||||
iter->setExpanded(true);
|
||||
iter->setSelected(true);
|
||||
}
|
||||
while(item && item->it == item->items.end()) {
|
||||
size_t str_i = str.rfind("/");
|
||||
if(str_i == std::string::npos) {
|
||||
str = "";
|
||||
} else {
|
||||
str = str.substr(0, str_i);
|
||||
}
|
||||
item = item->parent;
|
||||
iter2 = iter->parent();
|
||||
iter = iter2;
|
||||
}
|
||||
if(item) {
|
||||
item2 = &*item->it;
|
||||
if(item->it == item->items.begin()) iter2 = iter;
|
||||
++item->it;
|
||||
item = item2;
|
||||
item->it = item->items.begin();
|
||||
}
|
||||
}
|
||||
if(has_uncat) {
|
||||
//add "Uncategorized" category if there are units without category
|
||||
l.clear(); l << tr("Uncategorized"); l << "Uncategorized";
|
||||
iter = new QTreeWidgetItem(iter3, l);
|
||||
if(selected_category == "Uncategorized") {
|
||||
iter->setSelected(true);
|
||||
}
|
||||
}
|
||||
l.clear(); l << tr("User units"); l << "User items";
|
||||
iter = new QTreeWidgetItem(iter3, l);
|
||||
if(selected_category == "User items") {
|
||||
iter->setSelected(true);
|
||||
}
|
||||
if(has_inactive) {
|
||||
//add "Inactive" category if there are inactive units
|
||||
l.clear(); l << tr("Inactive"); l << "Inactive";
|
||||
iter = new QTreeWidgetItem(categoriesView, l);
|
||||
if(selected_category == "Inactive") {
|
||||
iter->setSelected(true);
|
||||
}
|
||||
}
|
||||
if(categoriesView->selectedItems().isEmpty()) {
|
||||
//if no category has been selected (previously selected has been renamed/deleted), select "All"
|
||||
selected_category = "All";
|
||||
iter3->setExpanded(true);
|
||||
iter3->setSelected(true);
|
||||
}
|
||||
}
|
||||
void UnitsDialog::setSearch(const QString &str) {
|
||||
searchEdit->setText(str);
|
||||
searchChanged(str);
|
||||
}
|
||||
void UnitsDialog::selectCategory(std::string str) {
|
||||
QList<QTreeWidgetItem*> list = categoriesView->findItems((str.empty() || str == "All") ? "All" : "/" + QString::fromStdString(str), Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
|
||||
if(!list.isEmpty()) {
|
||||
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
}
|
||||
|
||||
|
99
src/unitsdialog.h
Normal file
99
src/unitsdialog.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
Qalculate (QT UI)
|
||||
|
||||
Copyright (C) 2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef UNITS_DIALOG_H
|
||||
#define UNITS_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <libqalculate/qalculate.h>
|
||||
|
||||
class QTreeView;
|
||||
class QTreeWidget;
|
||||
class QTextEdit;
|
||||
class QTreeWidgetItem;
|
||||
class QStandardItemModel;
|
||||
class QPushButton;
|
||||
class QLineEdit;
|
||||
class QSplitter;
|
||||
class ItemProxyModel;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
|
||||
class UnitsDialog : public QDialog {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
|
||||
QTreeView *unitsView;
|
||||
QTreeWidget *categoriesView;
|
||||
QTextEdit *descriptionView;
|
||||
ItemProxyModel *unitsModel, *toModel;
|
||||
QStandardItemModel *sourceModel, *toSourceModel;
|
||||
QPushButton *deactivateButton, *insertButton, *delButton, *editButton, *newButton, *convertButton;
|
||||
QLineEdit *searchEdit, *fromEdit, *toEdit;
|
||||
QSplitter *vsplitter, *hsplitter;
|
||||
QLabel *fromLabel, *equalsLabel;
|
||||
QComboBox *toCombo;
|
||||
bool last_from;
|
||||
|
||||
std::string selected_category;
|
||||
ExpressionItem *selected_item;
|
||||
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void closeEvent(QCloseEvent*) override;
|
||||
void convert(bool from);
|
||||
|
||||
protected slots:
|
||||
|
||||
void selectedCategoryChanged(QTreeWidgetItem*, QTreeWidgetItem*);
|
||||
void selectedUnitChanged(const QModelIndex&, const QModelIndex&);
|
||||
|
||||
void newClicked();
|
||||
void editClicked();
|
||||
void delClicked();
|
||||
void insertClicked();
|
||||
void convertClicked();
|
||||
void deactivateClicked();
|
||||
void searchChanged(const QString&);
|
||||
void fromChanged();
|
||||
void toChanged();
|
||||
void toUnitChanged();
|
||||
void fromUnitChanged();
|
||||
void onUnitActivated(const QModelIndex&);
|
||||
|
||||
public:
|
||||
|
||||
UnitsDialog(QWidget *parent = NULL);
|
||||
virtual ~UnitsDialog();
|
||||
|
||||
void updateUnits();
|
||||
void setSearch(const QString&);
|
||||
void selectCategory(std::string);
|
||||
void unitRemoved(Unit*);
|
||||
|
||||
public slots:
|
||||
|
||||
void reject() override;
|
||||
|
||||
signals:
|
||||
|
||||
void itemsChanged();
|
||||
void variableRemoved(Variable*);
|
||||
void insertUnitRequest(Unit*);
|
||||
void convertToUnitRequest(Unit*);
|
||||
void unitActivated(Unit*);
|
||||
|
||||
};
|
||||
|
||||
#endif //UNITS_DIALOG_H
|
||||
|
198
src/unknowneditdialog.cpp
Normal file
198
src/unknowneditdialog.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
Qalculate (QT UI)
|
||||
|
||||
Copyright (C) 2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QCheckBox>
|
||||
#include <QMessageBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDebug>
|
||||
|
||||
#include "qalculateqtsettings.h"
|
||||
#include "unknowneditdialog.h"
|
||||
|
||||
UnknownEditDialog::UnknownEditDialog(QWidget *parent) : QDialog(parent) {
|
||||
QVBoxLayout *box = new QVBoxLayout(this);
|
||||
QGridLayout *grid = new QGridLayout();
|
||||
box->addLayout(grid);
|
||||
grid->addWidget(new QLabel(tr("Name:"), this), 0, 0);
|
||||
nameEdit = new QLineEdit(this);
|
||||
grid->addWidget(nameEdit, 0, 1);
|
||||
customBox = new QCheckBox(tr("Custom assumptions"), this);
|
||||
customBox->setChecked(true);
|
||||
grid->addWidget(customBox, 1, 0, 1, 2);
|
||||
grid->addWidget(new QLabel(tr("Type:"), this), 2, 0);
|
||||
typeCombo = new QComboBox(this);
|
||||
typeCombo->addItem("Number", ASSUMPTION_TYPE_NUMBER);
|
||||
typeCombo->addItem("Real number", ASSUMPTION_TYPE_REAL);
|
||||
typeCombo->addItem("Rational number", ASSUMPTION_TYPE_RATIONAL);
|
||||
typeCombo->addItem("Integer", ASSUMPTION_TYPE_INTEGER);
|
||||
typeCombo->addItem("Boolean", ASSUMPTION_TYPE_BOOLEAN);
|
||||
grid->addWidget(typeCombo, 2, 1);
|
||||
grid->addWidget(new QLabel(tr("Sign:"), this), 3, 0);
|
||||
signCombo = new QComboBox(this);
|
||||
signCombo->addItem("Unknown", ASSUMPTION_SIGN_UNKNOWN);
|
||||
signCombo->addItem("Non-zero", ASSUMPTION_SIGN_NONZERO);
|
||||
signCombo->addItem("Positive", ASSUMPTION_SIGN_POSITIVE);
|
||||
signCombo->addItem("Non-negative", ASSUMPTION_SIGN_NONNEGATIVE);
|
||||
signCombo->addItem("Negative", ASSUMPTION_SIGN_NEGATIVE);
|
||||
signCombo->addItem("Non-positive", ASSUMPTION_SIGN_NONPOSITIVE);
|
||||
grid->addWidget(signCombo, 3, 1);
|
||||
typeCombo->setCurrentIndex(typeCombo->findData(CALCULATOR->defaultAssumptions()->type()));
|
||||
signCombo->setCurrentIndex(signCombo->findData(CALCULATOR->defaultAssumptions()->sign()));
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
okButton = buttonBox->button(QDialogButtonBox::Ok);
|
||||
box->addWidget(buttonBox);
|
||||
connect(nameEdit, SIGNAL(textEdited(const QString&)), this, SLOT(onNameEdited(const QString&)));
|
||||
connect(typeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onTypeChanged(int)));
|
||||
connect(signCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSignChanged(int)));
|
||||
connect(customBox, SIGNAL(toggled(bool)), this, SLOT(onCustomToggled(bool)));
|
||||
connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
|
||||
okButton->setEnabled(false);
|
||||
if(settings->always_on_top) setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
}
|
||||
UnknownEditDialog::~UnknownEditDialog() {}
|
||||
|
||||
void UnknownEditDialog::onTypeChanged(int i) {
|
||||
int t = typeCombo->itemData(i).toInt();
|
||||
int s = signCombo->currentData().toInt();
|
||||
if((t == ASSUMPTION_TYPE_NUMBER && s != ASSUMPTION_SIGN_NONZERO && s != ASSUMPTION_SIGN_UNKNOWN) || (t == ASSUMPTION_TYPE_BOOLEAN && s != ASSUMPTION_SIGN_UNKNOWN)) {
|
||||
signCombo->blockSignals(true);
|
||||
signCombo->setCurrentIndex(signCombo->findData(ASSUMPTION_SIGN_UNKNOWN));
|
||||
signCombo->blockSignals(false);
|
||||
}
|
||||
}
|
||||
void UnknownEditDialog::onSignChanged(int i) {
|
||||
int t = typeCombo->currentData().toInt();
|
||||
int s = signCombo->itemData(i).toInt();
|
||||
if((t == ASSUMPTION_TYPE_NUMBER && s != ASSUMPTION_SIGN_NONZERO && s != ASSUMPTION_SIGN_UNKNOWN) || (t == ASSUMPTION_TYPE_BOOLEAN && s != ASSUMPTION_SIGN_UNKNOWN)) {
|
||||
typeCombo->blockSignals(true);
|
||||
typeCombo->setCurrentIndex(typeCombo->findData(ASSUMPTION_TYPE_REAL));
|
||||
typeCombo->blockSignals(false);
|
||||
}
|
||||
}
|
||||
void UnknownEditDialog::onCustomToggled(bool b) {
|
||||
typeCombo->setEnabled(b);
|
||||
signCombo->setEnabled(b);
|
||||
}
|
||||
UnknownVariable *UnknownEditDialog::createVariable(ExpressionItem **replaced_item) {
|
||||
if(replaced_item) *replaced_item = NULL;
|
||||
Variable *var = NULL;
|
||||
if(CALCULATOR->variableNameTaken(nameEdit->text().trimmed().toStdString())) {
|
||||
if(QMessageBox::question(this, tr("Question"), tr("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) != QMessageBox::Yes) {
|
||||
nameEdit->setFocus();
|
||||
return NULL;
|
||||
}
|
||||
if(replaced_item) {
|
||||
var = CALCULATOR->getActiveVariable(nameEdit->text().trimmed().toStdString());
|
||||
if(!var) *replaced_item = CALCULATOR->getActiveUnit(nameEdit->text().trimmed().toStdString());
|
||||
else *replaced_item = var;
|
||||
}
|
||||
}
|
||||
UnknownVariable *v;
|
||||
if(var && var->isLocal() && !var->isKnown()) {
|
||||
v = (UnknownVariable*) var;
|
||||
if(v->countNames() > 1) v->clearNames();
|
||||
v->setHidden(false); v->setApproximate(false); v->setDescription(""); v->setTitle("");
|
||||
if(!modifyVariable(v)) return NULL;
|
||||
return v;
|
||||
}
|
||||
v = new UnknownVariable("", nameEdit->text().trimmed().toStdString());
|
||||
if(customBox->isChecked()) {
|
||||
v->setAssumptions(new Assumptions());
|
||||
v->assumptions()->setType((AssumptionType) typeCombo->currentData().toInt());
|
||||
v->assumptions()->setSign((AssumptionSign) signCombo->currentData().toInt());
|
||||
}
|
||||
v->setCategory(CALCULATOR->getVariableById(VARIABLE_ID_X)->category());
|
||||
v->setChanged(false);
|
||||
CALCULATOR->addVariable(v);
|
||||
return v;
|
||||
}
|
||||
bool UnknownEditDialog::modifyVariable(UnknownVariable *v, ExpressionItem **replaced_item) {
|
||||
if(replaced_item) *replaced_item = NULL;
|
||||
if(CALCULATOR->variableNameTaken(nameEdit->text().trimmed().toStdString(), v)) {
|
||||
if(QMessageBox::question(this, tr("Question"), tr("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) != QMessageBox::Yes) {
|
||||
nameEdit->setFocus();
|
||||
return false;
|
||||
}
|
||||
if(replaced_item) {
|
||||
Variable *var = CALCULATOR->getActiveVariable(nameEdit->text().trimmed().toStdString());
|
||||
if(!var) *replaced_item = CALCULATOR->getActiveUnit(nameEdit->text().trimmed().toStdString());
|
||||
else if(var != v) *replaced_item = var;
|
||||
}
|
||||
}
|
||||
if(v->countNames() > 1 && v->getName(1).name != nameEdit->text().trimmed().toStdString()) v->clearNames();
|
||||
v->setName(nameEdit->text().trimmed().toStdString());
|
||||
if(!customBox->isChecked()) {
|
||||
v->setAssumptions(NULL);
|
||||
} else {
|
||||
if(!v->assumptions()) v->setAssumptions(new Assumptions());
|
||||
v->assumptions()->setType((AssumptionType) typeCombo->currentData().toInt());
|
||||
v->assumptions()->setSign((AssumptionSign) signCombo->currentData().toInt());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void UnknownEditDialog::setVariable(UnknownVariable *v) {
|
||||
nameEdit->setText(QString::fromStdString(v->getName(1).name));
|
||||
Assumptions *ass = v->assumptions();
|
||||
customBox->setChecked(ass);
|
||||
if(!ass) ass = CALCULATOR->defaultAssumptions();
|
||||
typeCombo->setCurrentIndex(typeCombo->findData(ass->type()));
|
||||
signCombo->setCurrentIndex(signCombo->findData(ass->sign()));
|
||||
okButton->setEnabled(true);
|
||||
}
|
||||
void UnknownEditDialog::onNameEdited(const QString &str) {
|
||||
okButton->setEnabled(!str.trimmed().isEmpty());
|
||||
if(!str.trimmed().isEmpty() && !CALCULATOR->variableNameIsValid(str.trimmed().toStdString())) {
|
||||
nameEdit->setText(QString::fromStdString(CALCULATOR->convertToValidVariableName(str.trimmed().toStdString())));
|
||||
}
|
||||
}
|
||||
void UnknownEditDialog::setName(const QString &str) {
|
||||
nameEdit->setText(str);
|
||||
onNameEdited(str);
|
||||
}
|
||||
bool UnknownEditDialog::editVariable(QWidget *parent, UnknownVariable *v, ExpressionItem **replaced_item) {
|
||||
UnknownEditDialog *d = new UnknownEditDialog(parent);
|
||||
d->setWindowTitle(tr("Edit Unknown Variable"));
|
||||
d->setVariable(v);
|
||||
while(d->exec() == QDialog::Accepted) {
|
||||
if(d->modifyVariable(v, replaced_item)) {
|
||||
d->deleteLater();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
d->deleteLater();
|
||||
return false;
|
||||
}
|
||||
UnknownVariable* UnknownEditDialog::newVariable(QWidget *parent, ExpressionItem **replaced_item) {
|
||||
UnknownEditDialog *d = new UnknownEditDialog(parent);
|
||||
d->setWindowTitle(tr("New Unknown Variable"));
|
||||
std::string v_name;
|
||||
int i = 1;
|
||||
do {
|
||||
v_name = "v"; v_name += i2s(i);
|
||||
i++;
|
||||
} while(CALCULATOR->nameTaken(v_name));
|
||||
d->setName(QString::fromStdString(v_name));
|
||||
UnknownVariable *v = NULL;
|
||||
while(d->exec() == QDialog::Accepted) {
|
||||
v = d->createVariable(replaced_item);
|
||||
if(v) break;
|
||||
}
|
||||
d->deleteLater();
|
||||
return v;
|
||||
}
|
||||
|
57
src/unknowneditdialog.h
Normal file
57
src/unknowneditdialog.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
Qalculate (QT UI)
|
||||
|
||||
Copyright (C) 2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef UNKNOWN_EDIT_DIALOG_H
|
||||
#define UNKNOWN_EDIT_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <libqalculate/qalculate.h>
|
||||
|
||||
class QLineEdit;
|
||||
class QCheckBox;
|
||||
class QPushButton;
|
||||
class QComboBox;
|
||||
|
||||
class UnknownEditDialog : public QDialog {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
|
||||
QLineEdit *nameEdit;
|
||||
QCheckBox *customBox;
|
||||
QComboBox *typeCombo, *signCombo;
|
||||
QPushButton *okButton;
|
||||
|
||||
protected slots:
|
||||
|
||||
void onNameEdited(const QString&);
|
||||
void onTypeChanged(int);
|
||||
void onSignChanged(int);
|
||||
void onCustomToggled(bool);
|
||||
|
||||
public:
|
||||
|
||||
UnknownEditDialog(QWidget *parent = NULL);
|
||||
virtual ~UnknownEditDialog();
|
||||
|
||||
UnknownVariable *createVariable(ExpressionItem **replaced_item = NULL);
|
||||
bool modifyVariable(UnknownVariable *v, ExpressionItem **replaced_item = NULL);
|
||||
void setVariable(UnknownVariable *v);
|
||||
void setName(const QString&);
|
||||
|
||||
static bool editVariable(QWidget *parent, UnknownVariable *, ExpressionItem **replaced_item = NULL);
|
||||
static UnknownVariable* newVariable(QWidget *parent, ExpressionItem **replaced_item = NULL);
|
||||
|
||||
};
|
||||
|
||||
#endif //UNKNOWN_EDIT_DIALOG_H
|
@ -16,18 +16,21 @@
|
||||
#include <QPushButton>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDebug>
|
||||
|
||||
#include "qalculateqtsettings.h"
|
||||
#include "variableeditdialog.h"
|
||||
|
||||
VariableEditDialog::VariableEditDialog(QWidget *parent, bool allow_empty_value) : QDialog(parent), b_empty(allow_empty_value) {
|
||||
QGridLayout *grid = new QGridLayout(this);
|
||||
QVBoxLayout *box = new QVBoxLayout(this);
|
||||
QGridLayout *grid = new QGridLayout();
|
||||
box->addLayout(grid);
|
||||
grid->addWidget(new QLabel(tr("Name:"), this), 0, 0);
|
||||
nameEdit = new QLineEdit(this);
|
||||
grid->addWidget(nameEdit, 0, 1);
|
||||
grid->addWidget(new QLabel(tr("Value:"), this), 1, 0);
|
||||
valueEdit = new QLineEdit(this);
|
||||
valueEdit = new MathLineEdit(this);
|
||||
valueEdit->setAlignment(Qt::AlignRight);
|
||||
if(b_empty) valueEdit->setPlaceholderText(tr("current result"));
|
||||
grid->addWidget(valueEdit, 1, 1);
|
||||
@ -36,7 +39,7 @@ VariableEditDialog::VariableEditDialog(QWidget *parent, bool allow_empty_value)
|
||||
grid->addWidget(temporaryBox, 2, 0, 1, 2, Qt::AlignRight);
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
okButton = buttonBox->button(QDialogButtonBox::Ok);
|
||||
grid->addWidget(buttonBox, 3, 0, 1, 2);
|
||||
box->addWidget(buttonBox);
|
||||
connect(nameEdit, SIGNAL(textEdited(const QString&)), this, SLOT(onNameEdited(const QString&)));
|
||||
if(!b_empty) connect(valueEdit, SIGNAL(textEdited(const QString&)), this, SLOT(onValueEdited(const QString&)));
|
||||
connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
|
||||
@ -46,17 +49,25 @@ VariableEditDialog::VariableEditDialog(QWidget *parent, bool allow_empty_value)
|
||||
}
|
||||
VariableEditDialog::~VariableEditDialog() {}
|
||||
|
||||
KnownVariable *VariableEditDialog::createVariable(MathStructure *default_value) {
|
||||
KnownVariable *VariableEditDialog::createVariable(MathStructure *default_value, ExpressionItem **replaced_item) {
|
||||
if(replaced_item) *replaced_item = NULL;
|
||||
Variable *var = NULL;
|
||||
if(CALCULATOR->variableNameTaken(nameEdit->text().trimmed().toStdString())) {
|
||||
if(QMessageBox::question(this, tr("Question"), tr("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) != QMessageBox::Yes) {
|
||||
nameEdit->setFocus();
|
||||
return NULL;
|
||||
}
|
||||
if(replaced_item) {
|
||||
var = CALCULATOR->getActiveVariable(nameEdit->text().trimmed().toStdString());
|
||||
if(!var) *replaced_item = CALCULATOR->getActiveUnit(nameEdit->text().trimmed().toStdString());
|
||||
else *replaced_item = var;
|
||||
}
|
||||
}
|
||||
KnownVariable *v;
|
||||
Variable *var = CALCULATOR->getActiveVariable(nameEdit->text().trimmed().toStdString());
|
||||
if(var && var->isLocal() && var->isKnown()) {
|
||||
v = (KnownVariable*) var;
|
||||
if(v->countNames() > 1) v->clearNames();
|
||||
v->setHidden(false); v->setDescription(""); v->setTitle("");
|
||||
if(!modifyVariable(v, default_value)) return NULL;
|
||||
return v;
|
||||
}
|
||||
@ -71,15 +82,22 @@ KnownVariable *VariableEditDialog::createVariable(MathStructure *default_value)
|
||||
CALCULATOR->addVariable(v);
|
||||
return v;
|
||||
}
|
||||
bool VariableEditDialog::modifyVariable(KnownVariable *v, MathStructure *default_value) {
|
||||
bool VariableEditDialog::modifyVariable(KnownVariable *v, MathStructure *default_value, ExpressionItem **replaced_item) {
|
||||
if(replaced_item) *replaced_item = NULL;
|
||||
if(CALCULATOR->variableNameTaken(nameEdit->text().trimmed().toStdString(), v)) {
|
||||
if(QMessageBox::question(this, tr("Question"), tr("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) != QMessageBox::Yes) {
|
||||
nameEdit->setFocus();
|
||||
return false;
|
||||
}
|
||||
if(replaced_item) {
|
||||
Variable *var = CALCULATOR->getActiveVariable(nameEdit->text().trimmed().toStdString());
|
||||
if(!var) *replaced_item = CALCULATOR->getActiveUnit(nameEdit->text().trimmed().toStdString());
|
||||
else if(var != v) *replaced_item = var;
|
||||
}
|
||||
}
|
||||
if(v->countNames() > 1) v->clearNames();
|
||||
if(v->countNames() > 1 && v->getName(1).name != nameEdit->text().trimmed().toStdString()) v->clearNames();
|
||||
v->setName(nameEdit->text().trimmed().toStdString());
|
||||
v->setApproximate(false); v->setUncertainty(""); v->setUnit("");
|
||||
if(default_value && valueEdit->text().isEmpty()) {
|
||||
v->set(*default_value);
|
||||
} else {
|
||||
@ -102,7 +120,10 @@ void VariableEditDialog::setVariable(KnownVariable *v) {
|
||||
po.base = 10;
|
||||
valueEdit->setText(QString::fromStdString(CALCULATOR->print(v->get(), 1000, po)));
|
||||
}
|
||||
okButton->setEnabled(true);
|
||||
nameEdit->setReadOnly(!v->isLocal());
|
||||
valueEdit->setReadOnly(!v->isLocal());
|
||||
temporaryBox->setChecked(v->category() == CALCULATOR->temporaryCategory());
|
||||
okButton->setEnabled(v->isLocal());
|
||||
}
|
||||
void VariableEditDialog::onNameEdited(const QString &str) {
|
||||
okButton->setEnabled(!str.trimmed().isEmpty() && (b_empty || !valueEdit->text().trimmed().isEmpty()));
|
||||
@ -124,12 +145,12 @@ void VariableEditDialog::setName(const QString &str) {
|
||||
QString VariableEditDialog::value() const {
|
||||
return valueEdit->text();
|
||||
}
|
||||
bool VariableEditDialog::editVariable(QWidget *parent, KnownVariable *v, MathStructure *default_value) {
|
||||
bool VariableEditDialog::editVariable(QWidget *parent, KnownVariable *v, MathStructure *default_value, ExpressionItem **replaced_item) {
|
||||
VariableEditDialog *d = new VariableEditDialog(parent, default_value != NULL);
|
||||
d->setWindowTitle(tr("Edit Variable"));
|
||||
d->setVariable(v);
|
||||
while(d->exec() == QDialog::Accepted) {
|
||||
if(d->modifyVariable(v, default_value)) {
|
||||
if(d->modifyVariable(v, default_value, replaced_item)) {
|
||||
d->deleteLater();
|
||||
return true;
|
||||
}
|
||||
@ -137,7 +158,7 @@ bool VariableEditDialog::editVariable(QWidget *parent, KnownVariable *v, MathStr
|
||||
d->deleteLater();
|
||||
return false;
|
||||
}
|
||||
KnownVariable* VariableEditDialog::newVariable(QWidget *parent, MathStructure *default_value, const QString &value_str) {
|
||||
KnownVariable* VariableEditDialog::newVariable(QWidget *parent, MathStructure *default_value, const QString &value_str, ExpressionItem **replaced_item) {
|
||||
VariableEditDialog *d = new VariableEditDialog(parent, default_value != NULL && value_str.isEmpty());
|
||||
d->setWindowTitle(tr("New Variable"));
|
||||
std::string v_name;
|
||||
@ -152,7 +173,7 @@ KnownVariable* VariableEditDialog::newVariable(QWidget *parent, MathStructure *d
|
||||
while(d->exec() == QDialog::Accepted) {
|
||||
QString str = d->value().trimmed();
|
||||
if(default_value && str == value_str) d->setValue("");
|
||||
v = d->createVariable(default_value);
|
||||
v = d->createVariable(default_value, replaced_item);
|
||||
if(v) break;
|
||||
d->setValue(str);
|
||||
}
|
||||
|
@ -41,15 +41,15 @@ class VariableEditDialog : public QDialog {
|
||||
VariableEditDialog(QWidget *parent = NULL, bool allow_empty_value = true);
|
||||
virtual ~VariableEditDialog();
|
||||
|
||||
KnownVariable *createVariable(MathStructure *default_value = NULL);
|
||||
bool modifyVariable(KnownVariable *v, MathStructure *default_value = NULL);
|
||||
KnownVariable *createVariable(MathStructure *default_value = NULL, ExpressionItem **replaced_item = NULL);
|
||||
bool modifyVariable(KnownVariable *v, MathStructure *default_value = NULL, ExpressionItem **replaced_item = NULL);
|
||||
void setVariable(KnownVariable *v);
|
||||
void setValue(const QString&);
|
||||
QString value() const;
|
||||
void setName(const QString&);
|
||||
|
||||
static bool editVariable(QWidget *parent, KnownVariable *v, MathStructure *default_value = NULL);
|
||||
static KnownVariable* newVariable(QWidget *parent, MathStructure *default_value = NULL, const QString &value_str = QString());
|
||||
static bool editVariable(QWidget *parent, KnownVariable *v, MathStructure *default_value = NULL, ExpressionItem **replaced_item = NULL);
|
||||
static KnownVariable* newVariable(QWidget *parent, MathStructure *default_value = NULL, const QString &value_str = QString(), ExpressionItem **replaced_item = NULL);
|
||||
|
||||
};
|
||||
|
||||
|
556
src/variablesdialog.cpp
Normal file
556
src/variablesdialog.cpp
Normal file
@ -0,0 +1,556 @@
|
||||
/*
|
||||
Qalculate (QT UI)
|
||||
|
||||
Copyright (C) 2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QSplitter>
|
||||
#include <QTextEdit>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTreeView>
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QPushButton>
|
||||
#include <QLineEdit>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
#include <QDebug>
|
||||
|
||||
#include "qalculateqtsettings.h"
|
||||
#include "variablesdialog.h"
|
||||
#include "itemproxymodel.h"
|
||||
#include "unknowneditdialog.h"
|
||||
#include "variableeditdialog.h"
|
||||
|
||||
VariablesDialog::VariablesDialog(QWidget *parent) : QDialog(parent) {
|
||||
QVBoxLayout *topbox = new QVBoxLayout(this);
|
||||
setWindowTitle(tr("Variables"));
|
||||
QHBoxLayout *hbox = new QHBoxLayout();
|
||||
topbox->addLayout(hbox);
|
||||
vsplitter = new QSplitter(Qt::Vertical, this);
|
||||
hbox->addWidget(vsplitter, 1);
|
||||
hsplitter = new QSplitter(Qt::Horizontal, this);
|
||||
categoriesView = new QTreeWidget(this);
|
||||
categoriesView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
categoriesView->setRootIsDecorated(false);
|
||||
categoriesView->headerItem()->setText(0, tr("Category"));
|
||||
categoriesView->setColumnCount(2);
|
||||
categoriesView->setColumnHidden(1, true);
|
||||
hsplitter->addWidget(categoriesView);
|
||||
QWidget *w = new QWidget(this);
|
||||
QVBoxLayout *vbox = new QVBoxLayout(w);
|
||||
vbox->setSpacing(0);
|
||||
vbox->setContentsMargins(0, 0, 0, 0);
|
||||
variablesView = new QTreeView(this);
|
||||
variablesView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
variablesView->setRootIsDecorated(false);
|
||||
variablesModel = new ItemProxyModel(this);
|
||||
sourceModel = new QStandardItemModel(this);
|
||||
variablesModel->setSourceModel(sourceModel);
|
||||
sourceModel->setColumnCount(1);
|
||||
sourceModel->setHorizontalHeaderItem(0, new QStandardItem(tr("Variable")));
|
||||
variablesView->setModel(variablesModel);
|
||||
selected_item = NULL;
|
||||
vbox->addWidget(variablesView, 1);
|
||||
searchEdit = new QLineEdit(this);
|
||||
searchEdit->addAction(LOAD_ICON("edit-find"), QLineEdit::LeadingPosition);
|
||||
vbox->addWidget(searchEdit, 0);
|
||||
hsplitter->addWidget(w);
|
||||
vsplitter->addWidget(hsplitter);
|
||||
descriptionView = new QTextEdit(this);
|
||||
descriptionView->setReadOnly(true);
|
||||
vsplitter->addWidget(descriptionView);
|
||||
vsplitter->setStretchFactor(0, 3);
|
||||
vsplitter->setStretchFactor(1, 1);
|
||||
hsplitter->setStretchFactor(0, 2);
|
||||
hsplitter->setStretchFactor(1, 3);
|
||||
QVBoxLayout *box = new QVBoxLayout();
|
||||
newButton = new QPushButton(tr("New"), this); box->addWidget(newButton);
|
||||
QMenu *menu = new QMenu(this);
|
||||
menu->addAction(tr("Variable/constant"), this, SLOT(newVariable()));
|
||||
menu->addAction(tr("Unknown variable"), this, SLOT(newUnknown()));
|
||||
newButton->setMenu(menu);
|
||||
editButton = new QPushButton(tr("Edit"), this); box->addWidget(editButton); connect(editButton, SIGNAL(clicked()), this, SLOT(editClicked()));
|
||||
delButton = new QPushButton(tr("Delete"), this); box->addWidget(delButton); connect(delButton, SIGNAL(clicked()), this, SLOT(delClicked()));
|
||||
deactivateButton = new QPushButton(tr("Deactivate"), this); box->addWidget(deactivateButton); connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateClicked()));
|
||||
box->addSpacing(24);
|
||||
insertButton = new QPushButton(tr("Insert"), this); box->addWidget(insertButton); connect(insertButton, SIGNAL(clicked()), this, SLOT(insertClicked()));
|
||||
insertButton->setDefault(true);
|
||||
box->addStretch(1);
|
||||
hbox->addLayout(box, 0);
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this);
|
||||
topbox->addWidget(buttonBox);
|
||||
selected_category = "All";
|
||||
updateVariables();
|
||||
variablesModel->setFilter("All");
|
||||
connect(searchEdit, SIGNAL(textEdited(const QString&)), this, SLOT(searchChanged(const QString&)));
|
||||
connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(categoriesView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(selectedCategoryChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
|
||||
connect(variablesView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(selectedVariableChanged(const QModelIndex&, const QModelIndex&)));
|
||||
connect(variablesView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(insertClicked()));
|
||||
selectedVariableChanged(QModelIndex(), QModelIndex());
|
||||
if(!settings->variables_geometry.isEmpty()) restoreGeometry(settings->variables_geometry);
|
||||
else resize(900, 700);
|
||||
if(!settings->variables_vsplitter_state.isEmpty()) vsplitter->restoreState(settings->variables_vsplitter_state);
|
||||
if(!settings->variables_hsplitter_state.isEmpty()) hsplitter->restoreState(settings->variables_hsplitter_state);
|
||||
}
|
||||
VariablesDialog::~VariablesDialog() {}
|
||||
|
||||
void VariablesDialog::keyPressEvent(QKeyEvent *event) {
|
||||
if(event->matches(QKeySequence::Find)) {
|
||||
searchEdit->setFocus();
|
||||
return;
|
||||
}
|
||||
if(event->key() == Qt::Key_Escape && searchEdit->hasFocus()) {
|
||||
searchEdit->clear();
|
||||
variablesView->setFocus();
|
||||
return;
|
||||
}
|
||||
if(event->key() == Qt::Key_Return && variablesView->hasFocus()) {
|
||||
QModelIndex index = variablesView->selectionModel()->currentIndex();
|
||||
if(index.isValid()) {
|
||||
insertClicked();
|
||||
return;
|
||||
}
|
||||
}
|
||||
QDialog::keyPressEvent(event);
|
||||
}
|
||||
void VariablesDialog::closeEvent(QCloseEvent *e) {
|
||||
settings->variables_geometry = saveGeometry();
|
||||
settings->variables_vsplitter_state = vsplitter->saveState();
|
||||
settings->variables_hsplitter_state = hsplitter->saveState();
|
||||
QDialog::closeEvent(e);
|
||||
}
|
||||
void VariablesDialog::reject() {
|
||||
settings->variables_geometry = saveGeometry();
|
||||
settings->variables_vsplitter_state = vsplitter->saveState();
|
||||
settings->variables_hsplitter_state = hsplitter->saveState();
|
||||
QDialog::reject();
|
||||
}
|
||||
void VariablesDialog::searchChanged(const QString &str) {
|
||||
variablesModel->setSecondaryFilter(str.toStdString());
|
||||
variablesView->selectionModel()->setCurrentIndex(variablesModel->index(0, 0), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
void VariablesDialog::newVariable() {
|
||||
ExpressionItem *replaced_item = NULL;
|
||||
KnownVariable *v = VariableEditDialog::newVariable(this, NULL, QString(), &replaced_item);
|
||||
if(v) {
|
||||
if(replaced_item && (replaced_item == v || !item_in_calculator(replaced_item))) {
|
||||
QModelIndexList list = sourceModel->match(sourceModel->index(0, 0), Qt::UserRole, QVariant::fromValue((void*) replaced_item), 1, Qt::MatchExactly);
|
||||
if(!list.isEmpty()) sourceModel->removeRow(list[0].row());
|
||||
}
|
||||
selected_item = v;
|
||||
QStandardItem *item = new QStandardItem(QString::fromStdString(v->title(true)));
|
||||
item->setEditable(false);
|
||||
item->setData(QVariant::fromValue((void*) v), Qt::UserRole);
|
||||
sourceModel->appendRow(item);
|
||||
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + v->category()) {
|
||||
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
|
||||
if(!list.isEmpty()) {
|
||||
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
} else {
|
||||
variablesModel->invalidate();
|
||||
}
|
||||
sourceModel->sort(0);
|
||||
QModelIndex index = variablesModel->mapFromSource(item->index());
|
||||
if(index.isValid()) {
|
||||
variablesView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
variablesView->scrollTo(index);
|
||||
}
|
||||
emit itemsChanged();
|
||||
}
|
||||
}
|
||||
void VariablesDialog::newUnknown() {
|
||||
ExpressionItem *replaced_item = NULL;
|
||||
UnknownVariable *v = UnknownEditDialog::newVariable(this, &replaced_item);
|
||||
if(v) {
|
||||
if(replaced_item && (replaced_item == v || !item_in_calculator(replaced_item))) {
|
||||
if(!CALCULATOR->stillHasUnit((Unit*) replaced_item)) {
|
||||
emit unitRemoved((Unit*) replaced_item);
|
||||
} else if(replaced_item == v || !CALCULATOR->stillHasVariable((Variable*) replaced_item) || (replaced_item->type() == TYPE_VARIABLE && !CALCULATOR->hasVariable((Variable*) replaced_item))) {
|
||||
QModelIndexList list = sourceModel->match(sourceModel->index(0, 0), Qt::UserRole, QVariant::fromValue((void*) replaced_item), 1, Qt::MatchExactly);
|
||||
if(!list.isEmpty()) sourceModel->removeRow(list[0].row());
|
||||
} else if(replaced_item->type() == TYPE_UNIT && !CALCULATOR->hasUnit((Unit*) replaced_item)) {
|
||||
emit unitRemoved((Unit*) replaced_item);
|
||||
}
|
||||
}
|
||||
selected_item = v;
|
||||
QStandardItem *item = new QStandardItem(QString::fromStdString(v->title(true)));
|
||||
item->setEditable(false);
|
||||
item->setData(QVariant::fromValue((void*) v), Qt::UserRole);
|
||||
sourceModel->appendRow(item);
|
||||
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + v->category()) {
|
||||
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
|
||||
if(!list.isEmpty()) {
|
||||
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
} else {
|
||||
variablesModel->invalidate();
|
||||
}
|
||||
sourceModel->sort(0);
|
||||
QModelIndex index = variablesModel->mapFromSource(item->index());
|
||||
if(index.isValid()) {
|
||||
variablesView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
variablesView->scrollTo(index);
|
||||
}
|
||||
emit itemsChanged();
|
||||
}
|
||||
}
|
||||
void VariablesDialog::variableRemoved(Variable *v) {
|
||||
QModelIndexList list = sourceModel->match(sourceModel->index(0, 0), Qt::UserRole, QVariant::fromValue((void*) v), 1, Qt::MatchExactly);
|
||||
if(!list.isEmpty()) sourceModel->removeRow(list[0].row());
|
||||
}
|
||||
void VariablesDialog::editClicked() {
|
||||
QModelIndex index = variablesView->selectionModel()->currentIndex();
|
||||
if(!index.isValid()) return;
|
||||
Variable *v = (Variable*) index.data(Qt::UserRole).value<void*>();
|
||||
if(!v) return;
|
||||
bool b = false;
|
||||
ExpressionItem *replaced_item = NULL;
|
||||
if(v->isKnown()) {
|
||||
b = VariableEditDialog::editVariable(this, (KnownVariable*) v, NULL, &replaced_item);
|
||||
} else {
|
||||
b = UnknownEditDialog::editVariable(this, (UnknownVariable*) v, &replaced_item);
|
||||
}
|
||||
if(b) {
|
||||
sourceModel->removeRow(variablesModel->mapToSource(variablesView->selectionModel()->currentIndex()).row());
|
||||
if(replaced_item) {
|
||||
if(!CALCULATOR->stillHasUnit((Unit*) replaced_item)) {
|
||||
emit unitRemoved((Unit*) replaced_item);
|
||||
} else if(!CALCULATOR->stillHasVariable((Variable*) replaced_item) || (replaced_item->type() == TYPE_VARIABLE && !CALCULATOR->hasVariable((Variable*) replaced_item))) {
|
||||
QModelIndexList list = sourceModel->match(sourceModel->index(0, 0), Qt::UserRole, QVariant::fromValue((void*) replaced_item), 1, Qt::MatchExactly);
|
||||
if(!list.isEmpty()) sourceModel->removeRow(list[0].row());
|
||||
} else if(replaced_item->type() == TYPE_UNIT && !CALCULATOR->hasUnit((Unit*) replaced_item)) {
|
||||
emit unitRemoved((Unit*) replaced_item);
|
||||
}
|
||||
}
|
||||
QStandardItem *item = new QStandardItem(QString::fromStdString(v->title(true)));
|
||||
item->setEditable(false);
|
||||
item->setData(QVariant::fromValue((void*) v), Qt::UserRole);
|
||||
sourceModel->appendRow(item);
|
||||
selected_item = v;
|
||||
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + v->category()) {
|
||||
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
|
||||
if(!list.isEmpty()) {
|
||||
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
} else {
|
||||
variablesModel->invalidate();
|
||||
}
|
||||
sourceModel->sort(0);
|
||||
QModelIndex index = variablesModel->mapFromSource(item->index());
|
||||
if(index.isValid()) {
|
||||
variablesView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
variablesView->scrollTo(index);
|
||||
}
|
||||
emit itemsChanged();
|
||||
}
|
||||
}
|
||||
void VariablesDialog::delClicked() {
|
||||
QModelIndex index = variablesView->selectionModel()->currentIndex();
|
||||
if(!index.isValid()) return;
|
||||
Variable *v = (Variable*) index.data(Qt::UserRole).value<void*>();
|
||||
if(v && v->isLocal()) {
|
||||
sourceModel->removeRow(variablesModel->mapToSource(variablesView->selectionModel()->currentIndex()).row());
|
||||
selected_item = NULL;
|
||||
v->destroy();
|
||||
emit itemsChanged();
|
||||
}
|
||||
}
|
||||
void VariablesDialog::insertClicked() {
|
||||
QModelIndex index = variablesView->selectionModel()->currentIndex();
|
||||
if(!index.isValid()) return;
|
||||
Variable *v = (Variable*) index.data(Qt::UserRole).value<void*>();
|
||||
if(v) {
|
||||
emit insertVariableRequest(v);
|
||||
}
|
||||
}
|
||||
void VariablesDialog::deactivateClicked() {
|
||||
QModelIndex index = variablesView->selectionModel()->currentIndex();
|
||||
if(!index.isValid()) return;
|
||||
Variable *v = (Variable*) index.data(Qt::UserRole).value<void*>();
|
||||
if(v) {
|
||||
v->setActive(!v->isActive());
|
||||
variablesModel->invalidate();
|
||||
emit itemsChanged();
|
||||
}
|
||||
}
|
||||
void VariablesDialog::selectedVariableChanged(const QModelIndex &index, const QModelIndex&) {
|
||||
if(index.isValid()) {
|
||||
Variable *v = (Variable*) index.data(Qt::UserRole).value<void*>();
|
||||
if(CALCULATOR->stillHasVariable(v)) {
|
||||
selected_item = v;
|
||||
std::string str;
|
||||
const ExpressionName *ename = &v->preferredName(false, settings->printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) descriptionView);
|
||||
str = "<b>";
|
||||
str += ename->name;
|
||||
str += "</b>";
|
||||
for(size_t i2 = 1; i2 <= v->countNames(); i2++) {
|
||||
if(&v->getName(i2) != ename) {
|
||||
str += ", ";
|
||||
str += v->getName(i2).name;
|
||||
}
|
||||
}
|
||||
str += "<br><br>";
|
||||
if(v->isKnown()) {
|
||||
bool is_approximate = false;
|
||||
if(((KnownVariable*) v)->get().isMatrix() && ((KnownVariable*) v)->get().columns() * ((KnownVariable*) v)->get().rows() > 16) {
|
||||
str += tr("a matrix").toStdString();
|
||||
} else if(((KnownVariable*) v)->get().isVector() && ((KnownVariable*) v)->get().size() > 10) {
|
||||
str += tr("a vector").toStdString();
|
||||
} else {
|
||||
PrintOptions po = settings->printops;
|
||||
po.can_display_unicode_string_arg = (void*) descriptionView;
|
||||
po.interval_display = INTERVAL_DISPLAY_PLUSMINUS;
|
||||
po.base = 10;
|
||||
po.number_fraction_format = FRACTION_DECIMAL_EXACT;
|
||||
po.allow_non_usable = true;
|
||||
po.is_approximate = &is_approximate;
|
||||
if(v->isApproximate() || is_approximate) str += SIGN_ALMOST_EQUAL " ";
|
||||
else str += "= ";
|
||||
str += CALCULATOR->print(((KnownVariable*) v)->get(), 1000, po, true, settings->colorize_result ? settings->color : 0, TAG_TYPE_HTML);
|
||||
}
|
||||
} else {
|
||||
if(((UnknownVariable*) v)->assumptions()) {
|
||||
QString value;
|
||||
if(((UnknownVariable*) v)->assumptions()->type() != ASSUMPTION_TYPE_BOOLEAN) {
|
||||
switch(((UnknownVariable*) v)->assumptions()->sign()) {
|
||||
case ASSUMPTION_SIGN_POSITIVE: {value = tr("positive"); break;}
|
||||
case ASSUMPTION_SIGN_NONPOSITIVE: {value = tr("non-positive"); break;}
|
||||
case ASSUMPTION_SIGN_NEGATIVE: {value = tr("negative"); break;}
|
||||
case ASSUMPTION_SIGN_NONNEGATIVE: {value = tr("non-negative"); break;}
|
||||
case ASSUMPTION_SIGN_NONZERO: {value = tr("non-zero"); break;}
|
||||
default: {}
|
||||
}
|
||||
}
|
||||
if(!value.isEmpty() && ((UnknownVariable*) v)->assumptions()->type() != ASSUMPTION_TYPE_NONE) value += " ";
|
||||
switch(((UnknownVariable*) v)->assumptions()->type()) {
|
||||
case ASSUMPTION_TYPE_INTEGER: {value += tr("integer"); break;}
|
||||
case ASSUMPTION_TYPE_BOOLEAN: {value += tr("boolean"); break;}
|
||||
case ASSUMPTION_TYPE_RATIONAL: {value += tr("rational"); break;}
|
||||
case ASSUMPTION_TYPE_REAL: {value += tr("real"); break;}
|
||||
case ASSUMPTION_TYPE_COMPLEX: {value += tr("complex"); break;}
|
||||
case ASSUMPTION_TYPE_NUMBER: {value += tr("number"); break;}
|
||||
case ASSUMPTION_TYPE_NONMATRIX: {value += tr("non-matrix"); break;}
|
||||
default: {}
|
||||
}
|
||||
if(value.isEmpty()) value = tr("unknown");
|
||||
str += value.toStdString();
|
||||
} else {
|
||||
str += tr("Default assumptions").toStdString();
|
||||
}
|
||||
}
|
||||
if(!v->description().empty()) {
|
||||
str += "<br><br>";
|
||||
str += v->description();
|
||||
}
|
||||
if(v->isActive() != (deactivateButton->text() == tr("Deactivate"))) {
|
||||
deactivateButton->setMinimumWidth(deactivateButton->width());
|
||||
if(v->isActive()) {
|
||||
deactivateButton->setText(tr("Deactivate"));
|
||||
} else {
|
||||
deactivateButton->setText(tr("Activate"));
|
||||
}
|
||||
}
|
||||
editButton->setEnabled(!v->isBuiltin());
|
||||
insertButton->setEnabled(v->isActive());
|
||||
delButton->setEnabled(v->isLocal());
|
||||
deactivateButton->setEnabled(!settings->isAnswerVariable(v) && v != settings->v_memory);
|
||||
descriptionView->setHtml(QString::fromStdString(str));
|
||||
return;
|
||||
}
|
||||
}
|
||||
editButton->setEnabled(false);
|
||||
insertButton->setEnabled(false);
|
||||
delButton->setEnabled(false);
|
||||
deactivateButton->setEnabled(false);
|
||||
descriptionView->clear();
|
||||
selected_item = NULL;
|
||||
}
|
||||
void VariablesDialog::selectedCategoryChanged(QTreeWidgetItem *iter, QTreeWidgetItem*) {
|
||||
if(!iter) selected_category = "";
|
||||
else selected_category = iter->text(1).toStdString();
|
||||
searchEdit->clear();
|
||||
variablesModel->setFilter(selected_category);
|
||||
QModelIndex index = variablesView->selectionModel()->currentIndex();
|
||||
if(index.isValid()) {
|
||||
selectedVariableChanged(index, QModelIndex());
|
||||
variablesView->scrollTo(index);
|
||||
}
|
||||
}
|
||||
|
||||
struct tree_struct {
|
||||
std::string item;
|
||||
std::list<tree_struct> items;
|
||||
std::list<tree_struct>::iterator it;
|
||||
std::list<tree_struct>::reverse_iterator rit;
|
||||
|
||||
tree_struct *parent;
|
||||
void sort() {
|
||||
items.sort();
|
||||
for(std::list<tree_struct>::iterator it = items.begin(); it != items.end(); ++it) {
|
||||
it->sort();
|
||||
}
|
||||
}
|
||||
bool operator < (const tree_struct &s1) const {
|
||||
return string_is_less(item, s1.item);
|
||||
}
|
||||
};
|
||||
void VariablesDialog::updateVariables() {
|
||||
|
||||
size_t cat_i, cat_i_prev;
|
||||
bool b;
|
||||
std::string str, cat, cat_sub;
|
||||
tree_struct variable_cats;
|
||||
variable_cats.parent = NULL;
|
||||
bool has_inactive = false, has_uncat = false;
|
||||
std::list<tree_struct>::iterator it;
|
||||
|
||||
sourceModel->clear();
|
||||
sourceModel->setColumnCount(1);
|
||||
sourceModel->setHorizontalHeaderItem(0, new QStandardItem(tr("Variable")));
|
||||
|
||||
for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
|
||||
Variable *v = CALCULATOR->variables[i];
|
||||
if(!v->isActive()) {
|
||||
has_inactive = true;
|
||||
} else {
|
||||
tree_struct *item = &variable_cats;
|
||||
if(!v->category().empty()) {
|
||||
cat = v->category();
|
||||
cat_i = cat.find("/"); cat_i_prev = 0;
|
||||
b = false;
|
||||
while(true) {
|
||||
if(cat_i == std::string::npos) {
|
||||
cat_sub = cat.substr(cat_i_prev, cat.length() - cat_i_prev);
|
||||
} else {
|
||||
cat_sub = cat.substr(cat_i_prev, cat_i - cat_i_prev);
|
||||
}
|
||||
b = false;
|
||||
for(it = item->items.begin(); it != item->items.end(); ++it) {
|
||||
if(cat_sub == it->item) {
|
||||
item = &*it;
|
||||
b = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!b) {
|
||||
tree_struct cat;
|
||||
item->items.push_back(cat);
|
||||
it = item->items.end();
|
||||
--it;
|
||||
it->parent = item;
|
||||
item = &*it;
|
||||
item->item = cat_sub;
|
||||
}
|
||||
if(cat_i == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
cat_i_prev = cat_i + 1;
|
||||
cat_i = cat.find("/", cat_i_prev);
|
||||
}
|
||||
} else if(!v->isLocal()) {
|
||||
has_uncat = true;
|
||||
}
|
||||
}
|
||||
QStandardItem *item = new QStandardItem(QString::fromStdString(v->title(true)));
|
||||
item->setEditable(false);
|
||||
item->setData(QVariant::fromValue((void*) v), Qt::UserRole);
|
||||
sourceModel->appendRow(item);
|
||||
if(v == selected_item) variablesView->selectionModel()->setCurrentIndex(variablesModel->mapFromSource(item->index()), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
sourceModel->sort(0);
|
||||
variable_cats.sort();
|
||||
|
||||
categoriesView->clear();
|
||||
QTreeWidgetItem *iter, *iter2, *iter3;
|
||||
QStringList l;
|
||||
l << tr("All", "All variables"); l << "All";
|
||||
iter3 = new QTreeWidgetItem(categoriesView, l);
|
||||
tree_struct *item, *item2;
|
||||
variable_cats.it = variable_cats.items.begin();
|
||||
if(variable_cats.it != variable_cats.items.end()) {
|
||||
item = &*variable_cats.it;
|
||||
++variable_cats.it;
|
||||
item->it = item->items.begin();
|
||||
} else {
|
||||
item = NULL;
|
||||
}
|
||||
str = "";
|
||||
iter2 = iter3;
|
||||
while(item) {
|
||||
str += "/";
|
||||
str += item->item;
|
||||
l.clear(); l << QString::fromStdString(item->item); l << QString::fromStdString(str);
|
||||
iter = new QTreeWidgetItem(iter2, l);
|
||||
if(str == selected_category) {
|
||||
iter->setExpanded(true);
|
||||
iter->setSelected(true);
|
||||
}
|
||||
while(item && item->it == item->items.end()) {
|
||||
size_t str_i = str.rfind("/");
|
||||
if(str_i == std::string::npos) {
|
||||
str = "";
|
||||
} else {
|
||||
str = str.substr(0, str_i);
|
||||
}
|
||||
item = item->parent;
|
||||
iter2 = iter->parent();
|
||||
iter = iter2;
|
||||
}
|
||||
if(item) {
|
||||
item2 = &*item->it;
|
||||
if(item->it == item->items.begin()) iter2 = iter;
|
||||
++item->it;
|
||||
item = item2;
|
||||
item->it = item->items.begin();
|
||||
}
|
||||
}
|
||||
if(has_uncat) {
|
||||
//add "Uncategorized" category if there are variables without category
|
||||
l.clear(); l << tr("Uncategorized"); l << "Uncategorized";
|
||||
iter = new QTreeWidgetItem(iter3, l);
|
||||
if(selected_category == "Uncategorized") {
|
||||
iter->setSelected(true);
|
||||
}
|
||||
}
|
||||
l.clear(); l << tr("User variables"); l << "User items";
|
||||
iter = new QTreeWidgetItem(iter3, l);
|
||||
if(selected_category == "User items") {
|
||||
iter->setSelected(true);
|
||||
}
|
||||
if(has_inactive) {
|
||||
//add "Inactive" category if there are inactive variables
|
||||
l.clear(); l << tr("Inactive"); l << "Inactive";
|
||||
iter = new QTreeWidgetItem(categoriesView, l);
|
||||
if(selected_category == "Inactive") {
|
||||
iter->setSelected(true);
|
||||
}
|
||||
}
|
||||
if(categoriesView->selectedItems().isEmpty()) {
|
||||
//if no category has been selected (previously selected has been renamed/deleted), select "All"
|
||||
selected_category = "All";
|
||||
iter3->setExpanded(true);
|
||||
iter3->setSelected(true);
|
||||
}
|
||||
}
|
||||
void VariablesDialog::setSearch(const QString &str) {
|
||||
searchEdit->setText(str);
|
||||
searchChanged(str);
|
||||
}
|
||||
void VariablesDialog::selectCategory(std::string str) {
|
||||
QList<QTreeWidgetItem*> list = categoriesView->findItems((str.empty() || str == "All") ? "All" : "/" + QString::fromStdString(str), Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
|
||||
if(!list.isEmpty()) {
|
||||
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
|
||||
}
|
||||
}
|
||||
|
87
src/variablesdialog.h
Normal file
87
src/variablesdialog.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Qalculate (QT UI)
|
||||
|
||||
Copyright (C) 2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef VARIABLES_DIALOG_H
|
||||
#define VARIABLES_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <libqalculate/qalculate.h>
|
||||
|
||||
class QTreeView;
|
||||
class QTreeWidget;
|
||||
class QTextEdit;
|
||||
class QTreeWidgetItem;
|
||||
class QStandardItemModel;
|
||||
class QPushButton;
|
||||
class QLineEdit;
|
||||
class QSplitter;
|
||||
class ItemProxyModel;
|
||||
|
||||
class VariablesDialog : public QDialog {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
|
||||
QTreeView *variablesView;
|
||||
QTreeWidget *categoriesView;
|
||||
QTextEdit *descriptionView;
|
||||
ItemProxyModel *variablesModel;
|
||||
QStandardItemModel *sourceModel;
|
||||
QPushButton *deactivateButton, *insertButton, *delButton, *editButton, *newButton;
|
||||
QLineEdit *searchEdit;
|
||||
QSplitter *vsplitter, *hsplitter;
|
||||
|
||||
std::string selected_category;
|
||||
ExpressionItem *selected_item;
|
||||
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void closeEvent(QCloseEvent*) override;
|
||||
|
||||
protected slots:
|
||||
|
||||
void selectedCategoryChanged(QTreeWidgetItem*, QTreeWidgetItem*);
|
||||
void selectedVariableChanged(const QModelIndex&, const QModelIndex&);
|
||||
|
||||
void newVariable();
|
||||
void newUnknown();
|
||||
void editClicked();
|
||||
void delClicked();
|
||||
void insertClicked();
|
||||
void deactivateClicked();
|
||||
void searchChanged(const QString&);
|
||||
|
||||
public:
|
||||
|
||||
VariablesDialog(QWidget *parent = NULL);
|
||||
virtual ~VariablesDialog();
|
||||
|
||||
void updateVariables();
|
||||
void setSearch(const QString&);
|
||||
void selectCategory(std::string);
|
||||
void variableRemoved(Variable*);
|
||||
|
||||
public slots:
|
||||
|
||||
void reject() override;
|
||||
|
||||
signals:
|
||||
|
||||
void itemsChanged();
|
||||
void unitRemoved(Unit*);
|
||||
void applyVariableRequest(Variable*);
|
||||
void insertVariableRequest(Variable*);
|
||||
|
||||
};
|
||||
|
||||
#endif //VARIABLES_DIALOG_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user