/**********************************************************************
** Copyright (C) 2000 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.
**
** 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.
**
**********************************************************************/

#ifndef ACTIONDND_H
#define ACTIONDND_H

#include <tqaction.h>
#include <tqmap.h>
#include <tqmenubar.h>
#include <tqpixmap.h>
#include <tqpopupmenu.h>
#include <tqptrlist.h>
#include <tqtoolbar.h>
#include <tqguardedptr.h>

class QDesignerPopupMenu;
class QDesignerIndicatorWidget;
class FormWindow;

class QDesignerActionGroup : public TQActionGroup
{
    Q_OBJECT
  

public:
    QDesignerActionGroup( TQObject *parent )
	: TQActionGroup( !parent || parent->inherits( "TQActionGroup" ) ? parent : 0 ), wid( 0 ), idx( -1 ) {}

    TQWidget *widget() const { return wid; }
    TQWidget *widget( TQAction *a ) const { return *widgets.find( a ); }
    int index() const { return idx; }

protected:
    void addedTo( TQWidget *w, TQWidget * ) {
	wid = w;
    }
    void addedTo( TQWidget *w, TQWidget *, TQAction *a ) {
	widgets.insert( a, w );
    }
    void addedTo( int index, TQPopupMenu * ) {
	idx = index;
    }

private:
    TQWidget *wid;
    TQMap<TQAction *, TQWidget *> widgets;
    int idx;

};

class QDesignerAction : public TQAction
{
    Q_OBJECT
  

public:
    QDesignerAction( TQObject *parent )
	: TQAction( !parent || parent->inherits( "TQActionGroup" ) ? parent : 0 ), wid( 0 ), idx( -1 ), widgetToInsert( 0 ) {}
    QDesignerAction( TQWidget *w, TQObject *parent )
	: TQAction( !parent || parent->inherits( "TQActionGroup" ) ? parent : 0 ), wid( 0 ), idx( -1 ), widgetToInsert( w ) {}

    TQWidget *widget() const { return wid; }
    int index() const { return idx; }

    bool addTo( TQWidget *w );
    bool removeFrom( TQWidget *w );

    void remove();
    bool supportsMenu() const { return !widgetToInsert; }

protected:
    void addedTo( TQWidget *w, TQWidget * ) {
	wid = w;
    }
    void addedTo( int index, TQPopupMenu * ) {
	idx = index;
    }

private:
    TQWidget *wid;
    int idx;
    TQWidget *widgetToInsert;

};

class QDesignerToolBarSeparator : public TQWidget
{
    Q_OBJECT
  

public:
    QDesignerToolBarSeparator( Orientation, TQToolBar *parent, const char* name=0 );

    TQSize sizeHint() const;
    Orientation orientation() const { return orient; }
public slots:
   void setOrientation( Orientation );
protected:
    void styleChange( TQStyle& );
    void paintEvent( TQPaintEvent * );
private:
    Orientation orient;
};


class QSeparatorAction : public TQAction
{
    Q_OBJECT
  

public:
    QSeparatorAction( TQObject *parent );

    bool addTo( TQWidget *w );
    bool removeFrom( TQWidget *w );
    TQWidget *widget() const;
    int index() const;

private:
    TQWidget *wid;
    int idx;

};

class QDesignerToolBar : public TQToolBar
{
    Q_OBJECT
  

public:
    QDesignerToolBar( TQMainWindow *mw );
    QDesignerToolBar( TQMainWindow *mw, Dock dock );
    TQPtrList<TQAction> insertedActions() const { return actionList; }
    void addAction( TQAction *a );

    void clear();
    void installEventFilters( TQWidget *w );
    void insertAction( TQWidget *w, TQAction *a ) { actionMap.insert( w, a ); }
    void insertAction( int index, TQAction *a ) { actionList.insert( index, a ); }
    void appendAction( TQAction *a ) { actionList.append( a ); }
    void removeAction( TQAction *a ) { actionList.remove( a ); }
    void reInsert();
    void removeWidget( TQWidget *w );

protected:
    bool eventFilter( TQObject *, TQEvent * );
    void paintEvent( TQPaintEvent * );
#ifndef TQT_NO_DRAGANDDROP
    void dragEnterEvent( TQDragEnterEvent * );
    void dragMoveEvent( TQDragMoveEvent * );
    void dragLeaveEvent( TQDragLeaveEvent * );
    void dropEvent( TQDropEvent * );
#endif
    void contextMenuEvent( TQContextMenuEvent *e );
    void mousePressEvent( TQMouseEvent *e );
    void mouseReleaseEvent( TQMouseEvent *e );

private slots:
    void actionRemoved();

private:
    void drawIndicator( const TQPoint &pos );
    TQPoint calcIndicatorPos( const TQPoint &pos );
    void buttonContextMenuEvent( TQContextMenuEvent *e, TQObject *o );
    void buttonMousePressEvent( TQMouseEvent *e, TQObject *o );
    void buttonMouseMoveEvent( TQMouseEvent *e, TQObject *o );
    void buttonMouseReleaseEvent( TQMouseEvent *e, TQObject *o );
    void doInsertWidget( const TQPoint &p );
    void findFormWindow();

private:
    TQPoint lastIndicatorPos;
    TQWidget *insertAnchor;
    bool afterAnchor;
    TQPtrList<TQAction> actionList;
    TQMap<TQWidget*, TQAction*> actionMap;
    TQPoint dragStartPos;
    QDesignerIndicatorWidget *indicator;
    bool widgetInserting;
    FormWindow *formWindow;

};

class QDesignerMenuBar : public TQMenuBar
{
    Q_OBJECT
  
    friend class QDesignerPopupMenu;

    TQ_PROPERTY( int itemNumber WRITE setItemNumber READ itemNumber )
    TQ_PROPERTY( TQString itemText WRITE setItemText READ itemText )
    TQ_PROPERTY( TQCString itemName WRITE setItemName READ itemName )

public:
    QDesignerMenuBar( TQWidget *mw );

    void setItemNumber( int num );
    int itemNumber() const;
    void setItemText( const TQString &s );
    TQString itemText() const;
    void setItemName( const TQCString &s );
    TQCString itemName() const;

protected:
    void mousePressEvent( TQMouseEvent *e );
    void mouseMoveEvent( TQMouseEvent *e );
    void mouseReleaseEvent( TQMouseEvent *e );
    void contextMenuEvent( TQContextMenuEvent *e );
#ifndef TQT_NO_DRAGANDDROP
    void dragEnterEvent( TQDragEnterEvent * );
    void dragMoveEvent( TQDragMoveEvent * );
    void dragLeaveEvent( TQDragLeaveEvent * );
    void dropEvent( TQDropEvent * );
#endif

private:
    void drawIndicator( const TQPoint &pos );
    TQPoint calcIndicatorPos( const TQPoint &pos );
    void findFormWindow();

private:
    int itemNum;
    TQPoint dragStartPos;
    bool mousePressed;
    TQPoint lastIndicatorPos;
    int insertAt;
    QDesignerIndicatorWidget *indicator;
    FormWindow *formWindow;
    int oldPos;

};

class QDesignerPopupMenu : public TQPopupMenu
{
    Q_OBJECT
  

public:
    QDesignerPopupMenu( TQWidget *w );
    TQPtrList<TQAction> insertedActions() const { return actionList; }
    void addAction( TQAction *a );
    void reInsert();
    void insertAction( int index, TQAction *a ) { actionList.insert( index, a ); }
    void removeAction( TQAction *a ) { actionList.remove( a ); }

protected:
    void mousePressEvent( TQMouseEvent *e );
    void mouseMoveEvent( TQMouseEvent *e );
    void mouseReleaseEvent( TQMouseEvent *e );
    void contextMenuEvent( TQContextMenuEvent *e );
    void paintEvent( TQPaintEvent * );
#ifndef TQT_NO_DRAGANDDROP
    void dragEnterEvent( TQDragEnterEvent * );
    void dragMoveEvent( TQDragMoveEvent * );
    void dragLeaveEvent( TQDragLeaveEvent * );
    void dropEvent( TQDropEvent * );
#endif

private slots:
    void actionRemoved();
    void createPopupMenu();

private:
    void drawIndicator( const TQPoint &pos );
    TQPoint calcIndicatorPos( const TQPoint &pos );
    void findFormWindow();

private:
    TQPoint lastIndicatorPos;
    int insertAt;
    TQPtrList<TQAction> actionList;
    TQPoint dragStartPos;
    bool mousePressed;
    QDesignerIndicatorWidget *indicator;
    FormWindow *formWindow;
    TQGuardedPtr<TQPopupMenu> popupMenu;
    TQPoint popupPos;
    TQPoint popupLocalPos;

};

class QDesignerIndicatorWidget : public TQWidget
{
    Q_OBJECT
  

public:
    QDesignerIndicatorWidget( TQWidget *p )
	: TQWidget( p, "qt_dockwidget_internal" ) {
	    setBackgroundColor( red );
    }

};

#endif
