kexi

kexirelationwidget.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002   Lucijan Busch <lucijan@gmx.at>
00003    Copyright (C) 2003   Joseph Wenninger<jowenn@kde.org>
00004    Copyright (C) 2003-2004 Jaroslaw Staniek <js@iidea.pl>
00005 
00006    This program is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this program; see the file COPYING.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "kexirelationwidget.h"
00023 
00024 #include <qlayout.h>
00025 #include <qlistbox.h>
00026 #include <qpushbutton.h>
00027 #include <qtimer.h>
00028 
00029 #include <kcombobox.h>
00030 #include <klocale.h>
00031 #include <kdebug.h>
00032 #include <kiconloader.h>
00033 #include <kpushbutton.h>
00034 
00035 #include <kexidb/connection.h>
00036 #include <kexidb/utils.h>
00037 
00038 #include <kexiproject.h>
00039 #include <keximainwindow.h>
00040 #include "kexirelationview.h"
00041 #include "kexirelationviewtable.h"
00042 #include "kexirelationviewconnection.h"
00043 
00044 KexiRelationWidget::KexiRelationWidget(KexiMainWindow *win, QWidget *parent, 
00045     const char *name)
00046     : KexiViewBase(win, parent, name)
00047     , m_win(win)
00048 {
00049     m_conn = m_win->project()->dbConnection();
00050 
00051     QHBoxLayout *hlyr = new QHBoxLayout(0);
00052     QGridLayout *g = new QGridLayout(this);
00053     g->addLayout( hlyr, 0, 0 );
00054 
00055     m_tableCombo = new KComboBox(this, "tables_combo");
00056     m_tableCombo->setMinimumWidth(QFontMetrics(font()).width("w")*20);
00057     QLabel *lbl = new QLabel(m_tableCombo, i18n("Table")+": ", this);
00058     lbl->setIndent(3);
00059     m_tableCombo->setInsertionPolicy(QComboBox::NoInsertion);
00060     hlyr->addWidget(lbl);
00061     hlyr->addWidget(m_tableCombo);
00062     m_tableCombo->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred));
00063     fillTablesCombo();
00064 
00065     m_btnAdd = new KPushButton(i18n("&Add"), this);
00066     hlyr->addWidget(m_btnAdd);
00067     hlyr->addStretch(1);
00068     connect(m_btnAdd, SIGNAL(clicked()), this, SLOT(slotAddTable()));
00069 
00070     m_relationView = new KexiRelationView(this, "relation_view");
00071     setViewWidget(m_relationView);
00072     g->addWidget(m_relationView, 1, 0);
00073     //m_relationView->setFocus();
00074 
00075     //actions
00076     m_tableQueryPopup = new KPopupMenu(this, "m_popup");
00077     m_tableQueryPopupTitleID = m_tableQueryPopup->insertTitle(SmallIcon("table"), "");
00078     connect(m_tableQueryPopup, SIGNAL(aboutToShow()), this, SLOT(aboutToShowPopupMenu()));
00079 
00080     m_connectionPopup = new KPopupMenu(this, "m_connectionPopup");
00081     m_connectionPopupTitleID = m_connectionPopup->insertTitle("");
00082     connect(m_connectionPopup, SIGNAL(aboutToShow()), this, SLOT(aboutToShowPopupMenu()));
00083 
00084     m_areaPopup = new KPopupMenu(this, "m_areaPopup");
00085     
00086     m_openSelectedTableAction = new KAction(i18n("&Open Table"), SmallIcon("fileopen"), KShortcut(),
00087         this, SLOT(openSelectedTable()), this, "relationsview_openTable");
00088     m_openSelectedTableAction->plug( m_tableQueryPopup );
00089     m_designSelectedTableAction = new KAction(i18n("&Design Table"), SmallIcon("edit"), KShortcut(),
00090         this, SLOT(designSelectedTable()), this, "relationsview_designTable");
00091     m_designSelectedTableAction->plug( m_tableQueryPopup );
00092     m_tableQueryPopup->insertSeparator();
00093 
00094     KAction* hide_action = plugSharedAction("edit_delete", i18n("&Hide Table"), m_tableQueryPopup);
00095     hide_action->setIconSet(QIconSet());
00096 
00097     plugSharedAction("edit_delete",m_connectionPopup);
00098     plugSharedAction("edit_delete",this, SLOT(removeSelectedObject()));
00099 
00100     connect(m_relationView, SIGNAL(tableViewGotFocus()),
00101         this, SLOT(tableViewGotFocus()));
00102     connect(m_relationView, SIGNAL(connectionViewGotFocus()),
00103         this, SLOT(connectionViewGotFocus()));
00104     connect(m_relationView, SIGNAL(emptyAreaGotFocus()),
00105         this, SLOT(emptyAreaGotFocus()));
00106     connect(m_relationView, SIGNAL(tableContextMenuRequest( const QPoint& )),
00107         this, SLOT(tableContextMenuRequest( const QPoint& )));
00108     connect(m_relationView, SIGNAL(connectionContextMenuRequest( const QPoint& )),
00109         this, SLOT(connectionContextMenuRequest( const QPoint& )));
00110     connect(m_relationView, SIGNAL(tableHidden(KexiDB::TableSchema&)),
00111         this, SLOT(slotTableHidden(KexiDB::TableSchema&)));
00112     connect(m_relationView, SIGNAL(tablePositionChanged(KexiRelationViewTableContainer*)),
00113         this, SIGNAL(tablePositionChanged(KexiRelationViewTableContainer*)));
00114     connect(m_relationView, SIGNAL(aboutConnectionRemove(KexiRelationViewConnection*)),
00115         this, SIGNAL(aboutConnectionRemove(KexiRelationViewConnection*)));
00116 
00117 #if 0
00118     if(!embedd)
00119     {
00120 /*todo      setContextHelp(i18n("Relations"), i18n("To create a relationship simply drag the source field onto the target field. "
00121             "An arrowhead is used to show which table is the parent (master) and which table is the child (slave) in the relationship."));*/
00122     }
00123 #endif
00124 //  else
00125 //js: while embedding means read-only?      m_relationView->setReadOnly(true);
00126 
00127 #ifdef TESTING_KexiRelationWidget
00128     for (int i=0;i<(int)m_db->tableNames().count();i++)
00129         QTimer::singleShot(100,this,SLOT(slotAddTable()));
00130 #endif
00131 
00132     invalidateActions();
00133 }
00134 
00135 KexiRelationWidget::~KexiRelationWidget()
00136 {
00137 }
00138 
00139 TablesDict* KexiRelationWidget::tables() const
00140 {
00141     return m_relationView->tables();
00142 }
00143 
00144 KexiRelationViewTableContainer* KexiRelationWidget::table(const QString& name) const
00145 {
00146     return m_relationView->tables()->find( name );
00147 }
00148 
00149 const ConnectionList* KexiRelationWidget::connections() const
00150 { 
00151     return m_relationView->connections();
00152 }
00153 
00154 void
00155 KexiRelationWidget::slotAddTable()
00156 {
00157     if (m_tableCombo->currentItem()==-1)
00158         return;
00159     QString tname = m_tableCombo->text(m_tableCombo->currentItem());
00160     KexiDB::TableSchema *t = m_conn->tableSchema(tname);
00161     addTable(t);
00162 }
00163 
00164 void
00165 KexiRelationWidget::addTable(KexiDB::TableSchema *t, const QRect &rect)
00166 {
00167     if (!t)
00168         return;
00169     KexiRelationViewTableContainer *c = m_relationView->addTable(t, rect);
00170     if (!c)
00171         return;
00172     connect(c->tableView(), SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)),
00173         this, SLOT(slotTableFieldDoubleClicked(QListViewItem*,const QPoint&,int)));
00174     kdDebug() << "KexiRelationWidget::slotAddTable(): adding table " << t->name() << endl;
00175 
00176     const QString tname = t->name().lower();
00177     const int count = m_tableCombo->count();
00178     int i = 0;
00179     for (; i < count; i++ ) {
00180         if (m_tableCombo->text(i).lower() == tname )
00181             break;
00182     }
00183     if (i<count) {
00184         int oi = m_tableCombo->currentItem();
00185         kdDebug()<<"KexiRelationWidget::slotAddTable(): removing a table from the combo box"<<endl;
00186         m_tableCombo->removeItem(i);
00187         if (m_tableCombo->count()>0) {
00188             if (oi>=m_tableCombo->count()) {
00189                 oi=m_tableCombo->count()-1;
00190             }
00191             m_tableCombo->setCurrentItem(oi);
00192         }
00193         else {
00194             m_tableCombo->setEnabled(false);
00195             m_btnAdd->setEnabled(false);
00196         }
00197     }
00198     emit tableAdded(*t);
00199 }
00200 
00201 void
00202 KexiRelationWidget::addConnection(const SourceConnection& conn)
00203 {
00204     m_relationView->addConnection(conn);
00205 }
00206 
00207 void
00208 KexiRelationWidget::addTable(QString t)
00209 {
00210     for(int i=0; i < m_tableCombo->count(); i++)
00211     {
00212         if(m_tableCombo->text(i) == t)
00213         {
00214             m_tableCombo->setCurrentItem(i);
00215             slotAddTable();
00216         }
00217     }
00218 }
00219 
00220 void KexiRelationWidget::tableViewGotFocus()
00221 {
00222 //  if (m_relationView->focusedTableView == sender())
00223 //      return;
00224 //  kdDebug() << "GOT FOCUS!" <<endl;
00225 //  clearSelection();
00226 //  if (m_focusedTableView)
00227 //      m_focusedTableView->unsetFocus();
00228 //  m_focusedTableView = (KexiRelationViewTableContainer*)sender();
00229     invalidateActions();
00230 }
00231 
00232 void KexiRelationWidget::connectionViewGotFocus()
00233 {
00234     invalidateActions();
00235 }
00236 
00237 void KexiRelationWidget::emptyAreaGotFocus()
00238 {
00239     invalidateActions();
00240 }
00241 
00242 void KexiRelationWidget::tableContextMenuRequest(const QPoint& pos)
00243 {
00244 //  if (m_focusedTableView != sender())
00245 //      return;
00246     kdDebug() << "HEADER CTXT MENU!" <<endl;
00247     invalidateActions();
00248     executePopup( pos );
00249 //  m_tableQueryPopup->exec(pos);
00250 }
00251 
00252 void KexiRelationWidget::connectionContextMenuRequest(const QPoint& pos)
00253 {
00254     invalidateActions();
00255     executePopup( pos );
00256 //  m_connectionPopup->exec(pos);
00257 }
00258 
00259 void KexiRelationWidget::emptyAreaContextMenuRequest( const QPoint& /*pos*/ )
00260 {
00261     invalidateActions();
00262     //TODO
00263 }
00264 
00265 void KexiRelationWidget::invalidateActions()
00266 {
00267     setAvailable("edit_delete", m_relationView->selectedConnection() || m_relationView->focusedTableView());
00268 }
00269 
00270 void KexiRelationWidget::executePopup( QPoint pos )
00271 {
00272     if (pos==QPoint(-1,-1)) {
00273         pos = mapToGlobal( 
00274             m_relationView->focusedTableView() ? m_relationView->focusedTableView()->pos() + m_relationView->focusedTableView()->rect().center() : rect().center() );
00275     }
00276     if (m_relationView->focusedTableView())
00277         m_tableQueryPopup->exec(pos);
00278     else if (m_relationView->selectedConnection())
00279         m_connectionPopup->exec(pos);
00280 }
00281 
00282 void KexiRelationWidget::removeSelectedObject()
00283 {
00284     m_relationView->removeSelectedObject();
00285 }
00286 
00287 void KexiRelationWidget::openSelectedTable()
00288 {
00290     if (!m_relationView->focusedTableView() || !m_relationView->focusedTableView()->schema()->table())
00291         return;
00292     bool openingCancelled;
00293     m_win->openObject("kexi/table", m_relationView->focusedTableView()->schema()->name(), 
00294         Kexi::DataViewMode, openingCancelled);
00295 }
00296 
00297 void KexiRelationWidget::designSelectedTable()
00298 {
00300     if (!m_relationView->focusedTableView() || !m_relationView->focusedTableView()->schema()->table())
00301         return;
00302     bool openingCancelled;
00303     m_win->openObject("kexi/table", m_relationView->focusedTableView()->schema()->name(), 
00304         Kexi::DesignViewMode, openingCancelled);
00305 }
00306 
00307 QSize KexiRelationWidget::sizeHint() const
00308 {
00309     return m_relationView->sizeHint();
00310 }
00311 
00312 void KexiRelationWidget::slotTableHidden(KexiDB::TableSchema &table)
00313 {
00314     const QString &t = table.name().lower();
00315     int i;
00316     for (i=0; i<m_tableCombo->count() && t > m_tableCombo->text(i).lower(); i++)
00317         ;
00318     m_tableCombo->insertItem(table.name(), i);
00319     if (!m_tableCombo->isEnabled()) {
00320         m_tableCombo->setCurrentItem(0);
00321         m_tableCombo->setEnabled(true);
00322         m_btnAdd->setEnabled(true);
00323     }
00324 
00325     emit tableHidden(table);
00326 }
00327 
00328 void KexiRelationWidget::aboutToShowPopupMenu()
00329 {
00331     if (m_relationView->focusedTableView() && m_relationView->focusedTableView()->schema()->table()) {
00332         m_tableQueryPopup->changeTitle(m_tableQueryPopupTitleID, SmallIcon("table"),
00333             QString(m_relationView->focusedTableView()->schema()->name()) + " : " + i18n("Table"));
00334     }
00335     else if (m_relationView->selectedConnection()) {
00336         m_connectionPopup->changeTitle( m_connectionPopupTitleID, 
00337              m_relationView->selectedConnection()->toString() + " : " + i18n("Relationship") );
00338     }
00339 }
00340 
00341 void
00342 KexiRelationWidget::slotTableFieldDoubleClicked(QListViewItem *i,const QPoint&,int)
00343 {
00344     if (!sender()->isA("KexiRelationViewTable"))
00345         return;
00346     emit tableFieldDoubleClicked( 
00347         static_cast<const KexiRelationViewTable*>(sender())->schema()->table(), i->text(0) );
00348 }
00349 
00350 void 
00351 KexiRelationWidget::clear()
00352 {
00353     m_relationView->clear();
00354     fillTablesCombo();
00355 }
00356 
00358 void KexiRelationWidget::removeAllConnections()
00359 {
00360     m_relationView->removeAllConnections();
00361 }
00362 
00363 void 
00364 KexiRelationWidget::fillTablesCombo()
00365 {
00366     m_tableCombo->clear();
00367     QStringList tmp = m_conn->tableNames();
00368     tmp.sort();
00369     m_tableCombo->insertStringList(tmp);
00370 }
00371 
00372 void
00373 KexiRelationWidget::objectCreated(const QCString &mime, const QCString& name)
00374 {
00375     if (mime=="kexi/table" || mime=="kexi/query") {
00377         m_tableCombo->insertItem(QString(name));
00378         m_tableCombo->listBox()->sort();
00379     }
00380 }
00381 
00382 void
00383 KexiRelationWidget::objectDeleted(const QCString &mime, const QCString& name)
00384 {
00385     if (mime=="kexi/table" || mime=="kexi/query") {
00386         QString strName(name);
00387         for (int i=0; i<m_tableCombo->count(); i++) {
00389             if (m_tableCombo->text(i)==strName) {
00390                 m_tableCombo->removeItem(i);
00391                 if (m_tableCombo->currentItem()==i) {
00392                     if (i==(m_tableCombo->count()-1))
00393                         m_tableCombo->setCurrentItem(i-1);
00394                     else
00395                         m_tableCombo->setCurrentItem(i);
00396                 }
00397                 break;
00398             }
00399         }
00400     }
00401 }
00402 
00403 void
00404 KexiRelationWidget::objectRenamed(const QCString &mime, const QCString& name, const QCString& newName)
00405 {
00406     if (mime=="kexi/table" || mime=="kexi/query") {
00407         QString strName(name);
00408         for (int i=0; i<m_tableCombo->count(); i++) {
00410             if (m_tableCombo->text(i)==strName) {
00411                 m_tableCombo->changeItem(QString(newName), i);
00412                 m_tableCombo->listBox()->sort();
00413                 break;
00414             }
00415         }
00416     }
00417 }
00418 
00419 void
00420 KexiRelationWidget::hideAllTablesExcept( KexiDB::TableSchema::List* tables )
00421 {
00422     m_relationView->hideAllTablesExcept(tables);
00423 }
00424 
00425 #include "kexirelationwidget.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys