alkimia  8.0.3
alkonlinequote.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright 2004 Ace Jones <acejones@users.sourceforge.net> *
3  * *
4  * This file is part of libalkimia. *
5  * *
6  * libalkimia is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License *
8  * as published by the Free Software Foundation; either version 2.1 of *
9  * the License or (at your option) version 3 or any later version. *
10  * *
11  * libalkimia is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License *
17  * along with this program. If not, see <http://www.gnu.org/licenses/> *
18  ***************************************************************************/
19 
20 #include "alkonlinequote.h"
21 
22 #include "alkdateformat.h"
23 #include "alkexception.h"
24 #include "alkfinancequoteprocess.h"
25 #include "alkonlinequoteprocess.h"
26 #include "alkonlinequotesprofile.h"
28 #include "alkonlinequotesource.h"
29 #include "alkwebpage.h"
30 
31 #include <QApplication>
32 #include <QByteArray>
33 #include <QFile>
34 //#include <QFileInfo>
35 #include <QRegExp>
36 #include <QTextStream>
37 #include <QTextCodec>
38 
39 #include <KConfigGroup>
40 #include <KDebug>
41 #include <KEncodingProber>
42 #include <KGlobal>
43 #include <kio/netaccess.h>
44 #include <kio/scheduler.h>
45 #include <KLocale>
46 #include <KProcess>
47 #include <KShell>
48 #include <KUrl>
49 
51 {
52 }
53 
55 {
56  m_type.append(type);
57 }
58 
60 {
61  m_type = e.m_type;
62 }
63 
65 {
66  if (!m_type.contains(t)) {
67  m_type.append(t);
68  }
69  return *this;
70 }
71 
73 {
74  return m_type.contains(t);
75 }
76 
77 
78 class AlkOnlineQuote::Private : public QObject
79 {
80  Q_OBJECT
81 public:
84  QString m_quoteData;
85  QString m_symbol;
86  QString m_id;
87  QDate m_date;
88  double m_price;
91  KUrl m_url;
92  QEventLoop *m_eventLoop;
96 
97  static int dbgArea()
98  {
99  static int s_area = KDebug::registerArea("Alkimia (AlkOnlineQuote)");
100  return s_area;
101  }
102 
104  : m_p(parent)
105  , m_eventLoop(nullptr)
106  , m_ownProfile(false)
107  {
108  connect(&m_filter, SIGNAL(processExited(QString)), this, SLOT(slotParseQuote(QString)));
109  }
110 
112  {
113  if (m_ownProfile)
114  delete m_profile;
115  }
116 
117  bool initLaunch(const QString &_symbol, const QString &_id, const QString &_source);
118  bool launchWebKitCssSelector(const QString &_symbol, const QString &_id,
119  const QString &_source);
120  bool launchWebKitHtmlParser(const QString &_symbol, const QString &_id, const QString &_source);
121  bool launchNative(const QString &_symbol, const QString &_id, const QString &_source);
122  bool launchFinanceQuote(const QString &_symbol, const QString &_id, const QString &_source);
123  void enter_loop();
124  bool parsePrice(const QString &pricestr);
125  bool parseDate(const QString &datestr);
126 
127 public slots:
128  void slotLoadStarted();
129  void slotLoadFinishedHtmlParser(bool ok);
130  void slotLoadFinishedCssSelector(bool ok);
131  bool slotParseQuote(const QString &_quotedata);
132 };
133 
134 bool AlkOnlineQuote::Private::initLaunch(const QString &_symbol, const QString &_id, const QString &_source)
135 {
136  m_symbol = _symbol;
137  m_id = _id;
138  m_errors = Errors::None;
139 
140  emit m_p->status(QString("(Debug) symbol=%1 id=%2...").arg(_symbol, _id));
141 
142  // Get sources from the config file
143  QString source = _source;
144  if (source.isEmpty()) {
145  source = "KMyMoney Currency";
146  }
147 
148  if (!m_profile->quoteSources().contains(source)) {
149  emit m_p->error(i18n("Source <placeholder>%1</placeholder> does not exist.", source));
150  m_errors |= Errors::Source;
151  return false;
152  }
153 
154  //m_profile->createSource(source);
155  m_source = AlkOnlineQuoteSource(source, m_profile);
156 
157  KUrl url;
158 
159  // if the source has room for TWO symbols..
160  if (m_source.url().contains("%2")) {
161  // this is a two-symbol quote. split the symbol into two. valid symbol
162  // characters are: 0-9, A-Z and the dot. anything else is a separator
163  QRegExp splitrx("([0-9a-z\\.]+)[^a-z0-9]+([0-9a-z\\.]+)", Qt::CaseInsensitive);
164  // if we've truly found 2 symbols delimited this way...
165  if (splitrx.indexIn(m_symbol) != -1) {
166  url = KUrl(m_source.url().arg(splitrx.cap(1), splitrx.cap(2)));
167  } else {
168  kDebug(Private::dbgArea()) << "WebPriceQuote::launch() did not find 2 symbols";
169  }
170  } else {
171  // a regular one-symbol quote
172  url = KUrl(m_source.url().arg(m_symbol));
173  }
174 
175  m_url = url;
176 
177  return true;
178 }
179 
181 {
182  if (!ok) {
183  emit m_p->error(i18n("Unable to fetch url for %1").arg(m_symbol));
184  m_errors |= Errors::URL;
185  emit m_p->failed(m_id, m_symbol);
186  } else {
187  // parse symbol
188  slotParseQuote(AlkOnlineQuotesProfileManager::instance().webPage()->toHtml());
189  }
190  if (m_eventLoop)
191  m_eventLoop->exit();
192 }
193 
195 {
196  if (!ok) {
197  emit m_p->error(i18n("Unable to fetch url for %1").arg(m_symbol));
198  m_errors |= Errors::URL;
199  emit m_p->failed(m_id, m_symbol);
200  } else {
202  // parse symbol
203  QString symbol = webPage->getFirstElement(m_source.sym());
204  if (!symbol.isEmpty()) {
205  emit m_p->status(i18n("Symbol found: '%1'", symbol));
206  } else {
207  m_errors |= Errors::Symbol;
208  emit m_p->error(i18n("Unable to parse symbol for %1", m_symbol));
209  }
210 
211  // parse price
212  QString price = webPage->getFirstElement(m_source.price());
213  bool gotprice = parsePrice(price);
214 
215  // parse date
216  QString date = webPage->getFirstElement(m_source.date());
217  bool gotdate = parseDate(date);
218 
219  if (gotprice && gotdate) {
220  emit m_p->quote(m_id, m_symbol, m_date, m_price);
221  } else {
222  emit m_p->failed(m_id, m_symbol);
223  }
224  }
225  if (m_eventLoop)
226  m_eventLoop->exit();
227 }
228 
230 {
231  emit m_p->status(i18n("Fetching URL %1...", m_url.prettyUrl()));
232 }
233 
234 bool AlkOnlineQuote::Private::launchWebKitCssSelector(const QString &_symbol, const QString &_id,
235  const QString &_source)
236 {
237  if (!initLaunch(_symbol, _id, _source)) {
238  return false;
239  }
241  connect(webPage, SIGNAL(loadStarted()), this, SLOT(slotLoadStarted()));
242  connect(webPage, SIGNAL(loadFinished(bool)), this,
243  SLOT(slotLoadFinishedCssSelector(bool)));
244  webPage->setUrl(m_url);
245  m_eventLoop = new QEventLoop;
246  m_eventLoop->exec();
247  delete m_eventLoop;
248  disconnect(webPage, SIGNAL(loadStarted()), this, SLOT(slotLoadStarted()));
249  disconnect(webPage, SIGNAL(loadFinished(bool)), this,
250  SLOT(slotLoadFinishedCssSelector(bool)));
251 
252  return !(m_errors & Errors::URL || m_errors & Errors::Price
253  || m_errors & Errors::Date || m_errors & Errors::Data);
254 }
255 
256 bool AlkOnlineQuote::Private::launchWebKitHtmlParser(const QString &_symbol, const QString &_id,
257  const QString &_source)
258 {
259  if (!initLaunch(_symbol, _id, _source)) {
260  return false;
261  }
263  connect(webPage, SIGNAL(loadStarted()), this, SLOT(slotLoadStarted()));
264  connect(webPage, SIGNAL(loadFinished(bool)), this, SLOT(slotLoadFinishedHtmlParser(bool)));
265  webPage->load(m_url, m_acceptLanguage);
266  m_eventLoop = new QEventLoop;
267  m_eventLoop->exec();
268  delete m_eventLoop;
269  disconnect(webPage, SIGNAL(loadStarted()), this, SLOT(slotLoadStarted()));
270  disconnect(webPage, SIGNAL(loadFinished(bool)), this, SLOT(slotLoadFinishedHtmlParser(bool)));
271 
272  return !(m_errors & Errors::URL || m_errors & Errors::Price
273  || m_errors & Errors::Date || m_errors & Errors::Data);
274 }
275 
276 bool AlkOnlineQuote::Private::launchNative(const QString &_symbol, const QString &_id,
277  const QString &_source)
278 {
279  bool result = true;
280  if (!initLaunch(_symbol, _id, _source)) {
281  return false;
282  }
283 
284  KUrl url = m_url;
285  if (url.isLocalFile()) {
286  emit m_p->status(i18nc("The process x is executing", "Executing %1...", url.toLocalFile()));
287 
288  m_filter.clearProgram();
289  m_filter << url.toLocalFile().split(' ', QString::SkipEmptyParts);
290  m_filter.setSymbol(m_symbol);
291 
292  m_filter.setOutputChannelMode(KProcess::MergedChannels);
293  m_filter.start();
294 
295  if (m_filter.waitForStarted()) {
296  result = true;
297  } else {
298  emit m_p->error(i18n("Unable to launch: %1", url.toLocalFile()));
299  m_errors |= Errors::Script;
300  result = slotParseQuote(QString());
301  }
302  } else {
303  slotLoadStarted();
304 
305  QString tmpFile;
306  if (KIO::NetAccess::download(url, tmpFile, 0)) {
307  // kDebug(Private::dbgArea()) << "Downloaded " << tmpFile;
308  kDebug(Private::dbgArea()) << "Downloaded" << tmpFile << "from" << url;
309  QFile f(tmpFile);
310  if (f.open(QIODevice::ReadOnly)) {
311  // Find out the page encoding and convert it to unicode
312  QByteArray page = f.readAll();
313  KEncodingProber prober(KEncodingProber::Universal);
314  prober.feed(page);
315  QTextCodec *codec = QTextCodec::codecForName(prober.encoding());
316  if (!codec) {
317  codec = QTextCodec::codecForLocale();
318  }
319  QString quote = codec->toUnicode(page);
320  f.close();
321  emit m_p->status(i18n("URL found: %1...", url.prettyUrl()));
322  if (AlkOnlineQuotesProfileManager::instance().webPageEnabled())
324  result = slotParseQuote(quote);
325  } else {
326  emit m_p->error(i18n("Failed to open downloaded file"));
327  m_errors |= Errors::URL;
328  result = slotParseQuote(QString());
329  }
330  KIO::NetAccess::removeTempFile(tmpFile);
331  } else {
332  emit m_p->error(KIO::NetAccess::lastErrorString());
333  m_errors |= Errors::URL;
334  result = slotParseQuote(QString());
335  }
336  }
337  return result;
338 }
339 
340 bool AlkOnlineQuote::Private::launchFinanceQuote(const QString &_symbol, const QString &_id,
341  const QString &_sourcename)
342 {
343  bool result = true;
344  m_symbol = _symbol;
345  m_id = _id;
346  m_errors = Errors::None;
347  m_source = AlkOnlineQuoteSource(_sourcename, m_profile->scriptPath(),
348  "\"([^,\"]*)\",.*", // symbol regexp
349  "[^,]*,[^,]*,\"([^\"]*)\"", // price regexp
350  "[^,]*,([^,]*),.*", // date regexp
351  "%y-%m-%d"); // date format
352 
353  //emit status(QString("(Debug) symbol=%1 id=%2...").arg(_symbol,_id));
355  QString fQSource = m_profile->type() == AlkOnlineQuotesProfile::Type::Script ?
356  tmp.crypticName(_sourcename) : _sourcename.section(' ', 1);
357 
358  QStringList args;
359  args << "perl" << m_profile->scriptPath() << fQSource << m_symbol;
360  m_filter.clearProgram();
361  m_filter << args;
362  emit m_p->status(i18nc("Executing 'script' 'online source' 'investment symbol' ",
363  "Executing %1 %2 %3...", args.join(" "), QString(), QString()));
364 
365  m_filter.setOutputChannelMode(KProcess::MergedChannels);
366  m_filter.start();
367 
368  // This seems to work best if we just block until done.
369  if (m_filter.waitForFinished()) {
370  } else {
371  emit m_p->error(i18n("Unable to launch: %1", m_profile->scriptPath()));
372  m_errors |= Errors::Script;
373  result = slotParseQuote(QString());
374  }
375  return result;
376 }
377 
378 bool AlkOnlineQuote::Private::parsePrice(const QString &_pricestr)
379 {
380  bool result = true;
381  // Deal with european quotes that come back as X.XXX,XX or XX,XXX
382  //
383  // We will make the assumption that ALL prices have a decimal separator.
384  // So "1,000" always means 1.0, not 1000.0.
385  //
386  // Remove all non-digits from the price string except the last one, and
387  // set the last one to a period.
388  QString pricestr(_pricestr);
389  if (!pricestr.isEmpty()) {
390  int pos = pricestr.lastIndexOf(QRegExp("\\D"));
391  if (pos > 0) {
392  pricestr[pos] = '.';
393  pos = pricestr.lastIndexOf(QRegExp("\\D"), pos - 1);
394  }
395  while (pos > 0) {
396  pricestr.remove(pos, 1);
397  pos = pricestr.lastIndexOf(QRegExp("\\D"), pos);
398  }
399 
400  m_price = pricestr.toDouble();
401  kDebug(Private::dbgArea()) << "Price" << pricestr;
402  emit m_p->status(i18n("Price found: '%1' (%2)", pricestr, m_price));
403  } else {
404  m_errors |= Errors::Price;
405  emit m_p->error(i18n("Unable to parse price for '%1'", m_symbol));
406  result = false;
407  }
408  return result;
409 }
410 
411 bool AlkOnlineQuote::Private::parseDate(const QString &datestr)
412 {
413  if (!datestr.isEmpty()) {
414  emit m_p->status(i18n("Date found: '%1'", datestr));
415 
416  AlkDateFormat dateparse(m_source.dateformat());
417  try {
418  m_date = dateparse.convertString(datestr, false /*strict*/);
419  kDebug(Private::dbgArea()) << "Date" << datestr;
420  emit m_p->status(i18n("Date format found: '%1' -> '%2'", datestr, m_date.toString()));
421  } catch (const AlkException &e) {
422  m_errors |= Errors::DateFormat;
423  emit m_p->error(i18n("Unable to parse date '%1' using format '%2': %3").arg(datestr,
424  dateparse.format(),
425  e.what()));
426  m_date = QDate::currentDate();
427  emit m_p->status(i18n("Using current date for '%1'").arg(m_symbol));
428  }
429  } else {
430  m_errors |= Errors::Date;
431  emit m_p->error(i18n("Unable to parse date for '%1'").arg(m_symbol));
432  m_date = QDate::currentDate();
433  emit m_p->status(i18n("Using current date for '%1'").arg(m_symbol));
434  }
435  return true;
436 }
437 
445 bool AlkOnlineQuote::Private::slotParseQuote(const QString &_quotedata)
446 {
447  QString quotedata = _quotedata;
448  m_quoteData = quotedata;
449  bool gotprice = false;
450  bool gotdate = false;
451  bool result = true;
452 
453  kDebug(Private::dbgArea()) << "quotedata" << _quotedata;
454 
455  if (!quotedata.isEmpty()) {
456  if (!m_source.skipStripping()) {
457  //
458  // First, remove extraneous non-data elements
459  //
460 
461  // HTML tags
462  quotedata.remove(QRegExp("<[^>]*>"));
463 
464  // &...;'s
465  quotedata.replace(QRegExp("&\\w+;"), " ");
466 
467  // Extra white space
468  quotedata = quotedata.simplified();
469  kDebug(Private::dbgArea()) << "stripped text" << quotedata;
470  }
471 
472  QRegExp symbolRegExp(m_source.sym());
473  QRegExp dateRegExp(m_source.date());
474  QRegExp priceRegExp(m_source.price());
475 
476  if (symbolRegExp.indexIn(quotedata) > -1) {
477  kDebug(Private::dbgArea()) << "Symbol" << symbolRegExp.cap(1);
478  emit m_p->status(i18n("Symbol found: '%1'", symbolRegExp.cap(1)));
479  } else {
480  m_errors |= Errors::Symbol;
481  emit m_p->error(i18n("Unable to parse symbol for %1", m_symbol));
482  }
483 
484  if (priceRegExp.indexIn(quotedata) > -1) {
485  gotprice = true;
486  QString pricestr = priceRegExp.cap(1);
487  parsePrice(pricestr);
488  } else {
489  parsePrice(QString());
490  }
491 
492  if (dateRegExp.indexIn(quotedata) > -1) {
493  gotdate = true;
494  QString datestr = dateRegExp.cap(1);
495  parseDate(datestr);
496  } else {
497  parseDate(QString());
498  }
499 
500  if (gotprice && gotdate) {
501  emit m_p->quote(m_id, m_symbol, m_date, m_price);
502  } else {
503  emit m_p->failed(m_id, m_symbol);
504  result = false;
505  }
506  } else {
507  m_errors |= Errors::Data;
508  emit m_p->error(i18n("Unable to update price for %1 (empty quote data)", m_symbol));
509  emit m_p->failed(m_id, m_symbol);
510  result = false;
511  }
512  return result;
513 }
514 
516  : QObject(_parent)
517  , d(new Private(this))
518 {
519  if (profile)
520  d->m_profile = profile;
521  else {
523  d->m_ownProfile = true;
524  }
525 }
526 
528 {
529  delete d;
530 }
531 
533 {
534  return d->m_profile;
535 }
536 
538 {
539  if (profile && d->m_ownProfile) {
540  // switching from own profile to external
541  delete d->m_profile;
542  d->m_ownProfile = false;
543  d->m_profile = profile;
544 
545  } else if (!profile && !d->m_ownProfile) {
546  // switching from external to own profile
548  d->m_ownProfile = true;
549 
550  } else if (profile) {
551  // exchange external profile
552  d->m_profile = profile;
553  }
554 }
555 
556 void AlkOnlineQuote::setAcceptLanguage(const QString &language)
557 {
558  d->m_acceptLanguage = language;
559 }
560 
561 bool AlkOnlineQuote::launch(const QString &_symbol, const QString &_id, const QString &_source)
562 {
565  return d->launchFinanceQuote(_symbol, _id, _source);
566  } else if (_source.endsWith(".css")) {
567  return d->launchWebKitCssSelector(_symbol, _id, _source);
568  } else if (_source.endsWith(".webkit")) {
569  return d->launchWebKitHtmlParser(_symbol, _id, _source);
570  } else {
571  return d->launchNative(_symbol, _id, _source);
572  }
573 }
574 
576 {
577  return d->m_errors;
578 }
579 
580 #include "alkonlinequote.moc"
AlkOnlineQuote::errors
const Errors & errors()
Definition: alkonlinequote.cpp:575
AlkOnlineQuote::Private::Private
Private(AlkOnlineQuote *parent)
Definition: alkonlinequote.cpp:103
AlkWebPage::getFirstElement
QString getFirstElement(const QString &symbol)
Definition: alkwebpage.cpp:154
AlkOnlineQuote::Private::m_source
AlkOnlineQuoteSource m_source
Definition: alkonlinequote.cpp:89
AlkOnlineQuote::Private::m_profile
AlkOnlineQuotesProfile * m_profile
Definition: alkonlinequote.cpp:94
alkexception.h
AlkOnlineQuote::Private::slotLoadFinishedCssSelector
void slotLoadFinishedCssSelector(bool ok)
Definition: alkonlinequote.cpp:194
AlkOnlineQuoteSource
Definition: alkonlinequotesource.h:35
AlkOnlineQuote::~AlkOnlineQuote
~AlkOnlineQuote()
Definition: alkonlinequote.cpp:527
AlkOnlineQuoteSource::isFinanceQuote
bool isFinanceQuote() const
Definition: alkonlinequotesource.cpp:357
AlkOnlineQuote::Private::launchWebKitCssSelector
bool launchWebKitCssSelector(const QString &_symbol, const QString &_id, const QString &_source)
Definition: alkonlinequote.cpp:234
AlkOnlineQuote::profile
AlkOnlineQuotesProfile * profile()
Definition: alkonlinequote.cpp:532
AlkOnlineQuote::Private::launchFinanceQuote
bool launchFinanceQuote(const QString &_symbol, const QString &_id, const QString &_source)
Definition: alkonlinequote.cpp:340
AlkOnlineQuote::Private::m_acceptLanguage
QString m_acceptLanguage
Definition: alkonlinequote.cpp:93
AlkOnlineQuote::setProfile
void setProfile(AlkOnlineQuotesProfile *profile)
Definition: alkonlinequote.cpp:537
AlkOnlineQuote::Private::launchWebKitHtmlParser
bool launchWebKitHtmlParser(const QString &_symbol, const QString &_id, const QString &_source)
Definition: alkonlinequote.cpp:256
AlkException::what
const QString & what() const
Definition: alkexception.h:73
AlkOnlineQuote::Private::parsePrice
bool parsePrice(const QString &pricestr)
Definition: alkonlinequote.cpp:378
AlkWebPage
Definition: alkwebpage.h:69
AlkException
Definition: alkexception.h:36
AlkOnlineQuote::Private::slotLoadFinishedHtmlParser
void slotLoadFinishedHtmlParser(bool ok)
Definition: alkonlinequote.cpp:180
AlkOnlineQuotesProfile
Definition: alkonlinequotesprofile.h:34
AlkOnlineQuote::Errors::operator&
bool operator&(Type t) const
Definition: alkonlinequote.cpp:72
alkdateformat.h
AlkOnlineQuote::Errors::Type
Type
Definition: alkonlinequote.h:54
alkonlinequoteprocess.h
AlkOnlineQuote::Private::slotLoadStarted
void slotLoadStarted()
Definition: alkonlinequote.cpp:229
AlkWebPage::setContent
void setContent(const QString &s)
Definition: alkwebpage.cpp:144
AlkOnlineQuote::Private::dbgArea
static int dbgArea()
Definition: alkonlinequote.cpp:97
AlkOnlineQuotesProfileManager::instance
static AlkOnlineQuotesProfileManager & instance()
Definition: alkonlinequotesprofilemanager.cpp:102
AlkWebPage::load
void load(const QUrl &url, const QString &acceptLanguage)
Definition: alkwebpage.cpp:133
AlkOnlineQuote::Private::m_quoteData
QString m_quoteData
Definition: alkonlinequote.cpp:84
AlkOnlineQuote::Private
Definition: alkonlinequote.cpp:78
AlkOnlineQuote::Errors::URL
@ URL
Definition: alkonlinequote.h:64
AlkOnlineQuote::Private::m_eventLoop
QEventLoop * m_eventLoop
Definition: alkonlinequote.cpp:92
AlkOnlineQuote::Errors::Errors
Errors()
Definition: alkonlinequote.cpp:50
AlkOnlineQuote::Errors::m_type
QList< Type > m_type
Definition: alkonlinequote.h:74
AlkOnlineQuote::Private::m_url
KUrl m_url
Definition: alkonlinequote.cpp:91
AlkFinanceQuoteProcess::crypticName
const QString crypticName(const QString &niceName) const
Definition: alkfinancequoteprocess.cpp:148
AlkOnlineQuote::Private::parseDate
bool parseDate(const QString &datestr)
Definition: alkonlinequote.cpp:411
AlkOnlineQuote::d
Private *const d
Definition: alkonlinequote.h:120
AlkOnlineQuote::Errors::Price
@ Price
Definition: alkonlinequote.h:59
AlkOnlineQuotesProfile::Type::Script
@ Script
AlkOnlineQuote::Private::m_price
double m_price
Definition: alkonlinequote.cpp:88
alkonlinequotesprofile.h
AlkOnlineQuote::launch
bool launch(const QString &_symbol, const QString &_id, const QString &_source=QString())
Definition: alkonlinequote.cpp:561
AlkOnlineQuotesProfileManager::webPage
AlkWebPage * webPage()
Definition: alkonlinequotesprofilemanager.cpp:95
AlkOnlineQuote::Private::enter_loop
void enter_loop()
AlkOnlineQuote::Errors::operator|=
Errors & operator|=(Type t)
Definition: alkonlinequote.cpp:64
alkonlinequote.h
AlkOnlineQuote::Private::initLaunch
bool initLaunch(const QString &_symbol, const QString &_id, const QString &_source)
Definition: alkonlinequote.cpp:134
AlkOnlineQuote::Errors::None
@ None
Definition: alkonlinequote.h:55
AlkOnlineQuote::Private::m_ownProfile
bool m_ownProfile
Definition: alkonlinequote.cpp:95
alkwebpage.h
alkonlinequotesprofilemanager.h
AlkOnlineQuote::Private::launchNative
bool launchNative(const QString &_symbol, const QString &_id, const QString &_source)
Definition: alkonlinequote.cpp:276
AlkOnlineQuote::Errors::DateFormat
@ DateFormat
Definition: alkonlinequote.h:58
AlkDateFormat::convertString
QDate convertString(const QString &date, bool strict=true, unsigned centuryMidPoint=QDate::currentDate().year())
Definition: alkdateformat.cpp:454
AlkOnlineQuoteProcess
Definition: alkonlinequoteprocess.h:34
AlkOnlineQuotesProfile::type
Type type()
Definition: alkonlinequotesprofile.cpp:369
AlkOnlineQuote::Private::m_errors
AlkOnlineQuote::Errors m_errors
Definition: alkonlinequote.cpp:90
AlkOnlineQuote::Private::m_filter
AlkOnlineQuoteProcess m_filter
Definition: alkonlinequote.cpp:83
AlkOnlineQuote::Private::~Private
~Private()
Definition: alkonlinequote.cpp:111
AlkDateFormat::format
const QString & format() const
Definition: alkdateformat.cpp:438
AlkOnlineQuote::Errors::Data
@ Data
Definition: alkonlinequote.h:56
AlkOnlineQuote::Private::slotParseQuote
bool slotParseQuote(const QString &_quotedata)
Definition: alkonlinequote.cpp:445
AlkOnlineQuote::quote
void quote(QString id, QString symbol, QDate date, double price)
AlkOnlineQuote::Private::m_symbol
QString m_symbol
Definition: alkonlinequote.cpp:85
AlkWebPage::setUrl
void setUrl(const QUrl &url)
Definition: alkwebpage.cpp:139
alkfinancequoteprocess.h
AlkOnlineQuote
Definition: alkonlinequote.h:37
AlkOnlineQuote::Errors
Definition: alkonlinequote.h:51
AlkOnlineQuote::Errors::Symbol
@ Symbol
Definition: alkonlinequote.h:62
AlkDateFormat
Definition: alkdateformat.h:39
AlkOnlineQuote::Private::m_date
QDate m_date
Definition: alkonlinequote.cpp:87
AlkOnlineQuote::Errors::Script
@ Script
Definition: alkonlinequote.h:60
alkonlinequotesource.h
AlkOnlineQuote::Errors::Source
@ Source
Definition: alkonlinequote.h:61
AlkOnlineQuote::setAcceptLanguage
void setAcceptLanguage(const QString &language)
Definition: alkonlinequote.cpp:556
AlkOnlineQuote::Private::m_p
AlkOnlineQuote * m_p
Definition: alkonlinequote.cpp:82
AlkOnlineQuote::Private::m_id
QString m_id
Definition: alkonlinequote.cpp:86
AlkOnlineQuote::Errors::Date
@ Date
Definition: alkonlinequote.h:57
AlkFinanceQuoteProcess
Definition: alkfinancequoteprocess.h:36
AlkOnlineQuote::AlkOnlineQuote
AlkOnlineQuote(AlkOnlineQuotesProfile *profile=0, QObject *=0)
Definition: alkonlinequote.cpp:515