libyui-qt-pkg  2.45.28
YQPkgChangesDialog.cc
1 /**************************************************************************
2 Copyright (C) 2000 - 2010 Novell, Inc.
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 **************************************************************************/
20 
21 
22 /*---------------------------------------------------------------------\
23 | |
24 | __ __ ____ _____ ____ |
25 | \ \ / /_ _/ ___|_ _|___ \ |
26 | \ V / _` \___ \ | | __) | |
27 | | | (_| |___) || | / __/ |
28 | |_|\__,_|____/ |_| |_____| |
29 | |
30 | core system |
31 | (C) SuSE GmbH |
32 \----------------------------------------------------------------------/
33 
34  File: YQPkgChangesDialog.cc
35 
36  Author: Stefan Hundhammer <sh@suse.de>
37 
38  Textdomain "qt-pkg"
39 
40 /-*/
41 
42 #define YUILogComponent "qt-pkg"
43 #include "YUILog.h"
44 
45 #include <QApplication>
46 #include <QDesktopWidget>
47 #include <QLabel>
48 #include <QLayout>
49 #include <QPushButton>
50 #include <QStyle>
51 #include <QBoxLayout>
52 
53 #include "YQZypp.h"
54 #include <zypp/ResStatus.h>
55 #include <zypp/VendorSupportOptions.h>
56 #include <zypp/ui/UserWantedPackages.h>
57 
58 #include "YQPkgChangesDialog.h"
59 #include "YQPkgList.h"
60 #include "QY2LayoutUtils.h"
61 #include "YQi18n.h"
62 #include "YQUI.h"
63 
64 using std::set;
65 using std::endl;
66 using std::string;
67 
69  const QString & message,
70  const QString & acceptButtonLabel,
71  const QString & rejectButtonLabel )
72  : QDialog( parent )
73  , _filter(0)
74 {
75  // Dialog title
76  setWindowTitle( _( "Changed Packages" ) );
77 
78  // Enable dialog resizing even without window manager
79  setSizeGripEnabled( true );
80 
81  // Limit dialog size to available screen size
82  setMaximumSize( qApp->desktop()->availableGeometry().size() );
83 
84  // Layout for the dialog ( can't simply insert a QVBox )
85 
86  QVBoxLayout * layout = new QVBoxLayout();
87  Q_CHECK_PTR( layout );
88  setLayout(layout);
89 
90  QHBoxLayout * hbox = new QHBoxLayout();
91  Q_CHECK_PTR( hbox );
92  layout->addLayout( hbox );
93 
94 
95  // Icon
96 
97  QLabel * iconLabel = new QLabel( this );
98  Q_CHECK_PTR( iconLabel );
99  hbox->addWidget(iconLabel);
100  iconLabel->setPixmap( YQUI::ui()->loadIcon( "dialog-information" ).pixmap(64) );
101  iconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) ); // hor/vert
102 
103  // Label for the message
104  QLabel * label = new QLabel( message, this );
105  Q_CHECK_PTR( label );
106  hbox->addWidget(label);
107  label->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) ); // hor/vert
108 
109  _filter = new QComboBox(this);
110 
111  // add the items.
112  _filter->addItem(_("All"), QVariant::fromValue(Filters(FilterAll)));
113  _filter->addItem(_("Selected by the user"), QVariant::fromValue(Filters(FilterUser)));
114  _filter->addItem(_("Automatic Changes"), QVariant::fromValue(Filters(FilterAutomatic)));
115 
116  _filter->setCurrentIndex(0);
117 
118  layout->addWidget(_filter);
119  connect( _filter, SIGNAL(currentIndexChanged(int)),
120  SLOT(slotFilterChanged(int)));
121 
122  // Pkg list
123 
124  _pkgList = new YQPkgList( this );
125  Q_CHECK_PTR( _pkgList );
126  _pkgList->setEditable( false );
127 
128  layout->addWidget( _pkgList );
129 
130 
131  // Button box
132 
133  hbox = new QHBoxLayout();
134  Q_CHECK_PTR( hbox );
135  layout->addLayout( hbox );
136 
137  hbox->addStretch();
138 
139  // Accept button - usually "OK" or "Continue"
140  QPushButton * button = new QPushButton( acceptButtonLabel, this );
141  Q_CHECK_PTR( button );
142  hbox->addWidget( button );
143  button->setDefault( true );
144 
145  connect( button, SIGNAL( clicked() ),
146  this, SLOT ( accept() ) );
147 
148  hbox->addStretch();
149 
150  if ( ! rejectButtonLabel.isEmpty() )
151  {
152  // Reject button ( if desired ) - usually "Cancel"
153 
154  button = new QPushButton( rejectButtonLabel, this );
155  Q_CHECK_PTR( button );
156  hbox->addWidget(button);
157  connect( button, SIGNAL( clicked() ),
158  this, SLOT ( reject() ) );
159 
160  hbox->addStretch();
161  }
162 }
163 
164 void
166 {
167  filter( QRegExp( "" ), f );
168 }
169 
170 void
172 {
173  yuiMilestone() << "filter index changed to: " << index << endl;
174  QVariant v = _filter->itemData(index);
175 
176  if ( v.isValid() && v.canConvert<Filters>() )
177  {
178  Filters f = v.value<Filters>();
179  filter(f);
180  }
181  else
182  {
183  yuiError() << "Can't find filter for index " << index << endl;
184  }
185 
186 }
187 
188 void
190 {
191  setFilter(QRegExp(""), f);
192 }
193 
194 void
195 YQPkgChangesDialog::setFilter( const QRegExp &regexp, Filters f )
196 {
197  yuiMilestone() << "filter changed to: " << f << endl;
198 
199  int index = -1;
200  for ( int k = 0; k < _filter->count(); ++k )
201  {
202  QVariant v = _filter->itemData(k);
203  if ( v.isValid() && v.canConvert<Filters>() )
204  {
205 
206  Filters setf = v.value<Filters>();
207  if ( setf == f )
208  index = k;
209  }
210  }
211 
212  if ( index != -1 )
213  {
214  // so we dont get called again
215  _filter->blockSignals(true);
216  // try to set the widget
217  _filter->setCurrentIndex(f);
218  _filter->blockSignals(false);
219  filter(regexp, f);
220  }
221  else
222  {
223  yuiError() << "Can't find index for filter " << f << endl;
224  }
225 }
226 
227 
228 void
229 YQPkgChangesDialog::filter( const QRegExp & regexp, Filters f )
230 {
231  YQUI::ui()->busyCursor();
232  _pkgList->clear();
233 
234  bool byAuto = f.testFlag(FilterAutomatic);
235  bool byUser = f.testFlag(FilterUser);
236  bool byApp = f.testFlag(FilterUser);
237 
238  int discard_regex = 0;
239  int discard_ignored = 0;
240  int discard_extra = 0;
241  int discard_notmodified = 0;
242  int discard_whomodified = 0;
243 
244  set<string> ignoredNames;
245 
246  if ( ! byUser || ! byApp )
247  ignoredNames = zypp::ui::userWantedPackageNames();
248 
249  for ( ZyppPoolIterator it = zyppPkgBegin();
250  it != zyppPkgEnd();
251  ++it )
252  {
253  ZyppSel selectable = *it;
254 
255  if ( selectable->toModify() )
256  {
257  zypp::ResStatus::TransactByValue modifiedBy = selectable->modifiedBy();
258 
259  if ( ( ( modifiedBy == zypp::ResStatus::SOLVER ) && byAuto ) ||
260  ( ( modifiedBy == zypp::ResStatus::APPL_LOW ||
261  modifiedBy == zypp::ResStatus::APPL_HIGH ) && byApp ) ||
262  ( ( modifiedBy == zypp::ResStatus::USER ) && byUser ) )
263  {
264  if ( regexp.isEmpty()
265  || regexp.indexIn( selectable->name().c_str() ) >= 0 )
266  {
267  if ( ! contains( ignoredNames, selectable->name() ) )
268  {
269  ZyppPkg pkg = tryCastToZyppPkg( selectable->theObj() );
270  if ( extraFilter( selectable, pkg ) )
271  _pkgList->addPkgItem( selectable, pkg );
272  else
273  discard_extra++;
274  }
275  else
276  { discard_ignored++; }
277  }
278  else
279  { discard_regex++; }
280  }
281  else
282  { discard_whomodified++; }
283 
284  }
285  else
286  { discard_notmodified++; }
287 
288  }
289 
290  yuiMilestone() << "Filter result summary: " << endl;
291  yuiMilestone() << "Discarded by extra filter: " << discard_extra << endl;
292  yuiMilestone() << "Discarded by ignored: " << discard_ignored << endl;
293  yuiMilestone() << "Discarded by regex: " << discard_regex << endl;
294  yuiMilestone() << "Discarded because not modified: " << discard_notmodified << endl;
295  yuiMilestone() << "Discarded by who modified: " << discard_whomodified << endl;
296  YQUI::ui()->normalCursor();
297 }
298 
299 bool
300 YQPkgChangesDialog::extraFilter( ZyppSel sel, ZyppPkg pkg )
301 {
302  return true;
303 }
304 
305 bool
307 {
308  return _pkgList->topLevelItemCount() == 0;
309 }
310 
311 
312 QSize
314 {
315  return limitToScreenSize( this, QDialog::sizeHint() );
316 }
317 
318 
319 bool
321  const QString & message,
322  const QString & acceptButtonLabel,
323  const QString & rejectButtonLabel,
324  Filters f,
325  Options o )
326 {
327  YQPkgChangesDialog dialog( parent,
328  message,
329  acceptButtonLabel,
330  rejectButtonLabel );
331 
332  dialog.setFilter(f);
333 
334  if ( dialog.isEmpty() && o.testFlag(OptionAutoAcceptIfEmpty) )
335  {
336  yuiMilestone() << "No items to show in changes dialog, accepting it automatically" << endl;
337  return true;
338  }
339 
340 
341  dialog.exec();
342 
343  return dialog.result() == QDialog::Accepted;
344 }
345 
346 
347 bool
349  const QString & message,
350  const QRegExp & regexp,
351  const QString & acceptButtonLabel,
352  const QString & rejectButtonLabel,
353  Filters f,
354  Options o )
355 {
356  YQPkgChangesDialog dialog( parent,
357  message,
358  acceptButtonLabel,
359  rejectButtonLabel );
360  dialog.setFilter(regexp,f);
361 
362  if ( dialog.isEmpty() && o.testFlag(OptionAutoAcceptIfEmpty) )
363  {
364  yuiMilestone() << "No items to show in dialog, accepting it automatically" << endl;
365  return true;
366  }
367 
368  dialog.exec();
369 
370  return dialog.result() == QDialog::Accepted;
371 }
372 
374  const QString & message,
375  const QString & acceptButtonLabel,
376  const QString & rejectButtonLabel )
377  : YQPkgChangesDialog( parent, message, acceptButtonLabel, rejectButtonLabel )
378 {
379 }
380 
381 bool YQPkgUnsupportedPackagesDialog::extraFilter( ZyppSel sel, ZyppPkg pkg )
382 {
383  if (!pkg || !sel)
384  return false;
385 
386  yuiDebug() << "UNSUPPORTED PKG: " << pkg << endl;
387  return pkg->maybeUnsupported() && sel->toInstall();
388 }
389 
390 bool
392  const QString & message,
393  const QString & acceptButtonLabel,
394  const QString & rejectButtonLabel,
395  Filters f,
396  Options o )
397 {
398  YQPkgUnsupportedPackagesDialog dialog( parent,
399  message,
400  acceptButtonLabel,
401  rejectButtonLabel );
402 
403  dialog.setFilter(f);
404 
405  if ( dialog.isEmpty() && o.testFlag(OptionAutoAcceptIfEmpty) )
406  {
407  yuiMilestone() << "No items to show in unsupported packages dialog, accepting it automatically" << endl;
408  return true;
409  }
410 
411  dialog.exec();
412 
413  return dialog.result() == QDialog::Accepted;
414 }
415 
416 
void setFilter(Filters f)
Set the current filter This will change the combo box current selected filter and update the list...
void addPkgItem(ZyppSel selectable, ZyppPkg zyppPkg)
Add a pkg to the list.
Definition: YQPkgList.cc:140
virtual bool extraFilter(ZyppSel sel, ZyppPkg pkg)
extra filter for child classes
void slotFilterChanged(int index)
called when the filter is changed
Changes dialog: Show a dialog with a list of packages that are changed.
bool isEmpty() const
Returns &#39;true&#39; if the pkg list is empty.
virtual QSize sizeHint() const
Returns the preferred size.
void setEditable(bool editable=true)
Set the list&#39;s editable status.
Definition: YQPkgObjList.h:113
Display a list of zypp::Package objects.
Definition: YQPkgList.h:54
YQPkgUnsupportedPackagesDialog(QWidget *parent, const QString &message, const QString &acceptButtonLabel, const QString &rejectButtonLabel=QString::null)
Constructor: Creates a changes dialog with text &#39;message&#39; on top, a list packages with an "auto" stat...
void clear()
Clears the tree-widgets content, resets the optimal column width values.
Definition: YQPkgList.cc:434
YQPkgChangesDialog(QWidget *parent, const QString &message, const QString &acceptButtonLabel, const QString &rejectButtonLabel=QString::null)
Constructor: Creates a changes dialog with text &#39;message&#39; on top, a list packages with an "auto" stat...
virtual bool extraFilter(ZyppSel sel, ZyppPkg pkg)
leave supported packages out.
static bool showChangesDialog(QWidget *parent, const QString &message, const QString &acceptButtonLabel, const QString &rejectButtonLabel=QString::null, Filters f=FilterAutomatic, Options o=OptionAutoAcceptIfEmpty)
Static convenience method: Post a changes dialog with text &#39;message&#39;, a list of changed packages and ...
static bool showUnsupportedPackagesDialog(QWidget *parent, const QString &message, const QString &acceptButtonLabel, const QString &rejectButtonLabel=QString::null, Filters f=FilterAutomatic, Options o=OptionAutoAcceptIfEmpty)
Static convenience method: Post a changes dialog with text &#39;message&#39;, a list of changed packages and ...
void filter(Filters f=FilterAutomatic)
Apply the filter criteria: Fill the pkg list with pkgs that have a "modify" status ( install...