Komposé – a fullscreen view of all your tasks and/or virtual desktops. Every window is represented by a scaled screenshot of it's own. Komposé was part of the BerliOS project.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

435 lines
13 KiB

/***************************************************************************
* Copyright (C) 2004 by Hans Oischinger *
* hans.oischinger@kde-mail.net *
* *
* 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; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "komposetaskwidget.h"
#include "komposetaskmanager.h"
#include "komposeviewmanager.h"
#include "komposetask.h"
#include "komposetaskcontainerwidget.h"
#include "komposetaskprefswidget.h"
#include "komposesettings.h"
#include "komposeglobal.h"
#include "komposesettings.h"
#include <tqpixmap.h>
#include <tqimage.h>
#include <tqpainter.h>
#include <tqdragobject.h>
#include <tqapplication.h>
#include <tqtooltip.h>
#include <tqiconset.h>
#include <tqtimer.h>
#include <tqcolor.h>
#include <tqfont.h>
#include <kcursor.h>
#include <tdelocale.h>
#include <tdepopupmenu.h>
#include <tdeactioncollection.h>
#include <tdeaction.h>
#include <tdeapplication.h>
#include <kiconloader.h>
#include <kdebug.h>
#include "komposetaskvisualizer.h"
KomposeTaskWidget::KomposeTaskWidget(KomposeTask *t, TQWidget *parent, KomposeLayout *l, const char *name)
: KomposeWidget(parent, l, name),
highlight(false),
task(t)
{
setWFlags( WStaticContents | WRepaintNoErase | WResizeNoErase ); // avoid redraw errors
setBackgroundMode( TQt::NoBackground ); // avoid flickering
TQToolTip::add( this, task->visibleNameWithState() );
pm_dbBackground.setOptimization( TQPixmap::BestOptim );
setBackgroundMode( TQt::NoBackground );
//setBackgroundPixmap(pm_dbBackground);
initActions();
initMenu();
prefWidget = new KomposeTaskPrefsWidget( this, "Task prefs" );
prefWidget->hide();
setActionIcons();
//connect( t, SIGNAL( destroyed() ), this, SLOT( slotTaskDestroyed() ) );
connect( t, SIGNAL( closed() ), this, SLOT( slotTaskDestroyed() ) );
connect( t, SIGNAL( stateChanged() ), this, SLOT( drawWidgetAndRepaint() ) );
connect( t, SIGNAL( stateChanged() ), this, SLOT( reInitMenu() ) );
#ifdef COMPOSITE
if ( KomposeGlobal::instance()->hasXcomposite() && KomposeSettings::instance()->getUseComposite() )
{
connect( t, SIGNAL( x11DamageNotify() ), this, SLOT( drawWidgetAndRepaint() ) );
}
#endif
//setFocusPolicy(TQWidget::ClickFocus);
setFocusPolicy(TQWidget::StrongFocus);
initFonts();
}
KomposeTaskWidget::~KomposeTaskWidget()
{
prefWidget->deleteLater();
menu->deleteLater();
delete actMinimizeRestoreTask;
delete actCloseTask;
delete taskActionCollection;
}
void KomposeTaskWidget::reInitMenu()
{
delete menu;
initMenu();
}
void KomposeTaskWidget::initFonts()
{
titleFont = KomposeSettings::instance()->getWindowTitleFont();
}
void KomposeTaskWidget::slotTaskDestroyed()
{
disconnect( task, SIGNAL( closed() ), this, SLOT( slotTaskDestroyed() ) );
disconnect( task, SIGNAL( stateChanged() ), this, SLOT( drawWidgetAndRepaint() ) );
//if (KomposeViewManager::instance()->hasActiveView())
emit requestRemoval(this);
}
void KomposeTaskWidget::resizeEvent ( TQResizeEvent * e )
{
if ( e->oldSize() != e->size())
{
prefWidget->move(width() - prefWidget->width() - 3, 3);
drawWidgetAndRepaint();
}
KomposeWidget::resizeEvent( e );
}
void KomposeTaskWidget::paintEvent ( TQPaintEvent * )
{
if (size().height() < 40 ) // small hack that will prevent drawing on init
return;
if ( pm_dbBackground.isNull() )
drawWidget();
bitBlt( this, 0, 0, &pm_dbBackground, 0, 0, width(), height() );
}
void KomposeTaskWidget::drawWidgetAndRepaint()
{
if (size().height() < 40 ) // small hack that will prevent drawing on init
return;
drawWidget();
repaint();
}
void KomposeTaskWidget::drawWidget()
{
if ( !KomposeViewManager::instance()->hasActiveView() || !isShown() )
return;
pm_dbBackground.resize( width(), height() );
//pm_dbBackground.fill(white);
TQPainter p( &pm_dbBackground );
int effect = IEFFECT_NONE;
if ( KomposeSettings::instance()->getShowWindowTitles() && !task->isIconified() )
effect = IEFFECT_TITLE;
if ( KomposeSettings::instance()->getShowWindowTitles() && task->isIconified() )
effect = IEFFECT_MINIMIZED_AND_TITLE;
if ( !KomposeSettings::instance()->getShowWindowTitles() && task->isIconified() )
effect = IEFFECT_MINIMIZED;
// if ( highlight ) // I hate it, so I disable it!
// effect = IEFFECT_HIGHLIGHT;
task->getVisualizer()->renderOnPixmap(&pm_dbBackground, effect);
// Icon
TQPoint titleTextPos( 6, KomposeSettings::instance()->getWindowTitleFontHeight() + 1);
if ( KomposeSettings::instance()->getShowIcons() )
{
TQPixmap icon = task->getIcon( KomposeSettings::instance()->getIconSizePixels() );
// Place the icon left or under the text, according to it's size
if ( KomposeSettings::instance()->getIconSize() < 2 || icon.height() < 50 )
{
// Medium sized or tiny Icon
p.drawPixmap( TQPoint(5, 5), icon );
titleTextPos.setX(icon.width() + 10);
}
else
{
// Big Icon
p.drawPixmap( TQPoint(5, 5), icon );
// titleTextPos.setX(icon.width());
}
}
// Title
if ( KomposeSettings::instance()->getShowWindowTitles() )
{
p.setFont(titleFont);
if ( KomposeSettings::instance()->getShowWindowTitleShadow() )
{
p.setPen( KomposeSettings::instance()->getWindowTitleFontShadowColor() );
p.drawText( titleTextPos, task->visibleNameWithState() );
}
p.setPen( KomposeSettings::instance()->getWindowTitleFontColor() );
p.drawText( TQPoint( titleTextPos.x()-2, titleTextPos.y()-2 ), task->visibleNameWithState() );
}
// Border
TQColor borderColor;
int borderWidth, borderStyle;
if (highlight)
{
borderColor = KomposeSettings::instance()->getWindowBorderActiveColor();
borderWidth = KomposeSettings::instance()->getWindowBorderActiveWidth();
borderStyle = KomposeSettings::instance()->getWindowBorderActiveStyle();
}
else
{
borderColor = KomposeSettings::instance()->getWindowBorderInactiveColor();
borderWidth = KomposeSettings::instance()->getWindowBorderInactiveWidth();
borderStyle = KomposeSettings::instance()->getWindowBorderInactiveStyle();
}
TQPen pen(borderColor, borderWidth, static_cast<TQt::PenStyle>(borderStyle));
p.setPen(pen);
p.drawRect(rect());
p.end();
}
void KomposeTaskWidget::mouseReleaseEvent ( TQMouseEvent * e )
{
if ( !rect().contains( e->pos() ) )
return;
KomposeViewManager::instance()->activateTask( task );
}
void KomposeTaskWidget::mouseMoveEvent ( TQMouseEvent * e )
{
if ( e->state() == TQt::LeftButton )
startDrag();
}
// void KomposeTaskWidget::mouseDoubleClickEvent ( TQMouseEvent * e )
// {
// if ( !rect().contains( e->pos() ) )
// return;
// KomposeTaskManager::instance()->activateTask( task );
// }
void KomposeTaskWidget::keyReleaseEvent ( TQKeyEvent * e )
{
if ( e->key() == TQt::Key_Return || e->key() == TQt::Key_Space )
{
kdDebug() << "KomposeTaskWidget::keyReleaseEvent - activating Task!" << endl;
e->accept();
KomposeViewManager::instance()->activateTask( task );
return;
}
else if ( e->key() == TQt::Key_C )
{
kdDebug() << "KomposeTaskWidget::keyReleaseEvent - closing Task!" << endl;
task->close();
e->accept();
}
else if ( e->key() == TQt::Key_M )
{
kdDebug() << "KomposeTaskWidget::keyReleaseEvent - toggling state!" << endl;
task->minimizeOrRestore();
e->accept();
}
else
{
kdDebug() << "KomposeTaskWidget::keyReleaseEvent - ignored..." << endl;
e->ignore();
}
KomposeWidget::keyReleaseEvent(e);
}
void KomposeTaskWidget::leaveEvent ( TQEvent * )
{
highlight = false;
unsetCursor();
// drawWidgetAndRepaint();
prefWidget->hide();
if ( parentWidget() )
parentWidget()->setFocus();
}
void KomposeTaskWidget::enterEvent ( TQEvent * )
{
setFocus();
setCursor( KCursor::handCursor() );
highlight = true;
// drawWidgetAndRepaint();
prefWidget->show();
}
void KomposeTaskWidget::focusInEvent ( TQFocusEvent * )
{
highlight = true;
drawWidgetAndRepaint();
}
void KomposeTaskWidget::focusOutEvent ( TQFocusEvent * )
{
highlight = false;
drawWidgetAndRepaint();
}
int KomposeTaskWidget::getHeightForWidth ( int w ) const
{
//kdDebug() << "KomposeTaskWidget::getHeightForWidth()");
return task->getHeightForWidth(w);
}
int KomposeTaskWidget::getWidthForHeight ( int h ) const
{
//kdDebug() << "KomposeTaskWidget::getWidthForHeight()");
return task->getWidthForHeight(h);
}
double KomposeTaskWidget::getAspectRatio()
{
//kdDebug() << "KomposeTaskWidget::getAspectRatio()");
return task->getAspectRatio();
}
void KomposeTaskWidget::startDrag()
{
// The text is just a dummy
// FIXME: Maybe we should us a "Task"-Mimetype
TQDragObject *d = new TQTextDrag( "toDesktop()", this );
d->dragCopy();
}
void KomposeTaskWidget::setGeometry( const TQRect &rect )
{
int width = task->getGeometry().width();
int height = task->getGeometry().height();
// Don't scale images bigger than they actually are
if ( rect.width() > width || rect.height() > height )
{
TQWidget::setGeometry( TQRect( rect.left(), rect.top(), width, height ) );
}
else
TQWidget::setGeometry( rect );
}
void KomposeTaskWidget::initActions()
{
taskActionCollection = new TDEActionCollection( this );
actCloseTask = new TDEAction( i18n("Close"), "window-close", Key_Delete , task,
SLOT( close() ), taskActionCollection, "closeTask" );
actCloseTask->setToolTip(i18n("Close"));
actMinimizeRestoreTask = new TDEAction( i18n("Minimize/Restore"), "", TDEShortcut() , this,
SLOT( slotMinimizeRestoreToggled() ), taskActionCollection, "minimizeRestoreTask" );
}
void KomposeTaskWidget::initMenu()
{
menu = new TDEPopupMenu();
actMinimizeRestoreTask->plug(menu);
// toDesktop menu
TQPopupMenu* m = new TQPopupMenu( this );
m->setCheckable( true );
int id = m->insertItem( i18n("&All Desktops"), task, SLOT( toDesktop(int) ) );
m->setItemParameter( id, 0 ); // 0 means all desktops
m->setItemChecked( id, task->isOnAllDesktops() );
m->insertSeparator();
for( int i = 1; i <= KomposeTaskManager::instance()->getNumDesktops(); i++ )
{
TQString name = TQString( "&%1 %2" ).arg( i ).arg( KomposeTaskManager::instance()->getDesktopName( i ).replace( '&', "&&" ) );
id = m->insertItem( name, task, SLOT( toDesktop(int) ) );
m->setItemParameter( id, i );
m->setItemChecked( id, !task->isOnAllDesktops() && task->onDesktop() == i );
}
menu->insertItem(i18n("To &Desktop"), m);
menu->insertSeparator();
actCloseTask->plug(menu);
}
/**
* Set the toggle icons for some actions
*
* The inverse flag is a hack to allow toggling of the icons when the minimized/restored event
* hasn't yet reached the Task object ( which is the case on buttonpress)
*/
void KomposeTaskWidget::setActionIcons( bool inverse )
{
kdDebug() << "setIconSet" << endl;
if ( ( task->isIconified() && !inverse ) || ( !task->isIconified() && inverse ) )
actMinimizeRestoreTask->setIconSet( kapp->iconLoader()->loadIconSet ( "go-up", TDEIcon::NoGroup, 16 ) );
else
actMinimizeRestoreTask->setIconSet( kapp->iconLoader()->loadIconSet ( "go-bottom", TDEIcon::NoGroup, 16 ) );
}
void KomposeTaskWidget::slotMinimizeRestoreToggled()
{
setActionIcons( true );
task->minimizeOrRestore();
}
void KomposeTaskWidget::mousePressEvent ( TQMouseEvent * e )
{
if ( !rect().contains( e->pos() ) )
return;
switch ( e->button() )
{
case LeftButton:
break;
case MidButton:
// fall through
case RightButton:
menu->popup( e->globalPos() );
break;
default:
// nothing
break;
}
}
#include "komposetaskwidget.moc"