diff --git a/src/lay/SaltManagerDialog.ui b/src/lay/SaltManagerDialog.ui index 9194d7715..a51993a12 100644 --- a/src/lay/SaltManagerDialog.ui +++ b/src/lay/SaltManagerDialog.ui @@ -17,7 +17,7 @@ - 0 + 1 @@ -231,8 +231,8 @@ 0 0 - 343 - 207 + 537 + 284 @@ -456,11 +456,18 @@ - Mark for installation + Mark or unmark for installation Mark + + + :/marked_16.png:/marked_16.png + + + true + diff --git a/src/lay/images/marked_16.png b/src/lay/images/marked_16.png new file mode 100644 index 000000000..aa152411b Binary files /dev/null and b/src/lay/images/marked_16.png differ diff --git a/src/lay/images/marked_24.png b/src/lay/images/marked_24.png new file mode 100644 index 000000000..8a445139b Binary files /dev/null and b/src/lay/images/marked_24.png differ diff --git a/src/lay/images/marked_64.png b/src/lay/images/marked_64.png new file mode 100644 index 000000000..02c23d603 Binary files /dev/null and b/src/lay/images/marked_64.png differ diff --git a/src/lay/layResources.qrc b/src/lay/layResources.qrc index 3ffd9e81e..52e7bc522 100644 --- a/src/lay/layResources.qrc +++ b/src/lay/layResources.qrc @@ -120,6 +120,9 @@ images/empty_16.png images/error_16.png images/info_16.png + images/marked_24.png + images/marked_64.png + images/marked_16.png syntax/ruby.xml diff --git a/src/lay/laySaltManagerDialog.cc b/src/lay/laySaltManagerDialog.cc index 5ce7cd4eb..57ce3fbf5 100644 --- a/src/lay/laySaltManagerDialog.cc +++ b/src/lay/laySaltManagerDialog.cc @@ -155,19 +155,27 @@ SaltManagerDialog::SaltManagerDialog (QWidget *parent) mp_salt = get_salt (); mp_salt_mine = get_salt_mine (); - SaltModel *model; - - model = new SaltModel (this, mp_salt); + SaltModel *model = new SaltModel (this, mp_salt); salt_view->setModel (model); salt_view->setItemDelegate (new SaltItemDelegate (this)); - model = new SaltModel (this, mp_salt_mine); - salt_mine_view->setModel (model); + SaltModel *mine_model = new SaltModel (this, mp_salt_mine); + salt_mine_view->setModel (mine_model); salt_mine_view->setItemDelegate (new SaltItemDelegate (this)); + // Establish a message saying that an update is available + for (Salt::flat_iterator g = mp_salt->begin_flat (); g != mp_salt->end_flat (); ++g) { + SaltGrain *gm = mp_salt_mine->grain_by_name ((*g)->name ()); + if (gm && SaltGrain::compare_versions (gm->version (), (*g)->version ()) > 0) { + model->set_message ((*g)->name (), tl::to_string (tr ("An update to version %1 is available").arg (tl::to_qstring (gm->version ())))); + mine_model->set_message ((*g)->name (), tl::to_string (tr ("The installed version is outdated (%1)").arg (tl::to_qstring ((*g)->version ())))); + } + } + mode_tab->setCurrentIndex (mp_salt->is_empty () ? 1 : 0); connect (mode_tab, SIGNAL (currentChanged (int)), this, SLOT (mode_changed ())); + connect (mp_salt, SIGNAL (collections_changed ()), this, SLOT (salt_changed ())); connect (mp_salt_mine, SIGNAL (collections_changed ()), this, SLOT (salt_mine_changed ())); @@ -175,12 +183,14 @@ SaltManagerDialog::SaltManagerDialog (QWidget *parent) salt_mine_changed (); connect (salt_view->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_changed ())); - connect (salt_mine_view->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (mine_current_changed ())); + connect (salt_mine_view->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (mine_current_changed ()), Qt::QueuedConnection); search_installed_edit->set_clear_button_enabled (true); search_new_edit->set_clear_button_enabled (true); connect (search_installed_edit, SIGNAL (textChanged (const QString &)), this, SLOT (search_text_changed (const QString &))); connect (search_new_edit, SIGNAL (textChanged (const QString &)), this, SLOT (search_text_changed (const QString &))); + + connect (mark_button, SIGNAL (clicked ()), this, SLOT (mark_clicked ())); } void @@ -233,6 +243,21 @@ SaltManagerDialog::search_text_changed (const QString &text) } } +void +SaltManagerDialog::mark_clicked () +{ + SaltModel *model = dynamic_cast (salt_mine_view->model ()); + if (! model) { + return; + } + SaltGrain *g = mine_current_grain (); + if (! g) { + return; + } + + model->set_marked (g->name (), !model->is_marked (g->name ())); +} + void SaltManagerDialog::edit_properties () { @@ -379,6 +404,7 @@ SaltManagerDialog::salt_mine_changed () void SaltManagerDialog::mine_current_changed () { + BEGIN_PROTECTED SaltGrain *g = mine_current_grain (); @@ -398,6 +424,22 @@ BEGIN_PROTECTED throw tl::Exception (tl::to_string (tr ("No download link available"))); } + QString text = tr ( + "" + "" + "" + "

Fetching Package Definition ...

" + "

URL: %1

