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