• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

knode

  • sources
  • kde-4.14
  • kdepim
  • knode
treewidget.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * This file is part of libkdepim.
4  *
5  * Copyright (C) 2008 Szymon Tomasz Stefanek <pragma@kvirc.net>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  *****************************************************************************/
23 
24 #include "treewidget.h"
25 
26 #include <KMenu>
27 #include <KConfig>
28 #include <KConfigGroup>
29 #include <KLocale>
30 
31 #include <QHeaderView>
32 #include <QVector>
33 #include <QEvent>
34 
35 namespace KPIM {
36 
37 #define KPIM_TREEWIDGET_DEFAULT_CONFIG_KEY "TreeWidgetLayout"
38 
39 TreeWidget::TreeWidget( QWidget * parent, const char * name )
40 : QTreeWidget( parent )
41 {
42  setObjectName( name );
43  setColumnCount( 0 );
44 
45  header()->setMovable( true );
46 
47  setManualColumnHidingEnabled( true );
48 
49  // At the moment of writing (25.11.2008) there is a bug in Qt
50  // which causes an assertion failure in animated views when
51  // the animated item is deleted. The bug notification has been
52  // sent to qt-bugs. For the moment we keep animations explicitly disabled.
53  // FIXME: Re-enable animations once the qt bug is fixed.
54  setAnimated( false );
55 }
56 
57 void TreeWidget::changeEvent( QEvent *e )
58 {
59  QTreeWidget::changeEvent( e );
60 
61  if ( e->type() == QEvent::StyleChange )
62  {
63  // At the moment of writing (25.11.2008) there is a bug in Qt
64  // which causes an assertion failure in animated views when
65  // the animated item is deleted. The bug notification has been
66  // sent to qt-bugs. For the moment we keep animations explicitly disabled.
67  // FIXME: Re-enable animations once the qt bug is fixed.
68  setAnimated( false );
69  }
70 }
71 
72 bool TreeWidget::saveLayout( KConfigGroup &group, const QString &keyName ) const
73 {
74  group.writeEntry(
75  keyName.isEmpty() ? QString( KPIM_TREEWIDGET_DEFAULT_CONFIG_KEY ) : keyName,
76  QVariant( header()->saveState().toHex() )
77  );
78 
79  return true;
80 }
81 
82 bool TreeWidget::saveLayout( KConfig * config, const QString &groupName, const QString &keyName ) const
83 {
84  if( !config || groupName.isEmpty() )
85  return false;
86 
87  KConfigGroup group( config, groupName );
88  return saveLayout( group, keyName );
89 }
90 
91 bool TreeWidget::restoreLayout( KConfigGroup &group, const QString &keyName )
92 {
93  // Restore the view column order, width and visibility
94  QByteArray state = group.readEntry(
95  keyName.isEmpty() ? QString( KPIM_TREEWIDGET_DEFAULT_CONFIG_KEY ) : keyName,
96  QVariant( QVariant::ByteArray )
97  ).toByteArray();
98  state = QByteArray::fromHex( state );
99 
100  if( state.isEmpty() )
101  return false;
102 
103  int cc = header()->count();
104 
105  // Qt writes also some options that can be set only
106  // programmatically. This can drive you crazy if you
107  // first setup the view and then restore the layout:
108  // it will overwrite your previous settings...
109 
110  bool sectionsWereClickable = header()->isClickable();
111  bool sectionsWereMovable = header()->isMovable();
112  bool sortIndicatorWasShown = header()->isSortIndicatorShown();
113  Qt::Alignment originalDefaultAlignment = header()->defaultAlignment();
114  //int defaultSectionSize = header()->defaultSectionSize();
115  int minimumSectionSize = header()->minimumSectionSize();
116  bool cascadingSectionResizes = header()->cascadingSectionResizes();
117  QVector<QHeaderView::ResizeMode> resizeModes( cc );
118  for ( int i = 0 ; i < cc ; ++i ) {
119  resizeModes[ i ] = header()->resizeMode( i );
120  }
121 
122  // Qt (4.4) will perform a layout based on the stored column sizes
123  // when restoreState() is called. However, there is an issue
124  // related to the last section: the restoreState() call will
125  // preserve the _current_ (pre-restoreState()-call) width
126  // of the last section if that is actually greater than the stored
127  // value. This is very likely to throw the last section out of
128  // the view and cause a horizontal scroll bar to appear even
129  // if it wasn't present when saveState() was called.
130  // This seems to be a Qt buggie and we workaround it by
131  // setting all the sections sizes to something very small
132  // just before calling restoreState().
133 
134  // we also need to save the current sections sizes in order to remain
135  // consistent if restoreState() fails for some reason.
136  QVector<int> savedSizes( cc );
137  for ( int i = 0 ; i < cc ; ++i )
138  {
139  savedSizes[ i ] = header()->sectionSize( i );
140  header()->resizeSection( i , 10 );
141  }
142 
143  if ( !header()->restoreState( state ) )
144  {
145  // failed: be consistent and restore the section sizes before returning
146  for ( int c = 0 ; c < cc ; ++c )
147  header()->resizeSection( c , savedSizes[ c ] );
148  return false;
149  }
150 
151  header()->setClickable( sectionsWereClickable );
152  header()->setMovable( sectionsWereMovable );
153  header()->setSortIndicatorShown( sortIndicatorWasShown );
154  header()->setDefaultAlignment( originalDefaultAlignment );
155  header()->setMinimumSectionSize( minimumSectionSize );
156  header()->setCascadingSectionResizes( cascadingSectionResizes );
157  for ( int i = 0 ; i < cc ; ++i ) {
158  header()->setResizeMode( i, resizeModes[ i ] );
159  }
160 
161  // FIXME: This would cause the sections to be resized and thus
162  // can't be reliably reset after the configuration
163  // has been read. Can do nothing about that except warning
164  // the user in the docs.
165  //header()->setDefaultSectionSize( defaultSectionSize );
166 
167  return true;
168 }
169 
170 bool TreeWidget::restoreLayout( KConfig * config, const QString &groupName, const QString &keyName )
171 {
172  if( !config || groupName.isEmpty() )
173  return false;
174 
175  if ( !config->hasGroup( groupName ) )
176  return false;
177 
178  KConfigGroup group( config, groupName );
179  return restoreLayout( group, keyName );
180 }
181 
182 void TreeWidget::setManualColumnHidingEnabled( bool enable )
183 {
184  if( enable )
185  {
186  header()->setContextMenuPolicy( Qt::CustomContextMenu ); // make sure it's true
187  QObject::connect( header(), SIGNAL(customContextMenuRequested(QPoint)),
188  this, SLOT(slotHeaderContextMenuRequested(QPoint)) );
189  } else {
190  if ( mEnableManualColumnHiding )
191  QObject::disconnect( header(), SIGNAL(customContextMenuRequested(QPoint)),
192  this, SLOT(slotHeaderContextMenuRequested(QPoint)) );
193  }
194 
195  mEnableManualColumnHiding = enable;
196 }
197 
198 void TreeWidget::setColumnHidden( int logicalIndex, bool hide )
199 {
200  if ( header()->isSectionHidden( logicalIndex ) == hide )
201  return;
202  header()->setSectionHidden( logicalIndex, hide );
203 
204  emit columnVisibilityChanged( logicalIndex );
205 }
206 
207 bool TreeWidget::isColumnHidden( int logicalIndex ) const
208 {
209  return header()->isSectionHidden( logicalIndex );
210 }
211 
212 bool TreeWidget::fillHeaderContextMenu( KMenu * menu, const QPoint & )
213 {
214  if ( !menu || !mEnableManualColumnHiding )
215  return false;
216 
217  menu->addTitle( i18n("View Columns") );
218 
219  QTreeWidgetItem * hitem = headerItem();
220  if ( !hitem )
221  return false; // oops..
222 
223  // Dynamically build the menu and check the items for visible columns
224  int cc = hitem->columnCount();
225  if ( cc < 1 )
226  return false;
227 
228  for ( int i = 1 ; i < cc; ++i )
229  {
230  QAction * act = menu->addAction( hitem->text( i ) );
231  act->setCheckable( true );
232  if ( !header()->isSectionHidden( i ) )
233  act->setChecked( true );
234  act->setData( QVariant( i ) );
235 
236  connect(
237  act, SIGNAL(triggered(bool)),
238  this, SLOT(slotToggleColumnActionTriggered(bool)) );
239  }
240 
241  return true;
242 }
243 
244 void TreeWidget::toggleColumn( int logicalIndex )
245 {
246  setColumnHidden( logicalIndex, !header()->isSectionHidden( logicalIndex ) );
247 }
248 
249 
250 void TreeWidget::slotToggleColumnActionTriggered( bool )
251 {
252  QAction *act = dynamic_cast< QAction * >( sender() );
253  if ( !act )
254  return;
255 
256  QVariant data = act->data();
257 
258  bool ok;
259  int id = data.toInt( &ok );
260  if ( !ok )
261  return;
262 
263  if ( id > columnCount() )
264  return;
265 
266  setColumnHidden( id, !act->isChecked() );
267 }
268 
269 void TreeWidget::slotHeaderContextMenuRequested( const QPoint &clickPoint )
270 {
271  KMenu menu( this );
272 
273  if ( !fillHeaderContextMenu( &menu, clickPoint ) )
274  return;
275 
276  menu.exec( header()->mapToGlobal( clickPoint ) );
277 }
278 
279 int TreeWidget::addColumn( const QString &label, int headerAlignment )
280 {
281  QTreeWidgetItem * hitem = headerItem();
282  if ( !hitem )
283  {
284  // In fact this seems to never happen
285  hitem = new QTreeWidgetItem( this );
286  hitem->setText( 0, label );
287  hitem->setTextAlignment( 0, headerAlignment );
288  setHeaderItem( hitem ); // will set column count to 1
289  return 0;
290  }
291 
292  int cc = columnCount();
293 
294  setColumnCount( cc + 1 );
295  hitem->setText( cc, label );
296  hitem->setTextAlignment( cc, headerAlignment );
297  return cc;
298 }
299 
300 bool TreeWidget::setColumnText( int columnIndex, const QString &label )
301 {
302  if ( columnIndex >= columnCount() )
303  return false;
304  QTreeWidgetItem * hitem = headerItem();
305  if ( !hitem )
306  return false;
307  hitem->setText( columnIndex, label );
308  return true;
309 }
310 
311 QTreeWidgetItem * TreeWidget::firstItem() const
312 {
313  if ( topLevelItemCount() < 1 )
314  return 0;
315  return topLevelItem( 0 );
316 }
317 
318 QTreeWidgetItem * TreeWidget::lastItem() const
319 {
320  QTreeWidgetItem *it = 0;
321  int cc = topLevelItemCount();
322  if ( cc < 1 )
323  return 0;
324  it = topLevelItem( cc - 1 );
325  if ( !it )
326  return 0; // sanity check
327  cc = it->childCount();
328  while ( cc > 0 )
329  {
330  it = it->child( cc - 1 );
331  if ( !it )
332  return 0; // aaaaaargh: something is really wrong :D
333  cc = it->childCount();
334  }
335  return it;
336 }
337 
338 }
QWidget::customContextMenuRequested
void customContextMenuRequested(const QPoint &pos)
saveState
KDEPIM_EXPORT void saveState(QWidget *widget, KConfigGroup &config)
QEvent
QWidget
QEvent::type
Type type() const
QHeaderView::setMovable
void setMovable(bool movable)
treewidget.h
A common QTreeWidget extension.
QByteArray
QTreeWidgetItem::child
QTreeWidgetItem * child(int index) const
QObject::sender
QObject * sender() const
QAction::setChecked
void setChecked(bool)
KPIM::TreeWidget::changeEvent
virtual void changeEvent(QEvent *e)
Reimplemented in order to catch style change events and explicitly disable animations.
Definition: treewidget.cpp:57
QAction::data
QVariant data() const
QHeaderView::resizeMode
ResizeMode resizeMode(int logicalIndex) const
KPIM::TreeWidget::fillHeaderContextMenu
virtual bool fillHeaderContextMenu(KMenu *menu, const QPoint &clickPoint)
Called by this class to fill the contextual menu shown when the user right clicks on one of the heade...
Definition: treewidget.cpp:212
QByteArray::isEmpty
bool isEmpty() const
QWidget::mapToGlobal
QPoint mapToGlobal(const QPoint &pos) const
QHeaderView::cascadingSectionResizes
cascadingSectionResizes
QTreeView::setAnimated
void setAnimated(bool enable)
QHeaderView::isSortIndicatorShown
bool isSortIndicatorShown() const
QPoint
KPIM::TreeWidget::setColumnHidden
void setColumnHidden(int logicalIndex, bool hide)
Hides or shows the column specified by logicalIndex.
Definition: treewidget.cpp:198
Qt::Alignment
typedef Alignment
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
KPIM::TreeWidget::setManualColumnHidingEnabled
void setManualColumnHidingEnabled(bool enable)
Enables or disables manual column hiding by the means of a contextual menu.
Definition: treewidget.cpp:182
QHeaderView::resizeSection
void resizeSection(int logicalIndex, int size)
KPIM::TreeWidget::isColumnHidden
bool isColumnHidden(int logicalIndex) const
Returns true if the column specified by logicalIndex is actually hidden.
Definition: treewidget.cpp:207
QTreeWidget::setHeaderItem
void setHeaderItem(QTreeWidgetItem *item)
QTreeWidget
QHeaderView::minimumSectionSize
minimumSectionSize
QVariant::toInt
int toInt(bool *ok) const
QHeaderView::isSectionHidden
bool isSectionHidden(int logicalIndex) const
KPIM::TreeWidget::setColumnText
bool setColumnText(int columnIndex, const QString &label)
Convenience function that changes the header text for the specified column.
Definition: treewidget.cpp:300
KPIM::TreeWidget::restoreLayout
bool restoreLayout(KConfigGroup &group, const QString &keyName=QString())
Attempts to restore the layout of this tree from the specified key of the specified KConfigGroup...
Definition: treewidget.cpp:91
QObject::setObjectName
void setObjectName(const QString &name)
QString::isEmpty
bool isEmpty() const
QFrame::changeEvent
virtual void changeEvent(QEvent *ev)
QHeaderView::defaultAlignment
defaultAlignment
KPIM::TreeWidget::toggleColumn
void toggleColumn(int logicalIndex)
Toggle the visibility state of the specified column.
Definition: treewidget.cpp:244
KPIM_TREEWIDGET_DEFAULT_CONFIG_KEY
#define KPIM_TREEWIDGET_DEFAULT_CONFIG_KEY
Definition: treewidget.cpp:37
QTreeWidgetItem::columnCount
int columnCount() const
QString
QTreeWidget::setColumnCount
void setColumnCount(int columns)
KPIM::TreeWidget::saveLayout
bool saveLayout(KConfigGroup &group, const QString &keyName=QString()) const
Stores the layout of this tree view to the specified KConfigGroup.
Definition: treewidget.cpp:72
restoreState
KDEPIM_EXPORT void restoreState(QWidget *widget, const KConfigGroup &config)
QHeaderView::sectionSize
int sectionSize(int logicalIndex) const
QByteArray::fromHex
QByteArray fromHex(const QByteArray &hexEncoded)
QAction::setData
void setData(const QVariant &userData)
QWidget::setContextMenuPolicy
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
QAction::setCheckable
void setCheckable(bool)
KPIM::TreeWidget::TreeWidget
TreeWidget(QWidget *parent, const char *name=0)
Constructs a TreeWidget.
Definition: treewidget.cpp:39
QAbstractItemView::state
State state() const
KPIM::TreeWidget::lastItem
QTreeWidgetItem * lastItem() const
Convenience function that returns the last item in the view.
Definition: treewidget.cpp:318
QHeaderView::isMovable
bool isMovable() const
QTreeWidget::headerItem
QTreeWidgetItem * headerItem() const
KPIM::TreeWidget::addColumn
int addColumn(const QString &label, int headerAlignment=Qt::AlignLeft|Qt::AlignVCenter)
Convenience function that adds a column to this tree widget and returns its logical index...
Definition: treewidget.cpp:279
QVector
QTreeWidgetItem
QHeaderView::isClickable
bool isClickable() const
QHeaderView::setResizeMode
void setResizeMode(ResizeMode mode)
QAction
QHeaderView::setClickable
void setClickable(bool clickable)
QTreeWidgetItem::setText
void setText(int column, const QString &text)
QTreeWidgetItem::setTextAlignment
void setTextAlignment(int column, int alignment)
QTreeView::header
QHeaderView * header() const
QTreeWidget::topLevelItem
QTreeWidgetItem * topLevelItem(int index) const
KPIM::TreeWidget::columnVisibilityChanged
void columnVisibilityChanged(int logicalIndex)
This signal is emitted when an existing column is shown or hidden either by the means of the popup me...
KPIM::TreeWidget::firstItem
QTreeWidgetItem * firstItem() const
Convenience function that returns the first item in the view.
Definition: treewidget.cpp:311
QTreeWidget::topLevelItemCount
int topLevelItemCount() const
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QTreeWidgetItem::childCount
int childCount() const
QTreeWidgetItem::text
QString text(int column) const
QHeaderView::setSectionHidden
void setSectionHidden(int logicalIndex, bool hide)
QHeaderView::count
int count() const
QVariant
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:34:18 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

knode

Skip menu "knode"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal