21 #include "partmanager.h"
22 #include <tdeparts/event.h>
23 #include <tdeparts/part.h>
24 #include <tdeglobal.h>
27 #include <tqapplication.h>
31 using namespace KParts;
33 template class TQPtrList<Part>;
37 class PartManagerPrivate
46 m_bAllowNestedParts =
false;
47 m_bIgnoreScrollBars =
false;
48 m_activationButtonMask = Qt::LeftButton | Qt::MidButton | Qt::RightButton;
49 m_reason = PartManager::NoReason;
54 void setReason( TQEvent* ev ) {
55 switch( ev->type() ) {
56 case TQEvent::MouseButtonPress:
57 case TQEvent::MouseButtonDblClick: {
58 TQMouseEvent* mev = TQT_TQMOUSEEVENT( ev );
59 m_reason = mev->button() == Qt::LeftButton
60 ? PartManager::ReasonLeftClick
61 : ( mev->button() == Qt::MidButton
62 ? PartManager::ReasonMidClick
63 : PartManager::ReasonRightClick );
66 case TQEvent::FocusIn:
67 m_reason = TQT_TQFOCUSEVENT( ev )->reason();
70 kdWarning(1000) <<
"PartManagerPrivate::setReason got unexpected ev type " << ev->type() <<
endl;
76 TQWidget *m_activeWidget;
78 TQPtrList<Part> m_parts;
83 TQWidget *m_selectedWidget;
85 TQPtrList<TQWidget> m_managedTopLevelWidgets;
86 short int m_activationButtonMask;
87 bool m_bIgnoreScrollBars;
88 bool m_bAllowNestedParts;
95 : TQObject( parent, name )
97 d =
new PartManagerPrivate;
99 tqApp->installEventFilter(
this );
101 d->m_policy = Direct;
107 : TQObject( parent, name )
109 d =
new PartManagerPrivate;
111 tqApp->installEventFilter(
this );
113 d->m_policy = Direct;
118 PartManager::~PartManager()
120 for ( TQPtrListIterator<TQWidget> it( d->m_managedTopLevelWidgets );
122 disconnect( it.current(), TQT_SIGNAL( destroyed() ),
123 this, TQT_SLOT( slotManagedTopLevelWidgetDestroyed() ) );
125 for ( TQPtrListIterator<Part> it( d->m_parts ); it.current(); ++it )
127 it.current()->setManager( 0 );
131 tqApp->removeEventFilter(
this );
137 d->m_policy = policy;
147 d->m_bAllowNestedParts = allow;
152 return d->m_bAllowNestedParts;
157 d->m_bIgnoreScrollBars = ignore;
162 return d->m_bIgnoreScrollBars;
167 d->m_activationButtonMask = buttonMask;
172 return d->m_activationButtonMask;
175 bool PartManager::eventFilter( TQObject *obj, TQEvent *ev )
178 if ( ev->type() != TQEvent::MouseButtonPress &&
179 ev->type() != TQEvent::MouseButtonDblClick &&
180 ev->type() != TQEvent::FocusIn )
183 if ( !obj->isWidgetType() )
186 TQWidget *w = TQT_TQWIDGET( obj );
188 if ( ( w->testWFlags( WType_Dialog ) && w->isModal() ) ||
189 w->testWFlags( WType_Popup ) || w->testWFlags( WStyle_Tool ) )
192 TQMouseEvent* mev = 0L;
193 if ( ev->type() == TQEvent::MouseButtonPress || ev->type() == TQEvent::MouseButtonDblClick )
195 mev = TQT_TQMOUSEEVENT( ev );
196 #ifdef DEBUG_PARTMANAGER
197 kdDebug(1000) <<
"PartManager::eventFilter button: " << mev->button() <<
" " <<
"d->m_activationButtonMask=" << d->m_activationButtonMask <<
endl;
199 if ( ( mev->button() & d->m_activationButtonMask ) == 0 )
208 if ( !d->m_managedTopLevelWidgets.containsRef( w->topLevelWidget() ) )
211 if ( d->m_bIgnoreScrollBars && w->inherits( TQSCROLLBAR_OBJECT_NAME_STRING ) )
216 pos = mev->globalPos();
217 part = findPartFromWidget( w, pos );
219 part = findPartFromWidget( w );
221 #ifdef DEBUG_PARTMANAGER
222 TQCString evType = ( ev->type() == TQEvent::MouseButtonPress ) ?
"MouseButtonPress"
223 : ( ev->type() == TQEvent::MouseButtonDblClick ) ?
"MouseButtonDblClick"
224 : ( ev->type() == TQEvent::FocusIn ) ?
"FocusIn" :
"OTHER! ERROR!";
228 if ( d->m_policy == PartManager::TriState )
230 if ( ev->type() == TQEvent::MouseButtonDblClick )
232 if ( part == d->m_activePart && w == d->m_activeWidget )
235 #ifdef DEBUG_PARTMANAGER
236 kdDebug(1000) <<
"PartManager::eventFilter dblclick -> setActivePart" << part <<
endl;
240 d->m_reason = NoReason;
244 if ( ( d->m_selectedWidget != w || d->m_selectedPart != part ) &&
245 ( d->m_activeWidget != w || d->m_activePart != part ) )
250 #ifdef DEBUG_PARTMANAGER
251 kdDebug(1000) <<
"Part " << part <<
" (non-selectable) made active because " << w->className() <<
" got event" <<
" " << evType <<
endl;
255 d->m_reason = NoReason;
259 else if ( d->m_selectedWidget == w && d->m_selectedPart == part )
261 #ifdef DEBUG_PARTMANAGER
262 kdDebug(1000) <<
"Part " << part <<
" made active (from selected) because " << w->className() <<
" got event" <<
" " << evType <<
endl;
266 d->m_reason = NoReason;
269 else if ( d->m_activeWidget == w && d->m_activePart == part )
277 else if ( part != d->m_activePart )
279 #ifdef DEBUG_PARTMANAGER
280 kdDebug(1000) <<
"Part " << part <<
" made active because " << w->className() <<
" got event" <<
" " << evType <<
endl;
284 d->m_reason = NoReason;
290 w = w->parentWidget();
292 if ( w && ( ( w->testWFlags( WType_Dialog ) && w->isModal() ) ||
293 w->testWFlags( WType_Popup ) || w->testWFlags( WStyle_Tool ) ) )
295 #ifdef DEBUG_PARTMANAGER
296 kdDebug(1000) << TQString(
"No part made active although %1/%2 got event - loop aborted").arg(obj->name()).arg(obj->className()) << endl;
303 #ifdef DEBUG_PARTMANAGER
304 kdDebug(1000) << TQString(
"No part made active although %1/%2 got event").arg(obj->name()).arg(obj->className()) << endl;
309 Part * PartManager::findPartFromWidget( TQWidget * widget,
const TQPoint &pos )
311 TQPtrListIterator<Part> it ( d->m_parts );
312 for ( ; it.current() ; ++it )
315 if ( part && d->m_parts.findRef( part ) != -1 )
321 Part * PartManager::findPartFromWidget( TQWidget * widget )
323 TQPtrListIterator<Part> it ( d->m_parts );
324 for ( ; it.current() ; ++it )
326 if ( widget == it.current()->widget() )
334 if ( d->m_parts.findRef( part ) != -1 )
336 #ifdef DEBUG_PARTMANAGER
342 d->m_parts.append( part );
344 part->setManager(
this );
350 part->
widget()->setFocus();
354 if ( part->
widget() && part->
widget()->focusPolicy() == TQ_NoFocus )
356 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;
358 if ( part->
widget() && part->
widget()->focusPolicy() == TQ_TabFocus )
360 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;
363 if ( setActive && part->
widget() )
370 if ( d->m_parts.findRef( part ) == -1 )
372 kdFatal(1000) << TQString(TQString(
"Can't remove part %1, not in KPartManager's list.").arg(part->name())) <<
endl;
378 int nb = d->m_parts.count();
379 bool ok = d->m_parts.removeRef( part );
381 Q_ASSERT( (
int)d->m_parts.count() == nb-1 );
386 if ( part == d->m_activePart )
388 if ( part == d->m_selectedPart )
396 if ( d->m_parts.findRef( oldPart ) == -1 )
398 kdFatal(1000) << TQString(TQString(
"Can't remove part %1, not in KPartManager's list.").arg(oldPart->name())) <<
endl;
402 d->m_parts.removeRef( oldPart );
403 oldPart->setManager(0);
412 if ( part && d->m_parts.findRef( part ) == -1 )
414 kdWarning( 1000 ) <<
"PartManager::setActivePart : trying to activate a non-registered part! " << part->name() <<
endl;
420 if ( part && !d->m_bAllowNestedParts )
422 TQObject *parentPart = TQT_TQOBJECT(part->parent());
423 if ( parentPart && parentPart->inherits(
"KParts::Part" ) )
431 #ifdef DEBUG_PARTMANAGER
432 kdDebug(1000) <<
"PartManager::setActivePart d->m_activePart=" << d->m_activePart <<
"<->part=" << part
433 <<
" d->m_activeWidget=" << d->m_activeWidget <<
"<->widget=" << widget <<
endl;
437 if ( d->m_activePart && part && d->m_activePart == part &&
438 (!widget || d->m_activeWidget == widget) )
442 TQWidget *oldActiveWidget = d->m_activeWidget;
446 d->m_activePart = part;
447 d->m_activeWidget = widget;
452 TQWidget *savedActiveWidget = widget;
455 TQApplication::sendEvent( oldActivePart, &ev );
456 if ( oldActiveWidget )
458 disconnect( oldActiveWidget, TQT_SIGNAL( destroyed() ),
459 this, TQT_SLOT( slotWidgetDestroyed() ) );
460 TQApplication::sendEvent( oldActiveWidget, &ev );
463 d->m_activePart = savedActivePart;
464 d->m_activeWidget = savedActiveWidget;
467 if ( d->m_activePart )
470 d->m_activeWidget = part->
widget();
473 TQApplication::sendEvent( d->m_activePart, &ev );
474 if ( d->m_activeWidget )
476 connect( d->m_activeWidget, TQT_SIGNAL( destroyed() ),
477 this, TQT_SLOT( slotWidgetDestroyed() ) );
478 TQApplication::sendEvent( d->m_activeWidget, &ev );
484 kdDebug(1000) <<
this <<
" emitting activePartChanged " << d->m_activePart <<
endl;
496 return d->m_activePart;
501 return d->m_activeWidget;
506 if ( part == d->m_selectedPart && widget == d->m_selectedWidget )
509 Part *oldPart = d->m_selectedPart;
510 TQWidget *oldWidget = d->m_selectedWidget;
512 d->m_selectedPart = part;
513 d->m_selectedWidget = widget;
515 if ( part && !widget )
516 d->m_selectedWidget = part->
widget();
521 TQApplication::sendEvent( oldPart, &ev );
522 TQApplication::sendEvent( oldWidget, &ev );
525 if ( d->m_selectedPart )
528 TQApplication::sendEvent( d->m_selectedPart, &ev );
529 TQApplication::sendEvent( d->m_selectedWidget, &ev );
535 return d->m_selectedPart;
540 return d->m_selectedWidget;
545 kdDebug(1000) <<
"KPartManager::slotObjectDestroyed()" <<
endl;
546 removePart( const_cast<Part *>( static_cast<const Part *>( sender() ) ) );
549 void PartManager::slotWidgetDestroyed()
551 kdDebug(1000) <<
"KPartsManager::slotWidgetDestroyed()" <<
endl;
552 if ( static_cast<const TQWidget *>( sender() ) == d->m_activeWidget )
564 if ( !topLevel->isTopLevel() )
567 if ( d->m_managedTopLevelWidgets.containsRef( topLevel ) )
570 d->m_managedTopLevelWidgets.append( topLevel );
571 connect( topLevel, TQT_SIGNAL( destroyed() ),
572 this, TQT_SLOT( slotManagedTopLevelWidgetDestroyed() ) );
577 if ( !topLevel->isTopLevel() )
580 if ( d->m_managedTopLevelWidgets.findRef( topLevel ) == -1 )
583 d->m_managedTopLevelWidgets.remove();
586 void PartManager::slotManagedTopLevelWidgetDestroyed()
588 const TQWidget *widget =
static_cast<const TQWidget *
>( sender() );
597 void PartManager::virtual_hook(
int,
void* )
600 #include "partmanager.moc"