File indexing completed on 2024-05-12 16:39:54

0001 /* This file is part of the KDE project
0002    Copyright (C) 2006 Jarosław Staniek <staniek@kde.org>
0003 
0004    This program is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This program is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this program; see the file COPYING.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "utils.h"
0021 #include "utils_p.h"
0022 #include <KexiIcon.h>
0023 
0024 #include <KDb>
0025 
0026 #include <KStandardGuiItem>
0027 
0028 #include <QThread>
0029 #include <QHeaderView>
0030 #include <QPushButton>
0031 #include <QTabWidget>
0032 #include <QVBoxLayout>
0033 #include <QDebug>
0034 
0035 static DebugWindow* debugWindow = 0;
0036 static QTabWidget* debugWindowTab = 0;
0037 static KexiDBDebugTreeWidget* kexiDBDebugPage = 0;
0038 static QTreeWidget* kexiAlterTableActionDebugPage = 0;
0039 
0040 static void addKexiDBDebug(const QString& text)
0041 {
0042     // (this is internal code - do not use i18n() here)
0043     if (!debugWindowTab)
0044         return;
0045     if (QThread::currentThread() != debugWindowTab->thread()) {
0046 //! @todo send debug using async. signal
0047         qWarning() << "Debugging from different thread not supported.";
0048         return;
0049     }
0050     if (!kexiDBDebugPage) {
0051         QWidget *page = new QWidget(debugWindowTab);
0052         QVBoxLayout *vbox = new QVBoxLayout(page);
0053         QHBoxLayout *hbox = new QHBoxLayout;
0054         vbox->addLayout(hbox);
0055         hbox->addStretch(1);
0056         QPushButton *btn_copy = new QPushButton(page);
0057         btn_copy->setIcon(koSmallIcon("edit-copy"));
0058         hbox->addWidget(btn_copy);
0059         QPushButton *btn_clear = new QPushButton(KStandardGuiItem::clear().icon(), KStandardGuiItem::clear().text(), page);
0060         hbox->addWidget(btn_clear);
0061 
0062         kexiDBDebugPage = new KexiDBDebugTreeWidget(page);
0063         kexiDBDebugPage->setObjectName("kexiDbDebugPage");
0064         kexiDBDebugPage->setFont(KexiUtils::smallestReadableFont());
0065         QObject::connect(btn_copy, SIGNAL(clicked()), kexiDBDebugPage, SLOT(copy()));
0066         QObject::connect(btn_clear, SIGNAL(clicked()), kexiDBDebugPage, SLOT(clear()));
0067         vbox->addWidget(kexiDBDebugPage);
0068         kexiDBDebugPage->setHeaderLabel(QString());
0069         kexiDBDebugPage->header()->hide();
0070         kexiDBDebugPage->setSortingEnabled(false);
0071         kexiDBDebugPage->setAllColumnsShowFocus(true);
0072         kexiDBDebugPage->header()->setSectionResizeMode(0, QHeaderView::Stretch);
0073         kexiDBDebugPage->header()->setStretchLastSection(true);
0074         kexiDBDebugPage->setRootIsDecorated(true);
0075         kexiDBDebugPage->setWordWrap(true);
0076         kexiDBDebugPage->setAlternatingRowColors(true);
0077         debugWindowTab->addTab(page, "KDb");
0078         debugWindowTab->setCurrentWidget(page);
0079         kexiDBDebugPage->show();
0080     }
0081     //add \n after (about) every 30 characters
0082     QTreeWidgetItem * lastItem = kexiDBDebugPage->invisibleRootItem()->child(
0083         kexiDBDebugPage->invisibleRootItem()->childCount()-1);
0084     QTreeWidgetItem* li;
0085     if (lastItem) {
0086         li = new QTreeWidgetItem(kexiDBDebugPage, lastItem);
0087     }
0088     else {
0089         li = new QTreeWidgetItem(kexiDBDebugPage->invisibleRootItem());
0090     }
0091     li->setText(0, text);
0092     li->setToolTip(0, text);
0093     li->setExpanded(true);
0094 }
0095 
0096 static void addAlterTableActionDebug(const QString& text, int nestingLevel)
0097 {
0098     // (this is internal code - do not use i18n() here)
0099     if (!debugWindowTab)
0100         return;
0101     if (!kexiAlterTableActionDebugPage) {
0102         QWidget *page = new QWidget(debugWindowTab);
0103         QVBoxLayout *vbox = new QVBoxLayout(page);
0104         QHBoxLayout *hbox = new QHBoxLayout(page);
0105         vbox->addLayout(hbox);
0106         hbox->addStretch(1);
0107         QPushButton *btn_exec = new QPushButton(KStandardGuiItem::save().icon(), "Real Alter Table", page);
0108         btn_exec->setObjectName("executeRealAlterTable");
0109         hbox->addWidget(btn_exec);
0110         QPushButton *btn_clear = new QPushButton(KStandardGuiItem::clear().icon(), KStandardGuiItem::clear().text(), page);
0111         hbox->addWidget(btn_clear);
0112         QPushButton *btn_sim = new QPushButton(QIcon::fromTheme("system-run"), "Simulate Execution", page);
0113         btn_sim->setObjectName("simulateAlterTableExecution");
0114         hbox->addWidget(btn_sim);
0115 
0116         kexiAlterTableActionDebugPage = new QTreeWidget(page);
0117         kexiAlterTableActionDebugPage->setFont(KexiUtils::smallestReadableFont());
0118         kexiAlterTableActionDebugPage->setObjectName("kexiAlterTableActionDebugPage");
0119         QObject::connect(btn_clear, SIGNAL(clicked()), kexiAlterTableActionDebugPage, SLOT(clear()));
0120         vbox->addWidget(kexiAlterTableActionDebugPage);
0121         kexiAlterTableActionDebugPage->setHeaderLabel(QString());
0122         kexiAlterTableActionDebugPage->header()->hide();
0123         kexiAlterTableActionDebugPage->setSortingEnabled(false);
0124         kexiAlterTableActionDebugPage->setAllColumnsShowFocus(true);
0125         kexiAlterTableActionDebugPage->header()->setSectionResizeMode(0, QHeaderView::Stretch);
0126         kexiAlterTableActionDebugPage->setRootIsDecorated(true);
0127         debugWindowTab->addTab(page, "AlterTable Actions");
0128         debugWindowTab->setCurrentWidget(page);
0129         page->show();
0130     }
0131     if (text.isEmpty()) //don't move up!
0132         return;
0133     QTreeWidgetItem * li;
0134     int availableNestingLevels = 0;
0135     // compute availableNestingLevels
0136     QTreeWidgetItem * lastItem = kexiAlterTableActionDebugPage->invisibleRootItem()->child(
0137         kexiAlterTableActionDebugPage->invisibleRootItem()->childCount()-1);
0138     //qDebug() << "lastItem: " << (lastItem ? lastItem->text(0) : QString());
0139     while (lastItem) {
0140         lastItem = lastItem->parent();
0141         availableNestingLevels++;
0142     }
0143     //qDebug() << "availableNestingLevels: " << availableNestingLevels;
0144     //go up (availableNestingLevels-levelsToGoUp) levels
0145     lastItem = kexiAlterTableActionDebugPage->invisibleRootItem()->child(
0146         kexiAlterTableActionDebugPage->invisibleRootItem()->childCount()-1);
0147     int levelsToGoUp = availableNestingLevels - nestingLevel;
0148     while (levelsToGoUp > 0 && lastItem) {
0149         lastItem = lastItem->parent();
0150         levelsToGoUp--;
0151     }
0152     //qDebug() << "lastItem2: " << (lastItem ? lastItem->text(0) : QString());
0153     if (lastItem) {
0154         if (lastItem->childCount() > 0) {
0155                li = new QTreeWidgetItem(lastItem, lastItem->child(lastItem->childCount()-1));   //child, after
0156         }
0157         else {
0158                li = new QTreeWidgetItem(lastItem);   //1st child
0159         }
0160     } else {
0161         lastItem = kexiAlterTableActionDebugPage->invisibleRootItem()->child(
0162             kexiAlterTableActionDebugPage->invisibleRootItem()->childCount()-1);
0163         while (lastItem && lastItem->parent()) {
0164             lastItem = lastItem->parent();
0165         }
0166         //qDebug() << "lastItem2: " << (lastItem ? lastItem->text(0) : QString());
0167         if (lastItem && lastItem->parent())
0168              li = new QTreeWidgetItem(lastItem->parent(), lastItem);   //after
0169         else if (!lastItem)
0170              li = new QTreeWidgetItem(kexiAlterTableActionDebugPage->invisibleRootItem());
0171         else if (!lastItem->parent())
0172              li = new QTreeWidgetItem(kexiAlterTableActionDebugPage->invisibleRootItem(), lastItem);
0173     }
0174         li->setText(0, text);
0175         li->setExpanded(true);
0176 }
0177 
0178 QWidget *KexiUtils::createDebugWindow(QWidget *parent)
0179 {
0180     Q_UNUSED(parent);
0181     KDb::setDebugGUIHandler(addKexiDBDebug);
0182     KDb::setAlterTableActionDebugHandler(addAlterTableActionDebug);
0183 
0184     // (this is internal code - do not use i18n() here)
0185     debugWindow = new DebugWindow(parent);
0186     QBoxLayout *lyr = new QVBoxLayout(debugWindow);
0187     debugWindowTab = new QTabWidget(debugWindow);
0188     debugWindowTab->setObjectName("debugWindowTab");
0189     lyr->addWidget(debugWindowTab);
0190     debugWindow->resize(900, 600);
0191     debugWindow->setWindowIcon(koIcon("document-properties"));
0192     debugWindow->setWindowTitle("Kexi Internal Debugger");
0193     debugWindow->show();
0194     return debugWindow;
0195 }
0196 
0197 void KexiUtils::connectPushButtonActionForDebugWindow(const char* actionName,
0198         const QObject *receiver, const char* slot)
0199 {
0200     if (debugWindow) {
0201         QPushButton* btn = KexiUtils::findFirstChild<QPushButton*>(
0202                                debugWindow, "QPushButton", actionName);
0203         if (btn)
0204             QObject::connect(btn, SIGNAL(clicked()), receiver, slot);
0205     }
0206 }