File indexing completed on 2024-05-12 16:40:56
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003-2011 Jarosław Staniek <staniek@kde.org> 0003 0004 This program is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this program; see the file COPYING. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "KexiProjectSelectorWidget.h" 0021 #include <core/kexi.h> 0022 #include <KexiIcon.h> 0023 0024 #include <KDbDriverManager> 0025 #include <KDbDriverMetaData> 0026 #include <KDbConnectionData> 0027 #include <KDbUtils> 0028 #include <KDbMessageHandler> 0029 0030 #include <KLocalizedString> 0031 #include <KGuiItem> 0032 0033 #include <QDebug> 0034 #include <QLabel> 0035 #include <QPushButton> 0036 #include <QKeyEvent> 0037 0038 #include <assert.h> 0039 0040 //! @internal 0041 class Q_DECL_HIDDEN KexiProjectSelectorWidget::Private 0042 { 0043 public: 0044 explicit Private(KexiProjectSet *prj_set_) 0045 : prj_set(prj_set_) 0046 { 0047 selectable = true; 0048 } 0049 0050 QIcon fileicon, dbicon; 0051 bool showProjectNameColumn; 0052 bool showConnectionColumns; 0053 bool selectable; 0054 0055 KexiProjectSet *prj_set; 0056 }; 0057 0058 class Q_DECL_HIDDEN KexiProjectSelectorDialog::Private 0059 { 0060 public: 0061 Private() {} 0062 KexiProjectSelectorWidget* sel; 0063 }; 0064 0065 /*================================================================*/ 0066 0067 //! helper class 0068 class ProjectDataLVItem : public QTreeWidgetItem 0069 { 0070 public: 0071 ProjectDataLVItem(KexiProjectData *d, 0072 const KDbDriverMetaData &driverMetaData, 0073 KexiProjectSelectorWidget *selector) 0074 : QTreeWidgetItem(selector->list()) 0075 , data(d) 0076 { 0077 int colnum = 0; 0078 const KDbConnectionData cdata = *data->connectionData(); 0079 if (selector->d->showProjectNameColumn) 0080 setText(colnum++, data->caption() + " "); 0081 0082 setText(colnum++, data->databaseName() + " "); 0083 0084 if (selector->d->showConnectionColumns) { 0085 QString driverName = driverMetaData.name(); 0086 if (driverName.isEmpty()) { 0087 KDbDriverManager manager; 0088 const KDbDriverMetaData *driverMetaDataFromCdata = manager.driverMetaData(cdata.driverId()); 0089 if (driverMetaDataFromCdata) { 0090 driverName = driverMetaDataFromCdata->name(); 0091 } 0092 } 0093 if (driverMetaData.isFileBased()) { 0094 setText(colnum++, xi18n("File (%1)", driverName) + " "); 0095 } else { 0096 setText(colnum++, driverName + " "); 0097 } 0098 QString conn; 0099 if (cdata.caption().isEmpty()) { 0100 conn = cdata.toUserVisibleString(); 0101 } 0102 else { 0103 conn = xi18nc("caption: server_info", "%1: %2", 0104 cdata.caption(), cdata.toUserVisibleString()); 0105 } 0106 setText(colnum++, conn + " "); 0107 } 0108 } 0109 ~ProjectDataLVItem() {} 0110 0111 KexiProjectData *data; 0112 }; 0113 0114 /*================================================================*/ 0115 0116 /*! 0117 * Constructs a KexiProjectSelector which is a child of 'parent', with the 0118 * name 'name' and widget flags set to 'f' 0119 */ 0120 KexiProjectSelectorWidget::KexiProjectSelectorWidget(QWidget* parent, 0121 KexiProjectSet* prj_set, bool showProjectNameColumn, bool showConnectionColumns) 0122 : QWidget(parent) 0123 , d(new Private(prj_set)) 0124 { 0125 setupUi(this); 0126 setObjectName("KexiProjectSelectorWidget"); 0127 d->showProjectNameColumn = showProjectNameColumn; 0128 d->showConnectionColumns = showConnectionColumns; 0129 list()->installEventFilter(this); 0130 0131 d->fileicon = Kexi::defaultFileBasedDriverIcon(); 0132 setWindowIcon(d->fileicon); 0133 d->dbicon = koIcon("server-database"); 0134 0135 QTreeWidgetItem *headerItem = list()->headerItem(); 0136 QTreeWidgetItem *newHeaderItem = new QTreeWidgetItem; 0137 int newHeaderItemIndex = 0; 0138 if (d->showProjectNameColumn) { 0139 newHeaderItem->setText(newHeaderItemIndex++, headerItem->text(0)); // project name 0140 } 0141 newHeaderItem->setText(newHeaderItemIndex++, headerItem->text(1)); // database 0142 if (d->showConnectionColumns) { 0143 newHeaderItem->setText(newHeaderItemIndex++, headerItem->text(2)); // type 0144 newHeaderItem->setText(newHeaderItemIndex++, headerItem->text(3)); // connection 0145 } 0146 list()->setHeaderItem(newHeaderItem); 0147 setFocusProxy(list()); 0148 0149 //show projects 0150 setProjectSet(d->prj_set); 0151 connect(list(), SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), 0152 this, SLOT(slotItemExecuted(QTreeWidgetItem*))); 0153 connect(list(), SIGNAL(itemSelectionChanged()), 0154 this, SLOT(slotItemSelected())); 0155 } 0156 0157 /*! 0158 * Destroys the object and frees any allocated resources 0159 */ 0160 KexiProjectSelectorWidget::~KexiProjectSelectorWidget() 0161 { 0162 delete d; 0163 } 0164 0165 KexiProjectData* KexiProjectSelectorWidget::selectedProjectData() const 0166 { 0167 QList<QTreeWidgetItem *> items = list()->selectedItems(); 0168 if (items.isEmpty()) 0169 return 0; 0170 ProjectDataLVItem *item = static_cast<ProjectDataLVItem*>(items.first()); 0171 if (item) 0172 return item->data; 0173 return 0; 0174 } 0175 0176 void KexiProjectSelectorWidget::slotItemExecuted(QTreeWidgetItem *item) 0177 { 0178 if (!d->selectable) 0179 return; 0180 ProjectDataLVItem *ditem = static_cast<ProjectDataLVItem*>(item); 0181 if (ditem) 0182 emit projectExecuted(ditem->data); 0183 } 0184 0185 void KexiProjectSelectorWidget::slotItemExecuted() 0186 { 0187 if (!d->selectable) 0188 return; 0189 QList<QTreeWidgetItem *> items = list()->selectedItems(); 0190 if (items.isEmpty()) 0191 return; 0192 slotItemExecuted(items.first()); 0193 } 0194 0195 void KexiProjectSelectorWidget::slotItemSelected() 0196 { 0197 if (!d->selectable) 0198 return; 0199 QList<QTreeWidgetItem *> items = list()->selectedItems(); 0200 ProjectDataLVItem *ditem = static_cast<ProjectDataLVItem*>(items.isEmpty() ? 0 : items.first()); 0201 emit selectionChanged(ditem ? ditem->data : 0); 0202 } 0203 0204 void KexiProjectSelectorWidget::setProjectSet(KexiProjectSet* prj_set) 0205 { 0206 if (prj_set) { 0207 //old list 0208 list()->clear(); 0209 } 0210 d->prj_set = prj_set; 0211 if (!d->prj_set) 0212 return; 0213 //! @todo what with project set's ownership? 0214 if (d->prj_set->result().isError()) { 0215 qDebug() << "d->prj_set->error()" << d->prj_set->result(); 0216 return; 0217 } 0218 KDbDriverManager manager; 0219 KexiProjectData::List prjlist = d->prj_set->list(); 0220 foreach(KexiProjectData* data, prjlist) { 0221 KDbMessageGuard mg(manager.resultable()); 0222 const KDbDriverMetaData *driverMetaData = manager.driverMetaData(data->connectionData()->driverId()); 0223 if (driverMetaData) { 0224 ProjectDataLVItem *item = new ProjectDataLVItem(data, *driverMetaData, this); 0225 if (!d->selectable) { 0226 Qt::ItemFlags flags = item->flags(); 0227 (flags |= Qt::ItemIsSelectable) ^= Qt::ItemIsSelectable; 0228 item->setFlags(flags); 0229 } 0230 if (driverMetaData->isFileBased()) 0231 item->setIcon(0, d->fileicon); 0232 else 0233 item->setIcon(0, d->dbicon); 0234 } 0235 else { 0236 qWarning() << "no driver found for" << data->connectionData()->driverId(); 0237 } 0238 } 0239 list()->setSortingEnabled(true); 0240 list()->sortItems(0, Qt::AscendingOrder); 0241 list()->resizeColumnToContents(0); 0242 if (list()->topLevelItemCount() > 0) { 0243 list()->topLevelItem(0)->setSelected(true); 0244 } 0245 } 0246 0247 KexiProjectSet *KexiProjectSelectorWidget::projectSet() { 0248 return d->prj_set; 0249 } 0250 0251 void KexiProjectSelectorWidget::setSelectable(bool set) 0252 { 0253 if (d->selectable == set) 0254 return; 0255 d->selectable = set; 0256 //update items' state 0257 QTreeWidgetItemIterator it(list()); 0258 while (*it) { 0259 Qt::ItemFlags flags = (*it)->flags(); 0260 flags |= Qt::ItemIsSelectable; 0261 if (!d->selectable) 0262 flags ^= Qt::ItemIsSelectable; 0263 (*it)->setFlags(flags); 0264 } 0265 } 0266 0267 bool KexiProjectSelectorWidget::isSelectable() const 0268 { 0269 return d->selectable; 0270 } 0271 0272 QLabel *KexiProjectSelectorWidget::label() const 0273 { 0274 return Ui_KexiProjectSelector::label; 0275 } 0276 0277 QTreeWidget* KexiProjectSelectorWidget::list() const 0278 { 0279 return Ui_KexiProjectSelector::list; 0280 } 0281 0282 bool KexiProjectSelectorWidget::eventFilter(QObject* watched, QEvent* event) 0283 { 0284 if (event->type() == QEvent::KeyPress) { 0285 QKeyEvent *ke = static_cast<QKeyEvent*>(event); 0286 if ((ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return) 0287 && ke->modifiers() == Qt::NoModifier) 0288 { 0289 slotItemExecuted(); 0290 return true; 0291 } 0292 } 0293 return QWidget::eventFilter(watched, event); 0294 } 0295 0296 /*================================================================*/ 0297 0298 KexiProjectSelectorDialog::KexiProjectSelectorDialog(QWidget *parent, 0299 const KDbConnectionData& cdata, 0300 bool showProjectNameColumn, bool showConnectionColumns) 0301 : KPageDialog(parent) 0302 , d(new Private) 0303 { 0304 setWindowTitle(xi18nc("@title:window", "Open Project")); 0305 KDbConnectionData _cdata(cdata); 0306 // errors are handled in KexiStartupHandler::selectProject() ... 0307 KexiProjectSet *prj_set = new KexiProjectSet; 0308 init(prj_set, showProjectNameColumn, showConnectionColumns); 0309 KGuiItem okItem(xi18nc("@action:button", "&Open"), koIconName("document-open"), 0310 xi18n("Open Database Connection")); 0311 KGuiItem::assign(button(QDialogButtonBox::Ok), okItem); 0312 0313 d->sel->label()->setText( 0314 xi18n("Select a project on <resource>%1</resource> database server to open:", 0315 _cdata.toUserVisibleString(KDbConnectionData::UserVisibleStringOption::None))); 0316 } 0317 0318 KexiProjectSelectorDialog::~KexiProjectSelectorDialog() 0319 { 0320 delete d; 0321 } 0322 0323 void KexiProjectSelectorDialog::init(KexiProjectSet* prj_set, bool showProjectNameColumn, 0324 bool showConnectionColumns) 0325 { 0326 setObjectName("KexiProjectSelectorDialog"); 0327 setModal(true); 0328 setStandardButtons( 0329 #ifdef KEXI_SHOW_UNFINISHED 0330 //! @todo re-add Help when doc is available 0331 QDialogButtonBox::Help | 0332 #endif 0333 QDialogButtonBox::Ok | QDialogButtonBox::Cancel 0334 ); 0335 button(QDialogButtonBox::Ok)->setDefault(true); 0336 setFaceType(Plain); 0337 setSizeGripEnabled(true); 0338 0339 d->sel = new KexiProjectSelectorWidget(this, prj_set, 0340 showProjectNameColumn, showConnectionColumns); 0341 //! @todo KEXI3 test this 0342 addPage(d->sel, QString()); 0343 setWindowIcon(d->sel->windowIcon()); 0344 d->sel->setFocus(); 0345 0346 connect(d->sel, SIGNAL(projectExecuted(KexiProjectData*)), 0347 this, SLOT(slotProjectExecuted(KexiProjectData*))); 0348 connect(d->sel, SIGNAL(selectionChanged(KexiProjectData*)), 0349 this, SLOT(slotProjectSelectionChanged(KexiProjectData*))); 0350 } 0351 0352 KexiProjectData* KexiProjectSelectorDialog::selectedProjectData() const 0353 { 0354 return d->sel->selectedProjectData(); 0355 } 0356 0357 void KexiProjectSelectorDialog::slotProjectExecuted(KexiProjectData*) 0358 { 0359 accept(); 0360 } 0361 0362 void KexiProjectSelectorDialog::slotProjectSelectionChanged(KexiProjectData* pdata) 0363 { 0364 button(QDialogButtonBox::Ok)->setEnabled(pdata); 0365 } 0366 0367 void KexiProjectSelectorDialog::showEvent(QShowEvent * event) 0368 { 0369 KPageDialog::showEvent(event); 0370 //! @todo KPageDialog::centerOnScreen(this); 0371 } 0372 0373 KexiProjectSet* KexiProjectSelectorDialog::projectSet() const 0374 { 0375 return d->sel->projectSet(); 0376 }