00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdlib.h>
00022
00023 #include <qheader.h>
00024 #include <qlayout.h>
00025 #include <qlabel.h>
00026 #include <qpushbutton.h>
00027 #include <qcursor.h>
00028 #include <qpoint.h>
00029 #include <qapplication.h>
00030 #include <qbitmap.h>
00031 #include <qstyle.h>
00032
00033 #include <kdebug.h>
00034 #include <kiconloader.h>
00035 #include <kdeversion.h>
00036 #include <kconfig.h>
00037 #include <kglobalsettings.h>
00038
00039 #include <kexidb/tableschema.h>
00040 #include <kexidb/utils.h>
00041 #include <kexidragobjects.h>
00042 #include "kexirelationviewtable.h"
00043 #include "kexirelationview.h"
00044
00045 KexiRelationViewTableContainer::KexiRelationViewTableContainer(
00046 KexiRelationView *parent, KexiDB::TableOrQuerySchema *schema)
00047 : QFrame(parent,"KexiRelationViewTableContainer" )
00048
00049 , m_parent(parent)
00050
00051 {
00052
00053
00054
00055
00056
00057 setFrameStyle( QFrame::WinPanel | QFrame::Raised );
00058
00059 QVBoxLayout *lyr = new QVBoxLayout(this,4,1);
00060
00061 m_tableHeader = new KexiRelationViewTableContainerHeader(schema->name(), this);
00062
00063 m_tableHeader->unsetFocus();
00064 m_tableHeader->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
00065 lyr->addWidget(m_tableHeader);
00066 connect(m_tableHeader,SIGNAL(moved()),this,SLOT(moved()));
00067 connect(m_tableHeader, SIGNAL(endDrag()), this, SIGNAL(endDrag()));
00068
00069 m_tableView = new KexiRelationViewTable(schema, parent, this, "KexiRelationViewTable");
00070
00071 m_tableView->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum));
00072
00073 m_tableView->setMaximumSize( m_tableView->sizeHint() );
00074
00075
00076 lyr->addWidget(m_tableView, 0);
00077 connect(m_tableView, SIGNAL(tableScrolling()), this, SLOT(moved()));
00078 connect(m_tableView, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)),
00079 this, SLOT(slotContextMenu(KListView*, QListViewItem*, const QPoint&)));
00080 }
00081
00082 KexiRelationViewTableContainer::~KexiRelationViewTableContainer()
00083 {
00084 }
00085
00086 KexiDB::TableOrQuerySchema* KexiRelationViewTableContainer::schema() const
00087 {
00088 return m_tableView->schema();
00089 }
00090
00091 void KexiRelationViewTableContainer::slotContextMenu(KListView *, QListViewItem *, const QPoint &p)
00092 {
00093
00094 emit contextMenuRequest( p );
00095 }
00096
00097 void KexiRelationViewTableContainer::moved() {
00098
00099 emit moved(this);
00100 }
00101
00102 int KexiRelationViewTableContainer::globalY(const QString &field)
00103 {
00104
00105
00106
00107 QPoint o(0, (m_tableView->globalY(field)) + m_parent->contentsY());
00108
00109 return m_parent->viewport()->mapFromGlobal(o).y();
00110 }
00111
00112 #if 0//js
00113 QSize KexiRelationViewTableContainer::sizeHint()
00114 {
00115 #ifdef Q_WS_WIN
00116 QSize s = m_tableView->sizeHint()
00117 + QSize( 2 * 5 , m_tableHeader->height() + 2 * 5 );
00118 #else
00119 QSize s = m_tableView->sizeHint();
00120 s.setWidth(s.width() + 4);
00121 s.setHeight(m_tableHeader->height() + s.height());
00122 #endif
00123 return s;
00124 }
00125 #endif
00126
00127 void KexiRelationViewTableContainer::setFocus()
00128 {
00129 kdDebug() << "SET FOCUS" << endl;
00130
00131 if (m_tableView->firstChild()) {
00132 if (!m_tableView->selectedItems().first())
00133 m_tableView->setSelected( m_tableView->firstChild(), true );
00134 }
00135 m_tableHeader->setFocus();
00136 m_tableView->setFocus();
00137
00138
00139
00140
00141
00142 raise();
00143 repaint();
00144 emit gotFocus();
00145 }
00146
00147 void KexiRelationViewTableContainer::unsetFocus()
00148 {
00149 kdDebug() << "UNSET FOCUS" << endl;
00150
00151
00152
00153 m_tableHeader->unsetFocus();
00154
00155 m_tableView->clearSelection();
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 clearFocus();
00169 repaint();
00170 }
00171
00172
00173
00174
00175
00176
00177
00178 KexiRelationViewTableContainerHeader::KexiRelationViewTableContainerHeader(
00179 const QString& text,QWidget *parent)
00180 :QLabel(text,parent),m_dragging(false)
00181 {
00182 setMargin(1);
00183 m_activeBG = KGlobalSettings::activeTitleColor();
00184 m_activeFG = KGlobalSettings::activeTextColor();
00185 m_inactiveBG = KGlobalSettings::inactiveTitleColor();
00186 m_inactiveFG = KGlobalSettings::inactiveTextColor();
00187
00188 installEventFilter(this);
00189 }
00190
00191 KexiRelationViewTableContainerHeader::~KexiRelationViewTableContainerHeader()
00192 {
00193 }
00194
00195 void KexiRelationViewTableContainerHeader::setFocus()
00196 {
00197 setPaletteBackgroundColor(m_activeBG);
00198 setPaletteForegroundColor(m_activeFG);
00199 }
00200
00201 void KexiRelationViewTableContainerHeader::unsetFocus()
00202 {
00203 setPaletteBackgroundColor(m_inactiveBG);
00204 setPaletteForegroundColor(m_inactiveFG);
00205 }
00206
00207 bool KexiRelationViewTableContainerHeader::eventFilter(QObject *, QEvent *ev)
00208 {
00209 if (ev->type()==QEvent::MouseMove)
00210 {
00211 if (m_dragging && static_cast<QMouseEvent*>(ev)->state()==Qt::LeftButton) {
00212 int diffX,diffY;
00213 diffX=static_cast<QMouseEvent*>(ev)->globalPos().x()-m_grabX;
00214 diffY=static_cast<QMouseEvent*>(ev)->globalPos().y()-m_grabY;
00215 if ((abs(diffX)>2) || (abs(diffY)>2))
00216 {
00217 QPoint newPos=parentWidget()->pos()+QPoint(diffX,diffY);
00218
00219 if (newPos.x()<0) {
00220 m_offsetX+=newPos.x();
00221 newPos.setX(0);
00222 }
00223 else if (m_offsetX<0) {
00224 m_offsetX+=newPos.x();
00225 if (m_offsetX>0) {
00226 newPos.setX(m_offsetX);
00227 m_offsetX=0;
00228 }
00229 else newPos.setX(0);
00230 }
00231
00232 if (newPos.y()<0) {
00233 m_offsetY+=newPos.y();
00234 newPos.setY(0);
00235 }
00236 else
00237 if (m_offsetY<0) {
00238 m_offsetY+=newPos.y();
00239 if (m_offsetY>0) {
00240 newPos.setY(m_offsetY);
00241 m_offsetY=0;
00242 }
00243 else newPos.setY(0);
00244 }
00245
00246
00247 parentWidget()->move(newPos);
00248 m_grabX=static_cast<QMouseEvent*>(ev)->globalPos().x();
00249 m_grabY=static_cast<QMouseEvent*>(ev)->globalPos().y();
00250
00251 emit moved();
00252 }
00253 return true;
00254 }
00255 }
00256 return false;
00257 }
00258
00259 void KexiRelationViewTableContainerHeader::mousePressEvent(QMouseEvent *ev) {
00260 kdDebug()<<"KexiRelationViewTableContainerHeader::Mouse Press Event"<<endl;
00261 parentWidget()->setFocus();
00262 ev->accept();
00263 if (ev->button()==Qt::LeftButton) {
00264 m_dragging=true;
00265 m_grabX=ev->globalPos().x();
00266 m_grabY=ev->globalPos().y();
00267 m_offsetX=0;
00268 m_offsetY=0;
00269 setCursor(Qt::SizeAllCursor);
00270 return;
00271 }
00272 if (ev->button()==Qt::RightButton) {
00273 emit static_cast<KexiRelationViewTableContainer*>(parentWidget())
00274 ->contextMenuRequest(ev->globalPos());
00275 }
00276
00277 }
00278
00279 void KexiRelationViewTableContainerHeader::mouseReleaseEvent(QMouseEvent *ev) {
00280 kdDebug()<<"KexiRelationViewTableContainerHeader::Mouse Release Event"<<endl;
00281 if (m_dragging && ev->button() & Qt::LeftButton) {
00282 setCursor(Qt::ArrowCursor);
00283 m_dragging=false;
00284 emit endDrag();
00285 }
00286 ev->accept();
00287 }
00288
00289
00290
00291
00292
00293
00294 KexiRelationViewTable::KexiRelationViewTable(KexiDB::TableOrQuerySchema* tableOrQuerySchema,
00295 KexiRelationView *view, QWidget *parent, const char *name)
00296 : KexiFieldListView(parent, name, KexiFieldListView::ShowAsterisk)
00297 , m_view(view)
00298 {
00299 setSchema(tableOrQuerySchema);
00300 header()->hide();
00301
00302 connect(this, SIGNAL(dropped(QDropEvent *, QListViewItem *)), this, SLOT(slotDropped(QDropEvent *)));
00303 connect(this, SIGNAL(contentsMoving(int, int)), this, SLOT(slotContentsMoving(int,int)));
00304
00305
00306 }
00307
00308 KexiRelationViewTable::~KexiRelationViewTable()
00309 {
00310 }
00311
00312 QSize KexiRelationViewTable::sizeHint()
00313 {
00314 QFontMetrics fm(font());
00315
00316 kdDebug() << schema()->name() << " cw=" << columnWidth(0) + fm.width("i")
00317 << ", " << fm.width(schema()->name()+" ") << endl;
00318
00320 int maxWidth = columnWidth(0) + fm.width("i");
00321 const KexiDB::QueryColumnInfo::Vector columns(schema()->columns(true));
00322 for (uint i=0; i<columns.count(); i++)
00323 maxWidth = QMAX(maxWidth, fm.width(columns[i]->field->name())+20);
00324
00325 QSize s(
00326 QMAX( maxWidth, fm.width(schema()->name()+" ")+20),
00327 childCount()*firstChild()->totalHeight() + 4 );
00328
00329 return s;
00330 }
00331
00332 #if 0
00333 void KexiRelationViewTable::setReadOnly(bool b)
00334 {
00335 setAcceptDrops(!b);
00336 viewport()->setAcceptDrops(!b);
00337 }
00338 #endif
00339
00340 int
00341 KexiRelationViewTable::globalY(const QString &item)
00342 {
00343 QListViewItem *i = findItem(item, 0);
00344 if(i)
00345 {
00346 int y=itemRect(i).y() + (itemRect(i).height() / 2);
00347 return mapToGlobal(QPoint(0, y)).y();
00348 }
00349 return -1;
00350 }
00351
00352 bool
00353 KexiRelationViewTable::acceptDrag(QDropEvent *ev) const
00354 {
00355
00356 QListViewItem *receiver = itemAt(ev->pos());
00357 if (!receiver || !KexiFieldDrag::canDecodeSingle(ev))
00358 return false;
00359 QString sourceMimeType;
00360 QString srcTable;
00361 QString srcField;
00362 if (!KexiFieldDrag::decodeSingle(ev,sourceMimeType,srcTable,srcField))
00363 return false;
00364 if (sourceMimeType!="kexi/table" && sourceMimeType=="kexi/query")
00365 return false;
00366 QString f = receiver->text(0).stripWhiteSpace();
00367 if (srcField.stripWhiteSpace()!="*" && f!="*" && ev->source() != (QWidget*)this)
00368 return true;
00369
00370 return false;
00371 }
00372
00373 void
00374 KexiRelationViewTable::slotDropped(QDropEvent *ev)
00375 {
00376 QListViewItem *recever = itemAt(ev->pos());
00377 if (!recever || !KexiFieldDrag::canDecodeSingle(ev)) {
00378 ev->ignore();
00379 return;
00380 }
00381 QString sourceMimeType;
00382 QString srcTable;
00383 QString srcField;
00384 if (!KexiFieldDrag::decodeSingle(ev,sourceMimeType,srcTable,srcField))
00385 return;
00386 if (sourceMimeType!="kexi/table" && sourceMimeType=="kexi/query")
00387 return;
00388
00389
00390 QString rcvField = recever->text(0);
00391
00392 SourceConnection s;
00393 s.masterTable = srcTable;
00394 s.detailsTable = schema()->name();
00395 s.masterField = srcField;
00396 s.detailsField = rcvField;
00397
00398 m_view->addConnection(s);
00399
00400 kdDebug() << "KexiRelationViewTable::slotDropped() " << srcTable << ":" << srcField << " "
00401 << schema()->name() << ":" << rcvField << endl;
00402 ev->accept();
00403 }
00404
00405 void
00406 KexiRelationViewTable::slotContentsMoving(int,int)
00407 {
00408 emit tableScrolling();
00409 }
00410
00411 void KexiRelationViewTable::contentsMousePressEvent(QMouseEvent *ev)
00412 {
00413 parentWidget()->setFocus();
00414 setFocus();
00415 KListView::contentsMousePressEvent(ev);
00416
00417
00418 }
00419
00420 QRect KexiRelationViewTable::drawItemHighlighter(QPainter *painter, QListViewItem *item)
00421 {
00422 if (painter) {
00423 style().drawPrimitive(QStyle::PE_FocusRect, painter, itemRect(item), colorGroup(),
00424 QStyle::Style_FocusAtBorder);
00425 }
00426 return itemRect(item);
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436 #if 0
00437 KexiRelationViewTableItem::KexiRelationViewTableItem(
00438 QListView *parent, QListViewItem *after, QString key, QString field)
00439 : KListViewItem(parent, after, key, field)
00440 {
00441 }
00442
00443 void KexiRelationViewTableItem::paintFocus (QPainter * , const QColorGroup &, const QRect &)
00444 {
00445 }
00446 #endif
00447
00448
00449
00450
00451 #include "kexirelationviewtable.moc"