lib/FormulaEdit.cpp

Go to the documentation of this file.
00001 /*
00002  *  Qtstalker stock charter
00003  *
00004  *  Copyright (C) 2001-2007 Stefan S. Stratigakos
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019  *  USA.
00020  */
00021 
00022 #include "FormulaEdit.h"
00023 #include "PrefDialog.h"
00024 #include "IndicatorPlugin.h"
00025 #include "SymbolDialog.h"
00026 #include "../pics/delete.xpm"
00027 #include "../pics/edit.xpm"
00028 #include "../pics/insert.xpm"
00029 #include "../pics/openchart.xpm"
00030 #include "../pics/include.xpm"
00031 #include <qlayout.h>
00032 #include <qfile.h>
00033 #include <qtextstream.h>
00034 #include <qdir.h>
00035 #include <qmessagebox.h>
00036 #include <qtabwidget.h>
00037 #include <qinputdialog.h>
00038 
00039 // not used #define BUTTON_SIZE 24
00040 
00041 FormulaEdit::FormulaEdit (QWidget *w, int t) : QWidget(w)
00042 {
00043   type = (FormulaEditType) t;
00044   /*  FIXME: take no effect, outdated or not yet implemented?
00045   config.getPluginList(Config::IndicatorPluginPath, functionList);
00046   */
00047 
00048   PlotLine pl;
00049   pl.getLineTypes(lineTypes);
00050   
00051   QHBoxLayout *hbox = new QHBoxLayout(this);
00052   hbox->setMargin(0);
00053   hbox->setSpacing(1);
00054 
00055   QTabWidget *tab = new QTabWidget(this);
00056   hbox->addWidget(tab);
00057 
00058   // create formula page
00059   QWidget *tw = new QWidget(this);
00060 
00061   QHBoxLayout *thbox = new QHBoxLayout(tw);
00062   thbox->setMargin(5);
00063   thbox->setSpacing(0);
00064 
00065   formula = new QTextEdit(tw);
00066   thbox->addWidget(formula);
00067 
00068   ftoolbar = new Toolbar(tw, Toolbar::Vertical);
00069   thbox->addWidget(ftoolbar);
00070 
00071   QString s = "open";
00072   QString s2 = tr("Open Rule");
00073   ftoolbar->addButton(s, openchart, s2);
00074   QObject::connect(ftoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(openRule()));
00075 
00076   s = "include";
00077   s2 = tr("Include Rule");
00078   ftoolbar->addButton(s, include, s2);
00079   QObject::connect(ftoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(includeRule()));
00080   
00081   s = "add";
00082   s2 = tr("Function Dialog");
00083   ftoolbar->addButton(s, insert, s2);
00084   QObject::connect(ftoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(functionDialog()));
00085 
00086   tab->addTab(tw, tr("Formula"));
00087 
00088   // create plot page
00089   tw = new QWidget(this);
00090 
00091   thbox = new QHBoxLayout(tw);
00092   thbox->setMargin(5);
00093   thbox->setSpacing(0);
00094 
00095   plot = new QListBox(tw);
00096   connect(plot, SIGNAL(doubleClicked(QListBoxItem *)), this, SLOT(slotDoubleClicked(QListBoxItem *)));
00097   thbox->addWidget(plot);
00098 
00099   ptoolbar = new Toolbar(tw, Toolbar::Vertical);
00100   thbox->addWidget(ptoolbar);
00101 
00102   s = "insert";
00103   s2 = tr("Insert");
00104   ptoolbar->addButton(s, insert, s2);
00105   QObject::connect(ptoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(insertPlotItem()));
00106   
00107   s = "edit";
00108   s2 = tr("Edit");
00109   ptoolbar->addButton(s, edit, s2);
00110   QObject::connect(ptoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(editPlotItem()));
00111   
00112   s = "delete";
00113   s2 = tr("Delete");
00114   ptoolbar->addButton(s, deleteitem, s2);
00115   QObject::connect(ptoolbar->getButton(s), SIGNAL(clicked()), this, SLOT(deletePlotItem()));
00116 
00117   tab->addTab(tw, tr("Plot"));
00118 }
00119 
00120 FormulaEdit::~FormulaEdit ()
00121 {
00122 }
00123 
00124 void FormulaEdit::insertPlotItem ()
00125 {
00126   QString pl = tr("Plot");
00127   QString cl = tr("Color");
00128   QString ll = tr("Label");
00129   QString ltl = tr("Line Type");
00130   QString vl = tr("Variable");
00131 
00132   PrefDialog *dialog = new PrefDialog(this);
00133   dialog->setCaption(tr("Insert Plot"));
00134   dialog->createPage (pl);
00135 
00136   QString s("Var");
00137   QStringList l;
00138   getVariableList(l, FALSE);
00139   dialog->addComboItem(vl, pl, l, 0);
00140 
00141   QColor c("red");
00142   dialog->addColorItem(cl, pl, c);
00143   s = "Label";
00144   dialog->addTextItem(ll, pl, s);
00145 
00146   dialog->addComboItem(ltl, pl, lineTypes, 4);
00147 
00148   int rc = dialog->exec();
00149   if (rc != QDialog::Accepted)
00150   {
00151     delete dialog;
00152     return;
00153   }
00154 
00155   QString ts;
00156   s = "plot (";
00157   dialog->getCombo(vl, ts);
00158   s.append(ts + ",");
00159   dialog->getColor(cl, c);
00160   s.append(c.name() + ",");
00161   dialog->getText(ll, ts);
00162   if (! ts.length())
00163     ts = " ";
00164   s.append(ts + ",");
00165   dialog->getCombo(ltl, ts);
00166   s.append(ts + ")");
00167   plot->insertItem(s, plot->currentItem() + 1);
00168 
00169   delete dialog;
00170 }
00171 
00172 void FormulaEdit::editPlotItem ()
00173 {
00174   QString s = plot->currentText();
00175   if (! s.length())
00176     return;
00177   s.remove(0, s.find("(", 0, TRUE) + 1);
00178   s.truncate(s.find(")", -1, TRUE));
00179   QStringList l = QStringList::split(",", s, FALSE);
00180   int loop;
00181   for (loop = 0; loop < (int) l.count(); loop++)
00182     l[loop] = l[loop].stripWhiteSpace();
00183 
00184   QString pl = tr("Plot");
00185   QString cl = tr("Color");
00186   QString ll = tr("Label");
00187   QString ltl = tr("Line Type");
00188   QString vl = tr("Variable");
00189 
00190   PrefDialog *dialog = new PrefDialog(this);
00191   dialog->setCaption(tr("Edit Plot"));
00192   dialog->createPage (pl);
00193 
00194   s = "Var";
00195   QStringList l2;
00196   getVariableList(l2, FALSE);
00197   dialog->addComboItem(vl, pl, l2, l[0]);
00198 
00199   QColor c(l[1]);
00200   dialog->addColorItem(cl, pl, c);
00201 
00202   dialog->addTextItem(ll, pl, l[2]);
00203 
00204   l2 = lineTypes;
00205   dialog->addComboItem(ltl, pl, l2, l[3]);
00206 
00207   int rc = dialog->exec();
00208   if (rc != QDialog::Accepted)
00209   {
00210     delete dialog;
00211     return;
00212   }
00213 
00214   QString ts;
00215   s = "plot (";
00216   dialog->getCombo(vl, ts);
00217   s.append(ts + ",");
00218   dialog->getColor(cl, c);
00219   s.append(c.name() + ",");
00220   dialog->getText(ll, ts);
00221   if (! ts.length())
00222     ts = " ";
00223   s.append(ts + ",");
00224   dialog->getCombo(ltl, ts);
00225   s.append(ts + ")");
00226   plot->changeItem(s, plot->currentItem());
00227 
00228   delete dialog;
00229 }
00230 
00231 void FormulaEdit::deletePlotItem ()
00232 {
00233   plot->removeItem(plot->currentItem());
00234 }
00235 
00236 void FormulaEdit::setLine (QString &d)
00237 {
00238   if (d.contains("script="))
00239   {
00240     QStringList l = QStringList::split("=", d, FALSE);
00241     QString k = l[0];
00242     QString s = d;
00243     s.remove(0, k.length() + 1);
00244     QStringList l2 = QStringList::split("|", s, FALSE);
00245     int loop;
00246     for (loop = 0; loop < (int) l2.count(); loop++)
00247       setLine(l2[loop]);    
00248     return;
00249   }
00250 
00251   if (d.contains(":="))
00252   {
00253     formula->append(d);
00254     return;
00255   }
00256 
00257   if (d.contains("//"))
00258   {
00259     formula->append(d);
00260     return;
00261   }
00262 
00263   if (d.contains("INCLUDECUS("))
00264   {
00265     formula->append(d);
00266     return;
00267   }
00268 
00269   if (d.contains("plot"))
00270     plot->insertItem(d, -1);
00271 }
00272 
00273 void FormulaEdit::getText (QString &s)
00274 {
00275   s = formula->text()  + "\n";
00276 
00277   int loop;
00278   for (loop = 0; loop < (int) plot->count(); loop++)
00279     s.append(plot->text(loop) + "\n");
00280 }
00281 
00282 void FormulaEdit::openRule ()
00283 {
00284   QString s("*");
00285   QString s2;
00286   config.getData(Config::IndicatorPath, s2);
00287   SymbolDialog *dialog = new SymbolDialog(this,
00288                                           s2,
00289                                           s2,
00290                                           s,
00291                                           QFileDialog::ExistingFiles);
00292   dialog->setCaption(tr("Select rule to open."));
00293 
00294   int rc = dialog->exec();
00295 
00296   if (rc != QDialog::Accepted)
00297   {
00298     delete dialog;
00299     return;
00300   }
00301 
00302   QStringList selection = dialog->selectedFile();
00303   delete dialog;
00304 
00305   if (! selection.count())
00306     return;
00307 
00308   QFile f(selection[0]);
00309   if (! f.open(IO_ReadOnly))
00310   {
00311     qDebug("FormulaEdit::openRule:can't read file %s", selection[0].latin1());
00312     return;
00313   }
00314   QTextStream stream(&f);
00315   
00316   QString script;
00317   while(stream.atEnd() == 0)
00318   {
00319     s = stream.readLine();
00320     s = s.stripWhiteSpace();
00321     if (s.contains("script="))
00322       script = s;
00323   }
00324   f.close();
00325 
00326   setLine(script);
00327 }
00328 
00329 /*
00330 void FormulaEdit::saveRule ()
00331 {
00332   if (! plot->count())
00333   {
00334     QMessageBox::information(this,
00335                              tr("Qtstalker: Error"),
00336                              tr("Plot missing."));
00337     return;
00338   }
00339 
00340   QString s("*");
00341   QString s2;
00342   config.getData(Config::IndicatorPath, s2);
00343   QString selection = QFileDialog::getSaveFileName(s2, s, this, "Save CUS Rule", "Save CUS Rule");
00344   if (! selection.length())
00345     return;
00346   
00347   while (selection.contains(" "))
00348     selection = selection.remove(selection.find(" ", 0, TRUE), 1);
00349     
00350   QDir dir;
00351   if (dir.exists(selection, TRUE))
00352   {
00353     int rc = QMessageBox::warning(this,
00354                                   tr("Qtstalker: Warning"),
00355                                   tr("Rule already exists. Do you want to replace it?"),
00356                                   QMessageBox::Yes,
00357                                   QMessageBox::No,
00358                                   QMessageBox::NoButton);
00359 
00360     if (rc == QMessageBox::No)
00361       return;
00362   }
00363   
00364   QFile f(selection);
00365   if (! f.open(IO_WriteOnly))
00366   {
00367     qDebug("FormulaEdit::saveItem:can't open file");
00368     return;
00369   }
00370   QTextStream stream(&f);
00371 
00372   int loop;
00373   for (loop = 0; loop < (int) formulaList.count(); loop++)
00374     stream << formulaList[loop] << "\n";
00375   getText(s);  
00376   stream << s << "\n";
00377 
00378   f.close(); 
00379 }
00380 */
00381 
00382 void FormulaEdit::slotDoubleClicked (QListBoxItem *)
00383 {
00384   editPlotItem();
00385 }
00386 
00387 int FormulaEdit::getLines ()
00388 {
00389   return (int) formula->lines();
00390 }
00391 
00392 void FormulaEdit::functionDialog ()
00393 {
00394   Config config;
00395   QStringList l;
00396   config.getIndicatorList(l);
00397   l.append("UTIL");
00398   l.append("SYMBOL");
00399   l.sort();
00400 
00401   bool ok;
00402   QString function = QInputDialog::getItem(QObject::tr("Indicator Selection"),
00403                                     QObject::tr("Select an indicator:"),
00404                                     l,
00405                                     0,
00406                                     TRUE,
00407                                     &ok,
00408                                     this);
00409   if (! ok)
00410     return;
00411 
00412   IndicatorPlugin *plug = config.getIndicatorPlugin(function);
00413   if (! plug)
00414   {
00415     qDebug("FormulaEdit::functionDialog:can't open %s plugin", function.latin1());
00416     return;
00417   }
00418 
00419   QString s;
00420   plug->getPluginName(s);
00421   if (! s.compare("TALIB"))
00422     plug->setFormatMethod(function);
00423 
00424   QString vname, format;
00425   QStringList vl;
00426   getVariableList(vl, TRUE);
00427   plug->formatDialog(vl, vname, format);
00428 
00429   if (! vname.length())
00430     return;
00431 
00432   if (vl.findIndex(vname) != -1)
00433   {
00434     QMessageBox::information(this, tr("Qtstalker: Error"), tr("Duplicate variable name."));
00435     return;
00436   }
00437 
00438   format.prepend(vname + " := " + function + "(");
00439   format.append(")");
00440   formula->insert(format);
00441 }
00442 
00443 void FormulaEdit::includeRule ()
00444 {
00445   QString s("*");
00446   QString s2, s3;
00447   config.getData(Config::IndicatorPath, s2);
00448   config.getData(Config::IndicatorGroup, s3);
00449   s2.append("/" + s3);
00450   SymbolDialog *dialog = new SymbolDialog(this,
00451                                           s2,
00452                                           s2,
00453                                           s,
00454                                           QFileDialog::ExistingFiles);
00455   dialog->setCaption(tr("Select rule to include"));
00456 
00457   int rc = dialog->exec();
00458 
00459   if (rc != QDialog::Accepted)
00460   {
00461     delete dialog;
00462     return;
00463   }
00464 
00465   QStringList selection = dialog->selectedFiles();
00466   delete dialog;
00467 
00468   if (! selection.count())
00469     return;
00470 
00471   QFileInfo fi(selection[0]);
00472   s = "INCLUDECUS(" + fi.fileName() + ")\n";
00473   formula->insert(s);
00474 }
00475 
00476 void FormulaEdit::getVariableList (QStringList &l, bool flag)
00477 {
00478   l.clear();
00479 
00480   if (flag)
00481   {
00482     QString s;
00483     BarData bd(s);
00484     bd.getInputFields(l);
00485   }
00486 
00487   QStringList l2 = QStringList::split("\n", formula->text(), FALSE);
00488   int loop;
00489   for (loop = 0; loop < (int) l2.count(); loop++)
00490   {
00491     if (l2[loop].contains(":="))
00492     {
00493       QStringList l3 = QStringList::split(":=", l2[loop], FALSE);
00494       l.append(l3[0].stripWhiteSpace());
00495     }
00496   }
00497 }
00498