Logo Search packages:      
Sourcecode: qalculate-kde version File versions  Download package

qalculatefunctionsdialog.cpp

/***************************************************************************
 *   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);
      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(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::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());
            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 += " (";
                              str += i18n("optional");
                              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);
            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"

Generated by  Doxygen 1.6.0   Back to index