libyui-qt-pkg  2.45.6
 All Classes Functions Variables Enumerations
YQPkgHistoryDialog.cc
1 /**************************************************************************
2 Copyright (C) 2000 - 2011 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: YQPkgHistoryDialog.cc
35 
36  Author: Stanislav Visnovsky <visnov@suse.com>
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 <QHBoxLayout>
48 #include <QLabel>
49 #include <QPushButton>
50 #include <QSplitter>
51 #include <QStyle>
52 #include <QList>
53 #include <QBoxLayout>
54 #include <QTreeWidget>
55 #include <QMessageBox>
56 
57 #include <zypp/parser/HistoryLogReader.h>
58 #include <zypp/Date.h>
59 #include <zypp/Edition.h>
60 
61 #include <boost/ref.hpp>
62 
63 #include "YQPkgHistoryDialog.h"
64 #include "YQPkgList.h"
65 #include "QY2LayoutUtils.h"
66 #include "YQi18n.h"
67 #include "YQUI.h"
68 #include "YQIconPool.h"
69 #include "utf8.h"
70 
71 
72 #define SPACING 2 // between subwidgets
73 #define MARGIN 4 // around the widget
74 
75 #define FILENAME "/var/log/zypp/history"
76 
77 using std::endl;
78 
80  : QDialog( parent )
81 {
82  // Dialog title
83  setWindowTitle( _( "Package History" ) );
84 
85  // Enable dialog resizing even without window manager
86  setSizeGripEnabled( true );
87 
88  // Layout for the dialog (can't simply insert a QVBox)
89 
90  QVBoxLayout * layout = new QVBoxLayout();
91  Q_CHECK_PTR( layout );
92  setLayout(layout);
93  layout->setMargin(MARGIN);
94  layout->setSpacing(SPACING);
95 
96  setMinimumSize (300,400);
97 
98  QLabel * label = new QLabel ( _("Show History (/var/log/zypp/history)" ), this );
99  label->setFixedHeight (label->sizeHint ().height ());
100  layout->addWidget (label);
101 
102  // VBox for splitter
103  QSplitter * splitter = new QSplitter( Qt::Horizontal, this );
104  Q_CHECK_PTR( splitter );
105  layout->addWidget( splitter );
106 
107  // History view
108  _dates = new QTreeWidget (splitter);
109  _dates->setColumnCount (1);
110  _dates->setHeaderLabels ( QStringList( _("Date") ) );
111 
112  _actions = new QTreeWidget (splitter);
113  _actions->setColumnCount (2);
114  _actions->setHeaderLabels ( QStringList( _("Action") ) << _("Version/URL") );
115  _actions->setColumnWidth (0, 200);
116 
117  splitter->setStretchFactor (0, 1);
118  splitter->setStretchFactor (1, 2);
119 
120  // Button box (to center the single button)
121 
122  QHBoxLayout * hbox = new QHBoxLayout();
123  Q_CHECK_PTR( hbox );
124  hbox->setSpacing( SPACING );
125  hbox->setMargin ( MARGIN );
126  layout->addLayout( hbox );
127  hbox->addStretch();
128 
129  // "OK" button
130 
131  QPushButton * button = new QPushButton( _( "&Close" ), this );
132  Q_CHECK_PTR( button );
133  hbox->addWidget(button);
134  button->setDefault( true );
135 
136  connect( button, SIGNAL( clicked() ),
137  this, SLOT ( accept() ) );
138 
139  connect( _dates, SIGNAL( itemSelectionChanged () ),
140  this, SLOT ( moveToDate () ) );
141 
142  connect( _actions, SIGNAL( itemSelectionChanged() ),
143  this, SLOT ( moveToAction () ) );
144 
145  initialize ();
146 }
147 
148 QSize
150 {
151  QRect available = qApp->desktop()->availableGeometry( (QWidget *) this );
152  QSize size = QDialog::sizeHint();
153  size = size.boundedTo( QSize( available.width(), available.height() ) );
154 
155  return size;
156 }
157 
158 
159 void
161 {
162  YQPkgHistoryDialog dialog( parent );
163  dialog.exec();
164 }
165 
166 QPixmap actionIcon (zypp::HistoryActionID id)
167 {
168  switch (id.toEnum ()) {
169  case zypp::HistoryActionID::INSTALL_e : return YQIconPool::pkgInstall ();
170  case zypp::HistoryActionID::REMOVE_e : return YQIconPool::pkgDel ();
171  case zypp::HistoryActionID::REPO_REMOVE_e : return YQIconPool::treeMinus ();
172  case zypp::HistoryActionID::REPO_ADD_e : return YQIconPool::treePlus ();
173  default: return QPixmap ();
174  }
175 
176  return QPixmap ();
177 }
178 
180 {
181  QTreeWidget* actions, * dates;
182  QString _last;
183  QTreeWidgetItem* date_start;
184 
185  bool operator()( const zypp::HistoryLogData::Ptr & item_ptr )
186  {
187  QString d = fromUTF8( item_ptr->date().form("%e %B %Y"));
188  if (d != _last)
189  {
190  _last = d;
191  date_start = new QTreeWidgetItem (actions, QStringList(d));
192  date_start->setExpanded (true);
193  actions-> insertTopLevelItem ( 0, date_start );
194  dates-> insertTopLevelItem ( 0, new QTreeWidgetItem (dates, QStringList(d)));
195  }
196 
197  QStringList columns;
198  if ( item_ptr->action() == zypp::HistoryActionID::INSTALL_e )
199  {
200  zypp::HistoryLogDataInstall* item = static_cast <zypp::HistoryLogDataInstall *> (item_ptr.get());
201 
202  columns << fromUTF8(item->name());
203  columns << fromUTF8(item->edition().version());
204  } else
205  if ( item_ptr->action() == zypp::HistoryActionID::REMOVE_e )
206  {
207  zypp::HistoryLogDataRemove* item = static_cast <zypp::HistoryLogDataRemove *> (item_ptr.get());
208 
209  columns << fromUTF8(item->name());
210  columns << fromUTF8(item->edition().version());
211  } else
212  if ( item_ptr->action() == zypp::HistoryActionID::REPO_ADD_e )
213  {
214  zypp::HistoryLogDataRepoAdd* item = static_cast <zypp::HistoryLogDataRepoAdd *> (item_ptr.get());
215 
216  columns << fromUTF8(item->alias());
217  columns << fromUTF8(item->url().asString());
218  } else
219  if ( item_ptr->action() == zypp::HistoryActionID::REPO_REMOVE_e )
220  {
221  zypp::HistoryLogDataRepoRemove* item = static_cast <zypp::HistoryLogDataRepoRemove *> (item_ptr.get());
222 
223  columns << fromUTF8(item->alias());
224  } else
225  if ( item_ptr->action() == zypp::HistoryActionID::REPO_CHANGE_ALIAS_e )
226  {
227  zypp::HistoryLogDataRepoAliasChange* item = static_cast <zypp::HistoryLogDataRepoAliasChange *> (item_ptr.get());
228 
229  columns << fromUTF8(item->oldAlias()) + " -> " + fromUTF8(item->newAlias());
230  } else
231  if ( item_ptr->action() == zypp::HistoryActionID::REPO_CHANGE_URL_e )
232  {
233  zypp::HistoryLogDataRepoUrlChange* item = static_cast <zypp::HistoryLogDataRepoUrlChange *> (item_ptr.get());
234 
235  columns << fromUTF8(item->alias());
236  columns << fromUTF8(item->newUrl().asString());
237  }
238 
239  QTreeWidgetItem *action = new QTreeWidgetItem (date_start, columns);
240  action->setIcon (0,actionIcon (item_ptr->action()) );
241  return true;
242  }
243 };
244 
245 
246 void
247 YQPkgHistoryDialog::initialize()
248 {
250 
251  ic.actions = _actions;
252  ic.dates = _dates;
253  zypp::parser::HistoryLogReader reader(FILENAME, zypp::parser::HistoryLogReader::Options(), boost::ref(ic));
254 
255  try
256  {
257  reader.readAll();
258  }
259  catch (const zypp::Exception & exception)
260  {
261  yuiWarning() << "CAUGHT zypp exception: " << exception.asUserHistory() << endl;
262 
263  QMessageBox msgBox;
264 
265  // Translators: This is a (short) text indicating that something went
266  // wrong while trying to read history file.
267 
268  QString heading = _( "Unable to read history" );
269 
270  if ( heading.length() < 25 ) // Avoid very narrow message boxes
271  {
272  QString blanks;
273  blanks.fill( ' ', 50 - heading.length() );
274  heading += blanks;
275  }
276 
277  msgBox.setText( heading );
278  msgBox.setIcon( QMessageBox::Warning );
279  msgBox.setInformativeText( fromUTF8( exception.asUserHistory() ) );
280  msgBox.exec();
281  }
282 }
283 
284 
285 void
286 YQPkgHistoryDialog::moveToDate ()
287 {
288  if (signalsBlocked() ) return;
289  QString item = _dates->selectedItems().first()->text(0);
290  QList<QTreeWidgetItem *> items = _actions->findItems (item, Qt::MatchExactly, 0);
291 
292  if( items.size () > 0 )
293  {
294  blockSignals(true);
295  _actions->expandItem (items.first());
296  _actions->setCurrentItem (items.first());
297  _actions->scrollToItem( items.first(), QAbstractItemView::PositionAtTop );
298  blockSignals(false);
299  }
300 }
301 
302 void
303 YQPkgHistoryDialog::moveToAction ()
304 {
305  if (signalsBlocked() ) return;
306  QTreeWidgetItem* item = _actions->selectedItems().first();
307 
308  // if this is not top-level item, better pick top-level one
309  if (item->parent ())
310  item = item->parent ();
311 
312  QList<QTreeWidgetItem *> items = _dates->findItems (item->text(0), Qt::MatchExactly | Qt::MatchRecursive, 0);
313 
314  if( items.size () > 0 )
315  {
316  blockSignals(true);
317  _dates->setCurrentItem (items.first());
318  blockSignals(false);
319  }
320 }
321 
322 #include "YQPkgHistoryDialog.moc"
virtual QSize sizeHint() const
Returns the preferred size.
Pkg status and History as a standalone popup dialog.
static void showHistoryDialog(QWidget *parent=0)
Static convenience method: Post a History dialog for pkg 'pkgName'.
YQPkgHistoryDialog(QWidget *parent)
Constructor: Creates a History dialog for all packages that match 'pkgName'.