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/plugins/tables/kexilookupcolumnpage.cpp

420 lines
14 KiB

/* This file is part of the KDE project
Copyright (C) 2006 Jaroslaw Staniek <js@iidea.pl>
This library 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 library 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 library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "kexilookupcolumnpage.h"
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqtooltip.h>
#include <tqheader.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdetoolbarbutton.h>
#include <kdebug.h>
#include <tdepopupmenu.h>
#include <widget/kexipropertyeditorview.h>
#include <widget/kexidatasourcecombobox.h>
#include <widget/kexifieldlistview.h>
#include <widget/kexifieldcombobox.h>
#include <widget/kexismalltoolbutton.h>
#include <kexidb/connection.h>
#include <kexiproject.h>
#include <koproperty/property.h>
#include <koproperty/utils.h>
TQString mimeTypeToType(const TQString& mimeType)
{
if (mimeType=="kexi/table")
return "table";
else if (mimeType=="kexi/query")
return "query";
//! @todo more types
return mimeType;
}
TQString typeToMimeType(const TQString& type)
{
if (type=="table")
return "kexi/table";
else if (type=="query")
return "kexi/query";
//! @todo more types
return type;
}
//----------------------------------------------
//! @internal
class KexiLookupColumnPage::Private
{
public:
Private()
: currentFieldUid(-1)
, insideClearRowSourceSelection(false)
, propertySetEnabled(true)
{
}
~Private()
{
}
bool hasPropertySet() const {
return propertySet;
}
void setPropertySet(KoProperty::Set* aPropertySet) {
propertySet = aPropertySet;
}
TQVariant propertyValue(const TQCString& propertyName) const {
return propertySet ? propertySet->property(propertyName).value() : TQVariant();
}
void changeProperty(const TQCString &property, const TQVariant &value)
{
if (!propertySetEnabled)
return;
propertySet->changeProperty(property, value);
}
void updateInfoLabelForPropertySet(const TQString& textToDisplayForNullSet) {
KexiPropertyEditorView::updateInfoLabelForPropertySet(
objectInfoLabel, propertySet, textToDisplayForNullSet);
}
KexiDataSourceComboBox *rowSourceCombo;
KexiFieldComboBox *boundColumnCombo, *visibleColumnCombo;
KexiObjectInfoLabel *objectInfoLabel;
TQLabel *rowSourceLabel, *boundColumnLabel, *visibleColumnLabel;
TQToolButton *clearRowSourceButton, *gotoRowSourceButton, *clearBoundColumnButton,
*clearVisibleColumnButton;
//! Used only in assignPropertySet() to check whether we already have the set assigned
int currentFieldUid;
bool insideClearRowSourceSelection : 1;
//! True is changeProperty() works. Used to block updating properties when within assignPropertySet().
bool propertySetEnabled : 1;
private:
//! A property set that is displayed on the page.
//! The set is also updated after any change in this page's data.
TQGuardedPtr<KoProperty::Set> propertySet;
};
//----------------------------------------------
KexiLookupColumnPage::KexiLookupColumnPage(TQWidget *parent)
: TQWidget(parent)
, d(new Private())
{
setName("KexiLookupColumnPage");
TQVBoxLayout *vlyr = new TQVBoxLayout(this);
d->objectInfoLabel = new KexiObjectInfoLabel(this, "KexiObjectInfoLabel");
vlyr->addWidget(d->objectInfoLabel);
//todo d->noDataSourceAvailableSingleText = i18n("No data source could be assigned for this widget.");
//todo d->noDataSourceAvailableMultiText = i18n("No data source could be assigned for multiple widgets.");
//-Row Source
TQWidget *contents = new TQWidget(this);
vlyr->addWidget(contents);
TQVBoxLayout *contentsVlyr = new TQVBoxLayout(contents);
TQHBoxLayout *hlyr = new TQHBoxLayout(contentsVlyr);
d->rowSourceLabel = new TQLabel(i18n("Row source:"), contents);
d->rowSourceLabel->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
d->rowSourceLabel->setMargin(2);
d->rowSourceLabel->setMinimumHeight(IconSize(TDEIcon::Small)+4);
d->rowSourceLabel->setAlignment(TQt::AlignLeft|TQt::AlignBottom);
hlyr->addWidget(d->rowSourceLabel);
d->gotoRowSourceButton = new KexiSmallToolButton(contents, TQString(), "goto", "gotoRowSourceButton");
d->gotoRowSourceButton->setMinimumHeight(d->rowSourceLabel->minimumHeight());
TQToolTip::add(d->gotoRowSourceButton, i18n("Go to selected row source"));
hlyr->addWidget(d->gotoRowSourceButton);
connect(d->gotoRowSourceButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotGotoSelectedRowSource()));
d->clearRowSourceButton = new KexiSmallToolButton(contents, TQString(),
"clear_left", "clearRowSourceButton");
d->clearRowSourceButton->setMinimumHeight(d->rowSourceLabel->minimumHeight());
TQToolTip::add(d->clearRowSourceButton, i18n("Clear row source"));
hlyr->addWidget(d->clearRowSourceButton);
connect(d->clearRowSourceButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(clearRowSourceSelection()));
d->rowSourceCombo = new KexiDataSourceComboBox(contents, "rowSourceCombo");
d->rowSourceLabel->setBuddy(d->rowSourceCombo);
contentsVlyr->addWidget(d->rowSourceCombo);
contentsVlyr->addSpacing(8);
//- Bound Column
hlyr = new TQHBoxLayout(contentsVlyr);
d->boundColumnLabel = new TQLabel(i18n("Bound column:"), contents);
d->boundColumnLabel->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
d->boundColumnLabel->setMargin(2);
d->boundColumnLabel->setMinimumHeight(IconSize(TDEIcon::Small)+4);
d->boundColumnLabel->setAlignment(TQt::AlignLeft|TQt::AlignBottom);
hlyr->addWidget(d->boundColumnLabel);
d->clearBoundColumnButton = new KexiSmallToolButton(contents, TQString(),
"clear_left", "clearBoundColumnButton");
d->clearBoundColumnButton->setMinimumHeight(d->boundColumnLabel->minimumHeight());
TQToolTip::add(d->clearBoundColumnButton, i18n("Clear bound column"));
hlyr->addWidget(d->clearBoundColumnButton);
connect(d->clearBoundColumnButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(clearBoundColumnSelection()));
d->boundColumnCombo = new KexiFieldComboBox(contents, "boundColumnCombo");
d->boundColumnLabel->setBuddy(d->boundColumnCombo);
contentsVlyr->addWidget(d->boundColumnCombo);
contentsVlyr->addSpacing(8);
//- Visible Column
hlyr = new TQHBoxLayout(contentsVlyr);
d->visibleColumnLabel = new TQLabel(i18n("Visible column:"), contents);
d->visibleColumnLabel->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
d->visibleColumnLabel->setMargin(2);
d->visibleColumnLabel->setMinimumHeight(IconSize(TDEIcon::Small)+4);
d->visibleColumnLabel->setAlignment(TQt::AlignLeft|TQt::AlignBottom);
hlyr->addWidget(d->visibleColumnLabel);
d->clearVisibleColumnButton = new KexiSmallToolButton(contents, TQString(),
"clear_left", "clearVisibleColumnButton");
d->clearVisibleColumnButton->setMinimumHeight(d->visibleColumnLabel->minimumHeight());
TQToolTip::add(d->clearVisibleColumnButton, i18n("Clear visible column"));
hlyr->addWidget(d->clearVisibleColumnButton);
connect(d->clearVisibleColumnButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(clearVisibleColumnSelection()));
d->visibleColumnCombo = new KexiFieldComboBox(contents, "visibleColumnCombo");
d->visibleColumnLabel->setBuddy(d->visibleColumnCombo);
contentsVlyr->addWidget(d->visibleColumnCombo);
vlyr->addStretch(1);
connect(d->rowSourceCombo, TQ_SIGNAL(textChanged(const TQString &)),
this, TQ_SLOT(slotRowSourceTextChanged(const TQString &)));
connect(d->rowSourceCombo, TQ_SIGNAL(dataSourceChanged()), this, TQ_SLOT(slotRowSourceChanged()));
connect(d->boundColumnCombo, TQ_SIGNAL(selected()), this, TQ_SLOT(slotBoundColumnSelected()));
connect(d->visibleColumnCombo, TQ_SIGNAL(selected()), this, TQ_SLOT(slotVisibleColumnSelected()));
clearBoundColumnSelection();
clearVisibleColumnSelection();
}
KexiLookupColumnPage::~KexiLookupColumnPage()
{
delete d;
}
void KexiLookupColumnPage::setProject(KexiProject *prj)
{
d->rowSourceCombo->setProject(prj,
true/*showTables*/, true/*showQueries*/
);
d->boundColumnCombo->setProject(prj);
d->visibleColumnCombo->setProject(prj);
}
void KexiLookupColumnPage::assignPropertySet(KoProperty::Set* propertySet)
{
if (!d->hasPropertySet() && !propertySet)
return;
if (propertySet && d->currentFieldUid == (*propertySet)["uid"].value().toInt())
return; //already assigned
d->propertySetEnabled = false;
d->setPropertySet( propertySet );
d->updateInfoLabelForPropertySet( i18n("No field selected") );
const bool hasRowSource = d->hasPropertySet() && !d->propertyValue("rowSourceType").isNull()
&& !d->propertyValue("rowSource").isNull();
TQString rowSource, rowSourceType;
if (hasRowSource) {
rowSourceType = typeToMimeType( d->propertyValue("rowSourceType").toString() );
rowSource = d->propertyValue("rowSource").toString();
}
d->rowSourceCombo->setDataSource( rowSourceType, rowSource );
d->rowSourceLabel->setEnabled( d->hasPropertySet() );
d->rowSourceCombo->setEnabled( d->hasPropertySet() );
if (!d->hasPropertySet())
d->clearRowSourceButton->setEnabled( false );
int boundColumn = -1, visibleColumn = -1;
if (d->rowSourceCombo->isSelectionValid()) {
boundColumn = d->propertyValue("boundColumn").toInt();
visibleColumn = d->propertyValue("visibleColumn").toInt();
}
d->boundColumnCombo->setFieldOrExpression(boundColumn);
d->visibleColumnCombo->setFieldOrExpression(visibleColumn);
updateBoundColumnWidgetsAvailability();
d->propertySetEnabled = true;
}
void KexiLookupColumnPage::clearBoundColumnSelection()
{
d->boundColumnCombo->setCurrentText("");
d->boundColumnCombo->setFieldOrExpression(TQString());
slotBoundColumnSelected();
d->clearBoundColumnButton->setEnabled(false);
}
void KexiLookupColumnPage::slotBoundColumnSelected()
{
// KexiDB::Field::Type dataType = KexiDB::Field::InvalidType;
//! @todo this should also work for expressions
/*disabled KexiDB::Field *field = d->fieldListView->schema()->field( d->boundColumnCombo->fieldOrExpression() );
if (field)
dataType = field->type();
*/
d->clearBoundColumnButton->setEnabled( !d->boundColumnCombo->fieldOrExpression().isEmpty() );
if (!d->boundColumnCombo->fieldOrExpression().isEmpty()) {
kdDebug() << endl;
}
// update property set
if (d->hasPropertySet()) {
d->changeProperty("boundColumn", d->boundColumnCombo->indexOfField());
}
/*
emit boundColumnChanged(
d->boundColumnCombo->fieldOrExpression(),
d->boundColumnCombo->fieldOrExpressionCaption(),
dataType
);*/
}
void KexiLookupColumnPage::clearVisibleColumnSelection()
{
d->visibleColumnCombo->setCurrentText("");
d->visibleColumnCombo->setFieldOrExpression(TQString());
slotVisibleColumnSelected();
d->clearVisibleColumnButton->setEnabled(false);
}
void KexiLookupColumnPage::slotVisibleColumnSelected()
{
// KexiDB::Field::Type dataType = KexiDB::Field::InvalidType;
//! @todo this should also work for expressions
d->clearVisibleColumnButton->setEnabled( !d->visibleColumnCombo->fieldOrExpression().isEmpty() );
// update property set
if (d->hasPropertySet()) {
//! @todo support expression in special "visibleExpression"
d->changeProperty("visibleColumn", d->visibleColumnCombo->indexOfField());
}
}
void KexiLookupColumnPage::slotRowSourceChanged()
{
if (!d->rowSourceCombo->project())
return;
TQString mime = d->rowSourceCombo->selectedMimeType();
bool rowSourceFound = false;
TQString name = d->rowSourceCombo->selectedName();
if ((mime=="kexi/table" || mime=="kexi/query") && d->rowSourceCombo->isSelectionValid()) {
KexiDB::TableOrQuerySchema *tableOrQuery = new KexiDB::TableOrQuerySchema(
d->rowSourceCombo->project()->dbConnection(), name.latin1(), mime=="kexi/table");
if (tableOrQuery->table() || tableOrQuery->query()) {
//disabled d->fieldListView->setSchema( tableOrQuery );
/*tmp*/ delete tableOrQuery;
rowSourceFound = true;
d->boundColumnCombo->setTableOrQuery(name, mime=="kexi/table");
d->visibleColumnCombo->setTableOrQuery(name, mime=="kexi/table");
}
else {
delete tableOrQuery;
}
}
if (!rowSourceFound) {
d->boundColumnCombo->setTableOrQuery("", true);
d->visibleColumnCombo->setTableOrQuery("", true);
}
clearBoundColumnSelection();
clearVisibleColumnSelection();
d->clearRowSourceButton->setEnabled(rowSourceFound);
d->gotoRowSourceButton->setEnabled(rowSourceFound);
/* disabled
if (dataSourceFound) {
slotFieldListViewSelectionChanged();
} else {
d->addField->setEnabled(false);
}*/
updateBoundColumnWidgetsAvailability();
//update property set
if (d->hasPropertySet()) {
d->changeProperty("rowSourceType", mimeTypeToType(mime));
d->changeProperty("rowSource", name);
}
//disabled emit formDataSourceChanged(mime, name);
//! @todo update d->propertySet ^^
}
void KexiLookupColumnPage::slotRowSourceTextChanged(const TQString & string)
{
Q_UNUSED(string);
const bool enable = d->rowSourceCombo->isSelectionValid();
if (enable) {
updateBoundColumnWidgetsAvailability();
}
else {
clearRowSourceSelection( d->rowSourceCombo->selectedName().isEmpty()/*alsoClearComboBox*/ );
}
}
void KexiLookupColumnPage::clearRowSourceSelection(bool alsoClearComboBox)
{
if (d->insideClearRowSourceSelection)
return;
d->insideClearRowSourceSelection = true;
if (alsoClearComboBox && !d->rowSourceCombo->selectedName().isEmpty())
d->rowSourceCombo->setDataSource("", "");
d->clearRowSourceButton->setEnabled(false);
d->gotoRowSourceButton->setEnabled(false);
d->insideClearRowSourceSelection = false;
}
void KexiLookupColumnPage::slotGotoSelectedRowSource()
{
TQString mime = d->rowSourceCombo->selectedMimeType();
if (mime=="kexi/table" || mime=="kexi/query") {
if (d->rowSourceCombo->isSelectionValid())
emit jumpToObjectRequested(mime.latin1(), d->rowSourceCombo->selectedName().latin1());
}
}
void KexiLookupColumnPage::updateBoundColumnWidgetsAvailability()
{
const bool hasRowSource = d->rowSourceCombo->isSelectionValid();
d->boundColumnCombo->setEnabled( hasRowSource );
d->boundColumnLabel->setEnabled( hasRowSource );
d->clearBoundColumnButton->setEnabled( hasRowSource && !d->boundColumnCombo->fieldOrExpression().isEmpty() );
d->visibleColumnCombo->setEnabled( hasRowSource );
d->visibleColumnLabel->setEnabled( hasRowSource );
d->clearVisibleColumnButton->setEnabled( hasRowSource && !d->visibleColumnCombo->fieldOrExpression().isEmpty() );
}
#include "kexilookupcolumnpage.moc"