27 #include <QtGui/QApplication>
28 #include <QtGui/QScrollBar>
33 using namespace KParts;
37 class PartManagerPrivate
46 m_bAllowNestedParts =
false;
47 m_bIgnoreScrollBars =
false;
48 m_activationButtonMask = Qt::LeftButton | Qt::MidButton | Qt::RightButton;
54 void setReason(
QEvent* ev ) {
55 switch( ev->type() ) {
56 case QEvent::MouseButtonPress:
57 case QEvent::MouseButtonDblClick: {
58 QMouseEvent* mev =
static_cast<QMouseEvent *
>( ev );
59 m_reason = mev->button() == Qt::LeftButton
61 : ( mev->button() == Qt::MidButton
67 m_reason =
static_cast<QFocusEvent *
>( ev )->reason();
70 kWarning(1000) <<
"PartManagerPrivate::setReason got unexpected ev type " << ev->type();
78 QList<Part *> m_parts;
85 QList<const QWidget *> m_managedTopLevelWidgets;
86 short int m_activationButtonMask;
87 bool m_bIgnoreScrollBars;
88 bool m_bAllowNestedParts;
95 :
QObject( parent ),d(new PartManagerPrivate)
98 qApp->installEventFilter(
this );
106 :
QObject( parent ),d(new PartManagerPrivate)
109 qApp->installEventFilter(
this );
118 foreach(
const QWidget* w, d->m_managedTopLevelWidgets )
120 disconnect( w, SIGNAL(destroyed()),
124 foreach(
Part* it, d->m_parts )
130 qApp->removeEventFilter(
this );
136 d->m_policy = policy;
146 d->m_bAllowNestedParts = allow;
151 return d->m_bAllowNestedParts;
156 d->m_bIgnoreScrollBars = ignore;
161 return d->m_bIgnoreScrollBars;
166 d->m_activationButtonMask = buttonMask;
171 return d->m_activationButtonMask;
177 if ( ev->type() != QEvent::MouseButtonPress &&
178 ev->type() != QEvent::MouseButtonDblClick &&
179 ev->type() != QEvent::FocusIn )
182 if ( !obj->isWidgetType() )
187 if ( ( ( w->windowFlags().testFlag(Qt::Dialog) ) && w->isModal() ) ||
188 ( w->windowFlags().testFlag(Qt::Popup) ) || ( w->windowFlags().testFlag(Qt::Tool) ) )
191 QMouseEvent* mev = 0;
192 if ( ev->type() == QEvent::MouseButtonPress || ev->type() == QEvent::MouseButtonDblClick )
194 mev =
static_cast<QMouseEvent *
>( ev );
195 #ifdef DEBUG_PARTMANAGER
196 kDebug(1000) <<
"PartManager::eventFilter button: " << mev->button() <<
" " <<
"d->m_activationButtonMask=" << d->m_activationButtonMask;
198 if ( ( mev->button() & d->m_activationButtonMask ) == 0 )
207 if ( !d->m_managedTopLevelWidgets.contains( w->topLevelWidget() ) )
210 if ( d->m_bIgnoreScrollBars && ::qobject_cast<QScrollBar *>(w) )
215 pos = mev->globalPos();
216 part = findPartFromWidget( w, pos );
218 part = findPartFromWidget( w );
220 #ifdef DEBUG_PARTMANAGER
221 const char* evType = ( ev->type() == QEvent::MouseButtonPress ) ?
"MouseButtonPress"
222 : ( ev->type() == QEvent::MouseButtonDblClick ) ?
"MouseButtonDblClick"
223 : ( ev->type() == QEvent::FocusIn ) ?
"FocusIn" :
"OTHER! ERROR!";
229 if ( ev->type() == QEvent::MouseButtonDblClick )
231 if ( part == d->m_activePart && w == d->m_activeWidget )
234 #ifdef DEBUG_PARTMANAGER
235 kDebug(1000) <<
"PartManager::eventFilter dblclick -> setActivePart" << part;
243 if ( ( d->m_selectedWidget != w || d->m_selectedPart != part ) &&
244 ( d->m_activeWidget != w || d->m_activePart != part ) )
249 #ifdef DEBUG_PARTMANAGER
250 kDebug(1000) <<
"Part " << part <<
" (non-selectable) made active because " << w->metaObject()->className() <<
" got event" <<
" " << evType;
258 else if ( d->m_selectedWidget == w && d->m_selectedPart == part )
260 #ifdef DEBUG_PARTMANAGER
261 kDebug(1000) <<
"Part " << part <<
" made active (from selected) because " << w->metaObject()->className() <<
" got event" <<
" " << evType;
268 else if ( d->m_activeWidget == w && d->m_activePart == part )
276 else if ( part != d->m_activePart )
278 #ifdef DEBUG_PARTMANAGER
279 kDebug(1000) <<
"Part " << part <<
" made active because " << w->metaObject()->className() <<
" got event" <<
" " << evType;
289 w = w->parentWidget();
291 if ( w && ( ( ( w->windowFlags() & Qt::Dialog ) && w->isModal() ) ||
292 ( w->windowFlags() & Qt::Popup ) || ( w->windowFlags() & Qt::Tool ) ) )
294 #ifdef DEBUG_PARTMANAGER
295 kDebug(1000) <<
QString(
"No part made active although %1/%2 got event - loop aborted").arg(obj->objectName()).arg(obj->metaObject()->className());
302 #ifdef DEBUG_PARTMANAGER
303 kDebug(1000) <<
QString(
"No part made active although %1/%2 got event").arg(obj->objectName()).arg(obj->metaObject()->className());
310 for ( QList<Part *>::iterator it = d->m_parts.begin(),
end = d->m_parts.end() ; it !=
end ; ++it )
313 if ( part && d->m_parts.contains( part ) )
319 Part * PartManager::findPartFromWidget(
QWidget * widget )
321 for ( QList<Part *>::iterator it = d->m_parts.begin(),
end = d->m_parts.end() ; it !=
end ; ++it )
323 if ( widget == (*it)->widget() )
334 if ( d->m_parts.contains( part ) ) {
335 #ifdef DEBUG_PARTMANAGER
336 kWarning(1000) << part <<
" already added" << kBacktrace(5);
341 d->m_parts.append( part );
350 if ( w->focusPolicy() == Qt::NoFocus ) {
351 kWarning(1000) <<
"Part '" << part->objectName() <<
"' has a widget "
352 << w->objectName() <<
" with a focus policy of NoFocus. It should have at least a"
353 <<
"ClickFocus policy, for part activation to work well." << endl;
355 if ( part->
widget() && part->
widget()->focusPolicy() == Qt::TabFocus ) {
356 kWarning(1000) <<
"Part '" << part->objectName() <<
"' has a widget "
357 << w->objectName() <<
" with a focus policy of TabFocus. It should have at least a"
358 <<
"ClickFocus policy, for part activation to work well." << endl;
369 if (!d->m_parts.contains(part)) {
373 const int nb = d->m_parts.removeAll(part);
380 if ( part == d->m_activePart )
382 if ( part == d->m_selectedPart )
390 if ( !d->m_parts.contains( oldPart ) )
392 kFatal(1000) <<
QString(
"Can't remove part %1, not in KPartManager's list.").arg(oldPart->objectName());
396 d->m_parts.removeAll( oldPart );
406 if ( part && !d->m_parts.contains( part ) )
408 kWarning(1000) <<
"trying to activate a non-registered part!" << part->objectName();
414 if ( part && !d->m_bAllowNestedParts )
416 QObject *parentPart = part->parent();
425 #ifdef DEBUG_PARTMANAGER
426 kDebug(1000) <<
"PartManager::setActivePart d->m_activePart=" << d->m_activePart <<
"<->part=" << part
427 <<
" d->m_activeWidget=" << d->m_activeWidget <<
"<->widget=" << widget << endl;
431 if ( d->m_activePart && part && d->m_activePart == part &&
432 (!widget || d->m_activeWidget == widget) )
436 QWidget *oldActiveWidget = d->m_activeWidget;
440 d->m_activePart = part;
441 d->m_activeWidget = widget;
446 QWidget *savedActiveWidget = widget;
449 QApplication::sendEvent( oldActivePart, &ev );
450 if ( oldActiveWidget )
452 disconnect( oldActiveWidget, SIGNAL(destroyed()),
454 QApplication::sendEvent( oldActiveWidget, &ev );
457 d->m_activePart = savedActivePart;
458 d->m_activeWidget = savedActiveWidget;
461 if ( d->m_activePart )
464 d->m_activeWidget = part->
widget();
467 QApplication::sendEvent( d->m_activePart, &ev );
468 if ( d->m_activeWidget )
470 connect( d->m_activeWidget, SIGNAL(destroyed()),
472 QApplication::sendEvent( d->m_activeWidget, &ev );
478 #ifdef DEBUG_PARTMANAGER
479 kDebug(1000) <<
this <<
" emitting activePartChanged " << d->m_activePart;
492 return d->m_activePart;
497 return d->m_activeWidget;
502 if ( part == d->m_selectedPart && widget == d->m_selectedWidget )
505 Part *oldPart = d->m_selectedPart;
506 QWidget *oldWidget = d->m_selectedWidget;
508 d->m_selectedPart = part;
509 d->m_selectedWidget = widget;
511 if ( part && !widget )
512 d->m_selectedWidget = part->
widget();
517 QApplication::sendEvent( oldPart, &ev );
518 QApplication::sendEvent( oldWidget, &ev );
521 if ( d->m_selectedPart )
524 QApplication::sendEvent( d->m_selectedPart, &ev );
525 QApplication::sendEvent( d->m_selectedWidget, &ev );
531 return d->m_selectedPart;
536 return d->m_selectedWidget;
542 removePart( const_cast<Part *>( static_cast<const Part *>( sender() ) ) );
548 if ( static_cast<const QWidget *>( sender() ) == d->m_activeWidget )
560 if ( !topLevel->isTopLevel() )
563 if ( d->m_managedTopLevelWidgets.contains( topLevel ) )
566 d->m_managedTopLevelWidgets.append( topLevel );
567 connect( topLevel, SIGNAL(destroyed()),
573 if ( !topLevel->isTopLevel() )
576 d->m_managedTopLevelWidgets.removeAll( topLevel );
590 #include "partmanager.moc"