kselectdatabasedlg.cpp 8.86 KB
Newer Older
Alvaro Soliverez's avatar
Alvaro Soliverez committed
1
2
3
/***************************************************************************
                          kselectdatabasedlg.cpp
                             -------------------
4
    copyright            : (C) 2005 by Tony Bloomfield <tonybloom@users.sourceforge.net>
5
                           (C) 2017 by Thomas Baumgart <tbaumgart@kde.org>
6
                           (C) 2017 by Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
7
8

***************************************************************************/
Alvaro Soliverez's avatar
Alvaro Soliverez committed
9
10
11
12
13
14
15
16
17

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
Cristian Oneț's avatar
Cristian Oneț committed
18

Tony Bloomfield's avatar
Tony Bloomfield committed
19
#include "kselectdatabasedlg.h"
Alvaro Soliverez's avatar
Alvaro Soliverez committed
20
21
22
23

// ----------------------------------------------------------------------------
// QT Includes

24
#include <QUrlQuery>
Alvaro Soliverez's avatar
Alvaro Soliverez committed
25
26
27
28

// ----------------------------------------------------------------------------
// KDE Includes

29
30
#include <KMessageBox>
#include <KHelpClient>
Cristian Oneț's avatar
Cristian Oneț committed
31

Alvaro Soliverez's avatar
Alvaro Soliverez committed
32
33
34
// ----------------------------------------------------------------------------
// Project Includes

Łukasz Wojniłowicz's avatar
Łukasz Wojniłowicz committed
35
36
#include "ui_kselectdatabasedlg.h"
#include "kguiutils.h"
Łukasz Wojniłowicz's avatar
Łukasz Wojniłowicz committed
37
38
#include "mymoneystoragesql.h"
#include "mymoneydbdriver.h"
39
#include "misc/platformtools.h"
40
#include "passwordtoggle.h"
Łukasz Wojniłowicz's avatar
Łukasz Wojniłowicz committed
41

Cristian Oneț's avatar
Cristian Oneț committed
42
KSelectDatabaseDlg::KSelectDatabaseDlg(int openMode, QUrl openURL, QWidget *)
43
44
45
  : m_widget(new Ui::KSelectDatabaseDlg())
  , m_mode(openMode)
  , m_url(openURL)
Łukasz Wojniłowicz's avatar
Łukasz Wojniłowicz committed
46
  , m_requiredFields(new KMandatoryFieldGroup(this))
47
  , m_sqliteSelected(false)
48
{
49
50
51
52
53
54
55
56
  m_widget->setupUi(this);

  connect(m_widget->buttonBox, &QDialogButtonBox::accepted, this, &KSelectDatabaseDlg::accept);
  connect(m_widget->buttonBox, &QDialogButtonBox::rejected, this, &KSelectDatabaseDlg::reject);
  connect(m_widget->buttonBox->button(QDialogButtonBox::Help), &QPushButton::clicked, this, &KSelectDatabaseDlg::slotHelp);

  m_requiredFields->setOkButton(m_widget->buttonBox->button(QDialogButtonBox::Ok));

57
  m_widget->checkPreLoad->setEnabled(openMode == QIODevice::ReadWrite);
58

59
  new PasswordToggle(m_widget->textPassword);
60
61
}

62
63
KSelectDatabaseDlg::~KSelectDatabaseDlg()
{
64
65
}

66
67
bool KSelectDatabaseDlg::checkDrivers()
{
68
69
70
71
72
  QString driverName;
  if (m_url != QUrl()) {
    driverName = QUrlQuery(m_url).queryItemValue("driver");
  }

Alvaro Soliverez's avatar
Alvaro Soliverez committed
73
  // list drivers supported by KMM
74
  QMap<QString, QString> map = MyMoneyDbDriver::driverMap();
Alvaro Soliverez's avatar
Alvaro Soliverez committed
75
76
  // list drivers installed on system
  QStringList list = QSqlDatabase::drivers();
77
78
79
80
81
82

  // clear out the current list of drivers
  while(m_widget->databaseTypeCombo->count()) {
    m_widget->databaseTypeCombo->removeItem(0);
  }

83
84
  // join the two
  QStringList::Iterator it = list.begin();
85
  bool driverSupported = false;
86
  while (it != list.end()) {
87
88
    QString dname = *it;
    if (map.keys().contains(dname)) { // only keep if driver is supported
89
90
91
92
      m_widget->databaseTypeCombo->addItem(map[dname], dname);
      if (driverName == dname) {
        driverSupported = true;
      }
93
    }
94
    it++;
95
  }
96
97
  if (!driverName.isEmpty() && !driverSupported) {
    KMessageBox::error(0, i18n("Qt SQL driver %1 is no longer installed on your system", driverName),
98
                         "");
99
    return false;
100
  }
101
102

  if (m_widget->databaseTypeCombo->count() == 0) {
103
    // why does KMessageBox not have a standard dialog with Help button?
104
    if ((KMessageBox::questionYesNo(this,
105
106
107
                                    i18n("In order to use a database, you need to install some additional software. Click Help for more information"),
                                    i18n("No Qt SQL Drivers"),
                                    KStandardGuiItem::help(), KStandardGuiItem::cancel()))
108
        == KMessageBox::Yes) { // Yes stands in for help here
Cristian Oneț's avatar
Cristian Oneț committed
109
      KHelpClient::invokeHelp("details.database.usage");
Alvaro Soliverez's avatar
Alvaro Soliverez committed
110
    }
111
    return false;
112
  }
113
  return true;
114
115
}

