00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kexidatasourcepage.h"
00021
00022 #include <qlabel.h>
00023 #include <qlayout.h>
00024 #include <qtooltip.h>
00025 #include <qheader.h>
00026
00027 #include <kiconloader.h>
00028 #include <klocale.h>
00029 #include <ktoolbarbutton.h>
00030 #include <kdebug.h>
00031 #include <kpopupmenu.h>
00032
00033 #include <widget/kexipropertyeditorview.h>
00034 #include <widget/kexidatasourcecombobox.h>
00035 #include <widget/kexifieldlistview.h>
00036 #include <widget/kexifieldcombobox.h>
00037 #include <widget/kexismalltoolbutton.h>
00038 #include <kexidb/connection.h>
00039 #include <kexiproject.h>
00040
00041 #include <formeditor/commands.h>
00042
00043 #include <koproperty/property.h>
00044 #include <koproperty/utils.h>
00045
00046 KexiDataSourcePage::KexiDataSourcePage(QWidget *parent, const char *name)
00047 : QWidget(parent, name)
00048 , m_insideClearDataSourceSelection(false)
00049 {
00050 QVBoxLayout *vlyr = new QVBoxLayout(this);
00051 m_objectInfoLabel = new KexiObjectInfoLabel(this, "KexiObjectInfoLabel");
00052 vlyr->addWidget(m_objectInfoLabel);
00053
00054 m_noDataSourceAvailableSingleText = i18n("No data source could be assigned for this widget.");
00055 m_noDataSourceAvailableMultiText = i18n("No data source could be assigned for multiple widgets.");
00056
00057 vlyr->addSpacing(8);
00058
00059
00060 KoProperty::GroupContainer *container = new KoProperty::GroupContainer(i18n("Data Source"), this);
00061 vlyr->addWidget(container);
00062
00063 QWidget *contents = new QWidget(container);
00064 container->setContents(contents);
00065 QVBoxLayout *contentsVlyr = new QVBoxLayout(contents);
00066
00067 m_noDataSourceAvailableLabel = new QLabel(m_noDataSourceAvailableSingleText, contents);
00068 m_noDataSourceAvailableLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
00069 m_noDataSourceAvailableLabel->setMargin(2);
00070 m_noDataSourceAvailableLabel->setAlignment(Qt::WordBreak | Qt::AlignBottom | Qt::AlignLeft);
00071 contentsVlyr->addWidget(m_noDataSourceAvailableLabel);
00072
00073
00074 QHBoxLayout *hlyr = new QHBoxLayout(contentsVlyr);
00075 #if 0
00077 // m_widgetDSLabel = new QLabel(i18n("Table Field, Query Field or Expression", "Source field or expression:"), this);
00078 #else
00079 m_widgetDSLabel = new QLabel(i18n("Table Field or Query Field", "Widget's data source:"), contents);
00080 #endif
00081 m_widgetDSLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
00082 m_widgetDSLabel->setMargin(2);
00083 m_widgetDSLabel->setMinimumHeight(IconSize(KIcon::Small)+4);
00084 m_widgetDSLabel->setAlignment(AlignLeft|AlignBottom);
00085 hlyr->addWidget(m_widgetDSLabel);
00086
00087 m_clearWidgetDSButton = new KexiSmallToolButton(contents, QString::null, "clear_left", "clearWidgetDSButton");
00088 m_clearWidgetDSButton->setMinimumHeight(m_widgetDSLabel->minimumHeight());
00089 QToolTip::add(m_clearWidgetDSButton, i18n("Clear widget's data source"));
00090 hlyr->addWidget(m_clearWidgetDSButton);
00091 connect(m_clearWidgetDSButton, SIGNAL(clicked()), this, SLOT(clearWidgetDataSourceSelection()));
00092
00093 m_sourceFieldCombo = new KexiFieldComboBox(contents, "sourceFieldCombo");
00094 m_widgetDSLabel->setBuddy(m_sourceFieldCombo);
00095 contentsVlyr->addWidget(m_sourceFieldCombo);
00096
00097
00098
00099
00100
00101
00102 contentsVlyr->addSpacing(8);
00103
00104
00105 hlyr = new QHBoxLayout(contentsVlyr);
00106 m_dataSourceLabel = new QLabel(i18n("Form's data source:"), contents);
00107 m_dataSourceLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
00108 m_dataSourceLabel->setMargin(2);
00109 m_dataSourceLabel->setMinimumHeight(IconSize(KIcon::Small)+4);
00110 m_dataSourceLabel->setAlignment(AlignLeft|AlignBottom);
00111 hlyr->addWidget(m_dataSourceLabel);
00112
00113 m_gotoButton = new KexiSmallToolButton(contents, QString::null, "goto", "gotoButton");
00114 m_gotoButton->setMinimumHeight(m_dataSourceLabel->minimumHeight());
00115 QToolTip::add(m_gotoButton, i18n("Go to selected form's data source"));
00116 hlyr->addWidget(m_gotoButton);
00117 connect(m_gotoButton, SIGNAL(clicked()), this, SLOT(slotGotoSelected()));
00118
00119 m_clearDSButton = new KexiSmallToolButton(contents, QString::null, "clear_left", "clearDSButton");
00120 m_clearDSButton->setMinimumHeight(m_dataSourceLabel->minimumHeight());
00121 QToolTip::add(m_clearDSButton, i18n("Clear form's data source"));
00122 hlyr->addWidget(m_clearDSButton);
00123 connect(m_clearDSButton, SIGNAL(clicked()), this, SLOT(clearDataSourceSelection()));
00124
00125 m_dataSourceCombo = new KexiDataSourceComboBox(contents, "dataSourceCombo");
00126 m_dataSourceLabel->setBuddy(m_dataSourceCombo);
00127 contentsVlyr->addWidget(m_dataSourceCombo);
00128
00129 #ifdef KEXI_NO_AUTOFIELD_WIDGET
00130 m_availableFieldsLabel = 0;
00131 m_addField = 0;
00132
00133 vlyr->addStretch();
00134 #else
00135 vlyr->addSpacing(fontMetrics().height());
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 container = new KoProperty::GroupContainer(i18n("Inserting Fields"), this);
00149 vlyr->addWidget(container, 1);
00150
00151
00153 contents = new QWidget(container);
00154 container->setContents(contents);
00155 contentsVlyr = new QVBoxLayout(contents);
00156 hlyr = new QHBoxLayout(contentsVlyr);
00157 m_mousePointerLabel = new QLabel(contents);
00158 hlyr->addWidget(m_mousePointerLabel);
00159 m_mousePointerLabel->setPixmap( SmallIcon("mouse_pointer") );
00160 m_mousePointerLabel->setFixedWidth( m_mousePointerLabel->pixmap() ? m_mousePointerLabel->pixmap()->width() : 0);
00161 m_availableFieldsDescriptionLabel = new QLabel(
00162 i18n("Select fields from the list below and drag them onto a form or click the \"Insert\" button"), contents);
00163 m_availableFieldsDescriptionLabel->setAlignment( Qt::AlignAuto | Qt::WordBreak );
00164 hlyr->addWidget(m_availableFieldsDescriptionLabel);
00165
00166
00167 contentsVlyr->addSpacing(4);
00168 hlyr = new QHBoxLayout(contentsVlyr);
00169 m_availableFieldsLabel = new QLabel(i18n("Available fields:"), contents);
00170 m_availableFieldsLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
00171 m_availableFieldsLabel->setMargin(2);
00172 m_availableFieldsLabel->setMinimumHeight(IconSize(KIcon::Small));
00173 hlyr->addWidget(m_availableFieldsLabel);
00174
00175 m_addField = new KexiSmallToolButton(contents, i18n("Insert selected field into form", "Insert"),
00176 "add_field", "addFieldButton");
00177 m_addField->setMinimumHeight(m_availableFieldsLabel->minimumHeight());
00178
00179 m_addField->setFocusPolicy(StrongFocus);
00180 QToolTip::add(m_addField, i18n("Insert selected fields into form"));
00181 hlyr->addWidget(m_addField);
00182 connect(m_addField, SIGNAL(clicked()), this, SLOT(slotInsertSelectedFields()));
00183
00184 m_fieldListView = new KexiFieldListView(contents, "fieldListView",
00185 KexiFieldListView::ShowDataTypes | KexiFieldListView::AllowMultiSelection );
00186 m_fieldListView->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding));
00187 m_availableFieldsLabel->setBuddy(m_fieldListView);
00188 contentsVlyr->addWidget(m_fieldListView, 1);
00189 connect(m_fieldListView, SIGNAL(selectionChanged()), this, SLOT(slotFieldListViewSelectionChanged()));
00190 connect(m_fieldListView, SIGNAL(fieldDoubleClicked(const QString&, const QString&, const QString&)),
00191 this, SLOT(slotFieldDoubleClicked(const QString&, const QString&, const QString&)));
00192 #endif
00193
00194 vlyr->addStretch(1);
00195
00196 connect(m_dataSourceCombo, SIGNAL(textChanged(const QString &)), this, SLOT(slotDataSourceTextChanged(const QString &)));
00197 connect(m_dataSourceCombo, SIGNAL(dataSourceChanged()), this, SLOT(slotDataSourceChanged()));
00198 connect(m_sourceFieldCombo, SIGNAL(selected()), this, SLOT(slotFieldSelected()));
00199
00200 clearDataSourceSelection();
00201 slotFieldListViewSelectionChanged();
00202 }
00203
00204 KexiDataSourcePage::~KexiDataSourcePage()
00205 {
00206 }
00207
00208 void KexiDataSourcePage::setProject(KexiProject *prj)
00209 {
00210 m_sourceFieldCombo->setProject(prj);
00211 m_dataSourceCombo->setProject(prj);
00212 }
00213
00214 void KexiDataSourcePage::clearDataSourceSelection(bool alsoClearComboBox)
00215 {
00216 if (m_insideClearDataSourceSelection)
00217 return;
00218 m_insideClearDataSourceSelection = true;
00219 if (alsoClearComboBox && !m_dataSourceCombo->selectedName().isEmpty())
00220 m_dataSourceCombo->setDataSource("", "");
00221
00222
00223
00224
00225 m_clearDSButton->setEnabled(false);
00226 m_gotoButton->setEnabled(false);
00227 #ifndef KEXI_NO_AUTOFIELD_WIDGET
00228 m_addField->setEnabled(false);
00229 m_fieldListView->clear();
00230 #endif
00231 m_insideClearDataSourceSelection = false;
00232 }
00233
00234 void KexiDataSourcePage::clearWidgetDataSourceSelection()
00235 {
00236 if (!m_sourceFieldCombo->currentText().isEmpty()) {
00237 m_sourceFieldCombo->setCurrentText("");
00238 m_sourceFieldCombo->setFieldOrExpression(QString::null);
00239 slotFieldSelected();
00240 }
00241 m_clearWidgetDSButton->setEnabled(false);
00242 }
00243
00244 void KexiDataSourcePage::slotGotoSelected()
00245 {
00246 QCString mime = m_dataSourceCombo->selectedMimeType().latin1();
00247 if (mime=="kexi/table" || mime=="kexi/query") {
00248 if (m_dataSourceCombo->isSelectionValid())
00249 emit jumpToObjectRequested(mime, m_dataSourceCombo->selectedName().latin1());
00250 }
00251 }
00252
00253 void KexiDataSourcePage::slotInsertSelectedFields()
00254 {
00255 #ifndef KEXI_NO_AUTOFIELD_WIDGET
00256 QStringList selectedFieldNames(m_fieldListView->selectedFieldNames());
00257 if (selectedFieldNames.isEmpty())
00258 return;
00259
00260 emit insertAutoFields(m_fieldListView->schema()->table() ? "kexi/table" : "kexi/query",
00261 m_fieldListView->schema()->name(), selectedFieldNames);
00262 #endif
00263 }
00264
00265 void KexiDataSourcePage::slotFieldDoubleClicked(const QString& sourceMimeType, const QString& sourceName,
00266 const QString& fieldName)
00267 {
00268 #ifndef KEXI_NO_AUTOFIELD_WIDGET
00269 QStringList selectedFields;
00270 selectedFields.append(fieldName);
00271 emit insertAutoFields(sourceMimeType, sourceName, selectedFields);
00272 #endif
00273 }
00274
00275 void KexiDataSourcePage::slotDataSourceTextChanged(const QString & string)
00276 {
00277 Q_UNUSED(string);
00278 const bool enable = m_dataSourceCombo->isSelectionValid();
00279 if (!enable) {
00280 clearDataSourceSelection( m_dataSourceCombo->selectedName().isEmpty() );
00281 }
00282 updateSourceFieldWidgetsAvailability();
00283
00284
00285
00286
00287
00288 }
00289
00290 void KexiDataSourcePage::slotDataSourceChanged()
00291 {
00292 if (!m_dataSourceCombo->project())
00293 return;
00294 QCString mime = m_dataSourceCombo->selectedMimeType().latin1();
00295 bool dataSourceFound = false;
00296 QCString name = m_dataSourceCombo->selectedName().latin1();
00297 if ((mime=="kexi/table" || mime=="kexi/query") && m_dataSourceCombo->isSelectionValid()) {
00298 KexiDB::TableOrQuerySchema *tableOrQuery = new KexiDB::TableOrQuerySchema(
00299 m_dataSourceCombo->project()->dbConnection(), name, mime=="kexi/table");
00300 if (tableOrQuery->table() || tableOrQuery->query()) {
00301 #ifdef KEXI_NO_AUTOFIELD_WIDGET
00302 m_tableOrQuerySchema = tableOrQuery;
00303 #else
00304 m_fieldListView->setSchema( tableOrQuery );
00305 #endif
00306 dataSourceFound = true;
00307 m_sourceFieldCombo->setTableOrQuery(name, mime=="kexi/table");
00308 }
00309 else {
00310 delete tableOrQuery;
00311 }
00312 }
00313 if (!dataSourceFound) {
00314 m_sourceFieldCombo->setTableOrQuery("", true);
00315 }
00316
00317
00318 m_clearDSButton->setEnabled(dataSourceFound);
00319 m_gotoButton->setEnabled(dataSourceFound);
00320 if (dataSourceFound) {
00321 slotFieldListViewSelectionChanged();
00322 } else {
00323 #ifndef KEXI_NO_AUTOFIELD_WIDGET
00324 m_addField->setEnabled(false);
00325 #endif
00326 }
00327 updateSourceFieldWidgetsAvailability();
00328 emit formDataSourceChanged(mime, name);
00329 }
00330
00331 void KexiDataSourcePage::slotFieldSelected()
00332 {
00333 KexiDB::Field::Type dataType = KexiDB::Field::InvalidType;
00334 #ifdef KEXI_NO_AUTOFIELD_WIDGET
00335 KexiDB::Field *field = m_tableOrQuerySchema->field( m_sourceFieldCombo->fieldOrExpression() );
00336 #else
00338 KexiDB::Field *field = m_fieldListView->schema()->field( m_sourceFieldCombo->fieldOrExpression() );
00339 #endif
00340 if (field)
00341 dataType = field->type();
00342
00343 m_clearWidgetDSButton->setEnabled( !m_sourceFieldCombo->fieldOrExpression().isEmpty() );
00344
00345 emit dataSourceFieldOrExpressionChanged(
00346 m_sourceFieldCombo->fieldOrExpression(),
00347 m_sourceFieldCombo->fieldOrExpressionCaption(),
00348 dataType
00349 );
00350 }
00351
00352 void KexiDataSourcePage::setDataSource(const QCString& mimeType, const QCString& name)
00353 {
00354 m_dataSourceCombo->setDataSource(mimeType, name);
00355 }
00356
00357 void KexiDataSourcePage::assignPropertySet(KoProperty::Set* propertySet)
00358 {
00359 QCString objectName;
00360 if (propertySet && propertySet->contains("name"))
00361 objectName = (*propertySet)["name"].value().toCString();
00362 if (!objectName.isEmpty() && objectName == m_currentObjectName)
00363 return;
00364 m_currentObjectName = objectName;
00365
00366 QCString objectClassName;
00367 if (propertySet && propertySet->contains("this:className"))
00368 objectClassName = (*propertySet)["this:className"].value().toCString();
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 KexiPropertyEditorView::updateInfoLabelForPropertySet(
00383 m_objectInfoLabel, propertySet);
00384
00385 const bool isForm = objectClassName=="KexiDBForm";
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 const bool multipleSelection = objectClassName=="special:multiple";
00399 const bool hasDataSourceProperty = propertySet && propertySet->contains("dataSource") && !multipleSelection;
00400
00401 if (!isForm) {
00402
00403 QCString dataSource;
00404 if (hasDataSourceProperty) {
00405 if (propertySet)
00406 dataSource = (*propertySet)["dataSource"].value().toCString();
00407 m_noDataSourceAvailableLabel->hide();
00408 m_sourceFieldCombo->setFieldOrExpression(dataSource);
00409 m_sourceFieldCombo->setEnabled(true);
00410 m_clearWidgetDSButton->setEnabled(!m_sourceFieldCombo->currentText().isEmpty());
00411 m_widgetDSLabel->show();
00412 m_clearWidgetDSButton->show();
00413 m_sourceFieldCombo->show();
00414
00415 updateSourceFieldWidgetsAvailability();
00416 }
00417 }
00418
00419 if (isForm) {
00420 m_noDataSourceAvailableLabel->hide();
00421
00422 }
00423 else if (!hasDataSourceProperty) {
00424 if (multipleSelection)
00425 m_noDataSourceAvailableLabel->setText(m_noDataSourceAvailableMultiText);
00426 else
00427 m_noDataSourceAvailableLabel->setText(m_noDataSourceAvailableSingleText);
00428 m_noDataSourceAvailableLabel->show();
00429
00430
00431 m_noDataSourceAvailableLabel->setMinimumHeight(m_widgetDSLabel->height()
00432 + m_sourceFieldCombo->height());
00433 m_sourceFieldCombo->setCurrentText("");
00434 }
00435
00436 if (isForm || !hasDataSourceProperty) {
00437
00438 m_widgetDSLabel->hide();
00439 m_clearWidgetDSButton->hide();
00440 m_sourceFieldCombo->hide();
00441 }
00442 }
00443
00444 void KexiDataSourcePage::slotFieldListViewSelectionChanged()
00445 {
00446 #ifndef KEXI_NO_AUTOFIELD_WIDGET
00447
00448 for (QListViewItemIterator it(m_fieldListView); it.current(); ++it) {
00449 if (it.current()->isSelected()) {
00450 m_addField->setEnabled(true);
00451 return;
00452 }
00453 }
00454 m_addField->setEnabled(false);
00455 #endif
00456 }
00457
00458 void KexiDataSourcePage::updateSourceFieldWidgetsAvailability()
00459 {
00460 const bool hasDataSource = m_dataSourceCombo->isSelectionValid();
00461 m_sourceFieldCombo->setEnabled( hasDataSource );
00462 m_widgetDSLabel->setEnabled( hasDataSource );
00463 #ifndef KEXI_NO_AUTOFIELD_WIDGET
00464 m_fieldListView->setEnabled( hasDataSource );
00465 m_availableFieldsLabel->setEnabled( hasDataSource );
00466 m_mousePointerLabel->setEnabled( hasDataSource );
00467 m_availableFieldsDescriptionLabel->setEnabled( hasDataSource );
00468 #endif
00469 }
00470
00471 #include "kexidatasourcepage.moc"