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/kexirelationviewtable.cpp

430 lines
13 KiB

/* This file is part of the KDE project
Copyright (C) 2002, 2003 Lucijan Busch <lucijan@gmx.at>
Copyright (C) 2003-2007 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 <stdlib.h>
#include <tqheader.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqpushbutton.h>
#include <tqcursor.h>
#include <tqpoint.h>
#include <tqapplication.h>
#include <tqbitmap.h>
#include <tqstyle.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <tdeversion.h>
#include <tdeconfig.h>
#include <tdeglobalsettings.h>
#include <kexidb/tableschema.h>
#include <kexidb/utils.h>
#include <kexidragobjects.h>
#include "kexirelationviewtable.h"
#include "kexirelationview.h"
KexiRelationViewTableContainer::KexiRelationViewTableContainer(
KexiRelationView *parent, KexiDB::TableOrQuerySchema *schema)
: TQFrame(parent,"KexiRelationViewTableContainer" )
// , m_table(t)
, m_parent(parent)
// , m_mousePressed(false)
{
// setFixedSize(100, 150);
//js: resize(100, 150);
//setMouseTracking(true);
setFrameStyle( TQFrame::WinPanel | TQFrame::Raised );
TQVBoxLayout *lyr = new TQVBoxLayout(this,4,1); //js: using Q*BoxLayout is a good idea
m_tableHeader = new KexiRelationViewTableContainerHeader(schema->name(), this);
m_tableHeader->unsetFocus();
m_tableHeader->setSizePolicy(TQSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed));
lyr->addWidget(m_tableHeader);
connect(m_tableHeader,TQ_SIGNAL(moved()),this,TQ_SLOT(moved()));
connect(m_tableHeader, TQ_SIGNAL(endDrag()), this, TQ_SIGNAL(endDrag()));
m_tableView = new KexiRelationViewTable(schema, parent, this, "KexiRelationViewTable");
//m_tableHeader->setFocusProxy( m_tableView );
m_tableView->setSizePolicy(TQSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum));
m_tableView->setMaximumSize( m_tableView->sizeHint() );
// m_tableView->resize( m_tableView->sizeHint() );
lyr->addWidget(m_tableView, 0);
connect(m_tableView, TQ_SIGNAL(tableScrolling()), this, TQ_SLOT(moved()));
connect(m_tableView, TQ_SIGNAL(contextMenu(TDEListView*, TQListViewItem*, const TQPoint&)),
this, TQ_SLOT(slotContextMenu(TDEListView*, TQListViewItem*, const TQPoint&)));
}
KexiRelationViewTableContainer::~KexiRelationViewTableContainer()
{
}
KexiDB::TableOrQuerySchema* KexiRelationViewTableContainer::schema() const
{
return m_tableView->schema();
}
void KexiRelationViewTableContainer::slotContextMenu(TDEListView *, TQListViewItem *, const TQPoint &p)
{
// m_parent->executePopup(p);
emit contextMenuRequest( p );
}
void KexiRelationViewTableContainer::moved() {
// kdDebug()<<"finally emitting moved"<<endl;
emit moved(this);
}
int KexiRelationViewTableContainer::globalY(const TQString &field)
{
// kdDebug() << "KexiRelationViewTableContainer::globalY()" << endl;
// TQPoint o = mapFromGlobal(TQPoint(0, (m_tableView->globalY(field))/*+m_parent->contentsY()*/));
TQPoint o(0, (m_tableView->globalY(field)) + m_parent->contentsY());
// kdDebug() << "KexiRelationViewTableContainer::globalY() db2" << endl;
return m_parent->viewport()->mapFromGlobal(o).y();
}
#if 0//js
TQSize KexiRelationViewTableContainer::sizeHint()
{
#ifdef TQ_WS_WIN
TQSize s = m_tableView->sizeHint()
+ TQSize( 2 * 5 , m_tableHeader->height() + 2 * 5 );
#else
TQSize s = m_tableView->sizeHint();
s.setWidth(s.width() + 4);
s.setHeight(m_tableHeader->height() + s.height());
#endif
return s;
}
#endif
void KexiRelationViewTableContainer::setFocus()
{
kdDebug() << "SET FOCUS" << endl;
//select 1st:
if (m_tableView->firstChild()) {
if (!m_tableView->selectedItems().first())
m_tableView->setSelected( m_tableView->firstChild(), true );
}
m_tableHeader->setFocus();
m_tableView->setFocus();
/* TQPalette p = tqApp->palette();
p.setColor( TQPalette::Active, TQColorGroup::Highlight, TDEGlobalSettings::highlightColor() );
p.setColor( TQPalette::Active, TQColorGroup::HighlightedText, TDEGlobalSettings::highlightedTextColor() );
m_tableView->setPalette(p);*/
raise();
repaint();
emit gotFocus();
}
void KexiRelationViewTableContainer::unsetFocus()
{
kdDebug() << "UNSET FOCUS" << endl;
// if (m_tableView->selectedItem()) //unselect item if was selected
// m_tableView->setSelected(m_tableView->selectedItem(), false);
// m_tableView->clearSelection();
m_tableHeader->unsetFocus();
m_tableView->clearSelection();
// m_tableView->unsetPalette();
/* TQPalette p = m_tableView->palette();
// p.setColor( TQPalette::Active, TQColorGroup::Highlight, TDEGlobalSettings::highlightColor() );
// p.setColor( TQPalette::Active, TQColorGroup::HighlightedText, TDEGlobalSettings::highlightedTextColor() );
p.setColor( TQPalette::Active, TQColorGroup::Highlight, p.color(TQPalette::Active, TQColorGroup::Background ) );
// p.setColor( TQPalette::Active, TQColorGroup::Highlight, gray );
p.setColor( TQPalette::Active, TQColorGroup::HighlightedText, p.color(TQPalette::Active, TQColorGroup::Foreground ) );
// p.setColor( TQPalette::Active, TQColorGroup::Highlight, green );
// p.setColor( TQPalette::Active, TQColorGroup::HighlightedText, blue );
m_tableView->setPalette(p);*/
clearFocus();
repaint();
}
//END KexiRelationViewTableContainer
//============================================================================
//BEGIN KexiRelatoinViewTableContainerHeader
KexiRelationViewTableContainerHeader::KexiRelationViewTableContainerHeader(
const TQString& text,TQWidget *parent)
:TQLabel(text,parent),m_dragging(false)
{
setMargin(1);
m_activeBG = TDEGlobalSettings::activeTitleColor();
m_activeFG = TDEGlobalSettings::activeTextColor();
m_inactiveBG = TDEGlobalSettings::inactiveTitleColor();
m_inactiveFG = TDEGlobalSettings::inactiveTextColor();
installEventFilter(this);
}
KexiRelationViewTableContainerHeader::~KexiRelationViewTableContainerHeader()
{
}
void KexiRelationViewTableContainerHeader::setFocus()
{
setPaletteBackgroundColor(m_activeBG);
setPaletteForegroundColor(m_activeFG);
}
void KexiRelationViewTableContainerHeader::unsetFocus()
{
setPaletteBackgroundColor(m_inactiveBG);
setPaletteForegroundColor(m_inactiveFG);
}
bool KexiRelationViewTableContainerHeader::eventFilter(TQObject *, TQEvent *ev)
{
if (ev->type()==TQEvent::MouseMove)
{
if (m_dragging && static_cast<TQMouseEvent*>(ev)->state()==TQt::LeftButton) {
int diffX,diffY;
diffX=static_cast<TQMouseEvent*>(ev)->globalPos().x()-m_grabX;
diffY=static_cast<TQMouseEvent*>(ev)->globalPos().y()-m_grabY;
if ((abs(diffX)>2) || (abs(diffY)>2))
{
TQPoint newPos=parentWidget()->pos()+TQPoint(diffX,diffY);
//correct the x position
if (newPos.x()<0) {
m_offsetX+=newPos.x();
newPos.setX(0);
}
else if (m_offsetX<0) {
m_offsetX+=newPos.x();
if (m_offsetX>0) {
newPos.setX(m_offsetX);
m_offsetX=0;
}
else newPos.setX(0);
}
//correct the y position
if (newPos.y()<0) {
m_offsetY+=newPos.y();
newPos.setY(0);
}
else
if (m_offsetY<0) {
m_offsetY+=newPos.y();
if (m_offsetY>0) {
newPos.setY(m_offsetY);
m_offsetY=0;
}
else newPos.setY(0);
}
//move and update helpers
parentWidget()->move(newPos);
m_grabX=static_cast<TQMouseEvent*>(ev)->globalPos().x();
m_grabY=static_cast<TQMouseEvent*>(ev)->globalPos().y();
// kdDebug()<<"HEADER:emitting moved"<<endl;
emit moved();
}
return true;
}
}
return false;
}
void KexiRelationViewTableContainerHeader::mousePressEvent(TQMouseEvent *ev) {
kdDebug()<<"KexiRelationViewTableContainerHeader::Mouse Press Event"<<endl;
parentWidget()->setFocus();
ev->accept();
if (ev->button()==TQt::LeftButton) {
m_dragging=true;
m_grabX=ev->globalPos().x();
m_grabY=ev->globalPos().y();
m_offsetX=0;
m_offsetY=0;
setCursor(TQt::SizeAllCursor);
return;
}
if (ev->button()==TQt::RightButton) {
emit static_cast<KexiRelationViewTableContainer*>(parentWidget())
->contextMenuRequest(ev->globalPos());
}
// TQLabel::mousePressEvent(ev);
}
void KexiRelationViewTableContainerHeader::mouseReleaseEvent(TQMouseEvent *ev) {
kdDebug()<<"KexiRelationViewTableContainerHeader::Mouse Release Event"<<endl;
if (m_dragging && ev->button() & TQt::LeftButton) {
setCursor(TQt::ArrowCursor);
m_dragging=false;
emit endDrag();
}
ev->accept();
}
//END KexiRelatoinViewTableContainerHeader
//=====================================================================================
KexiRelationViewTable::KexiRelationViewTable(KexiDB::TableOrQuerySchema* tableOrQuerySchema,
KexiRelationView *view, TQWidget *parent, const char *name)
: KexiFieldListView(parent, name, KexiFieldListView::ShowAsterisk)
, m_view(view)
{
setSchema(tableOrQuerySchema);
header()->hide();
connect(this, TQ_SIGNAL(dropped(TQDropEvent *, TQListViewItem *)), this, TQ_SLOT(slotDropped(TQDropEvent *)));
connect(this, TQ_SIGNAL(contentsMoving(int, int)), this, TQ_SLOT(slotContentsMoving(int,int)));
}
KexiRelationViewTable::~KexiRelationViewTable()
{
}
TQSize KexiRelationViewTable::sizeHint() const
{
TQFontMetrics fm(fontMetrics());
// kdDebug() << schema()->name() << " cw=" << columnWidth(0) + fm.width("i")
// << ", " << fm.width(schema()->name()+" ") << endl;
int maxWidth = -1;
const int iconWidth = IconSize(TDEIcon::Small) + fm.width("i")+20;
for (TQListViewItem *item = firstChild(); item; item = item->nextSibling())
maxWidth = TQMAX(maxWidth, iconWidth + fm.width(item->text(0)));
const uint rowCount = TQMIN( 8, childCount() );
TQSize s(
TQMAX( maxWidth, fm.width(schema()->name()+" ")),
rowCount*firstChild()->totalHeight() + 4 );
return s;
}
#if 0
void KexiRelationViewTable::setReadOnly(bool b)
{
setAcceptDrops(!b);
viewport()->setAcceptDrops(!b);
}
#endif
int
KexiRelationViewTable::globalY(const TQString &item)
{
TQListViewItem *i = findItem(item, 0);
if (!i)
return -1;
int y = itemRect(i).y() + (itemRect(i).height() / 2);
if (contentsY() > itemPos(i))
y = 0;
else if (y == 0)
y = height();
return mapToGlobal(TQPoint(0, y)).y();
}
bool
KexiRelationViewTable::acceptDrag(TQDropEvent *ev) const
{
// kdDebug() << "KexiRelationViewTable::acceptDrag()" << endl;
TQListViewItem *receiver = itemAt(ev->pos() - TQPoint(0,contentsY()));
if (!receiver || !KexiFieldDrag::canDecodeSingle(ev))
return false;
TQString sourceMimeType;
TQString srcTable;
TQString srcField;
if (!KexiFieldDrag::decodeSingle(ev,sourceMimeType,srcTable,srcField))
return false;
if (sourceMimeType!="kexi/table" && sourceMimeType=="kexi/query")
return false;
TQString f = receiver->text(0).stripWhiteSpace();
if (!srcField.stripWhiteSpace().startsWith("*") && !f.startsWith("*") && ev->source() != (TQWidget*)this)
return true;
return false;
}
void
KexiRelationViewTable::slotDropped(TQDropEvent *ev)
{
TQListViewItem *recever = itemAt(ev->pos() - TQPoint(0,contentsY()));
if (!recever || !KexiFieldDrag::canDecodeSingle(ev)) {
ev->ignore();
return;
}
TQString sourceMimeType;
TQString srcTable;
TQString srcField;
if (!KexiFieldDrag::decodeSingle(ev,sourceMimeType,srcTable,srcField))
return;
if (sourceMimeType!="kexi/table" && sourceMimeType=="kexi/query")
return;
// kdDebug() << "KexiRelationViewTable::slotDropped() srcfield: " << srcField << endl;
TQString rcvField = recever->text(0);
SourceConnection s;
s.masterTable = srcTable;
s.detailsTable = schema()->name();
s.masterField = srcField;
s.detailsField = rcvField;
m_view->addConnection(s);
kdDebug() << "KexiRelationViewTable::slotDropped() " << srcTable << ":" << srcField << " "
<< schema()->name() << ":" << rcvField << endl;
ev->accept();
}
void
KexiRelationViewTable::slotContentsMoving(int,int)
{
emit tableScrolling();
}
void KexiRelationViewTable::contentsMousePressEvent(TQMouseEvent *ev)
{
parentWidget()->setFocus();
setFocus();
TDEListView::contentsMousePressEvent(ev);
// if (ev->button()==TQt::RightButton)
// static_cast<KexiRelationView*>(parentWidget())->executePopup(ev->pos());
}
TQRect KexiRelationViewTable::drawItemHighlighter(TQPainter *painter, TQListViewItem *item)
{
if (painter) {
style().drawPrimitive(TQStyle::PE_FocusRect, painter, itemRect(item), colorGroup(),
TQStyle::Style_FocusAtBorder);
}
return itemRect(item);
}
#include "kexirelationviewtable.moc"