|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2002 Lucijan Busch <lucijan@gmx.at>
|
|
|
|
Copyright (C) 2003 Joseph Wenninger<jowenn@kde.org>
|
|
|
|
Copyright (C) 2003-2004 Jaroslaw Staniek <js@iidea.pl>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this program; see the file COPYING. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "kexirelationwidget.h"
|
|
|
|
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqlistbox.h>
|
|
|
|
#include <tqpushbutton.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
|
|
|
|
#include <kcombobox.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <kpushbutton.h>
|
|
|
|
|
|
|
|
#include <kexidb/connection.h>
|
|
|
|
#include <kexidb/utils.h>
|
|
|
|
|
|
|
|
#include <kexiproject.h>
|
|
|
|
#include <keximainwindow.h>
|
|
|
|
#include "kexirelationview.h"
|
|
|
|
#include "kexirelationviewtable.h"
|
|
|
|
#include "kexirelationviewconnection.h"
|
|
|
|
|
|
|
|
KexiRelationWidget::KexiRelationWidget(KexiMainWindow *win, TQWidget *parent,
|
|
|
|
const char *name)
|
|
|
|
: KexiViewBase(win, parent, name)
|
|
|
|
, m_win(win)
|
|
|
|
{
|
|
|
|
m_conn = m_win->project()->dbConnection();
|
|
|
|
|
|
|
|
TQHBoxLayout *hlyr = new TQHBoxLayout(0);
|
|
|
|
TQGridLayout *g = new TQGridLayout(this);
|
|
|
|
g->addLayout( hlyr, 0, 0 );
|
|
|
|
|
|
|
|
m_tableCombo = new KComboBox(this, "tables_combo");
|
|
|
|
m_tableCombo->setMinimumWidth(TQFontMetrics(font()).width("w")*20);
|
|
|
|
TQLabel *lbl = new TQLabel(m_tableCombo, i18n("Table")+": ", this);
|
|
|
|
lbl->setIndent(3);
|
|
|
|
m_tableCombo->setInsertionPolicy(TQComboBox::NoInsertion);
|
|
|
|
hlyr->addWidget(lbl);
|
|
|
|
hlyr->addWidget(m_tableCombo);
|
|
|
|
m_tableCombo->setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::Preferred));
|
|
|
|
fillTablesCombo();
|
|
|
|
|
|
|
|
m_btnAdd = new KPushButton(i18n("&Add"), this);
|
|
|
|
hlyr->addWidget(m_btnAdd);
|
|
|
|
hlyr->addStretch(1);
|
|
|
|
connect(m_btnAdd, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotAddTable()));
|
|
|
|
|
|
|
|
m_relationView = new KexiRelationView(this, "relation_view");
|
|
|
|
setViewWidget(m_relationView);
|
|
|
|
g->addWidget(m_relationView, 1, 0);
|
|
|
|
//m_relationView->setFocus();
|
|
|
|
|
|
|
|
//actions
|
|
|
|
m_tableQueryPopup = new TDEPopupMenu(this, "m_popup");
|
|
|
|
m_tableQueryPopupTitleID = m_tableQueryPopup->insertTitle(SmallIcon("table"), "");
|
|
|
|
connect(m_tableQueryPopup, TQ_SIGNAL(aboutToShow()), this, TQ_SLOT(aboutToShowPopupMenu()));
|
|
|
|
|
|
|
|
m_connectionPopup = new TDEPopupMenu(this, "m_connectionPopup");
|
|
|
|
m_connectionPopupTitleID = m_connectionPopup->insertTitle("");
|
|
|
|
connect(m_connectionPopup, TQ_SIGNAL(aboutToShow()), this, TQ_SLOT(aboutToShowPopupMenu()));
|
|
|
|
|
|
|
|
m_areaPopup = new TDEPopupMenu(this, "m_areaPopup");
|
|
|
|
|
Bring filenew, fileopen, fileprint, filequickprint, filesave, filesaveas, fileclose, editclear, editcopy, editcut, editdelete, editpaste, folder_new, and gohome icons into XDG compliance
10 years ago
|
|
|
m_openSelectedTableAction = new TDEAction(i18n("&Open Table"), SmallIcon("document-open"), TDEShortcut(),
|
|
|
|
this, TQ_SLOT(openSelectedTable()), this, "relationsview_openTable");
|
|
|
|
m_openSelectedTableAction->plug( m_tableQueryPopup );
|
|
|
|
m_designSelectedTableAction = new TDEAction(i18n("&Design Table"), SmallIcon("edit"), TDEShortcut(),
|
|
|
|
this, TQ_SLOT(designSelectedTable()), this, "relationsview_designTable");
|
|
|
|
m_designSelectedTableAction->plug( m_tableQueryPopup );
|
|
|
|
m_tableQueryPopup->insertSeparator();
|
|
|
|
|
|
|
|
TDEAction* hide_action = plugSharedAction("edit_delete", i18n("&Hide Table"), m_tableQueryPopup);
|
|
|
|
hide_action->setIconSet(TQIconSet());
|
|
|
|
|
|
|
|
plugSharedAction("edit_delete",m_connectionPopup);
|
|
|
|
plugSharedAction("edit_delete",this, TQ_SLOT(removeSelectedObject()));
|
|
|
|
|
|
|
|
connect(m_relationView, TQ_SIGNAL(tableViewGotFocus()),
|
|
|
|
this, TQ_SLOT(tableViewGotFocus()));
|
|
|
|
connect(m_relationView, TQ_SIGNAL(connectionViewGotFocus()),
|
|
|
|
this, TQ_SLOT(connectionViewGotFocus()));
|
|
|
|
connect(m_relationView, TQ_SIGNAL(emptyAreaGotFocus()),
|
|
|
|
this, TQ_SLOT(emptyAreaGotFocus()));
|
|
|
|
connect(m_relationView, TQ_SIGNAL(tableContextMenuRequest( const TQPoint& )),
|
|
|
|
this, TQ_SLOT(tableContextMenuRequest( const TQPoint& )));
|
|
|
|
connect(m_relationView, TQ_SIGNAL(connectionContextMenuRequest( const TQPoint& )),
|
|
|
|
this, TQ_SLOT(connectionContextMenuRequest( const TQPoint& )));
|
|
|
|
connect(m_relationView, TQ_SIGNAL(tableHidden(KexiDB::TableSchema&)),
|
|
|
|
this, TQ_SLOT(slotTableHidden(KexiDB::TableSchema&)));
|
|
|
|
connect(m_relationView, TQ_SIGNAL(tablePositionChanged(KexiRelationViewTableContainer*)),
|
|
|
|
this, TQ_SIGNAL(tablePositionChanged(KexiRelationViewTableContainer*)));
|
|
|
|
connect(m_relationView, TQ_SIGNAL(aboutConnectionRemove(KexiRelationViewConnection*)),
|
|
|
|
this, TQ_SIGNAL(aboutConnectionRemove(KexiRelationViewConnection*)));
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if(!embedd)
|
|
|
|
{
|
|
|
|
/*todo setContextHelp(i18n("Relations"), i18n("To create a relationship simply drag the source field onto the target field. "
|
|
|
|
"An arrowhead is used to show which table is the parent (master) and which table is the child (slave) in the relationship."));*/
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
// else
|
|
|
|
//js: while embedding means read-only? m_relationView->setReadOnly(true);
|
|
|
|
|
|
|
|
#ifdef TESTING_KexiRelationWidget
|
|
|
|
for (int i=0;i<(int)m_db->tableNames().count();i++)
|
|
|
|
TQTimer::singleShot(100,this,TQ_SLOT(slotAddTable()));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
invalidateActions();
|
|
|
|
}
|
|
|
|
|
|
|
|
KexiRelationWidget::~KexiRelationWidget()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
TablesDict* KexiRelationWidget::tables() const
|
|
|
|
{
|
|
|
|
return m_relationView->tables();
|
|
|
|
}
|
|
|
|
|
|
|
|
KexiRelationViewTableContainer* KexiRelationWidget::table(const TQString& name) const
|
|
|
|
{
|
|
|
|
return m_relationView->tables()->find( name );
|
|
|
|
}
|
|
|
|
|
|
|
|
const ConnectionList* KexiRelationWidget::connections() const
|
|
|
|
{
|
|
|
|
return m_relationView->connections();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::slotAddTable()
|
|
|
|
{
|
|
|
|
if (m_tableCombo->currentItem()==-1)
|
|
|
|
return;
|
|
|
|
TQString tname = m_tableCombo->text(m_tableCombo->currentItem());
|
|
|
|
KexiDB::TableSchema *t = m_conn->tableSchema(tname);
|
|
|
|
addTable(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::addTable(KexiDB::TableSchema *t, const TQRect &rect)
|
|
|
|
{
|
|
|
|
if (!t)
|
|
|
|
return;
|
|
|
|
if (!m_relationView->tableContainer(t)) {
|
|
|
|
KexiRelationViewTableContainer *c = m_relationView->addTableContainer(t, rect);
|
|
|
|
kdDebug() << "KexiRelationWidget::slotAddTable(): adding table " << t->name() << endl;
|
|
|
|
if (!c)
|
|
|
|
return;
|
|
|
|
connect(c->tableView(), TQ_SIGNAL(doubleClicked(TQListViewItem*,const TQPoint&,int)),
|
|
|
|
this, TQ_SLOT(slotTableFieldDoubleClicked(TQListViewItem*,const TQPoint&,int)));
|
|
|
|
}
|
|
|
|
|
|
|
|
const TQString tname = t->name().lower();
|
|
|
|
const int count = m_tableCombo->count();
|
|
|
|
int i = 0;
|
|
|
|
for (; i < count; i++ ) {
|
|
|
|
if (m_tableCombo->text(i).lower() == tname )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i<count) {
|
|
|
|
int oi = m_tableCombo->currentItem();
|
|
|
|
kdDebug()<<"KexiRelationWidget::slotAddTable(): removing a table from the combo box"<<endl;
|
|
|
|
m_tableCombo->removeItem(i);
|
|
|
|
if (m_tableCombo->count()>0) {
|
|
|
|
if (oi>=m_tableCombo->count()) {
|
|
|
|
oi=m_tableCombo->count()-1;
|
|
|
|
}
|
|
|
|
m_tableCombo->setCurrentItem(oi);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_tableCombo->setEnabled(false);
|
|
|
|
m_btnAdd->setEnabled(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
emit tableAdded(*t);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::addConnection(const SourceConnection& conn)
|
|
|
|
{
|
|
|
|
m_relationView->addConnection(conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::addTable(const TQString& t)
|
|
|
|
{
|
|
|
|
for(int i=0; i < m_tableCombo->count(); i++)
|
|
|
|
{
|
|
|
|
if(m_tableCombo->text(i) == t)
|
|
|
|
{
|
|
|
|
m_tableCombo->setCurrentItem(i);
|
|
|
|
slotAddTable();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::tableViewGotFocus()
|
|
|
|
{
|
|
|
|
// if (m_relationView->focusedTableView == sender())
|
|
|
|
// return;
|
|
|
|
// kdDebug() << "GOT FOCUS!" <<endl;
|
|
|
|
// clearSelection();
|
|
|
|
// if (m_focusedTableView)
|
|
|
|
// m_focusedTableView->unsetFocus();
|
|
|
|
// m_focusedTableView = (KexiRelationViewTableContainer*)sender();
|
|
|
|
invalidateActions();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::connectionViewGotFocus()
|
|
|
|
{
|
|
|
|
invalidateActions();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::emptyAreaGotFocus()
|
|
|
|
{
|
|
|
|
invalidateActions();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::tableContextMenuRequest(const TQPoint& pos)
|
|
|
|
{
|
|
|
|
invalidateActions();
|
|
|
|
executePopup( pos );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::connectionContextMenuRequest(const TQPoint& pos)
|
|
|
|
{
|
|
|
|
invalidateActions();
|
|
|
|
executePopup( pos );
|
|
|
|
// m_connectionPopup->exec(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::emptyAreaContextMenuRequest( const TQPoint& /*pos*/ )
|
|
|
|
{
|
|
|
|
invalidateActions();
|
|
|
|
//TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::invalidateActions()
|
|
|
|
{
|
|
|
|
setAvailable("edit_delete", m_relationView->selectedConnection() || m_relationView->focusedTableView());
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::executePopup( TQPoint pos )
|
|
|
|
{
|
|
|
|
if (pos==TQPoint(-1,-1)) {
|
|
|
|
pos = mapToGlobal(
|
|
|
|
m_relationView->focusedTableView() ? m_relationView->focusedTableView()->pos() + m_relationView->focusedTableView()->rect().center() : rect().center() );
|
|
|
|
}
|
|
|
|
if (m_relationView->focusedTableView())
|
|
|
|
m_tableQueryPopup->exec(pos);
|
|
|
|
else if (m_relationView->selectedConnection())
|
|
|
|
m_connectionPopup->exec(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::removeSelectedObject()
|
|
|
|
{
|
|
|
|
m_relationView->removeSelectedObject();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::openSelectedTable()
|
|
|
|
{
|
|
|
|
/*! @todo what about query? */
|
|
|
|
if (!m_relationView->focusedTableView() || !m_relationView->focusedTableView()->schema()->table())
|
|
|
|
return;
|
|
|
|
bool openingCancelled;
|
|
|
|
m_win->openObject("kexi/table", m_relationView->focusedTableView()->schema()->name(),
|
|
|
|
Kexi::DataViewMode, openingCancelled);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::designSelectedTable()
|
|
|
|
{
|
|
|
|
/*! @todo what about query? */
|
|
|
|
if (!m_relationView->focusedTableView() || !m_relationView->focusedTableView()->schema()->table())
|
|
|
|
return;
|
|
|
|
bool openingCancelled;
|
|
|
|
m_win->openObject("kexi/table", m_relationView->focusedTableView()->schema()->name(),
|
|
|
|
Kexi::DesignViewMode, openingCancelled);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQSize KexiRelationWidget::sizeHint() const
|
|
|
|
{
|
|
|
|
return m_relationView->sizeHint();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::slotTableHidden(KexiDB::TableSchema &table)
|
|
|
|
{
|
|
|
|
const TQString &t = table.name().lower();
|
|
|
|
int i;
|
|
|
|
for (i=0; i<m_tableCombo->count() && t > m_tableCombo->text(i).lower(); i++)
|
|
|
|
;
|
|
|
|
m_tableCombo->insertItem(table.name(), i);
|
|
|
|
if (!m_tableCombo->isEnabled()) {
|
|
|
|
m_tableCombo->setCurrentItem(0);
|
|
|
|
m_tableCombo->setEnabled(true);
|
|
|
|
m_btnAdd->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
emit tableHidden(table);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationWidget::aboutToShowPopupMenu()
|
|
|
|
{
|
|
|
|
/*! @todo what about query? */
|
|
|
|
if (m_relationView->focusedTableView() && m_relationView->focusedTableView()->schema()->table()) {
|
|
|
|
m_tableQueryPopup->changeTitle(m_tableQueryPopupTitleID, SmallIcon("table"),
|
|
|
|
TQString(m_relationView->focusedTableView()->schema()->name()) + " : " + i18n("Table"));
|
|
|
|
}
|
|
|
|
else if (m_relationView->selectedConnection()) {
|
|
|
|
m_connectionPopup->changeTitle( m_connectionPopupTitleID,
|
|
|
|
m_relationView->selectedConnection()->toString() + " : " + i18n("Relationship") );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::slotTableFieldDoubleClicked(TQListViewItem *i,const TQPoint&,int)
|
|
|
|
{
|
|
|
|
if (!sender()->isA("KexiRelationViewTable"))
|
|
|
|
return;
|
|
|
|
const KexiRelationViewTable* t = static_cast<const KexiRelationViewTable*>(sender());
|
|
|
|
const TQStringList selectedFieldNames( t->selectedFieldNames() );
|
|
|
|
if (selectedFieldNames.count()==1)
|
|
|
|
emit tableFieldDoubleClicked( t->schema()->table(), selectedFieldNames.first() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::clear()
|
|
|
|
{
|
|
|
|
m_relationView->clear();
|
|
|
|
fillTablesCombo();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*! Removes all coonections from the view. */
|
|
|
|
void KexiRelationWidget::removeAllConnections()
|
|
|
|
{
|
|
|
|
m_relationView->removeAllConnections();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::fillTablesCombo()
|
|
|
|
{
|
|
|
|
m_tableCombo->clear();
|
|
|
|
TQStringList tmp = m_conn->tableNames();
|
|
|
|
tmp.sort();
|
|
|
|
m_tableCombo->insertStringList(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::objectCreated(const TQCString &mime, const TQCString& name)
|
|
|
|
{
|
|
|
|
if (mime=="kexi/table" || mime=="kexi/query") {
|
|
|
|
//! @todo query?
|
|
|
|
m_tableCombo->insertItem(TQString(name));
|
|
|
|
m_tableCombo->listBox()->sort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::objectDeleted(const TQCString &mime, const TQCString& name)
|
|
|
|
{
|
|
|
|
if (mime=="kexi/table" || mime=="kexi/query") {
|
|
|
|
TQString strName(name);
|
|
|
|
for (int i=0; i<m_tableCombo->count(); i++) {
|
|
|
|
//! @todo query?
|
|
|
|
if (m_tableCombo->text(i)==strName) {
|
|
|
|
m_tableCombo->removeItem(i);
|
|
|
|
if (m_tableCombo->currentItem()==i) {
|
|
|
|
if (i==(m_tableCombo->count()-1))
|
|
|
|
m_tableCombo->setCurrentItem(i-1);
|
|
|
|
else
|
|
|
|
m_tableCombo->setCurrentItem(i);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::objectRenamed(const TQCString &mime, const TQCString& name, const TQCString& newName)
|
|
|
|
{
|
|
|
|
if (mime=="kexi/table" || mime=="kexi/query") {
|
|
|
|
TQString strName(name);
|
|
|
|
for (int i=0; i<m_tableCombo->count(); i++) {
|
|
|
|
//! @todo query?
|
|
|
|
if (m_tableCombo->text(i)==strName) {
|
|
|
|
m_tableCombo->changeItem(TQString(newName), i);
|
|
|
|
m_tableCombo->listBox()->sort();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationWidget::hideAllTablesExcept( KexiDB::TableSchema::List* tables )
|
|
|
|
{
|
|
|
|
m_relationView->hideAllTablesExcept(tables);
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "kexirelationwidget.moc"
|