You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kexi/widget/relations/kexirelationwidget.cpp

426 lines
13 KiB

/* 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, TQT_SIGNAL(clicked()), this, TQT_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, TQT_SIGNAL(aboutToShow()), this, TQT_SLOT(aboutToShowPopupMenu()));
m_connectionPopup = new TDEPopupMenu(this, "m_connectionPopup");
m_connectionPopupTitleID = m_connectionPopup->insertTitle("");
connect(m_connectionPopup, TQT_SIGNAL(aboutToShow()), this, TQT_SLOT(aboutToShowPopupMenu()));
m_areaPopup = new TDEPopupMenu(this, "m_areaPopup");
m_openSelectedTableAction = new TDEAction(i18n("&Open Table"), SmallIcon("document-open"), TDEShortcut(),
this, TQT_SLOT(openSelectedTable()), this, "relationsview_openTable");
m_openSelectedTableAction->plug( m_tableQueryPopup );
m_designSelectedTableAction = new TDEAction(i18n("&Design Table"), SmallIcon("edit"), TDEShortcut(),
this, TQT_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, TQT_SLOT(removeSelectedObject()));
connect(m_relationView, TQT_SIGNAL(tableViewGotFocus()),
this, TQT_SLOT(tableViewGotFocus()));
connect(m_relationView, TQT_SIGNAL(connectionViewGotFocus()),
this, TQT_SLOT(connectionViewGotFocus()));
connect(m_relationView, TQT_SIGNAL(emptyAreaGotFocus()),
this, TQT_SLOT(emptyAreaGotFocus()));
connect(m_relationView, TQT_SIGNAL(tableContextMenuRequest( const TQPoint& )),
this, TQT_SLOT(tableContextMenuRequest( const TQPoint& )));
connect(m_relationView, TQT_SIGNAL(connectionContextMenuRequest( const TQPoint& )),
this, TQT_SLOT(connectionContextMenuRequest( const TQPoint& )));
connect(m_relationView, TQT_SIGNAL(tableHidden(KexiDB::TableSchema&)),
this, TQT_SLOT(slotTableHidden(KexiDB::TableSchema&)));
connect(m_relationView, TQT_SIGNAL(tablePositionChanged(KexiRelationViewTableContainer*)),
this, TQT_SIGNAL(tablePositionChanged(KexiRelationViewTableContainer*)));
connect(m_relationView, TQT_SIGNAL(aboutConnectionRemove(KexiRelationViewConnection*)),
this, TQT_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,TQT_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(), TQT_SIGNAL(doubleClicked(TQListViewItem*,const TQPoint&,int)),
this, TQT_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"