TranslationAbout::TranslationAbout(QWidget *) : QDialog() { ui.setupUi(this); setWindowFlags(Qt::WindowCloseButtonHint); setWindowModality(Qt::ApplicationModal); setAttribute(Qt::WA_DeleteOnClose,true); //setFixedSize(size()); #ifdef Q_OS_WIN if(QtWin::isCompositionEnabled()) QtWin::extendFrameIntoClientArea(this); #endif #ifdef GENERATE_LANGUAGE_FILE julyTranslator->loadMapFromUi(this); julyTranslator->saveToFile("LanguageDefault.lng"); #endif julyTranslator->translateUi(this); ui.languageField->setText(julyTr("LANGUAGE_NAME","Invalid Language")); ui.translationAuthor->setText(julyTr("LANGUAGE_AUTHOR","Invalid About")); ui.aboutBitcoinTraderGroupBox->setTitle(julyTr("ABOUT_QT_BITCOIN_TRADER","About %1").arg(windowTitle())); ui.aboutTextLabel->setText(julyTr("ABOUT_QT_BITCOIN_TRADER_TEXT","Qt Bitcoin Trader is a free Open Source project<br>developed on C++ Qt and OpenSSL.<br>If you want to help make project better please donate: %1<br>Feel free to send me recommendations and fixes to: %2").arg("<a href=\"bitcoin:1d6iMwjjNo8ZGYeJBZKXgcgVk9o7fXcjc\">1d6iMwjjNo8ZGYeJBZKXgcgVk9o7fXcjc</a>").arg("<a href=\"mailto:[email protected]\">[email protected]</a>")); }
AllExchangesModel::AllExchangesModel() : QAbstractItemModel() { rowsCount=0; columnsCount=2; headerList.append(julyTr("NAME","Name")); headerList.append(julyTr("SUPPORTED_CUEEENCIRS","Supported currencies")); }
void TranslationAbout::showWindow() { julyTranslator.translateUi(this); setWindowTitle("Qt Bitcon Trader v"+baseValues.appVerStr); ui.languageField->setText(julyTr("LANGUAGE_NAME","Invalid Language")); ui.translationAuthor->setText(julyTr("LANGUAGE_AUTHOR","Invalid About")); ui.aboutBitcoinTraderGroupBox->setTitle(julyTr("ABOUT_QT_BITCOIN_TRADER","About %1").arg("Qt Bitcon Trader")); ui.aboutTextLabel->setText(julyTr("ABOUT_QT_BITCOIN_TRADER_TEXT","Qt Bitcoin Trader is a free Open Source project<br>developed on C++ Qt and OpenSSL.<br>If you want to help make project better please donate.<br>Feel free to send me recommendations and fixes to: %1").arg("<a href=\"mailto:[email protected]\">[email protected]</a>")); show(); }
void RulesModel::setHorizontalHeaderLabels(QStringList list) { if(list.count()!=columnsCount)return; headerLabels=list; stateWidth=qMax(textFontWidth(headerLabels.first()),textFontWidth(julyTr("RULE_STATE_PROCESSING","processing"))); stateWidth=qMax(stateWidth,textFontWidth(julyTr("RULE_STATE_PENDING","pending"))); stateWidth=qMax(stateWidth,textFontWidth(julyTr("RULE_STATE_DONE","done"))); stateWidth=qMax(stateWidth,textFontWidth(julyTr("RULE_STATE_DISABLED","disabled"))); stateWidth+=12; emit headerDataChanged(Qt::Horizontal, 0, columnsCount-1); }
void TradesModel::setHorizontalHeaderLabels(QStringList list) { if(list.count()!=columnsCount)return; textAsk=julyTr("ORDER_TYPE_ASK","ask"); textBid=julyTr("ORDER_TYPE_BID","bid"); dateWidth=qMax(qMax(textFontWidth(QDateTime(QDate(2000,12,30),QTime(23,59,59,999)).toString(baseValues.dateTimeFormat)),textFontWidth(QDateTime(QDate(2000,12,30),QTime(12,59,59,999)).toString(baseValues.dateTimeFormat))),textFontWidth(list.at(0)))+10; typeWidth=qMax(qMax(textFontWidth(textAsk),textFontWidth(textBid)),textFontWidth(list.at(2)))+10; headerLabels=list; emit headerDataChanged(Qt::Horizontal, 0, columnsCount-1); emit layoutChanged(); }
void TranslationDialog::deleteTranslationButton() { QMessageBox msgBox(this); msgBox.setIcon(QMessageBox::Question); msgBox.setWindowTitle(julyTr("MESSAGE_CONFIRM_DELETE_TRANSLATION","Please confirm removing file")); msgBox.setText(julyTr("MESSAGE_CONFIRM_DELETE_TRANSLATION_TEXT","Are you sure to delete translation file?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); if(msgBox.exec()!=QMessageBox::Yes)return; if(QFile::exists(julyTranslator->lastFile()))QFile::remove(julyTranslator->lastFile()); ui.deleteTranslationButton->setEnabled(QFile::exists(julyTranslator->lastFile())); mainWindow.reloadLanguageList(); close(); }
QVariant RulesModel::data(const QModelIndex &index, int role) const { if(!index.isValid())return QVariant(); int currentRow=index.row(); if(currentRow<0||currentRow>=holderList.count())return QVariant(); if(role!=Qt::DisplayRole&&role!=Qt::ToolTipRole&&role!=Qt::ForegroundRole&&role!=Qt::BackgroundRole&&role!=Qt::TextAlignmentRole)return QVariant(); int indexColumn=index.column(); if(role==Qt::TextAlignmentRole)return 0x0084; if(role==Qt::ForegroundRole)return baseValues.appTheme.black; if(role==Qt::BackgroundRole) { switch(stateList.at(currentRow)) { case 1: return QVariant(); break; case 2: return baseValues.appTheme.lightRedGreen; break; case 3: return baseValues.appTheme.lightGreen; break; default: return baseValues.appTheme.lightRed; break; } return QVariant(); } switch(indexColumn) { case 0://State switch(stateList.at(currentRow)) { case 1: { if(pauseList.at(currentRow))return julyTr("RULE_STATE_PAUSED","paused"); return julyTr("RULE_STATE_PROCESSING","processing"); } break; case 2: return julyTr("RULE_STATE_PENDING","pending"); break; case 3: return julyTr("RULE_STATE_DONE","done"); break; default: return julyTr("RULE_STATE_DISABLED","disabled");break; } case 1://Description return holderList.at(currentRow).description; break; default: break; } return QVariant(); }
void TimeSync::getNTPTime() { QUdpSocket sock; sock.connectToHost("0.pool.ntp.org",123); if(!sock.waitForConnected(1000))return; QByteArray data(48,char(0)); *(reinterpret_cast<qint32 *>(&data.data()[0]))=4194959577; if(sock.write(data)<0||!sock.waitForReadyRead(3000)||sock.bytesAvailable()!=48)return; data=sock.readAll(); quint32 seconds=qToBigEndian(*(reinterpret_cast<quint32 *>(&data.data()[40]))); quint32 fraction=qToBigEndian(*(reinterpret_cast<quint32 *>(&data.data()[44]))); quint32 newTime=QDateTime::fromMSecsSinceEpoch(seconds*1000ll+fraction*1000ll/0x100000000ll-2208988800000ll).toTime_t(); if(newTime<1451606400 || newTime>4000000000){ QThread::msleep(500); emit startSync(); return; } qint32 tempTimeShift=qint64(newTime)-qint64(QDateTime::currentDateTime().toTime_t()); if(timeShift!=0)tempTimeShift=qint32((qint64(timeShift)+qint64(tempTimeShift))/2); if(tempTimeShift>3600 || tempTimeShift<-3600){ static bool showMessage=true; if(showMessage)emit warningMessage(julyTr("TIME_SYNC_ERROR","Your clock is not set. Please close the Qt Bitcoin Trader and set the clock. Changing time at Qt Bitcoin Trader enabled can cause errors and damage the keys.")); showMessage=false; } else timeShift.fetchAndStoreOrdered(tempTimeShift); getNTPTimeRetryCount++; if(getNTPTimeRetryCount<3)emit startSync(); }
void RuleWidget::on_ruleSave_clicked() { QString lastRulesDir=mainWindow.iniSettings->value("UI/LastRulesPath",baseValues.desktopLocation).toString(); if(!QFile::exists(lastRulesDir))lastRulesDir=baseValues.desktopLocation; QString fileName=QFileDialog::getSaveFileName(baseValues.mainWindow_, julyTr("SAVE_GOUP","Save Rules Group"),lastRulesDir+"/"+QString(groupName).replace("/","_").replace("\\","").replace(":","").replace("?","")+".JLR","JL Ruels (*.JLR)"); if(fileName.isEmpty())return; mainWindow.iniSettings->setValue("UI/LastRulesPath",QFileInfo(fileName).dir().path()); mainWindow.iniSettings->sync(); if(QFile::exists(fileName))QFile::remove(fileName); QSettings saveScript(fileName,QSettings::IniFormat); saveScript.beginGroup("JLRuleGroup"); saveScript.setValue("Version",baseValues.jlScriptVersion); saveScript.setValue("Name",groupName); saveScript.endGroup(); for(int n=0;n<rulesModel->holderList.count();n++) RuleScriptParser::writeHolderToSettings(rulesModel->holderList[n],saveScript,"Rule_"+QString::number(n+101)); saveScript.sync(); if(!QFile::exists(fileName)) { QMessageBox::warning(baseValues.mainWindow_,windowTitle(),"Can not write file"); return; } }
bool RuleWidget::agreeRuleImmediately(QString text) { text.replace(QLatin1Char('<'),QLatin1String("<")); text.replace(QLatin1Char('='),QLatin1String("=")); text.replace(QLatin1Char('>'),QLatin1String(">")); QMessageBox msgBox(baseValues.mainWindow_); msgBox.setIcon(QMessageBox::Question); msgBox.setWindowTitle(windowTitle()); msgBox.setText(julyTr("INVALID_RULE_CHECK","This rule will be executed instantly.<br>This means that you make a mistake.<br>Please check values you entered.")+"<br><br>\""+text+"\""); msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.setButtonText(QMessageBox::Ok,julyTr("RULE_ENABLE","Enable Rule")); msgBox.setButtonText(QMessageBox::Cancel,julyTranslator.translateButton("TRCANCEL","Cancel")); return msgBox.exec()==QMessageBox::Ok; }
AllExchangesDialog::AllExchangesDialog() : QDialog() { startIndex=1; exchangeNum=-1; ui.setupUi(this); ui.okButton->setEnabled(false); setWindowFlags(Qt::WindowCloseButtonHint); setWindowTitle("Qt Bitcoin Trader v"+baseValues.appVerStr+" - "+julyTr("ALL_EXCHANGES","All Exchanges")); QSettings listSettings(":/Resources/Exchanges/List.ini",QSettings::IniFormat); QStringList exchangesList=listSettings.childGroups(); allExchangesModel=new AllExchangesModel; ui.exchangesTableView->setModel(allExchangesModel); for(int n=startIndex;n<exchangesList.count();n++) { QString currentName=listSettings.value(exchangesList.at(n)+"/Name").toString(); if(currentName.isEmpty())continue; allExchangesModel->addExchange(n, currentName, loadCurrencies(currentName)); } mainWindow.setColumnResizeMode(ui.exchangesTableView,0,QHeaderView::ResizeToContents); mainWindow.setColumnResizeMode(ui.exchangesTableView,1,QHeaderView::Stretch); connect(ui.exchangesTableView->selectionModel(),SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),this,SLOT(selectionExchange())); julyTranslator.translateUi(this); mainWindow.fixTableViews(this); }
void RuleWidget::on_ruleRemoveAll_clicked() { QMessageBox msgBox(baseValues.mainWindow_); msgBox.setIcon(QMessageBox::Question); msgBox.setWindowTitle(julyTr("APPLICATION_TITLE",windowTitle())); msgBox.setText(julyTr("RULE_CONFIRM_REMOVE_ALL","Are you sure to remove all rules?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); msgBox.setButtonText(QMessageBox::Yes,julyTr("YES","Yes")); msgBox.setButtonText(QMessageBox::No,julyTr("NO","No")); if(msgBox.exec()!=QMessageBox::Yes)return; rulesModel->clear(); checkValidRulesButtons(); saveRulesData(); }
void TranslationDialog::applyButton() { QStringList resultList; for(int n=0;n<lineEdits.count();n++) { QString curText=lineEdits.at(n)->getValidText(); if(curText.isEmpty()) { ui.buttonSaveAs->setEnabled(false); QMessageBox::warning(this,windowTitle(),julyTr("LANGUAGE_NOT_APPROVED","Please fill empty fields")); return; } resultList<<lineEdits.at(n)->toolTip()+"="+curText; } resultList<<"String_LANGUAGE_NAME="+ui.languageName->text(); resultList<<"String_LANGUAGE_AUTHOR="+authorAbout->getValidText(); resultList<<"String_LANGUAGE_LOCALE="+locale().name(); QFile writeFile(appDataDir+"Language/Custom.lng"); writeFile.open(QIODevice::WriteOnly|QIODevice::Truncate); writeFile.write(resultList.join("\r\n").toUtf8()); writeFile.close(); if(mainWindow_)mainWindow.reloadLanguageList(appDataDir+"Language/Custom.lng"); ui.buttonSaveAs->setEnabled(true); ui.buttonApply->setEnabled(false); ui.deleteTranslationButton->setEnabled(QFile::exists(appDataDir+"Language/Custom.lng")); }
void ChartsView::clearCharts() { refreshTimer->stop(); sceneCharts->clear(); drawText(julyTr("CHARTS_WAITING_FOR_DATA","Waiting for data..."),0,0,"font-size:28px;color:"+baseValues.appTheme.gray.name()); sceneCharts->setSceneRect(sceneCharts->itemsBoundingRect()); refreshTimer->start(5000); }
void FeeCalculator::languageChanged() { julyTranslator.translateUi(this); setWindowTitle(julyTr("FEE_CALCULATOR_TITLE","Calculator")); mainWindow.fixAllChildButtonsAndLabels(this); QSize minSizeHint=minimumSizeHint(); if(mainWindow.isValidSize(&minSizeHint))setMaximumSize(minimumSizeHint().width()+200,minimumSizeHint().height()); }
void RuleWidget::on_ruleRemove_clicked() { QMessageBox msgBox(baseValues.mainWindow_); msgBox.setIcon(QMessageBox::Question); msgBox.setWindowTitle(julyTr("APPLICATION_TITLE",windowTitle())); msgBox.setText(julyTr("RULE_CONFIRM_REMOVE","Are you sure to remove this rule?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); msgBox.setButtonText(QMessageBox::Yes,julyTr("YES","Yes")); msgBox.setButtonText(QMessageBox::No,julyTr("NO","No")); if(msgBox.exec()!=QMessageBox::Yes)return; QModelIndexList selectedRows=ui.rulesTable->selectionModel()->selectedRows(); if(selectedRows.count()==0)return; int curRow=selectedRows.first().row(); rulesModel->removeRuleByRow(curRow); checkValidRulesButtons(); saveRulesData(); }
void TranslationDialog::saveAsButton() { applyButton(); if(ui.buttonSaveAs->isEnabled()==false)return; QString fileName=QFileDialog::getSaveFileName(this, julyTr("SAVE_TRANSLATION","Save Translation"),QDesktopServices::storageLocation(QDesktopServices::DesktopLocation)+"/"+ui.languageName->text().replace("/","_").replace("\\","").replace(":","").replace("?","")+".lng","(*.lng)"); if(fileName.isEmpty())return; if(QFile::exists(fileName))QFile::remove(fileName); QFile::copy(julyTranslator->lastFile(),fileName); }
bool ChartsView::prepareCharts() { int width=ui.graphicsView->width()-4; int height=ui.graphicsView->height()-4; if(width<550)width=550; if(height<220)height=220; if(!chartsModel->prepareChartsData(width,height))return false; int graphWidth=chartsModel->chartsWidth; int graphHeight=chartsModel->chartsHeight; sceneCharts->clear(); sceneCharts->setSceneRect(-chartsModel->widthAmountYAxis-2,-27,width,height); sceneCharts->addLine(0,0,graphWidth,0,QPen("#777777")); sceneCharts->addLine(0,0,0,graphHeight,QPen("#777777")); sceneCharts->addLine(graphWidth,0,graphWidth,graphHeight,QPen("#777777")); explainColor("- "+julyTr("CHARTS_BUY","Buy"),0.11*graphWidth,graphHeight+20,"#0000FF"); explainColor("- "+julyTr("CHARTS_SELL","Sell"),0.36*graphWidth,graphHeight+20,"#FF0000"); explainColor("- "+julyTr("CHARTS_SPREAD","Spread"),0.61*graphWidth,graphHeight+20,"#BFFFBF"); explainColor("- "+julyTr("CHARTS_AMOUNT","Amount"),0.86*graphWidth,graphHeight+20,"#777777"); for(qint32 i=0;i<chartsModel->graphDateText.count();i++){ sceneCharts->addLine(chartsModel->graphDateTextX.at(i),-5,chartsModel->graphDateTextX.at(i),0,QPen("#777777")); drawText(chartsModel->graphDateText.at(i),chartsModel->graphDateTextX.at(i)-17,-5); } for(qint32 i=0;i<chartsModel->graphAmountText.count();i++){ sceneCharts->addLine(-5,chartsModel->graphAmountTextY.at(i),0,chartsModel->graphAmountTextY.at(i),QPen("#777777")); drawText(chartsModel->graphAmountText.at(i),-chartsModel->widthAmountYAxis,chartsModel->graphAmountTextY.at(i)+11); } for(qint32 i=0;i<chartsModel->graphPriceText.count();i++){ if(i>0)sceneCharts->addLine(1,chartsModel->graphPriceTextY.at(i),graphWidth-1,chartsModel->graphPriceTextY.at(i),QPen("#DDDDDD")); sceneCharts->addLine(graphWidth,chartsModel->graphPriceTextY.at(i),graphWidth+5,chartsModel->graphPriceTextY.at(i),QPen("#777777")); drawText(chartsModel->graphPriceText.at(i),graphWidth+7,chartsModel->graphPriceTextY.at(i)+11); } return true; }
ChartsView::ChartsView():QWidget() { ui.setupUi(this); ui.graphicsView->scale(1,-1); sceneCharts=new QGraphicsScene; ui.graphicsView->setScene(sceneCharts); drawText(julyTr("CHARTS_WAITING_FOR_DATA","Waiting for data..."),0,0,"font-size:28px;color:"+baseValues.appTheme.gray.name()); chartsModel=new ChartsModel; refreshTimer=new QTimer; connect(refreshTimer,SIGNAL(timeout()),this,SLOT(refreshCharts())); refreshTimer->start(5000); lastResize=0; }
void RuleWidget::languageChanged() { julyTranslator.translateUi(this); ui.rulesTabs->setTabText(0,julyTr("TAB_RULES_FOR_ORDERS","Rules")); ui.rulesTabs->setTabText(1,julyTr("CONSOLE_OUT","Console output")); ui.rulesTabs->setTabText(2,julyTr("SCRIPT_NOTES","Notes")); rulesModel->setHorizontalHeaderLabels(QStringList()<<julyTr("RULES_T_STATE","State")<<julyTr("RULES_T_DESCR","Description")); //Removed <<julyTr("RULES_T_ACTION","Action")<<julyTr("ORDERS_AMOUNT","Amount")<<julyTr("RULES_T_PRICE","Price")); rulesEnableDisableMenu->actions().at(0)->setText(julyTr("RULE_ENABLE","Enable Selected")); rulesEnableDisableMenu->actions().at(1)->setText(julyTr("RULE_DISABLE","Disable Selected")); rulesEnableDisableMenu->actions().at(3)->setText(julyTr("RULE_ENABLE_ALL","Enable All")); rulesEnableDisableMenu->actions().at(4)->setText(julyTr("RULE_DISABLE_ALL","Disable All")); mainWindow.fixAllChildButtonsAndLabels(this); }
void ChartsView::refreshCharts() { if(!prepareCharts()){ sceneCharts->clear(); drawText(julyTr("CHARTS_WAITING_FOR_DATA","Waiting for data..."),0,0,"font-size:28px;color:"+baseValues.appTheme.gray.name()); return; } for(qint32 i=0;i<chartsModel->graphAmountY.count();i++){ drawRect(chartsModel->graphAmountX.at(i),chartsModel->graphAmountY.at(i)); } /*for(qint32 i=1;i<chartsModel->graphBoundsSellX.count();i++){ sceneCharts->addLine(chartsModel->graphBoundsSellX.at(i-1),chartsModel->graphBoundsSellY.at(i-1),chartsModel->graphBoundsSellX.at(i),chartsModel->graphBoundsSellY.at(i),QPen("#000000")); } for(qint32 i=1;i<chartsModel->graphBoundsBuyX.count();i++){ sceneCharts->addLine(chartsModel->graphBoundsBuyX.at(i-1),chartsModel->graphBoundsBuyY.at(i-1),chartsModel->graphBoundsBuyX.at(i),chartsModel->graphBoundsBuyY.at(i),QPen("#000000")); }*/ QPolygonF boundsPolygon; for(qint32 i=0;i<chartsModel->graphBoundsSellX.count();i++){ boundsPolygon << QPointF(chartsModel->graphBoundsSellX.at(i), chartsModel->graphBoundsSellY.at(i)); } for(qint32 i=chartsModel->graphBoundsBuyX.count()-1;i>=0;i--){ boundsPolygon << QPointF(chartsModel->graphBoundsBuyX.at(i), chartsModel->graphBoundsBuyY.at(i)); } if(boundsPolygon.count())sceneCharts->addPolygon(boundsPolygon,QPen("#4000FF00"),QBrush("#4000FF00")); if(chartsModel->graphTradesX.count()){ QPen pen; if(chartsModel->graphTradesType[0]==1)pen=QPen("#FF0000");else pen=QPen("#0000FF"); sceneCharts->addEllipse(chartsModel->graphTradesX.at(0)-2,chartsModel->graphTradesY.at(0)-2,4,4,pen); for(qint32 i=1;i<chartsModel->graphTradesX.count();i++){ if(chartsModel->graphTradesType[i]==1)pen=QPen("#FF0000");else pen=QPen("#0000FF"); sceneCharts->addLine(chartsModel->graphTradesX.at(i-1),chartsModel->graphTradesY.at(i-1),chartsModel->graphTradesX.at(i),chartsModel->graphTradesY.at(i),pen); sceneCharts->addEllipse(chartsModel->graphTradesX.at(i)-2,chartsModel->graphTradesY.at(i)-2,4,4,pen); } } }
TranslationDialog::TranslationDialog(QWidget *parent) : QDialog(parent) { ui.setupUi(this); ui.buttonSaveAs->setEnabled(false); setWindowFlags(Qt::Window); setAttribute(Qt::WA_DeleteOnClose,true); //setFixedSize(size()); #ifdef GENERATE_LANGUAGE_FILE julyTranslator->loadMapFromUi(this); julyTranslator->saveToFile("LanguageDefault.lng"); #endif #ifdef Q_OS_WIN if(QtWin::isCompositionEnabled())QtWin::extendFrameIntoClientArea(this); #endif julyTranslator->translateUi(this); ui.deleteTranslationButton->setEnabled(!julyTranslator->lastFile().startsWith(":/Resource")); ui.languageName->setText(julyTr("LANGUAGE_NAME","Invalid")); authorAbout=new TranslationLine; ui.authorLayout->addWidget(authorAbout); authorAbout->setItemText(julyTr("LANGUAGE_AUTHOR","Invalid")); gridLayout=new QGridLayout; fonWidget.setLayout(gridLayout); ui.scrollArea->setWidget(&fonWidget); JulyTranslator defaultTranslation; defaultTranslation.loadFromFile(":/Resources/Language/English.lng"); fillLayoutByMap(&(julyTranslator->labelMap),"Label_",&(defaultTranslation.labelMap)); fillLayoutByMap(&(julyTranslator->groupBoxMap),"GroupBox_",&(defaultTranslation.groupBoxMap)); fillLayoutByMap(&(julyTranslator->checkBoxMap),"CheckBox_",&(defaultTranslation.checkBoxMap)); fillLayoutByMap(&(julyTranslator->buttonMap),"Button_",&(defaultTranslation.buttonMap)); fillLayoutByMap(&(julyTranslator->spinBoxMap),"SpinBox_",&(defaultTranslation.spinBoxMap)); fillLayoutByMap(&(julyTranslator->stringMap),"String_",&(defaultTranslation.stringMap)); setTabOrder(ui.languageName,authorAbout); int currentRow=0; QWidget *lastWidget=authorAbout; for(int n=0;n<lineEdits.count();n++) if(lineEdits[n]->isChanged()==false) { TranslationLine *nextWidget=lineEdits[n]; gridLayout->addWidget(nextWidget, currentRow++, 0); setTabOrder(lastWidget,nextWidget); lastWidget=nextWidget; } for(int n=0;n<lineEdits.count();n++) if(lineEdits[n]->isChanged()==true) { TranslationLine *nextWidget=lineEdits[n]; gridLayout->addWidget(nextWidget, currentRow++, 0); setTabOrder(lastWidget,nextWidget); lastWidget=nextWidget; } setTabOrder(lastWidget,ui.searchLineEdit); resize(640,640); fixLayout(); if(mainWindow_)mainWindow.ui.aboutTranslationButton->setEnabled(false); QTimer::singleShot(100,this,SLOT(fixLayout())); }
void UpdaterDialog::downloadError() { QMessageBox::warning(this,windowTitle(),julyTr("DOWNLOAD_ERROR","Download error. Please try again.")+"<br>"+httpGet->errorString()); exitSlot(); }
void UpdaterDialog::copyDonateButton() { QApplication::clipboard()->setText(ui.bitcoinAddress->text()); QDesktopServices::openUrl(QUrl("bitcoin:"+ui.bitcoinAddress->text())); QMessageBox::information(this,"Qt Bitcoin Trader",julyTr("COPY_DONATE_MESSAGE","Bitcoin address copied to clipboard.<br>Thank you for support!")); }
int main(int argc, char *argv[]) { QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8")); QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8")); julyTranslator=new JulyTranslator; appDataDir_=new QByteArray(); appVerIsBeta_=new bool(false); appVerStr_=new QByteArray("1.0707"); appVerReal_=new double(appVerStr.toDouble()); if(appVerStr.size()>4) { appVerStr.insert(4,"."); if(appVerStr.at(appVerStr.size()-1)!='0')appVerIsBeta=true; } appVerLastReal_=new double(appVerReal); currencyBStr_=new QByteArray("USD"); currencyBStrLow_=new QByteArray("usd"); currencyBSign_=new QByteArray("USD"); validKeySign_=new bool(false); currencyASign_=new QByteArray("BTC"); currencyAStr_=new QByteArray("BTC"); currencyAStrLow_=new QByteArray("btc"); currencyRequest_=new QByteArray("BTCUSD"); defaultLangFile_=new QString();pickDefaultLangFile(); currencySignMap=new QMap<QByteArray,QByteArray>; currencyNamesMap=new QMap<QByteArray,QByteArray>; dateTimeFormat_=new QString(QLocale().dateTimeFormat(QLocale::ShortFormat)); timeFormat_=new QString(QLocale().timeFormat(QLocale::ShortFormat)); exchangeName_=new QString("Mt.Gox"); btcDecimals_=new int(8); usdDecimals_=new int(5); priceDecimals_=new int(5); minTradePrice_=new double(0.01); minTradeVolume_=new double(0.01); currentTimeStamp_=new qint32(QDateTime::currentDateTime().toTime_t()); httpRequestInterval_=new int(400); httpRequestTimeout_=new int(5); QString globalStyleSheet="QGroupBox {background: rgba(255,255,255,190); border: 1px solid gray;border-radius: 3px;margin-top: 7px;} QGroupBox:title {background: qradialgradient(cx: 0.5, cy: 0.5, fx: 0.5, fy: 0.5, radius: 0.7, stop: 0 #fff, stop: 1 transparent); border-radius: 2px; padding: 1 4px; top: -7; left: 7px;} QLabel {color: black;} QDoubleSpinBox {background: white;} QTextEdit {background: white;} QPlainTextEdit {background: white;} QCheckBox {color: black;} QLineEdit {color: black; background: white; border: 1px solid gray;}"; #ifdef Q_OS_WIN if(QFile::exists("./QtBitcoinTrader")) { appDataDir="./QtBitcoinTrader/"; QDir().mkpath(appDataDir+"Language"); if(!QFile::exists(appDataDir+"Language"))appDataDir.clear(); } if(appDataDir.isEmpty()) { appDataDir=QDesktopServices::storageLocation(QDesktopServices::DataLocation).replace("\\","/").toAscii()+"/QtBitcoinTrader/"; if(!QFile::exists(appDataDir))QDir().mkpath(appDataDir); } #else appDataDir=QDesktopServices::storageLocation(QDesktopServices::HomeLocation).toAscii()+"/.config/QtBitcoinTrader/"; if(!QFile::exists(appDataDir))QDir().mkpath(appDataDir); #endif if(argc>1) { QApplication a(argc,argv); if(a.arguments().last().startsWith("/checkupdate")) { #ifndef Q_OS_WIN a.setStyle(new QPlastiqueStyle); #endif a.setStyleSheet(globalStyleSheet); QSettings settings(appDataDir+"/Settings.set",QSettings::IniFormat); QString langFile=settings.value("LanguageFile","").toString(); if(langFile.isEmpty()||!langFile.isEmpty()&&!QFile::exists(langFile))langFile=defaultLangFile; julyTranslator->loadFromFile(langFile); UpdaterDialog updater(a.arguments().last()!="/checkupdate"); return a.exec(); } } QApplication a(argc,argv); #ifndef Q_OS_WIN a.setStyle(new QPlastiqueStyle); #endif #ifdef Q_OS_WIN if(QFile::exists(a.applicationFilePath()+".upd"))QFile::remove(a.applicationFilePath()+".upd"); if(QFile::exists(a.applicationFilePath()+".bkp"))QFile::remove(a.applicationFilePath()+".bkp"); #endif #ifdef Q_OS_MAC if(QFile::exists(a.applicationFilePath()+".upd"))QFile::remove(a.applicationFilePath()+".upd"); if(QFile::exists(a.applicationFilePath()+".bkp"))QFile::remove(a.applicationFilePath()+".bkp"); #endif a.setWindowIcon(QIcon(":/Resources/QtBitcoinTrader.png")); QFile *lockFile=0; { QNetworkProxy proxy; QList<QNetworkProxy> proxyList=QNetworkProxyFactory::systemProxyForQuery(QNetworkProxyQuery(QUrl("https://"))); if(proxyList.count())proxy=proxyList.first(); QNetworkProxy::setApplicationProxy(proxy); logEnabled_=new bool(false); a.setStyleSheet(globalStyleSheet); logFileName_=new QString("QtBitcoinTrader.log"); iniFileName_=new QString("QtBitcoinTrader.ini"); restKey_=new QByteArray; restSign_=new QByteArray; { QFile currencyFile("://Resources/Currencies.map"); currencyFile.open(QIODevice::ReadOnly); QStringList currencyList=QString(currencyFile.readAll().replace("\r","")).split("\n"); currencyFile.close(); for(int n=0;n<currencyList.count();n++) { QStringList currencyName=currencyList.at(n).split("="); if(currencyName.count()!=3)continue; currencyNamesMap->insert(currencyName.at(0).toAscii(),currencyName.at(1).toAscii()); currencySignMap->insert(currencyName.at(0).toAscii(),currencyName.at(2).toAscii()); } if(!QFile::exists(appDataDir+"Language"))QDir().mkpath(appDataDir+"Language"); QSettings settings(appDataDir+"/Settings.set",QSettings::IniFormat); QString langFile=settings.value("LanguageFile","").toString(); appVerLastReal=settings.value("Version",1.0).toDouble(); settings.setValue("Version",appVerReal); if(langFile.isEmpty()||!langFile.isEmpty()&&!QFile::exists(langFile))langFile=defaultLangFile; julyTranslator->loadFromFile(langFile); } bool tryDecrypt=true; bool showNewPasswordDialog=false; while(tryDecrypt) { QString tryPassword; restKey.clear(); restSign.clear(); if(QDir(appDataDir,"*.ini").entryList().isEmpty()||showNewPasswordDialog) { NewPasswordDialog newPassword; if(newPassword.exec()==QDialog::Accepted) { tryPassword=newPassword.getPassword(); newPassword.updateIniFileName(); restKey=newPassword.getRestKey().toAscii(); QSettings settings(iniFileName,QSettings::IniFormat); settings.setValue("ExchangeId",newPassword.getExchangeId()); QByteArray cryptedData; if(newPassword.getExchangeId()==0) { restSign=QByteArray::fromBase64(newPassword.getRestSign().toAscii()); cryptedData=JulyAES256::encrypt("Qt Bitcoin Trader\r\n"+restKey+"\r\n"+restSign.toBase64(),tryPassword.toAscii()); } else if(newPassword.getExchangeId()==1) { restSign=newPassword.getRestSign().toAscii(); cryptedData=JulyAES256::encrypt("Qt Bitcoin Trader\r\n"+restKey+"\r\n"+restSign.toBase64(),tryPassword.toAscii()); } settings.setValue("CryptedData",QString(cryptedData.toBase64())); settings.setValue("ProfileName",newPassword.selectedProfileName()); settings.remove("RestSign"); settings.remove("RestKey"); settings.sync(); showNewPasswordDialog=false; } } PasswordDialog enterPassword; if(enterPassword.exec()==QDialog::Rejected)return 0; if(enterPassword.resetData) { if(QFile::exists(enterPassword.getIniFilePath())) QFile::remove(enterPassword.getIniFilePath()); continue; } if(enterPassword.newProfile){showNewPasswordDialog=true;continue;} tryPassword=enterPassword.getPassword(); if(!tryPassword.isEmpty()) { iniFileName=enterPassword.getIniFilePath(); bool profileLocked=enterPassword.isProfileLocked(iniFileName); if(profileLocked) { QMessageBox msgBox(0); msgBox.setIcon(QMessageBox::Question); msgBox.setWindowTitle("Qt Bitcoin Trader"); msgBox.setText(julyTr("THIS_PROFILE_ALREADY_USED","This profile is already used by another instance.<br>API does not allow to run two instances with same key sign pair.<br>Please create new profile if you want to use two instances.")); #ifdef Q_OS_WIN msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); #else msgBox.setStandardButtons(QMessageBox::Ignore|QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); if(msgBox.exec()==QMessageBox::Ignore)profileLocked=false; #endif if(profileLocked)tryPassword.clear(); } if(!profileLocked) { QSettings settings(iniFileName,QSettings::IniFormat); QStringList decryptedList=QString(JulyAES256::decrypt(QByteArray::fromBase64(settings.value("CryptedData","").toString().toAscii()),tryPassword.toAscii())).split("\r\n"); if(decryptedList.count()==3&&decryptedList.first()=="Qt Bitcoin Trader") { restKey=decryptedList.at(1).toAscii(); restSign=QByteArray::fromBase64(decryptedList.last().toAscii()); tryDecrypt=false; lockFile=new QFile(enterPassword.lockFilePath(iniFileName)); lockFile->open(QIODevice::WriteOnly|QIODevice::Truncate); lockFile->write("Qt Bitcoin Trader Lock File"); } } } } QSettings settings(iniFileName,QSettings::IniFormat); isLogEnabled=settings.value("LogEnabled",false).toBool(); settings.setValue("LogEnabled",isLogEnabled); currencyASign=currencySignMap->value("BTC","BTC"); currencyBStr=settings.value("Currency","USD").toString().toAscii(); currencyBSign=currencySignMap->value(currencyBStr,"$"); if(isLogEnabled)logThread=new LogThread; mainWindow_=new QtBitcoinTrader; QObject::connect(mainWindow_,SIGNAL(quit()),&a,SLOT(quit())); } mainWindow.loadUiSettings(); a.exec(); if(lockFile) { lockFile->close(); lockFile->remove(); delete lockFile; } return 0; }
void UpdaterDialog::httpDone(bool error) { timeOutTimer->stop(); if(error) { if(isVisible()) { if(httpGet->errorString()=="Request aborted")return; downloadError(); return; } if(feedbackMessage) QMessageBox::information(0,"Qt Bitcoin Trader",julyTr("UPDATE_ERROR","Cannot check for update. Network error: %1").arg(httpGet->errorString())); exitSlot(); return; } if(stateUpdate==0) { QByteArray dataReceived(httpGet->readAll().replace("\r","")); if(dataReceived.size()>10245)exitSlot(); QMap<QString,QString>versionsMap; QStringList dataList=QString(dataReceived).split("\n"); for(int n=0;n<dataList.count();n++) { QString varData=dataList.at(n); int splitPos=varData.indexOf('='); if(splitPos>-1) { QString varName=varData.left(splitPos); varData.remove(0,splitPos+1); versionsMap[varName]=varData; } } QString os="Src"; bool canAutoUpdate=false; #ifdef Q_OS_MAC os="Mac"; canAutoUpdate=true; #endif #ifdef Q_OS_WIN os="Win32"; canAutoUpdate=true; #endif updateVersion=versionsMap.value(os+"Ver"); updateSignature=versionsMap.value(os+"Signature").toAscii(); if(!updateSignature.isEmpty())updateSignature=QByteArray::fromBase64(updateSignature); updateChangeLog=versionsMap.value(os+"ChangeLog"); updateLink=versionsMap.value(os+"Bin"); if(updateVersion.toDouble()<=appVerReal) { if(feedbackMessage) QMessageBox::information(0,"Qt Bitcoin Trader",julyTr("UP_TO_DATE","Your version of Qt Bitcoin Trader is up to date.")); exitSlot(); return; } stateUpdate=1; ui.autoUpdateGroupBox->setVisible(canAutoUpdate); ui.changeLogText->setHtml(updateChangeLog); ui.versionLabel->setText("v"+updateVersion); #ifdef Q_OS_WIN if(QtWin::isCompositionEnabled()) QtWin::extendFrameIntoClientArea(this); #endif #ifdef GENERATE_LANGUAGE_FILE julyTranslator->loadMapFromUi(this); julyTranslator->saveToFile("LanguageDefault.lng"); #endif julyTranslator->translateUi(this); ui.iconLabel->setPixmap(QPixmap(":/Resources/QtBitcoinTrader.png")); QSize minSizeHint=minimumSizeHint(); if(mainWindow.isValidSize(&minSizeHint))setFixedSize(minimumSizeHint()); show(); } else if(stateUpdate==1) { QByteArray binData=httpGet->readAll(); QByteArray fileSha1=QCryptographicHash::hash(binData,QCryptographicHash::Sha1); QFile readPublicKey(":/Resources/Public.key"); if(!readPublicKey.open(QIODevice::ReadOnly)){QMessageBox::critical(this,windowTitle(),"Public.key is missing");return;} QByteArray publicKey=readPublicKey.readAll(); QByteArray decrypted=JulyRSA::getSignature(updateSignature,publicKey); if(decrypted==fileSha1) { QString curBin=QApplication::applicationFilePath(); QString updBin=curBin+".upd"; QString bkpBin=curBin+".bkp"; if(QFile::exists(updBin))QFile::remove(updBin); if(QFile::exists(bkpBin))QFile::remove(bkpBin); if(QFile::exists(updBin)||QFile::exists(bkpBin)){downloadError();return;} { QFile wrFile(updBin); if(wrFile.open(QIODevice::WriteOnly|QIODevice::Truncate)) { wrFile.write(binData); wrFile.close(); }else {downloadError();return;} } QByteArray fileData; { QFile opFile(updBin); if(opFile.open(QIODevice::ReadOnly))fileData=opFile.readAll(); opFile.close(); } if(QCryptographicHash::hash(fileData,QCryptographicHash::Sha1)!=fileSha1){downloadError();return;} QFile::rename(curBin,bkpBin); if(!QFile::exists(bkpBin)){downloadError();return;} QFile::rename(updBin,curBin); if(!QFile::exists(curBin)){QMessageBox::critical(this,windowTitle(),"Critical error. Please reinstall application. Download it from http://sourceforge.net/projects/bitcointrader/<br>File not exists: "+curBin+"\n"+updBin);downloadError();return;} #ifdef Q_OS_MAC QFile(curBin).setPermissions(QFile(bkpBin).permissions()); #endif QMessageBox::information(this,windowTitle(),julyTr("UPDATED_SUCCESSFULLY","Application updated successfully. Please restart application to apply changes.")); exitSlot(); } } }
FeaturedExchangesDialog::FeaturedExchangesDialog() : QDialog() { exchangeNum=-1; ui.setupUi(this); ui.okButton->setEnabled(false); setWindowFlags(Qt::WindowCloseButtonHint); setWindowTitle("Qt Bitcoin Trader v"+baseValues.appVerStr+" - "+julyTr("FEATURED_EXCHANGES","Featured Exchanges")); QSettings listSettings(":/Resources/Exchanges/List.ini",QSettings::IniFormat); allExchangesList=listSettings.childGroups(); { JulyHttp *httpGet=new JulyHttp("qbtapi.centrabit.com",0,this,true,false); connect(httpGet,SIGNAL(dataReceived(QByteArray,int)),this,SLOT(dataReceived(QByteArray,int))); httpGet->noReconnect=true; httpGet->sendData(145,"GET /?Object=General&Method=FeaturedExchanges"); QElapsedTimer elapsedRequest; elapsedRequest.restart(); int counter=0; while(cacheData.isEmpty()&&counter++<30&&elapsedRequest.elapsed()<3000) { QEventLoop loop; QTimer::singleShot(100,&loop,SLOT(quit())); loop.exec(); } delete httpGet; featuredExchangesList=QString(mainWindow.getMidData("Exchanges\":[","]",&cacheData)).split(","); cacheData.clear(); } for(int n=featuredExchangesList.count()-1;n>=0;n--) { if(featuredExchangesList.at(n).isEmpty())featuredExchangesList.removeAt(n); } if(featuredExchangesList.isEmpty()) { QSettings settings(appDataDir+"/QtBitcoinTrader.cfg",QSettings::IniFormat); featuredExchangesList=settings.value("LastFeaturedExchanges",featuredExchangesList).toStringList(); } else { QSettings settings(appDataDir+"/QtBitcoinTrader.cfg",QSettings::IniFormat); settings.setValue("LastFeaturedExchanges",featuredExchangesList); } for(int n=featuredExchangesList.count()-1;n>=0;n--) { if(featuredExchangesList.at(n).isEmpty())featuredExchangesList.removeAt(n); else if(featuredExchangesList.at(n).length()<2)featuredExchangesList[n].prepend("0"); } if(featuredExchangesList.count()==0) { exchangeNum=-2; return; } removeNotValidExchanges(); quint32 countCol=3; if(featuredExchangesList.count()<=4)countCol=2; for(int i=0;i<featuredExchangesList.count();i++) { QString currentName=listSettings.value(featuredExchangesList.at(i)+"/Name").toString(); QString currentLogo=fixLogo(listSettings.value(featuredExchangesList.at(i)+"/Logo").toString()); QString currentURL =fixURL(listSettings.value(featuredExchangesList.at(i)+"/GetApiUrl").toString()); if(currentName.isEmpty()||currentLogo.isEmpty()||currentURL.isEmpty())continue; ExchangeButton *exchangeItem = new ExchangeButton(currentLogo,loadCurrencies(currentName),currentURL,featuredExchangesListIndex.at(i),this); if(countCol==3 && i==featuredExchangesList.count()-1 && (i-qFloor(i/countCol)*countCol)==0)i++; ui.gridLayoutExchange->addWidget(exchangeItem,qFloor(i/countCol),i-qFloor(i/countCol)*countCol,Qt::AlignCenter); } julyTranslator.translateUi(this); setFixedSize(minimumSizeHint()); }
void Exchange_BitCurex::dataReceivedAuth(QByteArray data, int reqType) { if(debugLevel)logThread->writeLog("RCV: "+data); if(data.size()<4)return; if(data.at(0)==QLatin1Char('<'))return; bool success=true; switch(reqType) { case 103: //ticker if(data.startsWith("{\"lowest_tx_price_h\": \"")) { QByteArray tickerHigh=getMidData("\"highest_tx_price_h\": \"","\", \"",&data); if(!tickerHigh.isEmpty()) { double newTickerHigh=tickerHigh.toDouble(); if(newTickerHigh!=lastTickerHigh) IndicatorEngine::setValue(baseValues.exchangeName,baseValues.currentPair.symbol,"High",newTickerHigh); lastTickerHigh=newTickerHigh; } QByteArray tickerLow=getMidData("\"lowest_tx_price_h\": \"","\", \"",&data); if(!tickerLow.isEmpty()) { double newTickerLow=tickerLow.toDouble(); if(newTickerLow!=lastTickerLow) IndicatorEngine::setValue(baseValues.exchangeName,baseValues.currentPair.symbol,"Low",newTickerLow); lastTickerLow=newTickerLow; } QByteArray tickerSell=getMidData("\"best_bid_h\": \"","\", \"",&data); if(!tickerSell.isEmpty()) { double newTickerSell=tickerSell.toDouble(); if(newTickerSell!=lastTickerSell) IndicatorEngine::setValue(baseValues.exchangeName,baseValues.currentPair.symbol,"Sell",newTickerSell); lastTickerSell=newTickerSell; } QByteArray tickerBuy=getMidData("\"best_ask_h\": \"","\", \"",&data); if(!tickerBuy.isEmpty()) { double newTickerBuy=tickerBuy.toDouble(); if(newTickerBuy!=lastTickerBuy) IndicatorEngine::setValue(baseValues.exchangeName,baseValues.currentPair.symbol,"Buy",newTickerBuy); lastTickerBuy=newTickerBuy; } QByteArray tickerVolume=getMidData("\"total_volume_h\": \"","\", \"",&data); if(!tickerVolume.isEmpty()) { double newTickerVolume=tickerVolume.toDouble(); if(newTickerVolume!=lastTickerVolume) IndicatorEngine::setValue(baseValues.exchangeName,baseValues.currentPair.symbol,"Volume",newTickerVolume); lastTickerVolume=newTickerVolume; } QByteArray tickerLast=getMidData("\"last_tx_price_h\": \"","\", \"",&data); if(!tickerLast.isEmpty()) { double newTickerLast=tickerLast.toDouble(); if(newTickerLast!=lastTickerLast) IndicatorEngine::setValue(baseValues.exchangeName,baseValues.currentPair.symbol,"Last",newTickerLast); lastTickerLast=newTickerLast; } } else success=false; break;//ticker case 109: //trades if(data.startsWith("{\"status\": \"ok\", \"data\": {\"symbol\": \""+baseValues.currentPair.symbol.toLower().toLatin1()+"\", \"trades\": [{\"")) { QStringList tradeList=QString(data).split("}, {"); QList<TradesItem> *newTradesItems=new QList<TradesItem>; TradesItem newItem; for(int n=tradeList.count()-1;n>=0;n--) { QByteArray tradeData=tradeList.at(n).toLatin1()+"}"; newItem.date=getMidData("\"ts\": ",", \"",&tradeData).toUInt(); if(newItem.date<startTradesDate)continue; quint32 currentTid=getMidData("\"txid\": ",", \"",&tradeData).toUInt(); if(lastFetchTid>=currentTid)continue; lastFetchTid=currentTid; newItem.price=getMidData("\"price\": ",", \"",&tradeData).toDouble(); newItem.amount=getMidData("\"amount\": ",", \"",&tradeData).toDouble(); newItem.orderType=getMidData("\"type\": \"","\"}",&tradeData)=="ask"?-1:1; newItem.symbol=baseValues.currentPair.symbol; if(newItem.isValid())(*newTradesItems)<<newItem; else if(debugLevel)logThread->writeLog("Invalid trades fetch data line:"+tradeData,2); } if(newItem.price>0&&lastTradesDate<newItem.date) { lastTradesDate=newItem.date; IndicatorEngine::setValue(baseValues.exchangeName,baseValues.currentPair.symbol,"Last",newItem.price); lastTickerLast=newItem.price; } if(newTradesItems->count())emit addLastTrades(baseValues.currentPair.symbol,newTradesItems); else delete newTradesItems; } else if(!data.startsWith("{\"status\": \"ok\", \"data\": {\"symbol\": \""))success=false; break;//trades case 111: //depth if(data.startsWith("{\"symbol\": \""+baseValues.currentPair.symbol.toLower().toLatin1()+"\", \"bids\": [")) { emit depthRequestReceived(); if(lastDepthData!=data) { lastDepthData=data; depthAsks=new QList<DepthItem>; depthBids=new QList<DepthItem>; QMap<double,double> currentAsksMap; QStringList asksList=QString(getMidData("asks\": [[","]]",&data)).split("], ["); double groupedPrice=0.0; double groupedVolume=0.0; int rowCounter=0; for(int n=0;n<asksList.count();n++) { if(baseValues.depthCountLimit&&rowCounter>=baseValues.depthCountLimit)break; QStringList currentPair=asksList.at(n).split(", "); if(currentPair.count()!=2)continue; double priceDouble=currentPair.first().toDouble(); double amount=currentPair.last().toDouble(); if(baseValues.groupPriceValue>0.0) { if(n==0) { emit depthFirstOrder(baseValues.currentPair.symbol,priceDouble,amount,true); groupedPrice=baseValues.groupPriceValue*(int)(priceDouble/baseValues.groupPriceValue); groupedVolume=amount; } else { bool matchCurrentGroup=priceDouble<groupedPrice+baseValues.groupPriceValue; if(matchCurrentGroup)groupedVolume+=amount; if(!matchCurrentGroup||n==asksList.count()-1) { depthSubmitOrder(baseValues.currentPair.symbol, ¤tAsksMap,groupedPrice+baseValues.groupPriceValue,groupedVolume,true); rowCounter++; groupedVolume=amount; groupedPrice+=baseValues.groupPriceValue; } } } else { depthSubmitOrder(baseValues.currentPair.symbol, ¤tAsksMap,priceDouble,amount,true); rowCounter++; } } QList<double> currentAsksList=lastDepthAsksMap.keys(); for(int n=0;n<currentAsksList.count();n++) if(currentAsksMap.value(currentAsksList.at(n),0)==0)depthUpdateOrder(baseValues.currentPair.symbol, currentAsksList.at(n),0.0,true); lastDepthAsksMap=currentAsksMap; QMap<double,double> currentBidsMap; QStringList bidsList=QString(getMidData("bids\": [[","]]",&data)).split("], ["); groupedPrice=0.0; groupedVolume=0.0; rowCounter=0; for(int n=0;n<bidsList.count();n++) { if(baseValues.depthCountLimit&&rowCounter>=baseValues.depthCountLimit)break; QStringList currentPair=bidsList.at(n).split(", "); if(currentPair.count()!=2)continue; double priceDouble=currentPair.first().toDouble(); double amount=currentPair.last().toDouble(); if(baseValues.groupPriceValue>0.0) { if(n==0) { emit depthFirstOrder(baseValues.currentPair.symbol,priceDouble,amount,false); groupedPrice=baseValues.groupPriceValue*(int)(priceDouble/baseValues.groupPriceValue); groupedVolume=amount; } else { bool matchCurrentGroup=priceDouble>groupedPrice-baseValues.groupPriceValue; if(matchCurrentGroup)groupedVolume+=amount; if(!matchCurrentGroup||n==asksList.count()-1) { depthSubmitOrder(baseValues.currentPair.symbol, ¤tBidsMap,groupedPrice-baseValues.groupPriceValue,groupedVolume,false); rowCounter++; groupedVolume=amount; groupedPrice-=baseValues.groupPriceValue; } } } else { depthSubmitOrder(baseValues.currentPair.symbol, ¤tBidsMap,priceDouble,amount,false); rowCounter++; } } QList<double> currentBidsList=lastDepthBidsMap.keys(); for(int n=0;n<currentBidsList.count();n++) if(currentBidsMap.value(currentBidsList.at(n),0)==0)depthUpdateOrder(baseValues.currentPair.symbol, currentBidsList.at(n),0.0,false); lastDepthBidsMap=currentBidsMap; emit depthSubmitOrders(baseValues.currentPair.symbol,depthAsks, depthBids); depthAsks=0; depthBids=0; } } else if(!data.startsWith("{\"symbol\": \"")) { if(debugLevel)logThread->writeLog("Invalid depth data:"+data,2); success=false; } break; case 202: //info if(data.startsWith("{\"status\": \"ok\", \"data\": {\"")) { QByteArray fundsData=getMidData("data\": {","}",&data); QByteArray btcBalance=getMidData(baseValues.currentPair.currAStrLow+"\": \"","\"",&fundsData); if(!btcBalance.isEmpty()) { double newBtcBalance=btcBalance.toDouble(); if(lastBtcBalance!=newBtcBalance)emit accBtcBalanceChanged(baseValues.currentPair.symbol,newBtcBalance); lastBtcBalance=newBtcBalance; } QByteArray usdBalance=getMidData("\""+baseValues.currentPair.currBStrLow+"\": \"","\"",&fundsData); if(!usdBalance.isEmpty()) { double newUsdBalance=usdBalance.toDouble(); if(newUsdBalance!=lastUsdBalance)emit accUsdBalanceChanged(baseValues.currentPair.symbol,newUsdBalance); lastUsdBalance=newUsdBalance; } QByteArray fee=getMidData("\"fee\": ",",",&data); if(!fee.isEmpty()) { double newFee=fee.toDouble(); if(newFee!=lastFee)emit accFeeChanged(baseValues.currentPair.symbol,newFee); lastFee=newFee; } } else success=false; break;//info case 204://orders if(data.startsWith("{\"status\": \"ok\", \"data\": [{\"")) { if(lastOrders!=data) { lastOrders=data; QStringList ordersList=QString(data).split("}, {"); QList<OrderItem> *orders=new QList<OrderItem>; for(int n=0;n<ordersList.count();n++) { OrderItem currentOrder; QByteArray currentOrderData=ordersList.at(n).toLatin1()+"}"; currentOrder.oid=getMidData("id\": \"","\"}",¤tOrderData); QByteArray tempDate=getMidData("issued\": ",", \"",¤tOrderData); tempDate.chop(3); currentOrder.date=tempDate.toUInt(); currentOrder.type=getMidData("type\": \"","\", \"",¤tOrderData)=="ask"; currentOrder.amount=getMidData("volume\": \"","\", \"",¤tOrderData).toDouble(); currentOrder.price=getMidData("limit\": \"","\", \"",¤tOrderData).toDouble(); currentOrder.symbol="BTC"+getMidData("currency\": \"","\", \"",¤tOrderData).toUpper(); currentOrder.status=1; if(currentOrder.isValid())(*orders)<<currentOrder; } emit orderBookChanged(baseValues.currentPair.symbol,orders); } } else if(data.startsWith("{\"status\": \"ok\", \"data\": [")) emit ordersIsEmpty(); else success=false; break;//orders case 305: //order/cancel if(data.startsWith("{\"status\": \"ok\", \"data\": [{\"")) { QByteArray oid=getMidData("id\": \"","\"",&data); if(!oid.isEmpty())emit orderCanceled(baseValues.currentPair.symbol,oid); } else success=false; break;//order/cancel case 306: if(debugLevel)logThread->writeLog("Buy OK: "+data,2);break;//order/buy case 307: if(debugLevel)logThread->writeLog("Sell OK: "+data,2);break;//order/sell case 208: ///history if(data.startsWith("{\"status\": \"ok\", \"data\": {\"symbol\": \""+baseValues.currentPair.symbol.toLower().toLatin1()+"\", \"trades\": [")) { if(lastHistory!=data) { lastHistory=data; QStringList dataList=QString(data).split("}, {"); QList<HistoryItem> *historyItems=new QList<HistoryItem>; quint32 currentId; quint32 maxId=0; for(int n=dataList.count()-1;n>=0;n--) { QByteArray curLog=dataList.at(n).toLatin1()+"}"; currentId=getMidData("txid\": ",", \"",&curLog).toUInt(); if(currentId<=lastHistoryId)break; if(n==dataList.count()-1)maxId=currentId; HistoryItem currentHistoryItem; QByteArray logType=getMidData("type\": \"","\"}",&curLog); if(logType=="ask")currentHistoryItem.type=2; else if(logType=="bid")currentHistoryItem.type=1; if(currentHistoryItem.type) { currentHistoryItem.symbol=baseValues.currentPair.symbol; currentHistoryItem.dateTimeInt=getMidData("ts\": ",", \"",&curLog).toUInt(); currentHistoryItem.price=getMidData("price\": ",", \"",&curLog).toDouble(); currentHistoryItem.volume=getMidData("amount\": ",", \"",&curLog).toDouble(); if(currentHistoryItem.isValid())(*historyItems)<<currentHistoryItem; } } if(maxId>lastHistoryId)lastHistoryId=maxId; emit historyChanged(historyItems); } } else success=false; break;//money/wallet/history default: break; } static int authErrorCount=0; if(reqType>=200 && reqType<300) { if(!success) { authErrorCount++; if(authErrorCount>2) { QString authErrorString=getMidData("data\": \"","\"",&data); if(debugLevel)logThread->writeLog("API error: "+authErrorString.toLatin1()+" ReqType: "+QByteArray::number(reqType),2); if(authErrorString=="auth_error")authErrorString=julyTr("TRUNAUTHORIZED","Invalid API key."); else if(authErrorString=="nonce_error")authErrorString=julyTr("THIS_PROFILE_ALREADY_USED","Invalid nonce parameter."); if(!authErrorString.isEmpty())emit showErrorMessage(authErrorString); } } else authErrorCount=0; } static int errorCount=0; if(!success) { QString errorString; errorString=getMidData("{\"status\": \"error\", \"data\": \"","\"",&data); errorCount++; if(errorCount<3)return; if(debugLevel)logThread->writeLog("API error: "+errorString.toLatin1()+" ReqType:"+QByteArray::number(reqType),2); if(errorString.isEmpty())return; if(errorString==QLatin1String("no orders"))return; if(reqType<300)emit showErrorMessage("I:>"+errorString); } else errorCount=0; }