diff options
Diffstat (limited to 'kexi/widget/relations/kexirelationwidget.cpp')
-rw-r--r-- | kexi/widget/relations/kexirelationwidget.cpp | 425 |
1 files changed, 425 insertions, 0 deletions
diff --git a/kexi/widget/relations/kexirelationwidget.cpp b/kexi/widget/relations/kexirelationwidget.cpp new file mode 100644 index 00000000..14ec4ce0 --- /dev/null +++ b/kexi/widget/relations/kexirelationwidget.cpp @@ -0,0 +1,425 @@ +/* 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 <qlayout.h> +#include <qlistbox.h> +#include <qpushbutton.h> +#include <qtimer.h> + +#include <kcombobox.h> +#include <klocale.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, QWidget *parent, + const char *name) + : KexiViewBase(win, parent, name) + , m_win(win) +{ + m_conn = m_win->project()->dbConnection(); + + QHBoxLayout *hlyr = new QHBoxLayout(0); + QGridLayout *g = new QGridLayout(this); + g->addLayout( hlyr, 0, 0 ); + + m_tableCombo = new KComboBox(this, "tables_combo"); + m_tableCombo->setMinimumWidth(QFontMetrics(font()).width("w")*20); + QLabel *lbl = new QLabel(m_tableCombo, i18n("Table")+": ", this); + lbl->setIndent(3); + m_tableCombo->setInsertionPolicy(QComboBox::NoInsertion); + hlyr->addWidget(lbl); + hlyr->addWidget(m_tableCombo); + m_tableCombo->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred)); + fillTablesCombo(); + + m_btnAdd = new KPushButton(i18n("&Add"), this); + hlyr->addWidget(m_btnAdd); + hlyr->addStretch(1); + connect(m_btnAdd, SIGNAL(clicked()), this, 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 KPopupMenu(this, "m_popup"); + m_tableQueryPopupTitleID = m_tableQueryPopup->insertTitle(SmallIcon("table"), ""); + connect(m_tableQueryPopup, SIGNAL(aboutToShow()), this, SLOT(aboutToShowPopupMenu())); + + m_connectionPopup = new KPopupMenu(this, "m_connectionPopup"); + m_connectionPopupTitleID = m_connectionPopup->insertTitle(""); + connect(m_connectionPopup, SIGNAL(aboutToShow()), this, SLOT(aboutToShowPopupMenu())); + + m_areaPopup = new KPopupMenu(this, "m_areaPopup"); + + m_openSelectedTableAction = new KAction(i18n("&Open Table"), SmallIcon("fileopen"), KShortcut(), + this, SLOT(openSelectedTable()), this, "relationsview_openTable"); + m_openSelectedTableAction->plug( m_tableQueryPopup ); + m_designSelectedTableAction = new KAction(i18n("&Design Table"), SmallIcon("edit"), KShortcut(), + this, SLOT(designSelectedTable()), this, "relationsview_designTable"); + m_designSelectedTableAction->plug( m_tableQueryPopup ); + m_tableQueryPopup->insertSeparator(); + + KAction* hide_action = plugSharedAction("edit_delete", i18n("&Hide Table"), m_tableQueryPopup); + hide_action->setIconSet(QIconSet()); + + plugSharedAction("edit_delete",m_connectionPopup); + plugSharedAction("edit_delete",this, SLOT(removeSelectedObject())); + + connect(m_relationView, SIGNAL(tableViewGotFocus()), + this, SLOT(tableViewGotFocus())); + connect(m_relationView, SIGNAL(connectionViewGotFocus()), + this, SLOT(connectionViewGotFocus())); + connect(m_relationView, SIGNAL(emptyAreaGotFocus()), + this, SLOT(emptyAreaGotFocus())); + connect(m_relationView, SIGNAL(tableContextMenuRequest( const QPoint& )), + this, SLOT(tableContextMenuRequest( const QPoint& ))); + connect(m_relationView, SIGNAL(connectionContextMenuRequest( const QPoint& )), + this, SLOT(connectionContextMenuRequest( const QPoint& ))); + connect(m_relationView, SIGNAL(tableHidden(KexiDB::TableSchema&)), + this, SLOT(slotTableHidden(KexiDB::TableSchema&))); + connect(m_relationView, SIGNAL(tablePositionChanged(KexiRelationViewTableContainer*)), + this, SIGNAL(tablePositionChanged(KexiRelationViewTableContainer*))); + connect(m_relationView, SIGNAL(aboutConnectionRemove(KexiRelationViewConnection*)), + this, 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++) + QTimer::singleShot(100,this,SLOT(slotAddTable())); +#endif + + invalidateActions(); +} + +KexiRelationWidget::~KexiRelationWidget() +{ +} + +TablesDict* KexiRelationWidget::tables() const +{ + return m_relationView->tables(); +} + +KexiRelationViewTableContainer* KexiRelationWidget::table(const QString& 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; + QString tname = m_tableCombo->text(m_tableCombo->currentItem()); + KexiDB::TableSchema *t = m_conn->tableSchema(tname); + addTable(t); +} + +void +KexiRelationWidget::addTable(KexiDB::TableSchema *t, const QRect &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(), SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)), + this, SLOT(slotTableFieldDoubleClicked(QListViewItem*,const QPoint&,int))); + } + + const QString 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 QString& 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 QPoint& pos) +{ + invalidateActions(); + executePopup( pos ); +} + +void KexiRelationWidget::connectionContextMenuRequest(const QPoint& pos) +{ + invalidateActions(); + executePopup( pos ); +// m_connectionPopup->exec(pos); +} + +void KexiRelationWidget::emptyAreaContextMenuRequest( const QPoint& /*pos*/ ) +{ + invalidateActions(); + //TODO +} + +void KexiRelationWidget::invalidateActions() +{ + setAvailable("edit_delete", m_relationView->selectedConnection() || m_relationView->focusedTableView()); +} + +void KexiRelationWidget::executePopup( QPoint pos ) +{ + if (pos==QPoint(-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); +} + +QSize KexiRelationWidget::sizeHint() const +{ + return m_relationView->sizeHint(); +} + +void KexiRelationWidget::slotTableHidden(KexiDB::TableSchema &table) +{ + const QString &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"), + QString(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(QListViewItem *i,const QPoint&,int) +{ + if (!sender()->isA("KexiRelationViewTable")) + return; + const KexiRelationViewTable* t = static_cast<const KexiRelationViewTable*>(sender()); + const QStringList 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(); + QStringList tmp = m_conn->tableNames(); + tmp.sort(); + m_tableCombo->insertStringList(tmp); +} + +void +KexiRelationWidget::objectCreated(const QCString &mime, const QCString& name) +{ + if (mime=="kexi/table" || mime=="kexi/query") { +//! @todo query? + m_tableCombo->insertItem(QString(name)); + m_tableCombo->listBox()->sort(); + } +} + +void +KexiRelationWidget::objectDeleted(const QCString &mime, const QCString& name) +{ + if (mime=="kexi/table" || mime=="kexi/query") { + QString 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 QCString &mime, const QCString& name, const QCString& newName) +{ + if (mime=="kexi/table" || mime=="kexi/query") { + QString strName(name); + for (int i=0; i<m_tableCombo->count(); i++) { +//! @todo query? + if (m_tableCombo->text(i)==strName) { + m_tableCombo->changeItem(QString(newName), i); + m_tableCombo->listBox()->sort(); + break; + } + } + } +} + +void +KexiRelationWidget::hideAllTablesExcept( KexiDB::TableSchema::List* tables ) +{ + m_relationView->hideAllTablesExcept(tables); +} + +#include "kexirelationwidget.moc" |