/*************************************************************************** * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 if (!highlight) { TQPen pen( gray, 1, TQt::SolidLine ); p.setPen( pen ); p.drawRect(rect()); } else { TQPen pen( black, 2, TQt::DotLine ); p.setPen( pen ); p.drawRect( TQRect( 1, 1, rect().width()-1, rect().height()-1 ) ); } 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"), "fileclose", 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 ) { if ( ( task->isIconified() && !inverse ) || ( !task->isIconified() && inverse ) ) actMinimizeRestoreTask->setIconSet( kapp->iconLoader()->loadIconSet ( "up", TDEIcon::NoGroup, 16 ) ); else actMinimizeRestoreTask->setIconSet( kapp->iconLoader()->loadIconSet ( "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"