You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
374 lines
9.7 KiB
374 lines
9.7 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
|
|
Copyright (C) 2004 Jaroslaw Staniek <js@iidea.pl>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this program; see the file COPYING. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <tqpainter.h>
|
|
#include <tqclipboard.h>
|
|
#include <tqregexp.h>
|
|
|
|
#include <kpopupmenu.h>
|
|
#include <klocale.h>
|
|
#include <kiconloader.h>
|
|
#include <kdebug.h>
|
|
#include <kglobalsettings.h>
|
|
#include <kapplication.h>
|
|
|
|
#include "kexiquerydesignersqlhistory.h"
|
|
|
|
KexiQueryDesignerSQLHistory::KexiQueryDesignerSQLHistory(TQWidget *parent, const char *name)
|
|
: TQScrollView(parent, name)
|
|
{
|
|
viewport()->setPaletteBackgroundColor(white);
|
|
|
|
m_selected = 0;
|
|
m_history = new History();
|
|
m_history->setAutoDelete(true);
|
|
|
|
m_popup = new KPopupMenu(this);
|
|
m_popup->insertItem(SmallIcon("editcopy"), i18n("Copy to Clipboard"), this, TQT_SLOT(slotToClipboard()));
|
|
}
|
|
|
|
KexiQueryDesignerSQLHistory::~KexiQueryDesignerSQLHistory()
|
|
{
|
|
}
|
|
|
|
void
|
|
KexiQueryDesignerSQLHistory::drawContents(TQPainter *p, int cx, int cy, int cw, int ch)
|
|
{
|
|
TQRect clipping(cx, cy, cw, ch);
|
|
|
|
int y = 0;
|
|
for(HistoryEntry *it = m_history->first(); it; it = m_history->next())
|
|
{
|
|
// it->drawItem(p, visibleWidth());
|
|
if(clipping.intersects(it->geometry(y, visibleWidth(), fontMetrics())))
|
|
{
|
|
p->saveWorldMatrix();
|
|
p->translate(0, y);
|
|
it->drawItem(p, visibleWidth(), colorGroup());
|
|
p->restoreWorldMatrix();
|
|
}
|
|
y += it->geometry(y, visibleWidth(), fontMetrics()).height() + 5;
|
|
}
|
|
}
|
|
|
|
void
|
|
KexiQueryDesignerSQLHistory::contentsMousePressEvent(TQMouseEvent * e)
|
|
{
|
|
int y = 0;
|
|
HistoryEntry *popupHistory = 0;
|
|
int pos;
|
|
for(TQPtrListIterator<HistoryEntry> it(*m_history); it.current(); ++it)
|
|
{
|
|
if(it.current()->isSelected())
|
|
{
|
|
//clear
|
|
it.current()->setSelected(false, colorGroup());
|
|
updateContents(it.current()->geometry(y, visibleWidth(), fontMetrics()));
|
|
}
|
|
|
|
if(it.current()->geometry(y, visibleWidth(), fontMetrics()).contains(e->pos()))
|
|
{
|
|
popupHistory = it.current();
|
|
pos = y;
|
|
}
|
|
y += it.current()->geometry(y, visibleWidth(), fontMetrics()).height() + 5;
|
|
}
|
|
|
|
//now do update
|
|
if (popupHistory) {
|
|
if (m_selected && m_selected != popupHistory) {
|
|
m_selected->setSelected(false, colorGroup());
|
|
updateContents(m_selected->geometry(pos, visibleWidth(), fontMetrics()));
|
|
}
|
|
m_selected = popupHistory;
|
|
m_selected->setSelected(true, colorGroup());
|
|
updateContents(m_selected->geometry(pos, visibleWidth(), fontMetrics()));
|
|
if(e->button() == Qt::RightButton) {
|
|
m_popup->exec(e->globalPos());
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
KexiQueryDesignerSQLHistory::contentsMouseDoubleClickEvent(TQMouseEvent * e)
|
|
{
|
|
contentsMousePressEvent(e);
|
|
if (m_selected)
|
|
emit currentItemDoubleClicked();
|
|
}
|
|
|
|
void
|
|
KexiQueryDesignerSQLHistory::addEvent(const TQString& q, bool s, const TQString &error)
|
|
{
|
|
HistoryEntry *he=m_history->last();
|
|
if (he) {
|
|
if (he->statement()==q) {
|
|
he->updateTime(TQTime::currentTime());
|
|
repaint();
|
|
return;
|
|
}
|
|
}
|
|
addEntry(new HistoryEntry(s, TQTime::currentTime(), q, error));
|
|
}
|
|
|
|
void
|
|
KexiQueryDesignerSQLHistory::addEntry(HistoryEntry *e)
|
|
{
|
|
m_history->append(e);
|
|
// m_history->prepend(e);
|
|
|
|
int y = 0;
|
|
for(HistoryEntry *it = m_history->first(); it; it = m_history->next())
|
|
{
|
|
y += it->geometry(y, visibleWidth(), fontMetrics()).height() + 5;
|
|
}
|
|
|
|
resizeContents(visibleWidth() - 1, y);
|
|
if (m_selected) {
|
|
m_selected->setSelected(false, colorGroup());
|
|
}
|
|
m_selected = e;
|
|
m_selected->setSelected(true, colorGroup());
|
|
ensureVisible(0,y+5);
|
|
updateContents();
|
|
/* ensureVisible(0, 0);
|
|
if (m_selected) {
|
|
m_selected->setSelected(false, colorGroup());
|
|
}
|
|
m_selected = e;
|
|
m_selected->setSelected(true, colorGroup());
|
|
// updateContents();
|
|
updateContents(m_selected->geometry(0, visibleWidth(), fontMetrics()));*/
|
|
}
|
|
|
|
/*void
|
|
KexiQueryDesignerSQLHistory::contextMenu(const TQPoint &pos, HistoryEntry *)
|
|
{
|
|
KPopupMenu p(this);
|
|
p.insertItem(SmallIcon("editcopy"), i18n("Copy to Clipboard"), this, TQT_SLOT(slotToClipboard()));
|
|
|
|
|
|
#ifndef KEXI_NO_UNFINISHED
|
|
p.insertSeparator();
|
|
p.insertItem(SmallIcon("edit"), i18n("Edit"), this, TQT_SLOT(slotEdit()));
|
|
p.insertItem(SmallIcon("reload"), i18n("Requery"));
|
|
#endif
|
|
|
|
p.exec(pos);
|
|
}*/
|
|
|
|
void
|
|
KexiQueryDesignerSQLHistory::slotToClipboard()
|
|
{
|
|
if(!m_selected)
|
|
return;
|
|
|
|
TQApplication::clipboard()->setText(m_selected->statement(), TQClipboard::Clipboard);
|
|
}
|
|
|
|
void
|
|
KexiQueryDesignerSQLHistory::slotEdit()
|
|
{
|
|
emit editRequested(m_selected->statement());
|
|
}
|
|
|
|
TQString
|
|
KexiQueryDesignerSQLHistory::selectedStatement() const
|
|
{
|
|
return m_selected ? m_selected->statement() : TQString();
|
|
}
|
|
|
|
void
|
|
KexiQueryDesignerSQLHistory::setHistory(History *h)
|
|
{
|
|
m_history = h;
|
|
update();
|
|
}
|
|
|
|
void KexiQueryDesignerSQLHistory::clear()
|
|
{
|
|
m_selected = 0;
|
|
m_history->clear();
|
|
updateContents();
|
|
}
|
|
|
|
KPopupMenu* KexiQueryDesignerSQLHistory::popupMenu() const
|
|
{
|
|
return m_popup;
|
|
}
|
|
|
|
//==================================
|
|
|
|
HistoryEntry::HistoryEntry(bool succeed, const TQTime &execTime, const TQString &statement, /*int ,*/ const TQString &err)
|
|
{
|
|
m_succeed = succeed;
|
|
m_execTime = execTime;
|
|
m_statement = statement;
|
|
m_error = err;
|
|
m_selected = false;
|
|
highlight(TQColorGroup());
|
|
}
|
|
|
|
void
|
|
HistoryEntry::drawItem(TQPainter *p, int width, const TQColorGroup &cg)
|
|
{
|
|
p->setPen(TQColor(200, 200, 200));
|
|
p->setBrush(TQColor(200, 200, 200));
|
|
p->drawRect(2, 2, 200, 20);
|
|
p->setPen(TQColor(0, 0, 0));
|
|
|
|
if(m_succeed)
|
|
p->drawPixmap(4, 4, SmallIcon("button_ok"));
|
|
else
|
|
p->drawPixmap(4, 4, SmallIcon("button_cancel"));
|
|
|
|
p->drawText(22, 2, 180, 20, TQt::AlignLeft | TQt::AlignVCenter, m_execTime.toString());
|
|
p->setPen(TQColor(200, 200, 200));
|
|
p->setBrush(TQColor(255, 255, 255));
|
|
m_formated->setWidth(width - 2);
|
|
TQRect content(2, 21, width - 2, m_formated->height());
|
|
// TQRect content = p->fontMetrics().boundingRect(2, 21, width - 2, 0, TQt::WordBreak | TQt::AlignLeft | TQt::AlignVCenter, m_statement);
|
|
// TQRect content(2, 21, width - 2, p->fontMetrics().height() + 4);
|
|
// content = TQRect(2, 21, width - 2, m_for.height());
|
|
|
|
if(m_selected)
|
|
p->setBrush(cg.highlight());
|
|
|
|
p->drawRect(content);
|
|
|
|
if(!m_selected)
|
|
p->setPen(cg.text());
|
|
else
|
|
p->setPen(cg.highlightedText());
|
|
|
|
content.setX(content.x() + 2);
|
|
content.setWidth(content.width() - 2);
|
|
// p->drawText(content, TQt::WordBreak | TQt::AlignLeft | TQt::AlignVCenter, m_statement);
|
|
m_formated->draw(p, content.x(), content.y(), content, cg);
|
|
}
|
|
|
|
void
|
|
HistoryEntry::highlight(const TQColorGroup &cg)
|
|
{
|
|
TQString statement;
|
|
TQString text;
|
|
bool quote = false;
|
|
bool dblquote = false;
|
|
|
|
statement = m_statement;
|
|
statement.replace("<", "<");
|
|
statement.replace(">", ">");
|
|
statement.replace("\r\n", "<br>"); //(js) first win32 specific pair
|
|
statement.replace("\n", "<br>"); // now single \n
|
|
statement.replace(" ", " ");
|
|
statement.replace("\t", " ");
|
|
|
|
// getting quoting...
|
|
if(!m_selected)
|
|
{
|
|
for(int i=0; i < (int)statement.length(); i++)
|
|
{
|
|
TQString beginTag;
|
|
TQString endTag;
|
|
TQChar curr = TQChar(statement[i]);
|
|
|
|
if(TQString(curr) == "'" && !dblquote && TQString(TQChar(statement[i-1])) != "\\")
|
|
{
|
|
if(!quote)
|
|
{
|
|
quote = true;
|
|
beginTag += "<font color=\"#ff0000\">";
|
|
}
|
|
else
|
|
{
|
|
quote = false;
|
|
endTag += "</font>";
|
|
}
|
|
}
|
|
if(TQString(curr) == "\"" && !quote && TQString(TQChar(statement[i-1])) != "\\")
|
|
{
|
|
if(!dblquote)
|
|
{
|
|
dblquote = true;
|
|
beginTag += "<font color=\"#ff0000\">";
|
|
}
|
|
else
|
|
{
|
|
dblquote = false;
|
|
endTag += "</font>";
|
|
}
|
|
}
|
|
if(TQRegExp("[0-9]").exactMatch(TQString(curr)) && !quote && !dblquote)
|
|
{
|
|
beginTag += "<font color=\"#0000ff\">";
|
|
endTag += "</font>";
|
|
}
|
|
|
|
text += beginTag + curr + endTag;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
text = TQString("<font color=\"%1\">%2").arg(cg.highlightedText().name()).arg(statement);
|
|
}
|
|
|
|
TQRegExp keywords("\\b(SELECT|UPDATE|INSERT|DELETE|DROP|FROM|WHERE|AND|OR|NOT|NULL|JOIN|LEFT|RIGHT|ON|INTO|TABLE)\\b");
|
|
keywords.setCaseSensitive(false);
|
|
text = text.replace(keywords, "<b>\\1</b>");
|
|
|
|
if(!m_error.isEmpty())
|
|
// text += ("<br>"+i18n("Error: %1").arg(m_error));
|
|
// text += TQString("<br><font face=\"") + KGlobalSettings::generalFont().family() + TQString("\" size=\"-1\">") + i18n("Error: %1").arg(m_error) + "</font>";
|
|
text += TQString("<br><font face=\"") + KGlobalSettings::generalFont().family() + TQString("\">") + i18n("Error: %1").arg(m_error) + "</font>";
|
|
|
|
kdDebug() << "HistoryEntry::highlight() text:" << text << endl;
|
|
// m_formated = new TQSimpleRichText(text, TQFont("courier", 8));
|
|
m_formated = new TQSimpleRichText(text, KGlobalSettings::fixedFont());
|
|
|
|
}
|
|
|
|
void
|
|
HistoryEntry::setSelected(bool selected, const TQColorGroup &cg)
|
|
{
|
|
m_selected = selected;
|
|
highlight(cg);
|
|
}
|
|
|
|
TQRect
|
|
HistoryEntry::geometry(int y, int width, TQFontMetrics f)
|
|
{
|
|
Q_UNUSED( f );
|
|
|
|
// int h = 21 + f.boundingRect(2, 21, width - 2, 0, TQt::WordBreak | TQt::AlignLeft | TQt::AlignVCenter, m_statement).height();
|
|
// return TQRect(0, y, width, h);
|
|
m_formated->setWidth(width - 2);
|
|
return TQRect(0, y, width, m_formated->height() + 21);
|
|
}
|
|
|
|
void HistoryEntry::updateTime(const TQTime &execTime) {
|
|
m_execTime=execTime;
|
|
}
|
|
|
|
HistoryEntry::~HistoryEntry()
|
|
{
|
|
}
|
|
|
|
#include "kexiquerydesignersqlhistory.moc"
|