lib/IndicatorPlot.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 "IndicatorPlot.h"
00023 #include "DbPlugin.h"
00024 #include "PrefDialog.h"
00025 #include "HelpWindow.h"
00026 #include "RcFile.h"
00027 #include <qpainter.h>
00028 #include <qpen.h>
00029 #include <qpoint.h>
00030 #include <qpointarray.h>
00031 #include <qcursor.h>
00032 #include <math.h>
00033 #include <qprinter.h>
00034 #include <qpaintdevicemetrics.h>
00035 #include <qimage.h>
00036 #include <qmessagebox.h>
00037 #include <qinputdialog.h>
00038 #include <qdir.h>
00039                 
00040 // only for fabs()
00041 #include <math.h>
00042                 
00043 #include "../pics/indicator.xpm"
00044 #include "../pics/edit.xpm"
00045 #include "../pics/delete.xpm"
00046 #include "../pics/co.xpm"
00047 #include "../pics/print.xpm"
00048 #include "../pics/loggrid.xpm"
00049 #include "../pics/date.xpm"
00050 #include "../pics/buyarrow.xpm"
00051 #include "../pics/arc.xpm"
00052 #include "../pics/fib.xpm"
00053 #include "../pics/horizontal.xpm"
00054 #include "../pics/sellarrow.xpm"
00055 #include "../pics/text.xpm"
00056 #include "../pics/trend.xpm"
00057 #include "../pics/vertical.xpm"
00058 #include "../pics/help.xpm"
00059 
00060 IndicatorPlot::IndicatorPlot (QWidget *w, DBIndex *i) : QWidget(w)
00061 {
00062   chartIndex = i;
00063   setBackgroundMode(NoBackground);
00064   startX = 2;
00065   backgroundColor.setNamedColor("black");
00066   borderColor.setNamedColor("white");
00067   gridColor.setNamedColor("#626262");
00068   pixelspace = 0;
00069   gridFlag = TRUE;
00070   interval = BarData::DailyBar;
00071   scaleToScreen = FALSE;
00072   logScale = FALSE;
00073   startIndex = 0;
00074   mouseFlag = None;
00075   crossHairFlag = FALSE;
00076   chartMenu = 0;
00077   drawMode = FALSE;
00078   crosshairs = TRUE;
00079   infoFlag = TRUE;
00080   coSelected = 0;
00081   dateFlag = TRUE;
00082   menuFlag = TRUE;
00083 
00084   plotFont.setFamily("Helvetica");
00085   plotFont.setPointSize(12);
00086   plotFont.setWeight(50);  
00087   plotFontMetrics = new QFontMetrics(plotFont);
00088   
00089   indy = 0;
00090   data = 0;
00091 
00092   chartMenu = new QPopupMenu();
00093   
00094   setMouseTracking(TRUE);
00095 
00096   setFocusPolicy(QWidget::ClickFocus);
00097   
00098   coList.setAutoDelete(TRUE);
00099 }
00100 
00101 IndicatorPlot::~IndicatorPlot ()
00102 {
00103   delete chartMenu;
00104   config.closePlugins();
00105 }
00106 
00107 void IndicatorPlot::clear ()
00108 {
00109   saveChartObjects();
00110 
00111   if (indy)
00112   {
00113     delete indy;
00114     indy = 0;
00115   }
00116 
00117   data = 0;
00118   mouseFlag = None;
00119   crossHairFlag = FALSE;
00120 
00121   coList.clear();
00122 }
00123 
00124 void IndicatorPlot::setData (BarData *l)
00125 {
00126   if (! l->count())
00127     return;
00128 
00129   data = l;
00130 }
00131 
00132 void IndicatorPlot::setScaleToScreen (bool d)
00133 {
00134   scaleToScreen = d;
00135 }
00136 
00137 void IndicatorPlot::setLogScale (bool d)
00138 {
00139   logScale = d;
00140 }
00141 
00142 void IndicatorPlot::setDateFlag (bool d)
00143 {
00144   dateFlag = d;
00145 }
00146 
00147 void IndicatorPlot::setChartPath (QString &d)
00148 {
00149   chartPath = d;
00150 }
00151 
00152 void IndicatorPlot::setDrawMode (bool d)
00153 {
00154   drawMode = d;
00155   
00156   if (drawMode)
00157     setCursor(QCursor(ArrowCursor));
00158   else
00159     setCursor(QCursor(CrossCursor));
00160 
00161   if (! drawMode && mouseFlag == COSelected && coSelected)
00162   {
00163     QPoint p(-1, -1);
00164     coSelected->pointerClick(p, x1, y1);
00165     mouseFlag = None;
00166   }
00167 }
00168 
00169 void IndicatorPlot::setInfoFlag (bool d)
00170 {
00171   infoFlag = d;
00172 }
00173 
00174 void IndicatorPlot::setInterval (BarData::BarLength d)
00175 {
00176   interval = d;
00177 }
00178 
00179 void IndicatorPlot::draw ()
00180 {
00181   buffer.fill(backgroundColor);
00182 
00183   if (data)
00184   {
00185     if (! indy)
00186     {
00187       paintEvent(0);
00188       return;
00189     }
00190 
00191     setScale();
00192     drawXGrid();
00193     drawYGrid();
00194     drawInfo();
00195     drawLines();
00196     drawObjects();
00197     drawCrossHair();
00198 //    drawInfo();
00199   }
00200 
00201   paintEvent(0);
00202   
00203   emit signalDraw();
00204 }
00205 
00206 void IndicatorPlot::drawRefresh ()
00207 {
00208   paintEvent(0);
00209 }
00210 
00211 void IndicatorPlot::drawLines ()
00212 {
00213   if (! indy->getEnable())
00214     return;
00215 
00216   int loop;
00217   for (loop = 0; loop < indy->getLines(); loop++)
00218   {
00219     currentLine = indy->getLine(loop);
00220 
00221     if (! currentLine->getSize())
00222       continue;
00223             
00224     switch (currentLine->getType())
00225     {
00226       case PlotLine::Histogram:
00227         drawHistogram();
00228         break;
00229       case PlotLine::HistogramBar:
00230         drawHistogramBar();
00231         break;
00232       case PlotLine::Dot:
00233         drawDot();
00234         break;
00235       case PlotLine::Line:
00236       case PlotLine::Dash:
00237         drawLine();
00238         break;
00239       case PlotLine::Horizontal:
00240         drawHorizontalLine();
00241         break;
00242       case PlotLine::Bar:
00243         drawBar();
00244         break;
00245       case PlotLine::Candle:
00246         drawCandle();
00247         break;
00248       case PlotLine::PF:
00249         drawPF();
00250         break;
00251       default:
00252         break;
00253     }
00254   }
00255 }
00256 
00257 void IndicatorPlot::paintEvent (QPaintEvent *)
00258 {
00259   bitBlt(this, 0, 0, &buffer);
00260 }
00261 
00262 void IndicatorPlot::resizeEvent (QResizeEvent *event)
00263 {
00264   buffer.resize(event->size());
00265   draw();
00266 }
00267 
00268 void IndicatorPlot::mousePressEvent (QMouseEvent *event)
00269 {
00270   if (! indy || ! data)
00271     return;
00272 
00273   if (! drawMode)
00274   {
00275     if (event->button() == LeftButton)
00276     {
00277       if (crosshairs)
00278       {
00279         crossHair(event->x(), event->y(), TRUE);
00280         updateStatusBar(event->x(), event->y());
00281         emit leftMouseButton(event->x(), event->y(), 0);
00282       }
00283       else
00284         updateStatusBar(event->x(), event->y());
00285       return;
00286     }
00287   }
00288     
00289   if (event->button() == LeftButton)
00290   {
00291     getXY(event->x(), event->y());
00292     
00293     if (mouseFlag == None)
00294     {
00295       QDictIterator<COBase> it(coList);
00296       for (; it.current(); ++it)
00297       {
00298         coSelected = it.current();
00299         QPoint p(event->x(), event->y());
00300         COBase::Status rc = coSelected->pointerClick(p, x1, y1);
00301         if (rc != COBase::None)
00302         {
00303           mouseFlag = COSelected;
00304           return;
00305         }
00306       }
00307     }
00308     
00309     if (mouseFlag == COSelected)
00310     {
00311       QPoint p(event->x(), event->y());
00312       COBase::Status rc = coSelected->pointerClick(p, x1, y1);
00313       if (rc == COBase::Moving)
00314       {
00315         mouseFlag = Moving;
00316         return;
00317       }
00318       
00319       if (rc == COBase::None)
00320       {
00321         mouseFlag = None;
00322         return;
00323       }
00324     }
00325     
00326     if (mouseFlag == Moving)
00327     {
00328       QPoint p(event->x(), event->y());
00329       coSelected->pointerClick(p, x1, y1);
00330       mouseFlag = COSelected;
00331       return;
00332     }
00333     
00334     if (mouseFlag == ClickWait)
00335     {
00336       QPoint p(event->x(), event->y());
00337       COBase::Status rc = coSelected->pointerClick(p, x1, y1);
00338       if (rc == COBase::None)
00339       {
00340         mouseFlag = None;
00341         emit statusMessage("");
00342         setCursor(QCursor(Qt::ArrowCursor));
00343         return;
00344       }
00345     }
00346   }
00347 }
00348 
00349 void IndicatorPlot::contextMenuEvent (QContextMenuEvent *)
00350 {
00351   if (drawMode && mouseFlag == COSelected && coSelected)
00352     coSelected->showMenu();
00353   else
00354   {
00355     if (menuFlag)
00356       showPopupMenu();
00357   }
00358 }
00359 
00360 void IndicatorPlot::mouseMoveEvent (QMouseEvent *event)
00361 {
00362   if (! indy || ! data)
00363     return;
00364 
00365   // ignore moves above the top of the chart - we get draw errors if we don't
00366   if (event->y() <= 0)
00367     return;
00368     
00369   // are we trying to drag a chart object?
00370   if (drawMode)
00371   {
00372     if (mouseFlag == Moving || mouseFlag == ClickWait)
00373     {
00374       getXY(event->x(), event->y());
00375       QPoint p(event->x(), event->y());
00376       coSelected->pointerMoving(buffer, p, x1, y1);
00377       return;
00378     }
00379   }
00380   
00381   if (! infoFlag)
00382     return;
00383   else
00384     getInfo(event->x());
00385 }
00386 
00387 void IndicatorPlot::getInfo (int x)
00388 {
00389   int i = convertXToDataIndex(x);
00390 
00391   Setting tr;
00392   QString s, k;
00393   Bar bar;
00394   data->getBar(i, bar);
00395   bar.getDateString(TRUE, s);
00396   k = "D";
00397   tr.setData(k, s);
00398   bar.getTimeString(TRUE, s);
00399   k = "T";
00400   tr.setData(k, s);
00401 
00402   // If there are Buy/Sell objects, then show them in the data panel
00403   if (coList.count() > 0)
00404   {
00405     QDateTime d;
00406     bar.getDate(d);
00407     QDateTime coDate;
00408     int c = 0;
00409     Setting set;
00410     QDictIterator<COBase> it(coList);
00411     for (; it.current(); ++it)
00412     {
00413       it.current()->getDate(coDate);
00414       if (coDate == d)
00415       {
00416         it.current()->getSettings(set);
00417         k = "Type";
00418         set.getData(k, s);
00419         if (s == "BuyArrow" || s == "SellArrow")
00420         {
00421           c++;
00422           QString label = "Trade";
00423           label += "-" + QString::number(c);
00424           QString text = s.replace("Arrow", "");
00425           k = "Identifier";
00426           set.getData(k, s);
00427           if (s != "") text += " " + s;
00428           k = "Price";
00429           set.getData(k, s);
00430           if (s != "") text += " " + s;
00431           tr.setData(label, text);
00432         }
00433       }
00434     }
00435   }
00436   
00437   if (indy && indy->getEnable())
00438   {
00439     int loop;
00440     for (loop = 0; loop < (int) indy->getLines(); loop++)
00441     {
00442       PlotLine *line = indy->getLine(loop);
00443       int li = line->getSize() - data->count() + i;
00444       if (li > -1 && li < line->getSize())
00445         line->getInfo(li, tr);
00446     }
00447   }
00448 
00449   if (tr.count())
00450   {
00451     Setting *r = new Setting;
00452     tr.copy(r);
00453     emit infoMessage(r);
00454   }
00455 }
00456 
00457 void IndicatorPlot::mouseDoubleClickEvent (QMouseEvent *)
00458 {
00459   if (! indy || ! data)
00460     return;
00461 
00462   if (mouseFlag != COSelected)
00463     return;
00464     
00465   coSelected->prefDialog();
00466 }
00467 
00468 void IndicatorPlot::keyPressEvent (QKeyEvent *key)
00469 {
00470   // if chart object selected then pass keyevent to it
00471   if (mouseFlag == COSelected)
00472   {
00473     coSelected->keyEvent(key);
00474     return;
00475   }
00476   
00477   // process for plot keyevents
00478   switch (key->key())
00479   {
00480     case Qt::Key_Left:
00481     case Qt::Key_Right:
00482     case Qt::Key_Home:
00483     case Qt::Key_End:
00484     case Qt::Key_Plus:
00485     case Qt::Key_Minus:
00486     case Qt::Key_Prior:
00487     case Qt::Key_Next:
00488     case Qt::Key_Up:
00489     case Qt::Key_Down:
00490       emit keyPressed(key);
00491       break;
00492     default:
00493       key->ignore();
00494       break;
00495   }
00496 }
00497 
00498 void IndicatorPlot::setBackgroundColor (QColor &d)
00499 {
00500   backgroundColor = d;
00501 }
00502 
00503 void IndicatorPlot::setBorderColor (QColor &d)
00504 {
00505   borderColor = d;
00506 }
00507 
00508 void IndicatorPlot::setGridColor (QColor &d)
00509 {
00510   gridColor = d;
00511 }
00512 
00513 void IndicatorPlot::setPlotFont (QFont &d)
00514 {
00515   plotFont = d;
00516   delete plotFontMetrics;
00517   plotFontMetrics = new QFontMetrics(plotFont);
00518 }
00519 
00520 void IndicatorPlot::setGridFlag (bool d)
00521 {
00522   gridFlag = d;
00523 }
00524 
00525 void IndicatorPlot::setMenuFlag (bool d)
00526 {
00527   menuFlag = d;
00528 }
00529 
00530 void IndicatorPlot::setPixelspace (int d)
00531 {
00532   pixelspace = d;
00533 }
00534 
00535 void IndicatorPlot::setIndex (int d)
00536 {
00537   startIndex = d;
00538 }
00539 
00540 void IndicatorPlot::setXGrid (QMemArray<int> &d)
00541 {
00542   xGrid = d;
00543 }
00544 
00545 void IndicatorPlot::drawXGrid ()
00546 {
00547   if (gridFlag == FALSE)
00548     return;
00549 
00550   QPainter painter;
00551   painter.begin(&buffer);
00552   painter.setPen(QPen(gridColor, 1, QPen::DotLine));
00553 
00554   int loop;
00555   for (loop = 0; loop < (int) xGrid.size(); loop++)
00556   {
00557     if (xGrid[loop] >= startIndex)
00558     {
00559       int x = startX + (xGrid[loop] * pixelspace) - (startIndex * pixelspace);
00560       painter.drawLine (x, 0, x, buffer.height());
00561     }
00562   }
00563 
00564   painter.end();
00565 }
00566 
00567 void IndicatorPlot::addIndicator (Indicator *i)
00568 {
00569   indy = i;
00570 }
00571 
00572 Indicator * IndicatorPlot::getIndicator ()
00573 {
00574   return indy;
00575 }
00576 
00577 bool IndicatorPlot::deleteIndicator ()
00578 {
00579   if (indy)
00580   {
00581     delete indy;
00582     indy = 0;
00583   }
00584 
00585   return FALSE;
00586 }
00587 
00588 void IndicatorPlot::drawYGrid ()
00589 {
00590   if (! gridFlag)
00591     return;
00592 
00593   QPainter painter;
00594   painter.begin(&buffer);
00595   painter.setPen(QPen(gridColor, 1, QPen::DotLine));
00596   
00597   QMemArray<double> scaleArray;
00598   scaler.getScaleArray(scaleArray);
00599 
00600   int loop;
00601   for (loop = 0; loop < (int) scaleArray.size(); loop++)
00602   {
00603     int y = scaler.convertToY(scaleArray[loop]);
00604     painter.drawLine (startX, y, buffer.width(), y);
00605   }
00606 
00607   painter.end();
00608 }
00609 
00610 void IndicatorPlot::drawInfo ()
00611 // plot the indicator values at the top of the screen
00612 {
00613   QPainter painter;
00614   painter.begin(&buffer);
00615   painter.setPen(borderColor);
00616   painter.setFont(plotFont);
00617   painter.setBackgroundMode(OpaqueMode);
00618   painter.setBackgroundColor(backgroundColor);
00619   
00620   //QFontMetrics fm = painter.fontMetrics();
00621   int pos = startX;
00622 
00623   QString s;
00624   Bar bar;
00625   data->getBar(data->count() - 1, bar);
00626   bar.getDateString(TRUE, s);
00627   s.append(" ");
00628   painter.drawText(pos, 10, s, -1);
00629   pos = pos + plotFontMetrics->width(s);
00630 
00631   if (indy && indy->getEnable())
00632   {
00633     int loop;
00634     for (loop = 0; loop < (int) indy->getLines(); loop++)
00635     {
00636       PlotLine *line = indy->getLine(loop);
00637       if (line->getSize() > 1)
00638       {
00639         if (line->getType() == PlotLine::Bar || line->getType() == PlotLine::Candle)
00640         {
00641           if (data->count())
00642           {
00643             double ch = 0;
00644             double per = 0;
00645             if (data->count() > 1)
00646             {
00647               ch = data->getClose(data->count() - 1) - data->getClose(data->count() - 2);
00648               per = (ch / data->getClose(data->count() - 2)) * 100;
00649             }
00650             s = "CH=";
00651             QString str;
00652             strip(ch, 4, str);
00653             s.append(str);
00654             s.append(" (");
00655             strip(per, 2, str);
00656             s.append(str);
00657             s.append("%) ");
00658             if (ch < 0)
00659               painter.setPen(QColor("red"));
00660             else
00661             {
00662               if (ch > 0)
00663                 painter.setPen(QColor("green"));
00664               else
00665                 painter.setPen(QColor("blue"));
00666             }
00667             painter.drawText(pos, 10, s, -1);
00668             pos = pos + plotFontMetrics->width(s);
00669   
00670             painter.setPen(borderColor);
00671     
00672             s = "O=";
00673             strip(data->getOpen(data->count() - 1), 4, str);
00674             s.append(str);
00675             s.append(" H=");
00676             strip(data->getHigh(data->count() - 1), 4, str);
00677             s.append(str);
00678             s.append(" L=");
00679             strip(data->getLow(data->count() - 1), 4, str);
00680             s.append(str);
00681             s.append(" C=");
00682             strip(data->getClose(data->count() - 1), 4, str);
00683             s.append(str);
00684             s.append(" ");
00685             painter.drawText(pos, 10, s, -1);
00686             pos = pos + plotFontMetrics->width(s);
00687           }
00688         }
00689         
00690         else if (line->getType() == PlotLine::Horizontal)
00691         {
00692           //dont print value of horizontal at the top 
00693           //because its already displayed in the chart
00694           continue;
00695         }
00696         else
00697         {
00698           line->getLabel(s);
00699           s.append("=");
00700           QString str;
00701           strip(line->getData(line->getSize() - 1), 4, str);
00702           s.append(str);
00703           s.append(" ");
00704 
00705           QColor c;
00706           line->getColor(c);
00707           painter.setPen(c);
00708           painter.drawText(pos, 10, s, -1);
00709           pos = pos + plotFontMetrics->width(s);
00710         }
00711       }
00712     }
00713   }
00714   
00715   painter.end();
00716 }
00717 
00718 void IndicatorPlot::crossHair (int x, int y, bool f)
00719 {
00720   crossHairFlag = TRUE;
00721   getXY(x, y);
00722   crossHairY = y1;
00723   crossHairX = x1;
00724   if (f)
00725     draw();
00726 }
00727 
00728 void IndicatorPlot::drawCrossHair ()
00729 {
00730   if (! crosshairs)
00731     return;
00732     
00733   if (! crossHairFlag)
00734     return;
00735     
00736   int y = scaler.convertToY(crossHairY);
00737   int x = startX + (data->getX(crossHairX) * pixelspace) - (startIndex * pixelspace);
00738   
00739   QPainter painter;
00740   painter.begin(&buffer);
00741   painter.setPen(QPen(borderColor, 1, QPen::DotLine));
00742   painter.drawLine (0, y, buffer.width(), y);
00743   painter.drawLine (x, 0, x, buffer.height());
00744   painter.end();
00745 }
00746 
00747 void IndicatorPlot::getXY (int x, int y)
00748 {
00749   int i = convertXToDataIndex(x);
00750   data->getDate(i, x1);
00751   y1 = scaler.convertToVal(y);
00752 }
00753 
00754 int IndicatorPlot::convertXToDataIndex (int x)
00755 {
00756   int i = (x / pixelspace) + startIndex;
00757   if (i >= (int) data->count())
00758     i = data->count() - 1;
00759   if (i < startIndex)
00760     i = startIndex;
00761   
00762   return i;
00763 }
00764 
00765 void IndicatorPlot::updateStatusBar (int x, int y)
00766 {
00767   int i = convertXToDataIndex(x);
00768   QString s;
00769   Bar bar;
00770   data->getBar(i, bar);
00771   bar.getDateTimeString(TRUE, s);
00772   s.append(" ");
00773   QString str;
00774   strip(scaler.convertToVal(y), 4, str);
00775   s.append(str);
00776   emit statusMessage(s);
00777 }
00778 
00779 void IndicatorPlot::setScale ()
00780 {
00781   double scaleHigh = -99999999;
00782   double scaleLow = 99999999;
00783   bool pfFlag = FALSE;
00784 
00785   if (indy && indy->getEnable())
00786   {
00787     int loop;
00788     for (loop = 0; loop < indy->getLines(); loop++)
00789     {
00790       PlotLine *line = indy->getLine(loop);
00791       if (line->getType() == PlotLine::Invisible)
00792         continue;
00793 
00794       if (line->getScaleFlag())
00795         continue;
00796 
00797       if (line->getType() == PlotLine::PF)
00798         pfFlag = TRUE;
00799 
00800       if (! scaleToScreen)
00801       {
00802         if (line->getHigh() > scaleHigh)
00803           scaleHigh = line->getHigh();
00804 
00805         if (line->getLow() < scaleLow)
00806           scaleLow = line->getLow();
00807       }
00808       else
00809       {        
00810         int loop2 = line->getSize() - data->count() + startIndex;
00811         int end = (buffer.width() / pixelspace) + loop2;
00812         if (loop2 < 0)
00813           loop2 = 0;
00814         if (end > line->getSize())
00815           end = line->getSize();
00816 
00817         double h, l;
00818         line->getHighLowRange(loop2, end - 1, h, l);
00819         if (h > scaleHigh)
00820           scaleHigh = h;
00821         if (l < scaleLow)
00822           scaleLow = l;
00823       }
00824     }
00825   }
00826 
00827   if (! scaleToScreen)
00828   {
00829     QDictIterator<COBase> it(coList);
00830     for (; it.current(); ++it)
00831     {
00832       COBase *plug = it.current();
00833       
00834       if (plug->getHigh() > scaleHigh)
00835         scaleHigh = plug->getHigh();
00836         
00837       if (plug->getLow() < scaleLow)
00838         scaleLow = plug->getLow();
00839     }
00840   }
00841 
00842   // we need to make a little extra room at the top of the chart for P&F plots
00843   // if we don't, then the top X or O is lost
00844   if (pfFlag)
00845     scaleHigh = scaleHigh * 1.02;
00846 
00847 //  scaleLow = scaleLow * 0.999;
00848 
00849   double logScaleHigh = 1;
00850   double logRange = 0;
00851   if (logScale)
00852   {
00853     logScaleHigh = scaleHigh > 0.0 ? log(scaleHigh) : 1;
00854     double logScaleLow = scaleLow > 0.0 ? log(scaleLow) : 0;
00855     logRange = logScaleHigh - logScaleLow;
00856   }
00857 
00858   scaler.set(buffer.height(), scaleHigh, scaleLow, logScaleHigh, logRange, logScale);
00859 }
00860 
00861 int IndicatorPlot::getXFromDate (QDateTime &d)
00862 {
00863   int x2 = data->getX(d);
00864   if (x2 == -1)
00865     return -1;
00866 
00867   int x = startX + (x2 * pixelspace) - (startIndex * pixelspace);
00868 
00869   return x;
00870 }
00871 
00872 void IndicatorPlot::strip (double d, int p, QString &s)
00873 {
00874   if (fabs(d) < 1)
00875     s = QString::number(d, 'f', p);
00876   else
00877   {
00878     if (fabs(d) > 1000)
00879       s = QString::number(d, 'f', 0);
00880     else
00881       s = QString::number(d, 'f', 2);
00882   }
00883 
00884 /*
00885 s = QString::number(d, 'f', p);
00886 
00887   while (1)
00888   {
00889     if (s.find('.', -1, TRUE) != -1)
00890     {
00891       s.truncate(s.length() - 1);
00892       break;
00893     }
00894     else
00895     {
00896       if (s.find('0', -1, TRUE) != -1)
00897         s.truncate(s.length() - 1);
00898       else
00899         break;
00900     }
00901   }
00902 */
00903 }
00904 
00905 void IndicatorPlot::printChart ()
00906 {
00907   QPrinter printer;
00908   printer.setPageSize(QPrinter::Letter);
00909 
00910   if (printer.setup())
00911   {
00912     emit statusMessage(tr("Creating chart snapshot..."));
00913 
00914     printer.setFullPage(true);
00915     QSize margins = printer.margins();
00916     int leftMargin = margins.width();
00917     int topMargin  = margins.height();
00918 
00919     QPaintDeviceMetrics prm(&printer);
00920     
00921     int prmw = prm.width() - leftMargin;
00922     int prmh = prm.height() - topMargin;
00923 
00924     if ((buffer.width() > prmw) || (buffer.height() > prmh))
00925     {
00926       QImage image = buffer.convertToImage();
00927       image = image.smoothScale(prmw, prmh, QImage::ScaleMin);
00928       buffer.convertFromImage(image);
00929     }
00930 
00931     emit statusMessage(tr("Printing..."));
00932 
00933     QPainter painter;
00934     painter.begin(&printer);
00935     painter.drawPixmap(leftMargin/2, topMargin/2, buffer);
00936     painter.end();
00937     emit statusMessage(tr("Printing complete."));
00938   }
00939 }
00940 
00941 void IndicatorPlot::showPopupMenu ()
00942 {
00943   chartMenu->clear();
00944     
00945   chartMenu->insertItem(QPixmap(indicator), tr("New &Indicator"), this,
00946                         SLOT(slotNewIndicator()), CTRL+Key_I);
00947   chartMenu->insertItem(QPixmap(edit), tr("&Edit Indicator"), this, SLOT(slotEditIndicator()), CTRL+Key_E);
00948   chartMenu->insertItem(QPixmap(help), tr("Indicator &Help"), this, SLOT(slotIndicatorHelp()), CTRL+Key_H);
00949   chartMenu->insertSeparator ();
00950   chartMenu->insertItem(QPixmap(edit), tr("Edit &Chart"), this, SLOT(slotEditChart()), CTRL+Key_C);
00951   chartMenu->insertSeparator ();
00952 
00953   chartObjectMenu = new QPopupMenu();
00954   int id = chartObjectMenu->insertItem(QPixmap(buyarrow), "BuyArrow", this, SLOT(slotNewChartObject(int)));
00955   chartObjectMenu->setItemParameter(id, id);
00956   id = chartObjectMenu->insertItem(QPixmap(arc), "Cycle", this, SLOT(slotNewChartObject(int)));
00957   chartObjectMenu->setItemParameter(id, id);
00958   id = chartObjectMenu->insertItem(QPixmap(fib), "FiboLine", this, SLOT(slotNewChartObject(int)));
00959   chartObjectMenu->setItemParameter(id, id);
00960   id = chartObjectMenu->insertItem(QPixmap(horizontal), "HorizontalLine", this,
00961                                    SLOT(slotNewChartObject(int)));
00962   chartObjectMenu->setItemParameter(id, id);
00963   id = chartObjectMenu->insertItem(QPixmap(sellarrow), "SellArrow", this, SLOT(slotNewChartObject(int)));
00964   chartObjectMenu->setItemParameter(id, id);
00965   id = chartObjectMenu->insertItem(QPixmap(text), "Text", this, SLOT(slotNewChartObject(int)));
00966   chartObjectMenu->setItemParameter(id, id);
00967   id = chartObjectMenu->insertItem(QPixmap(trend), "TrendLine", this, SLOT(slotNewChartObject(int)));
00968   chartObjectMenu->setItemParameter(id, id);
00969   id = chartObjectMenu->insertItem(QPixmap(vertical), "VerticalLine", this, SLOT(slotNewChartObject(int)));
00970   chartObjectMenu->setItemParameter(id, id);
00971 
00972   id = chartMenu->insertItem (QPixmap(co), tr("New Chart Object"), chartObjectMenu);
00973   
00974   if (! drawMode || ! data)
00975     chartObjectMenu->setEnabled(FALSE);
00976   else
00977     chartObjectMenu->setEnabled(TRUE);
00978   
00979   chartMenu->insertItem(QPixmap(deleteitem), tr("Delete &All Chart Objects"), this,
00980                         SLOT(slotDeleteAllChartObjects()), CTRL+Key_A);
00981 
00982   chartMenu->insertSeparator ();
00983   chartMenu->insertItem(QPixmap(print), tr("&Print Chart"), this, SLOT(printChart()), CTRL+Key_P);
00984     
00985   id = chartMenu->insertItem(QPixmap(date), tr("Date"), this, SLOT(toggleDate()), CTRL+Key_D);
00986   chartMenu->setItemChecked(id, dateFlag);
00987 
00988   id = chartMenu->insertItem(QPixmap(loggridicon), tr("Log Scaling"), this, SLOT(toggleLog()), CTRL+Key_L);
00989   chartMenu->setItemChecked(id, logScale);
00990   
00991   chartMenu->exec(QCursor::pos());
00992 }
00993 
00994 void IndicatorPlot::toggleDate ()
00995 {
00996   if (dateFlag == FALSE)
00997     dateFlag = TRUE;
00998   else
00999     dateFlag = FALSE;
01000 
01001   if (indy)
01002   {
01003     Setting set;
01004     QString s;
01005     indy->getFile(s);
01006     config.getIndicator(s, set);
01007     QString k = "dateFlag";
01008     QString d = QString::number(dateFlag);
01009     set.setData(k, d);
01010     config.setIndicator(s, set);
01011   }
01012 
01013   emit signalDateFlag(dateFlag);
01014 }
01015 
01016 void IndicatorPlot::toggleLog ()
01017 {
01018   if (logScale == FALSE)
01019     logScale = TRUE;
01020   else
01021     logScale = FALSE;
01022 
01023   if (indy)
01024   {
01025     Setting set;
01026     QString s;
01027     indy->getFile(s);
01028     config.getIndicator(s, set);
01029     QString k = "logScale";
01030     QString d = QString::number(logScale);
01031     set.setData(k, d);
01032     config.setIndicator(s, set);
01033   }
01034 
01035   emit signalLogFlag(logScale);
01036 }
01037 
01038 void IndicatorPlot::setCrosshairsStatus (bool status)
01039 {
01040   crosshairs = status;
01041   crossHairFlag = FALSE;
01042   draw();
01043 }
01044 
01045 void IndicatorPlot::slotEditIndicator ()
01046 {
01047   if (indy)
01048   {
01049     QString s;
01050     indy->getName(s);
01051     emit signalEditIndicator(s);
01052   }
01053 }
01054 
01055 void IndicatorPlot::slotNewIndicator ()
01056 {
01057   emit signalNewIndicator();
01058 }
01059 
01060 void IndicatorPlot::slotMessage (QString d)
01061 {
01062   emit statusMessage(d);
01063 }
01064 
01065 void IndicatorPlot::slotSliderChanged (int v)
01066 {
01067   setIndex(v);
01068   draw();
01069 }
01070 
01071 void IndicatorPlot::slotGridChanged (bool d)
01072 {
01073   setGridFlag(d);
01074   draw();
01075 }
01076 
01077 void IndicatorPlot::slotScaleToScreenChanged (bool d)
01078 {
01079   setScaleToScreen(d);
01080   draw();
01081 }
01082 
01083 void IndicatorPlot::slotDrawModeChanged (bool d)
01084 {
01085   setDrawMode(d);
01086 }
01087 
01088 void IndicatorPlot::slotLogScaleChanged (bool d)
01089 {
01090   setLogScale(d);
01091   draw();
01092 }
01093 
01094 int IndicatorPlot::getWidth ()
01095 {
01096   return buffer.width();
01097 }
01098 
01099 void IndicatorPlot::slotEditChart ()
01100 {
01101   emit signalEditChart(chartPath);
01102 }
01103 
01104 void IndicatorPlot::slotIndicatorHelp ()
01105 {
01106   QString s, f;
01107   QString h = "indicator/intro.html";
01108   indy->getName(s);
01109   s.append(".html");
01110   // Convert to lowercase. The indicator names are case insensitive.
01111   // FIXME: Better to do case insensitive match for the file.
01112   s.lower();
01113   RcFile rcfile;
01114   rcfile.loadData(RcFile::UserDocsPath, userDocsPath);
01115   userDocsPath.append("/");
01116   rcfile.loadData(RcFile::HelpFilePath, helpFilePath);
01117   helpFilePath.append("/");
01118   QDir dir;
01119   // look for indicator doc first in the user docs,
01120   // then in main docs,
01121   // otherwise use the default "intro" page.
01122   f = userDocsPath + "indicator/" + s;
01123   if (dir.exists(f))
01124     h = f;
01125   else
01126   { 
01127     f = helpFilePath + "indicator/" + s;
01128     if (dir.exists(f))
01129       h = "indicator/" + s;
01130     else
01131     {
01132       // try old indicator docs location at top-level
01133       f = helpFilePath + s;
01134       if (dir.exists(f))
01135         h = s;
01136     }
01137   }
01138   HelpWindow *hw = new HelpWindow(this, h);
01139   hw->show();
01140 }
01141 
01142 //*************************************************************************
01143 //******************** draw line functions ********************************
01144 //*************************************************************************
01145 
01146 void IndicatorPlot::drawLine ()
01147 {
01148   QPainter painter;
01149   painter.begin(&buffer);
01150 
01151   QPen pen;
01152   QColor c;
01153   currentLine->getColor(c);
01154   pen.setColor(c);
01155 
01156   if (currentLine->getType() == PlotLine::Dash)
01157     pen.setStyle(Qt::DotLine);
01158   else
01159     pen.setStyle(Qt::SolidLine);
01160   painter.setPen(pen);
01161 
01162   int x = -1;
01163   int x2 = startX;
01164   int y = -1;
01165   int y2 = -1;
01166   int loop = currentLine->getSize() - data->count() + startIndex;
01167   
01168   Scaler scale;
01169   if (currentLine->getScaleFlag())
01170   {
01171     scale.set(scaler.getHeight(),
01172               currentLine->getHigh(),
01173               currentLine->getLow(),
01174               scaler.getLogScaleHigh(),
01175               scaler.getLogRange(),
01176               scaler.getLogFlag());
01177   }
01178 
01179   while ((x2 < buffer.width()) && (loop < (int) currentLine->getSize()))
01180   {
01181     if (loop > -1)
01182     {
01183       if (currentLine->getScaleFlag())
01184         y2 = scale.convertToY(currentLine->getData(loop));
01185       else
01186         y2 = scaler.convertToY(currentLine->getData(loop));
01187 
01188       if (y != -1)
01189         painter.drawLine (x, y, x2, y2);
01190       x = x2;
01191       y = y2;
01192     }
01193 
01194     x2 = x2 + pixelspace;
01195     loop++;
01196   }
01197 
01198   painter.end();
01199 }
01200 
01201 void IndicatorPlot::drawHorizontalLine ()
01202 {
01203   QPainter painter;
01204   painter.begin(&buffer);
01205 
01206   QPen pen;
01207   QColor c;
01208   currentLine->getColor(c);
01209   pen.setColor(c);
01210   painter.setPen(pen);
01211 
01212   int y = scaler.convertToY(currentLine->getData(currentLine->getSize() - 1));
01213 
01214   painter.drawLine (0, y, buffer.width(), y);
01215 
01216   QString s, s2;
01217   strip(currentLine->getData(currentLine->getSize() - 1), 4, s);
01218   currentLine->getLabel(s2);
01219   s = s2 + "=" + s;
01220   
01221   painter.setBackgroundMode(OpaqueMode);
01222   painter.setBackgroundColor(backgroundColor);
01223   painter.setFont(plotFont);
01224   
01225   QRect rc = painter.boundingRect(startX, y - (plotFontMetrics->height()/2) , 1, 1, AlignAuto, s, -1, 0);
01226   painter.drawText(rc, AlignAuto, s);
01227   painter.drawRect(rc);
01228   painter.end();
01229 }
01230 
01231 void IndicatorPlot::drawDot ()
01232 {
01233   QPainter painter;
01234   painter.begin(&buffer);
01235 
01236   QPen pen;
01237   QColor c;
01238   currentLine->getColor(c);
01239   pen.setColor(c);
01240   painter.setPen(pen);
01241 
01242   int x = startX;
01243   int loop = currentLine->getSize() - data->count() + startIndex;
01244   
01245   Scaler scale;
01246   if (currentLine->getScaleFlag())
01247   {
01248     scale.set(scaler.getHeight(),
01249               currentLine->getHigh(),
01250               currentLine->getLow(),
01251               scaler.getLogScaleHigh(),
01252               scaler.getLogRange(),
01253               scaler.getLogFlag());
01254   }
01255 
01256   while ((x < buffer.width()) && (loop < (int) currentLine->getSize()))
01257   {
01258     if (loop > -1)
01259     {
01260       int y;
01261       if (currentLine->getScaleFlag())
01262         y = scale.convertToY(currentLine->getData(loop));
01263       else
01264         y = scaler.convertToY(currentLine->getData(loop));
01265 
01266       painter.drawPoint(x, y);
01267     }
01268 
01269     x = x + pixelspace;
01270     loop++;
01271   }
01272 
01273   painter.end();
01274 }
01275 
01276 void IndicatorPlot::drawHistogram ()
01277 {
01278   QPainter painter;
01279   painter.begin(&buffer);
01280   QColor c;
01281   currentLine->getColor(c);
01282   painter.setPen(c);
01283   painter.setBrush(c);
01284 
01285   int loop = currentLine->getSize() - data->count() + startIndex;
01286 
01287   QPointArray pa(4);
01288 
01289   int zero = 0;
01290   Scaler scale;
01291   if (currentLine->getScaleFlag())
01292   {
01293     scale.set(scaler.getHeight(),
01294               currentLine->getHigh(),
01295               currentLine->getLow(),
01296               scaler.getLogScaleHigh(),
01297               scaler.getLogRange(),
01298               scaler.getLogFlag());
01299     zero = scale.convertToY(0);
01300   }
01301   else
01302     zero = scaler.convertToY(0);
01303 
01304   int x = -1;
01305   int x2 = startX;
01306   int y = -1;
01307   int y2 = -1;
01308 
01309   while ((x < buffer.width()) && (loop < (int) currentLine->getSize()))
01310   {
01311     if (loop > -1)
01312     {
01313       if (currentLine->getScaleFlag())
01314         y2 = scale.convertToY(currentLine->getData(loop));
01315       else
01316         y2 = scaler.convertToY(currentLine->getData(loop));
01317       pa.setPoint(0, x, zero);
01318       pa.setPoint(1, x, y);
01319       pa.setPoint(2, x2, y2);
01320       pa.setPoint(3, x2, zero);
01321 
01322       if (y != -1)
01323         painter.drawPolygon(pa, TRUE, 0, -1);
01324 
01325       x = x2;
01326       y = y2;
01327     }
01328 
01329     x2 = x2 + pixelspace;
01330     loop++;
01331   }
01332 
01333   painter.end();
01334 }
01335 
01336 void IndicatorPlot::drawHistogramBar ()
01337 {
01338   QPainter painter;
01339   painter.begin(&buffer);
01340 
01341   QColor color;
01342   currentLine->getColor(color);
01343 
01344   int x = startX;
01345   int zero = 0;
01346   Scaler scale;
01347   if (currentLine->getScaleFlag())
01348   {
01349     scale.set(scaler.getHeight(),
01350               currentLine->getHigh(),
01351               currentLine->getLow(),
01352               scaler.getLogScaleHigh(),
01353               scaler.getLogRange(),
01354               scaler.getLogFlag());
01355     zero = scale.convertToY(0);
01356   }
01357   else
01358     zero = scaler.convertToY(0);
01359 
01360   int loop = currentLine->getSize() - data->count() + startIndex;
01361 
01362   while ((x < buffer.width()) && (loop < (int) currentLine->getSize()))
01363   {
01364     if (loop > -1)
01365     {
01366       int y;
01367       if (currentLine->getScaleFlag())
01368         y = scale.convertToY(currentLine->getData(loop));
01369       else
01370         y = scaler.convertToY(currentLine->getData(loop));
01371 
01372       if (currentLine->getColorFlag() == TRUE)
01373         currentLine->getColorBar(loop, color);
01374 
01375       painter.fillRect(x, y, pixelspace - 1, zero - y, color);
01376     }
01377 
01378     x = x + pixelspace;
01379     loop++;
01380   }
01381 
01382   painter.end();
01383 }
01384 
01385 void IndicatorPlot::drawBar ()
01386 {
01387   QPainter painter;
01388   painter.begin(&buffer);
01389 
01390   int loop = currentLine->getSize() - data->count() + startIndex;
01391   int x = startX;
01392   double o = 0;
01393   double h = 0;
01394   double l = 0;
01395   double cl = 0;
01396   bool ff = FALSE;
01397   QColor c;
01398 
01399   while ((x < buffer.width()) && (loop < (int) currentLine->getSize()))
01400   {
01401     if (loop > -1)
01402     {
01403       currentLine->getData(loop, c, o, h, l, cl, ff);
01404 
01405       painter.setPen(c);
01406 
01407       int y = scaler.convertToY(o);
01408       painter.drawLine (x - 2, y, x, y);
01409 
01410       y = scaler.convertToY(cl);
01411       painter.drawLine (x + 2, y, x, y);
01412 
01413       y = scaler.convertToY(h);
01414       int y2 = scaler.convertToY(l);
01415       painter.drawLine (x, y, x, y2);
01416     }
01417 
01418     x = x + pixelspace;
01419     loop++;
01420   }
01421 
01422   painter.end();
01423 }
01424 
01425 void IndicatorPlot::drawCandle ()
01426 {
01427   QPainter painter;
01428   painter.begin(&buffer);
01429 
01430   int loop = currentLine->getSize() - data->count() + startIndex;
01431   int x = startX;
01432   double o = 0;
01433   double h = 0;
01434   double l = 0;
01435   double cl = 0;
01436   QColor c;
01437   bool ff = FALSE;
01438 
01439   while ((x < buffer.width()) && (loop < (int) currentLine->getSize()))
01440   {
01441     if (loop > -1)
01442     {
01443       currentLine->getData(loop, c, o, h, l, cl, ff);
01444 
01445       painter.setPen(c);
01446 
01447       int xh = scaler.convertToY(h);
01448       int xl = scaler.convertToY(l);
01449       int xc = scaler.convertToY(cl);
01450       int xo = scaler.convertToY(o);
01451 
01452       if (! ff)
01453       {
01454         painter.drawLine (x, xh, x, xc);
01455         painter.drawLine (x, xo, x, xl);
01456 
01457         if (xc == xo)
01458           painter.drawLine (x - 2, xo, x + 2, xo);
01459         else
01460           painter.drawRect(x - 2, xc, 5, xo - xc);
01461       }
01462       else
01463       {
01464         painter.drawLine (x, xh, x, xl);
01465       
01466         if (xc == xo)
01467           painter.drawLine (x - 2, xo, x + 2, xo);
01468         else
01469           painter.fillRect(x - 2, xo, 5, xc - xo, c);
01470       }
01471     }
01472 
01473     x = x + pixelspace;
01474     loop++;
01475   }
01476 
01477   painter.end();
01478 }
01479 
01480 void IndicatorPlot::drawPF ()
01481 {
01482   QPainter painter;
01483   painter.begin(&buffer);
01484 
01485   painter.setFont(plotFont);
01486   //QFontMetrics fm(plotFont);
01487 
01488   double box = 0;
01489   double h = 0;
01490   double l = 0;
01491   double cl = 0;
01492   QColor c;
01493   bool ff = FALSE;
01494   int x = startX;
01495   int loop = currentLine->getSize() - data->count() + startIndex;
01496 
01497   while ((x < buffer.width()) && (loop < (int) currentLine->getSize()))
01498   {
01499     if (loop > -1)
01500     {
01501       currentLine->getData(loop, c, box, h, l, cl, ff);
01502 
01503       painter.setPen(c);
01504 
01505       QString s = "O";
01506       if (ff)
01507         s = "X";
01508 
01509 //      int xh = scaler.convertToY(h);
01510 //      int xl = scaler.convertToY(l);
01511 
01512 //      painter.fillRect(x, xh, pixelspace - 1, xl - xh, c);
01513 
01514       // draw some separartor lines to simulate boxes
01515       double d = l;
01516 //      painter.setPen(backgroundColor);
01517       while (d <= h)
01518       {
01519         int y = scaler.convertToY(d);
01520         painter.drawText (x, y, s, -1);
01521         d = d + box;
01522 //        painter.drawLine (x, y, x + pixelspace - 1, y);
01523       }
01524     }
01525 
01526     x = x + pixelspace;
01527     loop++;
01528   }
01529 
01530   painter.end();
01531 }
01532 
01533 //*************************************************************************
01534 //******************** chart object functions *****************************
01535 //*************************************************************************
01536 
01537 void IndicatorPlot::slotNewChartObject (int id)
01538 {
01539   if (! chartPath.length())
01540     return;
01541     
01542   QDir dir;
01543   if (! dir.exists(chartPath))
01544     return;
01545 
01546   QString selection = chartObjectMenu->text(id);
01547 
01548   COBase tco;
01549   coSelected = tco.getCO(selection);
01550   if (! coSelected)
01551     return;
01552   
01553   coSelected->setData(data);
01554   QObject::connect(coSelected, SIGNAL(signalDraw()), this, SLOT(draw()));
01555   QObject::connect(coSelected, SIGNAL(signalRefresh()), this, SLOT(drawRefresh()));
01556   QObject::connect(coSelected, SIGNAL(message(QString)), this, SLOT(slotMessage(QString)));
01557   QObject::connect(coSelected, SIGNAL(signalObjectDeleted(QString)), this, SLOT(slotChartObjectDeleted(QString)));
01558   QObject::connect(coSelected, SIGNAL(signalSave(QString)), this, SLOT(saveChartObject(QString)));
01559 
01560   QFileInfo fi(chartPath);
01561   QString symbol = fi.fileName();
01562   DBIndexItem item;
01563   chartIndex->getIndexItem(symbol, item);
01564   QString s, name;
01565   item.getSymbol(s);
01566   chartIndex->getNewChartObjectName(s, name);
01567 
01568   coList.replace(name, coSelected);
01569 
01570   indy->getName(s);
01571   
01572   setCursor(QCursor(Qt::PointingHandCursor));
01573 
01574   mouseFlag = ClickWait;
01575 
01576   coSelected->newObject(s, name);
01577 }
01578 
01579 void IndicatorPlot::addChartObject (Setting &set)
01580 {
01581   COBase tco;
01582   COBase *co = tco.getCO(set);
01583   if (! co)
01584     return;
01585 
01586   co->setData(data);
01587   QObject::connect(co, SIGNAL(signalDraw()), this, SLOT(draw()));
01588   QObject::connect(co, SIGNAL(signalRefresh()), this, SLOT(drawRefresh()));
01589   QObject::connect(co, SIGNAL(message(QString)), this, SLOT(slotMessage(QString)));
01590   QObject::connect(co, SIGNAL(signalObjectDeleted(QString)), this, SLOT(slotChartObjectDeleted(QString)));
01591 
01592   QString s;
01593   QString k = "Name";
01594   set.getData(k, s);
01595   coList.replace(s, co);
01596 
01597   co->addObject(set);
01598 }
01599 
01600 void IndicatorPlot::drawObjects ()
01601 {
01602   QDictIterator<COBase> it(coList);
01603   for (; it.current(); ++it)
01604   {
01605     COBase *co = it.current();
01606     co->draw(buffer, scaler, startIndex, pixelspace, startX);
01607   }
01608 }
01609 
01610 void IndicatorPlot::slotDeleteAllChartObjects ()
01611 {
01612   if (! chartPath.length())
01613     return;
01614     
01615   QDir dir;
01616   if (! dir.exists(chartPath))
01617     return;
01618 
01619   if (! coList.count())
01620   {
01621     QMessageBox::information(this,
01622                              tr("Qtstalker: Delete All Chart Objects"),
01623                              tr("No chart objects to delete."));
01624     return;
01625   }
01626 
01627   emit signalDeleteAllCO();
01628     
01629   coList.clear();
01630 
01631   mouseFlag = None;
01632   draw();
01633 }
01634 
01635 void IndicatorPlot::setCrosshairsFlag (bool d)
01636 {
01637   crosshairs = d;
01638 }
01639 
01640 void IndicatorPlot::setScaler (Scaler &d)
01641 {
01642   scaler = d;
01643 }
01644 
01645 Scaler & IndicatorPlot::getScaler ()
01646 {
01647   return scaler;
01648 }
01649 
01650 void IndicatorPlot::slotChartObjectDeleted (QString d)
01651 {
01652   if (! chartPath.length())
01653     return;
01654     
01655   QDir dir;
01656   if (! dir.exists(chartPath))
01657     return;
01658 
01659   if (! coList.count())
01660     return;
01661 
01662   emit signalDeleteCO(d);    
01663 
01664   coList.remove(d);
01665 
01666   mouseFlag = None;
01667 
01668   draw();
01669 }
01670 
01671 void IndicatorPlot::saveChartObjects ()
01672 {
01673   if (! chartPath.length())
01674     return;
01675 
01676   QDictIterator<COBase> it(coList);
01677   for (; it.current(); ++it)
01678   {
01679     COBase *co = it.current();
01680     if (co->getSaveFlag())
01681     {
01682       Setting set;
01683       co->getSettings(set);
01684       emit signalSaveCO(set);
01685     }
01686   }
01687 }
01688 
01689 void IndicatorPlot::saveChartObject (QString name)
01690 {
01691   COBase *co = coList[name];
01692   if (! co)
01693     return;
01694 
01695   Setting set;
01696   co->getSettings(set);
01697   emit signalSaveCO(set);
01698 }
01699