src/ChartToolbar.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 "ChartToolbar.h"
00023 //#include "Config.h"
00024 //#include "RcFile.h"
00025 #include "BarData.h"
00026 #include "PrefDialog.h"
00027 #include <qtooltip.h>
00028 #include <qaccel.h>
00029 #include <qvalidator.h>
00030 #include "../pics/date.xpm"
00031 #include "../pics/next.xpm"
00032 
00033 ChartToolbar::ChartToolbar (QMainWindow *mw) : QToolBar (mw, "chartToolbar")
00034 {
00035   minPixelspace = 2;
00036   
00037   QString ts; // temporary string
00038   int ti;  // temporary integer
00039   
00040   ptDate = QDateTime::currentDateTime();
00041   
00042   BarData bd(ts);
00043   compressionCombo = new QComboBox(this);
00044   bd.getBarLengthList(compressionList);
00045   compressionCombo->insertStringList(compressionList, -1);
00046   rcfile.loadData(RcFile::BarLength, ti);
00047   compressionCombo->setCurrentItem((BarData::BarLength) ti);
00048   QToolTip::add(compressionCombo, tr("Bar Length (Compression)"));
00049   connect(compressionCombo, SIGNAL(activated(int)), this, SIGNAL(signalBarLengthChanged(int)));
00050 
00051   cmpsBtnM = new QToolButton(this); // compression button monthly
00052   QToolTip::add(cmpsBtnM, tr("Monthly Compression"));
00053   cmpsBtnM->setToggleButton(TRUE);
00054   connect(cmpsBtnM, SIGNAL(clicked()), this, SLOT(cmpsBtnMClicked()));
00055 
00056   cmpsBtnW = new QToolButton(this); // compression button weekly
00057   QToolTip::add(cmpsBtnW, tr("Weekly Compression"));
00058   cmpsBtnW->setToggleButton(TRUE);
00059   connect(cmpsBtnW, SIGNAL(clicked()), this, SLOT(cmpsBtnWClicked()));
00060   
00061   cmpsBtnD = new QToolButton(this); // compression button daily
00062   QToolTip::add(cmpsBtnD, tr("Daily Compression"));
00063   cmpsBtnD->setToggleButton(TRUE);
00064   connect(cmpsBtnD, SIGNAL(clicked()), this, SLOT(cmpsBtnDClicked()));
00065   
00066   cmpsBtn15 = new QToolButton(this); // compression button 15min
00067   QToolTip::add(cmpsBtn15, tr("15min Compression"));
00068   cmpsBtn15->setToggleButton(TRUE);
00069   connect(cmpsBtn15, SIGNAL(clicked()), this, SLOT(cmpsBtn15Clicked()));
00070   
00071   addSeparator();
00072 
00073   pixelspace = new QSpinBox(this);
00074   pixelspace->setRange(minPixelspace, 99);
00075   rcfile.loadData(RcFile::Pixelspace, ti);
00076   pixelspace->setValue(ti);
00077   connect (pixelspace, SIGNAL(valueChanged(int)), this, SIGNAL(signalPixelspaceChanged(int)));
00078   QToolTip::add(pixelspace, tr("Bar Spacing"));
00079 
00080  
00081   ps1Button = new QToolButton(this);
00082   connect(ps1Button, SIGNAL(clicked()), this, SLOT(ps1ButtonClicked()));
00083 
00084   ps2Button = new QToolButton(this);
00085   connect(ps2Button, SIGNAL(clicked()), this, SLOT(ps2ButtonClicked()));
00086 
00087   ps3Button = new QToolButton(this);
00088   connect(ps3Button, SIGNAL(clicked()), this, SLOT(ps3ButtonClicked()));
00089 
00090   addSeparator();
00091   
00092   barCount = new QLineEdit(this);
00093   // regexp: a non-zero digit followed by 0 to 4 other digits
00094   QRegExp rx("[1-9]\\d{0,4}");
00095   QValidator *rv = new QRegExpValidator(rx, this);
00096   barCount->setValidator(rv);
00097   rcfile.loadData(RcFile::BarsToLoad, ti);
00098   barCount->setText(QString::number(ti));
00099   QToolTip::add(barCount, tr("Total bars to load"));
00100   connect(barCount, SIGNAL(lostFocus()), this, SLOT(barsChangedValidate()));
00101   connect(barCount, SIGNAL(returnPressed()), this, SLOT(barsChanged()));
00102 
00103   addSeparator();
00104 
00105   ptdButton = new QToolButton(this);
00106   QToolTip::add(ptdButton, tr("Paper Trade Date"));
00107   ptdButton->setPixmap(date);
00108   connect(ptdButton, SIGNAL(clicked()), this, SLOT(paperTradeDate()));
00109 
00110   ptnButton = new QToolButton(this);
00111   QToolTip::add(ptnButton, tr("Load Next Bar"));
00112   ptnButton->setPixmap(next);
00113   connect(ptnButton, SIGNAL(clicked()), this, SLOT(paperTradeNextBar()));
00114 //  ptnButton->setFocusPolicy(QWidget::StrongFocus);
00115 
00116   slider = new QSlider(this);
00117   slider->setOrientation(Qt::Horizontal);
00118   connect (slider, SIGNAL(valueChanged(int)), this, SIGNAL(signalSliderChanged(int)));
00119   slider->setEnabled(FALSE);
00120   QToolTip::add(slider, tr("Pan Chart"));
00121 
00122   setStretchableWidget(slider);
00123   
00124   QAccel *a = new QAccel(mw);
00125   connect(a, SIGNAL(activated(int)), this, SLOT(slotAccel(int)));
00126   a->insertItem(CTRL+Key_End, ChartPannerFocus);
00127   a->insertItem(CTRL+Key_Plus, BarsLoadedFocus);
00128   a->insertItem(CTRL+Key_Minus, BarSpacingFocus);
00129   a->insertItem(CTRL+Key_Prior, BarLengthFocus);
00130   a->insertItem(CTRL+Key_B, ToolbarFocus);
00131   
00132   focusFlag = BarLengthFocus;
00133   
00134   connect(this, SIGNAL(orientationChanged( Orientation)), this, SLOT(slotOrientationChanged(Orientation)));
00135   
00136   setVerticallyStretchable(TRUE);
00137 }
00138 
00139 ChartToolbar::~ChartToolbar ()
00140 {
00141 }
00142 
00143 int ChartToolbar::getBars ()
00144 {
00145   bool ok;
00146   int t = barCount->text().toInt(&ok);
00147   if (ok)
00148     return t;
00149   else
00150     return 0;
00151 }
00152 
00153 void ChartToolbar::enableSlider (bool d)
00154 {
00155   slider->setEnabled(d);
00156 }
00157 
00158 void ChartToolbar::setPixelspace (int min, int d)
00159 {
00160   pixelspace->blockSignals(TRUE);
00161   pixelspace->setRange(min, 99);
00162   pixelspace->setValue(d);
00163   pixelspace->blockSignals(FALSE);
00164 }
00165 
00166 int ChartToolbar::getPixelspace ()
00167 {
00168   return pixelspace->value();
00169 }
00170 
00171 int ChartToolbar::getBarLengthInt ()
00172 {
00173   return compressionCombo->currentItem();
00174 }
00175 
00176 QString ChartToolbar::getBarLength ()
00177 {
00178   return compressionCombo->currentText();
00179 }
00180 
00181 int ChartToolbar::getSlider ()
00182 {
00183   return slider->value();
00184 }
00185 
00186 int ChartToolbar::setSliderStart (int width, int records)
00187 {
00188   int page = width / getPixelspace();
00189   int max = records - page;
00190   if (max < 0)
00191     max = 0;
00192   slider->blockSignals(TRUE);
00193   slider->setRange(0, records - 1);
00194   int rc = 0;
00195   
00196   if ((int) records < page)
00197     slider->setValue(0);
00198   else
00199   {
00200     slider->setValue(max + 1);
00201     rc = max + 1;
00202   }
00203   
00204   slider->blockSignals(FALSE);
00205   
00206   return rc;
00207 }
00208 
00209 void ChartToolbar::saveSettings ()
00210 { 
00211   rcfile.saveData(RcFile::BarsToLoad, getBars());
00212   rcfile.saveData(RcFile::BarLength, getBarLengthInt());
00213   rcfile.saveData(RcFile::Pixelspace, getPixelspace());
00214   //rcfile.savePoint(RcFile::ChartToolBarPos, pos());
00215   //FIXME: IMPORTANT- save all belonged to restore the position of the toolbar. maybe not here but in Qtstalker.cpp. Possible is this the way
00216   //http://doc.trolltech.com/3.3/qdockarea.html#operator-lt-lt
00217 }
00218 
00219 void ChartToolbar::slotSetButtonView ()
00220 {
00221   // do all relating to visual aspekts
00222   
00223   QString ts;    // temporary variables
00224   int ti;
00225   bool tb;
00226   
00227   rcfile.loadData(RcFile::ShowCmpsComboBox, tb);
00228   if (tb) compressionCombo->show();
00229   else compressionCombo->hide();
00230   
00231   rcfile.loadData(RcFile::ShowCmps15Btn, tb);
00232   if (tb) cmpsBtn15->show();
00233   else cmpsBtn15->hide();
00234   cmpsBtn15->setText("15");
00235   
00236   rcfile.loadData(RcFile::ShowCmpsDayBtn, tb);
00237   if (tb) cmpsBtnD->show();
00238   else cmpsBtnD->hide();
00239   cmpsBtnD->setText("D");
00240   cmpsBtnD->setOn(TRUE); // FIXME: Need to save state on quit() and re-load
00241   
00242   rcfile.loadData(RcFile::ShowCmpsWkyBtn, tb);
00243   if (tb) cmpsBtnW->show();
00244   else cmpsBtnW->hide();
00245   cmpsBtnW->setText("W");
00246 
00247   rcfile.loadData(RcFile::ShowCmpsMtyBtn, tb);
00248   if (tb) cmpsBtnM->show();
00249   else cmpsBtnM->hide();
00250   cmpsBtnM->setText("M");
00251 
00252   rcfile.loadData(RcFile::ShowBarSpSpinbox, tb);
00253   if (tb) pixelspace->show();
00254   else pixelspace->hide();
00255   pixelspace->setMaximumWidth(40); // FIXME:calc as a function of app font metrics
00256   
00257   rcfile.loadData(RcFile::PSButton, ti, 1);
00258   ts = QString::number(ti);
00259   QToolTip::add(ps1Button, tr("Set Bar Spacing to " + ts));
00260   ps1Button->setText(ts);
00261   
00262   rcfile.loadData(RcFile::PSButton, ti, 2);
00263   ts = QString::number(ti);
00264   QToolTip::add(ps2Button, tr("Set Bar Spacing to " + ts));
00265   ps2Button->setText(ts);
00266   
00267   rcfile.loadData(RcFile::PSButton, ti, 3);
00268   ts = QString::number(ti);
00269   QToolTip::add(ps3Button, tr("Set Bar Spacing to " + ts));
00270   ps3Button->setText(ts);
00271   
00272   rcfile.loadData(RcFile::ShowBarsToLoadField, tb);
00273   if (tb) barCount->show();
00274   else barCount->hide();
00275   barCount->setMaximumWidth(40);// FIXME:calc as a function of app font metrics
00276   
00277   rcfile.loadData(RcFile::ShowSlider, tb);
00278   if (tb) slider->show();
00279   else slider->hide();
00280   
00281 }
00282 void ChartToolbar::setFocus ()
00283 {
00284   compressionCombo->setFocus();
00285   focusFlag = BarLengthFocus;
00286 }
00287 
00288 void ChartToolbar::slotAccel (int id)
00289 {
00290   switch (id)
00291   {
00292     case BarLengthFocus:
00293       compressionCombo->setFocus();
00294       focusFlag = BarLengthFocus;
00295       break;  
00296     case ChartPannerFocus:
00297       slider->setFocus();
00298       focusFlag = ChartPannerFocus;
00299       break;  
00300     case BarsLoadedFocus:
00301       barCount->setFocus();
00302       focusFlag = BarsLoadedFocus;
00303       break;  
00304     case BarSpacingFocus:
00305       pixelspace->setFocus();
00306       focusFlag = BarSpacingFocus;
00307       break;  
00308     case ToolbarFocus:
00309       setFocus();
00310       break;
00311     default:
00312       break;
00313   }
00314 }
00315 
00316 void ChartToolbar::doKeyPress (QKeyEvent *key)
00317 {
00318   key->accept();
00319   
00320   if (! key->state())
00321   {
00322     switch(focusFlag)
00323     {
00324       case BarLengthFocus:
00325 //        compressionCombo->doKeyPress(key);
00326         break;
00327       case BarSpacingFocus:
00328 //        pixelspace->doKeyPress(key);
00329         break;
00330       case BarsLoadedFocus:
00331 //        barCount->doKeyPress(key);
00332         break;
00333       case ChartPannerFocus:
00334 //        slider->doKeyPress(key);
00335         break;
00336       default:
00337         break;
00338     }
00339   }
00340   else
00341   {
00342     if (key->state() == Qt::ControlButton)
00343     {
00344       switch (key->key())
00345       {
00346         case Qt::Key_Prior:
00347           slotAccel(BarLengthFocus);
00348           break;
00349         case Qt::Key_Plus:
00350           slotAccel(BarsLoadedFocus);
00351           break;
00352         case Qt::Key_End:
00353           slotAccel(ChartPannerFocus);
00354           break;
00355         case Qt::Key_Minus:
00356           slotAccel(BarSpacingFocus);
00357           break;
00358         case Qt::Key_B:
00359           slotAccel(ToolbarFocus);
00360           break;
00361         default:
00362           break;
00363       }
00364     }
00365   }
00366 }
00367 
00368 void ChartToolbar::barsChanged ()
00369 {
00370   bool ok;
00371   int t = barCount->text().toInt(&ok);
00372   if (ok)
00373     emit signalBarsChanged(t);
00374 }
00375 
00376 void ChartToolbar::barsChangedValidate ()
00377 {
00378   // The barCount validator ensures non-zero integer value, but if users moves
00379   // focus without completing the text entry, then app can try to load zero bars
00380   // which would cause grief.
00381   bool ok;
00382   int t = barCount->text().toInt(&ok);
00383   if (!ok || t == 0)
00384     barCount->setText("250");
00385 }
00386 
00387 void ChartToolbar::ps1ButtonClicked ()
00388 {
00389   //RcFile rcfile;
00390   int ti;
00391   rcfile.loadData(RcFile::PSButton, ti, 1);
00392 //  setPixelspace(minPixelspace, s.toInt());
00393 //  emit signalBarLengthChanged(compressionCombo->currentItem());
00394   pixelspace->setValue(ti);
00395   //emit signalBarsChanged(0);
00396 //  emit signalPaperTradeNextBar();
00397 }
00398 
00399 void ChartToolbar::ps2ButtonClicked ()
00400 {
00401   //RcFile rcfile;
00402   int ti;
00403   rcfile.loadData(RcFile::PSButton, ti, 2);
00404 //  setPixelspace(minPixelspace, s.toInt());
00405 //  emit signalBarLengthChanged(compressionCombo->currentItem());
00406   pixelspace->setValue(ti);
00407   //emit signalBarsChanged(0);
00408 //  emit signalPaperTradeNextBar();
00409 }
00410 
00411 void ChartToolbar::ps3ButtonClicked ()
00412 {
00413   //RcFile rcfile;
00414   int ti;
00415   rcfile.loadData(RcFile::PSButton, ti, 3);
00416 //  setPixelspace(minPixelspace, s.toInt());
00417 //  emit signalBarLengthChanged(compressionCombo->currentItem());
00418   pixelspace->setValue(ti);
00419   //emit signalBarsChanged(0);
00420 //  emit signalPaperTradeNextBar();
00421 }
00422 
00423 void ChartToolbar::cmpsBtnMClicked()
00424 {
00425   compressionCombo->setCurrentItem((BarData::BarLength)8);
00426   // FIXME: Sorry about the repetitive code.
00427   cmpsBtnW->setOn(FALSE);
00428   cmpsBtnD->setOn(FALSE);
00429   cmpsBtn15->setOn(FALSE);
00430   emit signalBarLengthChanged((int)8);
00431 }
00432 
00433 void ChartToolbar::cmpsBtnWClicked()
00434 {
00435   compressionCombo->setCurrentItem((BarData::BarLength)7);
00436   // FIXME: Sorry about the repetitive code.
00437   cmpsBtnM->setOn(FALSE);
00438   cmpsBtnD->setOn(FALSE);
00439   cmpsBtn15->setOn(FALSE);
00440   emit signalBarLengthChanged((int)7);
00441 }
00442 
00443 void ChartToolbar::cmpsBtnDClicked()
00444 {
00445   compressionCombo->setCurrentItem((BarData::BarLength)6);
00446   // FIXME: Sorry about the repetitive code.
00447   cmpsBtnM->setOn(FALSE);
00448   cmpsBtnW->setOn(FALSE);
00449   cmpsBtn15->setOn(FALSE);
00450   emit signalBarLengthChanged((int)6);
00451 }
00452 
00453 void ChartToolbar::cmpsBtn15Clicked()
00454 {
00455   compressionCombo->setCurrentItem((BarData::BarLength)3);
00456   // FIXME: Sorry about the repetitive code.
00457   cmpsBtnM->setOn(FALSE);
00458   cmpsBtnW->setOn(FALSE);
00459   cmpsBtnD->setOn(FALSE);
00460   emit signalBarLengthChanged((int)3);
00461 }
00462 
00463 void ChartToolbar::slotOrientationChanged(Orientation o)
00464 {
00465     slider->setOrientation(o);
00466    // updateGeometry();
00467 
00468  // if(o)
00469  // {
00470     
00471  // }
00472 }
00473 
00474 //*********************************************************************
00475 //******************** paper trade stuff ******************************
00476 //*********************************************************************
00477 
00478 void ChartToolbar::getPaperTradeDate (QDateTime &d)
00479 {
00480   d = ptDate;
00481 }
00482 
00483 void ChartToolbar::paperTradeDate ()
00484 {
00485   QString dl = tr("Last Date");
00486   QString tl = tr("Last Time");
00487   QString pl = "Date";
00488 
00489   PrefDialog *dialog = new PrefDialog(this);
00490   dialog->setCaption(tr("Paper trade date select."));
00491   dialog->createPage (pl);
00492   dialog->addDateItem(dl, pl, ptDate);
00493   dialog->addTimeItem(tl, pl, ptDate);
00494 
00495   int rc = dialog->exec();
00496 
00497   if (rc == QDialog::Accepted)
00498   {
00499     QDateTime dt;
00500     dialog->getDate(dl, dt);
00501     ptDate.setDate(dt.date());
00502 
00503     dialog->getDate(tl, dt);
00504     ptDate.setTime(dt.time());
00505 
00506     emit signalPaperTradeNextBar();
00507   }
00508 
00509   delete dialog;
00510 }
00511 
00512 void ChartToolbar::paperTradeClicked (bool d)
00513 {
00514   if (d)
00515   {
00516     ptdButton->show();
00517     ptnButton->show();
00518     barCount->setEnabled(FALSE);
00519   }
00520   else
00521   {
00522     ptdButton->hide();
00523     ptnButton->hide();
00524     barCount->setEnabled(TRUE);
00525   }
00526 }
00527 
00528 void ChartToolbar::paperTradeNextBar ()
00529 {
00530   if (ptdButton->isHidden())
00531     return;
00532 
00533   switch (compressionCombo->currentItem())
00534   {
00535     case 0:
00536       ptDate = ptDate.addSecs(60);
00537       break;
00538     case 1:
00539       ptDate = ptDate.addSecs(300);
00540       break;
00541     case 2:
00542       ptDate = ptDate.addSecs(600);
00543       break;
00544     case 3:
00545       ptDate = ptDate.addSecs(900);
00546       break;
00547     case 4:
00548       ptDate = ptDate.addSecs(1800);
00549       break;
00550     case 5:
00551       ptDate = ptDate.addSecs(3600);
00552       break;
00553     case 6: // daily
00554       ptDate = ptDate.addDays(1);
00555       if (ptDate.date().dayOfWeek() == 6)
00556         ptDate = ptDate.addDays(2);
00557       else
00558       {
00559         if (ptDate.date().dayOfWeek() == 7)
00560           ptDate = ptDate.addDays(1);
00561       }
00562       break;
00563     case 7: // weekly
00564       ptDate = ptDate.addDays(7);
00565       break;
00566     case 8: // monthly
00567       ptDate = ptDate.addMonths(1);
00568       break;
00569     default:
00570       break;
00571   }
00572   
00573   emit signalPaperTradeNextBar();
00574 }