⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 formwindow.cpp

📁 Trolltech公司发布的基于C++图形开发环境
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/************************************************************************ 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 "formwindow.h"#include "defs.h"#include "mainwindow.h"#include "widgetfactory.h"#include "sizehandle.h"#include "metadatabase.h"#include "resource.h"#include "layout.h"#include "connectioneditorimpl.h"#include <widgetdatabase.h>#include "pixmapchooser.h"#include "orderindicator.h"#include "hierarchyview.h"#include <qevent.h>#include <qpainter.h>#include <qpen.h>#include <qlabel.h>#include <qobjectlist.h>#include <qtimer.h>#include <qapplication.h>#include <qlayout.h>#include <qspinbox.h>#include <qstatusbar.h>#include <qapplication.h>#include <qpalette.h>#include <qmessagebox.h>#include <qpopupmenu.h>#include <qsizegrip.h>#include <qpushbutton.h>#include <qwhatsthis.h>#include <qmetaobject.h>#include <qtooltip.h>static void setCursorToAll( const QCursor &c, QWidget *start ){    start->setCursor( c );    QObjectList *l = (QObjectList*)start->children();    if ( l ) {	for ( QObject *o = l->first(); o; o = l->next() ) {	    if ( o->isWidgetType() && !o->inherits( "SizeHandle" ) )		setCursorToAll( c, ( (QWidget*)o ) );	}    }}static void restoreCursors( QWidget *start, FormWindow *fw ){    if ( fw->widgets()->find( start ) )	start->setCursor( MetaDataBase::cursor( start ) );    else	start->setCursor( ArrowCursor );    QObjectList *l = (QObjectList*)start->children();    if ( l ) {	for ( QObject *o = l->first(); o; o = l->next() ) {	    if ( o->isWidgetType() && !o->inherits( "SizeHandle" ) )		restoreCursors( ( (QWidget*)o ), fw );	}    }}#if defined(_WS_WIN32_) // #### needed for the workaround for repaint problem on windows#include <qt_windows.h>static void flickerfree_update( QWidget *w ){    InvalidateRect( w->winId(), 0, FALSE );}#endif/*!  \class FormWindow formwindow.h  \brief Editor window for a form  The FormWindow is the widget which is used as editor for forms. It  handles inserting, deleting, moving, resizing, etc. of widgets.  Normally multiple formwindows are used at the same time in the  Designer. So each formwindow has its own undo/redo buffer, etc.  Also the formwindow has some signals to inform e.g. about selection  changes which is interesting for the PropertyEditor.  For handling the events of the child widgets (moving, etc.) the  handleMousePress(), etc. functions are called from the application  event filter which is implemented in MainWindow::eventFilter().*/FormWindow::FormWindow( MainWindow *mw, QWidget *parent, const char *name )    : QWidget( parent, name, WDestructiveClose ), mainwindow( mw ),      commands( 100 ), pixInline( TRUE ){    init();}FormWindow::FormWindow( QWidget *parent, const char *name )    : QWidget( parent, name, WDestructiveClose ), mainwindow( 0 ),      commands( 100 ), pixInline( TRUE ){    init();}void FormWindow::init(){    toolFixed = FALSE;    checkedSelectionsForMove = FALSE;    mContainer = 0;    connectSender = connectReceiver = 0;    currTool = POINTER_TOOL;    unclippedPainter = 0;    widgetPressed = FALSE;    drawRubber = FALSE;    setFocusPolicy( ClickFocus );    sizePreviewLabel = 0;    checkSelectionsTimer = new QTimer( this, "checkSelectionsTimer" );    connect( checkSelectionsTimer, SIGNAL( timeout() ),	     this, SLOT( invalidCheckedSelections() ) );    updatePropertiesTimer = new QTimer( this );    connect( updatePropertiesTimer, SIGNAL( timeout() ),	     this, SLOT( updatePropertiesTimerDone() ) );    showPropertiesTimer = new QTimer( this );    connect( showPropertiesTimer, SIGNAL( timeout() ),	     this, SLOT( showPropertiesTimerDone() ) );    selectionChangedTimer = new QTimer( this );    connect( selectionChangedTimer, SIGNAL( timeout() ),	     this, SLOT( selectionChangedTimerDone() ) );    windowsRepaintWorkaroundTimer = new QTimer( this );    connect( windowsRepaintWorkaroundTimer, SIGNAL( timeout() ),	     this, SLOT( windowsRepaintWorkaroundTimerTimeout() ) );    insertParent = 0;    connect( &commands, SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ),	     this, SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ) );    propShowBlocked = FALSE;    setIcon( PixmapChooser::loadPixmap( "form.xpm", PixmapChooser::Mini ) );    connect( &commands, SIGNAL( modificationChanged( bool ) ),	     this, SLOT( modificationChanged( bool ) ) );    buffer = 0;    QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QFrame" ), this );    setMainContainer( w );    propertyWidget = w;}void FormWindow::setMainWindow( MainWindow *w ){    mainwindow = w;}FormWindow::~FormWindow(){}void FormWindow::closeEvent( QCloseEvent *e ){    if ( mainwindow->unregisterClient( this ) )	e->accept();    else	e->ignore();}void FormWindow::paintGrid( QWidget *w, QPaintEvent *e ){    if ( !mainWindow()->showGrid() )	return;    int x = 0, y = 0, jmax = 0;    QPainter p( w );    p.setClipRegion( e->rect() );    p.setPen( colorGroup().foreground() );    jmax = w->height() / mainWindow()->grid().y() + 20;    int end = w->width() / mainWindow()->grid().x() + 20;    for ( int i = 0; i < end; ++i ) {	y = 0;	for ( int j = 0; j < jmax; ++j ) {	    p.drawPoint( x, y );	    y += mainWindow()->grid().y();	}	x += mainWindow()->grid().x();    }}/*!  For operations like drawing a rubber band or drawing the rect  when inserting a new widget, a unclipped painter (which draws also  on child widgets) is needed. This method does all the initialization.*/void FormWindow::beginUnclippedPainter( bool doNot ){    endUnclippedPainter();    bool unclipped = testWFlags( WPaintUnclipped );    setWFlags( WPaintUnclipped );    unclippedPainter = new QPainter;    unclippedPainter->begin( this );    if ( !unclipped )	clearWFlags( WPaintUnclipped );    if ( doNot ) {	unclippedPainter->setPen( QPen( color0, 2 ) );	unclippedPainter->setRasterOp( NotROP );    }}/*!  Gets rid of an open unclipped painter.  \sa beginUnclippedPainter()*/void FormWindow::endUnclippedPainter(){    if ( unclippedPainter )	unclippedPainter->end();    delete unclippedPainter;    unclippedPainter = 0;}QPoint FormWindow::gridPoint( const QPoint &p ){    return QPoint( ( p.x() / grid().x() ) * grid().x(),		   ( p.y() / grid().y() ) * grid().y() );}void FormWindow::drawSizePreview( const QPoint &pos, const QString& text ){    unclippedPainter->save();    unclippedPainter->setPen( QPen( colorGroup().foreground(), 1  ));    unclippedPainter->setRasterOp( CopyROP );    if ( !sizePreviewPixmap.isNull() )	unclippedPainter->drawPixmap( sizePreviewPos, sizePreviewPixmap );    if ( text.isNull() ) {	sizePreviewPixmap = QPixmap(); // set null again	unclippedPainter->restore();	return;    }    QRect r  =  fontMetrics().boundingRect( 0, 0, 0, 0, AlignCenter, text );    r = QRect( pos + QPoint( 10, 10 ), r.size() + QSize( 5, 5 ) );    checkPreviewGeometry( r );    sizePreviewPos = r.topLeft();    sizePreviewPixmap = QPixmap::grabWindow( winId(), r.x(), r.y(), r.width(), r.height() );    unclippedPainter->setBrush( QColor( 255, 255, 128 ) );    unclippedPainter->drawRect( r );    unclippedPainter->drawText( r, AlignCenter, text );    unclippedPainter->restore();}void FormWindow::insertWidget(){    if ( currTool == POINTER_TOOL )	return;    bool useSizeHint = !oldRectValid || ( currRect.width() < 2 && currRect.height() < 2 );    Orientation orient = Horizontal;    QString n = WidgetDatabase::className( currTool );    if (  useSizeHint && ( n == "Spacer" || n == "QSlider" || n == "Line" ) ) {	QPopupMenu m( mainWindow() );	m.insertItem( tr( "&Horizontal" ) );	int ver = m.insertItem( tr( "&Vertical" ) );	int r = m.exec( QCursor::pos() );	if ( r == ver )	    orient = Vertical;    }	    QWidget *w = WidgetFactory::create( currTool, insertParent, 0, TRUE, &currRect, orient );    if ( !w )	return;    if ( !savePixmapInline() && currTool == WidgetDatabase::idFromClassName( "PixmapLabel" ) )	( (QLabel*)w )->setPixmap( PixmapChooser::loadPixmap( "image.xpm" ) );    int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) );    if ( WidgetDatabase::isCustomWidget( id ) ) {	QWhatsThis::add( w, tr("<b>A %1 (custom widget)</b> "			    "<p>Select <b>Edit Custom Widgets...</b> in the <b>Tools->Custom</b> "			    "menu to add and change the custom widgets. You can add "			    "properties as well as signals and slots to integrate them into the "			    "designer, and provide a pixmap which will be used to represent "			    "the widget on the form.</p>")			    .arg(WidgetDatabase::toolTip( id )) );	QToolTip::add( w, tr("A %1 (custom widget)").arg(WidgetDatabase::toolTip( id )) );    } else {	QString tt = WidgetDatabase::toolTip( id );	QString wt = WidgetDatabase::whatsThis( id );	if ( !wt.isEmpty() && !tt.isEmpty() )	    QWhatsThis::add( w, QString("<b>A %1</b><p>%2</p>").arg( tt ).arg( wt ) );    }    QString s = w->name();    unify( w, s, TRUE );    w->setName( s );    if ( !w )	return;    insertWidget( w );    QRect r( currRect );    if ( !oldRectValid ||	 ( currRect.width() < 2 && currRect.height() < 2 ) )	r = QRect( rectAnchor, QSize( 0, 0 ) );    QPoint p = r.topLeft();    p = mapToGlobal( p );    p = insertParent->mapFromGlobal( p );    r = QRect( p, r.size() );    if ( useSizeHint ) {	r.setWidth( w->sizeHint().width() );	r.setHeight( w->sizeHint().height() );    }    if ( r.width() < 2 * grid().x() )	r.setWidth( 2 * grid().x() );    if ( r.height() < 2 * grid().y() )	r.setHeight( 2 * grid().y() );    const QObjectList *l = insertParent->children();    QObjectListIt it( *l );    QWidgetList lst;    for ( ; it.current(); ) {	QObject *o = it.current();	++it;	if ( o->isWidgetType() &&	     ( (QWidget*)o )->isVisibleTo( this ) &&	     insertedWidgets.find( (QWidget*)o ) && o != w ) {	    QRect r2( ( (QWidget*)o )->pos(),		      ( (QWidget*)o )->size() );	    if ( r.contains( r2 ) )		lst.append( (QWidget*)o );	}    }    if ( !lst.isEmpty() ) {	QWidget *pw = WidgetFactory::containerOfWidget( w );	QValueList<QPoint> op, np;	for ( QWidget *i = lst.first(); i; i = lst.next() ) {	    op.append( i->pos() );	    QPoint pos = pw->mapFromGlobal( i->mapToGlobal( QPoint( 0, 0 ) ) );	    pos -= r.topLeft();	    np.append( pos );	}	MoveCommand *mv = new MoveCommand( tr( "Reparent Widgets" ), this, lst, op, np, insertParent, pw );	if ( !toolFixed )	    mainwindow->resetTool();	else	    setCursorToAll( CrossCursor, w );	InsertCommand *cmd = new InsertCommand( tr( "Insert %1" ).arg( w->name() ), this, w, r );	QList<Command> commands;	commands.append( mv );	commands.append( cmd );		MacroCommand *mc = new MacroCommand( tr( "Insert %1" ).arg( w->name() ), this, commands );	commandHistory()->addCommand( mc );	mc->execute();    } else {	if ( !toolFixed )	    mainwindow->resetTool();	else	    setCursorToAll( CrossCursor, w );	InsertCommand *cmd = new InsertCommand( tr( "Insert %1" ).arg( w->name() ), this, w, r );	commandHistory()->addCommand( cmd );	cmd->execute();    }}void FormWindow::insertWidget( QWidget *w, bool checkName ){    if ( checkName ) {	QString s = w->name();	unify( w, s, TRUE );	w->setName( s );    }    MetaDataBase::addEntry( w );    int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) );    if ( WidgetDatabase::isCustomWidget( id ) ) {	QWhatsThis::add( w, tr("<b>A %1 (custom widget)</b> "			    "<p>Select <b>Edit Custom Widgets...</b> in the <b>Tools->Custom</b> "			    "menu to add and change the custom widgets. You can add "			    "properties as well as signals and slots to integrate them into the "			    "designer, and provide a pixmap which will be used to represent "			    "the widget on the form.</p>")			    .arg(WidgetDatabase::toolTip( id )) );	QToolTip::add( w, tr("A %1 (custom widget)").arg(WidgetDatabase::toolTip( id )) );    } else {	QString tt = WidgetDatabase::toolTip( id );	QString wt = WidgetDatabase::whatsThis( id );	if ( !wt.isEmpty() && !tt.isEmpty() )	    QWhatsThis::add( w, QString("<b>A %1</b><p>%2</p>").arg( tt ).arg( wt ) );    }    restoreCursors( w, this );    widgets()->insert( w, w );    w->show();}void FormWindow::removeWidget( QWidget *w ){    MetaDataBase::removeEntry( w );    widgets()->take( w );}void FormWindow::handleMousePress( QMouseEvent *e, QWidget *w ){    checkedSelectionsForMove = FALSE;    checkSelectionsTimer->stop();    if ( !sizePreviewLabel ) {	sizePreviewLabel = new QLabel( this );	sizePreviewLabel->hide();	sizePreviewLabel->setBackgroundColor( QColor( 255, 255, 128 ) );	sizePreviewLabel->setFrameStyle( QFrame::Plain | QFrame::Box );    }    switch ( currTool ) {    case POINTER_TOOL:	if ( !isMainContainer( w ) ) { // press on a child widget	    // if the clicked widget is not in a layout, raise it

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -