mirror of https://github.com/KLayout/klayout.git
Package manager enhancements
* marked icon * multiple selection * hidden flag for repository * background color of package list black always * consolidation of package list - identical packages are reduced to the latest one
This commit is contained in:
parent
7455a8151d
commit
4ca24df814
|
|
@ -17,7 +17,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="mode_tab">
|
<widget class="QTabWidget" name="mode_tab">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>2</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab_2">
|
<widget class="QWidget" name="tab_2">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
|
@ -143,9 +143,15 @@
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QListView" name="salt_mine_view_new">
|
<widget class="QListView" name="salt_mine_view_new">
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::WheelFocus</enum>
|
||||||
|
</property>
|
||||||
<property name="alternatingRowColors">
|
<property name="alternatingRowColors">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>64</width>
|
<width>64</width>
|
||||||
|
|
@ -436,9 +442,15 @@
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QListView" name="salt_mine_view_update">
|
<widget class="QListView" name="salt_mine_view_update">
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::WheelFocus</enum>
|
||||||
|
</property>
|
||||||
<property name="alternatingRowColors">
|
<property name="alternatingRowColors">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>64</width>
|
<width>64</width>
|
||||||
|
|
@ -722,9 +734,15 @@
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QListView" name="salt_view">
|
<widget class="QListView" name="salt_view">
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::WheelFocus</enum>
|
||||||
|
</property>
|
||||||
<property name="alternatingRowColors">
|
<property name="alternatingRowColors">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>64</width>
|
<width>64</width>
|
||||||
|
|
@ -786,8 +804,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>343</width>
|
<width>537</width>
|
||||||
<height>207</height>
|
<height>284</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 424 B After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1001 B After Width: | Height: | Size: 1.2 KiB |
|
|
@ -172,7 +172,12 @@ struct NameAndTopoIndexCompare
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: UTF-8 support?
|
// The hidden after non-hidden
|
||||||
|
if (a->is_hidden () != b->is_hidden ()) {
|
||||||
|
return a->is_hidden () < b->is_hidden ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally the name (TODO: UTF-8 support?)
|
||||||
return a->name () < b->name ();
|
return a->name () < b->name ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,6 +245,12 @@ Salt::invalidate ()
|
||||||
emit collections_changed ();
|
emit collections_changed ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Salt::consolidate ()
|
||||||
|
{
|
||||||
|
m_root.consolidate ();
|
||||||
|
invalidate ();
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool remove_from_collection (SaltGrains &collection, const std::string &name)
|
bool remove_from_collection (SaltGrains &collection, const std::string &name)
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,13 @@ public:
|
||||||
*/
|
*/
|
||||||
bool create_grain (const SaltGrain &templ, SaltGrain &target);
|
bool create_grain (const SaltGrain &templ, SaltGrain &target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes redundant entries with same names
|
||||||
|
*
|
||||||
|
* This method will keep the first entry or the one with the higher version.
|
||||||
|
*/
|
||||||
|
void consolidate ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the root collection
|
* @brief Gets the root collection
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ namespace lay
|
||||||
static const std::string grain_filename = "grain.xml";
|
static const std::string grain_filename = "grain.xml";
|
||||||
|
|
||||||
SaltGrain::SaltGrain ()
|
SaltGrain::SaltGrain ()
|
||||||
|
: m_hidden (false)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
@ -62,6 +63,7 @@ SaltGrain::operator== (const SaltGrain &other) const
|
||||||
m_author == other.m_author &&
|
m_author == other.m_author &&
|
||||||
m_author_contact == other.m_author_contact &&
|
m_author_contact == other.m_author_contact &&
|
||||||
m_license == other.m_license &&
|
m_license == other.m_license &&
|
||||||
|
m_hidden == other.m_hidden &&
|
||||||
m_authored_time == other.m_authored_time &&
|
m_authored_time == other.m_authored_time &&
|
||||||
m_installed_time == other.m_installed_time;
|
m_installed_time == other.m_installed_time;
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +80,12 @@ SaltGrain::set_token (const std::string &t)
|
||||||
m_token = t;
|
m_token = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SaltGrain::set_hidden (bool f)
|
||||||
|
{
|
||||||
|
m_hidden = f;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SaltGrain::set_version (const std::string &v)
|
SaltGrain::set_version (const std::string &v)
|
||||||
{
|
{
|
||||||
|
|
@ -374,6 +382,7 @@ SaltGrain::xml_elements ()
|
||||||
sp_xml_elements = new tl::XMLElementList (
|
sp_xml_elements = new tl::XMLElementList (
|
||||||
tl::make_member (&SaltGrain::name, &SaltGrain::set_name, "name") +
|
tl::make_member (&SaltGrain::name, &SaltGrain::set_name, "name") +
|
||||||
tl::make_member (&SaltGrain::token, &SaltGrain::set_token, "token") +
|
tl::make_member (&SaltGrain::token, &SaltGrain::set_token, "token") +
|
||||||
|
tl::make_member (&SaltGrain::is_hidden, &SaltGrain::set_hidden, "hidden") +
|
||||||
tl::make_member (&SaltGrain::version, &SaltGrain::set_version, "version") +
|
tl::make_member (&SaltGrain::version, &SaltGrain::set_version, "version") +
|
||||||
tl::make_member (&SaltGrain::api_version, &SaltGrain::set_api_version, "api-version") +
|
tl::make_member (&SaltGrain::api_version, &SaltGrain::set_api_version, "api-version") +
|
||||||
tl::make_member (&SaltGrain::title, &SaltGrain::set_title, "title") +
|
tl::make_member (&SaltGrain::title, &SaltGrain::set_title, "title") +
|
||||||
|
|
|
||||||
|
|
@ -326,6 +326,22 @@ public:
|
||||||
*/
|
*/
|
||||||
void set_url (const std::string &u);
|
void set_url (const std::string &u);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets a value indicating whether the grain is hidden
|
||||||
|
* A grain can be hidden (in Salt.Mine) if it's a pure dependency package
|
||||||
|
* which is only there because others need it. Such packages are listed
|
||||||
|
* as dependencies, but they are not shown by default.
|
||||||
|
*/
|
||||||
|
bool is_hidden () const
|
||||||
|
{
|
||||||
|
return m_hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a value indicating whether the grain is hidden
|
||||||
|
*/
|
||||||
|
void set_hidden (bool f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the dependencies of the grain
|
* @brief Gets the dependencies of the grain
|
||||||
* Grains this grain depends on are installed automatically when the grain
|
* Grains this grain depends on are installed automatically when the grain
|
||||||
|
|
@ -455,6 +471,7 @@ private:
|
||||||
std::string m_author;
|
std::string m_author;
|
||||||
std::string m_author_contact;
|
std::string m_author_contact;
|
||||||
std::string m_license;
|
std::string m_license;
|
||||||
|
bool m_hidden;
|
||||||
QDateTime m_authored_time, m_installed_time;
|
QDateTime m_authored_time, m_installed_time;
|
||||||
QImage m_icon, m_screenshot;
|
QImage m_icon, m_screenshot;
|
||||||
std::vector<Dependency> m_dependencies;
|
std::vector<Dependency> m_dependencies;
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,71 @@ SaltGrains::from_path (const std::string &path, const std::string &prefix)
|
||||||
return grains;
|
return grains;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SaltGrains::merge_with (const lay::SaltGrains &other)
|
||||||
|
{
|
||||||
|
for (lay::SaltGrains::collection_iterator c = other.begin_collections (); c != other.end_collections (); ++c) {
|
||||||
|
add_collection (*c);
|
||||||
|
}
|
||||||
|
for (lay::SaltGrains::grain_iterator g = other.begin_grains (); g != other.end_grains (); ++g) {
|
||||||
|
add_grain (*g);
|
||||||
|
}
|
||||||
|
consolidate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SaltGrains::consolidate ()
|
||||||
|
{
|
||||||
|
std::vector<collections_type::iterator> collection_to_delete;
|
||||||
|
|
||||||
|
std::map<std::string, collections_type::iterator> collection_by_name;
|
||||||
|
for (collections_type::iterator c = m_collections.begin (); c != m_collections.end (); ++c) {
|
||||||
|
|
||||||
|
std::map<std::string, collections_type::iterator>::iterator cn = collection_by_name.find (c->name ());
|
||||||
|
if (cn != collection_by_name.end ()) {
|
||||||
|
cn->second->merge_with (*c);
|
||||||
|
collection_to_delete.push_back (c);
|
||||||
|
} else {
|
||||||
|
c->consolidate ();
|
||||||
|
collection_by_name.insert (std::make_pair (c->name (), c));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually delete the additional collections
|
||||||
|
for (std::vector<collections_type::iterator>::reverse_iterator i = collection_to_delete.rbegin (); i != collection_to_delete.rend (); ++i) {
|
||||||
|
remove_collection (*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<lay::SaltGrains::grain_iterator> to_delete;
|
||||||
|
|
||||||
|
std::map<std::string, lay::SaltGrains::grain_iterator> grain_by_name;
|
||||||
|
for (lay::SaltGrains::grain_iterator g = begin_grains (); g != end_grains (); ++g) {
|
||||||
|
|
||||||
|
std::map<std::string, lay::SaltGrains::grain_iterator>::iterator gn = grain_by_name.find (g->name ());
|
||||||
|
if (gn != grain_by_name.end ()) {
|
||||||
|
|
||||||
|
// take the one with the higher version. On equal version use the first one.
|
||||||
|
if (lay::SaltGrain::compare_versions (gn->second->version (), g->version ()) < 0) {
|
||||||
|
to_delete.push_back (gn->second);
|
||||||
|
gn->second = g;
|
||||||
|
} else {
|
||||||
|
to_delete.push_back (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
grain_by_name.insert (std::make_pair (g->name (), g));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually delete the additional elements
|
||||||
|
for (std::vector<lay::SaltGrains::grain_iterator>::reverse_iterator i = to_delete.rbegin (); i != to_delete.rend (); ++i) {
|
||||||
|
remove_grain (*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static tl::XMLElementList s_group_struct =
|
static tl::XMLElementList s_group_struct =
|
||||||
tl::make_member (&SaltGrains::name, &SaltGrains::set_name, "name") +
|
tl::make_member (&SaltGrains::name, &SaltGrains::set_name, "name") +
|
||||||
tl::make_member (&SaltGrains::include, "include") +
|
tl::make_member (&SaltGrains::include, "include") +
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,19 @@ public:
|
||||||
*/
|
*/
|
||||||
bool remove_grain (grain_iterator iter, bool with_files = false);
|
bool remove_grain (grain_iterator iter, bool with_files = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Merges the other collection into this one
|
||||||
|
* This method will apply the rules of "consolidate" for grains and will merge
|
||||||
|
* grain collections with the same name into one.
|
||||||
|
*/
|
||||||
|
void merge_with (const lay::SaltGrains &other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes redundant entries with same names
|
||||||
|
* This method will keep the first entry or the one with the higher version.
|
||||||
|
*/
|
||||||
|
void consolidate ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets a value indicating whether the collection is empty
|
* @brief Gets a value indicating whether the collection is empty
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,7 @@ SaltManagerDialog::SaltManagerDialog (QWidget *parent, lay::Salt *salt, const st
|
||||||
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.load (m_salt_mine_url);
|
m_salt_mine.load (m_salt_mine_url);
|
||||||
}
|
}
|
||||||
|
m_salt_mine.consolidate ();
|
||||||
} catch (tl::Exception &ex) {
|
} catch (tl::Exception &ex) {
|
||||||
tl::error << ex.msg ();
|
tl::error << ex.msg ();
|
||||||
}
|
}
|
||||||
|
|
@ -168,10 +169,10 @@ SaltManagerDialog::SaltManagerDialog (QWidget *parent, lay::Salt *salt, const st
|
||||||
|
|
||||||
update_models ();
|
update_models ();
|
||||||
|
|
||||||
connect (salt_view->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_changed ()));
|
connect (salt_view->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (selected_changed ()));
|
||||||
connect (salt_view, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (edit_properties ()));
|
connect (salt_view, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (edit_properties ()));
|
||||||
connect (salt_mine_view_new->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (mine_new_current_changed ()), Qt::QueuedConnection);
|
connect (salt_mine_view_new->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (mine_new_selected_changed ()), Qt::QueuedConnection);
|
||||||
connect (salt_mine_view_update->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (mine_update_current_changed ()), Qt::QueuedConnection);
|
connect (salt_mine_view_update->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (mine_update_selected_changed ()), Qt::QueuedConnection);
|
||||||
connect (salt_mine_view_new, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (mark_clicked ()));
|
connect (salt_mine_view_new, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (mark_clicked ()));
|
||||||
connect (salt_mine_view_update, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (mark_clicked ()));
|
connect (salt_mine_view_update, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (mark_clicked ()));
|
||||||
|
|
||||||
|
|
@ -235,9 +236,9 @@ 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 ()));
|
||||||
|
|
||||||
mine_update_current_changed ();
|
mine_update_selected_changed ();
|
||||||
mine_new_current_changed ();
|
mine_new_selected_changed ();
|
||||||
current_changed ();
|
selected_changed ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -285,13 +286,13 @@ SaltManagerDialog::show_marked_only_new ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
salt_mine_view_new->setCurrentIndex (QModelIndex ());
|
salt_mine_view_new->clearSelection ();
|
||||||
|
|
||||||
for (int i = model->rowCount (QModelIndex ()); i > 0; ) {
|
for (int i = model->rowCount (QModelIndex ()); i > 0; ) {
|
||||||
--i;
|
--i;
|
||||||
SaltGrain *g = model->grain_from_index (model->index (i, 0, QModelIndex ()));
|
SaltGrain *g = model->grain_from_index (model->index (i, 0, QModelIndex ()));
|
||||||
salt_mine_view_new->setRowHidden (i, show_marked_only && !(g && model->is_marked (g->name ())));
|
salt_mine_view_new->setRowHidden (i, show_marked_only && !(g && model->is_marked (g->name ())));
|
||||||
mine_new_current_changed ();
|
mine_new_selected_changed ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -307,13 +308,13 @@ SaltManagerDialog::show_marked_only_update ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
salt_mine_view_update->setCurrentIndex (QModelIndex ());
|
salt_mine_view_new->clearSelection ();
|
||||||
|
|
||||||
for (int i = model->rowCount (QModelIndex ()); i > 0; ) {
|
for (int i = model->rowCount (QModelIndex ()); i > 0; ) {
|
||||||
--i;
|
--i;
|
||||||
SaltGrain *g = model->grain_from_index (model->index (i, 0, QModelIndex ()));
|
SaltGrain *g = model->grain_from_index (model->index (i, 0, QModelIndex ()));
|
||||||
salt_mine_view_update->setRowHidden (i, show_marked_only && !(g && model->is_marked (g->name ())));
|
salt_mine_view_update->setRowHidden (i, show_marked_only && !(g && model->is_marked (g->name ())));
|
||||||
mine_update_current_changed ();
|
mine_update_selected_changed ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -424,11 +425,15 @@ SaltManagerDialog::mark_clicked ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaltGrain *g = model->grain_from_index (view->currentIndex ());
|
QModelIndexList indexes = view->selectionModel ()->selectedIndexes ();
|
||||||
if (g) {
|
for (QModelIndexList::const_iterator i = indexes.begin (); i != indexes.end (); ++i) {
|
||||||
model->set_marked (g->name (), toggle ? ! model->is_marked (g->name ()) : set);
|
SaltGrain *g = model->grain_from_index (*i);
|
||||||
update_apply_state ();
|
if (g) {
|
||||||
|
model->set_marked (g->name (), toggle ? ! model->is_marked (g->name ()) : set);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_apply_state ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -461,7 +466,7 @@ SaltManagerDialog::update_apply_state ()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model = dynamic_cast <SaltModel *> (salt_mine_view_update->model ());
|
model = dynamic_cast <SaltModel *> (salt_mine_view_update->model ());
|
||||||
if (model) {
|
if (model) {
|
||||||
|
|
||||||
int marked = 0;
|
int marked = 0;
|
||||||
|
|
@ -548,7 +553,7 @@ SaltManagerDialog::edit_properties ()
|
||||||
QMessageBox::critical (this, tr ("Package is not Editable"),
|
QMessageBox::critical (this, tr ("Package is not Editable"),
|
||||||
tr ("This package cannot be edited.\n\nEither you don't have write permissions on the directory or the package was installed from a repository."));
|
tr ("This package cannot be edited.\n\nEither you don't have write permissions on the directory or the package was installed from a repository."));
|
||||||
} else if (mp_properties_dialog->exec_dialog (g, mp_salt)) {
|
} else if (mp_properties_dialog->exec_dialog (g, mp_salt)) {
|
||||||
current_changed ();
|
selected_changed ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -566,6 +571,7 @@ SaltManagerDialog::set_current_grain_by_name (const std::string ¤t)
|
||||||
QModelIndex index = model->index (i, 0, QModelIndex ());
|
QModelIndex index = model->index (i, 0, QModelIndex ());
|
||||||
SaltGrain *g = model->grain_from_index (index);
|
SaltGrain *g = model->grain_from_index (index);
|
||||||
if (g && g->name () == current) {
|
if (g && g->name () == current) {
|
||||||
|
salt_view->clearSelection ();
|
||||||
salt_view->setCurrentIndex (index);
|
salt_view->setCurrentIndex (index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -611,13 +617,22 @@ SaltManagerDialog::delete_grain ()
|
||||||
{
|
{
|
||||||
BEGIN_PROTECTED
|
BEGIN_PROTECTED
|
||||||
|
|
||||||
SaltGrain *g = current_grain ();
|
std::vector<SaltGrain *> gg = current_grains ();
|
||||||
if (! g) {
|
if (gg.empty ()) {
|
||||||
throw tl::Exception (tl::to_string (tr ("No package selected to delete")));
|
throw tl::Exception (tl::to_string (tr ("No package selected to delete")));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QMessageBox::question (this, tr ("Delete Package"), tr ("Are you sure to delete package '%1'?").arg (tl::to_qstring (g->name ())), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
|
if (gg.size () == 1) {
|
||||||
mp_salt->remove_grain (*g);
|
SaltGrain *g = gg.front ();
|
||||||
|
if (QMessageBox::question (this, tr ("Delete Package"), tr ("Are you sure to delete package '%1'?").arg (tl::to_qstring (g->name ())), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
|
||||||
|
mp_salt->remove_grain (*g);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (QMessageBox::question (this, tr ("Delete Packages"), tr ("Are you sure to delete the selected %1 packages?").arg (int (gg.size ())), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
|
||||||
|
for (std::vector<SaltGrain *>::const_iterator i = gg.begin (); i != gg.end (); ++i) {
|
||||||
|
mp_salt->remove_grain (**i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
END_PROTECTED
|
END_PROTECTED
|
||||||
|
|
@ -782,6 +797,7 @@ SaltManagerDialog::update_models ()
|
||||||
|
|
||||||
// select the first grain
|
// select the first grain
|
||||||
if (mine_model->rowCount (QModelIndex ()) > 0) {
|
if (mine_model->rowCount (QModelIndex ()) > 0) {
|
||||||
|
salt_mine_view_update->clearSelection ();
|
||||||
salt_mine_view_update->setCurrentIndex (mine_model->index (0, 0, QModelIndex ()));
|
salt_mine_view_update->setCurrentIndex (mine_model->index (0, 0, QModelIndex ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -804,17 +820,18 @@ SaltManagerDialog::update_models ()
|
||||||
|
|
||||||
// select the first grain
|
// select the first grain
|
||||||
if (mine_model->rowCount (QModelIndex ()) > 0) {
|
if (mine_model->rowCount (QModelIndex ()) > 0) {
|
||||||
|
salt_mine_view_new->clearSelection ();
|
||||||
salt_mine_view_new->setCurrentIndex (mine_model->index (0, 0, QModelIndex ()));
|
salt_mine_view_new->setCurrentIndex (mine_model->index (0, 0, QModelIndex ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
mine_new_current_changed ();
|
mine_new_selected_changed ();
|
||||||
mine_update_current_changed ();
|
mine_update_selected_changed ();
|
||||||
current_changed ();
|
selected_changed ();
|
||||||
update_apply_state ();
|
update_apply_state ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SaltManagerDialog::current_changed ()
|
SaltManagerDialog::selected_changed ()
|
||||||
{
|
{
|
||||||
SaltGrain *g = current_grain ();
|
SaltGrain *g = current_grain ();
|
||||||
details_text->set_grain (g);
|
details_text->set_grain (g);
|
||||||
|
|
@ -832,17 +849,49 @@ lay::SaltGrain *
|
||||||
SaltManagerDialog::current_grain ()
|
SaltManagerDialog::current_grain ()
|
||||||
{
|
{
|
||||||
SaltModel *model = dynamic_cast <SaltModel *> (salt_view->model ());
|
SaltModel *model = dynamic_cast <SaltModel *> (salt_view->model ());
|
||||||
return model ? model->grain_from_index (salt_view->currentIndex ()) : 0;
|
|
||||||
|
QModelIndexList indexes = salt_view->selectionModel ()->selectedIndexes ();
|
||||||
|
if (indexes.size () == 1 && model) {
|
||||||
|
return model->grain_from_index (indexes.front ());
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<lay::SaltGrain *>
|
||||||
|
SaltManagerDialog::current_grains ()
|
||||||
|
{
|
||||||
|
std::vector<lay::SaltGrain *> res;
|
||||||
|
|
||||||
|
SaltModel *model = dynamic_cast <SaltModel *> (salt_view->model ());
|
||||||
|
if (model) {
|
||||||
|
|
||||||
|
QModelIndexList indexes = salt_view->selectionModel ()->selectedIndexes ();
|
||||||
|
for (QModelIndexList::const_iterator i = indexes.begin (); i != indexes.end (); ++i) {
|
||||||
|
lay::SaltGrain *g = model->grain_from_index (*i);
|
||||||
|
if (g) {
|
||||||
|
res.push_back (g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SaltManagerDialog::mine_update_current_changed ()
|
SaltManagerDialog::mine_update_selected_changed ()
|
||||||
{
|
{
|
||||||
BEGIN_PROTECTED
|
BEGIN_PROTECTED
|
||||||
|
|
||||||
SaltModel *model = dynamic_cast <SaltModel *> (salt_mine_view_update->model ());
|
SaltModel *model = dynamic_cast <SaltModel *> (salt_mine_view_update->model ());
|
||||||
tl_assert (model != 0);
|
tl_assert (model != 0);
|
||||||
SaltGrain *g = model->grain_from_index (salt_mine_view_update->currentIndex ());
|
|
||||||
|
SaltGrain *g = 0;
|
||||||
|
QModelIndexList indexes = salt_mine_view_update->selectionModel ()->selectedIndexes();
|
||||||
|
if (indexes.size () == 1) {
|
||||||
|
g = model->grain_from_index (indexes.front ());
|
||||||
|
}
|
||||||
|
|
||||||
details_update_frame->setEnabled (g != 0);
|
details_update_frame->setEnabled (g != 0);
|
||||||
|
|
||||||
|
|
@ -852,13 +901,18 @@ END_PROTECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SaltManagerDialog::mine_new_current_changed ()
|
SaltManagerDialog::mine_new_selected_changed ()
|
||||||
{
|
{
|
||||||
BEGIN_PROTECTED
|
BEGIN_PROTECTED
|
||||||
|
|
||||||
SaltModel *model = dynamic_cast <SaltModel *> (salt_mine_view_new->model ());
|
SaltModel *model = dynamic_cast <SaltModel *> (salt_mine_view_new->model ());
|
||||||
tl_assert (model != 0);
|
tl_assert (model != 0);
|
||||||
SaltGrain *g = model->grain_from_index (salt_mine_view_new->currentIndex ());
|
|
||||||
|
SaltGrain *g = 0;
|
||||||
|
QModelIndexList indexes = salt_mine_view_new->selectionModel ()->selectedIndexes();
|
||||||
|
if (indexes.size () == 1) {
|
||||||
|
g = model->grain_from_index (indexes.front ());
|
||||||
|
}
|
||||||
|
|
||||||
details_new_frame->setEnabled (g != 0);
|
details_new_frame->setEnabled (g != 0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace lay
|
namespace lay
|
||||||
{
|
{
|
||||||
|
|
@ -81,17 +82,17 @@ private slots:
|
||||||
/**
|
/**
|
||||||
* @brief Called when the currently selected package (grain) has changed
|
* @brief Called when the currently selected package (grain) has changed
|
||||||
*/
|
*/
|
||||||
void current_changed ();
|
void selected_changed ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when the currently selected package from the update page has changed
|
* @brief Called when the currently selected package from the update page has changed
|
||||||
*/
|
*/
|
||||||
void mine_update_current_changed ();
|
void mine_update_selected_changed ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when the currently selected package from the new installation page has changed
|
* @brief Called when the currently selected package from the new installation page has changed
|
||||||
*/
|
*/
|
||||||
void mine_new_current_changed ();
|
void mine_new_selected_changed ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when the "edit" button is pressed
|
* @brief Called when the "edit" button is pressed
|
||||||
|
|
@ -172,10 +173,12 @@ private:
|
||||||
int m_current_tab;
|
int m_current_tab;
|
||||||
|
|
||||||
SaltGrain *current_grain ();
|
SaltGrain *current_grain ();
|
||||||
|
std::vector<lay::SaltGrain *> current_grains ();
|
||||||
void set_current_grain_by_name (const std::string ¤t);
|
void set_current_grain_by_name (const std::string ¤t);
|
||||||
void update_models ();
|
void update_models ();
|
||||||
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 ();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,10 +135,16 @@ SaltModel::data (const QModelIndex &index, int role) const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool en = is_enabled (g->name ());
|
bool en = is_enabled (g->name ());
|
||||||
|
bool hidden = g->is_hidden ();
|
||||||
|
|
||||||
std::string text = "<html><body>";
|
std::string text = "<html><body>";
|
||||||
if (! en) {
|
if (! en || hidden) {
|
||||||
text += "<font color=\"#c0c0c0\">";
|
text += "<font color=\"#c0c0c0\">";
|
||||||
|
} else {
|
||||||
|
text += "<font color=\"#303030\">";
|
||||||
|
}
|
||||||
|
if (hidden) {
|
||||||
|
text += "<i>";
|
||||||
}
|
}
|
||||||
text += "<h4>";
|
text += "<h4>";
|
||||||
text += tl::escaped_to_html (g->name ());
|
text += tl::escaped_to_html (g->name ());
|
||||||
|
|
@ -168,9 +174,12 @@ SaltModel::data (const QModelIndex &index, int role) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! en) {
|
if (hidden) {
|
||||||
text += "</font>";
|
text += "<p>";
|
||||||
|
text += tl::to_string (tr ("This package is an auxiliary package for use with other packages."));
|
||||||
|
text += "</p></i>";
|
||||||
}
|
}
|
||||||
|
text += "</font>";
|
||||||
text += "</body></html>";
|
text += "</body></html>";
|
||||||
|
|
||||||
return tl::to_qstring (text);
|
return tl::to_qstring (text);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QSignalSpy>
|
#include <QSignalSpy>
|
||||||
|
|
||||||
static std::string grains_to_string (const lay::SaltGrains &gg)
|
static std::string grains_to_string (const lay::SaltGrains &gg, bool with_version = false)
|
||||||
{
|
{
|
||||||
std::string res;
|
std::string res;
|
||||||
res += "[";
|
res += "[";
|
||||||
|
|
@ -41,6 +41,15 @@ static std::string grains_to_string (const lay::SaltGrains &gg)
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
res += g->name ();
|
res += g->name ();
|
||||||
|
if (with_version) {
|
||||||
|
res += "(";
|
||||||
|
res += g->version ();
|
||||||
|
if (!g->url ().empty ()) {
|
||||||
|
res += ":";
|
||||||
|
res += g->url ();
|
||||||
|
}
|
||||||
|
res += ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (lay::SaltGrains::collection_iterator gc = gg.begin_collections (); gc != gg.end_collections (); ++gc) {
|
for (lay::SaltGrains::collection_iterator gc = gg.begin_collections (); gc != gg.end_collections (); ++gc) {
|
||||||
if (! first) {
|
if (! first) {
|
||||||
|
|
@ -48,7 +57,7 @@ static std::string grains_to_string (const lay::SaltGrains &gg)
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
res += gc->name ();
|
res += gc->name ();
|
||||||
res += grains_to_string (*gc);
|
res += grains_to_string (*gc, with_version);
|
||||||
}
|
}
|
||||||
res += "]";
|
res += "]";
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -403,3 +412,163 @@ TEST (5)
|
||||||
|
|
||||||
EXPECT_EQ (tl::join (names, ","), "g3,g2,g1,g4");
|
EXPECT_EQ (tl::join (names, ","), "g3,g2,g1,g4");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST (6)
|
||||||
|
{
|
||||||
|
lay::SaltGrains gg1;
|
||||||
|
lay::SaltGrains gg2;
|
||||||
|
|
||||||
|
lay::SaltGrain ga1;
|
||||||
|
ga1.set_name ("a");
|
||||||
|
ga1.set_url ("url1");
|
||||||
|
ga1.set_version ("1.0");
|
||||||
|
|
||||||
|
lay::SaltGrain ga2;
|
||||||
|
ga2.set_name ("a");
|
||||||
|
ga2.set_url ("url2");
|
||||||
|
ga2.set_version ("1.1");
|
||||||
|
|
||||||
|
lay::SaltGrain gb;
|
||||||
|
gb.set_name ("b");
|
||||||
|
|
||||||
|
lay::SaltGrain gc;
|
||||||
|
gc.set_name ("c");
|
||||||
|
|
||||||
|
gg1.add_grain (ga1);
|
||||||
|
gg1.add_grain (gb);
|
||||||
|
|
||||||
|
gg2.add_grain (gc);
|
||||||
|
gg2.add_grain (ga2);
|
||||||
|
|
||||||
|
// higher version wins
|
||||||
|
gg1.merge_with (gg2);
|
||||||
|
EXPECT_EQ (grains_to_string (gg1, true), "[b(),c(),a(1.1:url2)]");
|
||||||
|
|
||||||
|
gg1 = lay::SaltGrains ();
|
||||||
|
gg2 = lay::SaltGrains ();
|
||||||
|
|
||||||
|
gg2.add_grain (gc);
|
||||||
|
gg1.add_grain (ga2);
|
||||||
|
gg1.add_grain (gb);
|
||||||
|
|
||||||
|
gg2.add_grain (ga1);
|
||||||
|
|
||||||
|
// higher version wins - also in different order
|
||||||
|
gg1.merge_with (gg2);
|
||||||
|
EXPECT_EQ (grains_to_string (gg1, true), "[a(1.1:url2),b(),c()]");
|
||||||
|
|
||||||
|
gg1 = lay::SaltGrains ();
|
||||||
|
gg2 = lay::SaltGrains ();
|
||||||
|
|
||||||
|
gg2.add_grain (gc);
|
||||||
|
ga2.set_version ("1.0");
|
||||||
|
gg1.add_grain (ga2);
|
||||||
|
gg1.add_grain (gb);
|
||||||
|
|
||||||
|
gg2.add_grain (ga1);
|
||||||
|
|
||||||
|
// first one wins on same version
|
||||||
|
gg1.merge_with (gg2);
|
||||||
|
EXPECT_EQ (grains_to_string (gg1, true), "[a(1.0:url2),b(),c()]");
|
||||||
|
|
||||||
|
gg1 = lay::SaltGrains ();
|
||||||
|
|
||||||
|
gg1.add_grain (gc);
|
||||||
|
gg1.add_grain (ga2);
|
||||||
|
gg1.add_grain (ga1);
|
||||||
|
gg1.add_grain (gb);
|
||||||
|
|
||||||
|
// consolidate does the same on one list
|
||||||
|
gg1.consolidate ();
|
||||||
|
EXPECT_EQ (grains_to_string (gg1, true), "[c(),a(1.0:url2),b()]");
|
||||||
|
|
||||||
|
gg1 = lay::SaltGrains ();
|
||||||
|
|
||||||
|
gg1.add_grain (ga1);
|
||||||
|
gg1.add_grain (ga2);
|
||||||
|
gg1.add_grain (gb);
|
||||||
|
gg1.add_grain (gc);
|
||||||
|
|
||||||
|
// consolidate does the same on one list
|
||||||
|
gg1.consolidate ();
|
||||||
|
EXPECT_EQ (grains_to_string (gg1, true), "[a(1.0:url1),b(),c()]");
|
||||||
|
|
||||||
|
gg1 = lay::SaltGrains ();
|
||||||
|
|
||||||
|
ga1.set_version ("1.1");
|
||||||
|
gg1.add_grain (ga1);
|
||||||
|
gg1.add_grain (ga2);
|
||||||
|
gg1.add_grain (gb);
|
||||||
|
|
||||||
|
// consolidate does the same on one list
|
||||||
|
gg1.consolidate ();
|
||||||
|
EXPECT_EQ (grains_to_string (gg1, true), "[a(1.1:url1),b()]");
|
||||||
|
|
||||||
|
|
||||||
|
// merging of sub-collections
|
||||||
|
|
||||||
|
gg1 = lay::SaltGrains ();
|
||||||
|
gg2 = lay::SaltGrains ();
|
||||||
|
|
||||||
|
lay::SaltGrains gga1;
|
||||||
|
gga1.set_name ("a");
|
||||||
|
|
||||||
|
{
|
||||||
|
lay::SaltGrain g;
|
||||||
|
g.set_name ("a");
|
||||||
|
g.set_version ("1.0");
|
||||||
|
g.set_url ("url1");
|
||||||
|
gga1.add_grain (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
lay::SaltGrain g;
|
||||||
|
g.set_name ("b");
|
||||||
|
gga1.add_grain (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
lay::SaltGrains ggb;
|
||||||
|
ggb.set_name ("b");
|
||||||
|
|
||||||
|
{
|
||||||
|
lay::SaltGrain g;
|
||||||
|
g.set_name ("x");
|
||||||
|
ggb.add_grain (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
gg1.add_collection (gga1);
|
||||||
|
gg1.add_collection (ggb);
|
||||||
|
|
||||||
|
lay::SaltGrains gga2;
|
||||||
|
gga2.set_name ("a");
|
||||||
|
|
||||||
|
{
|
||||||
|
lay::SaltGrain g;
|
||||||
|
g.set_name ("a");
|
||||||
|
g.set_version ("1.1");
|
||||||
|
g.set_url ("url2");
|
||||||
|
gga2.add_grain (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
lay::SaltGrain g;
|
||||||
|
g.set_name ("c");
|
||||||
|
gga2.add_grain (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
lay::SaltGrains ggc;
|
||||||
|
ggc.set_name ("c");
|
||||||
|
|
||||||
|
{
|
||||||
|
lay::SaltGrain g;
|
||||||
|
g.set_name ("y");
|
||||||
|
ggc.add_grain (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
gg2.add_collection (gga2);
|
||||||
|
gg2.add_collection (ggc);
|
||||||
|
|
||||||
|
// gg2:a collection is merged into gg1:a, gg2:c is copied.
|
||||||
|
gg1.merge_with (gg2);
|
||||||
|
EXPECT_EQ (grains_to_string (gg1, true), "[a[b(),a(1.1:url2),c()],b[x()],c[y()]]");
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue