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.
koffice/kexi/plugins/queries/kexiquerydesignersqlhistory...

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("<", "&lt;");
statement.replace(">", "&gt;");
statement.replace("\r\n", "<br>"); //(js) first win32 specific pair
statement.replace("\n", "<br>"); // now single \n
statement.replace(" ", "&nbsp;");
statement.replace("\t", "&nbsp;&nbsp;&nbsp;");
// 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"