00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "partmanager.h"
00023
#include <kparts/event.h>
00024
#include <kparts/part.h>
00025
#include <kglobal.h>
00026
#include <kdebug.h>
00027
00028
#include <qapplication.h>
00029
00030
00031
00032
using namespace KParts;
00033
00034
template class QPtrList<Part>;
00035
00036
namespace KParts {
00037
00038
class PartManagerPrivate
00039 {
00040
public:
00041 PartManagerPrivate()
00042 {
00043 m_activeWidget = 0;
00044 m_activePart = 0;
00045 m_selectedPart = 0;
00046 m_selectedWidget = 0;
00047 m_bAllowNestedParts =
false;
00048 m_bIgnoreScrollBars =
false;
00049 m_activationButtonMask = Qt::LeftButton | Qt::MidButton | Qt::RightButton;
00050 m_reason = PartManager::NoReason;
00051 }
00052 ~PartManagerPrivate()
00053 {
00054 }
00055
void setReason(
QEvent* ev ) {
00056
switch( ev->type() ) {
00057
case QEvent::MouseButtonPress:
00058
case QEvent::MouseButtonDblClick: {
00059
QMouseEvent* mev = static_cast<QMouseEvent *>( ev );
00060 m_reason = mev->button() == Qt::LeftButton
00061 ? PartManager::ReasonLeftClick
00062 : ( mev->button() == Qt::MidButton
00063 ? PartManager::ReasonMidClick
00064 : PartManager::ReasonRightClick );
00065
break;
00066 }
00067
case QEvent::FocusIn:
00068 m_reason = static_cast<QFocusEvent *>( ev )->reason();
00069
break;
00070
default:
00071
kdWarning(1000) <<
"PartManagerPrivate::setReason got unexpected ev type " << ev->type() <<
endl;
00072
break;
00073 }
00074 }
00075
00076
Part * m_activePart;
00077
QWidget *m_activeWidget;
00078
00079
QPtrList<Part> m_parts;
00080
00081 PartManager::SelectionPolicy m_policy;
00082
00083
Part *m_selectedPart;
00084
QWidget *m_selectedWidget;
00085
00086
QPtrList<QWidget> m_managedTopLevelWidgets;
00087
short int m_activationButtonMask;
00088
bool m_bIgnoreScrollBars;
00089
bool m_bAllowNestedParts;
00090
int m_reason;
00091 };
00092
00093 }
00094
00095 PartManager::PartManager(
QWidget * parent,
const char * name )
00096 :
QObject( parent, name )
00097 {
00098 d =
new PartManagerPrivate;
00099
00100 qApp->installEventFilter(
this );
00101
00102 d->m_policy = Direct;
00103
00104
addManagedTopLevelWidget( parent );
00105 }
00106
00107 PartManager::PartManager(
QWidget *topLevel,
QObject *parent,
const char *name )
00108 :
QObject( parent, name )
00109 {
00110 d =
new PartManagerPrivate;
00111
00112 qApp->installEventFilter(
this );
00113
00114 d->m_policy = Direct;
00115
00116
addManagedTopLevelWidget( topLevel );
00117 }
00118
00119 PartManager::~PartManager()
00120 {
00121
for (
QPtrListIterator<QWidget> it( d->m_managedTopLevelWidgets );
00122 it.current(); ++it )
00123 disconnect( it.current(), SIGNAL( destroyed() ),
00124
this, SLOT( slotManagedTopLevelWidgetDestroyed() ) );
00125
00126
for (
QPtrListIterator<Part> it( d->m_parts ); it.current(); ++it )
00127 {
00128 it.current()->setManager( 0 );
00129 }
00130
00131
00132 qApp->removeEventFilter(
this );
00133
delete d;
00134 }
00135
00136 void PartManager::setSelectionPolicy( SelectionPolicy policy )
00137 {
00138 d->m_policy = policy;
00139 }
00140
00141 PartManager::SelectionPolicy
PartManager::selectionPolicy()
const
00142
{
00143
return d->m_policy;
00144 }
00145
00146 void PartManager::setAllowNestedParts(
bool allow )
00147 {
00148 d->m_bAllowNestedParts = allow;
00149 }
00150
00151
bool PartManager::allowNestedParts()
const
00152
{
00153
return d->m_bAllowNestedParts;
00154 }
00155
00156 void PartManager::setIgnoreScrollBars(
bool ignore )
00157 {
00158 d->m_bIgnoreScrollBars = ignore;
00159 }
00160
00161
bool PartManager::ignoreScrollBars()
const
00162
{
00163
return d->m_bIgnoreScrollBars;
00164 }
00165
00166 void PartManager::setActivationButtonMask(
short int buttonMask )
00167 {
00168 d->m_activationButtonMask = buttonMask;
00169 }
00170
00171 short int PartManager::activationButtonMask()
const
00172
{
00173
return d->m_activationButtonMask;
00174 }
00175
00176
bool PartManager::eventFilter(
QObject *obj,
QEvent *ev )
00177 {
00178
00179
if ( ev->type() != QEvent::MouseButtonPress &&
00180 ev->type() != QEvent::MouseButtonDblClick &&
00181 ev->type() != QEvent::FocusIn )
00182
return false;
00183
00184
if ( !obj->isWidgetType() )
00185
return false;
00186
00187
QWidget *w = static_cast<QWidget *>( obj );
00188
00189
if ( ( w->testWFlags( WType_Dialog ) && w->isModal() ) ||
00190 w->testWFlags( WType_Popup ) || w->testWFlags( WStyle_Tool ) )
00191
return false;
00192
00193
QMouseEvent* mev = 0L;
00194
if ( ev->type() == QEvent::MouseButtonPress || ev->type() == QEvent::MouseButtonDblClick )
00195 {
00196 mev = static_cast<QMouseEvent *>( ev );
00197
#ifdef DEBUG_PARTMANAGER
00198
kdDebug(1000) <<
"PartManager::eventFilter button: " << mev->button() <<
" " <<
"d->m_activationButtonMask=" << d->m_activationButtonMask <<
endl;
00199
#endif
00200
if ( ( mev->button() & d->m_activationButtonMask ) == 0 )
00201
return false;
00202 }
00203
00204
Part * part;
00205
while ( w )
00206 {
00207
QPoint pos;
00208
00209
if ( !d->m_managedTopLevelWidgets.containsRef( w->topLevelWidget() ) )
00210
return false;
00211
00212
if ( d->m_bIgnoreScrollBars && w->inherits(
"QScrollBar" ) )
00213
return false;
00214
00215
if ( mev )
00216 {
00217 pos = mev->globalPos();
00218 part = findPartFromWidget( w, pos );
00219 }
else
00220 part = findPartFromWidget( w );
00221
00222
#ifdef DEBUG_PARTMANAGER
00223
QCString evType = ( ev->type() == QEvent::MouseButtonPress ) ?
"MouseButtonPress"
00224 : ( ev->type() == QEvent::MouseButtonDblClick ) ?
"MouseButtonDblClick"
00225 : ( ev->type() == QEvent::FocusIn ) ?
"FocusIn" :
"OTHER! ERROR!";
00226
#endif
00227
if ( part )
00228 {
00229
if ( d->m_policy == PartManager::TriState )
00230 {
00231
if ( ev->type() == QEvent::MouseButtonDblClick )
00232 {
00233
if ( part == d->m_activePart && w == d->m_activeWidget )
00234
return false;
00235
00236
#ifdef DEBUG_PARTMANAGER
00237
kdDebug(1000) <<
"PartManager::eventFilter dblclick -> setActivePart" << part <<
endl;
00238
#endif
00239
d->setReason( ev );
00240
setActivePart( part, w );
00241 d->m_reason = NoReason;
00242
return true;
00243 }
00244
00245
if ( ( d->m_selectedWidget != w || d->m_selectedPart != part ) &&
00246 ( d->m_activeWidget != w || d->m_activePart != part ) )
00247 {
00248
if ( part->
isSelectable() )
00249
setSelectedPart( part, w );
00250
else {
00251
#ifdef DEBUG_PARTMANAGER
00252
kdDebug(1000) <<
"Part " << part <<
" (non-selectable) made active because " << w->className() <<
" got event" <<
" " << evType <<
endl;
00253
#endif
00254
d->setReason( ev );
00255
setActivePart( part, w );
00256 d->m_reason = NoReason;
00257 }
00258
return true;
00259 }
00260
else if ( d->m_selectedWidget == w && d->m_selectedPart == part )
00261 {
00262
#ifdef DEBUG_PARTMANAGER
00263
kdDebug(1000) <<
"Part " << part <<
" made active (from selected) because " << w->className() <<
" got event" <<
" " << evType <<
endl;
00264
#endif
00265
d->setReason( ev );
00266
setActivePart( part, w );
00267 d->m_reason = NoReason;
00268
return true;
00269 }
00270
else if ( d->m_activeWidget == w && d->m_activePart == part )
00271 {
00272
setSelectedPart( 0L );
00273
return false;
00274 }
00275
00276
return false;
00277 }
00278
else if ( part != d->m_activePart )
00279 {
00280
#ifdef DEBUG_PARTMANAGER
00281
kdDebug(1000) <<
"Part " << part <<
" made active because " << w->className() <<
" got event" <<
" " << evType <<
endl;
00282
#endif
00283
d->setReason( ev );
00284
setActivePart( part, w );
00285 d->m_reason = NoReason;
00286 }
00287
00288
return false;
00289 }
00290
00291 w = w->parentWidget();
00292
00293
if ( w && ( ( w->testWFlags( WType_Dialog ) && w->isModal() ) ||
00294 w->testWFlags( WType_Popup ) || w->testWFlags( WStyle_Tool ) ) )
00295 {
00296
#ifdef DEBUG_PARTMANAGER
00297
kdDebug(1000) <<
QString(
"No part made active although %1/%2 got event - loop aborted").arg(obj->name()).arg(obj->className()) <<
endl;
00298
#endif
00299
return false;
00300 }
00301
00302 }
00303
00304
#ifdef DEBUG_PARTMANAGER
00305
kdDebug(1000) <<
QString(
"No part made active although %1/%2 got event").arg(obj->name()).arg(obj->className()) <<
endl;
00306
#endif
00307
return false;
00308 }
00309
00310
Part * PartManager::findPartFromWidget(
QWidget * widget,
const QPoint &pos )
00311 {
00312
QPtrListIterator<Part> it ( d->m_parts );
00313
for ( ; it.current() ; ++it )
00314 {
00315
Part *part = it.current()->hitTest( widget, pos );
00316
if ( part && d->m_parts.findRef( part ) != -1 )
00317
return part;
00318 }
00319
return 0L;
00320 }
00321
00322
Part * PartManager::findPartFromWidget(
QWidget * widget )
00323 {
00324
QPtrListIterator<Part> it ( d->m_parts );
00325
for ( ; it.current() ; ++it )
00326 {
00327
if ( widget == it.current()->widget() )
00328
return it.current();
00329 }
00330
return 0L;
00331 }
00332
00333 void PartManager::addPart(
Part *part,
bool setActive )
00334 {
00335
if ( d->m_parts.findRef( part ) != -1 )
00336 {
00337
#ifdef DEBUG_PARTMANAGER
00338
kdWarning(1000) <<
k_funcinfo << part <<
" already added" <<
kdBacktrace(5) <<
endl;
00339
#endif
00340
return;
00341 }
00342
00343 d->m_parts.append( part );
00344
00345 part->
setManager(
this );
00346
00347
if ( setActive )
00348 {
00349
setActivePart( part );
00350
if ( part->
widget() )
00351 part->
widget()->setFocus();
00352 }
00353
00354
00355
if ( part->
widget() && part->
widget()->focusPolicy() == QWidget::NoFocus )
00356 {
00357
kdWarning(1000) <<
"Part '" << part->name() <<
"' has a widget " << part->
widget()->name() <<
" with a focus policy of NoFocus. It should have at least a ClickFocus policy, for part activation to work well." <<
endl;
00358 }
00359
if ( part->
widget() && part->
widget()->focusPolicy() == QWidget::TabFocus )
00360 {
00361
kdWarning(1000) <<
"Part '" << part->name() <<
"' has a widget " << part->
widget()->name() <<
" with a focus policy of TabFocus. It should have at least a ClickFocus policy, for part activation to work well." <<
endl;
00362 }
00363
00364
if ( part->
widget() )
00365 part->
widget()->show();
00366 emit
partAdded( part );
00367 }
00368
00369 void PartManager::removePart(
Part *part )
00370 {
00371
if ( d->m_parts.findRef( part ) == -1 )
00372 {
00373
kdFatal(1000) <<
QString(
"Can't remove part %1, not in KPartManager's list.").arg(part->name()) <<
endl;
00374
return;
00375 }
00376
00377
00378
00379
int nb = d->m_parts.count();
00380
bool ok = d->m_parts.removeRef( part );
00381 Q_ASSERT( ok );
00382 Q_ASSERT( (
int)d->m_parts.count() == nb-1 );
00383 part->
setManager(0);
00384
00385 emit
partRemoved( part );
00386
00387
if ( part == d->m_activePart )
00388
setActivePart( 0 );
00389
if ( part == d->m_selectedPart )
00390
setSelectedPart( 0 );
00391 }
00392
00393 void PartManager::replacePart(
Part * oldPart,
Part * newPart,
bool setActive )
00394 {
00395
00396
00397
if ( d->m_parts.findRef( oldPart ) == -1 )
00398 {
00399
kdFatal(1000) <<
QString(
"Can't remove part %1, not in KPartManager's list.").arg(oldPart->name()) <<
endl;
00400
return;
00401 }
00402
00403 d->m_parts.removeRef( oldPart );
00404 oldPart->
setManager(0);
00405
00406 emit
partRemoved( oldPart );
00407
00408
addPart( newPart, setActive );
00409 }
00410
00411 void PartManager::setActivePart(
Part *part,
QWidget *widget )
00412 {
00413
if ( part && d->m_parts.findRef( part ) == -1 )
00414 {
00415
kdWarning( 1000 ) <<
"PartManager::setActivePart : trying to activate a non-registered part! " << part->name() <<
endl;
00416
return;
00417 }
00418
00419
00420
00421
if ( part && !d->m_bAllowNestedParts )
00422 {
00423
QObject *parentPart = part->parent();
00424
if ( parentPart && parentPart->inherits(
"KParts::Part" ) )
00425 {
00426
KParts::Part *parPart = static_cast<KParts::Part *>( parentPart );
00427
setActivePart( parPart, parPart->
widget() );
00428
return;
00429 }
00430 }
00431
00432
#ifdef DEBUG_PARTMANAGER
00433
kdDebug(1000) <<
"PartManager::setActivePart d->m_activePart=" << d->m_activePart <<
"<->part=" << part
00434 <<
" d->m_activeWidget=" << d->m_activeWidget <<
"<->widget=" << widget <<
endl;
00435
#endif
00436
00437
00438
if ( d->m_activePart && part && d->m_activePart == part &&
00439 (!widget || d->m_activeWidget == widget) )
00440
return;
00441
00442
KParts::Part *oldActivePart = d->m_activePart;
00443
QWidget *oldActiveWidget = d->m_activeWidget;
00444
00445
setSelectedPart( 0L );
00446
00447 d->m_activePart = part;
00448 d->m_activeWidget = widget;
00449
00450
if ( oldActivePart )
00451 {
00452
KParts::Part *savedActivePart = part;
00453
QWidget *savedActiveWidget = widget;
00454
00455
PartActivateEvent ev(
false, oldActivePart, oldActiveWidget );
00456 QApplication::sendEvent( oldActivePart, &ev );
00457
if ( oldActiveWidget )
00458 {
00459 disconnect( oldActiveWidget, SIGNAL( destroyed() ),
00460
this, SLOT( slotWidgetDestroyed() ) );
00461 QApplication::sendEvent( oldActiveWidget, &ev );
00462 }
00463
00464 d->m_activePart = savedActivePart;
00465 d->m_activeWidget = savedActiveWidget;
00466 }
00467
00468
if ( d->m_activePart )
00469 {
00470
if ( !widget )
00471 d->m_activeWidget = part->
widget();
00472
00473
PartActivateEvent ev(
true, d->m_activePart, d->m_activeWidget );
00474 QApplication::sendEvent( d->m_activePart, &ev );
00475
if ( d->m_activeWidget )
00476 {
00477 connect( d->m_activeWidget, SIGNAL( destroyed() ),
00478
this, SLOT( slotWidgetDestroyed() ) );
00479 QApplication::sendEvent( d->m_activeWidget, &ev );
00480 }
00481 }
00482
00483
setActiveInstance( d->m_activePart ? d->m_activePart->instance() : 0L );
00484
00485
kdDebug(1000) <<
this <<
" emitting activePartChanged " << d->m_activePart <<
endl;
00486 emit
activePartChanged( d->m_activePart );
00487 }
00488
00489 void PartManager::setActiveInstance(
KInstance * instance )
00490 {
00491
00492 KGlobal::_activeInstance = instance;
00493 }
00494
00495 Part *
PartManager::activePart()
const
00496
{
00497
return d->m_activePart;
00498 }
00499
00500 QWidget *
PartManager::activeWidget()
const
00501
{
00502
return d->m_activeWidget;
00503 }
00504
00505 void PartManager::setSelectedPart(
Part *part,
QWidget *widget )
00506 {
00507
if ( part == d->m_selectedPart && widget == d->m_selectedWidget )
00508
return;
00509
00510
Part *oldPart = d->m_selectedPart;
00511
QWidget *oldWidget = d->m_selectedWidget;
00512
00513 d->m_selectedPart = part;
00514 d->m_selectedWidget = widget;
00515
00516
if ( part && !widget )
00517 d->m_selectedWidget = part->
widget();
00518
00519
if ( oldPart )
00520 {
00521
PartSelectEvent ev(
false, oldPart, oldWidget );
00522 QApplication::sendEvent( oldPart, &ev );
00523 QApplication::sendEvent( oldWidget, &ev );
00524 }
00525
00526
if ( d->m_selectedPart )
00527 {
00528
PartSelectEvent ev(
true, d->m_selectedPart, d->m_selectedWidget );
00529 QApplication::sendEvent( d->m_selectedPart, &ev );
00530 QApplication::sendEvent( d->m_selectedWidget, &ev );
00531 }
00532 }
00533
00534 Part *
PartManager::selectedPart()
const
00535
{
00536
return d->m_selectedPart;
00537 }
00538
00539 QWidget *
PartManager::selectedWidget()
const
00540
{
00541
return d->m_selectedWidget;
00542 }
00543
00544 void PartManager::slotObjectDestroyed()
00545 {
00546
kdDebug(1000) <<
"KPartManager::slotObjectDestroyed()" <<
endl;
00547
removePart( const_cast<Part *>( static_cast<const Part *>( sender() ) ) );
00548 }
00549
00550
void PartManager::slotWidgetDestroyed()
00551 {
00552
kdDebug(1000) <<
"KPartsManager::slotWidgetDestroyed()" <<
endl;
00553
if ( static_cast<const QWidget *>( sender() ) == d->m_activeWidget )
00554
setActivePart( 0L );
00555
00556 }
00557
00558 const QPtrList<Part> *
PartManager::parts()
const
00559
{
00560
return &d->m_parts;
00561 }
00562
00563 void PartManager::addManagedTopLevelWidget(
const QWidget *topLevel )
00564 {
00565
if ( !topLevel->isTopLevel() )
00566
return;
00567
00568
if ( d->m_managedTopLevelWidgets.containsRef( topLevel ) )
00569
return;
00570
00571 d->m_managedTopLevelWidgets.append( topLevel );
00572 connect( topLevel, SIGNAL( destroyed() ),
00573
this, SLOT( slotManagedTopLevelWidgetDestroyed() ) );
00574 }
00575
00576 void PartManager::removeManagedTopLevelWidget(
const QWidget *topLevel )
00577 {
00578
if ( !topLevel->isTopLevel() )
00579
return;
00580
00581
if ( d->m_managedTopLevelWidgets.findRef( topLevel ) == -1 )
00582
return;
00583
00584 d->m_managedTopLevelWidgets.remove();
00585 }
00586
00587
void PartManager::slotManagedTopLevelWidgetDestroyed()
00588 {
00589
const QWidget *widget = static_cast<const QWidget *>( sender() );
00590
removeManagedTopLevelWidget( widget );
00591 }
00592
00593 int PartManager::reason()
const
00594
{
00595
return d->m_reason;
00596 }
00597
00598
void PartManager::virtual_hook(
int,
void* )
00599 { }
00600
00601
#include "partmanager.moc"