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

qalculateeditunitdialog.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 "qalculateeditunitdialog.h"
#include "qalculate_kde_utils.h"
#include "qalculateeditnamesdialog.h"

#include <qgrid.h>
#include <klineedit.h>
#include <qpushbutton.h>
#include <kcombobox.h>
#include <qlabel.h>
#include <klocale.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qcheckbox.h>
#include <kmessagebox.h>
#include <qgroupbox.h>
#include <qspinbox.h>
#include <qlayout.h>
#include <kapplication.h>

extern PrintOptions printops;
extern tree_struct unit_cats;

QalculateEditUnitDialog::QalculateEditUnitDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Unit"), Ok | Cancel | Help, Ok, true) {

      names_edit_dialog = NULL;
      edited_unit = NULL;

      QVBox *box = makeVBoxMainWidget();

      grid1 = new QGroupBox(1, Qt::Horizontal, i18n("Name"), box);
      grid1->setInsideMargin(spacingHint());
      grid1->setInsideSpacing(spacingHint());
      QWidget *widget = new QWidget(grid1);
      QGridLayout *grid = new QGridLayout(widget, 1, 1, 0, spacingHint());
      grid->addWidget(new QLabel(i18n("Name:"), widget), 0, 0);
      nameEdit = new KLineEdit(widget);
      grid->addWidget(nameEdit, 0, 1);
      QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
      grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
      namesLabel = new QLabel(widget);
      namesLabel->setAlignment(Qt::AlignRight);
      namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
      hbox->addWidget(namesLabel);
      namesButton = new QPushButton(i18n("Names Details"), widget);
      hbox->addWidget(namesButton);
      grid->addWidget(new QLabel(i18n("Descriptive name:"), widget), 2, 0);
      titleEdit = new KLineEdit(widget);
      grid->addWidget(titleEdit, 2, 1);
      hbox = new QHBoxLayout(0, 0, spacingHint());
      grid->addMultiCellLayout(hbox, 3, 3, 0, 1);
      hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
      hideButton = new QCheckBox(i18n("Hide unit"), widget);
      hbox->addWidget(hideButton);

      grid2 = new QGroupBox(1, Qt::Horizontal, i18n("Type"), box);
      grid2->setInsideMargin(spacingHint());
      grid2->setInsideSpacing(spacingHint());
      widget = new QWidget(grid2);
      grid = new QGridLayout(widget, 1, 1, 0, spacingHint());
      grid->addWidget(new QLabel(i18n("Class:"), widget), 0, 0);
      classCombo = new KComboBox(widget);
      grid->addWidget(classCombo, 0, 1);
      classCombo->insertItem(i18n("Base Unit"));
      classCombo->insertItem(i18n("Alias"));
      classCombo->insertItem(i18n("Composite Unit"));
      classCombo->setMaximumWidth(250);
      grid->addWidget(new QLabel(i18n("Category:"), widget), 1, 0);
      categoryCombo = new KComboBox(widget);
      grid->addWidget(categoryCombo, 1, 1);
      categoryCombo->setMaximumWidth(250);
      categoryCombo->setEditable(true);
      grid->addWidget(new QLabel(i18n("System:"), widget), 2, 0);
      systemCombo = new KComboBox(widget);
      grid->addWidget(systemCombo, 2, 1);
      systemCombo->insertItem(i18n("SI"));
      systemCombo->insertItem(i18n("CGS"));
      systemCombo->insertItem(i18n("Imperial"));
      systemCombo->insertItem(i18n("US Survey"));
      systemCombo->setMaximumWidth(250);
      systemCombo->setEditable(true);

      grid3 = new QGroupBox(1, Qt::Horizontal, i18n("Relation"), box);
      grid3->setInsideMargin(spacingHint());
      grid3->setInsideSpacing(spacingHint());
      widget = new QWidget(grid3);
      grid = new QGridLayout(widget, 1, 1, 0, spacingHint());
      grid->addWidget(new QLabel(i18n("Base unit:"), widget), 0, 0);
      baseEdit = new KLineEdit(widget);
      grid->addWidget(baseEdit, 0, 1);
      exponentLabel = new QLabel(i18n("Exponent:"), widget);
      grid->addWidget(exponentLabel, 1, 0);
      exponentBox = new QSpinBox(-9, 9, 1, widget);
      grid->addWidget(exponentBox, 1, 1);
      relationLabel = new QLabel(i18n("Relation:"), widget);
      grid->addWidget(relationLabel, 2, 0);
      relationEdit = new KLineEdit(widget);
      grid->addWidget(relationEdit, 2, 1);
      hbox = new QHBoxLayout(0, 0, spacingHint());
      grid->addMultiCellLayout(hbox, 3, 3, 0, 1);
      hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
      relationExactButton = new QCheckBox(i18n("Relation is exact"), widget);
      hbox->addWidget(relationExactButton);
      reversedRelationLabel = new QLabel(i18n("Reversed relation:"), widget);
      grid->addWidget(reversedRelationLabel, 4, 0);
      reversedRelationEdit = new KLineEdit(widget);
      grid->addWidget(reversedRelationEdit, 4, 1);

      connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
      connect(classCombo, SIGNAL(activated(int)), this, SLOT(classChanged(int)));
      connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
      
}

QalculateEditUnitDialog::~QalculateEditUnitDialog() {}

void QalculateEditUnitDialog::slotHelp() {
      KApplication::kApplication()->invokeHelp("qalculate-unit-creation");
}
void QalculateEditUnitDialog::slotOk() {

      string str = nameEdit->text().ascii();
      remove_blank_ends(str);
      if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
            //no name -- open dialog again
            KMessageBox::error(this, i18n("Empty name field"));
            return;
      }
      //unit with the same name exists -- overwrite or open dialog again
      if((!edited_unit || !edited_unit->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->unitNameTaken(str, edited_unit) && KMessageBox::questionYesNo(this, i18n("A variable or unit with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
            return;
      }
      
      Unit *u = edited_unit;
            
      bool add_unit = false;
      if(u) {
            //edited an existing unit -- update unit
            u->setLocal(true);
            int i1 = classCombo->currentItem();
            switch(u->subtype()) {
                  case SUBTYPE_ALIAS_UNIT: {
                        if(i1 != 1) {
                              u->destroy();
                              u = NULL;
                              break;
                        }
                        if(!u->isBuiltin()) {
                              AliasUnit *au = (AliasUnit*) u;
                              Unit *bu = CALCULATOR->getUnit(baseEdit->text().ascii());
                              if(!bu) bu = CALCULATOR->getCompositeUnit(baseEdit->text().ascii());
                              if(!bu) {
                                    KMessageBox::error(this, i18n("Base unit does not exist"));
                                    return;
                              }
                              au->setBaseUnit(bu);
                              au->setExpression(CALCULATOR->unlocalizeExpression(relationEdit->text().ascii()));
                              au->setReverseExpression(CALCULATOR->unlocalizeExpression(reversedRelationEdit->text().ascii()));
                              au->setExponent(exponentBox->value());
                              au->setApproximate(!relationExactButton->isChecked());
                        }
                        break;
                  }
                  case SUBTYPE_COMPOSITE_UNIT: {
                        if(i1 != 2) {
                              u->destroy();
                              u = NULL;
                              break;
                        }
                        if(!u->isBuiltin()) {
                              ((CompositeUnit*) u)->setBaseExpression(baseEdit->text().ascii());
                        }
                        break;
                  }
                  case SUBTYPE_BASE_UNIT: {
                        if(i1 != 0) {
                              u->destroy();
                              u = NULL;
                              break;
                        }
                        break;
                  }
            }
            if(u) {
                  u->setTitle(titleEdit->text().ascii());
                  u->setCategory(categoryCombo->lineEdit()->text().ascii());
            }
      }
      if(!u) {
            //new unit
            switch(classCombo->currentItem()) {
                  case 1: {
                        Unit *bu = CALCULATOR->getUnit(baseEdit->text().ascii());
                        if(!bu) bu = CALCULATOR->getCompositeUnit(baseEdit->text().ascii());
                        if(!bu) {
                              KMessageBox::error(this, i18n("Base unit does not exist"));
                              return;
                        }
                        u = new AliasUnit(categoryCombo->lineEdit()->text().ascii(), "", "", "", titleEdit->text().ascii(), bu, CALCULATOR->unlocalizeExpression(relationEdit->text().ascii()), exponentBox->value(), CALCULATOR->unlocalizeExpression(reversedRelationEdit->text().ascii()), true);
                        ((AliasUnit*) u)->setApproximate(!relationExactButton->isChecked());
                        break;
                  }
                  case 2: {
                        CompositeUnit *cu = new CompositeUnit(categoryCombo->lineEdit()->text().ascii(), "", titleEdit->text().ascii(), baseEdit->text().ascii(), true);
                        u = cu;
                        break;
                  }
                  default: {
                        u = new Unit(categoryCombo->lineEdit()->text().ascii(), "", "", "", titleEdit->text().ascii(), true);
                        break;
                  }
            }
            add_unit = true;
      }
      if(u) {
            u->setHidden(hideButton->isChecked());
            if(!u->isBuiltin()) {
                  u->setSystem(systemCombo->lineEdit()->text().ascii());
                  if(names_edit_dialog) {
                        names_edit_dialog->saveNames(u, str.c_str());
                  } else {
                        if(u->countNames() == 0) {
                              ExpressionName ename(str);
                              ename.reference = true;
                              u->setName(ename, 1);
                        } else {
                              u->setName(str, 1);
                        }
                  }
            }
            if(add_unit) {
                  CALCULATOR->addUnit(u);
            }
      }
      edited_unit = u;
      
      accept();
      
}


void QalculateEditUnitDialog::classChanged(int i) {
      exponentBox->setEnabled(i == 1);
      relationEdit->setEnabled(i == 1);
      relationExactButton->setEnabled(i == 1);
      reversedRelationEdit->setEnabled(i == 1);
      exponentLabel->setEnabled(i == 1);
      relationLabel->setEnabled(i == 1);
      reversedRelationLabel->setEnabled(i == 1);
      grid3->setEnabled(i != 0);
}

Unit *QalculateEditUnitDialog::editUnit(QString category, Unit *u) {

      nameEdit->setFocus();

      if(names_edit_dialog) {
            delete names_edit_dialog;
            names_edit_dialog = NULL;
      }
      edited_unit = u;
      if(u) {
            if(u->isLocal())
                  setCaption(i18n("Edit Unit"));
            else
                  setCaption(i18n("Edit Unit (global)"));
      } else {
            setCaption(i18n("New Unit"));
      }

      //QStringList cats;
      QString catstr;
      categoryCombo->clear();
      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;
      }

      catstr = "";
      while(item) {
            if(!catstr.isEmpty()) catstr += "/";
            catstr += item->item.c_str();
            categoryCombo->insertItem(catstr);
            while(item && item->it == item->items.end()) {
                  int str_i = catstr.findRev("/");
                  if(str_i < 0) {
                        catstr = "";
                  } else {
                        catstr.truncate(str_i);
                  }
                  item = item->parent;
            }
            if(item) {
                  item2 = &*item->it;
                  ++item->it;
                  item = item2;
                  item->it = item->items.begin();     
            }
      }

      categoryCombo->lineEdit()->setText(category);
      //clear entries
      nameEdit->clear();
      titleEdit->clear();
      baseEdit->clear();
      relationEdit->clear();
      reversedRelationEdit->clear();
      systemCombo->lineEdit()->clear();
      exponentBox->setValue(1);
      namesLabel->clear();
      actionButton(Ok)->setEnabled(true);
      nameEdit->setReadOnly(u && u->isBuiltin());
      relationEdit->setReadOnly(u && u->isBuiltin());
      reversedRelationEdit->setReadOnly(u && u->isBuiltin());
      systemCombo->setEnabled(!u || !u->isBuiltin());
      classCombo->setEnabled(!u || !u->isBuiltin());
      baseEdit->setReadOnly(u && u->isBuiltin());
      if(u) {
            //fill in original parameters
            if(u->subtype() == SUBTYPE_BASE_UNIT) {
                  classCombo->setCurrentItem(0);
                  classChanged(0);
            } else if(u->subtype() == SUBTYPE_ALIAS_UNIT) {
                  classCombo->setCurrentItem(1);
                  classChanged(1);
            } else if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
                  classCombo->setCurrentItem(2);
                  classChanged(2);
            }
            
            set_name_label_and_entry(u, nameEdit, namesLabel);
            systemCombo->lineEdit()->setText(u->system().c_str());
            hideButton->setChecked(u->isHidden());
            categoryCombo->lineEdit()->setText(u->category().c_str());
            titleEdit->setText(u->title(false).c_str());
            
            switch(u->subtype()) {
                  case SUBTYPE_ALIAS_UNIT: {
                        AliasUnit *au = (AliasUnit*) u;
                        baseEdit->setText(((CompositeUnit*) (au->firstBaseUnit()))->preferredDisplayName(printops.abbreviate_names, true, false, false, &can_display_unicode_string_function, (void*) baseEdit).name.c_str());
                        exponentBox->setValue(au->firstBaseExp());
                        relationEdit->setText(CALCULATOR->localizeExpression(au->expression()).c_str());
                        reversedRelationEdit->setText(CALCULATOR->localizeExpression(au->reverseExpression()).c_str());
                        relationExactButton->setChecked(!au->isApproximate());
                        relationEdit->setEnabled(true);
                        reversedRelationEdit->setEnabled(true);
                        relationExactButton->setEnabled(!u->isBuiltin());
                        exponentBox->setEnabled(!u->isBuiltin());
                        baseEdit->setEnabled(true);
                        break;
                  }
                  case SUBTYPE_COMPOSITE_UNIT: {
                        baseEdit->setText(((CompositeUnit*) u)->print(false, printops.abbreviate_names, true, &can_display_unicode_string_function, (void*) baseEdit).c_str());
                        baseEdit->setEnabled(true);
                  }
            }
      } else {
            //default values
            hideButton->setChecked(false);
            relationExactButton->setChecked(true);
            relationEdit->setText("1");
            classCombo->setCurrentItem(1);
            classChanged(1);
      }

      if(exec() == QDialog::Accepted) {
            u = edited_unit;
            edited_unit = NULL;
            return u;
      }
      edited_unit = NULL;
      return NULL;
}

void QalculateEditUnitDialog::editNames() {
      if(!names_edit_dialog) {
            names_edit_dialog = new QalculateEditNamesDialog(TYPE_UNIT, this);
            names_edit_dialog->setNames(edited_unit, nameEdit->text(), false);
      } else {
            names_edit_dialog->setNames(edited_unit, nameEdit->text(), true);
      }
      names_edit_dialog->exec();
      names_edit_dialog->setNamesLE(nameEdit, namesLabel);
}

void QalculateEditUnitDialog::nameChanged(const QString &name) {
      if(name.isNull()) return;
      if(!CALCULATOR->unitNameIsValid(name.ascii())) {
            nameEdit->blockSignals(true);
            nameEdit->setText(CALCULATOR->convertToValidUnitName(name.ascii()).c_str());
            nameEdit->blockSignals(false);
      }
}


#include "qalculateeditunitdialog.moc"


Generated by  Doxygen 1.6.0   Back to index