bool FileCSV::Load(const wxString& fileName, unsigned int itemsInLine) { // Make sure file exists if (fileName.IsEmpty() || !wxFileName::FileExists(fileName)) { mmErrorDialogs::InvalidFile(pParentWindow_); return false; } // Open file wxTextFile txtFile(fileName); if (!txtFile.Open(encoding_)) { mmErrorDialogs::MessageError(pParentWindow_, _("Unable to open file."), _("Universal CSV Import")); return false; } // Parse rows wxString line; int row = 0; for (line = txtFile.GetFirstLine(); !txtFile.Eof(); line = txtFile.GetNextLine()) { csv2tab_separated_values(line, delimiter_); wxStringTokenizer tkz(line, "\t", wxTOKEN_RET_EMPTY_ALL); itemsTable_.push_back(std::vector<ValueAndType>()); // Tokens in row while (tkz.HasMoreTokens()) { if (itemsTable_[row].size() >= itemsInLine) break; wxString token = tkz.GetNextToken(); itemsTable_[row].push_back(token); } ++row; } txtFile.Close(); return true; }
void mmStockDialog::OnHistoryImportButton(wxCommandEvent& /*event*/) { if (m_stock->SYMBOL.IsEmpty()) return; bool canceledbyuser = false; const wxString fileName = wxFileSelector(_("Choose CSV data file to import") , wxEmptyString, wxEmptyString, wxEmptyString, "*.csv", wxFD_FILE_MUST_EXIST); Model_Account::Data *account = Model_Account::instance().get(m_stock->HELDAT); Model_Currency::Data *currency = Model_Account::currency(account); if (!fileName.IsEmpty()) { wxFileName csv_file(fileName); if (fileName.IsEmpty() || !csv_file.FileExists()) return; wxTextFile tFile(fileName); if (!tFile.Open()) return; wxProgressDialog* progressDlg = new wxProgressDialog(_("Stock History CSV Import") , _("Quotes imported from CSV: "), tFile.GetLineCount() , NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_CAN_ABORT); long countNumTotal = 0; long countImported = 0; double price; wxDateTime dt; wxString dateStr, priceStr; Model_StockHistory::Data *data; Model_StockHistory::Cache stockData; wxString line; std::vector<wxString> rows; for (line = tFile.GetFirstLine(); !tFile.Eof(); line = tFile.GetNextLine()) { wxString progressMsg; progressMsg << _("Quotes imported from CSV: ") << countImported; if (!progressDlg->Update(countImported, progressMsg)) { canceledbyuser = true; break; // abort processing } if (!line.IsEmpty()) ++countNumTotal; else continue; dateStr.clear(); priceStr.clear(); const wxString& delimiter = Model_Infotable::instance().GetStringInfo("DELIMITER", mmex::DEFDELIMTER); csv2tab_separated_values(line, delimiter); wxStringTokenizer tkz(line, "\t", wxTOKEN_RET_EMPTY_ALL); if ((int)tkz.CountTokens() < 2) continue; std::vector<wxString> tokens; while (tkz.HasMoreTokens()) { wxString token = tkz.GetNextToken(); tokens.push_back(token); } // date dateStr = tokens[0]; mmParseDisplayStringToDate(dt, dateStr, mmOptions::instance().dateFormat_); dateStr = dt.FormatISODate(); // price priceStr = tokens[1]; priceStr.Replace(" ", wxEmptyString); if (!Model_Currency::fromString(priceStr, price, currency) || price <= 0.0) continue; data = Model_StockHistory::instance().create(); data->SYMBOL = m_stock->SYMBOL; data->DATE = dateStr; data->VALUE = price; data->UPDTYPE = 2; stockData.push_back(data); if (rows.size()<10) { dateStr << wxT (" ") << priceStr; rows.push_back(dateStr); } countImported++; } progressDlg->Destroy(); wxString msg = wxString::Format(_("Total Lines : %ld"), countNumTotal); msg << "\n"; msg << wxString::Format(_("Total Imported : %ld"), countImported); msg << "\n"; msg << _("Date") << " " << _("Price"); msg << "\n"; for (std::vector<wxString>::const_iterator d = rows.begin(); d != rows.end(); ++d) msg << *d << "\n"; wxString confirmMsg = msg + _("Please confirm saving..."); if (!canceledbyuser && wxMessageBox(confirmMsg , _("Importing CSV"), wxOK | wxCANCEL | wxICON_INFORMATION) == wxCANCEL) { canceledbyuser = true; } // Since all database transactions are only in memory, if (!canceledbyuser) { // we need to save them to the database. for (auto &d : stockData) Model_StockHistory::instance().save(d); // show the data showStockHistory(); } else { //TODO: and discard the database changes. } } }