summaryrefslogtreecommitdiffstats
path: root/src/komposetaskwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/komposetaskwidget.cpp')
-rw-r--r--src/komposetaskwidget.cpp427
1 files changed, 427 insertions, 0 deletions
diff --git a/src/komposetaskwidget.cpp b/src/komposetaskwidget.cpp
new file mode 100644
index 0000000..3d4abfe
--- /dev/null
+++ b/src/komposetaskwidget.cpp
@@ -0,0 +1,427 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Hans Oischinger *
+ * *
+ * 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 <qpixmap.h>
+#include <qimage.h>
+#include <qpainter.h>
+#include <qdragobject.h>
+#include <qapplication.h>
+#include <qtooltip.h>
+#include <qiconset.h>
+#include <qtimer.h>
+#include <qcolor.h>
+#include <qfont.h>
+
+#include <kcursor.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kactioncollection.h>
+#include <kaction.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+
+#include "komposetaskvisualizer.h"
+
+KomposeTaskWidget::KomposeTaskWidget(KomposeTask *t, QWidget *parent, KomposeLayout *l, const char *name)
+ : KomposeWidget(parent, l, name),
+ highlight(false),
+ task(t)
+{
+ setWFlags( WStaticContents | WRepaintNoErase | WResizeNoErase ); // avoid redraw errors
+ setBackgroundMode( Qt::NoBackground ); // avoid flickering
+
+ QToolTip::add( this, task->visibleNameWithState() );
+
+ pm_dbBackground.setOptimization( QPixmap::BestOptim );
+ setBackgroundMode( Qt::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(QWidget::ClickFocus);
+ setFocusPolicy(QWidget::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 ( QResizeEvent * e )
+{
+ if ( e->oldSize() != e->size())
+ {
+ prefWidget->move(width() - prefWidget->width() - 3, 3);
+ drawWidgetAndRepaint();
+ }
+ KomposeWidget::resizeEvent( e );
+}
+
+
+void KomposeTaskWidget::paintEvent ( QPaintEvent * )
+{
+ 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);
+
+ QPainter 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
+ QPoint titleTextPos( 6, KomposeSettings::instance()->getWindowTitleFontHeight() + 1);
+ if ( KomposeSettings::instance()->getShowIcons() )
+ {
+ QPixmap 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( QPoint(5, 5), icon );
+ titleTextPos.setX(icon.width() + 10);
+ }
+ else
+ {
+ // Big Icon
+ p.drawPixmap( QPoint(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( QPoint( titleTextPos.x()-2, titleTextPos.y()-2 ), task->visibleNameWithState() );
+ }
+
+ // Border
+ if (!highlight)
+ {
+ QPen pen( gray, 1, Qt::SolidLine );
+ p.setPen( pen );
+ p.drawRect(rect());
+ }
+ else
+ {
+ QPen pen( black, 2, Qt::DotLine );
+ p.setPen( pen );
+ p.drawRect( QRect( 1, 1, rect().width()-1, rect().height()-1 ) );
+ }
+
+ p.end();
+}
+
+void KomposeTaskWidget::mouseReleaseEvent ( QMouseEvent * e )
+{
+ if ( !rect().contains( e->pos() ) )
+ return;
+ KomposeViewManager::instance()->activateTask( task );
+}
+
+void KomposeTaskWidget::mouseMoveEvent ( QMouseEvent * e )
+{
+ if ( e->state() == Qt::LeftButton )
+ startDrag();
+}
+
+// void KomposeTaskWidget::mouseDoubleClickEvent ( QMouseEvent * e )
+// {
+// if ( !rect().contains( e->pos() ) )
+// return;
+// KomposeTaskManager::instance()->activateTask( task );
+// }
+
+void KomposeTaskWidget::keyReleaseEvent ( QKeyEvent * e )
+{
+ if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Space )
+ {
+ kdDebug() << "KomposeTaskWidget::keyReleaseEvent - activating Task!" << endl;
+ e->accept();
+ KomposeViewManager::instance()->activateTask( task );
+ return;
+ }
+ else if ( e->key() == Qt::Key_C )
+ {
+ kdDebug() << "KomposeTaskWidget::keyReleaseEvent - closing Task!" << endl;
+ task->close();
+ e->accept();
+ }
+ else if ( e->key() == Qt::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 ( QEvent * )
+{
+ highlight = false;
+ unsetCursor();
+// drawWidgetAndRepaint();
+
+ prefWidget->hide();
+ if ( parentWidget() )
+ parentWidget()->setFocus();
+}
+
+void KomposeTaskWidget::enterEvent ( QEvent * )
+{
+ setFocus();
+ setCursor( KCursor::handCursor() );
+ highlight = true;
+// drawWidgetAndRepaint();
+
+ prefWidget->show();
+}
+
+void KomposeTaskWidget::focusInEvent ( QFocusEvent * )
+{
+ highlight = true;
+ drawWidgetAndRepaint();
+}
+
+void KomposeTaskWidget::focusOutEvent ( QFocusEvent * )
+{
+ 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
+ QDragObject *d = new QTextDrag( "toDesktop()", this );
+ d->dragCopy();
+}
+
+void KomposeTaskWidget::setGeometry( const QRect &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 )
+ {
+ QWidget::setGeometry( QRect( rect.left(), rect.top(), width, height ) );
+ }
+ else
+ QWidget::setGeometry( rect );
+}
+
+void KomposeTaskWidget::initActions()
+{
+ taskActionCollection = new KActionCollection( this );
+
+ actCloseTask = new KAction( i18n("Close"), "fileclose", Key_Delete , task,
+ SLOT( close() ), taskActionCollection, "closeTask" );
+ actCloseTask->setToolTip(i18n("Close"));
+ actMinimizeRestoreTask = new KAction( i18n("Minimize/Restore"), "", KShortcut() , this,
+ SLOT( slotMinimizeRestoreToggled() ), taskActionCollection, "minimizeRestoreTask" );
+}
+
+void KomposeTaskWidget::initMenu()
+{
+ menu = new KPopupMenu();
+
+ actMinimizeRestoreTask->plug(menu);
+
+ // toDesktop menu
+ QPopupMenu* m = new QPopupMenu( 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++ )
+ {
+ QString name = QString( "&%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 )
+{
+ if ( ( task->isIconified() && !inverse ) || ( !task->isIconified() && inverse ) )
+ actMinimizeRestoreTask->setIconSet( kapp->iconLoader()->loadIconSet ( "up", KIcon::NoGroup, 16 ) );
+ else
+ actMinimizeRestoreTask->setIconSet( kapp->iconLoader()->loadIconSet ( "bottom", KIcon::NoGroup, 16 ) );
+}
+
+void KomposeTaskWidget::slotMinimizeRestoreToggled()
+{
+ setActionIcons( true );
+ task->minimizeOrRestore();
+}
+
+void KomposeTaskWidget::mousePressEvent ( QMouseEvent * 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"