src/Qtstalker.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           qtstalker.cpp  -  description
00003                              -------------------
00004     begin                : Thu Mar  7 22:43:41 EST 2002
00005     copyright            : (C) 2001-2008 by Stefan Stratigakos
00006     email                :
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include <qlayout.h>
00019 #include <qmessagebox.h>
00020 #include <qdir.h>
00021 #include <qfiledialog.h>
00022 #include <qinputdialog.h>
00023 #include <qapplication.h>
00024 #include <qfont.h>
00025 #include <qtextcodec.h>
00026 #include <qtranslator.h>
00027 #include <qcursor.h>
00028 #include <qcolor.h>
00029 #include <qstringlist.h>
00030 #include <qdatetime.h>
00031 
00032 #include <math.h> // only for fabs()
00033 
00034 #include "Qtstalker.h"
00035 #include "DataWindow.h"
00036 #include "ChartPage.h"
00037 #include "PlotLine.h"
00038 #include "PrefDialog.h"
00039 #include "HelpWindow.h"
00040 #include "DbPlugin.h"
00041 #include "IndicatorSummary.h"
00042 #include "Preferences.h"
00043 #include "RcFile.h"
00044 
00045 #include "../pics/qtstalker.xpm"
00046 
00047 QtstalkerApp::QtstalkerApp()
00048 {
00049   recordList = 0;
00050   status = None;
00051   plotList.setAutoDelete(FALSE);
00052   tabList.setAutoDelete(TRUE);
00053   widgetList.setAutoDelete(TRUE);
00054   setIcon(qtstalker);
00055 
00056   // setup the disk environment
00057   config.setup();
00058 
00059   // open and init the chart index
00060   QString s;
00061   chartIndex = new DBIndex;
00062   
00063   //RcFile rcfile;
00064   rcfile.loadData(RcFile::IndexPath, s);
00065   chartIndex->open(s);
00066   
00067   initMenuBar();
00068   
00069   initToolBar();
00070   
00071   statusbar = statusBar();
00072   
00073   baseWidget = new QWidget(this);
00074   setCentralWidget (baseWidget);
00075 
00076   QHBoxLayout *hbox = new QHBoxLayout(baseWidget);
00077 
00078   navSplitter = new QSplitter(baseWidget);
00079   navSplitter->setOrientation(Horizontal);
00080   hbox->addWidget(navSplitter);
00081   
00082   navBase = new QWidget(navSplitter);
00083   QVBoxLayout *vbox = new QVBoxLayout(navBase);
00084   
00085   // setup the data panel splitter
00086   dpSplitter = new QSplitter(navBase);
00087   dpSplitter->setOrientation(Vertical);
00088   vbox->addWidget(dpSplitter);
00089   
00090   // setup the side panels
00091   navTab = new NavigatorTab(dpSplitter, this);
00092   connect(navTab, SIGNAL(signalPositionChanged(int)), this, SLOT(slotNavigatorPosition(int)));
00093   connect(navTab, SIGNAL(signaVisibilityChanged(bool)), this, SLOT(slotHideNav(bool)));
00094   connect(extraToolbar, SIGNAL(recentTab(QString)), navTab, SLOT(recentTab(QString)));
00095   
00096   // setup the data panel area
00097   infoLabel = new QMultiLineEdit(dpSplitter);
00098   infoLabel->setReadOnly(TRUE);
00099 
00100   // construct the chart areas
00101   QWidget *chartBase = new QWidget(navSplitter);
00102 
00103   vbox = new QVBoxLayout(chartBase);
00104 
00105   split = new QSplitter(chartBase);
00106   split->setOrientation(Vertical);
00107   vbox->addWidget(split);
00108 
00109   // build the tab rows
00110   int loop;
00111   for (loop = 0; loop < 3; loop++)
00112   {
00113     QTabWidget *it = new QTabWidget(split);
00114  //FIXME: Use setMargin(), otherwise uses default value 10 on some systems
00115  // use setContentsMargins() with Qt4
00116  //   it->setMargin(2);
00117     connect(it, SIGNAL(currentChanged(QWidget *)), this, SLOT(slotDrawPlots()));
00118     tabList.append(it);
00119     it->hide();
00120   }
00121     
00122   // create the side panels
00123   initChartNav();
00124   initGroupNav();
00125   initIndicatorNav();
00126   initPortfolioNav();
00127   initTestNav();
00128   initScannerNav();  
00129   // aktivate last settings
00130   navTab->init();
00131 
00132   // restore the last used indicators
00133   rcfile.loadData(RcFile::LastIndicatorUsed, lastIndicatorUsed1, 1);
00134   rcfile.loadData(RcFile::LastIndicatorUsed, lastIndicatorUsed2, 2);
00135   rcfile.loadData(RcFile::LastIndicatorUsed, lastIndicatorUsed3, 3);
00136 
00137   // setup the initial indicators
00138   QString igroup;
00139   rcfile.loadData(RcFile::IndicatorGroup, igroup);
00140   QStringList l;
00141   config.getIndicators(igroup, l);
00142   for (loop = 0; loop < (int) l.count(); loop++)
00143     addIndicatorButton(l[loop]);
00144 
00145   // set the app font
00146   QFont font;
00147   rcfile.loadFont(RcFile::AppFont, font);
00148   slotAppFont(font);
00149 
00150   // place navigator on the last saved position
00151   navTab->loadSettings();
00152   navTab->togglePosition(navTab->getPosition());
00153  
00154   // restore the splitter sizes
00155   rcfile.loadSplitterSize(RcFile::NavAreaSize, navSplitter);
00156   slotLoadPlotSizes();
00157   rcfile.loadSplitterSize(RcFile::DataPanelSize,dpSplitter);
00158   
00159   // restore the size of the app
00160   QSize sz;
00161   rcfile.loadSize(RcFile::MainWindowSize, sz);
00162   resize(sz);
00163   
00164   // restore the position of the app
00165   QPoint p;
00166   rcfile.loadPoint(RcFile::MainWindowPos, p);
00167   move(p);
00168   
00169   // setup the indicator page  
00170   ip->updateList();
00171   
00172   // catch any kill signals and try to save config
00173   connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(slotQuit()));
00174   
00175   progBar = new QProgressBar(this);
00176   statusbar->addWidget(progBar, 0, TRUE);
00177   progBar->setMaximumHeight(progBar->height() - 10);
00178 
00179   statusbar->message(tr("Ready"), 2000);
00180 }
00181 
00182 QtstalkerApp::~QtstalkerApp()
00183 {
00184 }
00185 
00186 void QtstalkerApp::initMenuBar()
00187 {
00188   // create the main menubar
00189   menubar = new MainMenubar(this);
00190   connect(menubar, SIGNAL(signalExit()), qApp, SLOT(quit()));
00191   connect(menubar, SIGNAL(signalSidePanel(bool)), this, SLOT(slotHideNav(bool)));
00192   connect(menubar, SIGNAL(signalOptions()), this, SLOT(slotOptions()));
00193   connect(menubar, SIGNAL(signalQuotes()), this, SLOT(slotQuotes()));
00194   connect(menubar, SIGNAL(signalCrosshairs(bool)), this, SLOT(slotCrosshairsStatus(bool)));
00195   connect(menubar, SIGNAL(signalPaperTrade(bool)), this, SLOT(slotPaperTradeChanged(bool)));
00196 }
00197 
00198 void QtstalkerApp::initToolBar()
00199 {
00200   // construct the button toolbar
00201   toolbar = new QToolBar(this, "buttonToolbar");
00202   toolbar->setLabel("Main Toolbar");
00203   slotLoadMainToolbarSettings();
00204 
00205   // construct the chart toolbar
00206   toolbar2 = new ChartToolbar(this);
00207   toolbar2->setLabel("Chart Toolbar");
00208   toolbar2->slotSetButtonView();
00209   connect(toolbar2, SIGNAL(signalBarLengthChanged(int)), this, SLOT(slotBarLengthChanged(int)));
00210   connect(toolbar2, SIGNAL(signalPixelspaceChanged(int)), this, SLOT(slotPixelspaceChanged(int)));
00211   connect(toolbar2, SIGNAL(signalBarsChanged(int)), this, SLOT(slotChartUpdated()));
00212   
00213   connect(toolbar2, SIGNAL(signalPaperTradeNextBar()), this, SLOT(slotChartUpdated()));
00214   toolbar2->paperTradeClicked(menubar->getStatus(MainMenubar::PaperTrade));
00215 
00216   connect(menubar, SIGNAL(signalAdvancePaperTrade()), toolbar2, SLOT(paperTradeNextBar()));
00217 
00218   // construct the extra toolbar
00219   extraToolbar = new ExtraToolbar(this);
00220   extraToolbar->setLabel("Extra Toolbar");
00221   extraToolbar->slotSetButtonView();
00222   connect(extraToolbar, SIGNAL(fileSelected(QString)), this, SLOT(slotOpenChart(QString)));
00223 }
00224 
00225 void QtstalkerApp::slotLoadMainToolbarSettings()
00226 {
00227   toolbar->clear();
00228   bool tb;
00229   
00230   rcfile.loadData(RcFile::ShowQuitBtn, tb);
00231   if(tb) menubar->getAction(MainMenubar::Exit)->addTo(toolbar);
00232   rcfile.loadData(RcFile::ShowPrefBtn, tb);
00233   if(tb) menubar->getAction(MainMenubar::Options)->addTo(toolbar);
00234   rcfile.loadData(RcFile::ShowSidePanelBtn, tb);
00235   if(tb) menubar->getAction(MainMenubar::SidePanel)->addTo(toolbar);
00236   rcfile.loadData(RcFile::ShowGridBtn, tb);
00237   if(tb) menubar->getAction(MainMenubar::Grid)->addTo(toolbar);
00238   rcfile.loadData(RcFile::ShowScaleToScreenBtn, tb);
00239   if(tb) menubar->getAction(MainMenubar::ScaleToScreen)->addTo(toolbar);
00240   rcfile.loadData(RcFile::ShowCrosshairBtn, tb);
00241   if(tb) menubar->getAction(MainMenubar::Crosshairs)->addTo(toolbar);
00242   rcfile.loadData(RcFile::ShowPaperTradeBtn, tb);
00243   if(tb) menubar->getAction(MainMenubar::PaperTrade)->addTo(toolbar);
00244   rcfile.loadData(RcFile::ShowDrawModeBtn, tb);
00245   if(tb) menubar->getAction(MainMenubar::DrawMode)->addTo(toolbar);
00246   rcfile.loadData(RcFile::ShowNewIndicatorBtn, tb);
00247   if(tb) menubar->getAction(MainMenubar::NewIndicator)->addTo(toolbar);
00248   rcfile.loadData(RcFile::ShowDataWindowBtn, tb);
00249   if(tb) menubar->getAction(MainMenubar::DataWindow)->addTo(toolbar);
00250   rcfile.loadData(RcFile::ShowMainQuoteBtn, tb);
00251   if(tb) menubar->getAction(MainMenubar::Quotes)->addTo(toolbar);
00252   rcfile.loadData(RcFile::ShowHelpButton, tb);
00253   if(tb) menubar->getAction(MainMenubar::Help)->addTo(toolbar);
00254 }
00255 
00256 void QtstalkerApp::slotQuit()
00257 {
00258   // do this to save any pending chart object edits
00259   QDictIterator<Plot> it(plotList);
00260   for(; it.current(); ++it)
00261     it.current()->clear();
00262 
00263   // save last indicators used
00264   int loop;
00265   for (loop = 0; loop < (int) tabList.count(); loop++)
00266   {
00267     QTabWidget *tw = tabList.at(loop);
00268     QString s = tw->label(tw->currentPageIndex());
00269     rcfile.saveData(RcFile::LastIndicatorUsed, s, loop+1);
00270   }
00271 
00272   // save window sizes 
00273   //RcFile rcfile;
00274   slotSavePlotSizes();
00275   rcfile.saveSplitterSize(RcFile::DataPanelSize, dpSplitter);
00276   rcfile.saveSplitterSize(RcFile::NavAreaSize, navSplitter);
00277    
00278   rcfile.saveSize(RcFile::MainWindowSize, size());
00279   rcfile.savePoint(RcFile::MainWindowPos, pos());
00280 
00281   config.closePlugins();
00282   
00283   // make sure we clean up the local indicators before we quit
00284   ip->removeLocalIndicators();
00285   
00286   menubar->saveSettings();
00287   toolbar2->saveSettings();
00288   extraToolbar->saveSettings();
00289   delete menubar;
00290   delete toolbar2;
00291   delete extraToolbar;
00292   
00293   // delete any BarData
00294   if (recordList)
00295     delete recordList;
00296 
00297   chartIndex->close();
00298   
00299   // call the destructors which save some settings
00300   delete gp;
00301   delete chartNav;
00302   delete navTab;
00303 }
00304 
00305 void QtstalkerApp::slotAbout()
00306 {
00307   // display the about dialog
00308   QMessageBox *dialog = new QMessageBox(tr("About Qtstalker"),
00309                                         tr("Qtstalker\nVersion 0.36\n(C) 2001-2008 by Stefan Stratigakos"),
00310                                         QMessageBox::NoIcon,
00311                                         QMessageBox::Ok,
00312                                         QMessageBox::NoButton,
00313                                         QMessageBox::NoButton,
00314                                         this,
00315                                         "AboutDialog",
00316                                         FALSE);
00317   dialog->setIconPixmap(qtstalker);
00318   dialog->show();
00319 }
00320 
00321 void QtstalkerApp::slotOpenChart (QString selection)
00322 {
00323   // load a chart slot
00324   toolbar2->enableSlider(TRUE);
00325   status = Chart;
00326   qApp->processEvents();
00327   loadChart(selection);
00328 }
00329 
00330 void QtstalkerApp::slotQuotes ()
00331 {
00332   //RcFile rcfile;
00333   QStringList l;
00334   config.getPluginList(Config::QuotePluginPath, l);
00335   QString s;
00336   rcfile.loadData(RcFile::LastQuotePlugin, s);
00337   int i = l.findIndex(s);
00338   if (i == -1)
00339     i = 0;
00340 
00341   bool ok;
00342   s = QInputDialog::getItem (tr("Quote Dialog"), tr("Select Quote Type"), l, i, FALSE, &ok, this, 0);
00343   if (! ok)
00344     return;
00345 
00346   QuotePlugin *plug = config.getQuotePlugin(s);
00347   if (! plug)
00348     return;
00349 
00350   connect(plug, SIGNAL(chartUpdated()), this, SLOT(slotChartUpdated()));
00351   connect(plug, SIGNAL(signalWakeup()), this, SLOT(slotWakeup()));
00352 
00353   plug->setChartIndex(chartIndex);
00354 
00355   rcfile.saveData(RcFile::LastQuotePlugin, s);
00356 
00357   plug->show();
00358 }
00359 
00360 void QtstalkerApp::slotOptions ()
00361 {
00362   Preferences *dialog = new Preferences(this);
00363   connect(dialog, SIGNAL(signalMenubar(bool)), this, SLOT(slotMenubarStatus(bool)));
00364   connect(dialog, SIGNAL(signalExtraToolbar(bool)), this, SLOT(slotExtraToolbarStatus(bool)));
00365   connect(dialog, SIGNAL(signalBackgroundColor(QColor)), this, SIGNAL(signalBackgroundColor(QColor)));
00366   connect(dialog, SIGNAL(signalBorderColor(QColor)), this, SIGNAL(signalBorderColor(QColor)));
00367   connect(dialog, SIGNAL(signalGridColor(QColor)), this, SIGNAL(signalGridColor(QColor)));
00368   connect(dialog, SIGNAL(signalPlotFont(QFont)), this, SIGNAL(signalPlotFont(QFont)));
00369   connect(dialog, SIGNAL(signalAppFont(QFont)), this, SLOT(slotAppFont(QFont)));
00370   connect(dialog, SIGNAL(signalLoadChart()), this, SLOT(slotChartUpdated()));
00371   connect(dialog, SIGNAL(signalReloadToolBars()), this, SLOT(slotLoadMainToolbarSettings()));
00372   connect(dialog, SIGNAL(signalReloadToolBars()), toolbar2, SLOT(slotSetButtonView()));
00373   connect(dialog, SIGNAL(signalReloadToolBars()), extraToolbar, SLOT(slotSetButtonView()));
00374   
00375   dialog->show();
00376 }
00377 
00378 void QtstalkerApp::loadChart (QString &d)
00379 {
00380   // do all the stuff we need to do to load a chart
00381   if (d.length() == 0)
00382     return;
00383 
00384   QDir dir(d);
00385   if (! dir.exists(d, TRUE))
00386     return;
00387 
00388   // check if we need to save the slider position because chart is reloaded
00389   bool reload = FALSE;
00390   if (! chartPath.compare(d))
00391     reload = TRUE;
00392 
00393   chartPath = d;
00394   ip->setChartPath(chartPath); // let ip know what chart we are viewing currently
00395   
00396   QDictIterator<Plot> it(plotList);
00397   for(; it.current(); ++it)
00398     it.current()->clear();
00399     
00400   // make sure we change db's after Plot saves previous db edits
00401   emit signalChartPath(chartPath);
00402 
00403   // open the chart
00404   QFileInfo fi(chartPath);
00405   QString fn = fi.fileName();
00406   DbPlugin db;
00407   if (db.open(chartPath, chartIndex))
00408   {
00409     qDebug("QtstalkerApp::loadChart: can't open %s", chartPath.latin1());
00410     return;
00411   }
00412 
00413   rcfile.saveData(RcFile::CurrentChart, chartPath);
00414 
00415   DBIndexItem item;
00416   chartIndex->getIndexItem(fn, item);
00417   item.getTitle(chartName);
00418   item.getType(chartType);
00419   item.getSymbol(chartSymbol);
00420 
00421 //  connect(db, SIGNAL(signalMessage(int, int)), this, SLOT(slotProgMessage(int, int)));
00422 //  connect(db, SIGNAL(signalMessage(QString)), this, SLOT(slotStatusMessage(QString)));
00423   db.setBarLength((BarData::BarLength) toolbar2->getBarLengthInt());
00424   db.setBarRange(toolbar2->getBars());
00425   
00426   if (recordList)
00427     delete recordList;
00428   recordList = new BarData(chartPath);
00429   QString s;
00430   recordList->setBarType((BarData::BarType) item.getBarType());
00431   recordList->setBarLength((BarData::BarLength) toolbar2->getBarLengthInt());
00432   
00433   slotStatusMessage(tr("Loading chart..."));
00434   
00435   QDateTime dt = QDateTime::currentDateTime();
00436   if (menubar->getStatus(MainMenubar::PaperTrade))
00437     toolbar2->getPaperTradeDate(dt);
00438   db.getHistory(recordList, dt);
00439 
00440   slotProgMessage(1, 3);
00441   slotStatusMessage(tr("Loading indicators..."));
00442   
00443   for(it.toFirst(); it.current(); ++it)
00444     it.current()->setData(recordList);
00445 
00446   // setup the local indicators
00447   if (! reload)
00448   {
00449     ip->removeLocalIndicators();
00450     chartIndex->getIndicators(chartSymbol, s);
00451     ip->addLocalIndicators(s);
00452   }
00453   QStringList l;
00454   s = ip->getIndicatorGroup();
00455   config.getIndicators(s, l);
00456 
00457   int loop;  
00458   for (loop = 0; loop < (int) l.count(); loop++)
00459   {
00460     Setting set;
00461     config.getIndicator(l[loop], set);
00462     if (! set.count())
00463       continue;
00464     
00465     Indicator *i = new Indicator;
00466     i->setIndicator(set, l[loop]);
00467     if (! i->getEnable())
00468     {
00469       delete i;
00470       continue;
00471     }
00472 
00473     loadIndicator(i);
00474   }
00475   
00476   slotProgMessage(2, 3);
00477   slotStatusMessage(tr("Loading chart objects..."));
00478 
00479   chartIndex->getChartObjects(fn, l);
00480   Setting co;
00481   for (loop = 0; loop < (int) l.count(); loop++)
00482   {
00483     co.parse(l[loop]);
00484     s = "Plot";
00485     QString s2;
00486     co.getData(s, s2);
00487     Plot *plot = plotList[s2];
00488     if (plot)
00489       plot->addChartObject(co);
00490     else
00491       qDebug("QtstalkerApp::loadChart: plot %s not found for loading chart object", s2.latin1());
00492   }
00493   
00494   db.close();
00495 
00496   setSliderStart();
00497 
00498   slotDrawPlots();
00499 
00500   ip->updateList();
00501 
00502   setCaption(getWindowCaption());
00503   
00504   slotProgMessage(-1, 3);
00505   slotStatusMessage(QString());
00506 }
00507 
00508 void QtstalkerApp::loadIndicator (Indicator *i)
00509 {
00510   // create and prep an indicator for display
00511 
00512   QString plugin;
00513   i->getType(plugin);  
00514   IndicatorPlugin *plug = config.getIndicatorPlugin(plugin);
00515   if (! plug)
00516     return;
00517 
00518   connect(plug, SIGNAL(signalWakeup()), this, SLOT(slotWakeup()));
00519   if (recordList)
00520     plug->setIndicatorInput(recordList);
00521   QString s;
00522   i->getFile(s);
00523   plug->loadIndicatorSettings(s);
00524   Indicator *ti = 0;
00525   if (recordList)
00526     ti = plug->calculate();
00527   if (ti)
00528     i->copy(ti);
00529   if (ti)
00530     delete ti;
00531 
00532   QFileInfo fi(s);
00533   Plot *plot = plotList[fi.fileName()];
00534   if (! plot)
00535   {
00536     qDebug("QtstalkerApp::loadIndicator:plot %s not found", fi.fileName().latin1());
00537     return;
00538   }
00539   plot->addIndicator(i);
00540   if (recordList)
00541     plot->setData(recordList);
00542 }
00543 
00544 QString QtstalkerApp::getWindowCaption ()
00545 {
00546   // update the main window text
00547   
00548   QString caption = tr("Qtstalker");
00549 
00550   switch (status)
00551   {
00552     case Chart:
00553       caption.append(": ");
00554       caption.append(chartName);
00555       caption.append(" (");
00556       if (chartSymbol.length() > 0)
00557         caption.append(chartSymbol);
00558       else
00559         caption.append(chartType);
00560       caption.append(") ");
00561       break;
00562     default:
00563       break;
00564   }
00565 
00566   caption.append(toolbar2->getBarLength());
00567 
00568   return caption;
00569 }
00570 
00571 void QtstalkerApp::slotDataWindow ()
00572 {
00573   // show the datawindow dialog
00574   
00575   if (! recordList)
00576     return;
00577   
00578   DataWindow *dw = new DataWindow(0);
00579   dw->setCaption(getWindowCaption());
00580 
00581   dw->setBars(recordList);
00582   
00583   QDictIterator<Plot> it(plotList);
00584   for (; it.current(); ++it)
00585     dw->setPlot(it.current());
00586   
00587   dw->show();
00588 }
00589 
00590 void QtstalkerApp::slotBarLengthChanged (int)
00591 {
00592   // the compression has changed slot
00593   
00594   barLengthChanged();
00595   loadChart(chartPath);
00596 }
00597 
00598 void QtstalkerApp::barLengthChanged ()
00599 {
00600   // bar length has changed
00601 
00602   QString s = QString::number(toolbar2->getBarLengthInt());
00603   rcfile.saveData(RcFile::BarLength, s);
00604 
00605   emit signalInterval((BarData::BarLength) toolbar2->getBarLengthInt());
00606 }
00607 
00608 void QtstalkerApp::slotNewIndicator (Indicator *i)
00609 {
00610   // add a new indicator slot
00611   
00612   QString str;
00613   i->getFile(str);
00614   addIndicatorButton(str);
00615   loadIndicator(i);
00616   ip->updateList();
00617 }
00618 
00619 void QtstalkerApp::slotEditIndicator (Indicator *i)
00620 {
00621   // edit indicator slot
00622 
00623   loadIndicator(i);
00624 
00625   QString s;
00626   i->getFile(s);
00627   QFileInfo fi(s);
00628   Plot *p = plotList[fi.fileName()];
00629   if (p)
00630     p->draw();
00631 }
00632 
00633 void QtstalkerApp::slotDeleteIndicator (QString text)
00634 {
00635   // delete indicator slot
00636 
00637   QString s;
00638   //RcFile rcfile;
00639   rcfile.loadData(RcFile::IndicatorPath, s);
00640   s.append("/" + ip->getIndicatorGroup() + "/" + text);
00641   Setting set;
00642   config.getIndicator(s, set);
00643   if (! set.count())
00644   {
00645     qDebug("QtstalkerApp::slotDeleteIndicator:indicator settings empty");
00646     return;
00647   }
00648 
00649   // delete any chart objects that belong to the indicator
00650   Indicator i;
00651   i.setIndicator(set, s);
00652   QTabWidget *it = tabList.at(i.getTabRow() - 1);
00653   it->removePage(widgetList[text]);
00654   widgetList.remove(text);
00655 
00656   if (! it->count())
00657     it->hide();
00658 
00659   plotList.remove(text);
00660 
00661   config.deleteIndicator(s);
00662 
00663   ip->updateList();
00664 }
00665 
00666 void QtstalkerApp::slotDisableIndicator (QString name)
00667 {
00668   // remove indicator
00669 
00670   Setting set;
00671   config.getIndicator(name, set);
00672   if (! set.count())
00673   {
00674     qDebug("QtstalkerApp::slotDisableIndicator:indicator settings empty");
00675     return;
00676   }
00677 
00678   Indicator i;
00679   i.setIndicator(set, name);
00680   QTabWidget *it = tabList.at(i.getTabRow() - 1);
00681   QString s;
00682   i.getName(s);
00683   it->removePage(widgetList[s]);
00684   widgetList.remove(s);
00685 
00686   if (! it->count())
00687     it->hide();
00688 
00689   plotList.remove(s);
00690 }
00691 
00692 void QtstalkerApp::slotEnableIndicator (QString name)
00693 {
00694   // add indicator
00695 
00696   Setting set;
00697   config.getIndicator(name, set);
00698   if (! set.count())
00699     return;
00700 
00701   Indicator *i = new Indicator;
00702   i->setIndicator(set, name);
00703   if (i->getEnable() == 0)
00704   {
00705     delete i;
00706     return;
00707   }
00708   
00709   addIndicatorButton(name);
00710   loadIndicator(i);
00711 }
00712 
00713 void QtstalkerApp::slotPixelspaceChanged (int d)
00714 {
00715   emit signalPixelspace(d);
00716   emit signalIndex(toolbar2->getSlider());
00717   setSliderStart();
00718   slotDrawPlots();
00719 }
00720 
00721 void QtstalkerApp::addIndicatorButton (QString d)
00722 {
00723   Setting set;
00724   config.getIndicator(d, set);
00725   if (! set.count())
00726   {
00727     qDebug("QtstalkerApp::addIndicatorButton:indicator settings empty");
00728     return;
00729   }
00730 
00731   Indicator i;
00732   i.setIndicator(set, d);
00733   if (i.getEnable() == 0)
00734     return;
00735   
00736   QString type;
00737   i.getType(type);
00738   int row = i.getTabRow();
00739 
00740   QFileInfo fi(d);
00741   QString fn = fi.fileName();
00742 
00743   QWidget *w = new QWidget(baseWidget);
00744   QVBoxLayout *vbox = new QVBoxLayout(w);
00745   vbox->setMargin(0);
00746   vbox->setSpacing(0);
00747   Plot *plot = new Plot(w, chartIndex);
00748   vbox->addWidget(plot);
00749   widgetList.replace(fi.fileName(), w);
00750   
00751   plotList.replace(fi.fileName(), plot);
00752 
00753   QTabWidget *it = tabList.at(row - 1);
00754   it->addTab(w, fi.fileName());
00755 
00756   if (it->isHidden())
00757     it->show();
00758 
00759   // Set the current indicator in this row to the last used one.
00760   switch (row)
00761   {
00762     case 1:
00763       if (fn == lastIndicatorUsed1)
00764         it->setCurrentPage(it->indexOf(w));
00765       break;
00766     case 2:
00767       if (fn == lastIndicatorUsed2)
00768         it->setCurrentPage(it->indexOf(w));
00769       break;
00770     case 3:
00771       if (fn == lastIndicatorUsed3)
00772         it->setCurrentPage(it->indexOf(w));
00773       break;
00774     default:
00775       break;
00776   }
00777 
00778   QColor color;
00779   //RcFile rcfile;
00780   rcfile.loadColor(RcFile::BackgroundColor, color);
00781   
00782   connect(this, SIGNAL(signalBackgroundColor(QColor)), plot, SLOT(setBackgroundColor(QColor)));
00783   plot->setBackgroundColor(color);
00784 
00785   rcfile.loadColor(RcFile::BorderColor, color);
00786   connect(this, SIGNAL(signalBorderColor(QColor)), plot, SLOT(setBorderColor(QColor)));
00787   plot->setBorderColor(color);
00788 
00789   rcfile.loadColor(RcFile::GridColor, color);
00790   connect(this, SIGNAL(signalGridColor(QColor)), plot, SLOT(setGridColor(QColor)));
00791   plot->setGridColor(color);
00792 
00793   connect(this, SIGNAL(signalPlotFont(QFont)), plot, SLOT(setPlotFont(QFont)));
00794   QFont font;
00795   rcfile.loadFont(RcFile::PlotFont, font);
00796   plot->setPlotFont(font);
00797 
00798   plot->setGridFlag(menubar->getStatus(MainMenubar::Grid));
00799   plot->setScaleToScreen(menubar->getStatus(MainMenubar::ScaleToScreen));
00800   plot->setPixelspace(toolbar2->getPixelspace());
00801   plot->setIndex(toolbar2->getSlider());
00802   plot->setInterval((BarData::BarLength) toolbar2->getBarLengthInt());
00803   bool b;
00804   rcfile.loadData(RcFile::Crosshairs, b);
00805   plot->setCrosshairsStatus(b);  
00806   plot->setDrawMode(menubar->getStatus(MainMenubar::DrawMode));
00807     
00808   connect(plot->getIndicatorPlot(), SIGNAL(signalNewIndicator()), ip, SLOT(newIndicator()));
00809   connect(plot->getIndicatorPlot(), SIGNAL(signalEditIndicator(QString)), ip, SLOT(editIndicator(QString)));
00810   connect(plot->getIndicatorPlot(), SIGNAL(statusMessage(QString)), this, SLOT(slotStatusMessage(QString)));
00811   connect(plot->getIndicatorPlot(), SIGNAL(infoMessage(Setting *)), this, SLOT(slotUpdateInfo(Setting *)));
00812   connect(plot->getIndicatorPlot(), SIGNAL(leftMouseButton(int, int, bool)), this, SLOT(slotPlotLeftMouseButton(int, int, bool)));
00813   connect(plot->getIndicatorPlot(), SIGNAL(signalEditChart(QString)), chartNav, SLOT(editChart(QString)));
00814   connect(plot->getIndicatorPlot(), SIGNAL(signalDeleteAllCO()), this, SLOT(slotDeleteAllCO()));
00815   connect(plot->getIndicatorPlot(), SIGNAL(signalDeleteCO(QString)), this, SLOT(slotDeleteCO(QString)));
00816   connect(plot->getIndicatorPlot(), SIGNAL(signalSaveCO(Setting)), this, SLOT(slotSaveCO(Setting)));
00817   connect(this, SIGNAL(signalCrosshairsStatus(bool)), plot->getIndicatorPlot(), SLOT(setCrosshairsStatus(bool)));
00818   connect(this, SIGNAL(signalPixelspace(int)), plot, SLOT(setPixelspace(int)));
00819   connect(this, SIGNAL(signalIndex(int)), plot, SLOT(setIndex(int)));
00820   connect(this, SIGNAL(signalInterval(BarData::BarLength)), plot, SLOT(setInterval(BarData::BarLength)));
00821   connect(this, SIGNAL(signalChartPath(QString)), plot, SLOT(setChartPath(QString)));
00822   
00823   connect(toolbar2, SIGNAL(signalSliderChanged(int)), plot, SLOT(slotSliderChanged(int)));
00824   connect(menubar, SIGNAL(signalGrid(bool)), plot->getIndicatorPlot(), SLOT(slotGridChanged(bool)));
00825   connect(menubar, SIGNAL(signalScale(bool)), plot, SLOT(slotScaleToScreenChanged(bool)));
00826   connect(menubar, SIGNAL(signalDraw(bool)), plot->getIndicatorPlot(), SLOT(slotDrawModeChanged(bool)));
00827 }
00828 
00829 void QtstalkerApp::slotChartUpdated ()
00830 {
00831   chartNav->refreshList();
00832   
00833   if (status == None)
00834     return;
00835   
00836   int ti = toolbar2->getBars();
00837   rcfile.saveData(RcFile::BarsToLoad, ti);
00838 
00839   loadChart(chartPath);
00840 }
00841 
00842 void QtstalkerApp::slotStatusMessage (QString d)
00843 {
00844   statusbar->message(d);
00845   qApp->processEvents();
00846 }
00847 
00848 void QtstalkerApp::initGroupNav ()
00849 {
00850   gp = new GroupPage(baseWidget);
00851   connect(gp, SIGNAL(fileSelected(QString)), this, SLOT(slotOpenChart(QString)));
00852   connect(chartNav, SIGNAL(signalAddToGroup(QString)), gp, SLOT(addChartToGroup(QString)));
00853   connect(gp, SIGNAL(addRecentChart(QString)), extraToolbar, SLOT(slotAddRecentChart(QString)));
00854   connect(gp, SIGNAL(removeRecentCharts(QStringList)), extraToolbar, SLOT(slotRemoveRecentCharts(QStringList)));
00855   connect(extraToolbar, SIGNAL(signalSetGroupNavItem(QString, QString)), gp, SLOT(setGroupNavItem(QString, QString)));
00856   navTab->addWidget(gp, 1);
00857 }
00858 
00859 void QtstalkerApp::initChartNav ()
00860 {
00861   chartNav = new ChartPage(baseWidget, chartIndex);
00862   connect(chartNav, SIGNAL(fileSelected(QString)), this, SLOT(slotOpenChart(QString)));
00863   connect(chartNav, SIGNAL(addRecentChart(QString)), extraToolbar, SLOT(slotAddRecentChart(QString)));
00864   connect(chartNav, SIGNAL(removeRecentCharts(QStringList)), extraToolbar, SLOT(slotRemoveRecentCharts(QStringList)));
00865   connect(chartNav, SIGNAL(signalReloadChart()), this, SLOT(slotChartUpdated()));
00866   connect(extraToolbar, SIGNAL(signalSetChartNavItem(QString, QString)), chartNav, SLOT(setChartNavItem(QString, QString)));
00867   navTab->addWidget(chartNav, 0);
00868 }
00869 
00870 void QtstalkerApp::initPortfolioNav ()
00871 {
00872   pp = new PortfolioPage(baseWidget, chartIndex);
00873   navTab->addWidget(pp, 3);
00874 }
00875 
00876 void QtstalkerApp::initTestNav ()
00877 {
00878   tp = new TestPage(baseWidget, menubar, chartIndex);
00879   connect(tp, SIGNAL(message(QString)), this, SLOT(slotStatusMessage(QString)));
00880   navTab->addWidget(tp, 4);
00881 }
00882 
00883 void QtstalkerApp::initIndicatorNav ()
00884 {
00885   ip = new IndicatorPage(baseWidget, chartIndex);
00886   connect(ip, SIGNAL(signalDisableIndicator(QString)), this, SLOT(slotDisableIndicator(QString)));
00887   connect(ip, SIGNAL(signalEnableIndicator(QString)), this, SLOT(slotEnableIndicator(QString)));
00888   connect(ip, SIGNAL(signalNewIndicator(Indicator *)), this, SLOT(slotNewIndicator(Indicator *)));
00889   connect(ip, SIGNAL(signalEditIndicator(Indicator *)), this, SLOT(slotEditIndicator(Indicator *)));
00890   connect(ip, SIGNAL(signalDeleteIndicator(QString)), this, SLOT(slotDeleteIndicator(QString)));
00891   connect(menubar, SIGNAL(signalNewIndicator()), ip, SLOT(newIndicator()));
00892   connect(ip, SIGNAL(signalGroupIsChanging()), this, SLOT(slotSavePlotSizes()));
00893   connect(ip, SIGNAL(signalGroupChanged()), this, SLOT(slotLoadPlotSizes()));
00894   connect(ip, SIGNAL(signalGroupChanged()), this, SLOT(slotChartUpdated()));
00895   connect(ip, SIGNAL(signalLocalIndicator(QString)), this, SLOT(addIndicatorButton(QString)));
00896   navTab->addWidget(ip, 2);
00897 }
00898 
00899 void QtstalkerApp::initScannerNav ()
00900 {
00901   sp = new ScannerPage(baseWidget, chartIndex);
00902   connect(sp, SIGNAL(message(QString)), this, SLOT(slotStatusMessage(QString)));
00903   connect(sp, SIGNAL(refreshGroup()), gp, SLOT(refreshList()));
00904   navTab->addWidget(sp, 5);
00905 }
00906 
00907 void QtstalkerApp::slotHideNav (bool d)
00908 {
00909   menubar->setStatus(MainMenubar::SidePanel, d);
00910 
00911   if (d)
00912     navBase->show();
00913   else
00914     navBase->hide();
00915 }
00916 
00917 void QtstalkerApp::slotUpdateInfo (Setting *r)
00918 {
00919   // list bar values first
00920   QStringList l;
00921   l.append("D");
00922   l.append("T");
00923   l.append("O");
00924   l.append("H");
00925   l.append("L");
00926   l.append("C");
00927   l.append("VOL");
00928   l.append("OI");
00929   QString s, s2, str;
00930   int loop;
00931   for (loop = 0; loop < (int) l.count(); loop++)
00932   {
00933     r->getData(l[loop], s);
00934     if (s.length())
00935     {
00936       str.append(l[loop] + " " + s + "\n");
00937       r->remove(l[loop]);
00938     }
00939   }
00940 
00941   r->getKeyList(l);
00942   l.sort();
00943   for (loop = 0; loop < (int) l.count(); loop++)
00944   {
00945     r->getData(l[loop], s);
00946     // If it is a big number, then use zero precision.
00947     bool ok;
00948     double sn = s.toDouble(&ok);
00949     if (ok) {
00950       if (fabs(sn) > 1000)
00951         s = QString::number(sn, 'f', 0);
00952     }
00953     str.append(l[loop] + " " + s + "\n");
00954   }
00955 
00956   delete r;
00957 
00958   infoLabel->setText(str);
00959 }
00960 
00961 void QtstalkerApp::slotPlotLeftMouseButton (int x, int y, bool)
00962 {
00963   QDictIterator<Plot> it(plotList);
00964   for(; it.current(); ++it)
00965     it.current()->crossHair(x, y, FALSE);
00966   slotDrawPlots();  
00967 }
00968 
00969 void QtstalkerApp::slotCrosshairsStatus (bool status)
00970 {
00971   emit signalCrosshairsStatus(status);
00972 }
00973 
00974 void QtstalkerApp::setSliderStart ()
00975 {
00976   if (status == None)
00977     return;
00978 
00979   int loop;
00980   int rc = 0;
00981   for (loop = 0; loop < (int) tabList.count(); loop++)
00982   {
00983     QTabWidget *tw = tabList.at(loop);
00984     if (! tw->isHidden())
00985     {
00986       Plot *plot = plotList[tw->label(tw->currentPageIndex())];
00987       if (! plot)
00988         return;
00989       else
00990       {
00991         rc = toolbar2->setSliderStart(plot->getWidth(), recordList->count());
00992         break;
00993       }
00994     }
00995   }
00996 
00997   emit signalIndex(rc);
00998 }
00999 
01000 void QtstalkerApp::slotNavigatorPosition (int d)
01001 {
01002   if (! d)
01003     navSplitter->moveToFirst(navBase);
01004   else
01005     navSplitter->moveToLast(navBase);
01006     
01007   navSplitter->refresh();
01008 }
01009 
01010 void QtstalkerApp::slotHelp ()
01011 {
01012   QString s = "toc.html";
01013   HelpWindow *hw = new HelpWindow(this, s);
01014   hw->show();
01015 }
01016 
01017 void QtstalkerApp::slotProgMessage (int p, int t)
01018 {
01019   if (p == -1)
01020     progBar->reset();
01021   else
01022     progBar->setProgress(p, t);
01023     
01024   qApp->processEvents();
01025 }
01026 
01027 void QtstalkerApp::slotDrawPlots ()
01028 {
01029   int loop;
01030   for(loop = 0; loop < (int) tabList.count(); loop++)
01031   {
01032     QTabWidget *it = tabList.at(loop);
01033     if (it->isHidden())
01034       continue;
01035     QString s = it->label(it->currentPageIndex());
01036     Plot *p = plotList[s];
01037     if (p)
01038       p->draw();
01039   }
01040 }
01041 
01042 void QtstalkerApp::slotPaperTradeChanged (bool d)
01043 {
01044   toolbar2->paperTradeClicked(d);
01045   slotChartUpdated();
01046 }
01047 
01048 void QtstalkerApp::slotWakeup ()
01049 {
01050   qApp->processEvents();
01051 }
01052 
01053 void QtstalkerApp::slotIndicatorSummary ()
01054 {
01055   if (status == None)
01056     return;
01057 
01058   QString basePath, s;
01059   //RcFile rcfile;
01060   rcfile.loadData(RcFile::IndicatorPath, basePath);
01061   rcfile.loadData(RcFile::IndicatorGroup, s);
01062   basePath.append("/" + s);
01063 
01064   QStringList l;
01065   QDictIterator<Plot> it(plotList);
01066   for(; it.current(); ++it)
01067   {
01068     Indicator *i = it.current()->getIndicator();
01069     i->getName(s);
01070     l.append(basePath + "/" + s);
01071   }
01072 
01073   IndicatorSummary is(l, toolbar2->getBars(), (BarData::BarLength) toolbar2->getBarLengthInt(), chartIndex);
01074   connect(&is, SIGNAL(signalWakeup()), this, SLOT(slotWakeup()));
01075   is.run();
01076 }
01077 
01078 void QtstalkerApp::slotDeleteAllCO ()
01079 {
01080   chartIndex->deleteAllChartObjects(chartSymbol);
01081 }
01082 
01083 void QtstalkerApp::slotDeleteCO (QString d)
01084 {
01085   chartIndex->deleteChartObject(chartSymbol, d);
01086 }
01087 
01088 void QtstalkerApp::slotSaveCO (Setting d)
01089 {
01090   QString s = "Name";
01091   QString s2;
01092   d.getData(s, s2);
01093   chartIndex->setChartObject(chartSymbol, s2, d);
01094 }
01095 
01096 void QtstalkerApp::slotMenubarStatus (bool d)
01097 {
01098   if (d)
01099     menubar->show();
01100   else
01101     menubar->hide();
01102 }
01103 
01104 void QtstalkerApp::slotExtraToolbarStatus (bool d)
01105 {
01106   if (d)
01107     extraToolbar->show();
01108   else
01109     extraToolbar->hide();
01110 }
01111 
01112 void QtstalkerApp::slotAppFont (QFont d)
01113 {
01114   qApp->setFont(d, TRUE, 0);
01115   qApp->setFont(d, TRUE, "QComboBox");
01116 }
01117 
01118 void QtstalkerApp::slotSavePlotSizes ()
01119 {
01120   QString s;
01121   s = ip->getIndicatorGroup();
01122   rcfile.saveSplitterSize(RcFile::PlotSizes, split, s);
01123 }
01124 
01125 void QtstalkerApp::slotLoadPlotSizes ()
01126 {  
01127   QString s;
01128   s = ip->getIndicatorGroup();
01129   rcfile.loadSplitterSize(RcFile::PlotSizes, split, s);
01130 }
01131 
01132 //**********************************************************************
01133 //**********************************************************************
01134 //**********************************************************************
01135 
01136 int main(int argc, char *argv[])
01137 {
01138   QApplication a(argc, argv);
01139   QTranslator tor( 0 );
01140 
01141   // set the location where your .qm files are in load() below as the last parameter instead of "."
01142   // for development, use "/" to use the english original as
01143   // .qm files are stored in the base project directory.
01144 //  tor.load(QString("qtstalker_") + QTextCodec::locale(), "." );
01145   tor.load(QString("qtstalker_") + QTextCodec::locale(), "/usr/local/share/qtstalker/i18n" );
01146   a.installTranslator( &tor );
01147 
01148   QtstalkerApp *qtstalker = new QtstalkerApp();
01149   a.setMainWidget(qtstalker);
01150 
01151   qtstalker->show();
01152 
01153   return a.exec();
01154 }
01155