KexiConnSelector.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003,2005 Jaroslaw Staniek <js@iidea.pl>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "KexiConnSelector.h"
21
22#include <kexidb/drivermanager.h>
23#include <kexidb/connectiondata.h>
24
25#include <kexi.h>
26#include "KexiConnSelectorBase.h"
27//#include "KexiOpenExistingFile.h"
28#include <widget/kexiprjtypeselector.h>
29#include <widget/kexidbconnectionwidget.h>
30
31#include <tdeapplication.h>
32#include <kiconloader.h>
33#include <kmimetype.h>
34#include <tdelocale.h>
35#include <kdebug.h>
36#include <tdeconfig.h>
37#include <kurlcombobox.h>
38#include <tdetoolbar.h>
39#include <tdepopupmenu.h>
40#include <tdetoolbarbutton.h>
41#include <tdeactionclasses.h>
42
43#include <tqlabel.h>
44#include <tqpushbutton.h>
45#include <tqlayout.h>
46#include <tqcheckbox.h>
47#include <tqtooltip.h>
48#include <tqtextedit.h>
49#include <tqgroupbox.h>
50#include <tqwidgetstack.h>
51#include <tqbuttongroup.h>
52
53ConnectionDataLVItem::ConnectionDataLVItem(KexiDB::ConnectionData *data,
54 const KexiDB::Driver::Info& info, TQListView *list)
55 : TQListViewItem(list)
56 , m_data(data)
57{
58 update(info);
59}
60
61ConnectionDataLVItem::~ConnectionDataLVItem()
62{
63}
64
65void ConnectionDataLVItem::update(const KexiDB::Driver::Info& info)
66{
67 setText(0, m_data->caption+" ");
68 const TQString &sfile = i18n("File");
69 TQString drvname = info.caption.isEmpty() ? m_data->driverName : info.caption;
70 if (info.fileBased)
71 setText(1, sfile + " ("+drvname+") " );
72 else
73 setText(1, drvname+" " );
74 setText(2, (info.fileBased ? (TQString("<")+sfile.lower()+">") : m_data->serverInfoString(true))+" " );
75}
76
77/*================================================================*/
78
80class KexiConnSelectorWidgetPrivate
81{
82public:
83 KexiConnSelectorWidgetPrivate()
84 : conn_sel_shown(false)
85 , file_sel_shown(false)
86 , confirmOverwrites(true)
87 {
88 }
89
90 TQWidget* openExistingWidget;
91 KexiPrjTypeSelector* prjTypeSelector;
92 TQString startDirOrVariable;
93 TQWidgetStack *stack;
94 TQGuardedPtr<KexiDBConnectionSet> conn_set;
96 bool conn_sel_shown;
97 bool file_sel_shown;
98 bool confirmOverwrites;
99};
100
101/*================================================================*/
102
104 const TQString& startDirOrVariable, TQWidget* parent, const char* name )
105 : TQWidget( parent, name )
106 ,d(new KexiConnSelectorWidgetPrivate())
107{
108 d->conn_set = &conn_set;
109 d->startDirOrVariable = startDirOrVariable;
110 TQString none, iconname = KMimeType::mimeType( KexiDB::Driver::defaultFileBasedDriverMimeType() )->icon(none,0);
111 const TQPixmap &icon = TDEGlobal::iconLoader()->loadIcon( iconname, TDEIcon::Desktop );
112 setIcon( icon );
113
114 TQVBoxLayout* globalLyr = new TQVBoxLayout( this );
115
116 //create header with radio buttons
117 d->openExistingWidget = new TQWidget(this, "openExistingWidget");
118 TQVBoxLayout* openExistingWidgetLyr = new TQVBoxLayout( d->openExistingWidget );
119// TQLabel* lbl = new TQLabel(i18n("<b>Select existing Kexi project to open:</b>"), openExistingWidget);
120// openExistingWidgetLyr->addWidget( lbl );
121 d->prjTypeSelector = new KexiPrjTypeSelector( d->openExistingWidget );
122 connect(d->prjTypeSelector->buttonGroup,TQ_SIGNAL(clicked(int)),this,TQ_SLOT(slotPrjTypeSelected(int)));
123 openExistingWidgetLyr->addWidget( d->prjTypeSelector );
124 openExistingWidgetLyr->addSpacing( KDialogBase::spacingHint() );
125 TQFrame* line = new TQFrame( d->openExistingWidget, "line" );
126 line->setFrameShape( TQFrame::HLine );
127 line->setFrameShadow( TQFrame::Sunken );
128 openExistingWidgetLyr->addWidget( line );
129 globalLyr->addWidget(d->openExistingWidget);
130
131 d->stack = new TQWidgetStack(this, "stack");
132 globalLyr->addWidget(d->stack);
133
134// m_file = new KexiOpenExistingFile( this, "KexiOpenExistingFile");
135// m_file->btn_advanced->setIconSet( SmallIconSet("1downarrow") );
136 m_fileDlg = 0;
137
138// addWidget(m_file);
139// connect(m_file->btn_advanced,TQ_SIGNAL(clicked()),this,TQ_SLOT(showAdvancedConn()));
140
141 m_remote = new KexiConnSelectorBase(d->stack, "conn_sel");
142 m_remote->icon->setPixmap( DesktopIcon("network") );
143 m_remote->icon->setFixedSize( m_remote->icon->pixmap()->size() );
144// m_remote->btn_back->setIconSet( SmallIconSet("1uparrow") );
145 connect(m_remote->btn_add, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotRemoteAddBtnClicked()));
146 connect(m_remote->btn_edit, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotRemoteEditBtnClicked()));
147 connect(m_remote->btn_remove, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotRemoteRemoveBtnClicked()));
148 TQToolTip::add(m_remote->btn_add, i18n("Add a new database connection"));
149 TQToolTip::add(m_remote->btn_edit, i18n("Edit selected database connection"));
150 TQToolTip::add(m_remote->btn_remove, i18n("Remove selected database connections"));
151 d->stack->addWidget(m_remote);
152 if (m_remote->layout())
153 m_remote->layout()->setMargin(0);
154// connect(m_remote->btn_back,TQ_SIGNAL(clicked()),this,TQ_SLOT(showSimpleConn()));
155 connect(m_remote->list,TQ_SIGNAL(doubleClicked(TQListViewItem*)),
156 this,TQ_SLOT(slotConnectionItemExecuted(TQListViewItem*)));
157 connect(m_remote->list,TQ_SIGNAL(returnPressed(TQListViewItem*)),
158 this,TQ_SLOT(slotConnectionItemExecuted(TQListViewItem*)));
159 connect(m_remote->list,TQ_SIGNAL(selectionChanged()),
160 this,TQ_SLOT(slotConnectionSelectionChanged()));
161}
162
163KexiConnSelectorWidget::~KexiConnSelectorWidget()
164{
165 delete d;
166}
167
168/*void KexiConnSelectorWidget::disconnectShowSimpleConnButton()
169{
170 m_remote->btn_back->disconnect(this,TQ_SLOT(showSimpleConn()));
171}*/
172
173void KexiConnSelectorWidget::showAdvancedConn()
174{
175 slotPrjTypeSelected(2);
176 d->prjTypeSelector->buttonGroup->setButton(2);
177}
178
179//void KexiConnSelectorWidget::showAdvancedConn()
180void KexiConnSelectorWidget::slotPrjTypeSelected(int id)
181{
182 if (id==1) {//file-based prj type
183 showSimpleConn();
184 }
185 else if (id==2) {//server-based prj type
186 if (!d->conn_sel_shown) {
187 d->conn_sel_shown=true;
188
189 //show connections (on demand):
190 for (KexiDB::ConnectionData::ListIterator it(d->conn_set->list()); it.current(); ++it) {
191 addConnectionData( it.current() );
192 // else {
193 //this error should be more verbose:
194 // kdWarning() << "KexiConnSelector::KexiConnSelector(): no driver found for '" << it.current()->driverName << "'!" << endl;
195 // }
196 }
197 if (m_remote->list->firstChild()) {
198 m_remote->list->setSelected(m_remote->list->firstChild(),true);
199 }
200 m_remote->descriptionEdit->setPaletteBackgroundColor(palette().active().background());
201 m_remote->descGroupBox->layout()->setMargin(2);
202 m_remote->list->setFocus();
203 slotConnectionSelectionChanged();
204 }
205 d->stack->raiseWidget(m_remote);
206 }
207}
208
209ConnectionDataLVItem* KexiConnSelectorWidget::addConnectionData( KexiDB::ConnectionData* data )
210{
211 const KexiDB::Driver::Info info( d->manager.driverInfo(data->driverName) );
212// if (!info.name.isEmpty()) {
213 return new ConnectionDataLVItem(data, info, m_remote->list);
214// }
215}
216
217void KexiConnSelectorWidget::showSimpleConn()
218{
219 d->prjTypeSelector->buttonGroup->setButton(1);
220 if (!d->file_sel_shown) {
221 d->file_sel_shown=true;
222 m_fileDlg = new KexiStartupFileDialog( d->startDirOrVariable, KexiStartupFileDialog::Opening,
223 d->stack, "openExistingFileDlg");
224 m_fileDlg->setConfirmOverwrites( d->confirmOverwrites );
225// static_cast<TQVBoxLayout*>(m_file->layout())->insertWidget( 2, m_fileDlg );
226 d->stack->addWidget(m_fileDlg);
227
228 for (TQWidget *w = parentWidget(true);w;w=w->parentWidget(true)) {
229 if (w->isDialog()) {
230//#ifndef TQ_WS_WIN
231 connect(m_fileDlg,TQ_SIGNAL(rejected()),static_cast<TQDialog*>(w),TQ_SLOT(reject()));
232//#endif
233// connect(m_fileDlg,TQ_SIGNAL(cancelled()),static_cast<TQDialog*>(w),TQ_SLOT(reject()));
234 break;
235 }
236 }
237 }
238 d->stack->raiseWidget(m_fileDlg);
239}
240
242{
243 return (d->stack->visibleWidget()==m_fileDlg) ? FileBased : ServerBased;
244}
245
246/*ConnectionDataLVItem* KexiConnSelectorWidget::selectedConnectionDataItem() const
247{
248 if (selectedConnectionType()!=KexiConnSelectorWidget::ServerBased)
249 return 0;
250 ConnectionDataLVItem *item = 0; // = static_cast<ConnectionDataLVItem*>(m_remote->list->selectedItem());
251 for (TQListViewItemIterator it(m_remote->list); it.current(); ++it) {
252 if (it.current()->isSelected()) {
253 if (item)
254 return 0; //multiple
255 item = static_cast<ConnectionDataLVItem*>(it.current());
256 }
257 }
258 return item;
259}*/
260
262{
263 ConnectionDataLVItem *item = static_cast<ConnectionDataLVItem*>(m_remote->list->selectedItem()); //ConnectionDataItem();
264 if (!item)
265 return 0;
266 return item->data();
267}
268
270{
271 if (selectedConnectionType()!=KexiConnSelectorWidget::FileBased)
272 return TQString();
273 return m_fileDlg->currentFileName();
274}
275
277{
278 if (selectedConnectionType()!=KexiConnSelectorWidget::FileBased)
279 return;
280 return m_fileDlg->setSelection(fileName);
281}
282
283void KexiConnSelectorWidget::slotConnectionItemExecuted(TQListViewItem *item)
284{
285 emit connectionItemExecuted(static_cast<ConnectionDataLVItem*>(item));
286}
287
288void KexiConnSelectorWidget::slotConnectionSelectionChanged()
289{
290 ConnectionDataLVItem* item = static_cast<ConnectionDataLVItem*>(m_remote->list->selectedItem());
291 //update buttons availability
292/* ConnectionDataLVItem *singleItem = 0;
293 bool multi = false;
294 for (TQListViewItemIterator it(m_remote->list); it.current(); ++it) {
295 if (it.current()->isSelected()) {
296 if (singleItem) {
297 singleItem = 0;
298 multi = true;
299 break;
300 }
301 else
302 singleItem = static_cast<ConnectionDataLVItem*>(it.current());
303 }
304 }*/
305 m_remote->btn_edit->setEnabled(item);
306 m_remote->btn_remove->setEnabled(item);
307 m_remote->descriptionEdit->setText(item ? item->data()->description : TQString());
308 emit connectionItemHighlighted(item);
309}
310
311TQListView* KexiConnSelectorWidget::connectionsList() const
312{
313 return m_remote->list;
314}
315
316void KexiConnSelectorWidget::setFocus()
317{
318 TQWidget::setFocus();
319 if (d->stack->visibleWidget()==m_fileDlg)
320 m_fileDlg->setFocus(); //m_fileDlg->locationWidget()->setFocus();
321 else
322 m_remote->list->setFocus();
323}
324
326{
327 d->openExistingWidget->hide();
328
329/* m_file->lbl->hide();
330 m_file->line->hide();
331 m_file->spacer->hide();
332 m_file->label->hide();
333 m_remote->label->hide();
334 m_remote->label_back->hide();
335 m_remote->btn_back->hide();
336 m_remote->icon->hide();*/
337}
338
340{
341 d->confirmOverwrites = set;
342 if (m_fileDlg)
343 m_fileDlg->setConfirmOverwrites( d->confirmOverwrites );
344}
345
346bool KexiConnSelectorWidget::confirmOverwrites() const
347{
348 return d->confirmOverwrites;
349}
350
351/*static TQString msgUnfinished() {
352 return i18n("To define or change a connection, use command line options or click on .kexis file. "
353 "You can find example .kexis file at <a href=\"%1\">here</a>.").arg("") //temporary, please do not change for 0.8!
354 + "\nhttp://www.kexi-project.org/resources/testdb.kexis"; */
355// .arg("http://websvn.kde.org/*checkout*/branches/kexi/0.9/koffice/kexi/tests/startup/testdb.kexis");
356//}
357
359{
361 KexiDBConnectionDialog dlg(data, TQString(),
362 KGuiItem(i18n("&Add"), "button_ok", i18n("Add database connection")) );
363 dlg.setCaption(i18n("Add New Database Connection"));
364 if (TQDialog::Accepted!=dlg.exec())
365 return;
366
367 //store this conn. data
368 KexiDB::ConnectionData *newData = new KexiDB::ConnectionData(*dlg.currentProjectData().connectionData());
369 if (!d->conn_set->addConnectionData(newData)) {
371 delete newData;
372 return;
373 }
374
375 ConnectionDataLVItem* item = addConnectionData(newData);
376// m_remote->list->clearSelection();
377 m_remote->list->setSelected(item, true);
378 slotConnectionSelectionChanged();
379}
380
382{
383 ConnectionDataLVItem* item = static_cast<ConnectionDataLVItem*>(m_remote->list->selectedItem());
384 if (!item)
385 return;
386 KexiDBConnectionDialog dlg(*item->data(), TQString(),
387 KGuiItem(i18n("&Save"), "document-save", i18n("Save changes made to this database connection")) );
388 dlg.setCaption(i18n("Edit Database Connection"));
389 if (TQDialog::Accepted!=dlg.exec())
390 return;
391
392 KexiDB::ConnectionData *newData = new KexiDB::ConnectionData( *dlg.currentProjectData().connectionData() );
393 if (!d->conn_set->saveConnectionData(item->data(), newData)) {
395 delete newData;
396 return;
397 }
398 const KexiDB::Driver::Info info( d->manager.driverInfo(item->data()->driverName) );
399 item->update(info);
400 slotConnectionSelectionChanged(); //to update descr. edit
401}
402
403void KexiConnSelectorWidget::slotRemoteRemoveBtnClicked()
404{
405 ConnectionDataLVItem* item = static_cast<ConnectionDataLVItem*>(m_remote->list->selectedItem());
406 if (!item)
407 return;
408 if (KMessageBox::Continue!=KMessageBox::warningContinueCancel(0,
409 i18n("Do you want to remove database connection \"%1\" from the list of available connections?")
410 .arg(item->data()->serverInfoString(true)), TQString(), KStdGuiItem::del(), TQString(),
411 KMessageBox::Notify|KMessageBox::Dangerous))
412 return;
413
414 TQListViewItem* nextItem = item->itemBelow();
415 if (!nextItem)
416 nextItem = item->itemAbove();
417 if (!d->conn_set->removeConnectionData(item->data()))
418 return;
419
420 m_remote->list->removeItem(item);
421 if (nextItem)
422 m_remote->list->setSelected(nextItem, true);
423 slotConnectionSelectionChanged();
424}
425
426void KexiConnSelectorWidget::hideConnectonIcon()
427{
428 m_remote->icon->setFixedWidth(0);
429 m_remote->icon->setPixmap(TQPixmap());
430}
431
432#include "KexiConnSelector.moc"
void setConfirmOverwrites(bool set)
KexiDB::ConnectionData * selectedConnectionData() const
void setSelectedFileName(const TQString &fileName)
KexiConnSelectorWidget(KexiDBConnectionSet &conn_set, const TQString &startDirOrVariable, TQWidget *parent=0, const char *name=0)
TQString caption
The caption of the connection.
TQString description
The additional description for the connection.
TQString driverName
the name of the driver that should be used to create a connection
Database specific connection data, e.g. host, port.
TQString serverInfoString(bool addUser=true) const
A user-friendly string for the server.
Database driver management, e.g. finding and loading drivers.
bool fileBased
true is the driver is for file-based database backend
Definition driver.h:78
static TQString defaultFileBasedDriverMimeType()
Definition driver.cpp:137
A simple widget with radio buttons with "show file/server-based projects" options.
Widget for opening/saving files supported by Kexi.
void setConfirmOverwrites(bool set)