00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "KoContextCelp.h"
00021
00022 #include <qpainter.h>
00023 #include <qregion.h>
00024 #include <qfont.h>
00025 #include <qlabel.h>
00026 #include <qlayout.h>
00027 #include <qsimplerichtext.h>
00028
00029 #include <kpixmap.h>
00030 #include <klocale.h>
00031 #include <kdebug.h>
00032 #include <kiconloader.h>
00033 #include <kcursor.h>
00034 #include <kapplication.h>
00035 #include <qstring.h>
00036
00037 KoVerticalLabel::KoVerticalLabel( QWidget* parent, const char* name )
00038 : QWidget( parent, name, Qt::WRepaintNoErase )
00039 {
00040 QFont f( font() );
00041 f.setPointSize( f.pointSize() + 2 );
00042 f.setBold( true );
00043 setFont( f );
00044 setBackgroundMode( PaletteLight );
00045 }
00046
00047 KoVerticalLabel::~KoVerticalLabel()
00048 {
00049 }
00050
00051 void KoVerticalLabel::setText( const QString& text )
00052 {
00053 m_text = text;
00054 QFontMetrics fm( font() );
00055 setMinimumSize( fm.height() + 2, fm.width( m_text ) + 4 );
00056 update();
00057 }
00058
00059 void KoVerticalLabel::paintEvent( QPaintEvent* )
00060 {
00061 KPixmap pm;
00062 pm.resize( height(), width() );
00063 QPainter p( &pm );
00064 p.fillRect( 0, 0, height(), width(), colorGroup().background() );
00065 p.setFont( font() );
00066 p.drawText( 0, 0, height(), width(), AlignCenter, m_text );
00067 p.end();
00068 QPainter ap( this );
00069 ap.rotate( 270. );
00070 ap.translate( -height(), 0 );
00071 ap.drawPixmap( 0, 0, pm );
00072 }
00073
00074 static unsigned char upbits[] = { 0xc, 0x1e, 0x3f, 0x3f };
00075 static unsigned char downbits[] = { 0x3f, 0x3f, 0x1e, 0xc };
00076
00077 KoHelpNavButton::KoHelpNavButton( NavDirection d, QWidget* parent )
00078 : QWidget( parent )
00079 {
00080 m_pressed = false;
00081 m_bitmap = QBitmap( 8, 4, ( d == Up ? upbits : downbits ), true );
00082 m_bitmap.setMask( m_bitmap );
00083 setFixedSize( 8, 6 );
00084 setBackgroundMode( PaletteLight );
00085 }
00086
00087 void KoHelpNavButton::paintEvent( QPaintEvent* )
00088 {
00089 QPainter p( this );
00090 if ( isEnabled() )
00091 {
00092 if ( m_pressed )
00093 p.setPen( colorGroup().highlight() );
00094 else
00095 p.setPen( colorGroup().text() );
00096 p.drawPixmap( 1, 1, m_bitmap );
00097 }
00098 }
00099
00100 void KoHelpNavButton::enterEvent( QEvent* )
00101 {
00102 if ( isEnabled() )
00103 emit pressed();
00104 m_pressed = true;
00105 update();
00106 }
00107
00108 void KoHelpNavButton::leaveEvent( QEvent* )
00109 {
00110 if ( isEnabled() )
00111 emit released();
00112 m_pressed = false;
00113 update();
00114 }
00115
00116 static unsigned char notstickybits[] = { 0x8, 0x1e, 0xc, 0xa, 0x1 };
00117 static unsigned char stickybits[] = { 0xe, 0x11, 0x15, 0x11, 0xe };
00118 static unsigned char closebits[] = { 0x11, 0xa, 0x4, 0xa, 0x11 };
00119
00120 KoTinyButton::KoTinyButton( Action a, QWidget* parent )
00121 : QWidget( parent ), m_action( a )
00122 {
00123 m_pressed = false;
00124 m_toggled = false;
00125 switch ( a )
00126 {
00127 case Sticky:
00128 m_bitmap = QBitmap( 5, 5, notstickybits, true );
00129 break;
00130
00131 default:
00132 m_bitmap = QBitmap( 5, 5, closebits, true );
00133 }
00134 m_bitmap.setMask( m_bitmap );
00135 setMinimumSize( 7, 7 );
00136 setBackgroundMode( PaletteBackground );
00137 }
00138
00139 void KoTinyButton::paintEvent( QPaintEvent* )
00140 {
00141 QPainter p( this );
00142 if ( isEnabled() )
00143 {
00144 if ( m_pressed )
00145 p.setPen( colorGroup().highlight() );
00146 else
00147 p.setPen( colorGroup().text() );
00148 p.drawPixmap( width() / 2 - 2, 1, m_bitmap );
00149 }
00150 }
00151
00152 void KoTinyButton::mousePressEvent( QMouseEvent* )
00153 {
00154 if ( isEnabled() )
00155 {
00156 m_pressed = true;
00157 update();
00158 }
00159 }
00160
00161 void KoTinyButton::mouseReleaseEvent( QMouseEvent* )
00162 {
00163 if ( isEnabled() && m_pressed )
00164 {
00165 m_pressed = false;
00166 emit( clicked() );
00167 if ( ( m_action == Sticky ) )
00168 {
00169 m_toggled = !m_toggled;
00170 emit( toggled( m_toggled ) );
00171
00172
00173
00174 m_bitmap = QBitmap( 5, 5, ( m_toggled ? stickybits : notstickybits ), true );
00175
00176 m_bitmap.setMask( m_bitmap );
00177 }
00178 update();
00179 }
00180 }
00181
00182 KoHelpView::KoHelpView( QWidget* parent )
00183 : QWidget( parent )
00184 {
00185 currentText = 0L;
00186 setBackgroundMode( PaletteLight );
00187 parent->installEventFilter( this );
00188 setMouseTracking( true );
00189 }
00190
00191 KoHelpView::~KoHelpView()
00192 {
00193 if ( currentText )
00194 delete currentText;
00195 }
00196
00197 void KoHelpView::setText( const QString& text )
00198 {
00199 if ( currentText )
00200 delete currentText;
00201 currentText = new QSimpleRichText( text, font() );
00202 currentText->setWidth( width() );
00203 setFixedHeight( currentText->height() );
00204 }
00205
00206 void KoHelpView::mousePressEvent( QMouseEvent* e )
00207 {
00208 currentAnchor = currentText->anchorAt( e->pos() );
00209 if ( !currentAnchor.isEmpty() )
00210 e->accept();
00211 else
00212 e->ignore();
00213 }
00214
00215 void KoHelpView::mouseReleaseEvent( QMouseEvent* e )
00216 {
00217 if ( ( !currentAnchor.isEmpty() ) && ( currentAnchor == currentText->anchorAt( e->pos() ) ) )
00218 {
00219 e->accept();
00220 if (currentAnchor.startsWith("help://#")) {
00221
00222 kapp->invokeHelp(currentAnchor.right(currentAnchor.length()-8));
00223 }
00224 else
00225 if (currentAnchor.startsWith("help://")) {
00226
00227 QString helpapp=currentAnchor.right(currentAnchor.length()-7);
00228 QString helpanchor;
00229 int pos;
00230 if ((pos=helpapp.find("#"))!=-1) {
00231 helpanchor=helpapp.right(helpapp.length()-pos-1);
00232 helpapp=helpapp.left(pos);
00233 }
00234 kapp->invokeHelp(helpanchor,helpapp);
00235 }
00236 else
00237 emit linkClicked( currentAnchor );
00238 currentAnchor = "";
00239 }
00240 else
00241 e->ignore();
00242 }
00243
00244 void KoHelpView::mouseMoveEvent( QMouseEvent* e )
00245 {
00246 if ( !currentText->anchorAt( e->pos() ).isEmpty() )
00247 setCursor( KCursor::handCursor() );
00248 else
00249 setCursor( KCursor::arrowCursor() );
00250 }
00251
00252 bool KoHelpView::eventFilter( QObject*, QEvent* e )
00253 {
00254 if ( ( currentText ) && ( e->type() == QEvent::Resize ) )
00255 {
00256 setFixedWidth( ( (QResizeEvent*)e )->size().width() );
00257 currentText->setWidth( width() );
00258 setFixedHeight( currentText->height() );
00259
00260 return true;
00261 }
00262 return false;
00263 }
00264
00265 void KoHelpView::paintEvent( QPaintEvent* )
00266 {
00267 QPainter p( this );
00268 currentText->draw( &p, 0, 0, QRect(), colorGroup() );
00269 }
00270
00271 KoHelpWidget::KoHelpWidget( QString help, QWidget* parent )
00272 : QWidget( parent )
00273 {
00274 QGridLayout* layout = new QGridLayout( this, 3, 3 );
00275 layout->setMargin( 2 );
00276 layout->addWidget( m_upButton = new KoHelpNavButton( KoHelpNavButton::Up, this ), 0, 1, AlignHCenter );
00277 layout->addWidget( m_helpViewport = new QWidget( this ), 1, 1 );
00278 layout->addWidget( m_downButton = new KoHelpNavButton( KoHelpNavButton::Down, this ), 2, 1, AlignHCenter );
00279 layout->addColSpacing( 0, 5 );
00280 layout->addColSpacing( 2, 5 );
00281 layout->setColStretch( 1, 1 );
00282
00283 m_helpView = new KoHelpView( m_helpViewport );
00284 m_helpViewport->setBackgroundMode( PaletteLight );
00285 setText( help );
00286
00287 setBackgroundMode( PaletteLight );
00288
00289 connect( m_upButton, SIGNAL( pressed() ), this, SLOT( startScrollingUp() ) );
00290 connect( m_downButton, SIGNAL( pressed() ), this, SLOT( startScrollingDown() ) );
00291 connect( m_upButton, SIGNAL( released() ), this, SLOT( stopScrolling() ) );
00292 connect( m_downButton, SIGNAL( released() ), this, SLOT( stopScrolling() ) );
00293 connect( m_helpView, SIGNAL( linkClicked( const QString& ) ), this, SIGNAL( linkClicked( const QString& ) ) );
00294 }
00295
00296 void KoHelpWidget::updateButtons()
00297 {
00298 m_upButton->setEnabled( m_ypos < 0 );
00299 m_downButton->setEnabled( m_helpViewport->height() - m_ypos < m_helpView->height() );
00300 }
00301
00302 void KoHelpWidget::setText( QString text )
00303 {
00304 m_helpView->setText( text );
00305 m_helpView->move( 0, 0 );
00306 m_ypos = 0;
00307 updateButtons();
00308 }
00309
00310 void KoHelpWidget::resizeEvent( QResizeEvent* )
00311 {
00312 updateButtons();
00313 }
00314
00315 void KoHelpWidget::startScrollingUp()
00316 {
00317 if ( !m_upButton->isEnabled() )
00318 return;
00319 m_scrollDown = false;
00320 startTimer( 80 );
00321 }
00322
00323 void KoHelpWidget::startScrollingDown()
00324 {
00325 if ( !m_downButton->isEnabled() )
00326 return;
00327 m_scrollDown = true;
00328 startTimer( 80 );
00329 }
00330
00331 void KoHelpWidget::scrollUp()
00332 {
00333 if ( m_ypos > 0 )
00334 stopScrolling();
00335 else
00336 {
00337 m_ypos += 2;
00338 m_helpViewport->scroll( 0, 2 );
00339 m_helpViewport->update();
00340 updateButtons();
00341 }
00342 }
00343
00344 void KoHelpWidget::scrollDown()
00345 {
00346 if ( m_helpViewport->height() - m_helpView->height() - m_ypos > 0 )
00347 stopScrolling();
00348 else
00349 {
00350 m_ypos -= 2;
00351 m_helpViewport->scroll( 0, -2 );
00352 m_helpViewport->update();
00353 updateButtons();
00354 }
00355 }
00356
00357 void KoHelpWidget::timerEvent( QTimerEvent* )
00358 {
00359 if ( m_scrollDown )
00360 scrollDown();
00361 else
00362 scrollUp();
00363 }
00364
00365 void KoHelpWidget::stopScrolling()
00366 {
00367 killTimers();
00368 }
00369
00370 KoContextHelpPopup::KoContextHelpPopup( QWidget* parent )
00371 : QWidget( parent, "", WType_Dialog | WStyle_Customize | WStyle_NoBorder )
00372 {
00373 QGridLayout* layout = new QGridLayout( this );
00374 QHBoxLayout* buttonLayout;
00375 layout->addWidget( m_helpIcon = new QLabel( this ), 0, 0 );
00376 layout->addWidget( m_helpTitle = new KoVerticalLabel( this ), 1, 0 );
00377 buttonLayout = new QHBoxLayout( layout );
00378
00379 layout->addMultiCellWidget( m_helpViewer = new KoHelpWidget( "", this ), 0, 2, 1, 1 );
00380 buttonLayout->add( m_close = new KoTinyButton( KoTinyButton::Close, this ) );
00381 buttonLayout->add( m_sticky = new KoTinyButton( KoTinyButton::Sticky, this ) );
00382 layout->addColSpacing( 2, 2 );
00383 layout->addRowSpacing( 3, 2 );
00384 layout->setMargin( 3 );
00385 layout->setSpacing( 1 );
00386 layout->setRowStretch( 1, 1 );
00387 buttonLayout->setSpacing( 1 );
00388 setMinimumSize( 180, 180 );
00389
00390 m_isSticky = false;
00391 setFocusPolicy( StrongFocus );
00392
00393 connect( m_close, SIGNAL( clicked() ), this, SIGNAL( wantsToBeClosed() ) );
00394 connect( m_sticky, SIGNAL( toggled( bool ) ), this, SLOT( setSticky( bool ) ) );
00395 connect( m_helpViewer, SIGNAL( linkClicked( const QString& ) ), this, SIGNAL( linkClicked( const QString& ) ) );
00396 }
00397
00398 KoContextHelpPopup::~KoContextHelpPopup()
00399 {
00400 }
00401
00402 void KoContextHelpPopup::setContextHelp( const QString& title, const QString& text, const QPixmap* icon )
00403 {
00404 m_helpIcon->setPixmap( icon ? *icon : BarIcon( "help" ) );
00405 m_helpTitle->setText( title );
00406 m_helpViewer->setText( text );
00407 }
00408
00409 void KoContextHelpPopup::mousePressEvent( QMouseEvent* e )
00410 {
00411 m_mousePos = e->globalPos() - pos();
00412 }
00413
00414 void KoContextHelpPopup::mouseMoveEvent( QMouseEvent* e )
00415 {
00416 move( e->globalPos() - m_mousePos );
00417 }
00418
00419 void KoContextHelpPopup::resizeEvent( QResizeEvent* )
00420 {
00421 QBitmap mask( width(), height() );
00422 QPointArray a;
00423 QPainter p( &mask );
00424 p.fillRect( 0, 0, width(), height(), color1 );
00425 p.setPen( color0 );
00426 p.setBrush( color0 );
00427 p.drawLine( 0, 0, 0, 3 );
00428 p.drawLine( 0, 0, 3, 0 );
00429 p.drawPoint( 1, 1 );
00430 a.setPoints( 3, 0, height() - 5, 4, height() - 1, 0, height() - 1 );
00431 p.drawPolygon( a );
00432 a.setPoints( 3, width() - 5, 0, width() - 1, 4, width() - 1, 0 );
00433 p.drawPolygon( a );
00434 p.drawLine( width() - 1, height() - 1, width() - 4, height() - 1 );
00435 p.drawLine( width() - 1, height() - 1, width() - 1, height() - 4 );
00436 p.drawPoint( width() - 2, height() - 2 );
00437 p.drawPoint( 0, height() - 6 );
00438 p.drawPoint( width() - 6, 0 );
00439 p.drawPoint( width() - 5, height() - 3 );
00440 p.drawPoint( width() - 3, height() - 5 );
00441 p.setPen( NoPen );
00442 p.setBrush( QBrush( color0, Dense4Pattern ) );
00443 p.drawRect( 0, height() - 2, width() - 1, height() - 1 );
00444 p.drawRect( width() - 2, 0, width() - 1, height() - 1 );
00445 p.drawRect( width() - 4, height() - 4, width() - 2, height() - 2 );
00446 p.end();
00447 setMask( QRegion( mask ) );
00448 }
00449
00450 void KoContextHelpPopup::paintEvent( QPaintEvent* )
00451 {
00452 QPainter p( this );
00453 p.fillRect( 0, 0, width(), height(), colorGroup().light() );
00454 p.setPen( black );
00455 p.drawRect( 0, 0, width(), height() );
00456 p.fillRect( width() - 3, 0, width() - 1, height() - 1, black );
00457 p.fillRect( 0, height() - 3, width() - 1, height() - 1, black );
00458 p.drawLine( 1, 2, 1, 3 );
00459 p.drawLine( 2, 1, 3, 1 );
00460 p.drawLine( width() - 4, 2, width() - 4, 3 );
00461 p.drawLine( width() - 5, 1, width() - 6, 1 );
00462 p.drawLine( 1, height() - 5, 1, height() - 6 );
00463 p.drawLine( 2, height() - 4, 3, height() - 4 );
00464 p.drawLine( width() - 4, height() - 5, width() - 4, height() - 6 );
00465 p.drawLine( width() - 4, height() - 4, width() - 6, height() - 4 );
00466 }
00467
00468 void KoContextHelpPopup::windowActivationChange( bool )
00469 {
00470 if ( !isActiveWindow() && !m_isSticky )
00471 emit wantsToBeClosed();
00472 }
00473
00474 void KoContextHelpPopup::keyPressEvent( QKeyEvent* e )
00475 {
00476 switch ( e->key() )
00477 {
00478
00479
00480
00481
00482
00483
00484
00485 case Key_Up:
00486 m_helpViewer->scrollUp();
00487 break;
00488
00489 case Key_Down:
00490 m_helpViewer->scrollDown();
00491 break;
00492 }
00493 }
00494
00495 void KoContextHelpPopup::keyReleaseEvent( QKeyEvent* e )
00496 {
00497 switch ( e->key() )
00498 {
00499
00500
00501
00502
00503
00504 case Key_Escape:
00505 emit wantsToBeClosed();
00506 break;
00507 }
00508 }
00509
00510 KoContextHelpAction::KoContextHelpAction( KActionCollection* parent, QWidget* )
00511 : KToggleAction( i18n( "Context Help" ), BarIcon( "help" ), KShortcut( "CTRL+SHIFT+F1" ), 0, 0, parent, "help_context" )
00512 {
00513 m_popup = new KoContextHelpPopup( 0L );
00514 connect( m_popup, SIGNAL( wantsToBeClosed() ), this, SLOT( closePopup() ) );
00515 connect( this, SIGNAL( toggled( bool ) ), m_popup, SLOT( setShown( bool ) ) );
00516 connect( m_popup, SIGNAL( linkClicked( const QString& ) ), this, SIGNAL( linkClicked( const QString& ) ) );
00517 }
00518
00519 KoContextHelpAction::~KoContextHelpAction()
00520 {
00521 delete m_popup;
00522 }
00523
00524 void KoContextHelpAction::updateHelp( const QString& title, const QString& text, const QPixmap* icon )
00525 {
00526 m_popup->setContextHelp( title, text, icon );
00527 }
00528
00529 void KoContextHelpAction::closePopup()
00530 {
00531 activate();
00532 setChecked( false );
00533 }
00534
00535
00536 KoContextHelpWidget::KoContextHelpWidget( QWidget* parent, const char* name )
00537 : QWidget( parent, name )
00538 {
00539 setCaption( i18n( "Context Help" ) );
00540 QGridLayout* layout = new QGridLayout( this );
00541 layout->addWidget( m_helpIcon = new QLabel( this ), 0, 0 );
00542 layout->addWidget( m_helpTitle = new KoVerticalLabel( this ), 1, 0 );
00543 layout->addMultiCellWidget( m_helpViewer = new KoHelpWidget( "", this ), 0, 1, 1, 1 );
00544 layout->setMargin( 2 );
00545 layout->setSpacing( 1 );
00546 layout->setRowStretch( 1, 1 );
00547 this->setMinimumSize( 180, 120 );
00548 this->show();
00549 setContextHelp( i18n( "Context Help" ), i18n( "Here will be shown help according to your actions" ), 0 );
00550 connect( m_helpViewer, SIGNAL( linkClicked( const QString& ) ), this, SIGNAL( linkClicked( const QString& ) ) );
00551 }
00552
00553 KoContextHelpWidget::~KoContextHelpWidget()
00554 {
00555 }
00556
00557 void KoContextHelpWidget::setContextHelp( const QString& title, const QString& text, const QPixmap* icon )
00558 {
00559 m_helpIcon->setPixmap( icon ? *icon : BarIcon( "help" ) );
00560 m_helpTitle->setText( title );
00561 m_helpViewer->setText( text );
00562 }
00563
00564
00565 KoContextHelpDocker::KoContextHelpDocker( QWidget* parent, const char* name )
00566 : QDockWindow( parent, name )
00567 {
00568 setCaption( i18n( "Context Help" ) );
00569 QWidget* mainWidget = new QWidget( this );
00570 QGridLayout* layout = new QGridLayout( mainWidget );
00571 layout->addWidget( m_helpIcon = new QLabel( mainWidget ), 0, 0 );
00572 layout->addWidget( m_helpTitle = new KoVerticalLabel( mainWidget ), 1, 0 );
00573 layout->addMultiCellWidget( m_helpViewer = new KoHelpWidget( "", mainWidget ), 0, 1, 1, 1 );
00574 layout->setMargin( 2 );
00575 layout->setSpacing( 1 );
00576 layout->setRowStretch( 1, 1 );
00577 mainWidget->setMinimumSize( 180, 120 );
00578 mainWidget->show();
00579 setWidget( mainWidget );
00580 setContextHelp( i18n( "Context Help" ), i18n( "Here will be shown help according to your actions" ), 0 );
00581 connect( m_helpViewer, SIGNAL( linkClicked( const QString& ) ), this, SIGNAL( linkClicked( const QString& ) ) );
00582 }
00583
00584 KoContextHelpDocker::~KoContextHelpDocker()
00585 {
00586 }
00587
00588 void KoContextHelpDocker::setContextHelp( const QString& title, const QString& text, const QPixmap* icon )
00589 {
00590 m_helpIcon->setPixmap( icon ? *icon : BarIcon( "help" ) );
00591 m_helpTitle->setText( title );
00592 m_helpViewer->setText( text );
00593 }
00594
00595 #include "KoContextCelp.moc"