diff --git a/src/lay/SaltManagerInstallConfirmationDialog.ui b/src/lay/SaltManagerInstallConfirmationDialog.ui
new file mode 100644
index 000000000..0920a619b
--- /dev/null
+++ b/src/lay/SaltManagerInstallConfirmationDialog.ui
@@ -0,0 +1,156 @@
+
+
+ SaltManagerInstallConfirmationDialog
+
+
+
+ 0
+ 0
+ 495
+ 478
+
+
+
+ Ready for Installation
+
+
+ -
+
+
+ The following packages are now ready for installation or update:
+
+
+ true
+
+
+
+ -
+
+
+
+ Package
+
+
+
+
+ Action
+
+
+
+
+ Version
+
+
+
+
+ Download link
+
+
+
+
+ -
+
+
+ Press "Ok" to install or update these packages or "Cancel" to abort.
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 6
+
+
+
+
+ -
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+ :/add.png:/add.png
+
+
+ New
+
+
+ New package
+
+
+
+
+
+ :/clear.png:/clear.png
+
+
+ Delete
+
+
+ Delete package
+
+
+
+
+
+ :/import.png:/import.png
+
+
+ Import
+
+
+ Import package
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ SaltManagerInstallConfirmationDialog
+ accept()
+
+
+ 273
+ 431
+
+
+ 276
+ 448
+
+
+
+
+ buttonBox
+ rejected()
+ SaltManagerInstallConfirmationDialog
+ reject()
+
+
+ 351
+ 426
+
+
+ 363
+ 445
+
+
+
+
+
diff --git a/src/lay/lay.pro b/src/lay/lay.pro
index 7d1bff20d..0daa9efc7 100644
--- a/src/lay/lay.pro
+++ b/src/lay/lay.pro
@@ -101,7 +101,8 @@ FORMS = \
MainConfigPage7.ui \
SaltManagerDialog.ui \
SaltGrainPropertiesDialog.ui \
- SaltGrainTemplateSelectionDialog.ui
+ SaltGrainTemplateSelectionDialog.ui \
+ SaltManagerInstallConfirmationDialog.ui
SOURCES = \
gsiDeclLayApplication.cc \
diff --git a/src/lay/laySalt.cc b/src/lay/laySalt.cc
index c16bc8e56..2812d2095 100644
--- a/src/lay/laySalt.cc
+++ b/src/lay/laySalt.cc
@@ -21,11 +21,11 @@
*/
#include "laySalt.h"
-#include "laySaltDownloadManager.h"
#include "tlString.h"
#include "tlFileUtils.h"
#include "tlLog.h"
#include "tlInternational.h"
+#include "tlWebDAV.h"
#include
#include
@@ -307,12 +307,23 @@ public:
}
bool
-Salt::create_grain (const SaltGrain &templ, SaltGrain &target, SaltDownloadManager *download_manager)
+Salt::create_grain (const SaltGrain &templ, SaltGrain &target)
{
tl_assert (!m_root.is_empty ());
const SaltGrains *coll = m_root.begin_collections ().operator-> ();
+ if (target.name ().empty ()) {
+ target.set_name (templ.name ());
+ }
+
+ if (target.path ().empty ()) {
+ lay::SaltGrain *g = grain_by_name (target.name ());
+ if (g) {
+ target.set_path (g->path ());
+ }
+ }
+
std::string path = target.path ();
if (! path.empty ()) {
coll = 0;
@@ -383,11 +394,11 @@ Salt::create_grain (const SaltGrain &templ, SaltGrain &target, SaltDownloadManag
} else if (! templ.url ().empty ()) {
- tl_assert (download_manager != 0);
-
// otherwise download from the URL
tl::info << QObject::tr ("Downloading package from '%1' to '%2' ..").arg (tl::to_qstring (templ.url ())).arg (tl::to_qstring (target.path ()));
- res = download_manager->download (templ.url (), target.path ());
+ res = tl::WebDAVObject::download (templ.url (), target.path ());
+
+ target.set_url (templ.url ());
}
diff --git a/src/lay/laySalt.h b/src/lay/laySalt.h
index ff16c0280..d238476ae 100644
--- a/src/lay/laySalt.h
+++ b/src/lay/laySalt.h
@@ -34,8 +34,6 @@
namespace lay
{
-class SaltDownloadManager;
-
/**
* @brief The global salt (package manager) object
* This object can be configured to represent a couple of locations.
@@ -123,6 +121,14 @@ public:
*/
SaltGrain *grain_by_name (const std::string &name);
+ /**
+ * @brief Gets the grain with the given name (const version)
+ */
+ const SaltGrain *grain_by_name (const std::string &name) const
+ {
+ return const_cast (this)->grain_by_name (name);
+ }
+
/**
* @brief Loads the salt from a "salt mine" file
*/
@@ -165,11 +171,11 @@ public:
* all files related to this grain. It will copy the download URL from the template into the
* new grain, so updates will come from the original location.
*
- * The target's name must be set. If a specific target location is desired, the target's
- * path must be set too.
- *
- * This method refuses to overwrite existing grains, so an update needs to be performed by first
- * deleting the grain and then re-installing it.
+ * If the target's name is not set, it will be taken from the template.
+ * If the target's path is not set and a grain with the given name already exists in
+ * the package, the path is taken from that grain.
+ * If no target path is set and no grain with this name exists yet, a new path will
+ * be constructed using the first location in the salt.
*
* The target grain will be updated with the installation information. If the target grain
* contains an installation path prior to the installation, this path will be used for the
@@ -177,7 +183,7 @@ public:
*
* Returns true, if the package could be created successfully.
*/
- bool create_grain (const SaltGrain &templ, SaltGrain &target, SaltDownloadManager *download_manager = 0);
+ bool create_grain (const SaltGrain &templ, SaltGrain &target);
signals:
/**
diff --git a/src/lay/laySaltDownloadManager.cc b/src/lay/laySaltDownloadManager.cc
index f6970b851..c3e587551 100644
--- a/src/lay/laySaltDownloadManager.cc
+++ b/src/lay/laySaltDownloadManager.cc
@@ -21,20 +21,189 @@
*/
#include "laySaltDownloadManager.h"
+#include "laySalt.h"
+#include "tlFileUtils.h"
+#include "tlWebDAV.h"
+
+#include "ui_SaltManagerInstallConfirmationDialog.h"
+
+#include
namespace lay
{
+// ----------------------------------------------------------------------------------
+
+class ConfirmationDialog
+ : public QDialog, private Ui::SaltManagerInstallConfirmationDialog
+{
+public:
+ ConfirmationDialog (QWidget *parent)
+ : QDialog (parent)
+ {
+ Ui::SaltManagerInstallConfirmationDialog::setupUi (this);
+ }
+
+ void add_info (const std::string &name, bool update, const std::string &version, const std::string &url)
+ {
+ QTreeWidgetItem *item = new QTreeWidgetItem (list);
+ item->setText (0, tl::to_qstring (name));
+ item->setText (1, update ? tr ("UPDATE") : tr ("INSTALL"));
+ item->setText (2, tl::to_qstring (version));
+ item->setText (3, tl::to_qstring (url));
+ }
+};
+
+// ----------------------------------------------------------------------------------
+
SaltDownloadManager::SaltDownloadManager ()
{
// .. nothing yet ..
}
-bool
-SaltDownloadManager::download (const std::string &url, const std::string &target_dir)
+void
+SaltDownloadManager::register_download (const std::string &name, const std::string &url, const std::string &version)
{
- // @@@
+ m_registry.insert (std::make_pair (name, Descriptor (url, version)));
+}
+
+void
+SaltDownloadManager::compute_dependencies (const lay::Salt &salt, const lay::Salt &salt_mine)
+{
+ tl::AbsoluteProgress progress (tl::to_string (QObject::tr ("Computing package dependencies ..")));
+
+ while (needs_iteration ()) {
+
+ fetch_missing (salt_mine, progress);
+
+ std::map registry = m_registry;
+ for (std::map::const_iterator p = registry.begin (); p != registry.end (); ++p) {
+
+ for (std::vector::const_iterator d = p->second.grain.dependencies ().begin (); d != p->second.grain.dependencies ().end (); ++d) {
+
+ std::map::iterator r = m_registry.find (d->name);
+ if (r != m_registry.end ()) {
+
+ if (SaltGrain::compare_versions (r->second.version, d->version) < 0) {
+
+ // Grain is present, but too old -> update version and reload in the next iteration
+ r->second.downloaded = false;
+ r->second.version = d->version;
+ r->second.url = d->url;
+ r->second.downloaded = false;
+
+ }
+
+ } else {
+
+ const SaltGrain *g = salt.grain_by_name (d->name);
+ if (g) {
+
+ // Grain is installed already, but too old -> register for update
+ if (SaltGrain::compare_versions (g->version (), d->version) < 0) {
+ register_download (d->name, d->url, d->version);
+ }
+
+ } else {
+ register_download (d->name, d->url, d->version);
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+}
+
+bool
+SaltDownloadManager::needs_iteration ()
+{
+ for (std::map::const_iterator p = m_registry.begin (); p != m_registry.end (); ++p) {
+ if (! p->second.downloaded) {
+ return true;
+ }
+ }
return false;
}
+void
+SaltDownloadManager::fetch_missing (const lay::Salt &salt_mine, tl::AbsoluteProgress &progress)
+{
+ for (std::map::iterator p = m_registry.begin (); p != m_registry.end (); ++p) {
+
+ if (! p->second.downloaded) {
+
+ ++progress;
+
+ // If no URL is given, utilize the salt mine to fetch it
+ if (p->second.url.empty ()) {
+ const lay::SaltGrain *g = salt_mine.grain_by_name (p->first);
+ if (SaltGrain::compare_versions (g->version (), p->second.version) < 0) {
+ throw tl::Exception (tl::to_string (QObject::tr ("Package '%1': package in repository is too old (%2) to satisfy requirements (%3)").arg (tl::to_qstring (p->first)).arg (tl::to_qstring (g->version ())).arg (tl::to_qstring (p->second.version))));
+ }
+ p->second.version = g->version ();
+ p->second.url = g->url ();
+ }
+
+ p->second.grain = SaltGrain::from_url (p->second.url);
+ p->second.downloaded = true;
+
+ }
+
+ }
+}
+
+bool
+SaltDownloadManager::show_confirmation_dialog (QWidget *parent, const lay::Salt &salt)
+{
+ lay::ConfirmationDialog dialog (parent);
+
+ // First the packages to update
+ for (std::map::const_iterator p = m_registry.begin (); p != m_registry.end (); ++p) {
+ const lay::SaltGrain *g = salt.grain_by_name (p->first);
+ if (g) {
+ dialog.add_info (p->first, true, g->version () + "->" + p->second.version, p->second.url);
+ }
+ }
+
+ // Then the packages to install
+ for (std::map::const_iterator p = m_registry.begin (); p != m_registry.end (); ++p) {
+ const lay::SaltGrain *g = salt.grain_by_name (p->first);
+ if (!g) {
+ dialog.add_info (p->first, false, p->second.version, p->second.url);
+ }
+ }
+
+ return dialog.exec ();
+}
+
+bool
+SaltDownloadManager::execute (lay::Salt &salt)
+{
+ bool result = true;
+
+ tl::RelativeProgress progress (tl::to_string (QObject::tr ("Downloading packages")), m_registry.size (), 1);
+
+ for (std::map::const_iterator p = m_registry.begin (); p != m_registry.end (); ++p) {
+
+ lay::SaltGrain target;
+ target.set_name (p->first);
+ lay::SaltGrain *g = salt.grain_by_name (p->first);
+ if (g) {
+ target.set_path (g->path ());
+ }
+
+ if (! salt.create_grain (p->second.grain, target)) {
+ result = false;
+ }
+
+ ++progress;
+
+ }
+
+ return result;
+}
+
}
diff --git a/src/lay/laySaltDownloadManager.h b/src/lay/laySaltDownloadManager.h
index 141df238a..89fd74620 100644
--- a/src/lay/laySaltDownloadManager.h
+++ b/src/lay/laySaltDownloadManager.h
@@ -24,17 +24,27 @@
#define HDR_laySaltDownloadManager
#include "layCommon.h"
+#include "laySaltGrain.h"
+#include "tlProgress.h"
#include
#include
+#include