File indexing completed on 2024-05-12 16:35:19
0001 /* This file is part of the KDE project 0002 Copyright (C) 2008-2010 Marijn Kruisselbrink <mkruisselbrink@kde.org> 0003 (C) 2002-2003 Ariya Hidayat <ariya@kde.org> 0004 (C) 2002-2003 Norbert Andres <nandres@web.de> 0005 (C) 1999-2003 Laurent Montel <montel@kde.org> 0006 (C) 2002 Philipp Mueller <philipp.mueller@gmx.de> 0007 (C) 2002 John Dailey <dailey@vt.edu> 0008 (C) 2002 Daniel Herring <herring@eecs.ku.edu> 0009 (C) 2000-2001 Werner Trobin <trobin@kde.org> 0010 (C) 1998-2000 Torben Weis <weis@kde.org> 0011 0012 This library is free software; you can redistribute it and/or 0013 modify it under the terms of the GNU Library General Public 0014 License as published by the Free Software Foundation; either 0015 version 2 of the License, or (at your option) any later version. 0016 0017 This library is distributed in the hope that it will be useful, 0018 but WITHOUT ANY WARRANTY; without even the implied warranty of 0019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0020 Library General Public License for more details. 0021 0022 You should have received a copy of the GNU Library General Public License 0023 along with this library; see the file COPYING.LIB. If not, write to 0024 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0025 Boston, MA 02110-1301, USA. 0026 */ 0027 0028 // Local 0029 #include "FormulaDialog.h" 0030 0031 #include <QTabWidget> 0032 #include <QApplication> 0033 #include <QCloseEvent> 0034 #include <QGridLayout> 0035 #include <QVBoxLayout> 0036 0037 #include "CalculationSettings.h" 0038 #include "Cell.h" 0039 #include "Function.h" 0040 #include "FunctionDescription.h" 0041 #include "FunctionRepository.h" 0042 #include "Util.h" 0043 #include "ui/CellEditor.h" 0044 #include "Localization.h" 0045 #include "Map.h" 0046 #include "ui/Selection.h" 0047 #include "Sheet.h" 0048 #include "SheetsDebug.h" 0049 0050 #include <KoIcon.h> 0051 0052 #include <kcombobox.h> 0053 #include <klineedit.h> 0054 0055 #include <QDoubleValidator> 0056 #include <QEvent> 0057 #include <QTextBrowser> 0058 #include <QLabel> 0059 #include <QPushButton> 0060 #include <QLayout> 0061 #include <QStringListModel> 0062 #include <QSortFilterProxyModel> 0063 #include <QItemSelectionModel> 0064 0065 using namespace Calligra::Sheets; 0066 0067 FormulaDialog::FormulaDialog(QWidget* parent, Selection* selection, CellEditorBase* editor, const QString& formulaName) 0068 : KoDialog(parent) 0069 { 0070 setCaption(i18n("Function")); 0071 setButtons(Ok | Cancel); 0072 //setWFlags( Qt::WDestructiveClose ); 0073 0074 m_selection = selection; 0075 m_editor = editor; 0076 m_focus = 0; 0077 m_desc = 0; 0078 0079 Cell cell(m_selection->activeSheet(), m_selection->marker()); 0080 m_oldText = cell.userInput(); 0081 // Make sure that there is a cell editor running. 0082 if (cell.userInput().isEmpty()) 0083 m_editor->setText("="); 0084 else if (cell.userInput().at(0) != '=') 0085 m_editor->setText('=' + cell.userInput()); 0086 else 0087 m_editor->setText(cell.userInput()); 0088 0089 QWidget *page = new QWidget(this); 0090 setMainWidget(page); 0091 0092 QGridLayout *grid1 = new QGridLayout(page); 0093 0094 searchFunct = new KLineEdit(page); 0095 searchFunct->setClearButtonShown(true); 0096 searchFunct->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); 0097 0098 grid1->addWidget(searchFunct, 0, 0); 0099 0100 typeFunction = new KComboBox(page); 0101 QStringList cats = FunctionRepository::self()->groups(); 0102 cats.prepend(i18n("All")); 0103 typeFunction->setMaxVisibleItems(15); 0104 typeFunction->insertItems(0, cats); 0105 grid1->addWidget(typeFunction, 1, 0); 0106 0107 functions = new QListView(page); 0108 functions->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding)); 0109 functions->setSelectionMode(QAbstractItemView::SingleSelection); 0110 functions->setEditTriggers(QAbstractItemView::NoEditTriggers); 0111 grid1->addWidget(functions, 2, 0); 0112 0113 functionsModel = new QStringListModel(this); 0114 proxyModel = new QSortFilterProxyModel(functions); 0115 proxyModel->setSourceModel(functionsModel); 0116 proxyModel->setFilterKeyColumn(0); 0117 proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); 0118 functions->setModel(proxyModel); 0119 0120 QItemSelectionModel* selectionmodel = new QItemSelectionModel(proxyModel, this); 0121 functions->setSelectionModel(selectionmodel); 0122 connect(selectionmodel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), 0123 this, SLOT(slotSelected())); 0124 // When items are activated on single click, also change the help page on mouse-over, otherwise there is no (easy) way to get 0125 // the help without inserting the function 0126 if (functions->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, functions)) { 0127 connect(functions, SIGNAL(entered(QModelIndex)), this, SLOT(slotIndexSelected(QModelIndex))); 0128 functions->setMouseTracking(true); 0129 } 0130 //connect(proxyModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(slotDataChanged(QModelIndex,QModelIndex))); 0131 0132 selectFunction = new QPushButton(page); 0133 selectFunction->setToolTip(i18n("Insert function")); 0134 selectFunction->setIcon(koIcon("go-down")); 0135 grid1->addWidget(selectFunction, 3, 0); 0136 0137 result = new KLineEdit(page); 0138 grid1->addWidget(result, 4, 0, 1, -1); 0139 0140 m_tabwidget = new QTabWidget(page); 0141 m_tabwidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); 0142 grid1->addWidget(m_tabwidget, 0, 1, 4, 1); 0143 0144 m_browser = new QTextBrowser(m_tabwidget); 0145 m_browser->document()->setDefaultStyleSheet("h1 { font-size:x-large; } h2 { font-size:large; } h3 { font-size:medium; }"); 0146 m_browser->setMinimumWidth(300); 0147 0148 m_tabwidget->addTab(m_browser, i18n("Help")); 0149 int index = m_tabwidget->currentIndex(); 0150 0151 m_input = new QWidget(m_tabwidget); 0152 QVBoxLayout *grid2 = new QVBoxLayout(m_input); 0153 0154 // grid2->setResizeMode (QLayout::Minimum); 0155 0156 label1 = new QLabel(m_input); 0157 grid2->addWidget(label1); 0158 0159 firstElement = new KLineEdit(m_input); 0160 grid2->addWidget(firstElement); 0161 0162 label2 = new QLabel(m_input); 0163 grid2->addWidget(label2); 0164 0165 secondElement = new KLineEdit(m_input); 0166 grid2->addWidget(secondElement); 0167 0168 label3 = new QLabel(m_input); 0169 grid2->addWidget(label3); 0170 0171 thirdElement = new KLineEdit(m_input); 0172 grid2->addWidget(thirdElement); 0173 0174 label4 = new QLabel(m_input); 0175 grid2->addWidget(label4); 0176 0177 fourElement = new KLineEdit(m_input); 0178 grid2->addWidget(fourElement); 0179 0180 label5 = new QLabel(m_input); 0181 grid2->addWidget(label5); 0182 0183 fiveElement = new KLineEdit(m_input); 0184 grid2->addWidget(fiveElement); 0185 0186 grid2->addStretch(10); 0187 0188 m_tabwidget->addTab(m_input, i18n("Parameters")); 0189 m_tabwidget->setTabEnabled(m_tabwidget->indexOf(m_input), false); 0190 0191 m_tabwidget->setCurrentIndex(index); 0192 0193 refresh_result = true; 0194 0195 connect(this, SIGNAL(cancelClicked()), this, SLOT(slotClose())); 0196 connect(this, SIGNAL(okClicked()), this, SLOT(slotOk())); 0197 connect(typeFunction, SIGNAL(activated(QString)), 0198 this, SLOT(slotActivated(QString))); 0199 /* 0200 connect( functions, SIGNAL(highlighted(QString)), 0201 this, SLOT(slotSelected(QString)) ); 0202 connect( functions, SIGNAL(selected(QString)), 0203 this, SLOT(slotSelected(QString)) ); 0204 */ 0205 connect(functions, SIGNAL(activated(QModelIndex)), 0206 this , SLOT(slotDoubleClicked(QModelIndex))); 0207 0208 slotActivated(i18n("All")); 0209 0210 connect(selectFunction, SIGNAL(clicked()), 0211 this, SLOT(slotSelectButton())); 0212 0213 connect(firstElement, SIGNAL(textChanged(QString)), 0214 this, SLOT(slotChangeText(QString))); 0215 connect(secondElement, SIGNAL(textChanged(QString)), 0216 this, SLOT(slotChangeText(QString))); 0217 connect(thirdElement, SIGNAL(textChanged(QString)), 0218 this, SLOT(slotChangeText(QString))); 0219 connect(fourElement, SIGNAL(textChanged(QString)), 0220 this, SLOT(slotChangeText(QString))); 0221 connect(fiveElement, SIGNAL(textChanged(QString)), 0222 this, SLOT(slotChangeText(QString))); 0223 0224 connect(m_selection, SIGNAL(changed(Region)), 0225 this, SLOT(slotSelectionChanged())); 0226 0227 connect(m_browser, SIGNAL(anchorClicked(QUrl)), 0228 this, SLOT(slotShowFunction(QUrl))); 0229 0230 // Save the name of the active sheet. 0231 m_sheetName = m_selection->activeSheet()->sheetName(); 0232 // Save the cells current text. 0233 QString tmp_oldText = m_editor->toPlainText(); 0234 // Position of the cell. 0235 m_column = m_selection->marker().x(); 0236 m_row = m_selection->marker().y(); 0237 0238 if (tmp_oldText.isEmpty()) 0239 result->setText("="); 0240 else { 0241 if (tmp_oldText.at(0) != '=') 0242 result->setText('=' + tmp_oldText); 0243 else 0244 result->setText(tmp_oldText); 0245 } 0246 0247 // Allow the user to select cells on the spreadsheet. 0248 m_selection->startReferenceSelection(); 0249 0250 qApp->installEventFilter(this); 0251 0252 // Was a function name passed along with the constructor ? Then activate it. 0253 if (!formulaName.isEmpty()) { 0254 debugSheets << "formulaName=" << formulaName; 0255 #if 0 0256 QList<QListWidgetItem *> items = functions->findItems(formulaName, Qt::MatchFixedString); 0257 if (items.count() > 0) { 0258 functions->setCurrentItem(items[0]); 0259 slotDoubleClicked(items[0]); 0260 } 0261 #else 0262 int row = functionsModel->stringList().indexOf(formulaName); 0263 const QModelIndex sourcemodelindex = functionsModel->index(row, 0); 0264 const QModelIndex proxymodelindex = proxyModel->mapFromSource(sourcemodelindex); 0265 if (proxymodelindex.isValid()) { 0266 functions->setCurrentIndex(proxymodelindex); 0267 slotDoubleClicked(proxymodelindex); 0268 } 0269 #endif 0270 } else { 0271 // Set keyboard focus to allow selection of a formula. 0272 searchFunct->setFocus(); 0273 } 0274 0275 // Add auto completion. 0276 searchFunct->setCompletionMode(KCompletion::CompletionAuto); 0277 searchFunct->setCompletionObject(&listFunct, true); 0278 0279 if (functions->currentIndex().isValid()) 0280 selectFunction->setEnabled(false); 0281 0282 connect(searchFunct, SIGNAL(textChanged(QString)), 0283 this, SLOT(slotSearchText(QString))); 0284 connect(searchFunct, SIGNAL(returnPressed()), 0285 this, SLOT(slotPressReturn())); 0286 0287 resize(QSize(660, 520).expandedTo(minimumSizeHint())); 0288 } 0289 0290 FormulaDialog::~FormulaDialog() 0291 { 0292 debugSheets << "FormulaDialog::~FormulaDialog()"; 0293 } 0294 0295 void FormulaDialog::slotPressReturn() 0296 { 0297 //laurent 2001-07-07 desactivate this code 0298 //because Calligra Sheets crash. 0299 //TODO fix it 0300 /* 0301 if( !functions->currentText().isEmpty() ) 0302 slotDoubleClicked( functions->findItem( functions->currentText() ) ); 0303 */ 0304 } 0305 0306 void FormulaDialog::slotSearchText(const QString &_text) 0307 { 0308 proxyModel->setFilterFixedString(_text); 0309 if (functions->currentIndex().isValid()) 0310 functions->scrollTo(functions->currentIndex()); 0311 } 0312 0313 bool FormulaDialog::eventFilter(QObject* obj, QEvent* ev) 0314 { 0315 if (obj == firstElement && ev->type() == QEvent::FocusIn) 0316 m_focus = firstElement; 0317 else if (obj == secondElement && ev->type() == QEvent::FocusIn) 0318 m_focus = secondElement; 0319 else if (obj == thirdElement && ev->type() == QEvent::FocusIn) 0320 m_focus = thirdElement; 0321 else if (obj == fourElement && ev->type() == QEvent::FocusIn) 0322 m_focus = fourElement; 0323 else if (obj == fiveElement && ev->type() == QEvent::FocusIn) 0324 m_focus = fiveElement; 0325 else 0326 return false; 0327 0328 if (m_focus) 0329 m_selection->startReferenceSelection(); 0330 0331 return false; 0332 } 0333 0334 void FormulaDialog::slotOk() 0335 { 0336 // Pretend none of the text edits have focus; otherwise the next line will change the 0337 // value of whatever parameter has focus to the name of the cell we're editing 0338 m_focus = 0; 0339 0340 m_selection->endReferenceSelection(); 0341 0342 // Revert the marker to its original position 0343 m_selection->initialize(QPoint(m_column, m_row)); 0344 0345 // If there is still an editor then set the text. 0346 // Usually the editor is always in place. 0347 if (m_editor != 0) { 0348 Q_ASSERT(m_editor); 0349 QString tmp = result->text(); 0350 if (tmp.at(0) != '=') 0351 tmp = '=' + tmp; 0352 int pos = m_editor->cursorPosition() + tmp.length(); 0353 m_editor->setText(tmp); 0354 m_editor->widget()->setFocus(); 0355 m_editor->setCursorPosition(pos); 0356 } 0357 0358 m_selection->emitModified(); 0359 accept(); 0360 deleteLater(); 0361 } 0362 0363 void FormulaDialog::slotClose() 0364 { 0365 deleteLater(); 0366 0367 m_selection->endReferenceSelection(); 0368 0369 // Revert the marker to its original position 0370 m_selection->initialize(QPoint(m_column, m_row)); 0371 0372 // If there is still an editor then reset the text. 0373 // Usually the editor is always in place. 0374 if (m_editor != 0) { 0375 Q_ASSERT(m_editor); 0376 m_editor->setText(m_oldText); 0377 m_editor->widget()->setFocus(); 0378 } 0379 0380 m_selection->emitModified(); 0381 reject(); 0382 } 0383 0384 void FormulaDialog::slotSelectButton() 0385 { 0386 if (functions->currentIndex().isValid()) { 0387 //slotDoubleClicked(functions->findItem(functions->text(functions->currentItem()))); 0388 slotDoubleClicked(functions->currentIndex()); 0389 } 0390 } 0391 0392 void FormulaDialog::slotChangeText(const QString&) 0393 { 0394 // Test the lock 0395 if (!refresh_result) 0396 return; 0397 0398 if (m_focus == 0) 0399 return; 0400 0401 QString tmp = m_leftText + m_funcName + '(' + createFormula() + ')' + m_rightText; 0402 0403 result->setText(tmp); 0404 } 0405 0406 QString FormulaDialog::createFormula() 0407 { 0408 QString tmp(""); 0409 0410 if (!m_desc) 0411 return QString(); 0412 0413 bool first = true; 0414 0415 int count = m_desc->params(); 0416 0417 if (!firstElement->text().isEmpty() && count >= 1) { 0418 tmp = tmp + createParameter(firstElement->text(), 0); 0419 first = false; 0420 } 0421 0422 if (!secondElement->text().isEmpty() && count >= 2) { 0423 first = false; 0424 if (!first) 0425 tmp = tmp + ';' + createParameter(secondElement->text(), 1); 0426 else 0427 tmp = tmp + createParameter(secondElement->text(), 1); 0428 } 0429 if (!thirdElement->text().isEmpty() && count >= 3) { 0430 first = false; 0431 if (!first) 0432 tmp = tmp + ';' + createParameter(thirdElement->text(), 2); 0433 else 0434 tmp = tmp + createParameter(thirdElement->text(), 2); 0435 } 0436 if (!fourElement->text().isEmpty() && count >= 4) { 0437 first = false; 0438 if (!first) 0439 tmp = tmp + ';' + createParameter(fourElement->text(), 3); 0440 else 0441 tmp = tmp + createParameter(fourElement->text(), 3); 0442 } 0443 if (!fiveElement->text().isEmpty() && count >= 5) { 0444 first = false; 0445 if (!first) 0446 tmp = tmp + ';' + createParameter(fiveElement->text(), 4); 0447 else 0448 tmp = tmp + createParameter(fiveElement->text(), 4); 0449 } 0450 0451 return(tmp); 0452 } 0453 0454 QString FormulaDialog::createParameter(const QString& _text, int param) 0455 { 0456 if (_text.isEmpty()) 0457 return QString(""); 0458 0459 if (!m_desc) 0460 return QString(""); 0461 0462 QString text; 0463 0464 ParameterType elementType = m_desc->param(param).type(); 0465 0466 switch (elementType) { 0467 case KSpread_Any: { 0468 bool isNumber; 0469 double tmp = m_selection->activeSheet()->map()->calculationSettings()->locale()->readNumber(_text, &isNumber); 0470 Q_UNUSED(tmp); 0471 0472 //In case of number or boolean return _text, else return value as KSpread_String 0473 if (isNumber || _text.toUpper() == "FALSE" || _text.toUpper() == "TRUE") 0474 return _text; 0475 } 0476 // fall through 0477 case KSpread_String: { 0478 // Does the text start with quotes? 0479 if (_text[0] == '"') { 0480 text = '\\'; // changed: was '"' 0481 0482 // Escape quotes 0483 QString tmp = _text; 0484 int pos; 0485 int start = 1; 0486 while ((pos = tmp.indexOf('"', start)) != -1) { 0487 if (tmp[pos - 1] != '\\') 0488 tmp.replace(pos, 1, "\\\""); 0489 else 0490 start = pos + 1; 0491 } 0492 0493 text += tmp; 0494 text += '"'; 0495 } else { 0496 const Region region(_text, m_selection->activeSheet()->map()); 0497 if (!region.isValid()) { 0498 text = '"'; 0499 0500 // Escape quotes 0501 QString tmp = _text; 0502 int pos; 0503 int start = 1; 0504 while ((pos = tmp.indexOf('"', start)) != -1) { 0505 if (tmp[pos - 1] != '\\') 0506 tmp.replace(pos, 1, "\\\""); 0507 else 0508 start = pos + 1; 0509 } 0510 0511 text += tmp; 0512 text += '"'; 0513 } else 0514 text = _text; 0515 } 0516 } 0517 return text; 0518 case KSpread_Float: 0519 return _text; 0520 case KSpread_Boolean: 0521 return _text; 0522 case KSpread_Int: 0523 return _text; 0524 case KSpread_Date: 0525 return _text; 0526 } 0527 0528 // Never reached 0529 return text; 0530 } 0531 0532 static void showEntry(KLineEdit* edit, QLabel* label, 0533 FunctionDescription* desc, int param) 0534 { 0535 edit->show(); 0536 label->setText(desc->param(param).helpText() + ':'); 0537 label->show(); 0538 ParameterType elementType = desc->param(param).type(); 0539 switch (elementType) { 0540 case KSpread_String: 0541 case KSpread_Boolean: 0542 case KSpread_Any: 0543 case KSpread_Date: 0544 edit->setValidator(0); 0545 break; 0546 case KSpread_Float: 0547 edit->setValidator(new QDoubleValidator(edit)); 0548 edit->setText("0"); 0549 break; 0550 case KSpread_Int: 0551 edit->setValidator(new QIntValidator(edit)); 0552 edit->setText("0"); 0553 break; 0554 } 0555 0556 0557 0558 } 0559 0560 void FormulaDialog::slotDoubleClicked(QModelIndex item) 0561 { 0562 if (!item.isValid()) { 0563 item = functions->currentIndex(); 0564 if (!item.isValid()) 0565 return; 0566 } 0567 refresh_result = false; 0568 if (!m_desc) { 0569 m_browser->setText(""); 0570 return; 0571 } 0572 0573 m_focus = 0; 0574 int old_length = result->text().length(); 0575 0576 // Do not change order of these function calls due to a bug in Qt 2.2 0577 m_browser->setText(m_desc->toQML()); 0578 m_tabwidget->setTabEnabled(m_tabwidget->indexOf(m_input), true); 0579 m_tabwidget->setCurrentIndex(1); 0580 0581 // 0582 // Show as many KLineEdits as needed. 0583 // 0584 if (m_desc->params() > 0) { 0585 m_focus = firstElement; 0586 firstElement->setFocus(); 0587 0588 showEntry(firstElement, label1, m_desc, 0); 0589 } else { 0590 label1->hide(); 0591 firstElement->hide(); 0592 } 0593 0594 if (m_desc->params() > 1) { 0595 showEntry(secondElement, label2, m_desc, 1); 0596 } else { 0597 label2->hide(); 0598 secondElement->hide(); 0599 } 0600 0601 if (m_desc->params() > 2) { 0602 showEntry(thirdElement, label3, m_desc, 2); 0603 } else { 0604 label3->hide(); 0605 thirdElement->hide(); 0606 } 0607 0608 if (m_desc->params() > 3) { 0609 showEntry(fourElement, label4, m_desc, 3); 0610 } else { 0611 label4->hide(); 0612 fourElement->hide(); 0613 } 0614 0615 if (m_desc->params() > 4) { 0616 showEntry(fiveElement, label5, m_desc, 4); 0617 } else { 0618 label5->hide(); 0619 fiveElement->hide(); 0620 } 0621 0622 if (m_desc->params() > 5) 0623 debugSheets << "Error in param->nb_param"; 0624 refresh_result = true; 0625 0626 // 0627 // Put the new function call in the result. 0628 // 0629 if (result->cursorPosition() < old_length) { 0630 m_rightText = result->text().right(old_length - result->cursorPosition()); 0631 m_leftText = result->text().left(result->cursorPosition()); 0632 } else { 0633 m_rightText.clear(); 0634 m_leftText = result->text(); 0635 } 0636 0637 int pos = result->cursorPosition(); 0638 0639 { 0640 const QString text = proxyModel->data(functions->currentIndex()).toString(); 0641 result->setText(m_leftText + text + "()" + m_rightText); 0642 if (result->text()[0] != '=') 0643 result->setText('=' + result->text()); 0644 } 0645 0646 // 0647 // Put focus somewhere is there are no KLineEdits visible 0648 // 0649 if (m_desc->params() == 0) { 0650 label1->show(); 0651 label1->setText(i18n("This function has no parameters.")); 0652 result->setFocus(); 0653 const QString text = proxyModel->data(functions->currentIndex()).toString(); 0654 result->setCursorPosition(pos + text.length() + 2); 0655 } 0656 slotChangeText(""); 0657 } 0658 0659 void FormulaDialog::slotIndexSelected(const QModelIndex& index) 0660 { 0661 // This slot is only called when single-click to activate is uesd in the listbox, when the mouse moves over a item; to prevent 0662 // the active selection to change after the user activated one, slotSelected is only called when the current tab is the Help tab, 0663 // and not when the parameters tab is active 0664 if (m_tabwidget->currentIndex() != 0) return; 0665 QString function = proxyModel->data(index).toString(); 0666 slotSelected(function); 0667 } 0668 0669 void FormulaDialog::slotSelected(const QString& afunction) 0670 { 0671 QString function = afunction; 0672 if (function.isNull()) 0673 function = proxyModel->data(functions->currentIndex()).toString(); 0674 0675 FunctionDescription* desc = FunctionRepository::self()->functionInfo(function); 0676 if (!desc) { 0677 m_browser->setText(i18n("Description is not available.")); 0678 return; 0679 } 0680 0681 if (functions->currentIndex().isValid()) 0682 selectFunction->setEnabled(true); 0683 0684 // Lock 0685 refresh_result = false; 0686 0687 m_funcName = function; 0688 m_desc = desc; 0689 0690 // Set the help text 0691 m_browser->setText(m_desc->toQML()); 0692 //m_browser->setContentsPos( 0, 0 ); 0693 0694 m_focus = 0; 0695 0696 m_tabwidget->setCurrentIndex(0); 0697 m_tabwidget->setTabEnabled(m_tabwidget->indexOf(m_input), false); 0698 0699 // Unlock 0700 refresh_result = true; 0701 } 0702 0703 // from hyperlink in the "Related Function" 0704 void FormulaDialog::slotShowFunction(const QUrl& functionUrl) 0705 { 0706 const QString function = functionUrl.toString(); 0707 0708 FunctionDescription* desc = 0709 FunctionRepository::self()->functionInfo(function); 0710 if (!desc) return; 0711 0712 // select the category 0713 QString category = desc->group(); 0714 typeFunction->setCurrentIndex(typeFunction->findText(category)); 0715 slotActivated(category); 0716 0717 // select the function 0718 int row = functionsModel->stringList().indexOf(function); 0719 const QModelIndex sourcemodelindex = functionsModel->index(row, 0); 0720 const QModelIndex proxymodelindex = proxyModel->mapFromSource(sourcemodelindex); 0721 if (proxymodelindex.isValid()) 0722 functions->setCurrentIndex(proxymodelindex); 0723 0724 slotSelected(function); 0725 } 0726 0727 void FormulaDialog::slotSelectionChanged() 0728 { 0729 if (!m_focus) 0730 return; 0731 0732 if (m_selection->isValid()) { 0733 QString area = m_selection->name(); 0734 m_focus->setText(area); 0735 } 0736 } 0737 0738 void FormulaDialog::slotActivated(const QString& category) 0739 { 0740 const QStringList lst = (category == i18n("All")) ? 0741 FunctionRepository::self()->functionNames() : FunctionRepository::self()->functionNames(category); 0742 0743 debugSheets << "category:" << category << " (" << lst.count() << "functions)"; 0744 0745 functionsModel->setStringList(lst); 0746 0747 QStringList upperList; 0748 for (QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it) 0749 upperList.append((*it).toUpper()); 0750 listFunct.setItems(upperList); 0751 0752 // Go to the first function in the list. 0753 const QString text = proxyModel->data(proxyModel->index(0, 0)).toString(); 0754 slotSelected(text); 0755 } 0756 0757 void FormulaDialog::closeEvent(QCloseEvent * e) 0758 { 0759 deleteLater(); 0760 e->accept(); 0761 }