You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
540 lines
17 KiB
540 lines
17 KiB
/***************************************************************************
|
|
* 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_tde_utils.h"
|
|
#include "qalculateeditfunctiondialog.h"
|
|
#include <vector>
|
|
#include <string>
|
|
#include <kpushbutton.h>
|
|
#include <tqsplitter.h>
|
|
#include <tqvbox.h>
|
|
#include <tqhbox.h>
|
|
#include <tdelistview.h>
|
|
#include <tdemessagebox.h>
|
|
#include <tdelocale.h>
|
|
#include <tqlayout.h>
|
|
#include <ktextbrowser.h>
|
|
#include <tdeapplication.h>
|
|
#include <kstdguiitem.h>
|
|
|
|
extern tree_struct function_cats;
|
|
extern std::vector<void*> ia_functions;
|
|
extern PrintOptions printops;
|
|
|
|
QalculateFunctionsDialog::QalculateFunctionsDialog(TQWidget *parent, const char *name) : KDialog(parent, name, false) {
|
|
|
|
function_edit_dialog = NULL;
|
|
selected_category = "";
|
|
selected_function = NULL;
|
|
|
|
TQHBoxLayout *layout = new TQHBoxLayout(this, marginHint(), spacingHint());
|
|
|
|
setCaption(i18n("Functions"));
|
|
|
|
TQVBoxLayout *leftLayout = new TQVBoxLayout(layout, spacingHint());
|
|
|
|
TQSplitter *splitter = new TQSplitter(TQt::Horizontal, this);
|
|
leftLayout->addWidget(splitter);
|
|
|
|
categoryView = new TDEListView(splitter);
|
|
categoryView->addColumn(i18n("Category"));
|
|
categoryView->setRootIsDecorated(false);
|
|
|
|
functionView = new TDEListView(splitter);
|
|
functionView->addColumn(i18n("Function Name"));
|
|
functionView->setRootIsDecorated(false);
|
|
|
|
descriptionBrowser = new KTextBrowser(this);
|
|
leftLayout->addWidget(descriptionBrowser);
|
|
|
|
TQVBoxLayout *buttonLayout = new TQVBoxLayout(layout, spacingHint());
|
|
|
|
newButton = new TQPushButton(i18n("New"), this);
|
|
buttonLayout->addWidget(newButton);
|
|
editButton = new TQPushButton(i18n("Edit"), this);
|
|
editButton->setEnabled(false);
|
|
buttonLayout->addWidget(editButton);
|
|
deleteButton = new TQPushButton(i18n("Delete"), this);
|
|
deleteButton->setEnabled(false);
|
|
buttonLayout->addWidget(deleteButton);
|
|
deactivateButton = new TQPushButton(i18n("Deactivate"), this);
|
|
deactivateButton->setEnabled(false);
|
|
buttonLayout->addWidget(deactivateButton);
|
|
insertButton = new TQPushButton(i18n("Insert"), this);
|
|
insertButton->setEnabled(false);
|
|
buttonLayout->addWidget(insertButton);
|
|
applyButton = new TQPushButton(i18n("Apply"), this);
|
|
applyButton->setEnabled(false);
|
|
buttonLayout->addWidget(applyButton);
|
|
buttonLayout->addItem(new TQSpacerItem(0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding));
|
|
helpButton = new KPushButton(KStdGuiItem::help(), this);
|
|
buttonLayout->addWidget(helpButton);
|
|
buttonClose = new KPushButton(KStdGuiItem::close(), this);
|
|
buttonClose->setFocus();
|
|
buttonLayout->addWidget(buttonClose);
|
|
|
|
resize(TQSize(675, 475).expandedTo(size()));
|
|
|
|
connect(buttonClose, TQ_SIGNAL(clicked()), this, TQ_SLOT(close()));
|
|
connect(newButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(newFunction()));
|
|
connect(editButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(editFunction()));
|
|
connect(deleteButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(deleteFunction()));
|
|
connect(deactivateButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(deactivateFunction()));
|
|
connect(insertButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(insertFunction()));
|
|
connect(applyButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(applyFunction()));
|
|
connect(functionView, TQ_SIGNAL(selectionChanged()), this, TQ_SLOT(functionSelected()));
|
|
connect(functionView, TQ_SIGNAL(doubleClicked(TQListViewItem*)), this, TQ_SLOT(functionDoubleClicked(TQListViewItem*)));
|
|
connect(categoryView, TQ_SIGNAL(selectionChanged()), this, TQ_SLOT(categorySelected()));
|
|
connect(helpButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotHelp()));
|
|
|
|
}
|
|
|
|
QalculateFunctionsDialog::~QalculateFunctionsDialog() {
|
|
}
|
|
|
|
void QalculateFunctionsDialog::slotHelp() {
|
|
TDEApplication::kApplication()->invokeHelp("qalculate-managers");
|
|
}
|
|
|
|
void QalculateFunctionsDialog::updateFunctionTree() {
|
|
functionItems.clear();
|
|
categoryItems.clear();
|
|
categoryView->clear();
|
|
TQListViewItem *i = new TDEListViewItem(categoryView, i18n("All")), *i2;
|
|
categoryItems[i] = i18n("All");
|
|
i->setOpen(true);
|
|
TQString 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 TDEListViewItem(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 TDEListViewItem(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 TDEListViewItem(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");
|
|
TQListViewItemIterator it(categoryView);
|
|
if(it.current())
|
|
categoryView->setSelected(it.current(), true);
|
|
}
|
|
}
|
|
|
|
#define UPDATE_SELECTED_FUNCTION TQListViewItem *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(TQString::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 {
|
|
TQString 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(TQListViewItem*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(TQString::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() {
|
|
TQListViewItem *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;
|
|
TQString 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 += TQString::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.").utf8(), f->title().c_str());
|
|
str2.replace("<", "<");
|
|
str2.replace(">", ">");
|
|
str += str2;
|
|
str += "<br>";
|
|
}
|
|
if(!f->description().empty()) {
|
|
str += "<br>";
|
|
str2 = f->description().c_str();
|
|
str2.replace("<", "<");
|
|
str2.replace(">", ">");
|
|
str += str2;
|
|
str += "<br>";
|
|
}
|
|
if(f->subtype() == SUBTYPE_DATA_SET && !((DataSet*) f)->copyright().empty()) {
|
|
str += "<br>";
|
|
str2 = ((DataSet*) f)->copyright().c_str();
|
|
str2.replace("<", "<");
|
|
str2.replace(">", ">");
|
|
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 += TQString::number(i2);
|
|
}
|
|
str += ": <i>";
|
|
if(arg) {
|
|
str2= arg->printlong().c_str();
|
|
} else {
|
|
str2= default_arg.printlong().c_str();
|
|
}
|
|
str2.replace("<", "<");
|
|
str2.replace(">", ">");
|
|
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("<", "<");
|
|
str2.replace(">", ">");
|
|
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("<", "<");
|
|
str2.replace(">", ">");
|
|
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("<", "<");
|
|
str2.replace(">", ">");
|
|
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) {
|
|
TQListViewItem *i = new TDEListViewItem(functionView, f->title(true).c_str());
|
|
functionItems[i] = f;
|
|
if(f == selected_function) {
|
|
functionView->setSelected(i, true);
|
|
}
|
|
}
|
|
|
|
|
|
void QalculateFunctionsDialog::categorySelected() {
|
|
TQListViewItem *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] == '/') {
|
|
std::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 {
|
|
std::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()) {
|
|
TQListViewItemIterator it(functionView);
|
|
if(it.current())
|
|
functionView->setSelected(it.current(), true);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
#include "qalculatefunctionsdialog.moc"
|