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