libyui-qt  2.44.0
 All Classes Functions Variables
YQTable.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: YQTable.cc
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23 /-*/
24 
25 #include <QHeaderView>
26 #include <QVBoxLayout>
27 #include <QString>
28 #define YUILogComponent "qt-ui"
29 #include <yui/YUILog.h>
30 
31 #include "utf8.h"
32 #include "YQUI.h"
33 #include <yui/YEvent.h>
34 #include "YQSignalBlocker.h"
35 #include <yui/YUIException.h>
36 
37 #include "QY2ListView.h"
38 #include "YQTable.h"
39 #include "YQApplication.h"
40 
41 
42 
43 YQTable::YQTable( YWidget * parent, YTableHeader * tableHeader, bool multiSelectionMode )
44  : QFrame( (QWidget *) parent->widgetRep() )
45  , YTable( parent, tableHeader, multiSelectionMode )
46 {
47  setWidgetRep( this );
48  QVBoxLayout* layout = new QVBoxLayout( this );
49  layout->setSpacing( 0 );
50  setLayout( layout );
51 
52  layout->setMargin( YQWidgetMargin );
53 
54  _qt_listView = new QY2ListView( this );
55  YUI_CHECK_NEW( _qt_listView );
56  layout->addWidget( _qt_listView );
57  _qt_listView->setAllColumnsShowFocus( true );
58  _qt_listView->header()->setStretchLastSection( false );
59 
60  setKeepSorting( keepSorting() );
61 
62  if ( multiSelectionMode )
63  _qt_listView->setSelectionMode( QAbstractItemView::ExtendedSelection );
64 
65  _qt_listView->setContextMenuPolicy( Qt::CustomContextMenu );
66 
67  //
68  // Add columns
69  //
70 
71  QStringList headers;
72  _qt_listView->setColumnCount( columns() );
73 
74  for ( int i=0; i < columns(); i++ )
75  {
76  headers << fromUTF8( header(i) );
77  }
78 
79  _qt_listView->setHeaderLabels( headers );
80  _qt_listView->header()->setResizeMode( QHeaderView::Interactive );
81  _qt_listView->sortItems( 0, Qt::AscendingOrder);
82 
83 
84  //
85  // Connect signals and slots
86  //
87 
88  connect( _qt_listView, SIGNAL( itemDoubleClicked ( QTreeWidgetItem *, int ) ),
89  this, SLOT ( slotActivated ( QTreeWidgetItem * ) ) );
90 
91  connect( _qt_listView, SIGNAL( currentItemChanged ( QTreeWidgetItem *, QTreeWidgetItem * ) ),
92  this, SLOT ( slotSelected ( QTreeWidgetItem * ) ) );
93 
94  connect( _qt_listView, SIGNAL( customContextMenuRequested ( const QPoint & ) ),
95  this, SLOT ( slotContextMenu ( const QPoint & ) ) );
96 
97 
98  if ( multiSelectionMode )
99  {
100  // This is the exceptional case - avoid performance drop in the normal case
101 
102  connect( _qt_listView, SIGNAL( itemSelectionChanged() ),
103  this, SLOT ( slotSelectionChanged() ) );
104 
105  }
106 }
107 
108 
110 {
111  // NOP
112 }
113 
114 
115 void
116 YQTable::setKeepSorting( bool keepSorting )
117 {
118  YTable::setKeepSorting( keepSorting );
119  _qt_listView->setSortByInsertionSequence( keepSorting );
120  _qt_listView->setSortingEnabled( ! keepSorting );
121 }
122 
123 
124 void
125 YQTable::addItem( YItem * yitem )
126 {
127  addItem( yitem,
128  false, // batchMode
129  true); // resizeColumnsToContent
130 }
131 
132 
133 void
134 YQTable::addItem( YItem * yitem, bool batchMode, bool resizeColumnsToContent )
135 {
136  YTableItem * item = dynamic_cast<YTableItem *> (yitem);
137  YUI_CHECK_PTR( item );
138 
139  YTable::addItem( item );
140 
141  YQTableListViewItem * clone = new YQTableListViewItem( this, _qt_listView, item );
142  YUI_CHECK_NEW( clone );
143 
144  if ( ! batchMode && item->selected() )
145  {
146  // YTable enforces single selection, if appropriate
147 
148  YQSignalBlocker sigBlocker( _qt_listView );
149  YQTable::selectItem( YSelectionWidget::selectedItem(), true );
150  }
151 
152 
153  //
154  // Set column alignment
155  //
156 
157  for ( int col=0; col < columns(); col++ )
158  {
159  switch ( alignment( col ) )
160  {
161  case YAlignBegin: clone->setTextAlignment( col, Qt::AlignLeft | Qt::AlignVCenter ); break;
162  case YAlignCenter: clone->setTextAlignment( col, Qt::AlignCenter | Qt::AlignVCenter ); break;
163  case YAlignEnd: clone->setTextAlignment( col, Qt::AlignRight | Qt::AlignVCenter ); break;
164 
165  case YAlignUnchanged: break;
166  }
167  }
168 
169  if ( ! batchMode )
170  _qt_listView->sortItems( 0, Qt::AscendingOrder);
171 
172  if ( resizeColumnsToContent )
173  {
174  for ( int i=0; i < columns(); i++ )
175  _qt_listView->resizeColumnToContents( i );
176  /* NOTE: resizeColumnToContents(...) is performance-critical ! */
177  }
178 }
179 
180 
181 void
182 YQTable::addItems( const YItemCollection & itemCollection )
183 {
184  YQSignalBlocker sigBlocker( _qt_listView );
185 
186  for ( YItemConstIterator it = itemCollection.begin();
187  it != itemCollection.end();
188  ++it )
189  {
190  addItem( *it,
191  true, // batchMode
192  false ); // resizeColumnsToContent
193  /* NOTE: resizeToContents=true would cause a massive performance drop !
194  => resize columns to content only one time at the end of this
195  function */
196  }
197 
198  YItem * sel = YSelectionWidget::selectedItem();
199 
200  if ( sel )
201  YQTable::selectItem( sel, true );
202 
203  for ( int i=0; i < columns(); i++ )
204  _qt_listView->resizeColumnToContents( i );
205 }
206 
207 
208 void
209 YQTable::selectItem( YItem * yitem, bool selected )
210 {
211  YQSignalBlocker sigBlocker( _qt_listView );
212 
213  YTableItem * item = dynamic_cast<YTableItem *> (yitem);
214  YUI_CHECK_PTR( item );
215 
216  YQTableListViewItem * clone = (YQTableListViewItem *) item->data();
217  YUI_CHECK_PTR( clone );
218 
219 
220  if ( ! selected && clone == _qt_listView->currentItem() )
221  {
223  }
224  else
225  {
226  if ( ! hasMultiSelection() )
227  _qt_listView->setCurrentItem( clone ); // This deselects all other items!
228 
229  clone->setSelected( true );
230  YTable::selectItem( item, selected );
231  }
232 }
233 
234 
235 void
237 {
238  YQSignalBlocker sigBlocker( _qt_listView );
239 
240  YTable::deselectAllItems();
241  _qt_listView->clearSelection();
242 }
243 
244 
245 void
247 {
248  _qt_listView->clear();
249  YTable::deleteAllItems();
250 }
251 
252 
253 void
254 YQTable::cellChanged( const YTableCell * cell )
255 {
256  YTableItem * item = cell->parent();
257  YUI_CHECK_PTR( item );
258 
259  YQTableListViewItem * clone = (YQTableListViewItem *) item->data();
260  YUI_CHECK_PTR( clone );
261 
262  clone->updateCell( cell );
263 }
264 
265 
266 void
267 YQTable::selectOrigItem( QTreeWidgetItem * listViewItem )
268 {
269  if ( listViewItem )
270  {
271  YQTableListViewItem * tableListViewItem = dynamic_cast<YQTableListViewItem *> (listViewItem);
272  YUI_CHECK_PTR( tableListViewItem );
273 
274  YTable::selectItem( tableListViewItem->origItem(), true );
275  }
276 }
277 
278 
279 void
280 YQTable::slotSelected( QTreeWidgetItem * listViewItem )
281 {
282  if ( listViewItem && _qt_listView->selectedItems().count() > 0 )
283  selectOrigItem( listViewItem );
284  else
285  {
286  // Qt might select nothing if a user clicks outside the items in the widget
287 
288  if ( hasItems() && YSelectionWidget::hasSelectedItem() )
289  YQTable::selectItem( YSelectionWidget::selectedItem(), true );
290  }
291 
292  if ( immediateMode() )
293  {
294  if ( ! YQUI::ui()->eventPendingFor( this ) )
295  {
296  // Avoid overwriting a (more important) Activated event with a SelectionChanged event
297 
298  yuiDebug() << "Sending SelectionChanged event" << std::endl;
299  YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
300  }
301  }
302 }
303 
304 
305 void
307 {
308  YSelectionWidget::deselectAllItems();
309  yuiDebug() << std::endl;
310 
311  QList<QTreeWidgetItem *> selItems = _qt_listView->selectedItems();
312 
313  for ( QList<QTreeWidgetItem *>::iterator it = selItems.begin();
314  it != selItems.end();
315  ++it )
316  {
317  YQTableListViewItem * tableListViewItem = dynamic_cast<YQTableListViewItem *> (*it);
318 
319  if ( tableListViewItem )
320  {
321  tableListViewItem->origItem()->setSelected( true );
322 
323  yuiDebug() << "Selected item: " << tableListViewItem->origItem()->label() << std::endl;
324  }
325  }
326 
327  if ( immediateMode() )
328  {
329  if ( ! YQUI::ui()->eventPendingFor( this ) )
330  {
331  // Avoid overwriting a (more important) Activated event with a SelectionChanged event
332 
333  yuiDebug() << "Sending SelectionChanged event" << std::endl;
334  YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
335  }
336  }
337 }
338 
339 
340 void
341 YQTable::slotActivated( QTreeWidgetItem * listViewItem )
342 {
343  selectOrigItem( listViewItem );
344 
345  if ( notify() )
346  {
347  yuiDebug() << "Sending Activated event" << std::endl;
348  YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::Activated ) );
349  }
350 }
351 
352 
353 void
354 YQTable::setEnabled( bool enabled )
355 {
356  _qt_listView->setEnabled( enabled );
357  //FIXME _qt_listView->triggerUpdate();
358  YWidget::setEnabled( enabled );
359 }
360 
361 
362 
363 int
365 {
366  // Arbitrary value.
367  // Use a MinSize widget to set a size that is useful for the application.
368 
369  return 30;
370 }
371 
372 
373 int
375 {
376  // Arbitrary value.
377  // Use a MinSize widget to set a size that is useful for the application.
378 
379  return 30;
380 }
381 
382 
383 void
384 YQTable::setSize( int newWidth, int newHeight )
385 {
386  resize( newWidth, newHeight );
387 }
388 
389 
390 bool
392 {
393  _qt_listView->setFocus();
394 
395  return true;
396 }
397 
398 
399 void
400 YQTable::slotContextMenu ( const QPoint & pos )
401 {
402  if ( ! _qt_listView || ! _qt_listView->viewport() )
403  return;
404 
405  YQUI::yqApp()->setContextMenuPos( _qt_listView->viewport()->mapToGlobal( pos ) );
406  if ( notifyContextMenu() )
407  YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::ContextMenuActivated ) );
408 }
409 
410 
411 
412 
413 
415  QY2ListView * parent,
416  YTableItem * origItem )
417  : QY2ListViewItem( parent )
418  , _table( table )
419  , _origItem( origItem )
420 {
421  YUI_CHECK_PTR( _table );
422  YUI_CHECK_PTR( _origItem );
423 
424  _origItem->setData( this );
425 
426  for ( YTableCellIterator it = _origItem->cellsBegin();
427  it != _origItem->cellsEnd();
428  ++it )
429  {
430  updateCell( *it );
431  }
432 }
433 
434 
435 void
436 YQTableListViewItem::updateCell( const YTableCell * cell )
437 {
438  if ( ! cell )
439  return;
440 
441  int column = cell->column();
442 
443  //
444  // Set label text
445  //
446 
447  setText( column, fromUTF8( cell->label() ) );
448 
449 
450  //
451  // Set icon (if specified)
452  //
453 
454  if ( cell->hasIconName() )
455  {
456  // _table is checked against 0 in the constructor
457 
458  string iconName = _table->iconFullPath( cell->iconName() );
459  QPixmap icon = QPixmap( iconName.c_str() );
460 
461  if ( icon.isNull() )
462  yuiWarning() << "Can't load icon " << iconName << std::endl;
463  else
464  setData( column, Qt::DecorationRole, icon );
465  }
466  else // No pixmap name
467  {
468  if ( ! data( column, Qt::DecorationRole ).isNull() ) // Was there a pixmap before?
469  {
470  setData( column, Qt::DecorationRole, QPixmap() ); // Set empty pixmap
471  }
472  }
473 }
474 
475 
476 #include "YQTable.moc"
virtual void selectItem(YItem *item, bool selected=true)
Definition: YQTable.cc:209
YTableItem * origItem() const
Definition: YQTable.h:215
virtual void setSortByInsertionSequence(bool sortByInsertionSequence)
Definition: QY2ListView.cc:354
virtual void addItem(YItem *item)
Definition: YQTable.cc:125
static YQApplication * yqApp()
Definition: YQUI.cc:283
void slotContextMenu(const QPoint &pos)
Definition: YQTable.cc:400
virtual bool setKeyboardFocus()
Definition: YQTable.cc:391
bool eventPendingFor(YWidget *widget) const
Definition: YQUI.h:133
YQTableListViewItem(YQTable *table, QY2ListView *parent, YTableItem *origItem)
Definition: YQTable.cc:414
void slotSelected(QTreeWidgetItem *)
Definition: YQTable.cc:280
virtual void setKeepSorting(bool keepSorting)
Definition: YQTable.cc:116
virtual void clear()
Definition: QY2ListView.cc:101
virtual void deleteAllItems()
Definition: YQTable.cc:246
void selectOrigItem(QTreeWidgetItem *listViewItem)
Definition: YQTable.cc:267
virtual void setEnabled(bool enabled)
Definition: YQTable.cc:354
virtual void deselectAllItems()
Definition: YQTable.cc:236
virtual void setContextMenuPos(QPoint contextMenuPos)
virtual void cellChanged(const YTableCell *cell)
Definition: YQTable.cc:254
void sendEvent(YEvent *event)
Definition: YQUI.cc:476
YQTable(YWidget *parent, YTableHeader *header, bool multiSelection)
Definition: YQTable.cc:43
virtual ~YQTable()
Definition: YQTable.cc:109
void updateCell(const YTableCell *cell)
Definition: YQTable.cc:436
Enhanced QTreeWidget.
Definition: QY2ListView.h:47
virtual void setSize(int newWidth, int newHeight)
Definition: YQTable.cc:384
void slotActivated(QTreeWidgetItem *)
Definition: YQTable.cc:341
virtual void addItems(const YItemCollection &itemCollection)
Definition: YQTable.cc:182
virtual int preferredWidth()
Definition: YQTable.cc:364
virtual int preferredHeight()
Definition: YQTable.cc:374
void slotSelectionChanged()
Definition: YQTable.cc:306
static YQUI * ui()
Definition: YQUI.h:74