mirror of https://github.com/KLayout/klayout.git
Fixed #59 (async download of package index and details)
This commit is contained in:
parent
bf5f932ff1
commit
8eb3f5e6ce
|
|
@ -480,15 +480,14 @@ SaltGrain::from_path (const std::string &path)
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaltGrain
|
tl::InputStream *
|
||||||
SaltGrain::from_url (const std::string &url_in)
|
SaltGrain::stream_from_url (std::string &url_in)
|
||||||
{
|
{
|
||||||
if (url_in.empty ()) {
|
if (url_in.empty ()) {
|
||||||
throw tl::Exception (tl::to_string (QObject::tr ("No download link available")));
|
throw tl::Exception (tl::to_string (QObject::tr ("No download link available")));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string url = url_in;
|
std::string url = url_in;
|
||||||
std::auto_ptr<tl::InputStream> stream;
|
|
||||||
|
|
||||||
// base relative URL's on the salt mine URL
|
// base relative URL's on the salt mine URL
|
||||||
if (url.find ("http:") != 0 && url.find ("https:") != 0 && url.find ("file:") != 0 && !url.empty() && url[0] != '/' && url[0] != '\\' && lay::SaltController::instance ()) {
|
if (url.find ("http:") != 0 && url.find ("https:") != 0 && url.find ("file:") != 0 && !url.empty() && url[0] != '/' && url[0] != '\\' && lay::SaltController::instance ()) {
|
||||||
|
|
@ -501,16 +500,23 @@ SaltGrain::from_url (const std::string &url_in)
|
||||||
}
|
}
|
||||||
sami_url.setPath (path_comp.join (QString::fromUtf8 ("/")));
|
sami_url.setPath (path_comp.join (QString::fromUtf8 ("/")));
|
||||||
|
|
||||||
url = tl::to_string (sami_url.toString ());
|
url_in = tl::to_string (sami_url.toString ());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string spec_url = SaltGrain::spec_url (url);
|
std::string spec_url = SaltGrain::spec_url (url);
|
||||||
if (spec_url.find ("http:") == 0 || spec_url.find ("https:") == 0) {
|
if (spec_url.find ("http:") == 0 || spec_url.find ("https:") == 0) {
|
||||||
stream.reset (tl::WebDAVObject::download_item (spec_url));
|
return tl::WebDAVObject::download_item (spec_url);
|
||||||
} else {
|
} else {
|
||||||
stream.reset (new tl::InputStream (spec_url));
|
return new tl::InputStream (spec_url);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SaltGrain
|
||||||
|
SaltGrain::from_url (const std::string &url_in)
|
||||||
|
{
|
||||||
|
std::string url = url_in;
|
||||||
|
std::auto_ptr<tl::InputStream> stream (stream_from_url (url));
|
||||||
|
|
||||||
SaltGrain g;
|
SaltGrain g;
|
||||||
g.load (*stream);
|
g.load (*stream);
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,14 @@ public:
|
||||||
*/
|
*/
|
||||||
static SaltGrain from_url (const std::string &url);
|
static SaltGrain from_url (const std::string &url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a stream prepared for downloading the grain
|
||||||
|
* The stream is a new'd object and needs to be deleted by the caller.
|
||||||
|
* "url" is the download URL on input and gets modified to match the
|
||||||
|
* actual URL if it is a relative one.
|
||||||
|
*/
|
||||||
|
static tl::InputStream *stream_from_url (std::string &url);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Forms the spec file download URL from a given download URL
|
* @brief Forms the spec file download URL from a given download URL
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,8 @@ private:
|
||||||
SaltManagerDialog::SaltManagerDialog (QWidget *parent, lay::Salt *salt, const std::string &salt_mine_url)
|
SaltManagerDialog::SaltManagerDialog (QWidget *parent, lay::Salt *salt, const std::string &salt_mine_url)
|
||||||
: QDialog (parent),
|
: QDialog (parent),
|
||||||
m_salt_mine_url (salt_mine_url),
|
m_salt_mine_url (salt_mine_url),
|
||||||
dm_update_models (this, &SaltManagerDialog::update_models), m_current_tab (-1)
|
dm_update_models (this, &SaltManagerDialog::update_models), m_current_tab (-1),
|
||||||
|
mp_downloaded_target (0)
|
||||||
{
|
{
|
||||||
Ui::SaltManagerDialog::setupUi (this);
|
Ui::SaltManagerDialog::setupUi (this);
|
||||||
mp_properties_dialog = new lay::SaltGrainPropertiesDialog (this);
|
mp_properties_dialog = new lay::SaltGrainPropertiesDialog (this);
|
||||||
|
|
@ -126,18 +127,6 @@ SaltManagerDialog::SaltManagerDialog (QWidget *parent, lay::Salt *salt, const st
|
||||||
|
|
||||||
mp_salt = salt;
|
mp_salt = salt;
|
||||||
|
|
||||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
|
||||||
try {
|
|
||||||
if (! m_salt_mine_url.empty ()) {
|
|
||||||
tl::log << tl::to_string (tr ("Downloading package repository from %1").arg (tl::to_qstring (m_salt_mine_url)));
|
|
||||||
m_salt_mine.load (m_salt_mine_url);
|
|
||||||
}
|
|
||||||
m_salt_mine.consolidate ();
|
|
||||||
} catch (tl::Exception &ex) {
|
|
||||||
tl::error << ex.msg ();
|
|
||||||
}
|
|
||||||
QApplication::restoreOverrideCursor ();
|
|
||||||
|
|
||||||
SaltModel *model = new SaltModel (this, mp_salt);
|
SaltModel *model = new SaltModel (this, mp_salt);
|
||||||
model->set_empty_explanation (tr ("No packages are present on this system"));
|
model->set_empty_explanation (tr ("No packages are present on this system"));
|
||||||
salt_view->setModel (model);
|
salt_view->setModel (model);
|
||||||
|
|
@ -234,7 +223,7 @@ SaltManagerDialog::SaltManagerDialog (QWidget *parent, lay::Salt *salt, const st
|
||||||
connect (actionMarkForUpdate, SIGNAL (triggered ()), this, SLOT (mark_clicked ()));
|
connect (actionMarkForUpdate, SIGNAL (triggered ()), this, SLOT (mark_clicked ()));
|
||||||
connect (actionUnmarkForUpdate, SIGNAL (triggered ()), this, SLOT (mark_clicked ()));
|
connect (actionUnmarkForUpdate, SIGNAL (triggered ()), this, SLOT (mark_clicked ()));
|
||||||
|
|
||||||
update_models ();
|
refresh ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -245,10 +234,13 @@ SaltManagerDialog::mode_changed ()
|
||||||
|
|
||||||
QList<int> sizes;
|
QList<int> sizes;
|
||||||
if (m_current_tab == 2) {
|
if (m_current_tab == 2) {
|
||||||
|
selected_changed ();
|
||||||
sizes = splitter->sizes ();
|
sizes = splitter->sizes ();
|
||||||
} else if (m_current_tab == 1) {
|
} else if (m_current_tab == 1) {
|
||||||
|
mine_update_selected_changed ();
|
||||||
sizes = splitter_update->sizes ();
|
sizes = splitter_update->sizes ();
|
||||||
} else if (m_current_tab == 0) {
|
} else if (m_current_tab == 0) {
|
||||||
|
mine_new_selected_changed ();
|
||||||
sizes = splitter_new->sizes ();
|
sizes = splitter_new->sizes ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,6 +260,7 @@ SaltManagerDialog::mode_changed ()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_current_tab = mode_tab->currentIndex ();
|
m_current_tab = mode_tab->currentIndex ();
|
||||||
|
update_apply_state ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -665,31 +658,62 @@ SaltManagerDialog::salt_mine_about_to_change ()
|
||||||
void
|
void
|
||||||
SaltManagerDialog::refresh ()
|
SaltManagerDialog::refresh ()
|
||||||
{
|
{
|
||||||
BEGIN_PROTECTED
|
|
||||||
|
|
||||||
if (! m_salt_mine_url.empty ()) {
|
if (! m_salt_mine_url.empty ()) {
|
||||||
|
|
||||||
tl::log << tl::to_string (tr ("Downloading package repository from %1").arg (tl::to_qstring (m_salt_mine_url)));
|
tl::log << tl::to_string (tr ("Downloading package repository from %1").arg (tl::to_qstring (m_salt_mine_url)));
|
||||||
|
|
||||||
|
m_salt_mine_reader.reset (new tl::InputStream (m_salt_mine_url));
|
||||||
|
salt_mine_download_started ();
|
||||||
|
|
||||||
|
tl::InputHttpStream *http = dynamic_cast<tl::InputHttpStream *> (m_salt_mine_reader->base ());
|
||||||
|
if (http) {
|
||||||
|
// async reading on HTTP
|
||||||
|
http->ready ().add (this, &SaltManagerDialog::salt_mine_data_ready);
|
||||||
|
http->send ();
|
||||||
|
} else {
|
||||||
|
salt_mine_data_ready ();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SaltManagerDialog::salt_mine_download_started ()
|
||||||
|
{
|
||||||
|
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SaltManagerDialog::salt_mine_download_finished ()
|
||||||
|
{
|
||||||
|
QApplication::restoreOverrideCursor ();
|
||||||
|
m_salt_mine_reader.reset (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SaltManagerDialog::salt_mine_data_ready ()
|
||||||
|
{
|
||||||
|
BEGIN_PROTECTED
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
if (m_salt_mine_reader.get ()) {
|
||||||
|
|
||||||
lay::Salt new_mine;
|
lay::Salt new_mine;
|
||||||
new_mine.load (m_salt_mine_url);
|
new_mine.load (*m_salt_mine_reader);
|
||||||
m_salt_mine = new_mine;
|
m_salt_mine = new_mine;
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor ();
|
}
|
||||||
|
|
||||||
|
salt_mine_download_finished ();
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
QApplication::restoreOverrideCursor ();
|
salt_mine_download_finished ();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
salt_mine_changed ();
|
salt_mine_changed ();
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
END_PROTECTED
|
END_PROTECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -824,10 +848,7 @@ SaltManagerDialog::update_models ()
|
||||||
salt_mine_view_new->selectionModel ()->blockSignals (false);
|
salt_mine_view_new->selectionModel ()->blockSignals (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
mine_new_selected_changed ();
|
mode_changed ();
|
||||||
mine_update_selected_changed ();
|
|
||||||
selected_changed ();
|
|
||||||
update_apply_state ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -929,13 +950,14 @@ SaltManagerDialog::get_remote_grain_info (lay::SaltGrain *g, SaltGrainDetailsTex
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::auto_ptr<lay::SaltGrain> remote_grain;
|
m_downloaded_grain.reset (0);
|
||||||
|
m_downloaded_grain_reader.reset (0);
|
||||||
|
mp_downloaded_target = details;
|
||||||
|
m_salt_mine_grain.reset (new lay::SaltGrain (*g));
|
||||||
|
|
||||||
// Download actual grain definition file
|
// Download actual grain definition file
|
||||||
try {
|
try {
|
||||||
|
|
||||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
|
||||||
|
|
||||||
if (g->url ().empty ()) {
|
if (g->url ().empty ()) {
|
||||||
throw tl::Exception (tl::to_string (tr ("No download link available")));
|
throw tl::Exception (tl::to_string (tr ("No download link available")));
|
||||||
}
|
}
|
||||||
|
|
@ -954,27 +976,57 @@ SaltManagerDialog::get_remote_grain_info (lay::SaltGrain *g, SaltGrainDetailsTex
|
||||||
|
|
||||||
details->setHtml (html);
|
details->setHtml (html);
|
||||||
|
|
||||||
QApplication::processEvents (QEventLoop::ExcludeUserInputEvents);
|
std::string url = g->url ();
|
||||||
|
m_downloaded_grain_reader.reset (SaltGrain::stream_from_url (url));
|
||||||
|
m_downloaded_grain.reset (new SaltGrain ());
|
||||||
|
m_downloaded_grain->set_url (url);
|
||||||
|
|
||||||
remote_grain.reset (new SaltGrain (SaltGrain::from_url (g->url ())));
|
tl::InputHttpStream *http = dynamic_cast<tl::InputHttpStream *> (m_downloaded_grain_reader->base ());
|
||||||
|
if (http) {
|
||||||
if (g->name () != remote_grain->name ()) {
|
// async reading on HTTP
|
||||||
throw tl::Exception (tl::to_string (tr ("Name mismatch between repository and actual package (repository: %1, package: %2)").arg (tl::to_qstring (g->name ())).arg (tl::to_qstring (remote_grain->name ()))));
|
http->ready ().add (this, &SaltManagerDialog::data_ready);
|
||||||
|
http->send ();
|
||||||
|
} else {
|
||||||
|
data_ready ();
|
||||||
}
|
}
|
||||||
if (SaltGrain::compare_versions (g->version (), remote_grain->version ()) != 0) {
|
|
||||||
throw tl::Exception (tl::to_string (tr ("Version mismatch between repository and actual package (repository: %1, package: %2)").arg (tl::to_qstring (g->version ())).arg (tl::to_qstring (remote_grain->version ()))));
|
|
||||||
}
|
|
||||||
|
|
||||||
details->set_grain (remote_grain.get ());
|
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor ();
|
|
||||||
|
|
||||||
} catch (tl::Exception &ex) {
|
} catch (tl::Exception &ex) {
|
||||||
|
show_error (ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor ();
|
void
|
||||||
|
SaltManagerDialog::data_ready ()
|
||||||
|
{
|
||||||
|
if (! m_salt_mine_grain.get () || ! m_downloaded_grain.get () || ! m_downloaded_grain_reader.get () || ! mp_downloaded_target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
remote_grain.reset (0);
|
m_downloaded_grain->load (*m_downloaded_grain_reader);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (m_salt_mine_grain->name () != m_downloaded_grain->name ()) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Name mismatch between repository and actual package (repository: %1, package: %2)").arg (tl::to_qstring (m_salt_mine_grain->name ())).arg (tl::to_qstring (m_downloaded_grain->name ()))));
|
||||||
|
}
|
||||||
|
if (SaltGrain::compare_versions (m_salt_mine_grain->version (), m_downloaded_grain->version ()) != 0) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Version mismatch between repository and actual package (repository: %1, package: %2)").arg (tl::to_qstring (m_salt_mine_grain->version ())).arg (tl::to_qstring (m_downloaded_grain->version ()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_downloaded_target->set_grain (m_downloaded_grain.get ());
|
||||||
|
|
||||||
|
m_downloaded_grain.reset (0);
|
||||||
|
m_downloaded_grain_reader.reset (0);
|
||||||
|
m_salt_mine_grain.reset (0);
|
||||||
|
|
||||||
|
} catch (tl::Exception &ex) {
|
||||||
|
show_error (ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SaltManagerDialog::show_error (tl::Exception &ex)
|
||||||
|
{
|
||||||
QString html = tr (
|
QString html = tr (
|
||||||
"<html>"
|
"<html>"
|
||||||
"<body>"
|
"<body>"
|
||||||
|
|
@ -986,12 +1038,13 @@ SaltManagerDialog::get_remote_grain_info (lay::SaltGrain *g, SaltGrainDetailsTex
|
||||||
"</body>"
|
"</body>"
|
||||||
"</html>"
|
"</html>"
|
||||||
)
|
)
|
||||||
.arg (tl::to_qstring (SaltGrain::spec_url (g->url ())))
|
.arg (tl::to_qstring (m_downloaded_grain->url ()))
|
||||||
.arg (tl::to_qstring (tl::escaped_to_html (ex.msg ())));
|
.arg (tl::to_qstring (tl::escaped_to_html (ex.msg ())));
|
||||||
|
mp_downloaded_target->setHtml (html);
|
||||||
|
|
||||||
details->setHtml (html);
|
m_downloaded_grain.reset (0);
|
||||||
|
m_downloaded_grain_reader.reset (0);
|
||||||
}
|
m_salt_mine_grain.reset (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
#include "ui_SaltManagerDialog.h"
|
#include "ui_SaltManagerDialog.h"
|
||||||
#include "laySalt.h"
|
#include "laySalt.h"
|
||||||
#include "tlDeferredExecution.h"
|
#include "tlDeferredExecution.h"
|
||||||
|
#include "tlHttpStream.h"
|
||||||
|
#include "tlException.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
@ -40,7 +42,7 @@ class SaltGrainPropertiesDialog;
|
||||||
* @brief The dialog for managing the Salt ("Packages")
|
* @brief The dialog for managing the Salt ("Packages")
|
||||||
*/
|
*/
|
||||||
class SaltManagerDialog
|
class SaltManagerDialog
|
||||||
: public QDialog, private Ui::SaltManagerDialog
|
: public QDialog, private Ui::SaltManagerDialog, public tl::Object
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
@ -58,6 +60,17 @@ public:
|
||||||
return m_salt_mine_url;
|
return m_salt_mine_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Called when data is available from the grain downloader
|
||||||
|
*/
|
||||||
|
void data_ready ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when data is available from the salt mine downloader
|
||||||
|
*/
|
||||||
|
void salt_mine_data_ready ();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/**
|
/**
|
||||||
* @brief Called when the list of packages (grains) is about to change
|
* @brief Called when the list of packages (grains) is about to change
|
||||||
|
|
@ -171,6 +184,10 @@ private:
|
||||||
SaltGrainPropertiesDialog *mp_properties_dialog;
|
SaltGrainPropertiesDialog *mp_properties_dialog;
|
||||||
tl::DeferredMethod<SaltManagerDialog> dm_update_models;
|
tl::DeferredMethod<SaltManagerDialog> dm_update_models;
|
||||||
int m_current_tab;
|
int m_current_tab;
|
||||||
|
std::auto_ptr<tl::InputStream> m_downloaded_grain_reader;
|
||||||
|
std::auto_ptr<lay::SaltGrain> m_downloaded_grain, m_salt_mine_grain;
|
||||||
|
SaltGrainDetailsTextWidget *mp_downloaded_target;
|
||||||
|
std::auto_ptr<tl::InputStream> m_salt_mine_reader;
|
||||||
|
|
||||||
SaltGrain *current_grain ();
|
SaltGrain *current_grain ();
|
||||||
std::vector<lay::SaltGrain *> current_grains ();
|
std::vector<lay::SaltGrain *> current_grains ();
|
||||||
|
|
@ -179,6 +196,9 @@ private:
|
||||||
void update_apply_state ();
|
void update_apply_state ();
|
||||||
void get_remote_grain_info (lay::SaltGrain *g, SaltGrainDetailsTextWidget *details);
|
void get_remote_grain_info (lay::SaltGrain *g, SaltGrainDetailsTextWidget *details);
|
||||||
void consolidate_salt_mine_entries ();
|
void consolidate_salt_mine_entries ();
|
||||||
|
void show_error (tl::Exception &ex);
|
||||||
|
void salt_mine_download_started ();
|
||||||
|
void salt_mine_download_finished ();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue