libyui-qt-pkg  2.45.27
YQPkgServiceList.cc
1 /**************************************************************************
2 Copyright (C) 2018 SUSE LLC
3 All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 
19 Textdomain "qt-pkg"
20 
21 /-*/
22 
23 #include <algorithm>
24 #include <set>
25 #include <string>
26 #include <QDateTime>
27 #include <QHeaderView>
28 #include <QString>
29 
30 #define YUILogComponent "qt-pkg"
31 #include "YUILog.h"
32 #include <zypp/PoolQuery.h>
33 #include <zypp/RepoManager.h>
34 #include <zypp/ServiceInfo.h>
35 
36 #include <QTreeWidget>
37 #include "YQPkgServiceList.h"
38 #include "YQPkgFilters.h"
39 #include "YQi18n.h"
40 #include "YQUI.h"
41 #include "utf8.h"
42 
43 using std::string;
44 using std::list;
45 using std::endl;
46 using std::set;
47 using std::vector;
48 
49 
51  : QY2ListView( parent )
52 {
53  yuiDebug() << "Creating service list" << endl;
54 
55  QStringList headers;
56 
57  // TRANSLATORS: Column header for the service list
58  headers << _("Name");
59  _nameCol = 0;
60 
61  setHeaderLabels( headers );
62  header()->setSectionResizeMode( _nameCol, QHeaderView::Stretch );
63 
64  setSelectionMode( QAbstractItemView::ExtendedSelection ); // allow multi-selection with Ctrl-mouse
65 
66  connect( this, SIGNAL( itemSelectionChanged() ),
67  this, SLOT ( filterIfVisible()) );
68  setIconSize(QSize(32,32));
69  fillList();
70  setSortingEnabled( true );
71  sortByColumn( nameCol(), Qt::AscendingOrder );
72  selectSomething();
73 
74  yuiDebug() << "Creating service list done" << endl;
75 }
76 
78 {
79  // NOP
80 }
81 
82 void
84 {
85  clear();
86  yuiDebug() << "Filling service list" << endl;
87 
88  std::set<std::string> added_services;
89  zypp::RepoManager repo_manager;
90 
91  std::for_each(ZyppRepositoriesBegin(), ZyppRepositoriesEnd(), [&](const zypp::Repository& repo) {
92  const std::string &service_name(repo.info().service());
93  if (!service_name.empty())
94  {
95  bool found = std::any_of(added_services.begin(), added_services.end(), [&](const std::string& name) {
96  return service_name == name;
97  });
98 
99  if (!found)
100  {
101  addService(service_name, repo_manager);
102  added_services.insert(service_name);
103  }
104  }
105  });
106 
107  yuiDebug() << "Service list filled" << endl;
108 }
109 
110 void
112 {
113  if ( isVisible() )
114  filter();
115 }
116 
117 void
119 {
120  emit filterStart();
121 
122  yuiMilestone() << "Collecting packages in selected services..." << endl;
123  QTime stopWatch;
124  stopWatch.start();
125 
126  //
127  // Collect all packages from repositories belonging to this service
128  //
129  QTreeWidgetItem * item;
130  QList<QTreeWidgetItem *> items = selectedItems();
131  QListIterator<QTreeWidgetItem *> it(items);
132 
133  while ( it.hasNext() )
134  {
135  item = it.next();
136  YQPkgServiceListItem * serviceItem = dynamic_cast<YQPkgServiceListItem *> (item);
137 
138  if ( serviceItem )
139  {
140  yuiMilestone() << "Selected service: " << serviceItem->zyppService() << endl;
141 
142  zypp::PoolQuery query;
143  std::for_each(ZyppRepositoriesBegin(), ZyppRepositoriesEnd(), [&](const zypp::Repository& repo) {
144  if (serviceItem->zyppService() == repo.info().service())
145  {
146  yuiMilestone() << "Adding repo filter: " << repo.info().alias() << endl;
147  query.addRepo( repo.info().alias() );
148  }
149  });
150  query.addKind(zypp::ResKind::package);
151 
152  std::for_each(query.selectableBegin(), query.selectableEnd(), [&](const zypp::ui::Selectable::Ptr &selectable) {
153  emit filterMatch( selectable, tryCastToZyppPkg( selectable->theObj() ) );
154  });
155  }
156  }
157 
158  yuiDebug() << "Packages sent to package list. Elapsed time: "
159  << stopWatch.elapsed() / 1000.0 << " sec"
160  << endl;
161 
162  emit filterFinished();
163 }
164 
165 void
166 YQPkgServiceList::addService( ZyppService service, const zypp::RepoManager &mgr )
167 {
168  new YQPkgServiceListItem( this, service, mgr );
169 }
170 
171 
174 {
175  QTreeWidgetItem * item = currentItem();
176  return dynamic_cast<YQPkgServiceListItem *> (item);
177 }
178 
180  ZyppService service, const zypp::RepoManager &mgr )
181  : QY2ListViewItem( parentList )
182  , _serviceList( parentList )
183  , _zyppService( service )
184 {
185 
186  zypp::ServiceInfo srvinfo = mgr.getService(service);
187  _zyppServiceName = srvinfo.name();
188  QString service_name(fromUTF8(_zyppServiceName));
189 
190  if ( nameCol() >= 0 && !service.empty() )
191  {
192  setText( nameCol(), service_name);
193  }
194 
195  QString infoToolTip("<p><b>" + service_name.toHtmlEscaped() + "</b></p>");
196 
197  // TRANSLATORS: Tooltip item, followed by service URL
198  infoToolTip += "<p><b>" + _("URL: ") + "</b>" + fromUTF8(srvinfo.url().asString()).toHtmlEscaped() + "</p>";
199 
200  ZyppProduct product = singleProduct( _zyppService );
201  if ( product )
202  {
203  // TRANSLATORS: Tooltip item, followed by product name
204  infoToolTip += ("<p><b>" + _("Product: ") + "</b>"
205  + fromUTF8(product->summary()).toHtmlEscaped() + "</p>");
206  }
207 
208  // TRANSLATORS: Tooltip item, followed by the list of repositories inluded in the libzypp service
209  infoToolTip += "<p><b>" + _("Repositories:") + "</b><ul>";
210  std::for_each(ZyppRepositoriesBegin(), ZyppRepositoriesEnd(), [&](const zypp::Repository& repo) {
211  if (service == repo.info().service())
212  infoToolTip += "<li>" + fromUTF8(repo.name()).toHtmlEscaped() + "</li>";
213  });
214  infoToolTip += "</ul></p>";
215 
216  setToolTip( nameCol(), infoToolTip);
217 
218  setIcon( 0, YQUI::ui()->loadIcon( "yast-update" ) );
219 }
220 
222 {
223  // NOP
224 }
225 
226 ZyppProduct
227 YQPkgServiceListItem::singleProduct( ZyppService zyppService )
228 {
229  return YQPkgFilters::singleProductFilter([&](const zypp::PoolItem& item) {
230  // filter the products from the requested service
231  return item.resolvable()->repoInfo().service() == zyppService;
232  });
233 }
234 
235 bool
236 YQPkgServiceListItem::operator< ( const QTreeWidgetItem & other ) const
237 {
238  const YQPkgServiceListItem * otherItem = dynamic_cast<const YQPkgServiceListItem *>(&other);
239 
240  // case insensitive compare
241  return QString::compare(fromUTF8(zyppServiceName()), fromUTF8(otherItem->zyppServiceName()), Qt::CaseInsensitive) < 0;
242 }
243 
void filterStart()
Emitted when the filtering starts.
void filter()
Filter according to the view's rules and current selection.
ZyppService zyppService() const
Returns the ZYPP service this item corresponds to (its alias)
virtual ~YQPkgServiceList()
Destructor.
std::string zyppServiceName() const
Returns the ZYPP service name this item corresponds to.
virtual ~YQPkgServiceListItem()
Destructor.
void filterIfVisible()
Same as filter(), but only if this widget is currently visible.
YQPkgServiceList(QWidget *parent)
Constructor.
void filterFinished()
Emitted when filtering is finished.
A widget to display a list of libzypp services.
static ZyppProduct singleProduct(ZyppService service)
Returns the product on a source if it has one single product or 0 if there are no or multiple product...
void fillList()
Fill the list.
static ZyppProduct singleProductFilter(std::function< bool(const zypp::PoolItem &item)> filter)
Returns the product if the filter finds a single product or null product if there are no or multiple ...
Definition: YQPkgFilters.cc:35
void addService(ZyppService service, const zypp::RepoManager &mgr)
Add a service to the list.
YQPkgServiceListItem * selection() const
Returns the currently selected item or 0 if there is none.
YQPkgServiceListItem(YQPkgServiceList *parentList, ZyppService service, const zypp::RepoManager &mgr)
Constructor.
void filterMatch(ZyppSel selectable, ZyppPkg pkg)
Emitted during filtering for each pkg that matches the filter and the candidate package comes from th...