📄 ncreportdesignerdesignarea.cpp
字号:
/*************************************************************************** * Copyright (C) 2006 by Szab贸 Norbert * * nszabo@helta.hu * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/#include "ncreportdesignerdesignarea.h"#include "ncreportdesignerwindow.h"#include "ncreportdesignerdocument.h"#include "ncreportdesignersizehandler.h"#include "ncreportdesignerwidgetfactory.h"#include "ncreportdesignerwidget.h"#include "ncreportdesignerresourcehandler.h"#include "ncreportdesignerwidgetsetdialog.h"//#include <stdlib.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 <qmenu>#include <qsizegrip.h>#include <qpushbutton.h>#include <qwhatsthis.h>#include <qmetaobject.h>#include <qtooltip.h>//#include <qcloseevent.h>#include <qpixmapcache.h>#include <qbitmap.h>#include <qsplitter.h>#include <qwidgetlist.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() && !::qt_cast<SizeHandler*>(o) ) setCursorToAll( c, ( (QWidget*)o ) ); } }}static void restoreCursors( QWidget *start, NCReportDesignerDesignArea *area ){ if ( area->widgets()->find( start ) ) start->setCursor( Qt::ArrowCursor ); //start->setCursor( MetaDataBase::cursor( start ) ); else start->setCursor( Qt::ArrowCursor ); QObjectList *l = (QObjectList*)start->children(); if ( l ) { for ( QObject *o = l->first(); o; o = l->next() ) { if ( o->isWidgetType() && !::qt_cast<SizeHandler*>(o) ) restoreCursors( ( (QWidget*)o ), area ); } }}/*! \class NCReportDesignerDesignArea NCReportDesignerDesignArea.h \brief edit workplace section for the designer The NCReportDesignerDesignArea is the widget which is used as editor for forms. It handles inserting, deleting, moving, resizing, etc. of widgets. Normally multiple NCReportDesignerDesignAreas are used at the same time in the Designer. So each NCReportDesignerDesignArea has its own undo/redo buffer, etc. 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(). */NCReportDesignerDesignArea::NCReportDesignerDesignArea( NCReportDesignerWindow *mw, QWidget *parent, const char* name, Qt::WFlags f ) : QWidget( parent, name, f ), mwindow( mw ), commands( 100 ), pixInline( TRUE ), pixProject( FALSE ){ init(); initSlots();}NCReportDesignerDesignArea::NCReportDesignerDesignArea( QWidget *parent, const char* name, Qt::WFlags f ) : QWidget( parent, name, f ), mwindow( 0 ), commands( 100 ), pixInline( TRUE ){ init();}void NCReportDesignerDesignArea::init(){ propertyWidget = 0; toolFixed = FALSE; checkedSelectionsForMove = FALSE; mContainer = 0; startWidget = endWidget = 0; currTool = PointerTool; 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( QPixmap::fromMimeSource( "designer_form.png" ) ); //connect( &commands, SIGNAL( modificationChanged( bool ) ), this, SLOT( modificationChanged( bool ) ) ); buffer = 0; color1 = QColor( 128,128,128); propertyWidget = 0; targetContainer = 0; hadOwnPalette = FALSE; hasLayoutFunc = FALSE; //setBackgroundRole( QPalette::Base ); setPaletteBackgroundColor ( Qt::white ); sizePreview(); setFocusPolicy( StrongFocus ); //setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed) );}QSize NCReportDesignerDesignArea::sizeHint() const{ //return QSize( width(), height() ); return QWidget::sizeHint();}void NCReportDesignerDesignArea::setMainWindow( NCReportDesignerWindow *w ){ mwindow = w; initSlots();}void NCReportDesignerDesignArea::initSlots(){}NCReportDesignerDesignArea::~NCReportDesignerDesignArea(){ /* if ( MainWindow::self && MainWindow::self->objectHierarchy()->NCReportDesignerDesignArea() == this ) MainWindow::self->objectHierarchy()->setNCReportDesignerDesignArea( 0, 0 ); MetaDataBase::clear( this ); */}void NCReportDesignerDesignArea::closeEvent( QCloseEvent *e ){ e->accept();}void NCReportDesignerDesignArea::paintEvent( QPaintEvent *e ){ QWidget::paintEvent(e); QPainter p(this); paintGrid( p ); //p.drawLine(width()-1,0,width()-1,height()); if ( hasFocus() ) paintFocus( &p, true );}void NCReportDesignerDesignArea::paintGrid( QPainter& p ){ if ( !mainWindow() || !mainWindow()->showGrid() ) return; p.setPen( color1 ); for ( int y = 0; y < height(); y += mainWindow()->grid().y()) { for ( int x = 0; x < width(); x += mainWindow()->grid().x() ) p.drawPoint( x, y ); }}// void NCReportDesignerDesignArea::paintGrid( QWidget *w, QPaintEvent *e )// {// if ( !mainWindow() || !mainWindow()->showGrid() )// return;// QPixmap grid;// QString grid_name;// grid_name.sprintf("NCReportDesignerDesignAreaGrid_%d_%d", mainWindow()->grid().x(), mainWindow()->grid().y());// if( !QPixmapCache::find( grid_name, grid ) ) {// grid = QPixmap( 350 + ( 350 % mainWindow()->grid().x() ), 350 + ( 350 % mainWindow()->grid().y() ) );// //grid.fill( QPalette::Foreground );// grid.fill( colorGroup().color( QColorGroup::Foreground ) );// QBitmap mask( grid.width(), grid.height() );// mask.fill( color0 );// QPainter p( &mask );// p.setPen( color1 );// for ( int y = 0; y < grid.width(); y += mainWindow()->grid().y()) {// for ( int x = 0; x < grid.height(); x += mainWindow()->grid().x() ) {// p.drawPoint( x, y );// }// }// grid.setMask( mask );// QPixmapCache::insert( grid_name, grid );// }// QPainter p( w );// p.setClipRegion( e->rect() );// p.drawTiledPixmap( QRect( 0, 0, width(), height() ), grid );// }/*! 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 NCReportDesignerDesignArea::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( black, 2 ) ); unclippedPainter->setRasterOp( NotROP ); }}/*! Gets rid of an open unclipped painter. \sa beginUnclippedPainter() */void NCReportDesignerDesignArea::endUnclippedPainter(){ if ( unclippedPainter ) unclippedPainter->end(); delete unclippedPainter; unclippedPainter = 0;}QPoint NCReportDesignerDesignArea::gridPoint( const QPoint &p ){ return QPoint( ( p.x() / grid().x() ) * grid().x(), ( p.y() / grid().y() ) * grid().y() );}void NCReportDesignerDesignArea::insertWidget(){ if ( !insertParent ) return; if ( currTool == PointerTool ) return; QWidget *w = NCReportDesignerWidgetFactory::create( mainWindow()->currentTool(), insertParent, 0, TRUE, &currRect ); if ( !w ) return; //bool useSizeHint = !oldRectValid || ( currRect.width() < 2 && currRect.height() < 2 ); QString n; //= WidgetDatabase::className( currTool ); //QString s = w->name(); //w->setName( s ); 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 ( 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; */ if ( !toolFixed ) mwindow->resetTools(); else setCursorToAll( CrossCursor, w ); cmd_InsertCommand *cmd = new cmd_InsertCommand( tr( "Insert %1" ).arg( w->name() ), this, w, r ); commandHistory()->addCommand( cmd ); cmd->execute(); NCReportDesignerWidget *dw = (NCReportDesignerWidget*)w; if ( dw && dw->initOpenPropDia ) runWidgetSettingsDialog( dw, TRUE ); // inti mode }void NCReportDesignerDesignArea::insertWidget( QWidget *w, bool checkName ){ if ( !w ) return; if ( checkName ) { QString s = w->name(); w->setName( s ); } //int id = 0; //WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) ); 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 NCReportDesignerDesignArea::removeWidget( QWidget *w ){ widgets()->take( w );}void NCReportDesignerDesignArea::handleContextMenu( QContextMenuEvent *e, QWidget * ){ switch ( currTool ) { case PointerTool: { e->accept(); clearSelection(); //mwindow->popupNCReportDesignerDesignAreaMenu( e->globalPos(), this ); break; } default: break; }}void NCReportDesignerDesignArea::handleMousePress( QMouseEvent *e, QWidget *w ){ checkedSelectionsForMove = FALSE; //checkSelectionsTimer->stop(); if ( !hasFocus() ) setFocus(); switch ( currTool ) { case PointerTool: if ( w == this ) { if ( e->button() == LeftButton ) { // left button: start rubber selection and show NCReportDesignerDesignArea properties drawRubber = TRUE; if ( !( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) ) { clearSelection( FALSE ); //QObject *opw = propertyWidget; //propertyWidget = mainContainer(); //if ( opw->isWidgetType() ) // repaintSelection( (QWidget*)opw ); } currRect = QRect( 0, 0, -1, -1 ); startRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber ); } } else { //w->raise(); // el鮰閞be hoz if ( ( e->state() & ControlButton ) ) { // with control pressed, always start rubber band selection drawRubber = TRUE; currRect = QRect( 0, 0, -1, -1 ); startRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber ); break; } bool sel = isWidgetSelected( w ); if ( !( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) ) { // control not pressed... if ( !sel ) { // ...and widget no selectted: unselect all clearSelection( FALSE ); } else { // ...widget selected QObjectList *l = w->queryList( "QWidget" ); //setPropertyShowingBlocked( TRUE ); for ( QObject *o = l->first(); o; o = l->next() ) { if ( !o->isWidgetType() ) continue; if ( insertedWidgets.find( (QWidget*)o ) ) selectWidget( (QWidget*)o, FALSE ); } //setPropertyShowingBlocked( FALSE ); delete l; } qApp->processEvents(); } if ( ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) && sel && e->button() == LeftButton ) { // control pressed and selected, unselect widget selectWidget( w, FALSE ); break; } //raiseChildSelections( w ); // raise selections and select widget selectWidget( w ); if ( e->button() == LeftButton ) { // left button: store original geometry and more as the widget might start moving widgetPressed = TRUE; widgetGeom = QRect( w->pos(), w->size() ); oldPressPos = w->mapFromGlobal( e->globalPos() ); origPressPos = oldPressPos; checkedSelectionsForMove = FALSE; moving.clear(); /* if ( w->parentWidget() && !isMainContainer( w->parentWidget() ) && !isCentralWidget( w->parentWidget() ) ) { targetContainer = w->parentWidget(); hadOwnPalette = w->parentWidget()->ownPalette(); restorePalette = w->parentWidget()->palette(); } */ } } break; default: // any insert widget tool if ( e->button() == LeftButton ) { insertParent = this; //WidgetFactory::containerOfWidget( mainContainer() ); // default parent for new widget is the NCReportDesignerDesignArea startRectDraw( w->mapFromGlobal( e->globalPos() ), e->globalPos(), w, Insert ); } break; } }void NCReportDesignerDesignArea::handleMouseDblClick( QMouseEvent *, QWidget *w ){ if ( w == this ) return; NCReportDesignerWidget *dw = (NCReportDesignerWidget*)w; switch ( currTool ) { case PointerTool: { // open property dialog runWidgetSettingsDialog( dw ); break; } default:/* if ( !WidgetFactory::isPassiveInteractor( w ) && ( isMainContainer( w ) || w == this ) ) mainWindow()->editSource();*/ break; }}void NCReportDesignerDesignArea::handleMouseMove( QMouseEvent *e, QWidget *w ){ if ( ( e->state() & LeftButton ) != LeftButton ) return; //QWidget *newendWidget = endWidget, *oldendWidget = endWidget, *wid; //bool drawRecRect; switch ( currTool ) { case PointerTool: if ( widgetPressed && allowMove( w ) ) { // we are prepated for a move // calc correct position QPoint pos = w->mapFromGlobal( e->globalPos() ); // calc move distance and store it QPoint d = oldPressPos - pos; if ( QABS( d.x() ) < grid().x() ) d.setX( 0 ); if ( QABS( d.y() ) < grid().y() ) d.setY( 0 ); if ( d.x() == 0 ) pos.setX( oldPressPos.x() ); if ( d.y() == 0 ) pos.setY( oldPressPos.y() ); oldPressPos = pos; // snap to grid int x = widgetGeom.x() - d.x(); widgetGeom.setX( x ); x = ( x / grid().x() ) * grid().x(); int y = widgetGeom.y() - d.y(); widgetGeom.setY( y ); y = ( y / grid().y() ) * grid().y(); QPoint p = w->pos(); if ( x - p.x() != 0 || y - p.y() != 0 ) { // if we actually have to move if ( !checkedSelectionsForMove ) { // if not checked yet, check if the correct widget are selected... if ( !isWidgetSelected( w ) ) { // and unselect others. Only siblings can be moved at the same time //setPropertyShowingBlocked( TRUE ); selectWidget( w ); //setPropertyShowingBlocked( FALSE ); } checkSelectionsForMove( w ); } // check whether we would have to reparent the selection and highlight the possible new parent container QMapConstIterator<QWidget*, QPoint> it = moving.begin(); //QWidget* wa = containerAt( e->globalPos(), it.key() ); // finally move the selected widgets and show/update preview label moveSelectedWidgets( x - p.x(), y - p.y() ); //sizePreviewLabel->setText( tr( "%1/%2" ).arg( w->pos().x() ).arg( w->pos().y() ) ); sizePreviewLabel->setText( m->pixelPosToMeasureCaption( w->pos().x(), w->pos().y() ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -