You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdewebdev/kommander/editor/actiondnd.cpp

1245 lines
36 KiB

/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qt 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.
**
** 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.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#include <tqaction.h>
#include <tqapplication.h>
#include <tqbitmap.h>
#include <tqdragobject.h>
#include <kinputdialog.h>
#include <tqlayout.h>
#include <tqmainwindow.h>
#include <tqmenudata.h>
#include <tqmessagebox.h>
#include <tqobjectlist.h>
#include <tqpainter.h>
#include <tqstyle.h>
#include <tqtimer.h>
#include "actiondnd.h"
#include "command.h"
#include "defs.h"
#include "formwindow.h"
#include "mainwindow.h"
#include "metadatabase.h"
#include "widgetfactory.h"
#include <klocale.h>
bool QDesignerAction::addTo( TQWidget *w )
{
if ( !widgetToInsert )
return TQAction::addTo( w );
if ( w->inherits( "TQPopupMenu" ) )
return false;
widgetToInsert->reparent( w, TQPoint( 0, 0 ), false );
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( widgetToInsert, false );
widgetToInsert->reparent( 0, TQPoint( 0, 0 ), false );
}
QDesignerToolBarSeparator::QDesignerToolBarSeparator(Orientation o , TQToolBar *parent,
const char* name )
: TQWidget( parent, name )
{
connect( parent, TQT_SIGNAL(orientationChanged(Orientation)),
this, TQT_SLOT(setOrientation(Orientation)) );
setOrientation( o );
setBackgroundMode( parent->backgroundMode() );
setBackgroundOrigin( ParentOrigin );
setSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Minimum ) );
}
void QDesignerToolBarSeparator::setOrientation( Orientation o )
{
orient = o;
}
void QDesignerToolBarSeparator::styleChange( TQStyle& )
{
setOrientation( orient );
}
TQSize QDesignerToolBarSeparator::sizeHint() const
{
int extent = style().pixelMetric( TQStyle::PM_DockWindowSeparatorExtent,
this );
if ( orient == 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() == Horizontal )
flags |= TQStyle::Style_Horizontal;
style().drawPrimitive( TQStyle::PE_DockWindowSeparator, &p, rect(),
colorGroup(), flags );
}
QSeparatorAction::QSeparatorAction( TQObject *parent )
: TQAction( parent, "qt_designer_separator" ), wid( 0 )
{
}
bool QSeparatorAction::addTo( TQWidget *w )
{
if ( w->inherits( "TQToolBar" ) ) {
TQToolBar *tb = (TQToolBar*)w;
wid = new QDesignerToolBarSeparator( tb->orientation(), tb );
return true;
} else if ( w->inherits( "TQPopupMenu" ) ) {
idx = ( (TQPopupMenu*)w )->count();
( (TQPopupMenu*)w )->insertSeparator( idx );
return true;
}
return false;
}
bool QSeparatorAction::removeFrom( TQWidget *w )
{
if ( w->inherits( "TQToolBar" ) ) {
delete wid;
return true;
} else if ( w->inherits( "TQPopupMenu" ) ) {
( (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( 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::null, mw, dock), lastIndicatorPos( -1, -1 )
{
insertAnchor = 0;
afterAnchor = true;
setAcceptDrops( true );
indicator = new QDesignerIndicatorWidget( this );
indicator->hide();
MetaDataBase::addEntry( this );
installEventFilter( this );
widgetInserting = false;
findFormWindow();
mw->setDockEnabled( DockTornOff, false );
}
void QDesignerToolBar::findFormWindow()
{
TQWidget *w = this;
while ( w ) {
if ( w->inherits( "FormWindow" ) )
formWindow = (FormWindow*)w;
w = w->parentWidget();
}
}
void QDesignerToolBar::addAction( TQAction *a )
{
actionList.append( a );
connect( a, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( actionRemoved() ) );
if ( a->inherits( "TQActionGroup" ) ) {
( (QDesignerActionGroup*)a )->widget()->installEventFilter( this );
actionMap.insert( ( (QDesignerActionGroup*)a )->widget(), a );
} else if ( a->inherits( "QSeparatorAction" ) ) {
( (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() && !o->parent()->inherits( "QDesignerToolBar" ) )
o = o->parent();
}
bool QDesignerToolBar::eventFilter( TQObject *o, TQEvent *e )
{
if ( !o || !e || o->inherits( "QDockWindowHandle" ) || o->inherits( "QDockWindowTitleBar" ) )
return TQToolBar::eventFilter( o, e );
if ( o == this && e->type() == TQEvent::MouseButtonPress &&
( ( TQMouseEvent*)e )->button() == LeftButton ) {
mousePressEvent( (TQMouseEvent*)e );
return true;
}
if ( o == 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 ( de->provides( "application/x-designer-actions" ) ||
de->provides( "application/x-designer-actiongroup" ) ||
de->provides( "application/x-designer-separator" ) )
de->accept();
} else if ( e->type() == TQEvent::DragMove ) {
TQDragMoveEvent *de = (TQDragMoveEvent*)e;
if ( de->provides( "application/x-designer-actions" ) ||
de->provides( "application/x-designer-actiongroup" ) ||
de->provides( "application/x-designer-separator" ) )
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() == LeftButton &&
MainWindow::self->currentTool() != POINTER_TOOL &&
MainWindow::self->currentTool() != ORDER_TOOL ) {
if ( MainWindow::self->currentTool() == CONNECT_TOOL ) {
} else {
widgetInserting = true;
}
return;
}
}
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<TQWidget*, TQAction*>::Iterator it = actionMap.find( (TQWidget*)o );
if ( it != actionMap.end() && (*it)->inherits( "QSeparatorAction" ) )
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<TQWidget*, TQAction*>::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() == MidButton )
return;
if ( e->button() == LeftButton &&
MainWindow::self->currentTool() != POINTER_TOOL &&
MainWindow::self->currentTool() != ORDER_TOOL ) {
if ( MainWindow::self->currentTool() == CONNECT_TOOL ) {
} else {
widgetInserting = true;
}
return;
}
dragStartPos = e->pos();
}
void QDesignerToolBar::removeWidget( TQWidget *w )
{
TQMap<TQWidget*, TQAction*>::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() & LeftButton ) == 0 )
return;
if ( QABS( TQPoint( dragStartPos - e->pos() ).manhattanLength() ) < TQApplication::startDragDistance() )
return;
TQMap<TQWidget*, TQAction*>::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 = a->inherits( "TQActionGroup" ) ? TQString( "application/x-designer-actiongroup" ) :
a->inherits( "QSeparatorAction" ) ? TQString( "application/x-designer-separator" ) : TQString( "application/x-designer-actions" );
TQStoredDrag *drag = new TQStoredDrag( type, this );
TQString s = TQString::number( (long)a ); // #### huha, that is evil
drag->setEncodedData( TQCString( s.latin1() ) );
drag->setPixmap( a->iconSet().pixmap() );
if ( a->inherits( "QDesignerAction" ) ) {
if ( formWindow->widgets()->find( ( (QDesignerAction*)a )->widget() ) )
formWindow->selectWidget( ( (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 QT_NO_DRAGANDDROP
void QDesignerToolBar::dragEnterEvent( TQDragEnterEvent *e )
{
widgetInserting = false;
lastIndicatorPos = TQPoint( -1, -1 );
if ( e->provides( "application/x-designer-actions" ) ||
e->provides( "application/x-designer-actiongroup" ) ||
e->provides( "application/x-designer-separator" ) )
e->accept();
}
void QDesignerToolBar::dragMoveEvent( TQDragMoveEvent *e )
{
if ( e->provides( "application/x-designer-actions" ) ||
e->provides( "application/x-designer-actiongroup" ) ||
e->provides( "application/x-designer-separator" ) )
e->accept();
else
return;
drawIndicator( calcIndicatorPos( e->pos() ) );
}
void QDesignerToolBar::dragLeaveEvent( TQDragLeaveEvent * )
{
indicator->hide();
insertAnchor = 0;
afterAnchor = true;
}
void QDesignerToolBar::dropEvent( TQDropEvent *e )
{
if ( e->provides( "application/x-designer-actions" ) ||
e->provides( "application/x-designer-actiongroup" ) ||
e->provides( "application/x-designer-separator" ) )
e->accept();
else
return;
TQString s;
if ( e->provides( "application/x-designer-actiongroup" ) )
s = TQString( e->encodedData( "application/x-designer-actiongroup" ) );
else if ( e->provides( "application/x-designer-separator" ) )
s = TQString( e->encodedData( "application/x-designer-separator" ) );
else
s = TQString( e->encodedData( "application/x-designer-actions" ) );
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 = (QDesignerAction*)s.toLong();
else
a = (QSeparatorAction*)s.toLong();
} else {
a = (QDesignerActionGroup*)s.toLong();
}
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 ( a->inherits( "TQActionGroup" ) ) {
actionMap.insert( ( (QDesignerActionGroup*)a )->widget(), a );
if ( ( (QDesignerActionGroup*)a )->widget() )
( (QDesignerActionGroup*)a )->widget()->installEventFilter( this );
} else if ( a->inherits( "QDesignerAction" ) ) {
actionMap.insert( ( (QDesignerAction*)a )->widget(), a );
( (QDesignerAction*)a )->widget()->installEventFilter( this );
} else if ( a->inherits( "QSeparatorAction" ) ) {
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() == Horizontal ) {
TQPoint pnt( width() - 2, 0 );
insertAnchor = 0;
afterAnchor = true;
if ( !children() )
return pnt;
pnt = TQPoint( 13, 0 );
TQObjectListIt it( *children() );
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;
if ( !children() )
return pnt;
pnt = TQPoint( 0, 13 );
TQObjectListIt it( *children() );
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() == 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 ( a->inherits( "QDesignerAction" ) )
( (QDesignerAction*)a )->remove();
}
TQToolBar::clear();
}
void QDesignerToolBar::installEventFilters( TQWidget *w )
{
if ( !w )
return;
TQObjectList *l = w->queryList( "TQWidget" );
for ( TQObject *o = l->first(); o; o = l->next() )
o->installEventFilter( this );
delete l;
}
QDesignerMenuBar::QDesignerMenuBar( TQWidget *mw )
: TQMenuBar( mw, 0 )
{
show();
setAcceptDrops( true );
MetaDataBase::addEntry( this );
itemNum = 0;
mousePressed = false;
lastIndicatorPos = TQPoint( -1, -1 );
insertAt = -1;
indicator = new QDesignerIndicatorWidget( this );
indicator->hide();
findFormWindow();
}
void QDesignerMenuBar::findFormWindow()
{
TQWidget *w = this;
while ( w ) {
if ( w->inherits( "FormWindow" ) )
formWindow = (FormWindow*)w;
w = w->parentWidget();
}
}
void QDesignerMenuBar::contextMenuEvent( TQContextMenuEvent *e )
{
e->accept();
int itm = itemAtPos( e->pos() );
if ( itm == -1 ) {
if ( formWindow )
formWindow->mainWindow()->popupFormWindowMenu( e->globalPos(), formWindow );
return;
}
TQPopupMenu menu( this );
menu.insertItem( i18n("Delete Item" ), 1 );
menu.insertItem( i18n("Rename Item..." ), 2 );
int res = menu.exec( e->globalPos() );
if ( res == 1 ) {
TQMenuItem *item = findItem( idAt( itm ) );
RemoveMenuCommand *cmd = new RemoveMenuCommand( i18n("Delete Menu '%1'" ).arg( item->text() ),
formWindow,
(TQMainWindow*)parentWidget(), this,
(QDesignerPopupMenu*)item->popup(),
idAt( itm ), itm, item->text() );
formWindow->commandHistory()->addCommand( cmd );
cmd->execute();
// #### need to do a proper invalidate and re-layout
parentWidget()->layout()->invalidate();
parentWidget()->layout()->activate();
} else if ( res == 2 ) {
bool ok;
TQString old = text( idAt( itm ) );
TQString txt = KInputDialog::getText( i18n("Rename Menu Item" ), i18n("Menu text:" ),
text( idAt( itm ) ), &ok, 0 );
if ( ok ) {
RenameMenuCommand *cmd = new RenameMenuCommand(
i18n("Rename Menu '%1' to '%2'" ).arg( old ).arg( txt ),
formWindow, this, idAt( itm ), old, txt );
formWindow->commandHistory()->addCommand( cmd );
cmd->execute();
}
}
}
void QDesignerMenuBar::mousePressEvent( TQMouseEvent *e )
{
lastIndicatorPos = TQPoint( -1, -1 );
insertAt = -1;
mousePressed = true;
if ( e->button() == MidButton || e->button() == RightButton )
return;
dragStartPos = e->pos();
TQMenuBar::mousePressEvent( e );
}
void QDesignerMenuBar::mouseMoveEvent( TQMouseEvent *e )
{
if ( !mousePressed || e->state() == NoButton ) {
TQMenuBar::mouseMoveEvent( e );
return;
}
if ( QABS( TQPoint( dragStartPos - e->pos() ).manhattanLength() ) < TQApplication::startDragDistance() )
return;
hidePopups();
activateItemAt( -1 );
int itm = itemAtPos( dragStartPos );
if ( itm == -1 )
return;
TQPopupMenu *popup = findItem( idAt( itm ) )->popup();
TQString txt = findItem( idAt( itm ) )->text();
removeItemAt( itm );
TQStoredDrag *drag = new TQStoredDrag( "application/x-designer-menuitem", this );
TQString s = TQString::number( (long)popup );
s += "/" + txt;
drag->setEncodedData( TQCString( s.latin1() ) );
TQSize sz( fontMetrics().boundingRect( txt ).size() );
TQPixmap pix( sz.width() + 20, sz.height() * 2 );
pix.fill( white );
TQPainter p( &pix, this );
p.drawText( 2, 0, pix.width(), pix.height(), 0, txt );
p.end();
pix.setMask( pix.createHeuristicMask() );
drag->setPixmap( pix );
oldPos = itm;
if ( !drag->drag() ) {
insertItem( txt, popup, -1, itm );
}
lastIndicatorPos = TQPoint( -1, -1 );
indicator->hide();
mousePressed = false;
}
void QDesignerMenuBar::mouseReleaseEvent( TQMouseEvent *e )
{
TQMenuBar::mouseReleaseEvent( e );
mousePressed = false;
}
#ifndef QT_NO_DRAGANDDROP
void QDesignerMenuBar::dragEnterEvent( TQDragEnterEvent *e )
{
if ( e->provides( "application/x-designer-actions" ) ||
e->provides( "application/x-designer-actiongroup" ) ||
e->provides( "application/x-designer-separator" ) )
e->accept();
if ( e->provides( "application/x-designer-menuitem" ) )
e->accept();
lastIndicatorPos = TQPoint( -1, -1 );
insertAt = -1;
}
void QDesignerMenuBar::dragMoveEvent( TQDragMoveEvent *e )
{
if ( e->provides( "application/x-designer-actions" ) ||
e->provides( "application/x-designer-menuitem" ) ||
e->provides( "application/x-designer-actiongroup" ) ||
e->provides( "application/x-designer-separator" ) )
e->accept();
else
return;
if ( e->provides( "application/x-designer-actions" ) ||
e->provides( "application/x-designer-actiongroup" ) ||
e->provides( "application/x-designer-separator" ) ) {
int item = itemAtPos( e->pos() );
bool uieffect = TQApplication::isEffectEnabled( UI_AnimateMenu );
TQApplication::setEffectEnabled( UI_AnimateMenu, false );
if ( !qApp->activePopupWidget() )
actItem = -1;
activateItemAt( item );
TQApplication::setEffectEnabled( UI_AnimateMenu, uieffect );
if ( item == -1 )
hidePopups();
} else {
drawIndicator( calcIndicatorPos( e->pos() ) );
}
}
void QDesignerMenuBar::dragLeaveEvent( TQDragLeaveEvent * )
{
mousePressed = false;
lastIndicatorPos = TQPoint( -1, -1 );
insertAt = -1;
}
void QDesignerMenuBar::dropEvent( TQDropEvent *e )
{
mousePressed = false;
if ( !e->provides( "application/x-designer-menuitem" ) )
return;
e->accept();
TQString s( e->encodedData( "application/x-designer-menuitem" ) );
TQString s1 = s.left( s.find( "/" ) );
TQString s2 = s.mid( s.find( "/" ) + 1 );
TQPopupMenu *popup = (TQPopupMenu*)s1.toLong(); // #### huha, that is evil
TQString txt = s2;
insertItem( txt, popup, -1, insertAt );
MoveMenuCommand *cmd = new MoveMenuCommand( i18n("Move Menu '%1'" ).arg( txt ), formWindow,
this, (QDesignerPopupMenu*)popup, oldPos, insertAt, txt );
// do not execute, we did the work already
formWindow->commandHistory()->addCommand( cmd );
indicator->hide();
}
#endif
TQPoint QDesignerMenuBar::calcIndicatorPos( const TQPoint &pos )
{
int w = frameWidth();
insertAt = count();
for ( int i = 0; i < (int)count(); ++i ) {
TQRect r = itemRect( i );
if ( pos.x() < w + r.width() / 2 ) {
insertAt = i;
break;
}
w += r.width();
}
return TQPoint( w, 0 );
}
void QDesignerMenuBar::drawIndicator( const TQPoint &pos )
{
if ( lastIndicatorPos == pos )
return;
bool wasVsisible = indicator->isVisible();
indicator->resize( 3, height() );
indicator->move( pos.x() - 1, 0 );
indicator->show();
indicator->raise();
lastIndicatorPos = pos;
if ( !wasVsisible )
TQApplication::sendPostedEvents();
}
void QDesignerMenuBar::setItemNumber( int num )
{
itemNum = num;
}
int QDesignerMenuBar::itemNumber() const
{
return itemNum;
}
void QDesignerMenuBar::setItemText( const TQString &s )
{
if ( itemNum < 0 || itemNum >= (int)count() )
return;
changeItem( idAt( itemNum ), s );
}
TQString QDesignerMenuBar::itemText() const
{
if ( itemNum < 0 || (int)itemNum >= (int)count() )
return TQString::null;
return text( idAt( itemNum ) );
}
void QDesignerMenuBar::setItemName( const TQCString &s )
{
if ( itemNum < 0 || itemNum >= (int)count() )
return;
findItem( idAt( itemNum ) )->popup()->setName( s );
}
TQCString QDesignerMenuBar::itemName() const
{
if ( itemNum < 0 || itemNum >= (int)count() )
return "";
return findItem( idAt( itemNum ) )->popup()->name();
}
QDesignerPopupMenu::QDesignerPopupMenu( TQWidget *w )
: TQPopupMenu( w, 0 ),
popupMenu( 0 )
{
findFormWindow();
setAcceptDrops( true );
insertAt = -1;
mousePressed = false;
lastIndicatorPos = TQPoint( -1, -1 );
indicator = new QDesignerIndicatorWidget( this );
indicator->hide();
}
void QDesignerPopupMenu::contextMenuEvent( TQContextMenuEvent *e )
{
#if defined( Q_WS_MAC ) //the mac needs us to use context menu rather than right click
e->accept();
TQMouseEvent me( TQEvent::MouseButtonPress, e->pos(), e->globalPos(), RightButton, RightButton );
mousePressEvent(&me);
#else
Q_UNUSED( e );
#endif
}
void QDesignerPopupMenu::mousePressEvent( TQMouseEvent *e )
{
if ( e->button() == MidButton )
return;
if ( e->button() == RightButton ) {
// A popup for a popup, we only need one, so make sure that
// we don't create multiple. The timer keeps the event loop sane.
popupPos = e->globalPos();
popupLocalPos = e->pos();
if ( popupMenu ) {
popupMenu->close();
}
e->accept();
TQTimer::singleShot( 0, this, TQT_SLOT(createPopupMenu()) );
return;
}
mousePressed = true;
dragStartPos = e->pos();
TQPopupMenu::mousePressEvent( e );
}
void QDesignerPopupMenu::createPopupMenu()
{
// actually creates our popup for the popupmenu.
TQPopupMenu menu( 0 );
popupMenu = &menu;
int itm;
const int ID_DELETE = 1;
const int ID_SEP = 2;
itm = itemAtPos( popupLocalPos, false );
if ( itm == -1 )
return;
TQAction *a = actionList.at( itm );
if ( a && a->inherits( "QSeparatorAction" ) )
menu.insertItem( i18n("Delete Separator" ), ID_DELETE );
else
menu.insertItem( i18n("Delete Item" ), ID_DELETE );
menu.insertItem( i18n("Insert Separator" ), ID_SEP );
int res = menu.exec( popupPos );
if ( res == ID_DELETE ) {
TQAction *a = actionList.at( itm );
if ( !a )
return;
RemoveActionFromPopupCommand *cmd = new RemoveActionFromPopupCommand(
i18n("Delete Action '%1' From Popup Menu '%2'" ).
arg( a->name() ).arg( caption() ),
formWindow, a, this, itm );
formWindow->commandHistory()->addCommand( cmd );
cmd->execute();
} else if ( res == ID_SEP ) {
TQPoint p( pos() );
calcIndicatorPos( mapFromGlobal( popupPos ) );
TQAction *a = new QSeparatorAction( 0 );
AddActionToPopupCommand *cmd = new AddActionToPopupCommand(
i18n("Add Separator to Popup Menu '%1'" ).
arg( name() ),
formWindow, a, this, insertAt );
formWindow->commandHistory()->addCommand( cmd );
cmd->execute();
( (QDesignerMenuBar*)( (TQMainWindow*)parentWidget() )->menuBar() )->hidePopups();
( (QDesignerMenuBar*)( (TQMainWindow*)parentWidget() )->menuBar() )->activateItemAt( -1 );
popup( p );
}
// set this back to zero so we know a popup (will soon) not exist.
popupMenu = 0;
}
void QDesignerPopupMenu::mouseMoveEvent( TQMouseEvent *e )
{
if ( !mousePressed || e->state() == NoButton ) {
TQPopupMenu::mouseMoveEvent( e );
return;
}
if ( QABS( TQPoint( dragStartPos - e->pos() ).manhattanLength() ) < TQApplication::startDragDistance() ) {
TQPopupMenu::mouseMoveEvent( e );
return;
}
int itm = itemAtPos( dragStartPos, false );
if ( itm == -1 )
return;
TQAction *a = actionList.at( itm );
if ( !a )
return;
RemoveActionFromPopupCommand *cmd = new RemoveActionFromPopupCommand( i18n("Delete Action '%1' From Popup Menu '%2'" ).
arg( a->name() ).arg( caption() ),
formWindow, a, this, itm );
formWindow->commandHistory()->addCommand( cmd );
cmd->execute();
TQString type = a->inherits( "TQActionGroup" ) ? TQString( "application/x-designer-actiongroup" ) :
a->inherits( "QSeparatorAction" ) ? TQString( "application/x-designer-separator" ) : TQString( "application/x-designer-actions" );
TQStoredDrag *drag = new TQStoredDrag( type, this );
TQString s = TQString::number( (long)a ); // #### huha, that is evil
drag->setEncodedData( TQCString( s.latin1() ) );
drag->setPixmap( a->iconSet().pixmap() );
if ( !drag->drag() ) {
AddActionToPopupCommand *cmd = new AddActionToPopupCommand( i18n("Add Action '%1' to Popup Menu '%2'" ).
arg( a->name() ).arg( name() ),
formWindow, a, this, itm );
formWindow->commandHistory()->addCommand( cmd );
cmd->execute();
}
indicator->hide();
lastIndicatorPos = TQPoint( -1, -1 );
mousePressed = false;
}
void QDesignerPopupMenu::mouseReleaseEvent( TQMouseEvent *e )
{
mousePressed = false;
TQPopupMenu::mouseReleaseEvent( e );
}
#ifndef QT_NO_DRAGANDDROP
void QDesignerPopupMenu::dragEnterEvent( TQDragEnterEvent *e )
{
mousePressed = false;
lastIndicatorPos = TQPoint( -1, -1 );
if ( e->provides( "application/x-designer-actions" ) ||
e->provides( "application/x-designer-actiongroup" ) ||
e->provides( "application/x-designer-separator" ) )
e->accept();
}
void QDesignerPopupMenu::dragMoveEvent( TQDragMoveEvent *e )
{
mousePressed = false;
if ( e->provides( "application/x-designer-actions" ) ||
e->provides( "application/x-designer-actiongroup" ) ||
e->provides( "application/x-designer-separator" ) )
e->accept();
else
return;
drawIndicator( calcIndicatorPos( e->pos() ) );
}
void QDesignerPopupMenu::dragLeaveEvent( TQDragLeaveEvent * )
{
mousePressed = false;
indicator->hide();
insertAt = -1;
}
void QDesignerPopupMenu::dropEvent( TQDropEvent *e )
{
mousePressed = false;
if ( e->provides( "application/x-designer-actions" ) ||
e->provides( "application/x-designer-actiongroup" ) ||
e->provides( "application/x-designer-separator" ) )
e->accept();
else
return;
TQPoint p = pos();
TQAction *a = 0;
if ( e->provides( "application/x-designer-actiongroup" ) ) {
TQString s( e->encodedData( "application/x-designer-actiongroup" ) );
a = (QDesignerActionGroup*)s.toLong();
} else {
TQString s;
if ( e->provides( "application/x-designer-separator" ) ) {
s = TQString( e->encodedData( "application/x-designer-separator" ) );
a = (QSeparatorAction*)s.toLong();
} else {
s = TQString( e->encodedData( "application/x-designer-actions" ) );
a = (QDesignerAction*)s.toLong();
}
}
if ( actionList.findRef( a ) != -1 ) {
TQMessageBox::warning( MainWindow::self, i18n("Insert/Move Action" ),
i18n("Action '%1' has already been added to this menu.\n"
"An Action may only occur once in a given menu." ).
arg( a->name() ) );
return;
}
AddActionToPopupCommand *cmd = new AddActionToPopupCommand( i18n("Add Action '%1' to Popup Menu '%2'" ).
arg( a->name() ).arg( name() ),
formWindow, a, this, insertAt );
formWindow->commandHistory()->addCommand( cmd );
cmd->execute();
( (QDesignerMenuBar*)( (TQMainWindow*)parentWidget() )->menuBar() )->hidePopups();
( (QDesignerMenuBar*)( (TQMainWindow*)parentWidget() )->menuBar() )->activateItemAt( -1 );
indicator->hide();
popup( p );
}
#endif
void QDesignerPopupMenu::reInsert()
{
clear();
for ( TQAction *a = actionList.first(); a; a = actionList.next() )
a->addTo( this );
}
void QDesignerPopupMenu::drawIndicator( const TQPoint &pos )
{
if ( lastIndicatorPos == pos )
return;
bool wasVsisible = indicator->isVisible();
indicator->resize( width(), 3 );
indicator->move( 0, pos.y() - 1 );
indicator->show();
indicator->raise();
lastIndicatorPos = pos;
if ( !wasVsisible )
TQApplication::sendPostedEvents();
}
TQPoint QDesignerPopupMenu::calcIndicatorPos( const TQPoint &pos )
{
int h = frameWidth();
insertAt = count();
for ( int i = 0; i < (int)count(); ++i ) {
TQRect r = itemGeometry( i );
if ( pos.y() < h + r.height() / 2 ) {
insertAt = i;
break;
}
h += r.height();
}
return TQPoint( 0, h );
}
void QDesignerPopupMenu::addAction( TQAction *a )
{
actionList.append( a );
connect( a, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( actionRemoved() ) );
}
void QDesignerPopupMenu::actionRemoved()
{
actionList.removeRef( (TQAction*)sender() );
}
void QDesignerPopupMenu::paintEvent( TQPaintEvent *e )
{
TQPopupMenu::paintEvent( e );
if ( e->rect() != rect() )
return;
lastIndicatorPos = TQPoint( -1, -1 );
}
void QDesignerPopupMenu::findFormWindow()
{
TQWidget *w = this;
while ( w ) {
if ( w->inherits( "FormWindow" ) )
formWindow = (FormWindow*)w;
w = w->parentWidget();
}
}
#include "actiondnd.moc"