" + "
" + "" + "" + ) + .arg (tl::to_qstring (SaltGrain::spec_url (g->url ()))); + + details_new_text->setHtml (text); + + QApplication::processEvents (QEventLoop::ExcludeUserInputEvents); + tl::InputHttpStream http (SaltGrain::spec_url (g->url ())); tl::InputStream stream (http); @@ -422,9 +464,10 @@ BEGIN_PROTECTED "" "" "" - "

Error Fetching Package Definition

" - "

URL: %1

" - "

Error: %2

" + "

Error Fetching Package Definition

" + "

URL: %1

" + "

Error: %2

" + "
" "" "" ) diff --git a/src/lay/laySaltManagerDialog.h b/src/lay/laySaltManagerDialog.h index 68576602a..6a5068217 100644 --- a/src/lay/laySaltManagerDialog.h +++ b/src/lay/laySaltManagerDialog.h @@ -75,6 +75,11 @@ private slots: */ void edit_properties (); + /** + * @brief Called when the "mark" button is pressed + */ + void mark_clicked (); + /** * @brief Called when the "edit" button is pressed */ diff --git a/src/lay/laySaltModel.cc b/src/lay/laySaltModel.cc index ded796c86..57dd44212 100644 --- a/src/lay/laySaltModel.cc +++ b/src/lay/laySaltModel.cc @@ -120,6 +120,12 @@ SaltModel::data (const QModelIndex &index, int role) const text += tl::escaped_to_html (g->doc ()); text += "

"; } + + std::map::const_iterator m = m_messages.find (g->name ()); + if (m != m_messages.end ()) { + text += "

" + tl::escaped_to_html (m->second) + "

"; + } + text += ""; return tl::to_qstring (text); @@ -129,28 +135,39 @@ SaltModel::data (const QModelIndex &index, int role) const int icon_dim = 64; const lay::SaltGrain *g = mp_salt->begin_flat ()[index.row ()]; + + QImage img; if (g->icon ().isNull ()) { - return QIcon (":/salt_icon.png"); + img = QImage (":/salt_icon.png"); } else { + img = g->icon (); + } - QImage img = g->icon (); - if (img.width () == icon_dim && img.height () == icon_dim) { - return QPixmap::fromImage (img); - } else { + if (img.width () != icon_dim || img.height () != icon_dim) { - img = img.scaled (QSize (icon_dim, icon_dim), Qt::KeepAspectRatio, Qt::SmoothTransformation); + QImage scaled = img.scaled (QSize (icon_dim, icon_dim), Qt::KeepAspectRatio, Qt::SmoothTransformation); - QImage final_img (icon_dim, icon_dim, QImage::Format_ARGB32); - final_img.fill (QColor (0, 0, 0, 0)); - QPainter painter (&final_img); - painter.drawImage ((icon_dim - img.width ()) / 2, (icon_dim - img.height ()) / 2, img); - - return QPixmap::fromImage (final_img); - - } + img = QImage (icon_dim, icon_dim, QImage::Format_ARGB32); + img.fill (QColor (0, 0, 0, 0)); + QPainter painter (&img); + painter.drawImage ((icon_dim - scaled.width ()) / 2, (icon_dim - scaled.height ()) / 2, scaled); } + if (m_marked.find (g->name ()) != m_marked.end ()) { + QPainter painter (&img); + QImage warn (":/marked_64.png"); + painter.drawImage (0, 0, warn); + } + + if (m_messages.find (g->name ()) != m_messages.end ()) { + QPainter painter (&img); + QImage warn (":/warn_16.png"); + painter.drawImage (0, 0, warn); + } + + return QPixmap::fromImage (img); + } else { return QVariant (); } @@ -198,6 +215,34 @@ SaltModel::grain_from_index (const QModelIndex &index) const } } +bool +SaltModel::is_marked (const std::string &name) const +{ + return m_marked.find (name) != m_marked.end (); +} + +void +SaltModel::set_marked (const std::string &name, bool marked) +{ + if (! marked) { + m_marked.erase (name); + } else { + m_marked.insert (name); + } + emit dataChanged (index (0, 0, QModelIndex ()), index (rowCount (QModelIndex ()) - 1, 0, QModelIndex ())); +} + +void +SaltModel::set_message (const std::string &name, const std::string &message) +{ + if (message.empty ()) { + m_messages.erase (name); + } else { + m_messages.insert (std::make_pair (name, message)); + } + emit dataChanged (index (0, 0, QModelIndex ()), index (rowCount (QModelIndex ()) - 1, 0, QModelIndex ())); +} + void SaltModel::update () { diff --git a/src/lay/laySaltModel.h b/src/lay/laySaltModel.h index 1ffa5f86e..20a537e2c 100644 --- a/src/lay/laySaltModel.h +++ b/src/lay/laySaltModel.h @@ -29,6 +29,8 @@ #include #include #include +#include +#include namespace lay { @@ -86,8 +88,23 @@ public: */ void update (); + /** + * @brief Sets or resets the "marked" flag on the grain with the given name + */ + void set_marked (const std::string &name, bool marked); + + /** + * @brief Installs a message on the grain with the given name + * Installing an empty message basically removes the message. + */ + void set_message (const std::string &name, const std::string &message); + public: lay::Salt *mp_salt; + std::set m_marked; + std::map m_messages; + + bool is_marked (const std::string &name) const; }; // --------------------------------------------------------------------------------------