File indexing completed on 2024-12-01 09:50:25

0001 /*
0002  *  This file is part of the KDE libraries
0003  *  Copyright (C) 2006 Matt Broadstone (mbroadst@gmail.com)
0004  *
0005  *  This library is free software; you can redistribute it and/or
0006  *  modify it under the terms of the GNU Library General Public
0007  *  License as published by the Free Software Foundation; either
0008  *  version 2 of the License, or (at your option) any later version.
0009  *
0010  *  This library is distributed in the hope that it will be useful,
0011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  *  Library General Public License for more details.
0014  *
0015  *  You should have received a copy of the GNU Library General Public
0016  *  License along with this library; if not, write to the Free Software
0017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0018  */
0019 
0020 #include "callstackdock.h"
0021 
0022 #include <QVBoxLayout>
0023 #include <QTableWidget>
0024 #include <QHeaderView>
0025 
0026 #include <klocalizedstring.h>
0027 
0028 #include "debugdocument.h"
0029 #include "interpreter_ctx.h"
0030 
0031 namespace KJSDebugger
0032 {
0033 
0034 CallStackDock::CallStackDock(QWidget *parent)
0035     : QDockWidget(i18n("Call Stack"), parent)
0036 {
0037     setFeatures(DockWidgetMovable | DockWidgetFloatable);
0038     m_view = new QTableWidget(0, 2);
0039     m_view->setHorizontalHeaderLabels(QStringList() << i18n("Call") << i18n("Line"));
0040     m_view->verticalHeader()->hide();
0041     m_view->setShowGrid(false);
0042     m_view->setAlternatingRowColors(true);
0043     m_view->setSelectionBehavior(QAbstractItemView::SelectRows);
0044     m_view->setSelectionMode(QAbstractItemView::SingleSelection);
0045 
0046     connect(m_view, SIGNAL(itemClicked(QTableWidgetItem*)),
0047             this, SLOT(slotViewItem(QTableWidgetItem*)));
0048     connect(m_view, SIGNAL(itemDoubleClicked(QTableWidgetItem*)),
0049             this, SLOT(slotViewItem(QTableWidgetItem*)));
0050 
0051     setWidget(m_view);
0052 
0053     m_activeCtx = 0;
0054 }
0055 
0056 CallStackDock::~CallStackDock()
0057 {
0058 }
0059 
0060 void CallStackDock::clearDisplay()
0061 {
0062     m_activeCtx = 0;
0063     m_view->clearContents();
0064     m_view->setRowCount(0);
0065 }
0066 
0067 void CallStackDock::displayStack(InterpreterContext *ic)
0068 {
0069     m_activeCtx = ic;
0070 
0071     // Try to save our position across updates if nothing changed.
0072     // this is needed for console eval.
0073     bool dirty     = false;
0074     int  activeRow = m_view->currentRow();
0075 
0076     if (ic->callStack.count() != m_view->rowCount()) {
0077         m_view->setRowCount(ic->callStack.count());
0078         dirty = true;
0079     }
0080 
0081     for (int row = 0; row < ic->callStack.size(); ++row) {
0082         const CallStackEntry &entry =  ic->callStack[row];
0083 
0084         int displayRow = ic->callStack.count() - row - 1; //Want newest entry on top
0085         QString fnLabel = entry.name;
0086         QString lnLabel = QString::number(entry.lineNumber + 1);
0087 
0088         dirty = dirty /* avoids latter stuff if may be null */
0089                 || m_view->item(displayRow, 0)->text() != fnLabel
0090                 || m_view->item(displayRow, 1)->text() != lnLabel;
0091 
0092         QTableWidgetItem *function = new QTableWidgetItem(fnLabel);
0093         function->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
0094         m_view->setItem(displayRow, 0, function);
0095         QTableWidgetItem *lineNumber = new QTableWidgetItem(lnLabel);
0096         lineNumber->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
0097         m_view->setItem(displayRow, 1, lineNumber);
0098     }
0099 
0100     m_view->resizeColumnsToContents();
0101     m_view->resizeRowsToContents();
0102 
0103     if (!dirty && activeRow != -1) {
0104         m_view->setCurrentCell(activeRow, 0);
0105         slotViewItem(m_view->item(activeRow, 0));
0106     }
0107 }
0108 
0109 void CallStackDock::slotViewItem(QTableWidgetItem *item)
0110 {
0111     if (!m_activeCtx) {
0112         return;
0113     }
0114 
0115     CallStackEntry &entry = m_activeCtx->callStack[m_view->rowCount() - m_view->row(item) - 1];
0116     emit displayScript(entry.doc.get(), entry.lineNumber);
0117 }
0118 
0119 KJS::ExecState *CallStackDock::selectedFrameContext()
0120 {
0121     QList<QTableWidgetItem *> selected = m_view->selectedItems();
0122     if (selected.isEmpty()) {
0123         return 0;
0124     }
0125 
0126     return m_activeCtx->execContexts[m_view->rowCount() - m_view->row(selected[0]) - 1];
0127 
0128 }
0129 
0130 }
0131 
0132 #include "moc_callstackdock.cpp"