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.
koffice/lib/kofficeui/KoContextCelp.cpp

596 lines
18 KiB

/* This file is part of the KDE project
Copyright (C) 2002, Benoit Vautrin <benoit.vautrin@free.fr>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "KoContextCelp.h"
#include <tqpainter.h>
#include <tqregion.h>
#include <tqfont.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqsimplerichtext.h>
#include <kpixmap.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <kcursor.h>
#include <tdeapplication.h>
#include <tqstring.h>
KoVerticalLabel::KoVerticalLabel( TQWidget* parent, const char* name )
: TQWidget( parent, name, TQt::WRepaintNoErase )
{
TQFont f( font() );
f.setPointSize( f.pointSize() + 2 );
f.setBold( true );
setFont( f );
setBackgroundMode( PaletteLight );
} // KoVerticalLabel::KoVerticalLabel
KoVerticalLabel::~KoVerticalLabel()
{
} // KoVerticalLabel::~KoVerticalLabel
void KoVerticalLabel::setText( const TQString& text )
{
m_text = text;
TQFontMetrics fm( font() );
setMinimumSize( fm.height() + 2, fm.width( m_text ) + 4 );
update();
} // KoVerticalLabel::setText
void KoVerticalLabel::paintEvent( TQPaintEvent* )
{
KPixmap pm;
pm.resize( height(), width() );
TQPainter p( &pm );
p.fillRect( 0, 0, height(), width(), colorGroup().background() );
p.setFont( font() );
p.drawText( 0, 0, height(), width(), AlignCenter, m_text );
p.end();
TQPainter ap( this );
ap.rotate( 270. );
ap.translate( -height(), 0 );
ap.drawPixmap( 0, 0, pm );
} // KoVerticalLabel::paintEvent
static unsigned char upbits[] = { 0xc, 0x1e, 0x3f, 0x3f };
static unsigned char downbits[] = { 0x3f, 0x3f, 0x1e, 0xc };
KoHelpNavButton::KoHelpNavButton( NavDirection d, TQWidget* parent )
: TQWidget( parent )
{
m_pressed = false;
m_bitmap = TQBitmap( 8, 4, ( d == Up ? upbits : downbits ), true );
m_bitmap.setMask( m_bitmap );
setFixedSize( 8, 6 );
setBackgroundMode( PaletteLight );
} // KoHelpNavButton::KoHelpNavButton
void KoHelpNavButton::paintEvent( TQPaintEvent* )
{
TQPainter p( this );
if ( isEnabled() )
{
if ( m_pressed )
p.setPen( colorGroup().highlight() );
else
p.setPen( colorGroup().text() );
p.drawPixmap( 1, 1, m_bitmap );
}
} // KoHelpNavButton::paintEvent
void KoHelpNavButton::enterEvent( TQEvent* )
{
if ( isEnabled() )
emit pressed();
m_pressed = true;
update();
} // KoHelpNavButton::enterEvent
void KoHelpNavButton::leaveEvent( TQEvent* )
{
if ( isEnabled() )
emit released();
m_pressed = false;
update();
} // KoHelpNavButton::leaveEvent
static unsigned char notstickybits[] = { 0x8, 0x1e, 0xc, 0xa, 0x1 };
static unsigned char stickybits[] = { 0xe, 0x11, 0x15, 0x11, 0xe };
static unsigned char closebits[] = { 0x11, 0xa, 0x4, 0xa, 0x11 };
KoTinyButton::KoTinyButton( Action a, TQWidget* parent )
: TQWidget( parent ), m_action( a )
{
m_pressed = false;
m_toggled = false;
switch ( a )
{
case Sticky:
m_bitmap = TQBitmap( 5, 5, notstickybits, true );
break;
default:
m_bitmap = TQBitmap( 5, 5, closebits, true );
}
m_bitmap.setMask( m_bitmap );
setMinimumSize( 7, 7 );
setBackgroundMode( PaletteBackground );
} // KoTinyButton::KoTinyButton
void KoTinyButton::paintEvent( TQPaintEvent* )
{
TQPainter p( this );
if ( isEnabled() )
{
if ( m_pressed )
p.setPen( colorGroup().highlight() );
else
p.setPen( colorGroup().text() );
p.drawPixmap( width() / 2 - 2, 1, m_bitmap );
}
} // KoTinyButton::paintEvent
void KoTinyButton::mousePressEvent( TQMouseEvent* )
{
if ( isEnabled() )
{
m_pressed = true;
update();
}
} // KoTinyButton::mousePressEvent
void KoTinyButton::mouseReleaseEvent( TQMouseEvent* )
{
if ( isEnabled() && m_pressed )
{
m_pressed = false;
emit( clicked() );
if ( ( m_action == Sticky ) )
{
m_toggled = !m_toggled;
emit( toggled( m_toggled ) );
//switch ( m_action )
//{
// case Sticky:
m_bitmap = TQBitmap( 5, 5, ( m_toggled ? stickybits : notstickybits ), true );
//}
m_bitmap.setMask( m_bitmap );
}
update();
}
} // KoTinyButton::mouseReleaseEvent
KoHelpView::KoHelpView( TQWidget* parent )
: TQWidget( parent )
{
currentText = 0L;
setBackgroundMode( PaletteLight );
parent->installEventFilter( this );
setMouseTracking( true );
} // KoHelpView::KoHelpView
KoHelpView::~KoHelpView()
{
if ( currentText )
delete currentText;
} // KoHelpView::~KoHelpView
void KoHelpView::setText( const TQString& text )
{
if ( currentText )
delete currentText;
currentText = new TQSimpleRichText( text, font() );
currentText->setWidth( width() );
setFixedHeight( currentText->height() );
} // KoHelpView::setText
void KoHelpView::mousePressEvent( TQMouseEvent* e )
{
currentAnchor = currentText->anchorAt( e->pos() );
if ( !currentAnchor.isEmpty() )
e->accept();
else
e->ignore();
} // KoHelpView::mousePressEvent
void KoHelpView::mouseReleaseEvent( TQMouseEvent* e )
{
if ( ( !currentAnchor.isEmpty() ) && ( currentAnchor == currentText->anchorAt( e->pos() ) ) )
{
e->accept();
if (currentAnchor.startsWith("help://#")) {
//that's not really useful, since koffice documents can be embedded
kapp->invokeHelp(currentAnchor.right(currentAnchor.length()-8));
}
else
if (currentAnchor.startsWith("help://")) {
// that's the useful version of a help link
TQString helpapp=currentAnchor.right(currentAnchor.length()-7);
TQString helpanchor;
int pos;
if ((pos=helpapp.find("#"))!=-1) {
helpanchor=helpapp.right(helpapp.length()-pos-1);
helpapp=helpapp.left(pos);
}
kapp->invokeHelp(helpanchor,helpapp);
}
else
emit linkClicked( currentAnchor );
currentAnchor = "";
}
else
e->ignore();
} // KoHelpView::mouseReleaseEvent
void KoHelpView::mouseMoveEvent( TQMouseEvent* e )
{
if ( !currentText->anchorAt( e->pos() ).isEmpty() )
setCursor( KCursor::handCursor() );
else
setCursor( KCursor::arrowCursor() );
} // KoHelpView::mouseMove
bool KoHelpView::eventFilter( TQObject*, TQEvent* e )
{
if ( ( currentText ) && ( e->type() == TQEvent::Resize ) )
{
setFixedWidth( ( (TQResizeEvent*)e )->size().width() );
currentText->setWidth( width() );
setFixedHeight( currentText->height() );
return true;
}
return false;
} // KoHelpView::resizeEvent
void KoHelpView::paintEvent( TQPaintEvent* )
{
TQPainter p( this );
currentText->draw( &p, 0, 0, TQRect(), colorGroup() );
} // KoHelpView::paintEvent
KoHelpWidget::KoHelpWidget( TQString help, TQWidget* parent )
: TQWidget( parent )
{
TQGridLayout* layout = new TQGridLayout( this, 3, 3 );
layout->setMargin( 2 );
layout->addWidget( m_upButton = new KoHelpNavButton( KoHelpNavButton::Up, this ), 0, 1, AlignHCenter );
layout->addWidget( m_helpViewport = new TQWidget( this ), 1, 1 );
layout->addWidget( m_downButton = new KoHelpNavButton( KoHelpNavButton::Down, this ), 2, 1, AlignHCenter );
layout->addColSpacing( 0, 5 );
layout->addColSpacing( 2, 5 );
layout->setColStretch( 1, 1 );
m_helpView = new KoHelpView( m_helpViewport );
m_helpViewport->setBackgroundMode( PaletteLight );
setText( help );
setBackgroundMode( PaletteLight );
connect( m_upButton, TQT_SIGNAL( pressed() ), this, TQT_SLOT( startScrollingUp() ) );
connect( m_downButton, TQT_SIGNAL( pressed() ), this, TQT_SLOT( startScrollingDown() ) );
connect( m_upButton, TQT_SIGNAL( released() ), this, TQT_SLOT( stopScrolling() ) );
connect( m_downButton, TQT_SIGNAL( released() ), this, TQT_SLOT( stopScrolling() ) );
connect( m_helpView, TQT_SIGNAL( linkClicked( const TQString& ) ), this, TQT_SIGNAL( linkClicked( const TQString& ) ) );
} // KoHelpWidget::KoHelpWidget
void KoHelpWidget::updateButtons()
{
m_upButton->setEnabled( m_ypos < 0 );
m_downButton->setEnabled( m_helpViewport->height() - m_ypos < m_helpView->height() );
} // KoHelpWidget::updateButtons
void KoHelpWidget::setText( TQString text )
{
m_helpView->setText( text );
m_helpView->move( 0, 0 );
m_ypos = 0;
updateButtons();
} // KoHelpWidget::setText
void KoHelpWidget::resizeEvent( TQResizeEvent* )
{
updateButtons();
} // KoHelpWidget::resizeEvent
void KoHelpWidget::startScrollingUp()
{
if ( !m_upButton->isEnabled() )
return;
m_scrollDown = false;
startTimer( 80 );
} // KoHelpWidget::startScrollingUp
void KoHelpWidget::startScrollingDown()
{
if ( !m_downButton->isEnabled() )
return;
m_scrollDown = true;
startTimer( 80 );
} // KoHelpWidget::startScrollingDown
void KoHelpWidget::scrollUp()
{
if ( m_ypos > 0 )
stopScrolling();
else
{
m_ypos += 2;
m_helpViewport->scroll( 0, 2 );
m_helpViewport->update();
updateButtons();
}
} // KoHelpWidget::scrollUp()
void KoHelpWidget::scrollDown()
{
if ( m_helpViewport->height() - m_helpView->height() - m_ypos > 0 )
stopScrolling();
else
{
m_ypos -= 2;
m_helpViewport->scroll( 0, -2 );
m_helpViewport->update();
updateButtons();
}
} // KoHelpWidget::scrollUp()
void KoHelpWidget::timerEvent( TQTimerEvent* )
{
if ( m_scrollDown )
scrollDown();
else
scrollUp();
} // KoHelpWidget::timerEvent
void KoHelpWidget::stopScrolling()
{
this->killTimers();
} // KoHelpWidget::stopScrolling
KoContextHelpPopup::KoContextHelpPopup( TQWidget* parent )
: TQWidget( parent, "", WType_Dialog | WStyle_Customize | WStyle_NoBorder )
{
TQGridLayout* layout = new TQGridLayout( this );
TQHBoxLayout* buttonLayout;
layout->addWidget( m_helpIcon = new TQLabel( this ), 0, 0 );
layout->addWidget( m_helpTitle = new KoVerticalLabel( this ), 1, 0 );
buttonLayout = new TQHBoxLayout( layout );
//layout->addLayout( buttonLayout, 2, 0 );
layout->addMultiCellWidget( m_helpViewer = new KoHelpWidget( "", this ), 0, 2, 1, 1 );
buttonLayout->add( m_close = new KoTinyButton( KoTinyButton::Close, this ) );
buttonLayout->add( m_sticky = new KoTinyButton( KoTinyButton::Sticky, this ) );
layout->addColSpacing( 2, 2 );
layout->addRowSpacing( 3, 2 );
layout->setMargin( 3 );
layout->setSpacing( 1 );
layout->setRowStretch( 1, 1 );
buttonLayout->setSpacing( 1 );
setMinimumSize( 180, 180 );
m_isSticky = false;
setFocusPolicy( TQWidget::StrongFocus );
connect( m_close, TQT_SIGNAL( clicked() ), this, TQT_SIGNAL( wantsToBeClosed() ) );
connect( m_sticky, TQT_SIGNAL( toggled( bool ) ), this, TQT_SLOT( setSticky( bool ) ) );
connect( m_helpViewer, TQT_SIGNAL( linkClicked( const TQString& ) ), this, TQT_SIGNAL( linkClicked( const TQString& ) ) );
} // KoContextHelpPopup::KoContextHelpPopup
KoContextHelpPopup::~KoContextHelpPopup()
{
} // KoContextHelpPopup::~KoContextHelpPopup
void KoContextHelpPopup::setContextHelp( const TQString& title, const TQString& text, const TQPixmap* icon )
{
m_helpIcon->setPixmap( icon ? *icon : BarIcon( "help" ) );
m_helpTitle->setText( title );
m_helpViewer->setText( text );
} // KoContextHelpPopup::updateHelp
void KoContextHelpPopup::mousePressEvent( TQMouseEvent* e )
{
m_mousePos = e->globalPos() - pos();
} // KoContextHelpPopup::mousePressEvent
void KoContextHelpPopup::mouseMoveEvent( TQMouseEvent* e )
{
move( e->globalPos() - m_mousePos );
} // KoContextHelpPopup::mouseMoveEvent
void KoContextHelpPopup::resizeEvent( TQResizeEvent* )
{
TQBitmap mask( width(), height() );
TQPointArray a;
TQPainter p( &mask );
p.fillRect( 0, 0, width(), height(), color1 );
p.setPen( color0 );
p.setBrush( color0 );
p.drawLine( 0, 0, 0, 3 );
p.drawLine( 0, 0, 3, 0 );
p.drawPoint( 1, 1 );
a.setPoints( 3, 0, height() - 5, 4, height() - 1, 0, height() - 1 );
p.drawPolygon( a );
a.setPoints( 3, width() - 5, 0, width() - 1, 4, width() - 1, 0 );
p.drawPolygon( a );
p.drawLine( width() - 1, height() - 1, width() - 4, height() - 1 );
p.drawLine( width() - 1, height() - 1, width() - 1, height() - 4 );
p.drawPoint( width() - 2, height() - 2 );
p.drawPoint( 0, height() - 6 );
p.drawPoint( width() - 6, 0 );
p.drawPoint( width() - 5, height() - 3 );
p.drawPoint( width() - 3, height() - 5 );
p.setPen( NoPen );
p.setBrush( TQBrush( color0, Dense4Pattern ) );
p.drawRect( 0, height() - 2, width() - 1, height() - 1 );
p.drawRect( width() - 2, 0, width() - 1, height() - 1 );
p.drawRect( width() - 4, height() - 4, width() - 2, height() - 2 );
p.end();
setMask( TQRegion( mask ) );
} // KoContextHelpPopup::resizeEvent
void KoContextHelpPopup::paintEvent( TQPaintEvent* )
{
TQPainter p( this );
p.fillRect( 0, 0, width(), height(), colorGroup().light() );
p.setPen( black );
p.drawRect( 0, 0, width(), height() );
p.fillRect( width() - 3, 0, width() - 1, height() - 1, black );
p.fillRect( 0, height() - 3, width() - 1, height() - 1, black );
p.drawLine( 1, 2, 1, 3 );
p.drawLine( 2, 1, 3, 1 );
p.drawLine( width() - 4, 2, width() - 4, 3 );
p.drawLine( width() - 5, 1, width() - 6, 1 );
p.drawLine( 1, height() - 5, 1, height() - 6 );
p.drawLine( 2, height() - 4, 3, height() - 4 );
p.drawLine( width() - 4, height() - 5, width() - 4, height() - 6 );
p.drawLine( width() - 4, height() - 4, width() - 6, height() - 4 );
} // KoContextHelpPopup::paintEvent
void KoContextHelpPopup::windowActivationChange( bool )
{
if ( !isActiveWindow() && !m_isSticky )
emit wantsToBeClosed();
} // KoContestHelpPopup::windowActivationChange
void KoContextHelpPopup::keyPressEvent( TQKeyEvent* e )
{
switch ( e->key() )
{
/* case Key_Up:
m_helpViewer->startScrollingUp();
break;
case Key_Down:
m_helpViewer->startScrollingDown();
break;*/
case Key_Up:
m_helpViewer->scrollUp();
break;
case Key_Down:
m_helpViewer->scrollDown();
break;
}
} // KoContextHelpPopup::keyPressEvent
void KoContextHelpPopup::keyReleaseEvent( TQKeyEvent* e )
{
switch ( e->key() )
{
/*case Key_Up:
case Key_Down:
m_helpViewer->stopScrolling();
break;*/
case Key_Escape:
emit wantsToBeClosed();
break;
}
} // KoContextHelpPopup::keyPressEvent
KoContextHelpAction::KoContextHelpAction( TDEActionCollection* parent, TQWidget* /*popupParent*/ )
: TDEToggleAction( i18n( "Context Help" ), BarIcon( "help" ), TDEShortcut( "CTRL+SHIFT+F1" ), 0, 0, parent, "help_context" )
{
m_popup = new KoContextHelpPopup( 0L );
connect( m_popup, TQT_SIGNAL( wantsToBeClosed() ), this, TQT_SLOT( closePopup() ) );
connect( this, TQT_SIGNAL( toggled( bool ) ), m_popup, TQT_SLOT( setShown( bool ) ) );
connect( m_popup, TQT_SIGNAL( linkClicked( const TQString& ) ), this, TQT_SIGNAL( linkClicked( const TQString& ) ) );
} // KoContextHelpAction::KoContextHelpAction
KoContextHelpAction::~KoContextHelpAction()
{
delete m_popup;
} // KoContextHelpAction::~KoContextHelpAction
void KoContextHelpAction::updateHelp( const TQString& title, const TQString& text, const TQPixmap* icon )
{
m_popup->setContextHelp( title, text, icon );
} // KoContextHelpAction::updateHelp
void KoContextHelpAction::closePopup()
{
activate();
setChecked( false ); // For a unknown reason, this is needed...
} // KoContextHelpAction::closePopup
KoContextHelpWidget::KoContextHelpWidget( TQWidget* parent, const char* name )
: TQWidget( parent, name )
{
setCaption( i18n( "Context Help" ) );
TQGridLayout* layout = new TQGridLayout( this );
layout->addWidget( m_helpIcon = new TQLabel( this ), 0, 0 );
layout->addWidget( m_helpTitle = new KoVerticalLabel( this ), 1, 0 );
layout->addMultiCellWidget( m_helpViewer = new KoHelpWidget( "", this ), 0, 1, 1, 1 );
layout->setMargin( 2 );
layout->setSpacing( 1 );
layout->setRowStretch( 1, 1 );
this->setMinimumSize( 180, 120 );
this->show();
setContextHelp( i18n( "Context Help" ), i18n( "Here will be shown help according to your actions" ), 0 );
connect( m_helpViewer, TQT_SIGNAL( linkClicked( const TQString& ) ), this, TQT_SIGNAL( linkClicked( const TQString& ) ) );
} // KoContextHelpWidget::KoContextHelpWidget
KoContextHelpWidget::~KoContextHelpWidget()
{
} // KoContextHelpWidget::~KoContextHelpWidget
void KoContextHelpWidget::setContextHelp( const TQString& title, const TQString& text, const TQPixmap* icon )
{
m_helpIcon->setPixmap( icon ? *icon : BarIcon( "help" ) );
m_helpTitle->setText( title );
m_helpViewer->setText( text );
} // KoContextHelpWidget::updateHelp
KoContextHelpDocker::KoContextHelpDocker( TQWidget* parent, const char* name )
: TQDockWindow( parent, name )
{
setCaption( i18n( "Context Help" ) );
TQWidget* mainWidget = new TQWidget( this );
TQGridLayout* layout = new TQGridLayout( mainWidget );
layout->addWidget( m_helpIcon = new TQLabel( mainWidget ), 0, 0 );
layout->addWidget( m_helpTitle = new KoVerticalLabel( mainWidget ), 1, 0 );
layout->addMultiCellWidget( m_helpViewer = new KoHelpWidget( "", mainWidget ), 0, 1, 1, 1 );
layout->setMargin( 2 );
layout->setSpacing( 1 );
layout->setRowStretch( 1, 1 );
mainWidget->setMinimumSize( 180, 120 );
mainWidget->show();
setWidget( mainWidget );
setContextHelp( i18n( "Context Help" ), i18n( "Here will be shown help according to your actions" ), 0 );
connect( m_helpViewer, TQT_SIGNAL( linkClicked( const TQString& ) ), this, TQT_SIGNAL( linkClicked( const TQString& ) ) );
} // KoContextHelpDocker::KoContextHelpDocker
KoContextHelpDocker::~KoContextHelpDocker()
{
} // KoContextHelpDocker::~KoContextHelpDocker
void KoContextHelpDocker::setContextHelp( const TQString& title, const TQString& text, const TQPixmap* icon )
{
m_helpIcon->setPixmap( icon ? *icon : BarIcon( "help" ) );
m_helpTitle->setText( title );
m_helpViewer->setText( text );
} // KoContextHelpDocker::updateHelp
#include "KoContextCelp.moc"