diff --git a/leocad.pro b/leocad.pro index 682062c0..d89a8c76 100644 --- a/leocad.pro +++ b/leocad.pro @@ -20,7 +20,7 @@ win32 { QMAKE_LFLAGS += /INCREMENTAL PRECOMPILED_SOURCE = common/lc_global.cpp RC_FILE = qt/leocad.rc - LIBS += -ladvapi32 -lshell32 -lopengl32 + LIBS += -ladvapi32 -lshell32 -lopengl32 -lwininet.lib } else { PRECOMPILED_HEADER = common/lc_global.h LIBS += -lz diff --git a/qt/lc_setsdatabasedialog.cpp b/qt/lc_setsdatabasedialog.cpp index 84ec2f5b..b18c2705 100644 --- a/qt/lc_setsdatabasedialog.cpp +++ b/qt/lc_setsdatabasedialog.cpp @@ -3,6 +3,61 @@ #include #include +#ifdef Q_OS_WIN + +lcHttpReply::lcHttpReply(QObject* Parent, const QString& URL) + : QThread(Parent) +{ + mError = true; + mAbort = false; + mURL = URL; +} + +void lcHttpReply::run() +{ + HINTERNET Session = nullptr; + HINTERNET Request = nullptr; + + if (sizeof(wchar_t) != sizeof(QChar)) + return; + + Session = InternetOpen(L"LeoCAD", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + if (!Session) + return; + + Request = InternetOpenUrl(Session, (WCHAR*)mURL.data(), NULL, 0, 0, 0); + if (!Request) + { + InternetCloseHandle(Session); + return; + } + + for (;;) + { + char Buffer[1024]; + DWORD BytesRead; + + if (mAbort) + break; + + if (!InternetReadFile(Request, Buffer, sizeof(Buffer), &BytesRead)) + break; + + if (BytesRead) + mBuffer.append(Buffer, BytesRead); + else + { + mError = false; + break; + } + } + + InternetCloseHandle(Request); + InternetCloseHandle(Session); +} + +#endif + lcSetsDatabaseDialog::lcSetsDatabaseDialog(QWidget* Parent) : QDialog(Parent), ui(new Ui::lcSetsDatabaseDialog) @@ -12,9 +67,11 @@ lcSetsDatabaseDialog::lcSetsDatabaseDialog(QWidget* Parent) connect(ui->SetsTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(accept())); connect(this, SIGNAL(finished(int)), this, SLOT(Finished(int))); - connect(&mNetworkManager, SIGNAL(finished(QNetworkReply*)), SLOT(DownloadFinished(QNetworkReply*))); +#ifndef Q_OS_WIN + connect(&mNetworkManager, SIGNAL(finished(QNetworkReply*)), SLOT(DownloadFinished(lcHttpReply*))); +#endif - mKeyListReply = mNetworkManager.get(QNetworkRequest(QUrl("http://www.leocad.org/rebrickable.json"))); + mKeyListReply = RequestURL("http://www.leocad.org/rebrickable.json"); } lcSetsDatabaseDialog::~lcSetsDatabaseDialog() @@ -22,6 +79,18 @@ lcSetsDatabaseDialog::~lcSetsDatabaseDialog() delete ui; } +lcHttpReply* lcSetsDatabaseDialog::RequestURL(const QString& URL) +{ +#ifdef Q_OS_WIN + lcHttpReply* Reply = new lcHttpReply(this, URL); + connect(Reply, &QThread::finished, [this, Reply] { DownloadFinished(Reply); }); + Reply->start(); + return Reply; +#else + return mNetworkManager.get(QNetworkRequest(QUrl(URL))); +#endif +} + QString lcSetsDatabaseDialog::GetSetName() const { QTreeWidgetItem* Current = ui->SetsTree->currentItem(); @@ -74,7 +143,7 @@ void lcSetsDatabaseDialog::accept() int KeyIndex = QTime::currentTime().msec() % mKeys.size(); QString DownloadUrl = QString("https://rebrickable.com/api/v3/lego/sets/%1/parts/?key=%2").arg(SetNum, mKeys[KeyIndex]); - mInventoryReply = mNetworkManager.get(QNetworkRequest(QUrl(DownloadUrl))); + mInventoryReply = RequestURL(DownloadUrl); while (mInventoryReply) { @@ -135,7 +204,7 @@ void lcSetsDatabaseDialog::on_SearchButton_clicked() int KeyIndex = QTime::currentTime().msec() % mKeys.size(); QString SearchUrl = QString("https://rebrickable.com/api/v3/lego/sets/?search=%1&key=%2").arg(Keyword, mKeys[KeyIndex]); - mSearchReply = mNetworkManager.get(QNetworkRequest(QUrl(SearchUrl))); + mSearchReply = RequestURL(SearchUrl); while (mSearchReply) { @@ -151,7 +220,7 @@ void lcSetsDatabaseDialog::on_SearchButton_clicked() } } -void lcSetsDatabaseDialog::DownloadFinished(QNetworkReply* Reply) +void lcSetsDatabaseDialog::DownloadFinished(lcHttpReply* Reply) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) if (Reply == mKeyListReply) diff --git a/qt/lc_setsdatabasedialog.h b/qt/lc_setsdatabasedialog.h index 5f639161..bdd3f55b 100644 --- a/qt/lc_setsdatabasedialog.h +++ b/qt/lc_setsdatabasedialog.h @@ -7,6 +7,48 @@ namespace Ui { class lcSetsDatabaseDialog; } +#ifdef Q_OS_WIN + +#include + +class lcHttpReply : public QThread +{ + Q_OBJECT + +public: + lcHttpReply(QObject* Parent, const QString& URL); + + void run(); + + bool error() const + { + return mError; + } + + void abort() + { + mAbort = true; + } + + QByteArray readAll() const + { + return mBuffer; + } + +protected: + bool mError; + bool mAbort; + QByteArray mBuffer; + QString mURL; +}; + +#else + +typedef QNetworkReply lcHttpReply; + +#endif + + class lcSetsDatabaseDialog : public QDialog { Q_OBJECT @@ -26,16 +68,21 @@ public: virtual bool eventFilter(QObject* Object, QEvent* Event) override; public slots: - void DownloadFinished(QNetworkReply* Reply); + void DownloadFinished(lcHttpReply* Reply); void on_SearchButton_clicked(); void accept() override; void Finished(int Result); -private: +protected: + lcHttpReply* RequestURL(const QString& URL); + +#ifndef Q_OS_WIN QNetworkAccessManager mNetworkManager; - QNetworkReply* mKeyListReply; - QNetworkReply* mSearchReply; - QNetworkReply* mInventoryReply; +#endif + + lcHttpReply* mKeyListReply; + lcHttpReply* mSearchReply; + lcHttpReply* mInventoryReply; QStringList mKeys; QByteArray mInventory;