1 /* This file is part of the KDE project
2 Copyright (C) 2006 Jarosław Staniek <staniek@kde.org>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "utils.h"
21 #include "utils_p.h"
22 #include <KexiIcon.h>
23
24 #include <KDb>
25
26 #include <KStandardGuiItem>
27
28 #include <QThread>
29 #include <QHeaderView>
30 #include <QPushButton>
31 #include <QTabWidget>
32 #include <QVBoxLayout>
33 #include <QDebug>
34
35 static DebugWindow* debugWindow = 0;
36 static QTabWidget* debugWindowTab = 0;
37 static KexiDBDebugTreeWidget* kexiDBDebugPage = 0;
38 static QTreeWidget* kexiAlterTableActionDebugPage = 0;
39
addKexiDBDebug(const QString & text)40 static void addKexiDBDebug(const QString& text)
41 {
42 // (this is internal code - do not use i18n() here)
43 if (!debugWindowTab)
44 return;
45 if (QThread::currentThread() != debugWindowTab->thread()) {
46 //! @todo send debug using async. signal
47 qWarning() << "Debugging from different thread not supported.";
48 return;
49 }
50 if (!kexiDBDebugPage) {
51 QWidget *page = new QWidget(debugWindowTab);
52 QVBoxLayout *vbox = new QVBoxLayout(page);
53 QHBoxLayout *hbox = new QHBoxLayout;
54 vbox->addLayout(hbox);
55 hbox->addStretch(1);
56 QPushButton *btn_copy = new QPushButton(page);
57 btn_copy->setIcon(koSmallIcon("edit-copy"));
58 hbox->addWidget(btn_copy);
59 QPushButton *btn_clear = new QPushButton(KStandardGuiItem::clear().icon(), KStandardGuiItem::clear().text(), page);
60 hbox->addWidget(btn_clear);
61
62 kexiDBDebugPage = new KexiDBDebugTreeWidget(page);
63 kexiDBDebugPage->setObjectName("kexiDbDebugPage");
64 kexiDBDebugPage->setFont(KexiUtils::smallestReadableFont());
65 QObject::connect(btn_copy, SIGNAL(clicked()), kexiDBDebugPage, SLOT(copy()));
66 QObject::connect(btn_clear, SIGNAL(clicked()), kexiDBDebugPage, SLOT(clear()));
67 vbox->addWidget(kexiDBDebugPage);
68 kexiDBDebugPage->setHeaderLabel(QString());
69 kexiDBDebugPage->header()->hide();
70 kexiDBDebugPage->setSortingEnabled(false);
71 kexiDBDebugPage->setAllColumnsShowFocus(true);
72 kexiDBDebugPage->header()->setSectionResizeMode(0, QHeaderView::Stretch);
73 kexiDBDebugPage->header()->setStretchLastSection(true);
74 kexiDBDebugPage->setRootIsDecorated(true);
75 kexiDBDebugPage->setWordWrap(true);
76 kexiDBDebugPage->setAlternatingRowColors(true);
77 debugWindowTab->addTab(page, "KDb");
78 debugWindowTab->setCurrentWidget(page);
79 kexiDBDebugPage->show();
80 }
81 //add \n after (about) every 30 characters
82 QTreeWidgetItem * lastItem = kexiDBDebugPage->invisibleRootItem()->child(
83 kexiDBDebugPage->invisibleRootItem()->childCount()-1);
84 QTreeWidgetItem* li;
85 if (lastItem) {
86 li = new QTreeWidgetItem(kexiDBDebugPage, lastItem);
87 }
88 else {
89 li = new QTreeWidgetItem(kexiDBDebugPage->invisibleRootItem());
90 }
91 li->setText(0, text);
92 li->setToolTip(0, text);
93 li->setExpanded(true);
94 }
95
addAlterTableActionDebug(const QString & text,int nestingLevel)96 static void addAlterTableActionDebug(const QString& text, int nestingLevel)
97 {
98 // (this is internal code - do not use i18n() here)
99 if (!debugWindowTab)
100 return;
101 if (!kexiAlterTableActionDebugPage) {
102 QWidget *page = new QWidget(debugWindowTab);
103 QVBoxLayout *vbox = new QVBoxLayout(page);
104 QHBoxLayout *hbox = new QHBoxLayout(page);
105 vbox->addLayout(hbox);
106 hbox->addStretch(1);
107 QPushButton *btn_exec = new QPushButton(KStandardGuiItem::save().icon(), "Real Alter Table", page);
108 btn_exec->setObjectName("executeRealAlterTable");
109 hbox->addWidget(btn_exec);
110 QPushButton *btn_clear = new QPushButton(KStandardGuiItem::clear().icon(), KStandardGuiItem::clear().text(), page);
111 hbox->addWidget(btn_clear);
112 QPushButton *btn_sim = new QPushButton(QIcon::fromTheme("system-run"), "Simulate Execution", page);
113 btn_sim->setObjectName("simulateAlterTableExecution");
114 hbox->addWidget(btn_sim);
115
116 kexiAlterTableActionDebugPage = new QTreeWidget(page);
117 kexiAlterTableActionDebugPage->setFont(KexiUtils::smallestReadableFont());
118 kexiAlterTableActionDebugPage->setObjectName("kexiAlterTableActionDebugPage");
119 QObject::connect(btn_clear, SIGNAL(clicked()), kexiAlterTableActionDebugPage, SLOT(clear()));
120 vbox->addWidget(kexiAlterTableActionDebugPage);
121 kexiAlterTableActionDebugPage->setHeaderLabel(QString());
122 kexiAlterTableActionDebugPage->header()->hide();
123 kexiAlterTableActionDebugPage->setSortingEnabled(false);
124 kexiAlterTableActionDebugPage->setAllColumnsShowFocus(true);
125 kexiAlterTableActionDebugPage->header()->setSectionResizeMode(0, QHeaderView::Stretch);
126 kexiAlterTableActionDebugPage->setRootIsDecorated(true);
127 debugWindowTab->addTab(page, "AlterTable Actions");
128 debugWindowTab->setCurrentWidget(page);
129 page->show();
130 }
131 if (text.isEmpty()) //don't move up!
132 return;
133 QTreeWidgetItem * li;
134 int availableNestingLevels = 0;
135 // compute availableNestingLevels
136 QTreeWidgetItem * lastItem = kexiAlterTableActionDebugPage->invisibleRootItem()->child(
137 kexiAlterTableActionDebugPage->invisibleRootItem()->childCount()-1);
138 //qDebug() << "lastItem: " << (lastItem ? lastItem->text(0) : QString());
139 while (lastItem) {
140 lastItem = lastItem->parent();
141 availableNestingLevels++;
142 }
143 //qDebug() << "availableNestingLevels: " << availableNestingLevels;
144 //go up (availableNestingLevels-levelsToGoUp) levels
145 lastItem = kexiAlterTableActionDebugPage->invisibleRootItem()->child(
146 kexiAlterTableActionDebugPage->invisibleRootItem()->childCount()-1);
147 int levelsToGoUp = availableNestingLevels - nestingLevel;
148 while (levelsToGoUp > 0 && lastItem) {
149 lastItem = lastItem->parent();
150 levelsToGoUp--;
151 }
152 //qDebug() << "lastItem2: " << (lastItem ? lastItem->text(0) : QString());
153 if (lastItem) {
154 if (lastItem->childCount() > 0) {
155 li = new QTreeWidgetItem(lastItem, lastItem->child(lastItem->childCount()-1)); //child, after
156 }
157 else {
158 li = new QTreeWidgetItem(lastItem); //1st child
159 }
160 } else {
161 lastItem = kexiAlterTableActionDebugPage->invisibleRootItem()->child(
162 kexiAlterTableActionDebugPage->invisibleRootItem()->childCount()-1);
163 while (lastItem && lastItem->parent()) {
164 lastItem = lastItem->parent();
165 }
166 //qDebug() << "lastItem2: " << (lastItem ? lastItem->text(0) : QString());
167 if (lastItem && lastItem->parent())
168 li = new QTreeWidgetItem(lastItem->parent(), lastItem); //after
169 else if (!lastItem)
170 li = new QTreeWidgetItem(kexiAlterTableActionDebugPage->invisibleRootItem());
171 else if (!lastItem->parent())
172 li = new QTreeWidgetItem(kexiAlterTableActionDebugPage->invisibleRootItem(), lastItem);
173 }
174 li->setText(0, text);
175 li->setExpanded(true);
176 }
177
createDebugWindow(QWidget * parent)178 QWidget *KexiUtils::createDebugWindow(QWidget *parent)
179 {
180 Q_UNUSED(parent);
181 KDb::setDebugGUIHandler(addKexiDBDebug);
182 KDb::setAlterTableActionDebugHandler(addAlterTableActionDebug);
183
184 // (this is internal code - do not use i18n() here)
185 debugWindow = new DebugWindow(parent);
186 QBoxLayout *lyr = new QVBoxLayout(debugWindow);
187 debugWindowTab = new QTabWidget(debugWindow);
188 debugWindowTab->setObjectName("debugWindowTab");
189 lyr->addWidget(debugWindowTab);
190 debugWindow->resize(900, 600);
191 debugWindow->setWindowIcon(koIcon("document-properties"));
192 debugWindow->setWindowTitle("Kexi Internal Debugger");
193 debugWindow->show();
194 return debugWindow;
195 }
196
connectPushButtonActionForDebugWindow(const char * actionName,const QObject * receiver,const char * slot)197 void KexiUtils::connectPushButtonActionForDebugWindow(const char* actionName,
198 const QObject *receiver, const char* slot)
199 {
200 if (debugWindow) {
201 QPushButton* btn = KexiUtils::findFirstChild<QPushButton*>(
202 debugWindow, "QPushButton", actionName);
203 if (btn)
204 QObject::connect(btn, SIGNAL(clicked()), receiver, slot);
205 }
206 }
207