|
|
|
/**********************************************************************
|
|
|
|
This file is based on TQt Designer, Copyright (C) 2000 Trolltech AS. All rights reserved.
|
|
|
|
|
|
|
|
This file may be distributed and/or modified under the terms of the
|
|
|
|
GNU General Public License version 2 as published by the Free Software
|
|
|
|
Foundation and appearing in the file LICENSE.GPL included in the
|
|
|
|
packaging of this file.
|
|
|
|
|
|
|
|
This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
|
|
WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See http://www.trolltech.com/gpl/ for GPL licensing information.
|
|
|
|
|
|
|
|
Modified for Kommander:
|
|
|
|
(C) 2004 Michal Rudolf <mrudolf@tdewebdev.org>
|
|
|
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#include "connectioneditorimpl.h"
|
|
|
|
#include "metadatabase.h"
|
|
|
|
#include "formwindow.h"
|
|
|
|
#include "mainwindow.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "widgetfactory.h"
|
|
|
|
#include "pixmapchooser.h"
|
|
|
|
#include <tqmetaobject.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
|
|
|
|
#include <klistbox.h>
|
|
|
|
#include <klistview.h>
|
|
|
|
#include <kpushbutton.h>
|
|
|
|
#include <kcombobox.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
static const char *const ignore_slots[] = {
|
|
|
|
"destroyed()",
|
|
|
|
//"setCaption(const TQString&)",
|
|
|
|
"setIcon(const TQPixmap&)",
|
|
|
|
//"setIconText(const TQString&)",
|
|
|
|
"setMouseTracking(bool)",
|
|
|
|
"clearFocus()",
|
|
|
|
"setUpdatesEnabled(bool)",
|
|
|
|
"update()",
|
|
|
|
"update(int,int,int,int)",
|
|
|
|
"update(const TQRect&)",
|
|
|
|
"tqrepaint()",
|
|
|
|
"tqrepaint(bool)",
|
|
|
|
"tqrepaint(int,int,int,int,bool)",
|
|
|
|
"tqrepaint(const TQRect&,bool)",
|
|
|
|
"tqrepaint(const TQRegion&,bool)",
|
|
|
|
"tqrepaint(int,int,int,int)",
|
|
|
|
"tqrepaint(const TQRect&)",
|
|
|
|
"tqrepaint(const TQRegion&)",
|
|
|
|
//"show()",
|
|
|
|
//"hide()",
|
|
|
|
"iconify()",
|
|
|
|
"showMinimized()",
|
|
|
|
"showMaximized()",
|
|
|
|
"showFullScreen()",
|
|
|
|
"showNormal()",
|
|
|
|
"polish()",
|
|
|
|
"constPolish()",
|
|
|
|
//"raise()",
|
|
|
|
//"lower()",
|
|
|
|
"stackUnder(TQWidget*)",
|
|
|
|
//"move(int,int)",
|
|
|
|
"move(const TQPoint&)",
|
|
|
|
//"resize(int,int)",
|
|
|
|
"resize(const TQSize&)",
|
|
|
|
//"setGeometry(int,int,int,int)",
|
|
|
|
"setGeometry(const TQRect&)",
|
|
|
|
"focusProxyDestroyed()",
|
|
|
|
"showExtension(bool)",
|
|
|
|
"setUpLayout()",
|
|
|
|
//"showDockMenu(const TQPoint&)",
|
|
|
|
"init()",
|
|
|
|
"destroy()",
|
|
|
|
"deleteLater()",
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *const ignore_signals[] = {
|
|
|
|
"destroyed()",
|
|
|
|
"destroyed(TQObject*)",
|
|
|
|
"accessibilityChanged(int)",
|
|
|
|
"accessibilityChanged(int,int)",
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
ConnectionEditor::ConnectionEditor(TQWidget* parent, TQObject* sndr, TQObject* rcvr, FormWindow* fw)
|
|
|
|
: ConnectionEditorBase(parent, 0, true), m_formWindow(fw)
|
|
|
|
{
|
|
|
|
if (!rcvr || TQT_BASE_OBJECT(rcvr) == TQT_BASE_OBJECT(m_formWindow))
|
|
|
|
rcvr = TQT_TQOBJECT(m_formWindow->mainContainer());
|
|
|
|
if (!sndr || TQT_BASE_OBJECT(sndr) == TQT_BASE_OBJECT(m_formWindow))
|
|
|
|
sndr = TQT_TQOBJECT(m_formWindow->mainContainer());
|
|
|
|
m_sender = sndr;
|
|
|
|
m_receiver = rcvr;
|
|
|
|
|
|
|
|
/* Create widget list */
|
|
|
|
TQStringList lst;
|
|
|
|
lst << m_formWindow->name();
|
|
|
|
for (TQPtrDictIterator<TQWidget> it(*m_formWindow->widgets()); it.current(); ++it)
|
|
|
|
{
|
|
|
|
if (it.current()->isVisibleTo(this) &&
|
|
|
|
!it.current()->inherits(TQLAYOUTWIDGET_OBJECT_NAME_STRING) &&
|
|
|
|
!it.current()->inherits("Spacer") &&
|
|
|
|
qstrcmp(it.current()->name(), "central widget") &&
|
|
|
|
!m_formWindow->isMainContainer(TQT_TQOBJECT(it.current())) &&
|
|
|
|
!lst.contains(it.current()->name()))
|
|
|
|
lst << it.current()->name();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill receiver combos with widget list
|
|
|
|
// fillWidgetList(comboReceiver, lst, m_receiver->name());
|
|
|
|
|
|
|
|
// Fill receiver combos with widget and action list
|
|
|
|
for (TQPtrListIterator<TQAction> it(m_formWindow->actionList()); it.current(); ++it)
|
|
|
|
lst << it.current()->name();
|
|
|
|
lst.sort();
|
|
|
|
fillWidgetList(comboReceiver, lst, m_receiver->name());
|
|
|
|
fillWidgetList(comboSender, lst, m_sender->name());
|
|
|
|
senderChanged(m_sender->name());
|
|
|
|
fillConnectionsList();
|
|
|
|
updateConnectButton();
|
|
|
|
updateDisconnectButton();
|
|
|
|
|
|
|
|
// Connections
|
|
|
|
connect(comboSender, TQT_SIGNAL(activated(const TQString&)), TQT_SLOT(senderChanged(const TQString&)));
|
|
|
|
connect(comboReceiver, TQT_SIGNAL(activated(const TQString&)), TQT_SLOT(receiverChanged(const TQString&)));
|
|
|
|
connect(signalBox, TQT_SIGNAL(selectionChanged()), TQT_SLOT(updateConnectButton()));
|
|
|
|
connect(slotBox, TQT_SIGNAL(selectionChanged()), TQT_SLOT(updateConnectButton()));
|
|
|
|
connect(connectButton, TQT_SIGNAL(clicked()), TQT_SLOT(connectClicked()));
|
|
|
|
connect(disconnectButton, TQT_SIGNAL(clicked()), TQT_SLOT(disconnectClicked()));
|
|
|
|
connect(okButton, TQT_SIGNAL(clicked()), TQT_SLOT(okClicked()));
|
|
|
|
connect(cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(cancelClicked()));
|
|
|
|
connect(signalBox, TQT_SIGNAL(doubleClicked(TQListBoxItem*)), TQT_SLOT(connectClicked()));
|
|
|
|
connect(slotBox, TQT_SIGNAL(doubleClicked(TQListBoxItem*)), TQT_SLOT(connectClicked()));
|
|
|
|
}
|
|
|
|
|
|
|
|
ConnectionEditor::~ConnectionEditor()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ConnectionEditor::isSignalIgnored(const char *signal) const
|
|
|
|
{
|
|
|
|
for (int i = 0; ignore_signals[i]; i++)
|
|
|
|
if (!qstrcmp(signal, ignore_signals[i]))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ConnectionEditor::isSlotIgnored(const TQMetaData* md)
|
|
|
|
{
|
|
|
|
if (md->tqt_mo_access != TQMetaData::Public && (md->tqt_mo_access != TQMetaData::Protected ||
|
|
|
|
!m_formWindow->isMainContainer(TQT_TQOBJECT(m_receiver))))
|
|
|
|
return true;
|
|
|
|
for (int i = 0; ignore_slots[i]; i++)
|
|
|
|
if (!qstrcmp(md->tqt_mo_ci_name, ignore_slots[i]))
|
|
|
|
return true;
|
|
|
|
if (!m_formWindow->isMainContainer(TQT_TQOBJECT(m_receiver)) && !qstrcmp(md->tqt_mo_ci_name, "close()"))
|
|
|
|
return true;
|
|
|
|
if (!qstrcmp(md->tqt_mo_ci_name, "setFocus()") && m_receiver->isWidgetType() &&
|
|
|
|
((TQWidget*)m_receiver)->focusPolicy() == TQ_NoFocus)
|
|
|
|
return true;
|
|
|
|
for (int i = 0; i<comboSender->count(); i++)
|
|
|
|
if (checkConnectArgs(MetaDataBase::normalizeSlot(signalBox->text(i)).latin1(), m_receiver, md->tqt_mo_ci_name))
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQObject* ConnectionEditor::objectByName(const TQString& s) const
|
|
|
|
{
|
|
|
|
for (TQPtrDictIterator <TQWidget> it(*m_formWindow->widgets()); it.current(); ++it)
|
|
|
|
if (TQString(it.current()->name()) == s)
|
|
|
|
return TQT_TQOBJECT(it.current());
|
|
|
|
|
|
|
|
for (TQPtrListIterator<TQAction> it(m_formWindow->actionList()); it.current(); ++it)
|
|
|
|
if (TQString(it.current()->name()) == s)
|
|
|
|
return TQT_TQOBJECT(it.current());
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectionEditor::connectClicked()
|
|
|
|
{
|
|
|
|
if (signalBox->currentItem() == -1 || slotBox->currentItem() == -1)
|
|
|
|
return;
|
|
|
|
if (hasConnection(m_sender->name(), signalBox->currentText(), m_receiver->name(),
|
|
|
|
slotBox->currentText()))
|
|
|
|
return;
|
|
|
|
MetaDataBase::Connection conn;
|
|
|
|
conn.sender = m_sender;
|
|
|
|
conn.signal = signalBox->currentText();
|
|
|
|
conn.slot = slotBox->currentText();
|
|
|
|
conn.receiver = m_receiver;
|
|
|
|
KListViewItem *i = new KListViewItem(connectionView, m_sender->name(), conn.signal, m_receiver->name(),
|
|
|
|
conn.slot);
|
|
|
|
i->setPixmap(0, PixmapChooser::loadPixmap("connecttool.xpm"));
|
|
|
|
connectionView->setCurrentItem(i);
|
|
|
|
connectionView->setSelected(i, true);
|
|
|
|
m_connections.insert(i, conn);
|
|
|
|
connectButton->setEnabled(false);
|
|
|
|
updateDisconnectButton();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionEditor::disconnectClicked()
|
|
|
|
{
|
|
|
|
TQListViewItem *p_item = connectionView->currentItem();
|
|
|
|
if (!p_item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQMap <TQListViewItem*, MetaDataBase::Connection>::Iterator it = m_connections.find(p_item);
|
|
|
|
if (it != m_connections.end())
|
|
|
|
m_connections.remove(it);
|
|
|
|
delete p_item;
|
|
|
|
if (connectionView->currentItem())
|
|
|
|
connectionView->setSelected(connectionView->currentItem(), true);
|
|
|
|
updateConnectButton();
|
|
|
|
updateDisconnectButton();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionEditor::okClicked()
|
|
|
|
{
|
|
|
|
MacroCommand* rmConn = 0, *addConn = 0;
|
|
|
|
TQString n = i18n("Connect/Disconnect the signals and slots of '%1' and '%2'").tqarg(m_sender->name()).
|
|
|
|
arg(m_receiver->name());
|
|
|
|
TQValueList <MetaDataBase::Connection>::Iterator cit;
|
|
|
|
if (!m_oldConnections.isEmpty())
|
|
|
|
{
|
|
|
|
TQPtrList <Command> commands;
|
|
|
|
for (cit = m_oldConnections.begin(); cit != m_oldConnections.end(); ++cit)
|
|
|
|
commands.append(new RemoveConnectionCommand(i18n("Remove Connection"), m_formWindow, *cit));
|
|
|
|
rmConn = new MacroCommand(i18n("Remove Connections"), m_formWindow, commands);
|
|
|
|
}
|
|
|
|
if (!m_connections.isEmpty())
|
|
|
|
{
|
|
|
|
TQMap<TQListViewItem*, MetaDataBase::Connection>::Iterator it = m_connections.begin();
|
|
|
|
TQPtrList<Command> commands;
|
|
|
|
for (; it != m_connections.end(); ++it)
|
|
|
|
{
|
|
|
|
MetaDataBase::Connection conn = *it;
|
|
|
|
commands.append(new AddConnectionCommand(i18n("Add Connection"), m_formWindow, conn));
|
|
|
|
}
|
|
|
|
addConn = new MacroCommand(i18n("Add Connections"), m_formWindow, commands);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rmConn || addConn)
|
|
|
|
{
|
|
|
|
TQPtrList < Command > commands;
|
|
|
|
if (rmConn)
|
|
|
|
commands.append(rmConn);
|
|
|
|
if (addConn)
|
|
|
|
commands.append(addConn);
|
|
|
|
MacroCommand *cmd = new MacroCommand(n, m_formWindow, commands);
|
|
|
|
m_formWindow->commandHistory()->addCommand(cmd);
|
|
|
|
cmd->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
accept();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionEditor::cancelClicked()
|
|
|
|
{
|
|
|
|
reject();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionEditor::senderChanged(const TQString& s)
|
|
|
|
{
|
|
|
|
TQObject* p_object = objectByName(s);
|
|
|
|
if (!p_object)
|
|
|
|
return;
|
|
|
|
m_sender = p_object;
|
|
|
|
TQStrList p_sigs = m_sender->metaObject()->signalNames(true);
|
|
|
|
signalBox->clear();
|
|
|
|
for (TQStrListIterator it(p_sigs); it.current(); ++it)
|
|
|
|
if (!isSignalIgnored(it.current()) && !signalBox->findItem(it.current(), TQt::ExactMatch))
|
|
|
|
signalBox->insertItem(it.current());
|
|
|
|
if (TQT_BASE_OBJECT(m_sender) == TQT_BASE_OBJECT(m_formWindow->mainContainer()))
|
|
|
|
signalBox->insertStringList(MetaDataBase::signalList(TQT_TQOBJECT(m_formWindow)));
|
|
|
|
signalBox->sort();
|
|
|
|
signalBox->setCurrentItem(signalBox->firstItem());
|
|
|
|
// Update slots - some may (not) have their signal equivalents now.
|
|
|
|
receiverChanged(m_receiver->name());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionEditor::receiverChanged(const TQString& s)
|
|
|
|
{
|
|
|
|
TQObject* p_object = objectByName(s);
|
|
|
|
if (!p_object)
|
|
|
|
return;
|
|
|
|
m_receiver = p_object;
|
|
|
|
int n = m_receiver->metaObject()->numSlots(true);
|
|
|
|
slotBox->clear();
|
|
|
|
for (int i = 0; i < n; ++i)
|
|
|
|
{
|
|
|
|
const TQMetaData* md = m_receiver->metaObject()->slot(i, true);
|
|
|
|
if (!isSlotIgnored(md) && !slotBox->findItem(md->tqt_mo_ci_name, TQt::ExactMatch))
|
|
|
|
slotBox->insertItem(md->tqt_mo_ci_name);
|
|
|
|
}
|
|
|
|
slotBox->sort();
|
|
|
|
slotBox->setCurrentItem(slotBox->firstItem());
|
|
|
|
updateConnectButton();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionEditor::updateConnectButton()
|
|
|
|
{
|
|
|
|
bool itemsSelected = signalBox->currentItem() != -1 && slotBox->currentItem() != -1;
|
|
|
|
bool notConnected = !itemsSelected || !hasConnection(m_sender->name(), signalBox->currentText(),
|
|
|
|
m_receiver->name(), slotBox->currentText());
|
|
|
|
bool connectionAllowed = notConnected && checkConnectArgs(MetaDataBase::normalizeSlot(signalBox->currentText()).latin1(),
|
|
|
|
m_receiver, MetaDataBase::normalizeSlot(slotBox->currentText()).latin1());
|
|
|
|
connectButton->setEnabled(itemsSelected && notConnected && connectionAllowed);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionEditor::updateDisconnectButton()
|
|
|
|
{
|
|
|
|
disconnectButton->setEnabled((connectionView->currentItem()));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ConnectionEditor::hasConnection(const TQString& snder, const TQString& signal,
|
|
|
|
const TQString& rcvr, const TQString& slot) const
|
|
|
|
{
|
|
|
|
for (TQListViewItemIterator it(connectionView); it.current(); ++it)
|
|
|
|
if (it.current()->text(0) == snder &&
|
|
|
|
it.current()->text(1) == signal &&
|
|
|
|
it.current()->text(2) == rcvr && it.current()->text(3) == slot)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionEditor::fillConnectionsList()
|
|
|
|
{
|
|
|
|
connectionView->clear();
|
|
|
|
m_connections.clear();
|
|
|
|
m_oldConnections = MetaDataBase::connections(TQT_TQOBJECT(m_formWindow));
|
|
|
|
if (!m_oldConnections.isEmpty())
|
|
|
|
{
|
|
|
|
TQValueList <MetaDataBase::Connection>::Iterator it = m_oldConnections.begin();
|
|
|
|
for (; it != m_oldConnections.end(); ++it)
|
|
|
|
{
|
|
|
|
if (m_formWindow->isMainContainer(TQT_TQOBJECT((*it).receiver)) &&
|
|
|
|
!MetaDataBase::hasSlot(TQT_TQOBJECT(m_formWindow), MetaDataBase::normalizeSlot((*it).slot).latin1()))
|
|
|
|
continue;
|
|
|
|
MetaDataBase::Connection conn = *it;
|
|
|
|
KListViewItem *i = new KListViewItem(connectionView, conn.sender->name(), conn.signal,
|
|
|
|
conn.receiver->name(), conn.slot);
|
|
|
|
i->setPixmap(0, PixmapChooser::loadPixmap("connecttool.xpm"));
|
|
|
|
m_connections.insert(i, conn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
connectionView->setCurrentItem(connectionView->firstChild());
|
|
|
|
if (connectionView->currentItem())
|
|
|
|
connectionView->setSelected(connectionView->currentItem(), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionEditor::fillWidgetList(KComboBox* a_combo, const TQStringList& items, const TQString& defaultWidget)
|
|
|
|
{
|
|
|
|
a_combo->insertStringList(items);
|
|
|
|
for (int i = 0; i < a_combo->count(); ++i)
|
|
|
|
if (a_combo->text(i) == defaultWidget)
|
|
|
|
{
|
|
|
|
a_combo->setCurrentItem(i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (a_combo->count())
|
|
|
|
a_combo->setCurrentItem(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "connectioneditorimpl.moc"
|