21#include <tqsplitter.h>
27#include <tdeapplication.h>
29#include <tdemessagebox.h>
30#include <kiconloader.h>
32#include <kexiutils/utils.h>
33#include <kexidb/driver.h>
34#include <kexidb/connection.h>
35#include <kexidb/parser/parser.h>
37#include <kexiproject.h>
38#include <keximainwindow.h>
40#include "kexiquerydesignersqleditor.h"
41#include "kexiquerydesignersqlhistory.h"
42#include "kexiquerydesignersql.h"
43#include "kexiquerypart.h"
45#include "kexisectionheader.h"
48static bool compareSQL(
const TQString& sql1,
const TQString& sql2)
51 return sql1.stripWhiteSpace()==sql2.stripWhiteSpace();
57class KexiQueryDesignerSQLView::Private
63 , statusPixmapOk( DesktopIcon(
"button_ok") )
64 , statusPixmapErr( DesktopIcon(
"button_cancel") )
65 , statusPixmapInfo( DesktopIcon(
"messagebox_info") )
67 , heightForStatusMode(-1)
68 , heightForHistoryMode(-1)
69 , eventFilterForSplitterEnabled(true)
70 , justSwitchedFromNoViewMode(false)
71 , slotTextChangedEnabled(true)
75 KexiQueryDesignerSQLHistory *history;
76 TQLabel *pixmapStatus, *lblStatus;
78 TQVBox *history_section;
79 KexiSectionHeader *head, *historyHead;
80 TQPixmap statusPixmapOk, statusPixmapErr, statusPixmapInfo;
82 TDEToggleAction *action_toggle_history;
87 TQString origStatement;
89 int heightForStatusMode, heightForHistoryMode;
91 bool action_toggle_history_was_checked : 1;
93 bool eventFilterForSplitterEnabled : 1;
95 bool justSwitchedFromNoViewMode : 1;
97 bool slotTextChangedEnabled : 1;
102KexiQueryDesignerSQLView::KexiQueryDesignerSQLView(
KexiMainWindow *mainWin, TQWidget *parent,
const char *name)
106 d->splitter =
new TQSplitter(
this);
107 d->splitter->setOrientation(TQt::Vertical);
108 d->head =
new KexiSectionHeader(i18n(
"SQL Query Text"),TQt::Vertical, d->splitter);
111 connect(d->editor, TQ_SIGNAL(textChanged()),
this, TQ_SLOT(slotTextChanged()));
112 addChildView(d->editor);
113 setViewWidget(d->editor);
114 d->splitter->setFocusProxy(d->editor);
115 setFocusProxy(d->editor);
117 d->history_section =
new TQVBox(d->splitter);
119 d->status_hbox =
new TQHBox(d->history_section);
120 d->status_hbox->installEventFilter(
this);
121 d->splitter->setResizeMode(d->history_section, TQSplitter::KeepSize);
122 d->status_hbox->setSpacing(0);
123 d->pixmapStatus =
new TQLabel(d->status_hbox);
124 d->pixmapStatus->setFixedWidth(d->statusPixmapOk.width()*3/2);
125 d->pixmapStatus->setAlignment(AlignHCenter | AlignTop);
126 d->pixmapStatus->setMargin(d->statusPixmapOk.width()/4);
127 d->pixmapStatus->setPaletteBackgroundColor( palette().active().color(TQColorGroup::Base) );
129 d->lblStatus =
new TQLabel(d->status_hbox);
130 d->lblStatus->setAlignment(AlignLeft | AlignTop | WordBreak);
131 d->lblStatus->setMargin(d->statusPixmapOk.width()/4);
132 d->lblStatus->setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Expanding );
133 d->lblStatus->resize(d->lblStatus->width(),d->statusPixmapOk.width()*3);
134 d->lblStatus->setPaletteBackgroundColor( palette().active().color(TQColorGroup::Base) );
136 TQHBoxLayout *b =
new TQHBoxLayout(
this);
137 b->addWidget(d->splitter);
139 plugSharedAction(
"querypart_check_query",
this, TQ_SLOT(slotCheckQuery()));
140 plugSharedAction(
"querypart_view_toggle_history",
this, TQ_SLOT(slotUpdateMode()));
141 d->action_toggle_history =
static_cast<TDEToggleAction*
>( sharedAction(
"querypart_view_toggle_history" ) );
143 d->historyHead =
new KexiSectionHeader(i18n(
"SQL Query History"),TQt::Vertical, d->history_section);
144 d->historyHead->installEventFilter(
this);
145 d->history =
new KexiQueryDesignerSQLHistory(d->historyHead,
"sql_history");
147 static const TQString msg_back = i18n(
"Back to Selected Query");
148 static const TQString msg_clear = i18n(
"Clear History");
149 d->historyHead->addButton(
"select_item", msg_back,
this, TQ_SLOT(slotSelectQuery()));
150 d->historyHead->addButton(
"edit-clear", msg_clear, d->history, TQ_SLOT(clear()));
151 d->history->popupMenu()->insertItem(SmallIcon(
"select_item"), msg_back,
this, TQ_SLOT(slotSelectQuery()));
152 d->history->popupMenu()->insertItem(SmallIcon(
"edit-clear"), msg_clear, d->history, TQ_SLOT(clear()));
153 connect(d->history, TQ_SIGNAL(currentItemDoubleClicked()),
this, TQ_SLOT(slotSelectQuery()));
155 d->heightForHistoryMode = -1;
157 d->action_toggle_history_was_checked = !d->action_toggle_history->isChecked();
162KexiQueryDesignerSQLView::~KexiQueryDesignerSQLView()
172void KexiQueryDesignerSQLView::setStatusOk()
174 d->pixmapStatus->setPixmap(d->statusPixmapOk);
175 setStatusText(
"<h2>"+i18n(
"The query is correct")+
"</h2>");
176 d->history->addEvent(d->editor->text().stripWhiteSpace(),
true, TQString());
179void KexiQueryDesignerSQLView::setStatusError(
const TQString& msg)
181 d->pixmapStatus->setPixmap(d->statusPixmapErr);
182 setStatusText(
"<h2>"+i18n(
"The query is incorrect")+
"</h2><p>"+msg+
"</p>");
183 d->history->addEvent(d->editor->text().stripWhiteSpace(),
false, msg);
186void KexiQueryDesignerSQLView::setStatusEmpty()
188 d->pixmapStatus->setPixmap(d->statusPixmapInfo);
189 setStatusText(i18n(
"Please enter your query and execute \"Check query\" function to verify it."));
192void KexiQueryDesignerSQLView::setStatusText(
const TQString& text)
194 if (!d->action_toggle_history->isChecked()) {
195 TQSimpleRichText rt(text, d->lblStatus->font());
196 rt.setWidth(d->lblStatus->width());
197 TQValueList<int> sz = d->splitter->sizes();
198 const int newHeight = rt.height()+d->lblStatus->margin()*2;
199 if (sz[1]<newHeight) {
201 d->splitter->setSizes(sz);
203 d->lblStatus->setText(text);
212 if (mode==Kexi::DesignViewMode || mode==Kexi::DataViewMode) {
213 TQString sqlText = d->editor->text().stripWhiteSpace();
215 if (sqlText.isEmpty()) {
227 if (designViewWasVisible
228 && !d->justSwitchedFromNoViewMode
229 && compareSQL(d->origStatement, d->editor->text())) {
236 if (KMessageBox::No==KMessageBox::warningYesNo(
this,
"<p>"+i18n(
"The query you entered is incorrect.")
237 +
"</p><p>"+i18n(
"Do you want to cancel any changes made to this SQL text?")+
"</p>"
238 +
"</p><p>"+i18n(
"Answering \"No\" allows you to make corrections.")+
"</p>"))
245 d->justSwitchedFromNoViewMode =
false;
249 d->justSwitchedFromNoViewMode =
false;
278 d->editor->setFocus();
285 kdDebug() <<
"KexiQueryDesignerSQLView::afterSwitchFrom()" << endl;
291 d->justSwitchedFromNoViewMode =
true;
299 if (mode!=0 && !query) {
317 d->origStatement = conn->
selectStatement(*query, options).stripWhiteSpace();
320 d->slotTextChangedEnabled =
false;
321 d->editor->setText( d->origStatement );
322 d->slotTextChangedEnabled =
true;
323 TQTimer::singleShot(100, d->editor, TQ_SLOT(setFocus()));
328KexiQueryDesignerSQLView::sqlText()
const
330 return d->editor->text();
335 TQString sqlText( d->editor->text().stripWhiteSpace() );
336 if (sqlText.isEmpty()) {
337 delete d->parsedQuery;
343 kdDebug() <<
"KexiQueryDesignerSQLView::slotCheckQuery()" << endl;
346 const bool ok = parser->parse( sqlText );
347 delete d->parsedQuery;
348 d->parsedQuery = parser->query();
349 if (!d->parsedQuery || !ok || !parser->error().type().isEmpty()) {
351 setStatusError(err.
error());
352 d->editor->jump(err.
at());
353 delete d->parsedQuery;
362void KexiQueryDesignerSQLView::slotUpdateMode()
364 if (d->action_toggle_history->isChecked() == d->action_toggle_history_was_checked)
367 d->eventFilterForSplitterEnabled =
false;
369 TQValueList<int> sz = d->splitter->sizes();
370 d->action_toggle_history_was_checked = d->action_toggle_history->isChecked();
371 int heightToSet = -1;
372 if (d->action_toggle_history->isChecked()) {
373 d->status_hbox->hide();
374 d->historyHead->show();
376 if (d->heightForHistoryMode==-1)
377 d->heightForHistoryMode = m_dialog->height() / 2;
378 heightToSet = d->heightForHistoryMode;
379 d->heightForStatusMode = sz[1];
383 d->historyHead->hide();
384 d->status_hbox->show();
385 if (d->heightForStatusMode>=0) {
386 heightToSet = d->heightForStatusMode;
388 d->heightForStatusMode = d->status_hbox->height();
390 if (d->heightForHistoryMode>=0)
391 d->heightForHistoryMode = sz[1];
394 if (heightToSet>=0) {
396 d->splitter->setSizes(sz);
398 d->eventFilterForSplitterEnabled =
true;
402void KexiQueryDesignerSQLView::slotTextChanged()
404 if (!d->slotTextChangedEnabled)
410bool KexiQueryDesignerSQLView::eventFilter( TQObject *o, TQEvent *e )
412 if (d->eventFilterForSplitterEnabled) {
413 if (e->type()==TQEvent::Resize && o && o==d->historyHead && d->historyHead->isVisible()) {
414 d->heightForHistoryMode = d->historyHead->height();
416 else if (e->type()==TQEvent::Resize && o && o==d->status_hbox && d->status_hbox->isVisible()) {
417 d->heightForStatusMode = d->status_hbox->height();
420 return KexiViewBase::eventFilter(o, e);
433void KexiQueryDesignerSQLView::slotSelectQuery()
435 TQString sql = d->history->selectedStatement();
436 if (!sql.isEmpty()) {
437 d->editor->setText( sql );
442KexiQueryDesignerSQLView::tempData()
const
458 if (d->parsedQuery) {
459 query = d->parsedQuery;
469 m_dialog->
setId( query->id() );
480 ok = (KMessageBox::questionYesNo(
this, i18n(
"Do you want to save invalid query?"),
481 0, KStdGuiItem::yes(), KStdGuiItem::no(),
"askBeforeSavingInvalidQueries")==KMessageBox::Yes);
487 m_dialog->
setId( query->id() );
541#include "kexiquerydesignersql.moc"
options used in selectStatement()
int identifierEscaping
A mode for escaping identifier, Driver::EscapeDriver|Driver::EscapeAsNecessary by default.
bool addVisibleLookupColumns
Provides database connection, allowing queries and data modification.
bool storeObjectSchemaData(SchemaData &sdata, bool newObject)
TQString selectStatement(QuerySchema &querySchema, const TQValueList< TQVariant > ¶ms, const SelectStatementOptions &options=SelectStatementOptions()) const
Provides detailed i18n'ed error description about the Parser .
Parser for SQL statements.
KexiDB::QuerySchema provides information about database query.
KexiDialogTempData * tempData() const
KexiViewBase * viewForMode(int mode) const
Kexi's main window interface This interface is implemented by KexiMainWindowImpl class.
virtual KexiProject * project()=0
Project data of currently opened project or NULL if no project here yet.
KexiDB::Connection * dbConnection() const
Text editor for entering query statements.
virtual tristate afterSwitchFrom(int mode)
virtual void updateActions(bool activated)
virtual KexiDB::SchemaData * storeNewData(const KexiDB::SchemaData &sdata, bool &cancel)
virtual tristate storeData(bool dontAsk=false)
virtual tristate beforeSwitchTo(int mode, bool &dontStore)
Temporary data kept in memory while switching between Query Dialog's views.
KexiDB::QuerySchema * query() const
bool queryChangedInPreviousView
void setQuery(KexiDB::QuerySchema *query)
Base class for single view embeddable of in KexiDialogBase.
virtual tristate storeData(bool dontAsk=false)
virtual void setAvailable(const char *action_name, bool set)
bool storeDataBlock(const TQString &dataString, const TQString &dataID=TQString())
bool loadDataBlock(TQString &dataString, const TQString &dataID=TQString(), bool canBeEmpty=false)
KexiDialogBase * parentDialog() const
KexiMainWindow * mainWin() const
virtual void updateActions(bool activated)
3-state logical type with three values: true, false and cancelled and convenient operators.
@ NoViewMode
In KexiViewBase::afterSwitchFrom() and KexiViewBase::beforeSwitchTo() means that parent dialog of the...