00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "kocontexthelp.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* popupParent )
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 "kocontexthelp.moc"