/* kasgroupitem.cpp ** ** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> ** Contributor: Mosfet ** All rights reserved. ** ** KasBar is dual-licensed: you can choose the GPL or the BSD license. ** Short forms of both licenses are included below. */ /* ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program in a file called COPYING; if not, write to ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, ** MA 02110-1301, USA. */ /* ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions ** are met: ** 1. Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** 2. Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. */ /* ** Bug reports and questions can be sent to kde-devel@kde.org */ #include <tqpainter.h> #include <tqbitmap.h> #include <tqtimer.h> #include <tqwmatrix.h> #include <kdebug.h> #include <kglobal.h> #include <kwin.h> #include <kiconloader.h> #include <kpixmap.h> #include <kpixmapeffect.h> #include <kpopupmenu.h> #include <klocale.h> #include <taskmanager.h> #include <taskrmbmenu.h> #include "kastasker.h" #include "kaspopup.h" #include "kasgroupitem.h" #include "kasgroupitem.moc" KasGroupItem::KasGroupItem( KasTasker *parent ) : KasItem( parent ), items(), groupType_( GroupRelated ) { setCustomPopup( true ); setGroupItem( true ); setText( i18n("Group") ); connect( parent, TQT_SIGNAL( layoutChanged() ), this, TQT_SLOT( hidePopup() ) ); connect( parent, TQT_SIGNAL( layoutChanged() ), this, TQT_SLOT( update() ) ); connect( this, TQT_SIGNAL(leftButtonClicked(TQMouseEvent *)), TQT_SLOT(togglePopup()) ); connect( this, TQT_SIGNAL(rightButtonClicked(TQMouseEvent *)), TQT_SLOT(showGroupMenuAt(TQMouseEvent *) ) ); } KasGroupItem::~KasGroupItem() { } KasTasker *KasGroupItem::kasbar() const { return static_cast<KasTasker *> (KasItem::kasbar()); } void KasGroupItem::addTask( Task::Ptr t ) { if (!t) return; items.append( t ); if ( items.count() == 1 ) { setText( t->visibleName() ); updateIcon(); } connect( t, TQT_SIGNAL( changed(bool) ), this, TQT_SLOT( update() ) ); update(); } void KasGroupItem::removeTask( Task::Ptr t ) { if ( !t ) return; hidePopup(); for (Task::List::iterator it = items.begin(); it != items.end();) { if ((*it) == t) { it = items.erase(it); } else { ++it; } } updateIcon(); if ( items.count() == 1 ) kasbar()->moveToMain( this, items.first() ); } void KasGroupItem::updateIcon() { TQPixmap p; bool usedIconLoader = false; Task::Ptr t = items.first(); if (!t) p = KGlobal::iconLoader()->loadIcon( "kicker", KIcon::NoGroup, KIcon::SizeSmall ); int sizes[] = { KIcon::SizeEnormous, KIcon::SizeHuge, KIcon::SizeLarge, KIcon::SizeMedium, KIcon::SizeSmall }; p = t->bestIcon( sizes[kasbar()->itemSize()], usedIconLoader ); if ( p.isNull() ) p = KGlobal::iconLoader()->loadIcon( "error", KIcon::NoGroup, KIcon::SizeSmall ); setIcon( p ); } void KasGroupItem::paint( TQPainter *p ) { KasItem::paint( p ); // // Item summary info // int modCount = 0; for ( Task::List::iterator it = items.begin(); it != items.end() ; ++it ) { if ( (*it)->isModified() ) modCount++; } KasResources *res = resources(); p->setPen( isShowingPopup() ? res->activePenColor() : res->inactivePenColor() ); if ( modCount ) { TQString modCountStr; modCountStr.setNum( modCount ); p->drawText( extent()-fontMetrics().width( modCountStr )-3, 15+fontMetrics().ascent(), modCountStr ); p->drawPixmap( extent()-12, 29, res->modifiedIcon() ); } int microsPerCol; switch( kasbar()->itemSize() ) { default: case KasBar::Small: microsPerCol = 2; break; case KasBar::Medium: microsPerCol = 4; break; case KasBar::Large: microsPerCol = 7; break; case KasBar::Huge: microsPerCol = 9; break; case KasBar::Enormous: microsPerCol = 16; break; } int xpos = 3; int ypos = 16; for ( int i = 0; ( i < (int) items.count() ) && ( i < microsPerCol ); i++ ) { Task::Ptr t = items.tqat( i ); if( t->isIconified() ) p->drawPixmap( xpos, ypos, res->microMinIcon() ); else if ( t->isShaded() ) p->drawPixmap( xpos, ypos, res->microShadeIcon() ); else p->drawPixmap( xpos, ypos, res->microMaxIcon() ); ypos += 7; } if ( ((int) items.count() > microsPerCol) && ( kasbar()->itemSize() != KasBar::Small ) ) { TQString countStr; countStr.setNum( items.count() ); p->drawText( extent()-fontMetrics().width( countStr )-3, extent()+fontMetrics().ascent()-16, countStr ); } } void KasGroupItem::updatePopup() { if ( bar ) { bar->rereadMaster(); bar->clear(); if ( items.count() ) { for ( Task::List::iterator t = items.begin(); t != items.end(); ++t ) { bar->addTask( *t ); } } bar->updateLayout(); if ( popup() ) popup()->resize( bar->size() ); } } KasPopup *KasGroupItem::createPopup() { KasPopup *pop = new KasPopup( this ); bar = kasbar()->createChildBar( ( kasbar()->orientation() == Qt::Horizontal ) ? Qt::Vertical : Qt::Horizontal, pop ); connect( pop, TQT_SIGNAL(shown()), TQT_SLOT(updatePopup()) ); return pop; // // Test code // // // // This generates cool looking fractal-like patterns if you keep unfolding the // // groups! // int pos = (int) this; // if ( pos % 2 ) // bar->append( new KasItem( bar ) ); // if ( pos % 5 ) // bar->append( new KasItem( bar ) ); // bar->append( new KasGroupItem( bar ) ); // if ( pos % 3 ) // bar->append( new KasItem( bar ) ); // if ( pos % 7 ) // bar->append( new KasItem( bar ) ); // //////////// } void KasGroupItem::ungroup() { kasbar()->moveToMain( this ); } void KasGroupItem::showGroupMenuAt( TQMouseEvent *ev ) { showGroupMenuAt( ev->globalPos() ); } void KasGroupItem::showGroupMenuAt( const TQPoint &p ) { TaskRMBMenu *tm = new TaskRMBMenu(items, true, kasbar()); tm->insertItem( i18n("&Ungroup" ), this, TQT_SLOT( ungroup() ) ); tm->insertSeparator(); tm->insertItem( i18n("&Kasbar"), kasbar()->contextMenu() ); setLockPopup( true ); tm->exec( p ); delete tm; setLockPopup( false ); }