116
117
int KSelectDatabaseDlg::exec()
{
118
  m_requiredFields->removeAll();
Cristian Oneț's avatar
Cristian Oneț committed
119
  if (m_url == QUrl()) {
120
121
122
    m_widget->textDbName->setText(QLatin1String("KMyMoney"));
    m_widget->textHostName->setText(QLatin1String("localhost"));
    m_widget->textUserName->setText(QString());
123
    m_widget->textUserName->setText(platformTools::osUsername());
124
    m_widget->textPassword->setText(QString());
125
    connect(m_widget->databaseTypeCombo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &KSelectDatabaseDlg::slotDriverSelected);
Tony Bloomfield's avatar
Tony Bloomfield committed
126
    m_widget->checkPreLoad->setChecked(false);
127
128
129
130
    // ensure a driver gets selected; pre-select the first one
    if (m_widget->databaseTypeCombo->count() != 0) {
      m_widget->databaseTypeCombo->setCurrentIndex(0);
      slotDriverSelected(0);
131
    }
Tony Bloomfield's avatar
Tony Bloomfield committed
132
133
  } else {
    // fill in the fixed data from the URL
Cristian Oneț's avatar
Cristian Oneț committed
134
    QString driverName = QUrlQuery(m_url).queryItemValue("driver");
135
136
    int idx = m_widget->databaseTypeCombo->findData(driverName);
    m_widget->databaseTypeCombo->setCurrentIndex(idx);
137
    QString dbName = m_url.path().right(m_url.path().length() - 1); // remove separator slash
138
139
    m_widget->textDbName->setText(dbName);
    m_widget->textHostName->setText(m_url.host());
Cristian Oneț's avatar
Cristian Oneț committed
140
    m_widget->textUserName->setText(m_url.userName());
Tony Bloomfield's avatar
Tony Bloomfield committed
141
    // disable all but the password field, coz that's why we're here
Tony Bloomfield's avatar
Tony Bloomfield committed
142
    m_widget->textDbName->setEnabled(false);
Tony Bloomfield's avatar
Tony Bloomfield committed
143
    m_widget->urlSqlite->setEnabled(false);
144
    m_widget->databaseTypeCombo->setEnabled(false);
Tony Bloomfield's avatar
Tony Bloomfield committed
145
146
147
148
    m_widget->textHostName->setEnabled(false);
    m_widget->textUserName->setEnabled(false);
    m_widget->textPassword->setEnabled(true);
    m_widget->textPassword->setFocus();
149
    // set password required
Tony Bloomfield's avatar
Tony Bloomfield committed
150
    m_requiredFields->add(m_widget->textPassword);
Tony Bloomfield's avatar
Tony Bloomfield committed
151

Tony Bloomfield's avatar
Tony Bloomfield committed
152
    m_widget->checkPreLoad->setChecked(false);
Fernando Vilas's avatar
Fernando Vilas committed
153
    m_sqliteSelected = !m_widget->urlSqlite->text().isEmpty();
Alvaro Soliverez's avatar
Alvaro Soliverez committed
154
155
  }

156
  return QDialog::exec();
Alvaro Soliverez's avatar
Alvaro Soliverez committed
157
158
}

Cristian Oneț's avatar
Cristian Oneț committed
159
const QUrl KSelectDatabaseDlg::selectedURL()
160
{
Cristian Oneț's avatar
Cristian Oneț committed
161
162
163
164
  QUrl url;
  url.setScheme("sql");
  url.setUserName(m_widget->textUserName->text());
  url.setPassword(m_widget->textPassword->text());
Tony Bloomfield's avatar
Tony Bloomfield committed
165
  url.setHost(m_widget->textHostName->text());
166
  // set path which begins with a separator slash that will be removed when retrieved from path()
Tony Bloomfield's avatar
Tony Bloomfield committed
167
  if (m_sqliteSelected)
168
    url.setPath('/' + m_widget->urlSqlite->url().toLocalFile());
Tony Bloomfield's avatar
Tony Bloomfield committed
169
  else
170
    url.setPath('/' + m_widget->textDbName->text());
Alvaro Soliverez's avatar
Alvaro Soliverez committed
171
  QString qs = QString("driver=%1")
172
173
174
175
176
               .arg(m_widget->databaseTypeCombo->currentData().toString());
  if (m_widget->checkPreLoad->isChecked())
    qs.append("&options=loadAll");
  if (!m_widget->textPassword->text().isEmpty())
    qs.append("&secure=yes");
Alvaro Soliverez's avatar
Alvaro Soliverez committed
177
178
179
180
  url.setQuery(qs);
  return (url);
}

181
void KSelectDatabaseDlg::slotDriverSelected(int idx)
182
{
183
  QExplicitlySharedDataPointer<MyMoneyDbDriver> dbDriver = MyMoneyDbDriver::create(m_widget->databaseTypeCombo->itemData(idx).toString());
184
  if (!dbDriver->isTested()) {
185
186
187
188
    int rc = KMessageBox::warningContinueCancel(0,
             i18n("Database type %1 has not been fully tested in a KMyMoney environment.\n"
                  "Please make sure you have adequate backups of your data.\n"
                  "Please report any problems to the developer mailing list at "
189
                  "kmymoney-devel@kde.org", m_widget->databaseTypeCombo->currentText()),
190
             "");
Tony Bloomfield's avatar
Tony Bloomfield committed
191
192
193
194
195
    if (rc == KMessageBox::Cancel) {
      return;
    }
  }

196
197
  m_requiredFields->removeAll();

198
  if (dbDriver->requiresExternalFile()) {
199
    // currently, only sqlite requires an external file
Tony Bloomfield's avatar
Tony Bloomfield committed
200
    m_sqliteSelected = true;
201
    if (m_mode == QIODevice::WriteOnly) {
202
      m_widget->urlSqlite->setMode(KFile::Mode::File);
203
    } else {
204
      m_widget->urlSqlite->setMode(KFile::Mode::File | KFile::Mode::ExistingOnly);
205
    }
Tony Bloomfield's avatar
Tony Bloomfield committed
206

Tony Bloomfield's avatar
Tony Bloomfield committed
207
208
    m_widget->textDbName->setEnabled(false);
    m_widget->urlSqlite->setEnabled(true);
Tony Bloomfield's avatar
Tony Bloomfield committed
209
210
    // sqlite databases do not react to host/user/password;
    // file system permissions must be used
211
212
    m_widget->textHostName->setEnabled(false);
    m_widget->textUserName->setEnabled(false);
213
214
215

    // setup required fields last because the required widgets must be enabled
    m_requiredFields->add(m_widget->urlSqlite);
Tony Bloomfield's avatar
Tony Bloomfield committed
216
  } else {                         // not sqlite3
Tony Bloomfield's avatar
Tony Bloomfield committed
217
    m_sqliteSelected = false;
218

Tony Bloomfield's avatar
Tony Bloomfield committed
219
220
    m_widget->textDbName->setEnabled(true);
    m_widget->urlSqlite->setEnabled(false);
221
222
    m_widget->textUserName->setEnabled(true);
    m_widget->textHostName->setEnabled(true);
223
224
225
226
227

    // setup required fields last because the required widgets must be enabled
    m_requiredFields->add(m_widget->textDbName);
    m_requiredFields->add(m_widget->textHostName);
    m_requiredFields->add(m_widget->textUserName);
Alvaro Soliverez's avatar
Alvaro Soliverez committed
228
  }
229
  m_widget->textPassword->setEnabled(dbDriver->isPasswordSupported());
Alvaro Soliverez's avatar
Alvaro Soliverez committed
230
231
}

232
void KSelectDatabaseDlg::slotHelp()
233
{
Cristian Oneț's avatar
Cristian Oneț committed
234
  KHelpClient::invokeHelp("details.database.selectdatabase");
Alvaro Soliverez's avatar
Alvaro Soliverez committed
235
}