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.
420 lines
14 KiB
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"
|