summaryrefslogtreecommitdiffstats
path: root/src/qalculatefunctionsdialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qalculatefunctionsdialog.cpp')
-rw-r--r--src/qalculatefunctionsdialog.cpp537
1 files changed, 537 insertions, 0 deletions
diff --git a/src/qalculatefunctionsdialog.cpp b/src/qalculatefunctionsdialog.cpp
new file mode 100644
index 0000000..80b452d
--- /dev/null
+++ b/src/qalculatefunctionsdialog.cpp
@@ -0,0 +1,537 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculatefunctionsdialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateeditfunctiondialog.h"
+#include <kpushbutton.h>
+#include <qsplitter.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <klistview.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <qlayout.h>
+#include <ktextbrowser.h>
+#include <kapplication.h>
+#include <kstdguiitem.h>
+
+extern tree_struct function_cats;
+extern vector<void*> ia_functions;
+extern PrintOptions printops;
+
+QalculateFunctionsDialog::QalculateFunctionsDialog(QWidget *parent, const char *name) : KDialog(parent, name, false) {
+
+ function_edit_dialog = NULL;
+ selected_category = "";
+ selected_function = NULL;
+
+ QHBoxLayout *layout = new QHBoxLayout(this, marginHint(), spacingHint());
+
+ setCaption(i18n("Functions"));
+
+ QVBoxLayout *leftLayout = new QVBoxLayout(layout, spacingHint());
+
+ QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
+ leftLayout->addWidget(splitter);
+
+ categoryView = new KListView(splitter);
+ categoryView->addColumn(i18n("Category"));
+ categoryView->setRootIsDecorated(false);
+
+ functionView = new KListView(splitter);
+ functionView->addColumn(i18n("Function Name"));
+ functionView->setRootIsDecorated(false);
+
+ descriptionBrowser = new KTextBrowser(this);
+ leftLayout->addWidget(descriptionBrowser);
+
+ QVBoxLayout *buttonLayout = new QVBoxLayout(layout, spacingHint());
+
+ newButton = new QPushButton(i18n("New"), this);
+ buttonLayout->addWidget(newButton);
+ editButton = new QPushButton(i18n("Edit"), this);
+ editButton->setEnabled(false);
+ buttonLayout->addWidget(editButton);
+ deleteButton = new QPushButton(i18n("Delete"), this);
+ deleteButton->setEnabled(false);
+ buttonLayout->addWidget(deleteButton);
+ deactivateButton = new QPushButton(i18n("Deactivate"), this);
+ deactivateButton->setEnabled(false);
+ buttonLayout->addWidget(deactivateButton);
+ insertButton = new QPushButton(i18n("Insert"), this);
+ insertButton->setEnabled(false);
+ buttonLayout->addWidget(insertButton);
+ applyButton = new QPushButton(i18n("Apply"), this);
+ applyButton->setEnabled(false);
+ buttonLayout->addWidget(applyButton);
+ buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
+ helpButton = new KPushButton(KStdGuiItem::help(), this);
+ buttonLayout->addWidget(helpButton);
+ buttonClose = new KPushButton(KStdGuiItem::close(), this);
+ buttonClose->setFocus();
+ buttonLayout->addWidget(buttonClose);
+
+ resize(QSize(675, 475).expandedTo(size()));
+
+ connect(buttonClose, SIGNAL(clicked()), this, SLOT(close()));
+ connect(newButton, SIGNAL(clicked()), this, SLOT(newFunction()));
+ connect(editButton, SIGNAL(clicked()), this, SLOT(editFunction()));
+ connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteFunction()));
+ connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateFunction()));
+ connect(insertButton, SIGNAL(clicked()), this, SLOT(insertFunction()));
+ connect(applyButton, SIGNAL(clicked()), this, SLOT(applyFunction()));
+ connect(functionView, SIGNAL(selectionChanged()), this, SLOT(functionSelected()));
+ connect(functionView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(functionDoubleClicked(QListViewItem*)));
+ connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected()));
+ connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp()));
+
+}
+
+QalculateFunctionsDialog::~QalculateFunctionsDialog() {
+}
+
+void QalculateFunctionsDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-managers");
+}
+
+void QalculateFunctionsDialog::updateFunctionTree() {
+ functionItems.clear();
+ categoryItems.clear();
+ categoryView->clear();
+ QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2;
+ categoryItems[i] = i18n("All");
+ i->setOpen(true);
+ QString str;
+ tree_struct *item, *item2;
+ function_cats.it = function_cats.items.begin();
+ if(function_cats.it != function_cats.items.end()) {
+ item = &*function_cats.it;
+ ++function_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+ str = "";
+ i2 = i;
+ while(item) {
+ str += "/";
+ str += item->item.c_str();
+ i = new KListViewItem(i2, item->item.c_str());
+ i->setOpen(false);
+ categoryItems[i] = str;
+ if(str == selected_category) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ while(item && item->it == item->items.end()) {
+ int str_i = str.findRev("/");
+ if(str_i < 0) {
+ str = "";
+ } else {
+ str.truncate(str_i);
+ }
+ item = item->parent;
+ i = i->parent();
+ i2 = i;
+ }
+ if(item) {
+ item2 = &*item->it;
+ if(item->it == item->items.begin())
+ i2 = i;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+ if(!function_cats.objects.empty()) {
+ //add "Uncategorized" category if there are functions without category
+ i = new KListViewItem(categoryView, i18n("Uncategorized"));
+ categoryItems[i] = i18n("Uncategorized");
+ if(selected_category == i18n("Uncategorized")) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ }
+ if(!ia_functions.empty()) {
+ //add "Inactive" category if there are inactive functions
+ i = new KListViewItem(categoryView, i18n("Inactive"));
+ categoryItems[i] = i18n("Inactive");
+ if(selected_category == i18n("Inactive")) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ }
+ if(!categoryView->selectedItem()) {
+ //if no category has been selected (previously selected has been renamed/deleted), select "All"
+ selected_category = i18n("All");
+ QListViewItemIterator it(categoryView);
+ if(it.current())
+ categoryView->setSelected(it.current(), true);
+ }
+}
+
+#define UPDATE_SELECTED_FUNCTION QListViewItem *i = functionView->selectedItem(); if(!i) return; selected_function = functionItems[i]; if(!selected_function) return;
+#define CHECK_IF_FUNCTION_STILL_THERE if(!CALCULATOR->stillHasFunction(selected_function)) {KMessageBox::error(this, i18n("Function does not exist anymore.")); emit functionsChanged(); return;}
+
+void QalculateFunctionsDialog::insertFunction() {
+ UPDATE_SELECTED_FUNCTION
+ CHECK_IF_FUNCTION_STILL_THERE
+ emit insertRequest(selected_function);
+}
+
+void QalculateFunctionsDialog::applyFunction() {
+ UPDATE_SELECTED_FUNCTION
+ CHECK_IF_FUNCTION_STILL_THERE
+ emit applyRequest(selected_function);
+}
+
+void QalculateFunctionsDialog::deactivateFunction() {
+ UPDATE_SELECTED_FUNCTION
+ CHECK_IF_FUNCTION_STILL_THERE
+ selected_function->setActive(!selected_function->isActive());
+ emit functionsChanged();
+}
+
+void QalculateFunctionsDialog::deleteFunction() {
+ UPDATE_SELECTED_FUNCTION
+ CHECK_IF_FUNCTION_STILL_THERE
+ if(selected_function->isLocal()) {
+ //ensure that all references are removed in Calculator
+ selected_function->destroy();
+ //update menus and trees
+ emit functionsChanged();
+ }
+}
+
+
+void QalculateFunctionsDialog::editFunction() {
+ UPDATE_SELECTED_FUNCTION
+ CHECK_IF_FUNCTION_STILL_THERE
+ if(!function_edit_dialog) {
+ function_edit_dialog = new QalculateEditFunctionDialog(this);
+ }
+ MathFunction *f = function_edit_dialog->editFunction(QString::null, selected_function);
+ if(f) {
+ selected_function = f;
+ if(!f->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(f->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += f->category().c_str();
+ }
+ emit functionsChanged();
+ }
+}
+
+void QalculateFunctionsDialog::newFunction() {
+ if(!function_edit_dialog) {
+ function_edit_dialog = new QalculateEditFunctionDialog(this);
+ }
+ MathFunction *f = NULL;
+ if(selected_category.isEmpty() || selected_category[0] != '/') {
+ f = function_edit_dialog->editFunction();
+ } else {
+ QString str = selected_category;
+ str.remove(0, 1);
+ f = function_edit_dialog->editFunction(str);
+ }
+ if(f) {
+ selected_function = f;
+ if(!f->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(f->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += f->category().c_str();
+ }
+ emit functionsChanged();
+ }
+}
+
+void QalculateFunctionsDialog::functionDoubleClicked(QListViewItem*i) {
+ selected_function = functionItems[i];
+ if(!selected_function)
+ return;
+ CHECK_IF_FUNCTION_STILL_THERE
+ if(!function_edit_dialog) {
+ function_edit_dialog = new QalculateEditFunctionDialog(this);
+ }
+ MathFunction *f = function_edit_dialog->editFunction(QString::null, selected_function);
+ if(f) {
+ selected_function = f;
+ if(!f->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(f->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += f->category().c_str();
+ }
+ emit functionsChanged();
+ }
+}
+
+
+void QalculateFunctionsDialog::functionSelected() {
+ QListViewItem *selected = functionView->selectedItem();
+ if(selected) {
+ MathFunction *f = functionItems[selected];
+ if(!CALCULATOR->stillHasFunction(f)) {
+ KMessageBox::error(this, i18n("Function does not exist anymore."));
+ selected_function = NULL;
+ emit functionsChanged();
+ return;
+ }
+ //remember selection
+ selected_function = f;
+ editButton->setEnabled(true);
+ insertButton->setEnabled(f->isActive());
+ applyButton->setEnabled(f->isActive() && f->minargs() <= 1);
+ deleteButton->setEnabled(f->isLocal());
+ deactivateButton->setEnabled(true);
+ if(f->isActive()) {
+ deactivateButton->setText(i18n("Deactivate"));
+ } else {
+ deactivateButton->setText(i18n("Activate"));
+ }
+
+ Argument *arg;
+ Argument default_arg;
+ QString str, str2;
+ const ExpressionName *ename = &f->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) descriptionBrowser);
+ str += "<i><b>";
+ str += ename->name.c_str();
+ str += "</b>";
+ int iargs = f->maxargs();
+ if(iargs < 0) {
+ iargs = f->minargs() + 1;
+ }
+ str += "(";
+ if(iargs != 0) {
+ for(int i2 = 1; i2 <= iargs; i2++) {
+ if(i2 > f->minargs()) {
+ str += "[";
+ }
+ if(i2 > 1) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ";
+ }
+ arg = f->getArgumentDefinition(i2);
+ if(arg && !arg->name().empty()) {
+ str += arg->name().c_str();
+ } else {
+ str += i18n("argument");
+ str += " ";
+ str += QString::number(i2);
+ }
+ if(i2 > f->minargs()) {
+ str += "]";
+ }
+ }
+ if(f->maxargs() < 0) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ...";
+ }
+ }
+ str += ")";
+ for(size_t i2 = 1; i2 <= f->countNames(); i2++) {
+ if(&f->getName(i2) != ename) {
+ str += "<br>";
+ str += f->getName(i2).name.c_str();
+ }
+ }
+ str += "</i>";
+ str += "<br>";
+ if(f->subtype() == SUBTYPE_DATA_SET) {
+ str += "<br>";
+ str2.sprintf(i18n("Retrieves data from the %s data set for a given object and property. If \"info\" is typed as property, a dialog window will pop up with all properties of the object."), f->title().c_str());
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "<br>";
+ }
+ if(!f->description().empty()) {
+ str += "<br>";
+ str2 = f->description().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "<br>";
+ }
+ if(f->subtype() == SUBTYPE_DATA_SET && !((DataSet*) f)->copyright().empty()) {
+ str += "<br>";
+ str2 = ((DataSet*) f)->copyright().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "<br>";
+ }
+ if(iargs) {
+ str += "<br><b>";
+ str += i18n("Arguments");
+ str += "</b><br>";
+ for(int i2 = 1; i2 <= iargs; i2++) {
+ arg = f->getArgumentDefinition(i2);
+ if(arg && !arg->name().empty()) {
+ str += arg->name().c_str();
+ } else {
+ str += QString::number(i2);
+ }
+ str += ": <i>";
+ if(arg) {
+ str2= arg->printlong().c_str();
+ } else {
+ str2= default_arg.printlong().c_str();
+ }
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ if(i2 > f->minargs()) {
+ str += " (";
+ //optional argument
+ str += i18n("optional");
+ if(!f->getDefaultValue(i2).empty()) {
+ str += ", ";
+ //argument default, in description
+ str += i18n("default: ");
+ str += f->getDefaultValue(i2).c_str();
+ }
+ str += ")";
+ }
+ str += "</i><br>";
+ }
+ }
+ if(!f->condition().empty()) {
+ str += "<br>";
+ str += i18n("Requirement");
+ str += ": ";
+ str2 = f->printCondition().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "<br>";
+ }
+ if(f->subtype() == SUBTYPE_DATA_SET) {
+ DataSet *ds = (DataSet*) f;
+ str += "<br><b>";
+ str += i18n("Properties");
+ str += "</b><br>";
+ DataPropertyIter it;
+ DataProperty *dp = ds->getFirstProperty(&it);
+ while(dp) {
+ if(!dp->isHidden()) {
+ if(!dp->title(false).empty()) {
+ str2 = dp->title().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += ": ";
+ }
+ for(size_t i = 1; i <= dp->countNames(); i++) {
+ if(i > 1) str += ", ";
+ str += dp->getName(i).c_str();
+ }
+ if(dp->isKey()) {
+ str += " (";
+ str += i18n("key");
+ str += ")";
+ }
+ str += "<br>";
+ if(!dp->description().empty()) {
+ str += "<i>";
+ str2 = dp->description().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "</i><br>";
+ }
+ }
+ dp = ds->getNextProperty(&it);
+ }
+ }
+ str.replace("\n", "<br>");
+ descriptionBrowser->setText(str);
+ } else {
+ editButton->setEnabled(false);
+ insertButton->setEnabled(false);
+ applyButton->setEnabled(false);
+ deleteButton->setEnabled(false);
+ deactivateButton->setEnabled(false);
+ selected_function = NULL;
+ descriptionBrowser->clear();
+ }
+}
+
+void QalculateFunctionsDialog::addFunctionTreeItem(MathFunction *f) {
+ QListViewItem *i = new KListViewItem(functionView, f->title(true).c_str());
+ functionItems[i] = f;
+ if(f == selected_function) {
+ functionView->setSelected(i, true);
+ }
+}
+
+
+void QalculateFunctionsDialog::categorySelected() {
+ QListViewItem *selected = categoryView->selectedItem();
+ bool no_cat = false, b_all = false, b_inactive = false;
+ functionView->clear();
+ functionItems.clear();
+ if(!selected) {
+ selected_category = "";
+ functionSelected();
+ return;
+ }
+ selected_category = categoryItems[selected];
+ if(selected_category == i18n("All")) {
+ b_all = true;
+ } else if(selected_category == i18n("Uncategorized")) {
+ no_cat = true;
+ } else if(selected_category == i18n("Inactive")) {
+ b_inactive = true;
+ }
+ if(!b_all && !no_cat && !b_inactive && selected_category[0] == '/') {
+ string str = selected_category.ascii();
+ str.erase(str.begin());
+ for(size_t i = 0; i < CALCULATOR->functions.size(); i++) {
+ if(CALCULATOR->functions[i]->isActive() && CALCULATOR->functions[i]->category().substr(0, selected_category.length() - 1) == str) {
+ addFunctionTreeItem(CALCULATOR->functions[i]);
+ }
+ }
+ } else {
+ string str = selected_category.ascii();
+ for(size_t i = 0; i < CALCULATOR->functions.size(); i++) {
+ if((b_inactive && !CALCULATOR->functions[i]->isActive()) || (CALCULATOR->functions[i]->isActive() && (b_all || (no_cat && CALCULATOR->functions[i]->category().empty()) || (!b_inactive && CALCULATOR->functions[i]->category() == str)))) {
+ addFunctionTreeItem(CALCULATOR->functions[i]);
+ }
+ }
+ }
+ if(!selected_function || !functionView->selectedItem()) {
+ QListViewItemIterator it(functionView);
+ if(it.current())
+ functionView->setSelected(it.current(), true);
+ }
+
+}
+
+
+#include "qalculatefunctionsdialog.moc"