1
/**********************************************************************
2
** Copyright (C) 2000 Trolltech AS. All rights reserved.
4
** This file is part of Qt Designer.
6
** This file may be distributed and/or modified under the terms of the
7
** GNU General Public License version 2 as published by the Free Software
8
** Foundation and appearing in the file LICENSE.GPL included in the
9
** packaging of this file.
11
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
12
** licenses may use this file in accordance with the Qt Commercial License
13
** Agreement provided with the Software.
15
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18
** See http://www.trolltech.com/gpl/ for GPL licensing information.
19
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
20
** information about Qt Commercial License Agreements.
22
** Contact info@trolltech.com if any conditions of this licensing are
25
**********************************************************************/
27
#include "formwindow.h"
29
#include "mainwindow.h"
30
#include "widgetfactory.h"
31
#include "sizehandle.h"
32
#include "metadatabase.h"
35
#include "connectiondialog.h"
36
#include <widgetdatabase.h>
37
#include "pixmapchooser.h"
38
#include "orderindicator.h"
39
#include "hierarchyview.h"
40
#include "designerappiface.h"
41
#include "menubareditor.h"
42
#define NO_STATIC_COLORS
43
#include "globaldefs.h"
47
#include <kiconloader.h>
49
#include "kdevdesigner_part.h"
55
#include <qobjectlist.h>
57
#include <qapplication.h>
60
#include <qstatusbar.h>
61
#include <qapplication.h>
63
#include <qmessagebox.h>
64
#include <qpopupmenu.h>
65
#include <qsizegrip.h>
66
#include <qpushbutton.h>
67
#include <qwhatsthis.h>
68
#include <qmetaobject.h>
70
#include <qfeatures.h>
72
#include <qpixmapcache.h>
74
#include <qsplitter.h>
76
// FormWindow should be able to work to some limited degree
77
// (existance, loading) without a MainWindow. Functions which require
78
// a MainWindow in theory should never be called if no MainWindow
79
// exists. These macros are used to let us know if that happens anyway
80
// and to ensure that we don't crash
81
#define CHECK_MAINWINDOW Q_ASSERT( mainWindow() ); if ( !mainWindow() ) return
82
#define CHECK_MAINWINDOW_VALUE( v ) Q_ASSERT( mainWindow() ); if ( !mainWindow() ) return v
84
static void setCursorToAll( const QCursor &c, QWidget *start )
86
start->setCursor( c );
87
QObjectList *l = (QObjectList*)start->children();
89
for ( QObject *o = l->first(); o; o = l->next() ) {
90
if ( o->isWidgetType() && !::qt_cast<SizeHandle*>(o) )
91
setCursorToAll( c, ( (QWidget*)o ) );
96
static void restoreCursors( QWidget *start, FormWindow *fw )
98
if ( fw->widgets()->find( start ) )
99
start->setCursor( MetaDataBase::cursor( start ) );
101
start->setCursor( Qt::ArrowCursor );
102
QObjectList *l = (QObjectList*)start->children();
104
for ( QObject *o = l->first(); o; o = l->next() ) {
105
if ( o->isWidgetType() && !::qt_cast<SizeHandle*>(o) )
106
restoreCursors( ( (QWidget*)o ), fw );
111
#if defined(Q_WS_WIN32) // #### needed for the workaround for repaint problem on windows
112
#include <qt_windows.h>
113
static void flickerfree_update( QWidget *w )
115
InvalidateRect( w->winId(), 0, FALSE );
120
\class FormWindow formwindow.h
121
\brief Editor window for a form
123
The FormWindow is the widget which is used as editor for forms. It
124
handles inserting, deleting, moving, resizing, etc. of widgets.
126
Normally multiple formwindows are used at the same time in the
127
Designer. So each formwindow has its own undo/redo buffer, etc.
129
Also the formwindow has some signals to inform e.g. about selection
130
changes which is interesting for the PropertyEditor.
132
For handling the events of the child widgets (moving, etc.) the
133
handleMousePress(), etc. functions are called from the application
134
event filter which is implemented in MainWindow::eventFilter().
137
FormWindow::FormWindow( FormFile *f, MainWindow *mw, QWidget *parent, const char *name )
138
: QWidget( parent, name, WDestructiveClose ), mainwindow( mw ),
139
commands( 100 ), pixInline( TRUE ), pixProject( FALSE )
146
FormWindow::FormWindow( FormFile *f, QWidget *parent, const char *name )
147
: QWidget( parent, name, WDestructiveClose ), mainwindow( 0 ),
148
commands( 100 ), pixInline( TRUE )
154
void FormWindow::init()
156
setWFlags(getWFlags() & Qt::WStyle_Maximize);
158
fake = qstrcmp( name(), "qt_fakewindow" ) == 0;
159
MetaDataBase::addEntry( this );
160
ff->setFormWindow( this );
165
checkedSelectionsForMove = FALSE;
167
startWidget = endWidget = 0;
168
currTool = POINTER_TOOL;
169
unclippedPainter = 0;
170
widgetPressed = FALSE;
172
setFocusPolicy( ClickFocus );
173
sizePreviewLabel = 0;
174
checkSelectionsTimer = new QTimer( this, "checkSelectionsTimer" );
175
connect( checkSelectionsTimer, SIGNAL( timeout() ),
176
this, SLOT( invalidCheckedSelections() ) );
177
updatePropertiesTimer = new QTimer( this );
178
connect( updatePropertiesTimer, SIGNAL( timeout() ),
179
this, SLOT( updatePropertiesTimerDone() ) );
180
showPropertiesTimer = new QTimer( this );
182
connect( showPropertiesTimer, SIGNAL( timeout() ),
183
this, SLOT( showPropertiesTimerDone() ) );
184
selectionChangedTimer = new QTimer( this );
185
connect( selectionChangedTimer, SIGNAL( timeout() ),
186
this, SLOT( selectionChangedTimerDone() ) );
187
windowsRepaintWorkaroundTimer = new QTimer( this );
188
connect( windowsRepaintWorkaroundTimer, SIGNAL( timeout() ),
189
this, SLOT( windowsRepaintWorkaroundTimerTimeout() ) );
191
connect( &commands, SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ),
192
this, SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ) );
193
propShowBlocked = FALSE;
195
setIcon( SmallIcon( "designer_form.png" , KDevDesignerPartFactory::instance()) );
197
connect( &commands, SIGNAL( modificationChanged( bool ) ),
198
this, SLOT( modificationChanged( bool ) ) );
201
QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QFrame" ), this );
202
setMainContainer( w );
205
hadOwnPalette = FALSE;
207
defSpacing = BOXLAYOUT_DEFAULT_SPACING;
208
defMargin = BOXLAYOUT_DEFAULT_MARGIN;
209
hasLayoutFunc = FALSE;
212
void FormWindow::setMainWindow( MainWindow *w )
215
MetaDataBase::addEntry( this );
219
void FormWindow::initSlots()
223
Q_ASSERT( project() || MainWindow::self );
224
if ( !project() && !MainWindow::self )
226
Project *p = project() ? project() : MainWindow::self->currProject();
227
if ( p && p->isCpp() ) {
228
QString code = formFile()->code();
229
if ( code.isEmpty() )
230
formFile()->setCode( formFile()->codeComment() );
234
FormWindow::~FormWindow()
236
if ( MainWindow::self && MainWindow::self->objectHierarchy()->formWindow() == this )
237
MainWindow::self->objectHierarchy()->setFormWindow( 0, 0 );
239
MetaDataBase::clear( this );
241
ff->setFormWindow( 0 );
245
void FormWindow::closeEvent( QCloseEvent *e )
247
QGuardedPtr<FormWindow> that = this;
248
if ( ff->closeEvent() && ( !that || ( mainwindow && mainwindow->unregisterClient( this ) ) ) )
254
void FormWindow::paintGrid( QWidget *w, QPaintEvent *e )
256
if ( !mainWindow() || !mainWindow()->showGrid() )
260
grid_name.sprintf("FormWindowGrid_%d_%d", mainWindow()->grid().x(), mainWindow()->grid().y());
261
if( !QPixmapCache::find( grid_name, grid ) ) {
262
grid = QPixmap( 350 + ( 350 % mainWindow()->grid().x() ), 350 + ( 350 % mainWindow()->grid().y() ) );
263
grid.fill( colorGroup().color( QColorGroup::Foreground ) );
264
QBitmap mask( grid.width(), grid.height() );
268
for ( int y = 0; y < grid.width(); y += mainWindow()->grid().y()) {
269
for ( int x = 0; x < grid.height(); x += mainWindow()->grid().x() ) {
273
grid.setMask( mask );
274
QPixmapCache::insert( grid_name, grid );
277
p.setClipRegion( e->rect() );
278
p.drawTiledPixmap( QRect( 0, 0, width(), height() ), grid );
281
/*! For operations like drawing a rubber band or drawing the rect
282
when inserting a new widget, a unclipped painter (which draws also
283
on child widgets) is needed. This method does all the initialization.
286
void FormWindow::beginUnclippedPainter( bool doNot )
288
endUnclippedPainter();
289
bool unclipped = testWFlags( WPaintUnclipped );
290
setWFlags( WPaintUnclipped );
291
unclippedPainter = new QPainter;
292
unclippedPainter->begin( this );
294
clearWFlags( WPaintUnclipped );
296
unclippedPainter->setPen( QPen( color0, 2 ) );
297
unclippedPainter->setRasterOp( NotROP );
302
Gets rid of an open unclipped painter.
304
\sa beginUnclippedPainter()
307
void FormWindow::endUnclippedPainter()
309
if ( unclippedPainter )
310
unclippedPainter->end();
311
delete unclippedPainter;
312
unclippedPainter = 0;
315
QPoint FormWindow::gridPoint( const QPoint &p )
317
return QPoint( ( p.x() / grid().x() ) * grid().x(),
318
( p.y() / grid().y() ) * grid().y() );
321
void FormWindow::drawSizePreview( const QPoint &pos, const QString& text )
323
unclippedPainter->save();
324
unclippedPainter->setPen( QPen( colorGroup().foreground(), 1 ));
325
unclippedPainter->setRasterOp( CopyROP );
326
if ( !sizePreviewPixmap.isNull() )
327
unclippedPainter->drawPixmap( sizePreviewPos, sizePreviewPixmap );
328
if ( text.isNull() ) {
329
sizePreviewPixmap = QPixmap(); // set null again
330
unclippedPainter->restore();
333
QRect r = fontMetrics().boundingRect( 0, 0, 0, 0, AlignCenter, text );
334
r = QRect( pos + QPoint( 10, 10 ), r.size() + QSize( 5, 5 ) );
336
checkPreviewGeometry( r );
338
sizePreviewPos = r.topLeft();
339
sizePreviewPixmap = QPixmap::grabWindow( winId(), r.x(), r.y(), r.width(), r.height() );
340
unclippedPainter->setBrush( QColor( 255, 255, 128 ) );
341
unclippedPainter->drawRect( r );
342
unclippedPainter->drawText( r, AlignCenter, text );
343
unclippedPainter->restore();
346
void FormWindow::insertWidget()
352
if ( currTool == POINTER_TOOL )
355
bool useSizeHint = !oldRectValid || ( currRect.width() < 2 && currRect.height() < 2 );
356
Orientation orient = Horizontal;
357
QString n = WidgetDatabase::className( currTool );
358
if ( useSizeHint && ( n == "Spacer" || n == "QSlider" || n == "Line" || n == "QScrollBar" ) ) {
359
QPopupMenu m( mainWindow() );
360
m.insertItem( i18n( "&Horizontal" ) );
361
int ver = m.insertItem( i18n( "&Vertical" ) );
362
int r = m.exec( QCursor::pos() );
368
QWidget *w = WidgetFactory::create( currTool, insertParent, 0, TRUE, &currRect, orient );
372
if ( !savePixmapInline() && currTool == WidgetDatabase::idFromClassName( "PixmapLabel" ) ) { // ### what to do for pixmaps in project
374
// we have to force the pixmap to get a new and unique serial number. Unfortunately detatch() doesn't do that
375
pix.convertFromImage( SmallIcon( "designer_image.png" , KDevDesignerPartFactory::instance()).convertToImage() );
376
( (QLabel*)w )->setPixmap( pix );
378
int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) );
379
if ( WidgetDatabase::isCustomWidget( id ) ) {
380
QWhatsThis::add( w, i18n("<b>A %1 (custom widget)</b> "
381
"<p>Click <b>Edit Custom Widgets...</b> in the <b>Tools|Custom</b> "
382
"menu to add and change custom widgets. You can add "
383
"properties as well as signals and slots to integrate custom widgets into "
384
"<i>Qt Designer</i>, and provide a pixmap which will be used to represent "
385
"the widget on the form.</p>")
386
.arg(WidgetDatabase::toolTip( id )) );
387
QToolTip::add( w, i18n("A %1 (custom widget)").arg(WidgetDatabase::toolTip( id )) );
389
QString tt = WidgetDatabase::toolTip( id );
390
QString wt = WidgetDatabase::whatsThis( id );
391
if ( !wt.isEmpty() && !tt.isEmpty() )
392
QWhatsThis::add( w, QString("<b>A %1</b><p>%2</p>").arg( tt ).arg( wt ) );
395
QString s = w->name();
400
if ( !oldRectValid ||
401
( currRect.width() < 2 && currRect.height() < 2 ) )
402
r = QRect( rectAnchor, QSize( 0, 0 ) );
404
QPoint p = r.topLeft();
405
p = mapToGlobal( p );
406
p = insertParent->mapFromGlobal( p );
407
r = QRect( p, r.size() );
410
if ( n == "Spacer" ) {
411
if ( orient == Vertical ) {
419
r.setWidth( w->sizeHint().width() );
420
r.setHeight( w->sizeHint().height() );
424
if ( r.width() < 2 * grid().x() )
425
r.setWidth( 2 * grid().x() );
426
if ( r.height() < 2 * grid().y() )
427
r.setHeight( 2 * grid().y() );
429
const QObjectList *l = insertParent->children();
430
QObjectListIt it( *l );
432
if ( WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ) ) {
433
for ( ; it.current(); ) {
434
QObject *o = it.current();
436
if ( o->isWidgetType() &&
437
( (QWidget*)o )->isVisibleTo( this ) &&
438
insertedWidgets.find( (QWidget*)o ) && o != w ) {
439
QRect r2( ( (QWidget*)o )->pos(),
440
( (QWidget*)o )->size() );
441
if ( r.contains( r2 ) )
442
lst.append( (QWidget*)o );
447
if ( !lst.isEmpty() ) {
448
QWidget *pw = WidgetFactory::containerOfWidget( w );
450
QValueList<QPoint> op, np;
451
for ( QWidget *i = lst.first(); i; i = lst.next() ) {
452
op.append( i->pos() );
453
QPoint pos = pw->mapFromGlobal( i->mapToGlobal( QPoint( 0, 0 ) ) );
458
MoveCommand *mv = new MoveCommand( i18n( "Reparent Widgets" ), this,
459
lst, op, np, insertParent, pw );
462
mainwindow->resetTool();
464
setCursorToAll( CrossCursor, w );
466
InsertCommand *cmd = new InsertCommand( i18n( "Insert %1" ).arg( w->name() ), this, w, r );
468
QPtrList<Command> commands;
469
commands.append( mv );
470
commands.append( cmd );
472
MacroCommand *mc = new MacroCommand( i18n( "Insert %1" ).arg( w->name() ), this, commands );
473
commandHistory()->addCommand( mc );
478
mainwindow->resetTool();
480
setCursorToAll( CrossCursor, w );
482
InsertCommand *cmd = new InsertCommand( i18n( "Insert %1" ).arg( w->name() ), this, w, r );
483
commandHistory()->addCommand( cmd );
487
TemplateWizardInterface *iface = mainWindow()->templateWizardInterface( w->className() );
489
iface->setup( w->className(), w, iFace(), mainWindow()->designerInterface() );
494
void FormWindow::insertWidget( QWidget *w, bool checkName )
499
QString s = w->name();
504
MetaDataBase::addEntry( w );
505
int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) );
506
if ( WidgetDatabase::isCustomWidget( id ) ) {
507
QWhatsThis::add( w, i18n("<b>A %1 (custom widget)</b> "
508
"<p>Click <b>Edit Custom Widgets...</b> in the <b>Tools|Custom</b> "
509
"menu to add and change custom widgets. You can add "
510
"properties as well as signals and slots to integrate custom widgets into "
511
"<i>Qt Designer</i>, and provide a pixmap which will be used to represent "
512
"the widget on the form.</p>")
513
.arg(WidgetDatabase::toolTip( id )) );
514
QToolTip::add( w, i18n("A %1 (custom widget)").arg(WidgetDatabase::toolTip( id )) );
516
QString tt = WidgetDatabase::toolTip( id );
517
QString wt = WidgetDatabase::whatsThis( id );
518
if ( !wt.isEmpty() && !tt.isEmpty() )
519
QWhatsThis::add( w, QString("<b>A %1</b><p>%2</p>").arg( tt ).arg( wt ) );
522
restoreCursors( w, this );
523
widgets()->insert( w, w );
527
void FormWindow::removeWidget( QWidget *w )
529
MetaDataBase::removeEntry( w );
530
widgets()->take( w );
533
void FormWindow::handleContextMenu( QContextMenuEvent *e, QWidget *w )
536
switch ( currTool ) {
538
if ( !isMainContainer( w ) && qstrcmp( w->name(), "central widget" ) != 0 ) { // press on a child widget
539
raiseChildSelections( w ); // raise selections and select widget
541
// if widget is laid out, find the first non-laid out super-widget
542
QWidget *realWidget = w; // but store the original one
543
while ( w->parentWidget() &&
544
( WidgetFactory::layoutType( w->parentWidget()) != WidgetFactory::NoLayout ||
545
!insertedWidgets.find(w) ) )
546
w = w->parentWidget();
547
if ( ::qt_cast<QMainWindow*>(mainContainer()) && ((QMainWindow*)mainContainer())->centralWidget() == realWidget ) {
549
mainwindow->popupFormWindowMenu( e->globalPos(), this );
552
mainwindow->popupWidgetMenu( e->globalPos(), this, realWidget);
557
mainwindow->popupFormWindowMenu( e->globalPos(), this );
565
void FormWindow::handleMousePress( QMouseEvent *e, QWidget *w )
568
checkedSelectionsForMove = FALSE;
569
checkSelectionsTimer->stop();
570
if ( !sizePreviewLabel ) {
571
sizePreviewLabel = new QLabel( this );
572
sizePreviewLabel->hide();
573
sizePreviewLabel->setBackgroundColor( QColor( 255, 255, 128 ) );
574
sizePreviewLabel->setFrameStyle( QFrame::Plain | QFrame::Box );
577
switch ( currTool ) {
579
if ( !isMainContainer( w ) && qstrcmp( w->name(), "central widget" ) != 0 ) { // press on a child widget
580
// if the clicked widget is not in a layout, raise it
581
if ( !w->parentWidget() || WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout )
583
if ( ( e->state() & ControlButton ) ) { // with control pressed, always start rubber band selection
585
currRect = QRect( 0, 0, -1, -1 );
586
startRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber );
590
bool sel = isWidgetSelected( w );
591
if ( !( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) ) { // control not pressed...
592
if ( !sel ) { // ...and widget no selectted: unselect all
593
clearSelection( FALSE );
594
} else { // ...widget selected
595
// only if widget has a layout (it is a layout meta widget or a laid out container!), unselect its childs
596
if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout ) {
597
QObjectList *l = w->queryList( "QWidget" );
598
setPropertyShowingBlocked( TRUE );
599
for ( QObject *o = l->first(); o; o = l->next() ) {
600
if ( !o->isWidgetType() )
602
if ( insertedWidgets.find( (QWidget*)o ) )
603
selectWidget( (QWidget*)o, FALSE );
605
setPropertyShowingBlocked( FALSE );
609
qApp->processEvents();
611
if ( ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) &&
612
sel && e->button() == LeftButton ) { // control pressed and selected, unselect widget
613
selectWidget( w, FALSE );
617
raiseChildSelections( w ); // raise selections and select widget
620
// if widget is laid out, find the first non-laid out super-widget
621
while ( w->parentWidget() &&
622
( WidgetFactory::layoutType( w->parentWidget()) != WidgetFactory::NoLayout || !insertedWidgets.find(w) ) )
623
w = w->parentWidget();
625
if ( e->button() == LeftButton ) { // left button: store original geometry and more as the widget might start moving
626
widgetPressed = TRUE;
627
widgetGeom = QRect( w->pos(), w->size() );
628
oldPressPos = w->mapFromGlobal( e->globalPos() );
629
origPressPos = oldPressPos;
630
checkedSelectionsForMove = FALSE;
632
if ( w->parentWidget() && !isMainContainer( w->parentWidget() ) && !isCentralWidget( w->parentWidget() ) ) {
633
targetContainer = w->parentWidget();
634
hadOwnPalette = w->parentWidget()->ownPalette();
635
restorePalette = w->parentWidget()->palette();
638
} else { // press was on the formwindow
639
if ( e->button() == LeftButton ) { // left button: start rubber selection and show formwindow properties
641
if ( !( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) ) {
642
clearSelection( FALSE );
643
QObject *opw = propertyWidget;
644
propertyWidget = mainContainer();
645
if ( opw->isWidgetType() )
646
repaintSelection( (QWidget*)opw );
648
currRect = QRect( 0, 0, -1, -1 );
649
startRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber );
655
if ( e->button() != LeftButton )
657
validForBuddy = FALSE;
658
if ( currTool == BUDDY_TOOL ) {
659
if ( !::qt_cast<QLabel*>(w) )
661
clearSelection( FALSE );
662
validForBuddy = TRUE;
663
mainWindow()->statusMessage( i18n( "Set buddy for '%1' to..." ).arg( w->name() ) );
665
mainWindow()->statusMessage( i18n( "Connect '%1' with..." ).arg( w->name() ) );
668
startPos = mapFromGlobal( e->globalPos() );
669
currentPos = startPos;
670
startWidget = designerWidget( w );
671
endWidget = startWidget;
672
beginUnclippedPainter( FALSE );
673
drawConnectionLine();
676
if ( !isMainContainer( w ) ) { // press on a child widget
677
orderedWidgets.removeRef( w );
678
orderedWidgets.append( w );
679
for ( QWidget *wid = orderedWidgets.last(); wid; wid = orderedWidgets.prev() ) {
680
int i = stackedWidgets.findRef( wid );
682
stackedWidgets.removeRef( wid );
683
stackedWidgets.insert( 0, wid );
686
QWidgetList oldl = MetaDataBase::tabOrder( this );
687
TabOrderCommand *cmd = new TabOrderCommand( i18n( "Change Tab Order" ), this, oldl, stackedWidgets );
689
commandHistory()->addCommand( cmd, TRUE );
690
updateOrderIndicators();
693
default: // any insert widget tool
694
if ( e->button() == LeftButton ) {
695
insertParent = WidgetFactory::containerOfWidget( mainContainer() ); // default parent for new widget is the formwindow
696
if ( !isMainContainer( w ) ) { // press was not on formwindow, check if we can find another parent
699
int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( wid ) );
700
if ( ( WidgetDatabase::isContainer( id ) || wid == mainContainer() ) &&
701
!::qt_cast<QLayoutWidget*>(wid) && !::qt_cast<QSplitter*>(wid) ) {
702
insertParent = WidgetFactory::containerOfWidget( wid ); // found another parent, store it
705
wid = wid->parentWidget();
711
startRectDraw( w->mapFromGlobal( e->globalPos() ), e->globalPos(), w, Insert );
717
void FormWindow::handleMouseDblClick( QMouseEvent *, QWidget *w )
720
switch ( currTool ) {
722
if ( !isMainContainer( w ) ) { // press on a child widget
723
orderedWidgets.clear();
724
orderedWidgets.append( w );
725
for ( QWidget *wid = orderedWidgets.last(); wid; wid = orderedWidgets.prev() ) {
726
int i = stackedWidgets.findRef( wid );
728
stackedWidgets.removeRef( wid );
729
stackedWidgets.insert( 0, wid );
732
QWidgetList oldl = MetaDataBase::tabOrder( this );
733
TabOrderCommand *cmd = new TabOrderCommand( i18n( "Change Tab Order" ), this, oldl, stackedWidgets );
735
commandHistory()->addCommand( cmd, TRUE );
736
updateOrderIndicators();
739
if ( !WidgetFactory::isPassiveInteractor( w ) &&
740
( isMainContainer( w ) || w == this ) )
741
mainWindow()->editSource();
746
void FormWindow::handleMouseMove( QMouseEvent *e, QWidget *w )
749
if ( ( e->state() & LeftButton ) != LeftButton )
752
QWidget *newendWidget = endWidget, *oldendWidget = endWidget, *wid;
754
switch ( currTool ) {
756
if ( widgetPressed && allowMove( w ) ) { // we are prepated for a move
758
// if widget is laid out, find the first non-laid out super-widget
759
while ( w->parentWidget() &&
760
( WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout || !insertedWidgets.find(w ) ) )
761
w = w->parentWidget();
763
// calc correct position
764
QPoint pos = w->mapFromGlobal( e->globalPos() );
767
QPoint mpos = w->mapToParent( pos );
768
// check if we are not outside the visible area, else correct coords
770
pos.setX( w->mapFromParent( QPoint( 0, mpos.y() ) ).x() );
772
pos.setY( w->mapFromParent( QPoint( mpos.x(), 0 ) ).y() );
773
if ( mpos.x() > w->parentWidget()->width() )
774
pos.setX( w->mapFromParent( QPoint( w->parentWidget()->width(), mpos.y() ) ).x() );
775
if ( mpos.y() > w->parentWidget()->height() )
776
pos.setY( w->mapFromParent( QPoint( mpos.x(), w->parentWidget()->height() ) ).y() );
779
// calc move distance and store it
780
QPoint d = oldPressPos - pos;
781
if ( QABS( d.x() ) < grid().x() )
783
if ( QABS( d.y() ) < grid().y() )
786
pos.setX( oldPressPos.x() );
788
pos.setY( oldPressPos.y() );
792
int x = widgetGeom.x() - d.x();
793
widgetGeom.setX( x );
794
x = ( x / grid().x() ) * grid().x();
795
int y = widgetGeom.y() - d.y();
796
widgetGeom.setY( y );
797
y = ( y / grid().y() ) * grid().y();
800
if ( x - p.x() != 0 || y - p.y() != 0 ) { // if we actually have to move
801
if ( !checkedSelectionsForMove ) { // if not checked yet, check if the correct widget are selected...
802
if ( !isWidgetSelected( w ) ) { // and unselect others. Only siblings can be moved at the same time
803
setPropertyShowingBlocked( TRUE );
805
setPropertyShowingBlocked( FALSE );
807
checkSelectionsForMove( w );
810
// check whether we would have to reparent the selection and highlight the possible new parent container
811
QMapConstIterator<QWidget*, QPoint> it = moving.begin();
812
QWidget* wa = containerAt( e->globalPos(), it.key() );
813
if ( wa && !isMainContainer( wa ) && !isCentralWidget( wa ) ) {
814
wa = WidgetFactory::containerOfWidget( wa );
815
// ok, looks like we moved onto a container
817
if ( wa != targetContainer ) {
818
if ( targetContainer ) {
820
targetContainer->setPalette( restorePalette );
822
targetContainer->unsetPalette();
824
targetContainer = wa;
825
hadOwnPalette = wa->ownPalette();
826
restorePalette = wa->palette();
827
wa->setPaletteBackgroundColor( wa->colorGroup().midlight() );
830
else if ( targetContainer ) {
832
targetContainer->setPalette( restorePalette );
834
targetContainer->unsetPalette();
838
// finally move the selected widgets and show/update preview label
839
moveSelectedWidgets( x - p.x(), y - p.y() );
840
sizePreviewLabel->setText( i18n( "%1/%2" ).arg( w->pos().x() ).arg( w->pos().y() ) );
841
sizePreviewLabel->adjustSize();
842
QRect lg( mapFromGlobal( e->globalPos() ) + QPoint( 16, 16 ), sizePreviewLabel->size() );
843
checkPreviewGeometry( lg );
844
sizePreviewLabel->setGeometry( lg );
845
sizePreviewLabel->raise();
846
sizePreviewLabel->show();
847
#if defined(Q_WS_WIN32)
848
windowsRepaintWorkaroundTimer->start( 100, TRUE );
850
} else { // if we don't need to move, do some indication
851
QRect lg( mapFromGlobal( e->globalPos() ) + QPoint( 16, 16 ), sizePreviewLabel->size() );
852
checkPreviewGeometry( lg );
853
sizePreviewLabel->move( lg.x(), lg.y() );
856
oldPressPos += ( p - w->pos() );
857
} else if ( drawRubber ) { // draw rubber if we are in rubber-selection mode
858
continueRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber );
862
restoreConnectionLine();
863
wid = qApp->widgetAt( e->globalPos(), TRUE );
865
wid = designerWidget( wid );
866
if ( wid && ( isMainContainer( wid ) || insertedWidgets.find( wid ) ) && wid->isVisibleTo( this ) )
868
if ( ::qt_cast<QLayoutWidget*>(newendWidget) || ::qt_cast<Spacer*>(newendWidget) )
869
newendWidget = (QWidget*)endWidget;
870
drawRecRect = newendWidget != endWidget;
872
( isMainContainer( newendWidget ) || insertedWidgets.find( newendWidget ) ) && !isCentralWidget( newendWidget ) )
873
endWidget = newendWidget;
874
mainWindow()->statusMessage( i18n( "Connect '%1' to '%2'" ).arg( startWidget->name() ).
875
arg( endWidget->name() ) );
876
currentPos = mapFromGlobal( e->globalPos() );
877
qApp->processEvents();
879
restoreRect( QRect( mapToForm( ( (QWidget*)oldendWidget )->parentWidget(), ( (QWidget*)oldendWidget )->pos() ),
880
( (QWidget*)oldendWidget )->size() ) );
881
drawConnectionLine();
884
if ( !validForBuddy )
886
restoreConnectionLine();
887
wid = qApp->widgetAt( e->globalPos(), TRUE );
889
wid = designerWidget( wid );
890
if ( wid && canBeBuddy( wid ) && wid->isVisibleTo( this ) )
894
if ( ::qt_cast<QLayoutWidget*>(newendWidget) || ::qt_cast<Spacer*>(newendWidget) )
895
newendWidget = (QWidget*)endWidget;
896
drawRecRect = newendWidget != endWidget;
898
endWidget = newendWidget;
899
else if ( insertedWidgets.find( newendWidget ) && !isCentralWidget( newendWidget ) )
900
endWidget = newendWidget;
902
mainWindow()->statusMessage( i18n( "Set buddy '%1' to '%2'" ).arg( startWidget->name() ).
903
arg( endWidget->name() ) );
905
mainWindow()->statusMessage( i18n( "Set buddy '%1' to ..." ).arg( startWidget->name() ) );
906
currentPos = mapFromGlobal( e->globalPos() );
907
qApp->processEvents();
908
if ( drawRecRect && oldendWidget )
909
restoreRect( QRect( mapToForm( ( (QWidget*)oldendWidget )->parentWidget(), ( (QWidget*)oldendWidget )->pos() ),
910
( (QWidget*)oldendWidget )->size() ) );
911
drawConnectionLine();
915
default: // we are in an insert-widget tool
916
if ( insertParent ) // draw insert rect
917
continueRectDraw( w->mapFromGlobal( e->globalPos() ), e->globalPos(), w, Insert );
922
void FormWindow::handleMouseRelease( QMouseEvent *e, QWidget *w )
925
if ( e->button() != LeftButton )
928
switch ( currTool ) {
930
if ( widgetPressed && allowMove( w ) ) { // we moved the widget
931
sizePreviewLabel->hide();
933
if ( moving.isEmpty() || w->pos() == *moving.find(w) )
936
// restore targetContainer
937
if ( targetContainer ) {
939
targetContainer->setPalette( restorePalette );
941
targetContainer->unsetPalette();
944
// tell property editor to update
945
if ( propertyWidget && propertyWidget->isWidgetType() && !isMainContainer( propertyWidget ) )
946
emitUpdateProperties( propertyWidget );
948
QMapConstIterator<QWidget*,QPoint> it = moving.begin();
949
QWidget *oldParent = it.key()->parentWidget();
950
QWidget *newParent = oldParent;
951
// check whether we have to reparent the selection
952
QWidget* wa = containerAt( e->globalPos(), it.key() );
954
wa = WidgetFactory::containerOfWidget( wa );
955
// ok, looks like we moved onto a container
957
// check whether we really have different parents.
958
if ( wa == it.key()->parentWidget() )
959
goto make_move_command;
961
// break layout if necessary
962
if ( WidgetFactory::layoutType( wa ) != WidgetFactory::NoLayout ) {
963
if ( QMessageBox::information( mainWindow(), i18n( "Inserting Widget" ),
964
i18n( "You tried to insert a widget into the "
965
"layout Container Widget '%1'.\n"
966
"This is not possible. "
967
"In order to insert the widget, the layout of '%1'\n"
968
"must first be broken.\n"
969
"Break the layout or cancel the operation?" ).
971
arg( wa->name() ), i18n( "&Break Layout" ), i18n( "&Cancel" ) ) )
972
goto make_move_command; // cancel
976
// doesn't need to be a command, the MoveCommand does reparenting too
977
bool emitSelChanged = FALSE;
978
for ( QMap<QWidget*, QPoint>::Iterator it = moving.begin(); it != moving.end(); ++it ) {
979
QWidget *i = it.key();
980
if ( !emitSelChanged && ::qt_cast<QButton*>(i) ) {
981
if ( ::qt_cast<QButtonGroup*>(i->parentWidget()) || ::qt_cast<QButtonGroup*>(wa) )
982
emitSelChanged = TRUE;
983
if ( !::qt_cast<QButtonGroup*>(wa) ) {
984
MetaDataBase::setPropertyChanged( i, "buttonGroupId", FALSE );
985
if ( ::qt_cast<QButtonGroup*>(i->parentWidget()) )
986
( (QButtonGroup*)i->parentWidget() )->remove( (QButton*)i );
989
QPoint pos = wa->mapFromGlobal( i->mapToGlobal( QPoint(0,0) ) );
990
i->reparent( wa, pos, TRUE );
992
raiseChildSelections( i );
994
mainWindow()->objectHierarchy()->widgetRemoved( i );
995
mainWindow()->objectHierarchy()->widgetInserted( i );
997
if ( emitSelChanged ) {
998
emit showProperties( wa );
999
emit showProperties( propertyWidget );
1005
QWidgetList widgets; // collect the widgets and its old and new positions which have been moved
1006
QValueList<QPoint> oldPos, newPos;
1007
for ( it = moving.begin(); it != moving.end(); ++it ) {
1008
widgets.append( it.key() );
1009
oldPos.append( *it );
1010
newPos.append( it.key()->pos() );
1012
// add move command, don't execute it, this is just a summary of the operations we did during the move-event handling
1013
commandHistory()->addCommand( new MoveCommand( i18n( "Move" ),
1015
oldPos, newPos, oldParent, newParent ) );
1016
} else if ( drawRubber ) { // we were drawing a rubber selection
1017
endRectDraw(); // get rid of the rectangle
1018
blockSignals( TRUE );
1019
selectWidgets(); // select widgets which intersect the rect
1020
blockSignals( FALSE );
1021
emitSelectionChanged(); // inform about selection changes
1022
if ( propertyWidget )
1023
emitShowProperties( propertyWidget );
1028
restoreConnectionLine();
1030
restoreRect( QRect( mapToForm( ( (QWidget*)startWidget )->parentWidget(),
1031
( (QWidget*)startWidget )->pos() ),
1032
((QWidget*)startWidget )->size() ) );
1034
restoreRect( QRect( mapToForm( ( (QWidget*)endWidget )->parentWidget(),
1035
( (QWidget*)endWidget )->pos() ),
1036
( (QWidget*)endWidget )->size() ) );
1037
endUnclippedPainter();
1038
qApp->processEvents();
1040
if ( startWidget && endWidget ) {
1041
if ( currTool == CONNECT_TOOL )
1043
else if ( currTool == BUDDY_TOOL && validForBuddy && startWidget != endWidget ) {
1044
QString oldBuddy = startWidget->property( "buddy" ).toString();
1045
if ( oldBuddy.isNull() )
1047
SetPropertyCommand *cmd = new SetPropertyCommand( i18n( "Set Buddy for %1" ).arg( startWidget->name() ),
1048
this, startWidget, mainWindow()->propertyeditor(),
1049
"buddy", startWidget->property( "buddy" ),
1050
endWidget->name(), endWidget->name(),
1052
commandHistory()->addCommand( cmd, TRUE );
1054
emitUpdateProperties( startWidget );
1058
mainwindow->resetTool();
1059
startWidget = endWidget = 0;
1060
mainWindow()->statusBar()->clear();
1064
default: // any insert widget tool is active
1065
if ( insertParent ) { // we should insert the new widget now
1067
if ( WidgetFactory::layoutType( insertParent ) != WidgetFactory::NoLayout ) {
1068
if ( QMessageBox::information( mainWindow(), i18n( "Inserting Widget" ),
1069
i18n( "You tried to insert a widget into the "
1070
"layout Container Widget '%1'.\n"
1071
"This is not possible. "
1072
"In order to insert the widget, the layout of '%1'\n"
1073
"must first be broken.\n"
1074
"Break the layout or cancel the operation?" ).
1075
arg( insertParent->name() ).
1076
arg( insertParent->name() ), i18n( "&Break Layout" ), i18n( "&Cancel" ) ) == 0 ) {
1077
breakLayout( insertParent );
1080
mainWindow()->resetTool();
1084
insertWidget(); // so do it
1088
widgetPressed = FALSE;
1095
void FormWindow::handleKeyPress( QKeyEvent *e, QWidget *w )
1099
checkSelectionsTimer->stop();
1100
if ( !checkedSelectionsForMove &&
1101
( e->key() == Key_Left ||
1102
e->key() == Key_Right ||
1103
e->key() == Key_Up ||
1104
e->key() == Key_Down ) &&
1105
propertyWidget->isWidgetType() )
1106
checkSelectionsForMove( (QWidget*)propertyWidget );
1107
checkSelectionsTimer->start( 1000, TRUE );
1108
if ( e->key() == Key_Left || e->key() == Key_Right ||
1109
e->key() == Key_Up || e->key() == Key_Down ) {
1110
QWidgetList widgets;
1111
QValueList<QPoint> oldPos, newPos;
1112
for ( WidgetSelection *s = selections.first(); s; s = selections.next() ) {
1113
if ( s->isUsed() ) {
1115
bool control = e->state() & ControlButton;
1117
switch ( e->key() ) {
1150
widgets.append( s->widget() );
1151
oldPos.append( s->widget()->pos() );
1152
newPos.append( s->widget()->pos() + QPoint( dx, dy ) );
1155
if ( !widgets.isEmpty() ) {
1156
MoveCommand *cmd = new MoveCommand( i18n( "Move" ), this,
1157
widgets, oldPos, newPos, 0, 0 );
1158
commandHistory()->addCommand( cmd, TRUE );
1162
if ( !e->isAccepted() ) {
1163
QObjectList *l = queryList( "QWidget" );
1166
if ( l->find( w ) != -1 )
1173
void FormWindow::handleKeyRelease( QKeyEvent *e, QWidget * )
1178
void FormWindow::selectWidget( QObject *o, bool select )
1181
if ( !o->isWidgetType() ) {
1182
// ########### do QObject stuff
1186
QWidget *w = (QWidget*)o;
1188
if ( isMainContainer( w ) ) {
1189
QObject *opw = propertyWidget;
1190
propertyWidget = mainContainer();
1191
if ( opw->isWidgetType() )
1192
repaintSelection( (QWidget*)opw );
1193
emitShowProperties( propertyWidget );
1197
if ( ::qt_cast<QMainWindow*>(mainContainer()) && w == ( (QMainWindow*)mainContainer() )->centralWidget() ) {
1198
QObject *opw = propertyWidget;
1199
propertyWidget = mainContainer();
1200
if ( opw->isWidgetType() )
1201
repaintSelection( (QWidget*)opw );
1202
emitShowProperties( propertyWidget );
1206
if ( ::qt_cast<QDesignerToolBar*>(o) )
1210
QObject *opw = propertyWidget;
1212
if ( opw->isWidgetType() )
1213
repaintSelection( (QWidget*)opw );
1214
if ( !isPropertyShowingBlocked() )
1215
emitShowProperties( propertyWidget );
1216
WidgetSelection *s = usedSelections.find( w );
1222
for ( WidgetSelection *s2 = selections.first(); s2; s2 = selections.next() ) {
1223
if ( !s2->isUsed() ) {
1229
s = new WidgetSelection( this, &usedSelections );
1230
selections.append( s );
1234
emitSelectionChanged();
1236
WidgetSelection *s = usedSelections.find( w );
1239
QObject *opw = propertyWidget;
1240
if ( !usedSelections.isEmpty() )
1241
propertyWidget = QPtrDictIterator<WidgetSelection>( usedSelections ).current()->widget();
1243
propertyWidget = mainContainer();
1244
if ( opw->isWidgetType() )
1245
repaintSelection( (QWidget*)opw );
1246
if ( !isPropertyShowingBlocked() )
1247
emitShowProperties( propertyWidget );
1248
emitSelectionChanged();
1252
QPoint FormWindow::grid() const
1254
if ( !mainWindow() || !mainWindow()->snapGrid() )
1255
return QPoint( 1, 1 );
1256
return mainWindow()->grid();
1259
void FormWindow::updateSelection( QWidget *w )
1261
WidgetSelection *s = usedSelections.find( w );
1262
if ( !w->isVisibleTo( this ) )
1263
selectWidget( w, FALSE );
1265
s->updateGeometry();
1268
void FormWindow::raiseSelection( QWidget *w )
1270
WidgetSelection *s = usedSelections.find( w );
1275
void FormWindow::repaintSelection( QWidget *w )
1277
WidgetSelection *s = usedSelections.find( w );
1282
void FormWindow::clearSelection( bool changePropertyDisplay )
1284
QPtrDictIterator<WidgetSelection> it( usedSelections );
1285
for ( ; it.current(); ++it )
1286
it.current()->setWidget( 0, FALSE );
1288
usedSelections.clear();
1289
if ( changePropertyDisplay ) {
1290
QObject *opw = propertyWidget;
1291
propertyWidget = mainContainer();
1292
if ( opw->isWidgetType() )
1293
repaintSelection( (QWidget*)opw );
1294
emitShowProperties( propertyWidget );
1296
emitSelectionChanged();
1299
void FormWindow::startRectDraw( const QPoint &p, const QPoint &global, QWidget *, RectType t )
1302
pos = mapFromGlobal( global );
1303
oldRectValid = FALSE;
1304
beginUnclippedPainter( TRUE );
1306
unclippedPainter->setPen( QPen( color0, 1 ) );
1308
rectAnchor = gridPoint( pos );
1309
else if ( t == Rubber )
1311
currRect = QRect( rectAnchor, QPoint( 0, 0 ) );
1313
drawSizePreview( pos, i18n("Use Size Hint") );
1316
void FormWindow::continueRectDraw( const QPoint &p, const QPoint &global, QWidget *, RectType t )
1319
pos = mapFromGlobal( global );
1322
p2 = gridPoint( pos );
1323
else if ( t == Rubber )
1325
QRect r( rectAnchor, p2 );
1328
if ( currRect == r ) {
1329
QString t = i18n( "%1/%2" );
1330
t = t.arg( r.width() - 1 ).arg( r.height() - 1 );
1331
drawSizePreview( pos, t );
1336
unclippedPainter->drawRect( currRect );
1337
if ( r.width() > 1 || r.height() > 1 ) {
1338
oldRectValid = TRUE;
1340
if ( t == Insert ) {
1341
QString t = i18n( "%1/%2" );
1342
t = t.arg( r.width() - 1 ).arg( r.height() - 1 );
1343
drawSizePreview( pos, t );
1345
unclippedPainter->setClipRegion( QRegion( rect() ).subtract( QRect( sizePreviewPos, sizePreviewPixmap.size() ) ) );
1346
unclippedPainter->drawRect( currRect );
1347
unclippedPainter->setClipping( FALSE );
1349
oldRectValid = FALSE;
1351
drawSizePreview( pos, i18n("Use Size Hint") );
1355
void FormWindow::endRectDraw()
1357
if ( !unclippedPainter )
1361
unclippedPainter->drawRect( currRect );
1362
drawSizePreview( QPoint(-1,-1), QString::null );
1363
endUnclippedPainter();
1366
void FormWindow::selectWidgets()
1368
QObjectList *l = mainContainer()->queryList( "QWidget" );
1370
for ( QObject *o = l->first(); o; o = l->next() ) {
1371
if ( ( (QWidget*)o )->isVisibleTo( this ) &&
1372
insertedWidgets[ (void*)o ] ) {
1373
QPoint p = ( (QWidget*)o )->mapToGlobal( QPoint(0,0) );
1374
p = mapFromGlobal( p );
1375
QRect r( p, ( (QWidget*)o )->size() );
1376
if ( r.intersects( currRect ) && !r.contains( currRect ) )
1377
selectWidget( (QWidget*)o );
1382
emitSelectionChanged();
1385
bool FormWindow::isWidgetSelected( QObject *w )
1387
if ( w->isWidgetType() )
1388
return usedSelections.find( (QWidget*)w ) != 0;
1389
return FALSE; // #### do stuff for QObjects
1392
void FormWindow::moveSelectedWidgets( int dx, int dy )
1394
QPtrDictIterator<WidgetSelection> it( usedSelections );
1395
for ( ; it.current(); ++it ) {
1396
WidgetSelection *s = it.current();
1397
QWidget *w = s->widget();
1398
if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout )
1400
w->move( w->x() + dx, w->y() + dy );
1401
s->updateGeometry();
1402
updateChildSelections( w );
1406
CommandHistory *FormWindow::commandHistory()
1411
void FormWindow::undo()
1413
commandHistory()->undo();
1416
void FormWindow::redo()
1418
commandHistory()->redo();
1421
void FormWindow::raiseChildSelections( QWidget *w )
1423
QObjectList *l = w->queryList( "QWidget" );
1424
if ( !l || !l->first() ) {
1429
QPtrDictIterator<WidgetSelection> it( usedSelections );
1430
for ( ; it.current(); ++it ) {
1431
if ( l->findRef( it.current()->widget() ) != -1 )
1432
it.current()->show();
1437
void FormWindow::updateChildSelections( QWidget *w )
1439
QObjectList *l = w->queryList( "QWidget" );
1441
for ( QObject *o = l->first(); o; o = l->next() ) {
1442
if ( o->isWidgetType() &&
1443
insertedWidgets.find( (QWidget*)o ) )
1444
updateSelection( (QWidget*)o );
1450
void FormWindow::checkSelectionsForMove( QWidget *w )
1452
checkedSelectionsForMove = TRUE;
1454
QObjectList *l = w->parentWidget()->queryList( "QWidget", 0, FALSE, FALSE );
1457
QPtrDictIterator<WidgetSelection> it( usedSelections );
1458
WidgetSelection *sel;
1459
while ( ( sel = it.current() ) != 0 ) {
1460
if ( it.current()->widget() == mainContainer() )
1463
if ( l->find( sel->widget() ) == -1 ) {
1464
if ( WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout )
1465
sel->setWidget( 0 );
1467
if ( WidgetFactory::layoutType( sel->widget()->parentWidget() ) == WidgetFactory::NoLayout ) {
1468
moving.insert( sel->widget(), sel->widget()->pos() );
1469
sel->widget()->raise();
1470
raiseChildSelections( sel->widget() );
1471
raiseSelection( sel->widget() );
1479
void FormWindow::deleteWidgets()
1482
QWidgetList widgets;
1483
QPtrDictIterator<WidgetSelection> it( usedSelections );
1484
for ( ; it.current(); ++it ) {
1486
if ( !( tb = mainWindow()->isAToolBarChild( it.current()->widget() ) ) )
1487
widgets.append( it.current()->widget() );
1489
( (QDesignerToolBar*)tb )->removeWidget( it.current()->widget() );
1492
if ( widgets.isEmpty() )
1495
DeleteCommand *cmd = new DeleteCommand( i18n( "Delete" ), this, widgets );
1496
commandHistory()->addCommand( cmd );
1500
void FormWindow::editAdjustSize()
1502
QPtrList<Command> commands;
1503
QWidgetList widgets = selectedWidgets();
1504
if ( widgets.isEmpty() ) {
1505
QRect oldr = geometry();
1506
mainContainer()->adjustSize();
1507
resize( mainContainer()->size() );
1508
// check whether our own size constraint hit us
1509
if ( size() != mainContainer()->size() )
1510
mainContainer()->resize( size() );
1511
QRect nr = geometry();
1513
ResizeCommand *cmd = new ResizeCommand( i18n( "Adjust Size" ), this, this, oldr, nr );
1514
commandHistory()->addCommand( cmd );
1518
for ( QWidget* w = widgets.first(); w; w = widgets.next() ) {
1519
if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout )
1521
QRect oldr = w->geometry();
1523
QRect nr = w->geometry();
1525
commands.append( new ResizeCommand( i18n("Adjust Size"), this, w, oldr, nr ) );
1528
if ( commands.isEmpty() )
1530
for ( WidgetSelection *s = selections.first(); s; s = selections.next() )
1531
s->updateGeometry();
1533
MacroCommand *cmd = new MacroCommand( i18n( "Adjust Size" ), this, commands );
1534
commandHistory()->addCommand( cmd );
1538
QWidgetList FormWindow::selectedWidgets() const
1540
QWidgetList widgets;
1541
QPtrDictIterator<WidgetSelection> it( usedSelections );
1542
for ( ; it.current(); ++it )
1543
widgets.append( it.current()->widget() );
1547
void FormWindow::widgetChanged( QObject *w )
1549
if ( w->isWidgetType() )
1550
updateSelection( (QWidget*)w );
1551
// ########## do QObject stuff
1554
QLabel *FormWindow::sizePreview() const
1556
if ( !sizePreviewLabel ) {
1557
( (FormWindow*)this )->sizePreviewLabel = new QLabel( (FormWindow*)this );
1558
( (FormWindow*)this )->sizePreviewLabel->hide();
1559
( (FormWindow*)this )->sizePreviewLabel->setBackgroundColor( QColor( 255, 255, 128 ) );
1560
( (FormWindow*)this )->sizePreviewLabel->setFrameStyle( QFrame::Plain | QFrame::Box );
1562
return sizePreviewLabel;
1565
void FormWindow::invalidCheckedSelections()
1567
checkedSelectionsForMove = FALSE;
1570
void FormWindow::checkPreviewGeometry( QRect &r )
1572
if ( !rect().contains( r ) ) {
1573
if ( r.left() < rect().left() )
1574
r.moveTopLeft( QPoint( 0, r.top() ) );
1575
if ( r.right() > rect().right() )
1576
r.moveBottomRight( QPoint( rect().right(), r.bottom() ) );
1577
if ( r.top() < rect().top() )
1578
r.moveTopLeft( QPoint( r.left(), rect().top() ) );
1579
if ( r.bottom() > rect().bottom() )
1580
r.moveBottomRight( QPoint( r.right(), rect().bottom() ) );
1584
void FormWindow::focusInEvent( QFocusEvent * ){
1587
ff->checkTimeStamp();
1590
void FormWindow::focusOutEvent( QFocusEvent * )
1592
if ( propertyWidget && !isMainContainer( propertyWidget ) && !isWidgetSelected( propertyWidget ) ) {
1593
QObject *opw = propertyWidget;
1594
propertyWidget = mainContainer();
1595
if ( opw->isWidgetType() )
1596
repaintSelection( (QWidget*)opw );
1600
void FormWindow::resizeEvent( QResizeEvent *e )
1602
QWidget::resizeEvent( e );
1603
if ( currTool == ORDER_TOOL )
1604
repositionOrderIndicators();
1606
formFile()->setModified( TRUE, FormFile::WFormWindow );
1608
#if defined(Q_WS_WIN32)
1609
windowsRepaintWorkaroundTimer->start( 100, TRUE );
1613
void FormWindow::windowsRepaintWorkaroundTimerTimeout()
1615
#if defined(Q_WS_WIN32)
1616
QObjectList *l = queryList( "QWidget" );
1617
for ( QObject *o = l->first(); o; o = l->next() ) {
1618
flickerfree_update( (QWidget*)o );
1620
flickerfree_update( this );
1625
QPtrDict<QWidget> *FormWindow::widgets()
1627
return &insertedWidgets;
1630
QWidget *FormWindow::designerWidget( QObject *o ) const
1632
if ( !o || !o->isWidgetType() )
1634
QWidget *w = (QWidget*)o;
1635
while ( w && !isMainContainer( w ) && !insertedWidgets[ (void*)w ] || isCentralWidget( w ) )
1636
w = (QWidget*)w->parent();
1640
void FormWindow::emitShowProperties( QObject *w )
1643
QObject *opw = propertyWidget;
1645
if ( opw->isWidgetType() )
1646
repaintSelection( (QWidget*)opw );
1648
showPropertiesTimer->stop();
1649
// showPropertiesTimer->start( 0, TRUE );
1650
showPropertiesTimerDone();
1653
void FormWindow::emitUpdateProperties( QObject *w )
1655
if ( w == propertyWidget ) {
1656
updatePropertiesTimer->stop();
1657
updatePropertiesTimer->start( 0, TRUE );
1661
void FormWindow::emitSelectionChanged()
1663
selectionChangedTimer->stop();
1664
selectionChangedTimer->start( 0, TRUE );
1667
void FormWindow::updatePropertiesTimerDone()
1670
if ( propertyWidget && mainWindow()->formWindow() == this )
1671
emit updateProperties( propertyWidget );
1674
void FormWindow::showPropertiesTimerDone()
1677
if ( propertyWidget && mainWindow()->formWindow() == this )
1678
emit showProperties( propertyWidget );
1681
void FormWindow::selectionChangedTimerDone()
1683
emit selectionChanged();
1686
void FormWindow::currentToolChanged()
1690
int t = mainwindow->currentTool();
1691
if ( currTool == t && t != ORDER_TOOL )
1695
switch ( currTool ) {
1697
hideOrderIndicators();
1701
restoreConnectionLine();
1703
restoreRect( QRect( mapToForm( ( (QWidget*)startWidget )->parentWidget(),
1704
( (QWidget*)startWidget )->pos() ),
1705
( (QWidget*)startWidget )->size() ) );
1707
restoreRect( QRect( mapToForm( ( (QWidget*)endWidget )->parentWidget(),
1708
( (QWidget*)endWidget )->pos() ),
1709
( (QWidget*)endWidget )->size() ) );
1710
endUnclippedPainter();
1720
startWidget = endWidget = 0;
1721
widgetPressed = FALSE;
1730
clearSelection( FALSE );
1732
mainWindow()->statusBar()->clear();
1735
switch ( currTool ) {
1737
if ( propertyWidget && !isMainContainer( propertyWidget ) && !isWidgetSelected( propertyWidget ) )
1738
emitShowProperties( mainContainer() );
1739
restoreCursors( this, this );
1742
if ( mainWindow()->formWindow() == this ) {
1743
mainWindow()->statusMessage( i18n( "Click widgets to change the tab order...") );
1744
orderedWidgets.clear();
1745
showOrderIndicators();
1746
if ( mainWindow()->formWindow() == this )
1747
emitShowProperties( mainContainer() );
1748
setCursorToAll( ArrowCursor, this );
1753
if ( currTool == CONNECT_TOOL )
1754
mainWindow()->statusMessage( i18n( "Drag a line to create a connection...") );
1756
mainWindow()->statusMessage( i18n( "Drag a line to set a buddy...") );
1757
setCursorToAll( CrossCursor, this );
1758
if ( mainWindow()->formWindow() == this )
1759
emitShowProperties( mainContainer() );
1762
mainWindow()->statusMessage( i18n( "Click on the form to insert a %1..." ).arg( WidgetDatabase::toolTip( currTool ).lower() ) );
1763
setCursorToAll( CrossCursor, this );
1764
if ( mainWindow()->formWindow() == this )
1765
emitShowProperties( mainContainer() );
1770
void FormWindow::showOrderIndicators()
1772
hideOrderIndicators();
1773
orderIndicators.setAutoDelete( TRUE );
1774
QObjectList *l = mainContainer()->queryList( "QWidget" );
1775
stackedWidgets = MetaDataBase::tabOrder( this );
1778
for ( QObject *o = l->first(); o; o = l->next() ) {
1779
QWidget* w = (QWidget*) o;
1780
if ( w->isShown() &&
1781
insertedWidgets[ (void*)w ] &&
1782
w->focusPolicy() != NoFocus ) {
1783
OrderIndicator* ind = new OrderIndicator( order++, w, this );
1784
orderIndicators.append( ind );
1785
if ( stackedWidgets.findRef( w ) == -1 )
1786
stackedWidgets.append( w );
1791
updateOrderIndicators();
1794
void FormWindow::hideOrderIndicators()
1796
orderIndicators.clear();
1799
void FormWindow::updateOrderIndicators()
1802
for ( QWidget *w = stackedWidgets.first(); w; w = stackedWidgets.next() ) {
1803
for ( OrderIndicator* i = orderIndicators.first(); i; i = orderIndicators.next() )
1804
i->setOrder( order, w );
1809
void FormWindow::repositionOrderIndicators()
1811
for ( OrderIndicator* i = orderIndicators.first(); i; i = orderIndicators.next() )
1816
void FormWindow::updateUndoInfo()
1818
commandHistory()->emitUndoRedo();
1821
bool FormWindow::checkCustomWidgets()
1823
QStringList missingCustomWidgets;
1824
QPtrDictIterator<QWidget> it( insertedWidgets );
1825
for ( ; it.current(); ++it ) {
1826
if ( it.current()->isA( "CustomWidget" ) ) {
1827
QString className = WidgetFactory::classNameOf( it.current() );
1828
if ( !MetaDataBase::hasCustomWidget( className ) )
1829
missingCustomWidgets << className;
1833
if ( !missingCustomWidgets.isEmpty() ) {
1834
QString txt = i18n( "The following custom widgets are used in '%1',\n"
1835
"but are not known to Qt Designer:\n" ).arg( name() );
1836
for ( QStringList::Iterator sit = missingCustomWidgets.begin(); sit != missingCustomWidgets.end(); ++sit )
1837
txt += " " + *sit + "\n";
1838
txt += i18n( "If you save this form and generate code for it using uic, \n"
1839
"the generated code will not compile.\n"
1840
"Do you want to save this form now?" );
1841
if ( QMessageBox::information( mainWindow(), i18n( "Save Form" ), txt ) == 1 )
1847
void FormWindow::setPropertyShowingBlocked( bool b )
1849
propShowBlocked = b;
1852
bool FormWindow::isPropertyShowingBlocked() const
1854
return propShowBlocked;
1857
int FormWindow::numSelectedWidgets() const
1859
return usedSelections.count();
1862
QString FormWindow::copy()
1864
CHECK_MAINWINDOW_VALUE( QString::null );
1865
Resource resource( mainWindow() );
1866
resource.setWidget( this );
1867
return resource.copy();
1870
void FormWindow::lowerWidgets()
1872
QWidgetList widgets;
1873
QPtrDictIterator<WidgetSelection> it( usedSelections );
1874
for ( ; it.current(); ++it )
1875
widgets.append( it.current()->widget() );
1877
LowerCommand *cmd = new LowerCommand( i18n( "Lower" ), this, widgets );
1879
commandHistory()->addCommand( cmd );
1882
void find_accel( const QString &txt, QMap<QChar, QWidgetList > &accels, QWidget *w )
1884
int i = txt.find( "&" );
1887
QChar c = txt[ i + 1 ];
1888
if ( c.isNull() || c == '&' )
1891
QMap<QChar, QWidgetList >::Iterator it = accels.find( c );
1892
if ( it == accels.end() ) {
1895
accels.insert( c, wl );
1897
QWidgetList *wl = &*it;
1902
void FormWindow::checkAccels()
1905
QMap<QChar, QWidgetList > accels;
1906
QObjectList *l = mainContainer()->queryList( "QWidget" );
1908
for ( QObject *o = l->first(); o; o = l->next() ) {
1909
if ( ( (QWidget*)o )->isVisibleTo( this ) &&
1910
insertedWidgets[ (void*)o ] ) {
1911
QWidget *w = (QWidget*)o;
1912
const QMetaProperty* text =
1913
w->metaObject()->property( w->metaObject()->findProperty( "text", TRUE ), TRUE );
1914
const QMetaProperty* title =
1915
w->metaObject()->property( w->metaObject()->findProperty( "title", TRUE ), TRUE );
1916
const QMetaProperty* pageTitle =
1917
w->metaObject()->property( w->metaObject()->findProperty( "pageTitle", TRUE ), TRUE );
1919
find_accel( w->property( "text" ).toString(), accels, w );
1921
find_accel( w->property( "title" ).toString(), accels, w );
1923
find_accel( w->property( "pageTitle" ).toString(), accels, w );
1924
} else if ( ::qt_cast<MenuBarEditor*>(o) ) {
1925
((MenuBarEditor *)o)->checkAccels( accels );
1933
for ( QMap<QChar, QWidgetList >::Iterator it = accels.begin(); it != accels.end(); ++it ) {
1934
if ( (*it).count() > 1 ) {
1936
switch ( QMessageBox::information( mainWindow(), i18n( "Check Accelerators" ),
1937
i18n( "Accelerator '%1' is used once.", "Accelerator '%1' is used %n times.", (*it).count()
1938
).arg( it.key().upper() ),
1940
i18n( "&Cancel" ), QString::null, 2 ) ) {
1942
clearSelection( FALSE );
1943
for ( wid = (*it).first(); wid; wid = (*it).next() )
1944
selectWidget( wid, TRUE );
1953
QMessageBox::information( mainWindow(), i18n( "Check Accelerators" ),
1954
i18n( "No accelerator is used more than once." ) );
1957
void FormWindow::raiseWidgets()
1959
QWidgetList widgets;
1960
QPtrDictIterator<WidgetSelection> it( usedSelections );
1961
for ( ; it.current(); ++it )
1962
widgets.append( it.current()->widget() );
1964
RaiseCommand *cmd = new RaiseCommand( i18n( "Raise" ), this, widgets );
1966
commandHistory()->addCommand( cmd );
1969
void FormWindow::paste( const QString &cb, QWidget *parent )
1972
Resource resource( mainWindow() );
1973
resource.setWidget( this );
1974
resource.paste( cb, parent );
1977
void FormWindow::selectAll()
1979
checkedSelectionsForMove = FALSE;
1980
blockSignals( TRUE );
1981
QObjectList *l = mainContainer()->queryList( "QWidget" );
1983
for ( QObject *o = l->first(); o; o = l->next() ) {
1984
if ( ( (QWidget*)o )->isVisibleTo( this ) &&
1985
insertedWidgets[ (void*)o ] ) {
1986
selectWidget( (QWidget*)o );
1992
blockSignals( FALSE );
1993
emitSelectionChanged();
1994
if ( propertyWidget )
1995
emitShowProperties( propertyWidget );
1996
emitSelectionChanged();
1999
void FormWindow::layoutHorizontal()
2001
QWidgetList widgets( selectedWidgets() );
2002
LayoutHorizontalCommand *cmd = new LayoutHorizontalCommand( i18n( "Lay Out Horizontally" ),
2003
this, mainContainer(), 0, widgets );
2004
clearSelection( FALSE );
2005
commandHistory()->addCommand( cmd );
2009
void FormWindow::layoutVertical()
2011
QWidgetList widgets( selectedWidgets() );
2012
LayoutVerticalCommand *cmd = new LayoutVerticalCommand( i18n( "Lay Out Vertically" ),
2013
this, mainContainer(), 0, widgets );
2014
clearSelection( FALSE );
2015
commandHistory()->addCommand( cmd );
2019
void FormWindow::layoutHorizontalSplit()
2021
QWidgetList widgets( selectedWidgets() );
2022
LayoutHorizontalSplitCommand *cmd = new LayoutHorizontalSplitCommand( i18n( "Lay Out Horizontally (in splitter)" ),
2023
this, mainContainer(), 0, widgets );
2024
clearSelection( FALSE );
2025
commandHistory()->addCommand( cmd );
2029
void FormWindow::layoutVerticalSplit()
2031
QWidgetList widgets( selectedWidgets() );
2032
LayoutVerticalSplitCommand *cmd = new LayoutVerticalSplitCommand( i18n( "Lay Out Vertically (in splitter)" ),
2033
this, mainContainer(), 0, widgets );
2034
clearSelection( FALSE );
2035
commandHistory()->addCommand( cmd );
2039
void FormWindow::layoutGrid()
2041
int xres = grid().x();
2042
int yres = grid().y();
2044
QWidgetList widgets( selectedWidgets() );
2045
LayoutGridCommand *cmd = new LayoutGridCommand( i18n( "Lay Out in a Grid" ),
2046
this, mainContainer(), 0, widgets, xres, yres );
2047
clearSelection( FALSE );
2048
commandHistory()->addCommand( cmd );
2052
void FormWindow::layoutHorizontalContainer( QWidget *w )
2055
w = mainContainer();
2056
QObjectList *l = (QObjectList*)WidgetFactory::containerOfWidget(w)->children();
2059
QWidgetList widgets;
2060
for ( QObject *o = l->first(); o; o = l->next() ) {
2061
if ( o->isWidgetType() &&
2062
( (QWidget*)o )->isVisibleTo( this ) &&
2063
insertedWidgets.find( (QWidget*)o ) )
2064
widgets.append( (QWidget*)o );
2066
LayoutHorizontalCommand *cmd = new LayoutHorizontalCommand( i18n( "Lay Out Children Horizontally" ),
2067
this, mainContainer(), w, widgets );
2068
clearSelection( FALSE );
2069
commandHistory()->addCommand( cmd );
2073
void FormWindow::layoutVerticalContainer( QWidget *w )
2076
w = mainContainer();
2077
QObjectList *l = (QObjectList*)WidgetFactory::containerOfWidget(w)->children();
2080
QWidgetList widgets;
2081
for ( QObject *o = l->first(); o; o = l->next() ) {
2082
if ( o->isWidgetType() &&
2083
( (QWidget*)o )->isVisibleTo( this ) &&
2084
insertedWidgets.find( (QWidget*)o ) )
2085
widgets.append( (QWidget*)o );
2087
LayoutVerticalCommand *cmd = new LayoutVerticalCommand( i18n( "Lay Out Children Vertically" ),
2088
this, mainContainer(), w, widgets );
2089
clearSelection( FALSE );
2090
commandHistory()->addCommand( cmd );
2094
void FormWindow::layoutGridContainer( QWidget *w )
2097
w = mainContainer();
2098
int xres = grid().x();
2099
int yres = grid().y();
2101
QObjectList *l = (QObjectList*)WidgetFactory::containerOfWidget(w)->children();
2104
QWidgetList widgets;
2105
for ( QObject *o = l->first(); o; o = l->next() ) {
2106
if ( o->isWidgetType() &&
2107
( (QWidget*)o )->isVisibleTo( this ) &&
2108
insertedWidgets.find( (QWidget*)o ) )
2109
widgets.append( (QWidget*)o );
2111
LayoutGridCommand *cmd = new LayoutGridCommand( i18n( "Lay Out Children in a Grid" ),
2112
this, mainContainer(), w, widgets, xres, yres );
2113
clearSelection( FALSE );
2114
commandHistory()->addCommand( cmd );
2118
void FormWindow::breakLayout( QWidget *w )
2121
w = mainContainer();
2122
w = WidgetFactory::containerOfWidget( w );
2123
QPtrList<Command> commands;
2126
if ( !w || w == this )
2128
if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout &&
2129
WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ) ) {
2130
Command *cmd = breakLayoutCommand( w );
2132
commands.insert( 0, cmd );
2133
if ( !::qt_cast<QLayoutWidget*>(w) && !::qt_cast<QSplitter*>(w) )
2136
w = w->parentWidget();
2139
if ( commands.isEmpty() )
2142
clearSelection( FALSE );
2143
MacroCommand *cmd = new MacroCommand( i18n( "Break Layout" ), this, commands );
2144
commandHistory()->addCommand( cmd );
2148
BreakLayoutCommand *FormWindow::breakLayoutCommand( QWidget *w )
2150
CHECK_MAINWINDOW_VALUE( 0 );
2151
QObjectList *l = (QObjectList*)w->children();
2155
QWidgetList widgets;
2156
for ( QObject *o = l->first(); o; o = l->next() ) {
2157
if ( o->isWidgetType() &&
2158
!mainWindow()->isAToolBarChild( (QWidget*)o ) &&
2159
( (QWidget*)o )->isVisibleTo( this ) &&
2160
insertedWidgets.find( (QWidget*)o ) )
2161
widgets.append( (QWidget*)o );
2163
return new BreakLayoutCommand( i18n( "Break Layout" ), this, WidgetFactory::widgetOfContainer( w ), widgets );
2166
int FormWindow::numVisibleWidgets() const
2168
QPtrDictIterator<QWidget> it( insertedWidgets );
2170
for ( ; it.current(); ++it ) {
2171
if ( it.current()->isVisibleTo( (FormWindow*)this ) )
2177
bool FormWindow::hasInsertedChildren( QWidget *w ) const
2181
w = WidgetFactory::containerOfWidget( w );
2184
QObjectList *l = w->queryList( "QWidget" );
2185
if ( !l || !l->first() ) {
2190
for ( QObject *o = l->first(); o; o = l->next() ) {
2191
if ( o->isWidgetType() &&
2192
( (QWidget*)o )->isVisibleTo( (FormWindow*)this ) &&
2193
insertedWidgets.find( (QWidget*)o ) ) {
2203
bool FormWindow::allowMove( QWidget *w )
2205
w = w->parentWidget();
2207
if ( ( isMainContainer( w ) || insertedWidgets.find( w ) ) && WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout )
2209
w = w->parentWidget();
2215
void FormWindow::editConnections()
2219
if ( !startWidget || !endWidget )
2222
ConnectionDialog dlg( mainwindow );
2223
mainWindow()->statusMessage( i18n( "Edit connections...") );
2224
dlg.addConnection( startWidget, endWidget, QString::null, QString::null );
2225
QTimer::singleShot( 0, &dlg, SLOT(ensureConnectionVisible()) );
2229
void FormWindow::saveBackground()
2233
buffer = new QPixmap( width(), height() );
2234
*buffer = QPixmap::grabWindow( winId() );
2237
void FormWindow::restoreConnectionLine()
2239
if (!unclippedPainter || !buffer) // designer will occasionally crash if buffer is not tested to be non-zero
2242
int a =QABS( startPos.x() - currentPos.x() );
2243
int b = QABS( startPos.y() - currentPos.y() );
2244
QRect r( startPos, currentPos );
2246
if ( a < 32 || b < 32 ) { // special case: vertical or horizontal line
2248
unclippedPainter->drawPixmap( r.x() - 2, r.y() - 2, *buffer,
2249
r.x() - 2, r.y() - 2, r.width() + 4, r.height() + 4 );
2268
QPoint p( startPos );
2270
if ( r.x() > r.right() ) {
2272
p.setX( p.x() - 64 );
2275
if ( r.y() > r.bottom() ) {
2277
p.setY( p.y() - 64 );
2283
while ( r.contains( p ) ) {
2284
unclippedPainter->drawPixmap( p, *buffer, QRect( p, QSize( w, h ) ) );
2285
unclippedPainter->setPen( red );
2286
p.setX( p.x() + dx );
2287
p.setY( p.y() + dy );
2290
unclippedPainter->drawPixmap( startPos.x() - 10, startPos.y() - 10, *buffer,
2291
startPos.x() - 10, startPos.y() - 10, 20, 20 );
2294
void FormWindow::restoreRect( const QRect &rect )
2296
if (!unclippedPainter || !buffer)
2302
r = QRect( r.x() + 2, r.y() + 2, r.width() - 4, r.height() - 4 );
2304
unclippedPainter->drawPixmap( r.x() - 2, r.y() - 2, *buffer, r.x() - 2, r.y() - 2, r.width() + 4, 4 );
2305
unclippedPainter->drawPixmap( r.x() - 2, r.y() - 2, *buffer, r.x() - 2, r.y() - 2, 4, r.height() + 4 );
2306
unclippedPainter->drawPixmap( r.x() - 2, r.y() + r.height() - 3, *buffer, r.x() - 2, r.y() + r.height() - 3, r.width() + 4, 5 );
2307
unclippedPainter->drawPixmap( r.x() + r.width() - 2, r.y(), *buffer, r.x() + r.width() - 2, r.y(), 4, r.height() + 4 );
2310
void FormWindow::drawConnectionLine()
2312
if ( !unclippedPainter )
2315
unclippedPainter->setPen( QPen( white, 2 ) );
2316
unclippedPainter->drawLine( startPos, currentPos );
2317
if ( validForBuddy )
2318
unclippedPainter->setPen( QPen( darkRed, 1 ) );
2320
unclippedPainter->setPen( QPen( darkCyan, 1 ) );
2321
unclippedPainter->drawLine( startPos, currentPos );
2323
if ( validForBuddy )
2324
unclippedPainter->setPen( QPen( darkGreen, 1 ) );
2326
unclippedPainter->setPen( QPen( magenta, 1 ) );
2327
if ( startWidget ) {
2328
QWidget *s = (QWidget*)startWidget;
2329
QPoint p = mapToForm( s, QPoint(0,0) );
2330
unclippedPainter->drawRect( QRect( p + QPoint( 2, 2 ), s->size() - QSize( 4, 4 ) ) );
2333
QWidget *e = (QWidget*)endWidget;
2334
QPoint p = mapToForm( e, QPoint(0,0) );
2335
unclippedPainter->drawRect( QRect( p + QPoint( 2, 2 ), e->size() - QSize( 4, 4 ) ) );
2339
QString FormWindow::fileName() const
2341
return ff->absFileName();
2344
void FormWindow::setFileName( const QString &fn )
2346
ff->setFileName( fn );
2347
emit fileNameChanged( ff->fileName(), this );
2350
void FormWindow::modificationChanged( bool m )
2352
emit modificationChanged( m, this );
2353
emit modificationChanged( m, ff->fileName() );
2356
bool FormWindow::unify( QObject *w, QString &s, bool changeIt )
2358
bool found = !isMainContainer( w ) && qstrcmp( name(), s.latin1() ) == 0;
2362
QPtrDictIterator<QWidget> it( insertedWidgets );
2363
for ( ; it.current();) {
2364
if ( it.current() != w &&
2365
qstrcmp( it.current()->name(), s.latin1() ) == 0 ) {
2369
s = orig + "_" + QString::number( ++num );
2376
QPtrList<QAction> al;
2378
for ( a = actions.first(); a; a = actions.next() ) {
2379
QObjectList *l = a->queryList( "QAction" );
2381
for ( QObject *ao = l->first(); ao; ao = l->next() )
2382
al.append( (QAction*)ao );
2385
for ( a = al.first(); a; a = al.next() ) {
2387
qstrcmp( a->name(), s.latin1() ) == 0 ) {
2391
s = orig + "_" + QString::number( ++num );
2392
a = actions.first();
2396
if ( ::qt_cast<QMainWindow*>(mainContainer()) && !found ) {
2397
QObjectList *l = mainContainer()->queryList( "PopupMenuEditor" );
2398
for ( QObject *o = l->first(); o; o = l->next() ) {
2400
qstrcmp ( o->name(), s.latin1() ) == 0 ) {
2404
s = orig + "_" + QString::number( ++num );
2410
if ( ::qt_cast<QMainWindow*>(mainContainer()) ) {
2412
QObjectList *l = mainContainer()->queryList( "QDockWindow", 0, TRUE );
2413
for ( QObject *o = l->first(); o; o = l->next() ) {
2415
qstrcmp( o->name(), s.latin1() ) == 0 ) {
2419
s = orig + "_" + QString::number( ++num );
2433
bool FormWindow::isCustomWidgetUsed( MetaDataBase::CustomWidget *w )
2435
QPtrDictIterator<QWidget> it( insertedWidgets );
2436
for ( ; it.current(); ++it ) {
2437
if ( it.current()->isA( "CustomWidget" ) ) {
2438
if ( qstrcmp( WidgetFactory::classNameOf( it.current() ), w->className.utf8() ) == 0 )
2446
bool FormWindow::isDatabaseWidgetUsed() const
2449
QStringList dbClasses;
2450
dbClasses << "QDataTable"; // add more here
2451
QPtrDictIterator<QWidget> it( insertedWidgets );
2452
for ( ; it.current(); ++it ) {
2453
QString c( it.current()->className() );
2454
if ( dbClasses.contains( c ) > 0 ) {
2462
bool FormWindow::isDatabaseAware() const
2465
if ( QString(mContainer->className()) == "QDesignerDataBrowser" || QString(mContainer->className()) == "QDesignerDataView" )
2467
return isDatabaseWidgetUsed();
2473
void FormWindow::visibilityChanged()
2475
if ( currTool != ORDER_TOOL ) {
2476
emitUpdateProperties( currentWidget() );
2478
updateOrderIndicators();
2479
repositionOrderIndicators();
2485
Maps \a pos in \a w's coordinates to the form's coordinate system.
2487
This is the equivalent to mapFromGlobal(w->mapToGlobal(pos) ) but
2488
avoids the two roundtrips to the X-Server on Unix/X11.
2490
QPoint FormWindow::mapToForm( const QWidget* w, const QPoint& pos ) const
2493
const QWidget* i = w;
2494
while ( i && !i->isTopLevel() && !isMainContainer( (QWidget*)i ) ) {
2495
p = i->mapToParent( p );
2496
i = i->parentWidget();
2498
return mapFromGlobal( w->mapToGlobal( pos ) );
2501
static int widgetDepth( QWidget *w )
2504
while ( w && !w->isTopLevel() ) {
2506
w = w->parentWidget();
2512
static bool isChildOf( QWidget *c, QWidget *p )
2514
while ( c && !c->isTopLevel() ) {
2517
c = c->parentWidget();
2522
QWidget *FormWindow::containerAt( const QPoint &pos, QWidget *notParentOf )
2524
QPtrDictIterator<QWidget> it( insertedWidgets );
2525
QWidget *container = 0;
2527
QWidgetList selected = selectedWidgets();
2528
if ( rect().contains( mapFromGlobal( pos ) ) ) {
2529
container = mainContainer();
2530
depth = widgetDepth( container );
2533
for ( ; it.current(); ++it ) {
2534
if ( ::qt_cast<QLayoutWidget*>(it.current())
2535
|| ::qt_cast<QSplitter*>(it.current()) )
2537
if ( !it.current()->isVisibleTo( this ) )
2539
if ( selected.find( it.current() ) != -1 )
2541
if ( !WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( it.current() ) ) ) &&
2542
it.current() != mainContainer() )
2545
// the rectangles of all ancestors of the container must contain the insert position
2546
QWidget *w = it.current();
2547
while ( w && !w->isTopLevel() ) {
2548
if ( !w->rect().contains( ( w->mapFromGlobal( pos ) ) ) )
2550
w = w->parentWidget();
2552
if ( !( w == 0 || w->isTopLevel() ) ) continue; // we did not get through the full while loop
2554
int wd = widgetDepth( it.current() );
2555
if ( wd == depth && container ) {
2556
if ( ( (QObjectList*)it.current()->parentWidget()->children() )->find( it.current() ) >
2557
( (QObjectList*)container->parentWidget()->children() )->find( container ) )
2560
if ( wd > depth && !isChildOf( it.current(), notParentOf ) ) {
2562
container = it.current();
2569
bool FormWindow::isMainContainer( QObject *w ) const
2571
return w && w->isWidgetType() && ( w == (QWidget*)this || w == mainContainer() );
2574
void FormWindow::setMainContainer( QWidget *w )
2576
bool resetPropertyWidget = isMainContainer( propertyWidget );
2578
insertedWidgets.remove( mContainer );
2579
if ( propertyWidget == mContainer )
2583
insertedWidgets.insert( mContainer, mContainer );
2585
QHBoxLayout *l = new QHBoxLayout( this );
2587
if ( resetPropertyWidget ) {
2588
QObject *opw = propertyWidget;
2589
propertyWidget = mContainer;
2590
if ( opw && opw->isWidgetType() )
2591
repaintSelection( (QWidget*)opw );
2594
LanguageInterface *iface = MetaDataBase::languageInterface( project()->language() );
2595
if ( iface && !project()->isCpp() && !isFake() ) {
2596
if ( !MetaDataBase::hasFunction( this, "init()" ) )
2597
MetaDataBase::addFunction( this, "init()", "", "private", "function",
2598
project()->language(), "void" );
2599
if ( !MetaDataBase::hasFunction( this, "destroy()" ) )
2600
MetaDataBase::addFunction( this, "destroy()", "", "private", "function",
2601
project()->language(), "void" );
2602
if ( !MetaDataBase::hasConnection( this, mainContainer(), "shown()", mainContainer(), "init" ) )
2603
MetaDataBase::addConnection( this, mainContainer(), "shown()", mainContainer(), "init" );
2604
if ( !MetaDataBase::hasConnection( this, mainContainer(), "destroyed()", mainContainer(), "destroy" ) )
2605
MetaDataBase::addConnection( this, mainContainer(), "destroyed()",
2606
mainContainer(), "destroy" );
2611
bool FormWindow::savePixmapInline() const
2616
bool FormWindow::savePixmapInProject() const
2621
QString FormWindow::pixmapLoaderFunction() const
2626
void FormWindow::setSavePixmapInline( bool b )
2633
void FormWindow::setSavePixmapInProject( bool b )
2640
void FormWindow::setPixmapLoaderFunction( const QString &func )
2645
void FormWindow::setActiveObject( QObject *o )
2647
emitShowProperties( o );
2651
void FormWindow::setProject( Project *pro )
2656
Project *FormWindow::project() const
2661
QAction *FormWindow::findAction( const QString &name )
2663
for ( QAction *a = actionList().first(); a; a = actionList().next() ) {
2664
if ( QString( a->name() ) == name )
2666
QAction *ac = (QAction*)a->child( name.latin1(), "QAction" );
2673
void FormWindow::killAccels( QObject *top )
2675
QObjectList *l = top->queryList( "QAccel" );
2678
for ( QObject *o = l->first(); o; o = l->next() )
2679
( (QAccel*)o )->setEnabled( FALSE );
2683
DesignerFormWindow *FormWindow::iFace()
2686
iface = new DesignerFormWindowImpl( this );
2690
bool FormWindow::isCentralWidget( QObject *w ) const
2692
if ( !::qt_cast<QMainWindow*>(mainContainer()) )
2694
return w == ( (QMainWindow*)mainContainer() )->centralWidget();
2697
int FormWindow::layoutDefaultSpacing() const
2702
int FormWindow::layoutDefaultMargin() const
2707
void FormWindow::setLayoutDefaultSpacing( int s )
2712
void FormWindow::setLayoutDefaultMargin( int s )
2717
void FormWindow::setSpacingFunction( const QString &funct )
2719
spacFunction = funct;
2722
QString FormWindow::spacingFunction() const
2724
return spacFunction;
2727
void FormWindow::hasLayoutFunctions( bool b )
2732
bool FormWindow::hasLayoutFunctions() const
2734
return hasLayoutFunc;
2737
void FormWindow::setMarginFunction( const QString &funct )
2739
margFunction = funct;
2742
QString FormWindow::marginFunction() const
2744
return margFunction;
2747
FormFile *FormWindow::formFile() const
2752
void FormWindow::setFormFile( FormFile *f )
2756
connect( this, SIGNAL( modificationChanged(bool, const QString&) ), ff, SLOT( formWindowChangedSomehow() ) );
2759
bool FormWindow::canBeBuddy( const QWidget *w ) const
2761
return w->focusPolicy() != QWidget::NoFocus;
2764
bool FormWindow::event( QEvent *e )
2766
if (e->type() == QEvent::ShowMaximized)
2768
#if QT_VERSION >= 0x030300
2769
if ( isMaximized() )
2770
setWindowState( windowState() & ~WindowMaximized | WindowActive);
2774
return QWidget::event(e);