File indexing completed on 2025-01-05 04:25:45
0001 /**************************************************************************************** 0002 * Copyright (c) 2010 Rick W. Chen <stuffcorpse@archlinux.us> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #define DEBUG_PREFIX "UpcomingEventsStack" 0018 0019 #include "UpcomingEventsStack.h" 0020 #include "UpcomingEventsStackItem.h" 0021 #include "core/support/Debug.h" 0022 0023 #include <QGraphicsLinearLayout> 0024 #include <QSet> 0025 #include <QWeakPointer> 0026 0027 class UpcomingEventsStackPrivate 0028 { 0029 private: 0030 UpcomingEventsStack *const q_ptr; 0031 Q_DECLARE_PUBLIC( UpcomingEventsStack ) 0032 0033 public: 0034 UpcomingEventsStackPrivate( UpcomingEventsStack *parent ); 0035 ~UpcomingEventsStackPrivate(); 0036 0037 QGraphicsLinearLayout *layout; 0038 QHash< QString, QWeakPointer<UpcomingEventsStackItem> > items; 0039 0040 void _itemDestroyed() 0041 { 0042 QHashIterator< QString, QWeakPointer<UpcomingEventsStackItem> > i(items); 0043 while( i.hasNext() ) 0044 { 0045 i.next(); 0046 if( i.value().isNull() ) 0047 items.remove( i.key() ); 0048 } 0049 } 0050 }; 0051 0052 UpcomingEventsStackPrivate::UpcomingEventsStackPrivate( UpcomingEventsStack *parent ) 0053 : q_ptr( parent ) 0054 , layout( 0 ) 0055 { 0056 } 0057 0058 UpcomingEventsStackPrivate::~UpcomingEventsStackPrivate() 0059 { 0060 } 0061 0062 UpcomingEventsStack::UpcomingEventsStack( QGraphicsItem *parent, Qt::WindowFlags wFlags ) 0063 : QGraphicsWidget( parent, wFlags ) 0064 , d_ptr( new UpcomingEventsStackPrivate( this ) ) 0065 { 0066 Q_D( UpcomingEventsStack ); 0067 d->layout = new QGraphicsLinearLayout( Qt::Vertical, this ); 0068 d->layout->setContentsMargins( 0, 0, 0, 0 ); 0069 setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); 0070 } 0071 0072 UpcomingEventsStack::~UpcomingEventsStack() 0073 { 0074 delete d_ptr; 0075 } 0076 0077 int 0078 UpcomingEventsStack::count() const 0079 { 0080 Q_D( const UpcomingEventsStack ); 0081 return d->layout->count(); 0082 } 0083 0084 void 0085 UpcomingEventsStack::clear() 0086 { 0087 prepareGeometryChange(); 0088 Q_D( UpcomingEventsStack ); 0089 int itemCount = d->layout->count(); 0090 while( --itemCount >= 0 ) 0091 { 0092 QGraphicsLayoutItem *child = d->layout->itemAt( 0 ); 0093 d->layout->removeItem( child ); 0094 } 0095 foreach( QWeakPointer<UpcomingEventsStackItem> item, d->items ) 0096 item.data()->deleteLater(); 0097 d->items.clear(); 0098 } 0099 0100 bool 0101 UpcomingEventsStack::isEmpty() const 0102 { 0103 Q_D( const UpcomingEventsStack ); 0104 return d->items.isEmpty(); 0105 } 0106 0107 bool 0108 UpcomingEventsStack::hasItem( const QString &name ) const 0109 { 0110 Q_D( const UpcomingEventsStack ); 0111 if( d->items.value( name ) ) 0112 return true; 0113 else 0114 return false; 0115 } 0116 0117 UpcomingEventsStackItem * 0118 UpcomingEventsStack::item( const QString &name ) const 0119 { 0120 Q_D( const UpcomingEventsStack ); 0121 Q_ASSERT( d->items.contains( name ) ); 0122 return d->items.value( name ).data(); 0123 } 0124 0125 QList<UpcomingEventsStackItem *> 0126 UpcomingEventsStack::items( const QRegExp &pattern ) const 0127 { 0128 Q_D( const UpcomingEventsStack ); 0129 QList<UpcomingEventsStackItem *> matched; 0130 QHashIterator< QString, QWeakPointer<UpcomingEventsStackItem> > i( d->items ); 0131 while( i.hasNext() ) 0132 { 0133 i.next(); 0134 if( i.key().contains( pattern ) ) 0135 matched << i.value().data(); 0136 } 0137 return matched; 0138 } 0139 0140 UpcomingEventsStackItem * 0141 UpcomingEventsStack::create( const QString &name ) 0142 { 0143 if( hasItem( name ) ) 0144 return 0; 0145 0146 Q_D( UpcomingEventsStack ); 0147 QWeakPointer<UpcomingEventsStackItem> item = new UpcomingEventsStackItem( name, this ); 0148 d->layout->addItem( item.data() ); 0149 d->items.insert( name, item ); 0150 connect( item.data(), SIGNAL(destroyed()), SLOT(_itemDestroyed()) ); 0151 connect( item.data(), SIGNAL(collapseChanged(bool)), SIGNAL(collapseStateChanged()) ); 0152 return item.data(); 0153 } 0154 0155 void 0156 UpcomingEventsStack::remove( const QString &name ) 0157 { 0158 Q_D( UpcomingEventsStack ); 0159 d->items.take( name ).data()->deleteLater(); 0160 } 0161 0162 void 0163 UpcomingEventsStack::maximizeItem( const QString &name ) 0164 { 0165 if( hasItem( name ) ) 0166 { 0167 Q_D( UpcomingEventsStack ); 0168 d->items.value( name ).data()->setCollapsed( false ); 0169 QHashIterator< QString, QWeakPointer<UpcomingEventsStackItem> > i( d->items ); 0170 while( i.hasNext() ) 0171 { 0172 i.next(); 0173 if( i.value().data()->name() != name ) 0174 i.value().data()->setCollapsed( true ); 0175 } 0176 } 0177 } 0178 0179 void 0180 UpcomingEventsStack::cleanupListWidgets() 0181 { 0182 Q_D( UpcomingEventsStack ); 0183 QHashIterator< QString, QWeakPointer<UpcomingEventsStackItem> > i( d->items ); 0184 while( i.hasNext() ) 0185 { 0186 i.next(); 0187 if( i.value().isNull() ) 0188 d->items.remove( i.key() ); 0189 } 0190 } 0191