/********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of TQt Designer. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition ** licenses may use this file in accordance with the TQt Commercial License ** Agreement provided with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about TQt Commercial License Agreements. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "actiondnd.h" #include "command.h" #include "defs.h" #include "formwindow.h" #include "mainwindow.h" #include "metadatabase.h" #include "widgetfactory.h" #include "hierarchyview.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include TQAction *ActionDrag::the_action = 0; ActionDrag::ActionDrag(TQAction *action, TQWidget *source) : TQStoredDrag("application/x-designer-actions", source) { Q_ASSERT(the_action == 0); the_action = action; } ActionDrag::ActionDrag(TQActionGroup *group, TQWidget *source) : TQStoredDrag("application/x-designer-actiongroup", source) { Q_ASSERT(the_action == 0); the_action = group; } ActionDrag::ActionDrag(const TQString &type, TQAction *action, TQWidget *source) : TQStoredDrag(type, source) { Q_ASSERT(the_action == 0); the_action = action; } bool ActionDrag::canDecode(TQDropEvent *e) { return e->provides( "application/x-designer-actions" ) || e->provides( "application/x-designer-actiongroup" ) || e->provides( "application/x-designer-separator" ); } ActionDrag::~ActionDrag() { the_action = 0; } void QDesignerAction::init() { MetaDataBase::addEntry( this ); int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( this ) ); WidgetFactory::saveDefaultProperties( this, id ); WidgetFactory::saveChangedProperties( this, id ); } void QDesignerActionGroup::init() { MetaDataBase::addEntry( this ); int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( this ) ); WidgetFactory::saveDefaultProperties( this, id ); WidgetFactory::saveChangedProperties( this, id ); } bool QDesignerAction::addTo( TQWidget *w ) { if ( !widgetToInsert ) return TQAction::addTo( w ); if ( ::tqqt_cast(w) ) return FALSE; widgetToInsert->reparent( w, TQPoint( 0, 0 ), FALSE ); widgetToInsert->show(); addedTo( widgetToInsert, w ); return TRUE; } bool QDesignerAction::removeFrom( TQWidget *w ) { if ( !widgetToInsert ) return TQAction::removeFrom( w ); remove(); return TRUE; } void QDesignerAction::remove() { if ( !widgetToInsert ) return; MainWindow::self->formWindow()->selectWidget( TQT_TQOBJECT(widgetToInsert), FALSE ); widgetToInsert->reparent( 0, TQPoint( 0, 0 ), FALSE ); } QDesignerToolBarSeparator::QDesignerToolBarSeparator(Qt::Orientation o , TQToolBar *parent, const char* name ) : TQWidget( parent, name ) { connect( parent, TQT_SIGNAL(orientationChanged(Qt::Orientation)), this, TQT_SLOT(setOrientation(Qt::Orientation)) ); setOrientation( o ); setBackgroundMode( parent->backgroundMode() ); setBackgroundOrigin( ParentOrigin ); setSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Minimum ) ); } void QDesignerToolBarSeparator::setOrientation( Qt::Orientation o ) { orient = o; } void QDesignerToolBarSeparator::styleChange( TQStyle& ) { setOrientation( orient ); } TQSize QDesignerToolBarSeparator::sizeHint() const { int extent = style().pixelMetric( TQStyle::PM_DockWindowSeparatorExtent, this ); if ( orient ==Qt::Horizontal ) return TQSize( extent, 0 ); else return TQSize( 0, extent ); } void QDesignerToolBarSeparator::paintEvent( TQPaintEvent * ) { TQPainter p( this ); TQStyle::SFlags flags = TQStyle::Style_Default; if ( orientation() ==Qt::Horizontal ) flags |= TQStyle::Style_Horizontal; style().tqdrawPrimitive( TQStyle::PE_DockWindowSeparator, &p, rect(), colorGroup(), flags ); } QSeparatorAction::QSeparatorAction( TQObject *parent ) : TQAction( parent, "qt_designer_separator" ), wid( 0 ) { } bool QSeparatorAction::addTo( TQWidget *w ) { if ( ::tqqt_cast(w) ) { TQToolBar *tb = (TQToolBar*)w; wid = new QDesignerToolBarSeparator( tb->orientation(), tb ); return TRUE; } else if ( ::tqqt_cast(w) ) { idx = ( (TQPopupMenu*)w )->count(); ( (TQPopupMenu*)w )->insertSeparator( idx ); return TRUE; } return FALSE; } bool QSeparatorAction::removeFrom( TQWidget *w ) { if ( ::tqqt_cast(w) ) { delete wid; return TRUE; } else if ( ::tqqt_cast(w) ) { ( (TQPopupMenu*)w )->removeItemAt( idx ); return TRUE; } return FALSE; } TQWidget *QSeparatorAction::widget() const { return wid; } QDesignerToolBar::QDesignerToolBar( TQMainWindow *mw ) : TQToolBar( mw ), lastIndicatorPos( -1, -1 ) { insertAnchor = 0; afterAnchor = TRUE; setAcceptDrops( TRUE ); MetaDataBase::addEntry( TQT_TQOBJECT(this) ); lastIndicatorPos = TQPoint( -1, -1 ); indicator = new QDesignerIndicatorWidget( this ); indicator->hide(); installEventFilter( this ); widgetInserting = FALSE; findFormWindow(); mw->setDockEnabled( DockTornOff, FALSE ); } QDesignerToolBar::QDesignerToolBar( TQMainWindow *mw, Dock dock ) : TQToolBar( TQString(), mw, dock), lastIndicatorPos( -1, -1 ) { insertAnchor = 0; afterAnchor = TRUE; setAcceptDrops( TRUE ); indicator = new QDesignerIndicatorWidget( this ); indicator->hide(); MetaDataBase::addEntry( TQT_TQOBJECT(this) ); installEventFilter( this ); widgetInserting = FALSE; findFormWindow(); mw->setDockEnabled( DockTornOff, FALSE ); } void QDesignerToolBar::findFormWindow() { TQWidget *w = this; while ( w ) { formWindow = ::tqqt_cast(w); if ( formWindow ) break; w = w->parentWidget(); } } void QDesignerToolBar::addAction( TQAction *a ) { actionList.append( a ); connect( a, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( actionRemoved() ) ); if ( ::tqqt_cast(a) ) { ( (QDesignerActionGroup*)a )->widget()->installEventFilter( this ); actionMap.insert( ( (QDesignerActionGroup*)a )->widget(), a ); } else if ( ::tqqt_cast(a) ) { ( (QSeparatorAction*)a )->widget()->installEventFilter( this ); actionMap.insert( ( (QSeparatorAction*)a )->widget(), a ); } else { ( (QDesignerAction*)a )->widget()->installEventFilter( this ); actionMap.insert( ( (QDesignerAction*)a )->widget(), a ); } } static void fixObject( TQObject *&o ) { while ( o && o->parent() && !::tqqt_cast(o->parent()) ) o = o->parent(); } bool QDesignerToolBar::eventFilter( TQObject *o, TQEvent *e ) { if ( !o || !e || o->inherits( TQDOCKWINDOWHANDLE_OBJECT_NAME_STRING ) || o->inherits( "TQDockWindowTitleBar" ) ) return TQToolBar::eventFilter( o, e ); if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) && e->type() == TQEvent::MouseButtonPress && ( ( TQMouseEvent*)e )->button() == Qt::LeftButton ) { mousePressEvent( (TQMouseEvent*)e ); return TRUE; } if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) ) return TQToolBar::eventFilter( o, e ); if ( e->type() == TQEvent::MouseButtonPress ) { TQMouseEvent *ke = (TQMouseEvent*)e; fixObject( o ); if ( !o ) return FALSE; buttonMousePressEvent( ke, o ); return TRUE; } else if(e->type() == TQEvent::ContextMenu ) { TQContextMenuEvent *ce = (TQContextMenuEvent*)e; fixObject( o ); if( !o ) return FALSE; buttonContextMenuEvent( ce, o ); return TRUE; } else if ( e->type() == TQEvent::MouseMove ) { TQMouseEvent *ke = (TQMouseEvent*)e; fixObject( o ); if ( !o ) return FALSE; buttonMouseMoveEvent( ke, o ); return TRUE; } else if ( e->type() == TQEvent::MouseButtonRelease ) { TQMouseEvent *ke = (TQMouseEvent*)e; fixObject( o ); if ( !o ) return FALSE; buttonMouseReleaseEvent( ke, o ); return TRUE; } else if ( e->type() == TQEvent::DragEnter ) { TQDragEnterEvent *de = (TQDragEnterEvent*)e; if (ActionDrag::canDecode(de)) de->accept(); } else if ( e->type() == TQEvent::DragMove ) { TQDragMoveEvent *de = (TQDragMoveEvent*)e; if (ActionDrag::canDecode(de)) de->accept(); } return TQToolBar::eventFilter( o, e ); } void QDesignerToolBar::paintEvent( TQPaintEvent *e ) { TQToolBar::paintEvent( e ); if ( e->rect() != rect() ) return; lastIndicatorPos = TQPoint( -1, -1 ); } void QDesignerToolBar::contextMenuEvent( TQContextMenuEvent *e ) { e->accept(); TQPopupMenu menu( 0 ); menu.insertItem( i18n( "Delete Toolbar" ), 1 ); int res = menu.exec( e->globalPos() ); if ( res != -1 ) { RemoveToolBarCommand *cmd = new RemoveToolBarCommand( i18n( "Delete Toolbar '%1'" ).arg( name() ), formWindow, 0, this ); formWindow->commandHistory()->addCommand( cmd ); cmd->execute(); } } void QDesignerToolBar::mousePressEvent( TQMouseEvent *e ) { widgetInserting = FALSE; if ( e->button() == Qt::LeftButton && MainWindow::self->currentTool() != POINTER_TOOL && MainWindow::self->currentTool() != ORDER_TOOL && MainWindow::self->currentTool() != CONNECT_TOOL && MainWindow::self->currentTool() != BUDDY_TOOL ) widgetInserting = TRUE; } void QDesignerToolBar::mouseReleaseEvent( TQMouseEvent *e ) { if ( widgetInserting ) doInsertWidget( mapFromGlobal( e->globalPos() ) ); widgetInserting = FALSE; } void QDesignerToolBar::buttonMouseReleaseEvent( TQMouseEvent *e, TQObject *w ) { if ( widgetInserting ) doInsertWidget( mapFromGlobal( e->globalPos() ) ); else if ( w->isWidgetType() && formWindow->widgets()->find( w ) ) { formWindow->clearSelection( FALSE ); formWindow->selectWidget( w ); } widgetInserting = FALSE; } void QDesignerToolBar::buttonContextMenuEvent( TQContextMenuEvent *e, TQObject *o ) { e->accept(); TQPopupMenu menu( 0 ); const int ID_DELETE = 1; const int ID_SEP = 2; const int ID_DELTOOLBAR = 3; TQMap::Iterator it = actionMap.find( (TQWidget*)o ); if ( it != actionMap.end() && ::tqqt_cast(*it) ) menu.insertItem( i18n( "Delete Separator" ), ID_DELETE ); else menu.insertItem( i18n( "Delete Item" ), ID_DELETE ); menu.insertItem( i18n( "Insert Separator" ), ID_SEP ); menu.insertSeparator(); menu.insertItem( i18n( "Delete Toolbar" ), ID_DELTOOLBAR ); int res = menu.exec( e->globalPos() ); if ( res == ID_DELETE ) { TQMap::Iterator it = actionMap.find( (TQWidget*)o ); if ( it == actionMap.end() ) return; TQAction *a = *it; int index = actionList.find( a ); RemoveActionFromToolBarCommand *cmd = new RemoveActionFromToolBarCommand( i18n( "Delete Action '%1' From Toolbar '%2'" ). arg( a->name() ).arg( caption() ), formWindow, a, this, index ); formWindow->commandHistory()->addCommand( cmd ); cmd->execute(); } else if ( res == ID_SEP ) { calcIndicatorPos( mapFromGlobal( e->globalPos() ) ); TQAction *a = new QSeparatorAction( 0 ); int index = actionList.findRef( *actionMap.find( insertAnchor ) ); if ( index != -1 && afterAnchor ) ++index; if ( !insertAnchor ) index = 0; AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( i18n( "Add Separator to Toolbar '%1'" ). arg( a->name() ), formWindow, a, this, index ); formWindow->commandHistory()->addCommand( cmd ); cmd->execute(); } else if ( res == ID_DELTOOLBAR ) { RemoveToolBarCommand *cmd = new RemoveToolBarCommand( i18n( "Delete Toolbar '%1'" ).arg( name() ), formWindow, 0, this ); formWindow->commandHistory()->addCommand( cmd ); cmd->execute(); } } void QDesignerToolBar::buttonMousePressEvent( TQMouseEvent *e, TQObject * ) { widgetInserting = FALSE; if ( e->button() == Qt::MidButton ) return; if ( e->button() == Qt::LeftButton && MainWindow::self->currentTool() != POINTER_TOOL && MainWindow::self->currentTool() != ORDER_TOOL && MainWindow::self->currentTool() != CONNECT_TOOL && MainWindow::self->currentTool() != BUDDY_TOOL ) { widgetInserting = TRUE; return; } dragStartPos = e->pos(); } void QDesignerToolBar::removeWidget( TQWidget *w ) { TQMap::Iterator it = actionMap.find( w ); if ( it == actionMap.end() ) return; TQAction *a = *it; int index = actionList.find( a ); RemoveActionFromToolBarCommand *cmd = new RemoveActionFromToolBarCommand( i18n( "Delete Action '%1' From Toolbar '%2'" ). arg( a->name() ).arg( caption() ), formWindow, a, this, index ); formWindow->commandHistory()->addCommand( cmd ); cmd->execute(); TQApplication::sendPostedEvents(); adjustSize(); } void QDesignerToolBar::buttonMouseMoveEvent( TQMouseEvent *e, TQObject *o ) { if ( widgetInserting || ( e->state() & Qt::LeftButton ) == 0 ) return; if ( TQABS( TQPoint( dragStartPos - e->pos() ).manhattanLength() ) < TQApplication::startDragDistance() ) return; TQMap::Iterator it = actionMap.find( (TQWidget*)o ); if ( it == actionMap.end() ) return; TQAction *a = *it; if ( !a ) return; int index = actionList.find( a ); RemoveActionFromToolBarCommand *cmd = new RemoveActionFromToolBarCommand( i18n( "Delete Action '%1' From Toolbar '%2'" ). arg( a->name() ).arg( caption() ), formWindow, a, this, index ); formWindow->commandHistory()->addCommand( cmd ); cmd->execute(); TQApplication::sendPostedEvents(); adjustSize(); TQString type = ::tqqt_cast(a) ? TQString( "application/x-designer-actiongroup" ) : ::tqqt_cast(a) ? TQString( "application/x-designer-separator" ) : TQString( "application/x-designer-actions" ); TQStoredDrag *drag = new ActionDrag( type, a, this ); drag->setPixmap( a->iconSet().pixmap() ); if ( ::tqqt_cast(a) ) { if ( formWindow->widgets()->find( ( (QDesignerAction*)a )->widget() ) ) formWindow->selectWidget( ( TQT_TQOBJECT(( (QDesignerAction*)a )->widget())), FALSE ); } if ( !drag->drag() ) { AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( i18n( "Add Action '%1' to Toolbar '%2'" ). arg( a->name() ).arg( caption() ), formWindow, a, this, index ); formWindow->commandHistory()->addCommand( cmd ); cmd->execute(); } lastIndicatorPos = TQPoint( -1, -1 ); indicator->hide(); } #ifndef TQT_NO_DRAGANDDROP void QDesignerToolBar::dragEnterEvent( TQDragEnterEvent *e ) { widgetInserting = FALSE; lastIndicatorPos = TQPoint( -1, -1 ); if (ActionDrag::canDecode(e)) e->accept(); } void QDesignerToolBar::dragMoveEvent( TQDragMoveEvent *e ) { if (ActionDrag::canDecode(e)) { e->accept(); drawIndicator( calcIndicatorPos( e->pos() ) ); } } void QDesignerToolBar::dragLeaveEvent( TQDragLeaveEvent * ) { indicator->hide(); insertAnchor = 0; afterAnchor = TRUE; } void QDesignerToolBar::dropEvent( TQDropEvent *e ) { if (!ActionDrag::canDecode(e)) return; e->accept(); indicator->hide(); TQAction *a = 0; int index = actionList.findRef( *actionMap.find( insertAnchor ) ); if ( index != -1 && afterAnchor ) ++index; if ( !insertAnchor ) index = 0; if ( e->provides( "application/x-designer-actions" ) || e->provides( "application/x-designer-separator" ) ) { if ( e->provides( "application/x-designer-actions" ) ) a = ::tqqt_cast(ActionDrag::action()); else a = ::tqqt_cast(ActionDrag::action()); } else { a = ::tqqt_cast(ActionDrag::action()); } if ( actionList.findRef( a ) != -1 ) { TQMessageBox::warning( MainWindow::self, i18n( "Insert/Move Action" ), i18n( "Action '%1' has already been added to this toolbar.\n" "An Action may only occur once in a given toolbar." ). arg( a->name() ) ); return; } AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( i18n( "Add Action '%1' to Toolbar '%2'" ). arg( a->name() ).arg( caption() ), formWindow, a, this, index ); formWindow->commandHistory()->addCommand( cmd ); cmd->execute(); lastIndicatorPos = TQPoint( -1, -1 ); } #endif void QDesignerToolBar::reInsert() { TQAction *a = 0; actionMap.clear(); clear(); for ( a = actionList.first(); a; a = actionList.next() ) { a->addTo( this ); if ( ::tqqt_cast(a) ) { actionMap.insert( ( (QDesignerActionGroup*)a )->widget(), a ); if ( ( (QDesignerActionGroup*)a )->widget() ) ( (QDesignerActionGroup*)a )->widget()->installEventFilter( this ); } else if ( ::tqqt_cast(a) ) { actionMap.insert( ( (QDesignerAction*)a )->widget(), a ); ( (QDesignerAction*)a )->widget()->installEventFilter( this ); } else if ( ::tqqt_cast(a) ) { actionMap.insert( ( (QSeparatorAction*)a )->widget(), a ); ( (QSeparatorAction*)a )->widget()->installEventFilter( this ); } } TQApplication::sendPostedEvents(); adjustSize(); } void QDesignerToolBar::actionRemoved() { actionList.removeRef( (TQAction*)sender() ); } TQPoint QDesignerToolBar::calcIndicatorPos( const TQPoint &pos ) { if ( orientation() ==Qt::Horizontal ) { TQPoint pnt( width() - 2, 0 ); insertAnchor = 0; afterAnchor = TRUE; TQObjectList clo = childrenListObject(); if ( clo.isEmpty() ) return pnt; pnt = TQPoint( 13, 0 ); TQObjectListIt it( clo ); TQObject * obj; while( (obj=it.current()) != 0 ) { ++it; if ( obj->isWidgetType() && qstrcmp( "qt_dockwidget_internal", obj->name() ) != 0 ) { TQWidget *w = (TQWidget*)obj; if ( w->x() < pos.x() ) { pnt.setX( w->x() + w->width() + 1 ); insertAnchor = w; afterAnchor = TRUE; } } } return pnt; } else { TQPoint pnt( 0, height() - 2 ); insertAnchor = 0; afterAnchor = TRUE; TQObjectList clo = childrenListObject(); if ( clo.isEmpty() ) return pnt; pnt = TQPoint( 0, 13 ); TQObjectListIt it( clo ); TQObject * obj; while( (obj=it.current()) != 0 ) { ++it; if ( obj->isWidgetType() && qstrcmp( "qt_dockwidget_internal", obj->name() ) != 0 ) { TQWidget *w = (TQWidget*)obj; if ( w->y() < pos.y() ) { pnt.setY( w->y() + w->height() + 1 ); insertAnchor = w; afterAnchor = TRUE; } } } return pnt; } } void QDesignerToolBar::drawIndicator( const TQPoint &pos ) { if ( lastIndicatorPos == pos ) return; bool wasVsisible = indicator->isVisible(); if ( orientation() ==Qt::Horizontal ) { indicator->resize( 3, height() ); if ( pos != TQPoint( -1, -1 ) ) indicator->move( pos.x() - 1, 0 ); indicator->show(); indicator->raise(); lastIndicatorPos = pos; } else { indicator->resize( width(), 3 ); if ( pos != TQPoint( -1, -1 ) ) indicator->move( 0, pos.y() - 1 ); indicator->show(); indicator->raise(); lastIndicatorPos = pos; } if ( !wasVsisible ) TQApplication::sendPostedEvents(); } void QDesignerToolBar::doInsertWidget( const TQPoint &p ) { if ( formWindow != MainWindow::self->formWindow() ) return; calcIndicatorPos( p ); TQWidget *w = WidgetFactory::create( MainWindow::self->currentTool(), this, 0, TRUE ); installEventFilters( w ); MainWindow::self->formWindow()->insertWidget( w, TRUE ); QDesignerAction *a = new QDesignerAction( w, parent() ); int index = actionList.findRef( *actionMap.find( insertAnchor ) ); if ( index != -1 && afterAnchor ) ++index; if ( !insertAnchor ) index = 0; AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( i18n( "Add Widget '%1' to Toolbar '%2'" ). arg( w->name() ).arg( caption() ), formWindow, a, this, index ); formWindow->commandHistory()->addCommand( cmd ); cmd->execute(); MainWindow::self->resetTool(); } void QDesignerToolBar::clear() { for ( TQAction *a = actionList.first(); a; a = actionList.next() ) { if ( ::tqqt_cast(a) ) ( (QDesignerAction*)a )->remove(); } TQToolBar::clear(); } void QDesignerToolBar::installEventFilters( TQWidget *w ) { if ( !w ) return; TQObjectList *l = w->queryList( TQWIDGET_OBJECT_NAME_STRING ); for ( TQObject *o = l->first(); o; o = l->next() ) o->installEventFilter( this ); delete l; } //#include "actiondnd.moc"