1
/**********************************************************************
2
** Copyright (C) 2002 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 "connectionitems.h"
28
#include "formwindow.h"
29
#include "mainwindow.h"
30
#include "metadatabase.h"
31
#include "widgetfactory.h"
34
#include <qcombobox.h>
35
#include <qmetaobject.h>
36
#include <qcombobox.h>
39
#include <qdatabrowser.h>
41
static const char* const ignore_slots[] = {
43
"setCaption(const QString&)",
44
"setIcon(const QPixmap&)",
45
"setIconText(const QString&)",
46
"setMouseTracking(bool)",
48
"setUpdatesEnabled(bool)",
50
"update(int,int,int,int)",
51
"update(const QRect&)",
54
"repaint(int,int,int,int,bool)",
55
"repaint(const QRect&,bool)",
56
"repaint(const QRegion&,bool)",
68
"stackUnder(QWidget*)",
70
"move(const QPoint&)",
72
"resize(const QSize&)",
73
"setGeometry(int,int,int,int)",
74
"setGeometry(const QRect&)",
75
"focusProxyDestroyed()",
76
"showExtension(bool)",
78
"showDockMenu(const QPoint&)",
85
ConnectionItem::ConnectionItem( QTable *table, FormWindow *fw )
86
: QComboTableItem( table, QStringList(), FALSE ), formWindow( fw ), conn( 0 )
88
setReplaceable( FALSE );
91
void ConnectionItem::senderChanged( QObject * )
94
QWidget *w = table()->cellWidget( row(), col() );
96
setContentFromEditor( w );
99
void ConnectionItem::receiverChanged( QObject * )
102
QWidget *w = table()->cellWidget( row(), col() );
104
setContentFromEditor( w );
107
void ConnectionItem::signalChanged( const QString & )
110
QWidget *w = table()->cellWidget( row(), col() );
112
setContentFromEditor( w );
115
void ConnectionItem::slotChanged( const QString & )
118
QWidget *w = table()->cellWidget( row(), col() );
120
setContentFromEditor( w );
123
void ConnectionItem::setSender( SenderItem *i )
125
connect( i, SIGNAL( currentSenderChanged( QObject * ) ),
126
this, SLOT( senderChanged( QObject * ) ) );
129
void ConnectionItem::setReceiver( ReceiverItem *i )
131
connect( i, SIGNAL( currentReceiverChanged( QObject * ) ),
132
this, SLOT( receiverChanged( QObject * ) ) );
135
void ConnectionItem::setSignal( SignalItem *i )
137
connect( i, SIGNAL( currentSignalChanged( const QString & ) ),
138
this, SLOT( signalChanged( const QString & ) ) );
141
void ConnectionItem::setSlot( SlotItem *i )
143
connect( i, SIGNAL( currentSlotChanged( const QString & ) ),
144
this, SLOT( slotChanged( const QString & ) ) );
147
void ConnectionItem::paint( QPainter *p, const QColorGroup &cg,
148
const QRect &cr, bool selected )
150
p->fillRect( 0, 0, cr.width(), cr.height(),
151
selected ? cg.brush( QColorGroup::Highlight )
152
: cg.brush( QColorGroup::Base ) );
159
if ( currentText()[0] == '<' )
160
p->setPen( QObject::red );
162
p->setPen( cg.highlightedText() );
164
p->setPen( cg.text() );
166
QFont f( p->font() );
167
QFont oldf( p->font() );
168
if ( conn && conn->isModified() ) {
173
p->drawText( x + 2, 0, w - x - 4, h, alignment(), currentText() );
177
void ConnectionItem::setConnection( ConnectionContainer *c )
182
// ------------------------------------------------------------------
184
static void appendChildActions( QAction *action, QStringList &lst )
186
QObjectListIt it( *action->children() );
187
while ( it.current() ) {
188
QObject *o = it.current();
190
if ( !::qt_cast<QAction*>(o) )
193
if ( o->children() && ::qt_cast<QActionGroup*>(o) )
194
appendChildActions( (QAction*)o, lst );
198
static QStringList flatActions( const QPtrList<QAction> &l )
202
QPtrListIterator<QAction> it( l );
203
while ( it.current() ) {
204
QAction *action = it.current();
205
lst << action->name();
206
if ( action->children() && ::qt_cast<QActionGroup*>(action) )
207
appendChildActions( action, lst );
214
// ------------------------------------------------------------------
216
SenderItem::SenderItem( QTable *table, FormWindow *fw )
217
: ConnectionItem( table, fw )
221
QPtrDictIterator<QWidget> it( *formWindow->widgets() );
222
while ( it.current() ) {
223
if ( lst.find( it.current()->name() ) != lst.end() ) {
227
if ( !QString( it.current()->name() ).startsWith( "qt_dead_widget_" ) &&
228
!::qt_cast<QLayoutWidget*>(it.current()) &&
229
!::qt_cast<Spacer*>(it.current()) &&
230
!::qt_cast<SizeHandle*>(it.current()) &&
231
qstrcmp( it.current()->name(), "central widget" ) != 0 ) {
232
lst << it.current()->name();
237
lst += flatActions( formWindow->actionList() );
239
lst.prepend( "<No Sender>" );
241
setStringList( lst );
244
QWidget *SenderItem::createEditor() const
246
QComboBox *cb = (QComboBox*)ConnectionItem::createEditor();
247
cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) );
248
connect( cb, SIGNAL( activated( const QString & ) ),
249
this, SLOT( senderChanged( const QString & ) ) );
253
void SenderItem::setSenderEx( QObject *sender )
255
setCurrentItem( sender->name() );
256
emit currentSenderChanged( sender );
259
void SenderItem::senderChanged( const QString &sender )
261
QObject *o = formWindow->child( sender, "QObject" );
263
o = formWindow->findAction( sender );
266
emit currentSenderChanged( o );
271
// ------------------------------------------------------------------
273
ReceiverItem::ReceiverItem( QTable *table, FormWindow *fw )
274
: ConnectionItem( table, fw )
278
QPtrDictIterator<QWidget> it( *formWindow->widgets() );
279
while ( it.current() ) {
280
if ( lst.find( it.current()->name() ) != lst.end() ) {
284
if ( !QString( it.current()->name() ).startsWith( "qt_dead_widget_" ) &&
285
!::qt_cast<QLayoutWidget*>(it.current()) &&
286
!::qt_cast<Spacer*>(it.current()) &&
287
!::qt_cast<SizeHandle*>(it.current()) &&
288
qstrcmp( it.current()->name(), "central widget" ) != 0 ) {
289
lst << it.current()->name();
294
lst += flatActions( formWindow->actionList() );
296
lst.prepend( "<No Receiver>" );
298
setStringList( lst );
301
QWidget *ReceiverItem::createEditor() const
303
QComboBox *cb = (QComboBox*)ConnectionItem::createEditor();
304
cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) );
305
connect( cb, SIGNAL( activated( const QString & ) ),
306
this, SLOT( receiverChanged( const QString & ) ) );
310
void ReceiverItem::setReceiverEx( QObject *receiver )
312
setCurrentItem( receiver->name() );
313
emit currentReceiverChanged( receiver );
316
void ReceiverItem::receiverChanged( const QString &receiver )
318
QObject *o = formWindow->child( receiver, "QObject" );
320
o = formWindow->findAction( receiver );
323
emit currentReceiverChanged( o );
328
// ------------------------------------------------------------------
330
SignalItem::SignalItem( QTable *table, FormWindow *fw )
331
: ConnectionItem( table, fw )
334
lst << "<No Signal>";
336
setStringList( lst );
339
void SignalItem::senderChanged( QObject *sender )
341
QStrList sigs = sender->metaObject()->signalNames( TRUE );
342
sigs.remove( "destroyed()" );
343
sigs.remove( "destroyed(QObject*)" );
344
sigs.remove( "accessibilityChanged(int)" );
345
sigs.remove( "accessibilityChanged(int,int)" );
347
QStringList lst = QStringList::fromStrList( sigs );
349
if ( ::qt_cast<CustomWidget*>(sender) ) {
350
MetaDataBase::CustomWidget *w = ( (CustomWidget*)sender )->customWidget();
351
for ( QValueList<QCString>::Iterator it = w->lstSignals.begin();
352
it != w->lstSignals.end(); ++it )
353
lst << MetaDataBase::normalizeFunction( *it );
356
if ( sender == formWindow->mainContainer() ) {
357
QStringList extra = MetaDataBase::signalList( formWindow );
358
if ( !extra.isEmpty() )
362
lst.prepend( "<No Signal>" );
365
setStringList( lst );
367
ConnectionItem::senderChanged( sender );
370
QWidget *SignalItem::createEditor() const
372
QComboBox *cb = (QComboBox*)ConnectionItem::createEditor();
373
cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) );
374
connect( cb, SIGNAL( activated( const QString & ) ),
375
this, SIGNAL( currentSignalChanged( const QString & ) ) );
379
// ------------------------------------------------------------------
381
SlotItem::SlotItem( QTable *table, FormWindow *fw )
382
: ConnectionItem( table, fw )
387
setStringList( lst );
390
lastSignal = "<No Signal>";
393
void SlotItem::receiverChanged( QObject *receiver )
395
lastReceiver = receiver;
397
ConnectionItem::receiverChanged( receiver );
400
void SlotItem::signalChanged( const QString &signal )
404
ConnectionItem::signalChanged( signal );
407
bool SlotItem::ignoreSlot( const char* slot ) const
410
if ( qstrcmp( slot, "update()" ) == 0 &&
411
::qt_cast<QDataBrowser*>(lastReceiver) )
415
for ( int i = 0; ignore_slots[i]; i++ ) {
416
if ( qstrcmp( slot, ignore_slots[i] ) == 0 )
420
if ( !formWindow->isMainContainer( (QWidget*)lastReceiver ) ) {
421
if ( qstrcmp( slot, "close()" ) == 0 )
425
if ( qstrcmp( slot, "setFocus()" ) == 0 )
426
if ( lastReceiver->isWidgetType() &&
427
( (QWidget*)lastReceiver )->focusPolicy() == QWidget::NoFocus )
433
void SlotItem::updateSlotList()
436
if ( !lastReceiver || lastSignal == "<No Signal>" ) {
439
setStringList( lst );
443
QString signal = MetaDataBase::normalizeFunction( lastSignal );
444
int n = lastReceiver->metaObject()->numSlots( TRUE );
447
for( int i = 0; i < n; ++i ) {
448
// accept only public slots. For the form window, also accept protected slots
449
const QMetaData* md = lastReceiver->metaObject()->slot( i, TRUE );
450
if ( ( (lastReceiver->metaObject()->slot( i, TRUE )->access == QMetaData::Public) ||
451
(formWindow->isMainContainer( (QWidget*)lastReceiver ) &&
452
lastReceiver->metaObject()->slot(i, TRUE)->access ==
453
QMetaData::Protected) ) &&
454
!ignoreSlot( md->name ) &&
455
checkConnectArgs( signal.latin1(), lastReceiver, md->name ) )
456
if ( lst.find( md->name ) == lst.end() )
457
lst << MetaDataBase::normalizeFunction( md->name );
460
LanguageInterface *iface =
461
MetaDataBase::languageInterface( formWindow->project()->language() );
462
if ( !iface || iface->supports( LanguageInterface::ConnectionsToCustomSlots ) ) {
463
if ( formWindow->isMainContainer( (QWidget*)lastReceiver ) ) {
464
QValueList<MetaDataBase::Function> moreSlots = MetaDataBase::slotList( formWindow );
465
if ( !moreSlots.isEmpty() ) {
466
for ( QValueList<MetaDataBase::Function>::Iterator it = moreSlots.begin();
467
it != moreSlots.end(); ++it ) {
468
QCString s = (*it).function;
471
s = MetaDataBase::normalizeFunction( s );
472
if ( checkConnectArgs( signal.latin1(), lastReceiver, s ) ) {
473
if ( lst.find( (*it).function ) == lst.end() )
481
if ( ::qt_cast<CustomWidget*>(lastReceiver) ) {
482
MetaDataBase::CustomWidget *w = ( (CustomWidget*)lastReceiver )->customWidget();
483
for ( QValueList<MetaDataBase::Function>::Iterator it = w->lstSlots.begin();
484
it != w->lstSlots.end(); ++it ) {
485
QCString s = (*it).function;
488
s = MetaDataBase::normalizeFunction( s );
489
if ( checkConnectArgs( signal.latin1(), lastReceiver, s ) ) {
490
if ( lst.find( (*it).function ) == lst.end() )
496
lst.prepend( "<No Slot>" );
498
setStringList( lst );
501
QWidget *SlotItem::createEditor() const
503
QComboBox *cb = (QComboBox*)ConnectionItem::createEditor();
504
cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) );
505
connect( cb, SIGNAL( activated( const QString & ) ),
506
this, SIGNAL( currentSlotChanged( const QString & ) ) );
510
void SlotItem::customSlotsChanged()
512
QString currSlot = currentText();
514
setCurrentItem( "<No Slot>" );
515
setCurrentItem( currSlot );
516
emit currentSlotChanged( currentText() );