Changeset View
Changeset View
Standalone View
Standalone View
kexi/plugins/queries/kexiquerydesignersql.cpp
1 | /* This file is part of the KDE project | 1 | /* This file is part of the KDE project | ||
---|---|---|---|---|---|
2 | Copyright (C) 2003 Lucijan Busch <lucijan@kde.org> | 2 | Copyright (C) 2003 Lucijan Busch <lucijan@kde.org> | ||
3 | Copyright (C) 2004-2014 Jarosław Staniek <staniek@kde.org> | 3 | Copyright (C) 2004-2016 Jarosław Staniek <staniek@kde.org> | ||
4 | 4 | | |||
5 | This program is free software; you can redistribute it and/or | 5 | This program is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | 6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | 7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | 8 | version 2 of the License, or (at your option) any later version. | ||
9 | 9 | | |||
10 | This program is distributed in the hope that it will be useful, | 10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | 13 | Library General Public License for more details. | ||
14 | 14 | | |||
15 | You should have received a copy of the GNU Library General Public License | 15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this program; see the file COPYING. If not, write to | 16 | along with this program; see the file COPYING. If not, write to | ||
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | * Boston, MA 02110-1301, USA. | 18 | * Boston, MA 02110-1301, USA. | ||
19 | */ | 19 | */ | ||
20 | 20 | | |||
21 | #include "kexiquerydesignersql.h" | ||||
22 | #include "kexiquerydesignersqleditor.h" | ||||
23 | #include "kexiquerypart.h" | ||||
24 | #include "kexisectionheader.h" | ||||
25 | | ||||
21 | #include <QSplitter> | 26 | #include <QSplitter> | ||
22 | #include <QLayout> | 27 | #include <QLayout> | ||
23 | #include <QTimer> | 28 | #include <QTimer> | ||
24 | #include <QLabel> | 29 | #include <QLabel> | ||
25 | #include <QPalette> | 30 | #include <QPalette> | ||
26 | #include <QToolTip> | 31 | #include <QToolTip> | ||
27 | 32 | | |||
28 | #include <kdebug.h> | 33 | #include <kdebug.h> | ||
29 | #include <kmessagebox.h> | 34 | #include <kmessagebox.h> | ||
30 | #include <kaction.h> | 35 | #include <kaction.h> | ||
31 | #include <kdialog.h> | 36 | #include <kdialog.h> | ||
32 | 37 | | |||
33 | #include <KoIcon.h> | 38 | #include <KoIcon.h> | ||
34 | 39 | | |||
35 | #include <kexiutils/utils.h> | 40 | #include <kexiutils/utils.h> | ||
36 | #include <db/driver.h> | 41 | #include <db/driver.h> | ||
37 | #include <db/connection.h> | 42 | #include <db/connection.h> | ||
38 | #include <db/parser/parser.h> | 43 | #include <db/parser/parser.h> | ||
39 | 44 | | |||
40 | #include <kexiproject.h> | 45 | #include <kexiproject.h> | ||
41 | #include <KexiMainWindowIface.h> | 46 | #include <KexiMainWindowIface.h> | ||
42 | #include <KexiWindow.h> | 47 | #include <KexiWindow.h> | ||
43 | 48 | | |||
44 | #include "kexiquerydesignersqleditor.h" | | |||
45 | #include "kexiquerydesignersql.h" | | |||
46 | #include "kexiquerypart.h" | | |||
47 | | ||||
48 | #include "kexisectionheader.h" | | |||
49 | | ||||
50 | | ||||
51 | static bool compareSQL(const QString& sql1, const QString& sql2) | 49 | static bool compareSQL(const QString& sql1, const QString& sql2) | ||
52 | { | 50 | { | ||
53 | //! @todo use reformatting functions here | 51 | //! @todo use reformatting functions here | ||
54 | return sql1.trimmed() == sql2.trimmed(); | 52 | return sql1.trimmed() == sql2.trimmed(); | ||
55 | } | 53 | } | ||
56 | 54 | | |||
57 | //=================== | 55 | //=================== | ||
58 | 56 | | |||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Line(s) | 203 | //! @todo | |||
206 | dontStore = true; | 204 | dontStore = true; | ||
207 | if (mode == Kexi::DesignViewMode || mode == Kexi::DataViewMode) { | 205 | if (mode == Kexi::DesignViewMode || mode == Kexi::DataViewMode) { | ||
208 | QString sqlText = d->editor->text().trimmed(); | 206 | QString sqlText = d->editor->text().trimmed(); | ||
209 | KexiQueryPart::TempData * temp = tempData(); | 207 | KexiQueryPart::TempData * temp = tempData(); | ||
210 | const bool sqlTextIsEmpty = sqlText.isEmpty(); | 208 | const bool sqlTextIsEmpty = sqlText.isEmpty(); | ||
211 | if (sqlTextIsEmpty && mode == Kexi::DesignViewMode) { | 209 | if (sqlTextIsEmpty && mode == Kexi::DesignViewMode) { | ||
212 | //special case: empty SQL text, allow to switch to the design view | 210 | //special case: empty SQL text, allow to switch to the design view | ||
213 | if (temp->query()) { | 211 | if (temp->query()) { | ||
214 | temp->setQueryChangedInPreviousView(true); //query changed | 212 | temp->setQueryChangedInView(true); //query changed | ||
215 | temp->setQuery(0); | 213 | temp->setQuery(0); | ||
216 | } | 214 | } | ||
217 | } | 215 | } | ||
218 | else { | 216 | else { | ||
219 | const bool designViewWasVisible = window()->viewForMode(mode) != 0; | 217 | const bool designViewWasVisible = window()->viewForMode(mode) != 0; | ||
220 | //should we check SQL text? | 218 | //should we check SQL text? | ||
221 | if (designViewWasVisible | 219 | if (designViewWasVisible | ||
222 | && !sqlTextIsEmpty //for empty text always show error | 220 | && !sqlTextIsEmpty //for empty text always show error | ||
223 | && !d->justSwitchedFromNoViewMode //unchanged, but we should check SQL text | 221 | && !d->justSwitchedFromNoViewMode //unchanged, but we should check SQL text | ||
224 | && compareSQL(d->origStatement, d->editor->text())) | 222 | && compareSQL(d->origStatement, d->editor->text())) | ||
225 | { | 223 | { | ||
226 | //statement unchanged! - nothing to do | 224 | //statement unchanged! - nothing to do | ||
227 | temp->setQueryChangedInPreviousView(false); | 225 | temp->setQueryChangedInView(false); | ||
228 | } else { | 226 | } else { | ||
229 | //yes: parse SQL text | 227 | //yes: parse SQL text | ||
230 | if (sqlTextIsEmpty || !slotCheckQuery()) { | 228 | if (sqlTextIsEmpty || !slotCheckQuery()) { | ||
231 | if (KMessageBox::No == KMessageBox::warningYesNo(this, | 229 | if (KMessageBox::No == KMessageBox::warningYesNo(this, | ||
232 | "<p>" + i18n("The query you entered is incorrect.") | 230 | "<p>" + i18n("The query you entered is incorrect.") | ||
233 | + "</p><p>" + i18n("Do you want to cancel any changes made to this SQL text?") + "</p>" | 231 | + "</p><p>" + i18n("Do you want to cancel any changes made to this SQL text?") + "</p>" | ||
234 | + "</p><p>" + i18n("Answering \"No\" allows you to make corrections.") + "</p>")) { | 232 | + "</p><p>" + i18n("Answering \"No\" allows you to make corrections.") + "</p>")) { | ||
235 | return cancelled; | 233 | return cancelled; | ||
236 | } | 234 | } | ||
237 | //do not change original query - it's invalid | 235 | //do not change original query - it's invalid | ||
238 | temp->setQueryChangedInPreviousView(false); | 236 | temp->setQueryChangedInView(false); | ||
239 | //this view is no longer _just_ switched from "NoViewMode" | 237 | //this view is no longer _just_ switched from "NoViewMode" | ||
240 | d->justSwitchedFromNoViewMode = false; | 238 | d->justSwitchedFromNoViewMode = false; | ||
241 | return true; | 239 | return true; | ||
242 | } | 240 | } | ||
243 | //this view is no longer _just_ switched from "NoViewMode" | 241 | //this view is no longer _just_ switched from "NoViewMode" | ||
244 | d->justSwitchedFromNoViewMode = false; | 242 | d->justSwitchedFromNoViewMode = false; | ||
245 | //replace old query schema with new one | 243 | //replace old query schema with new one | ||
246 | temp->setQuery(d->parsedQuery); //this will also delete temp->query() | 244 | temp->setQuery(d->parsedQuery); //this will also delete temp->query() | ||
247 | d->parsedQuery = 0; | 245 | d->parsedQuery = 0; | ||
248 | temp->setQueryChangedInPreviousView(true); | 246 | temp->setQueryChangedInView(true); | ||
249 | } | 247 | } | ||
250 | } | 248 | } | ||
251 | d->origStatement = d->editor->text(); | 249 | d->origStatement = d->editor->text(); | ||
252 | } | 250 | } | ||
253 | 251 | | |||
254 | d->editor->setFocus(); | 252 | d->editor->setFocus(); | ||
255 | return true; | 253 | return true; | ||
256 | } | 254 | } | ||
Show All 17 Lines | 258 | { | |||
274 | if (mode != 0/*failure only if it is switching from prev. view*/ && !query) { | 272 | if (mode != 0/*failure only if it is switching from prev. view*/ && !query) { | ||
275 | //! @todo msg | 273 | //! @todo msg | ||
276 | return false; | 274 | return false; | ||
277 | } | 275 | } | ||
278 | 276 | | |||
279 | if (query) { | 277 | if (query) { | ||
280 | // Use query with Kexi keywords (but not driver-specific keywords) escaped. | 278 | // Use query with Kexi keywords (but not driver-specific keywords) escaped. | ||
281 | temp->setQuery(query); | 279 | temp->setQuery(query); | ||
282 | if (temp->queryChangedInPreviousView()) { | 280 | if (temp->queryChangedInView() != Kexi::NoViewMode) { | ||
283 | KexiDB::Connection::SelectStatementOptions options; | 281 | KexiDB::Connection::SelectStatementOptions options; | ||
284 | options.identifierEscaping = KexiDB::Driver::EscapeKexi; | 282 | options.identifierEscaping = KexiDB::Driver::EscapeKexi; | ||
285 | options.addVisibleLookupColumns = false; | 283 | options.addVisibleLookupColumns = false; | ||
286 | d->origStatement = KexiDB::selectStatement(0, *query, options).trimmed(); | 284 | d->origStatement = KexiDB::selectStatement(0, *query, options).trimmed(); | ||
287 | } | 285 | } | ||
288 | } | 286 | } | ||
289 | if (d->origStatement.isEmpty() && !window()->partItem()->neverSaved()) { | 287 | if (d->origStatement.isEmpty() && !window()->partItem()->neverSaved()) { | ||
290 | //no valid query delivered or query has not been modified: | 288 | //no valid query delivered or query has not been modified: | ||
291 | // just load sql text, no matter if it's valid | 289 | // just load sql text, no matter if it's valid | ||
292 | if (!loadDataBlock(d->origStatement, "sql", true /*canBeEmpty*/)) | 290 | if (!loadDataBlock(d->origStatement, "sql", true /*canBeEmpty*/)) | ||
293 | return false; | 291 | return false; | ||
294 | } | 292 | } | ||
295 | 293 | | |||
294 | if (temp->queryChangedInView() == Kexi::DesignViewMode /* true in this scenario: | ||||
295 | - user switched from SQL to Design, | ||||
296 | - changed the design, | ||||
297 | - switched to Data | ||||
298 | - switched back to SQL */ | ||||
299 | || mode != Kexi::DataViewMode) /* true in this scenario: user switched from No-view | ||||
300 | or Design view */ | ||||
301 | { | ||||
296 | if (!compareSQL(d->origStatement, d->editor->text())) { | 302 | if (!compareSQL(d->origStatement, d->editor->text())) { | ||
297 | d->slotTextChangedEnabled = false; | 303 | d->slotTextChangedEnabled = false; | ||
298 | d->editor->setText(d->origStatement); | 304 | d->editor->setText(d->origStatement); | ||
299 | d->slotTextChangedEnabled = true; | 305 | d->slotTextChangedEnabled = true; | ||
300 | } | 306 | } | ||
307 | } | ||||
301 | QTimer::singleShot(100, d->editor, SLOT(setFocus())); | 308 | QTimer::singleShot(100, d->editor, SLOT(setFocus())); | ||
302 | return true; | 309 | return true; | ||
303 | } | 310 | } | ||
304 | 311 | | |||
305 | QString KexiQueryDesignerSQLView::sqlText() const | 312 | QString KexiQueryDesignerSQLView::sqlText() const | ||
306 | { | 313 | { | ||
307 | return d->editor->text(); | 314 | return d->editor->text(); | ||
308 | } | 315 | } | ||
▲ Show 20 Lines • Show All 137 Lines • Show Last 20 Lines |