Qt 4.8
qscriptdebuggerlocalswidget.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtSCriptTools module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
47 
48 #include <QtCore/qdebug.h>
49 #include <QtGui/qheaderview.h>
50 #include <QtGui/qcompleter.h>
51 #include <QtGui/qstringlistmodel.h>
52 #include <QtGui/qtreeview.h>
53 #include <QtGui/qboxlayout.h>
54 #include <QtGui/qsortfilterproxymodel.h>
55 #include <QtGui/qlineedit.h>
56 #include <QtGui/qstyleditemdelegate.h>
57 #include <QtGui/qevent.h>
58 #include <QtGui/qmessagebox.h>
59 #include <QtScript/qscriptengine.h>
60 
62 
63 namespace {
64 
65 class CustomProxyModel : public QSortFilterProxyModel
66 {
67 public:
68  CustomProxyModel(QObject *parent = 0)
69  : QSortFilterProxyModel(parent) {}
70 
71  bool hasChildren(const QModelIndex &parent) const
72  {
73  if (!sourceModel())
74  return false;
75  QModelIndex sourceParent = mapToSource(parent);
76  if (parent.isValid() && !sourceParent.isValid())
77  return false;
78  return sourceModel()->hasChildren(sourceParent);
79  }
80 };
81 
82 } // namespace
83 
86 {
88 public:
91 
92  void complete(QLineEdit *le);
93 
94  // private slots
95  void _q_onCompletionTaskFinished();
96  void _q_insertCompletion(const QString &text);
97  void _q_expandIndex(const QModelIndex &index);
98 
102  CustomProxyModel *proxy;
103 };
104 
106 {
107  completingEditor = 0;
108  completer = 0;
109  proxy = 0;
110 }
111 
113 {
114 }
115 
117 {
120  // ### need to pass the current frame #
121  task = completionProvider->createCompletionTask(
122  le->text(), le->cursorPosition(),
123  q->localsModel()->frameIndex(), /*options=*/0);
124  QObject::connect(task, SIGNAL(finished()),
125  q, SLOT(_q_onCompletionTaskFinished()));
126  completingEditor = le;
127  task->start();
128 }
129 
131 {
134  task = qobject_cast<QScriptCompletionTaskInterface*>(q_func()->sender());
135  if (!completingEditor) {
136  task->deleteLater();
137  return;
138  }
139 
140  if (task->resultCount() == 1) {
141  // do the completion right away
142  QString completion = task->resultAt(0);
143  completion.append(task->appendix());
144  QString tmp = completingEditor->text();
145  tmp.remove(task->position(), task->length());
146  tmp.insert(task->position(), completion);
147  completingEditor->setText(tmp);
148  completingEditor = 0;
149  } else if (task->resultCount() > 1) {
150  // popup completion
151  if (!completer) {
152  completer = new QCompleter(q);
153  completer->setCompletionMode(QCompleter::PopupCompletion);
154  completer->setCaseSensitivity(Qt::CaseSensitive);
155  completer->setWrapAround(false);
156  QObject::connect(completer, SIGNAL(activated(QString)),
157  q, SLOT(_q_insertCompletion(QString)));
158  }
159  QStringListModel *model = qobject_cast<QStringListModel*>(completer->model());
160  if (!model) {
161  model = new QStringListModel(q);
162  completer->setModel(model);
163  }
164  QStringList strings;
165  for (int i = 0; i < task->resultCount(); ++i)
166  strings.append(task->resultAt(i));
167  model->setStringList(strings);
168  QString prefix = completingEditor->text().mid(task->position(), task->length());
169  completer->setCompletionPrefix(prefix);
170  completingEditor->setCompleter(completer);
171  // we want to handle the insertion ourselves
172  QObject::disconnect(completer, 0, completingEditor, 0);
173  completer->complete();
174  }
175  task->deleteLater();
176 }
177 
179 {
180  Q_ASSERT(completingEditor != 0);
181  QString tmp = completingEditor->text();
182  tmp.insert(completingEditor->cursorPosition(), text.mid(completer->completionPrefix().length()));
183  completingEditor->setText(tmp);
184  completingEditor = 0;
185 }
186 
188 {
189  if (view->model() == index.model())
190  view->expand(proxy->mapFromSource(index));
191 }
192 
194  : public QStyledItemDelegate
195 {
196  Q_OBJECT
197 public:
199 
200  QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
201  void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
202  void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
203 
204  bool eventFilter(QObject *watched, QEvent *event);
205 
206 private Q_SLOTS:
208  {
209  QWidget *editor = qobject_cast<QWidget*>(sender());
210  QPalette pal = editor->palette();
211  QColor col;
213  if (ok) {
214  col = Qt::white;
215  } else {
217  text + QLatin1Char('\n'));
219  col = QColor(255, 240, 192);
220  else
221  col = QColor(255, 102, 102);
222  }
223  pal.setColor(QPalette::Active, QPalette::Base, col);
224  editor->setPalette(pal);
225  }
226 
227 private:
228  static const QWidget *widget(const QStyleOptionViewItem &option)
229  {
230  if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option))
231  return v3->widget;
232  return 0;
233  }
234 };
235 
237  QObject *parent)
238  : QStyledItemDelegate(parent)
239 {
240 }
241 
243  QWidget *parent, const QStyleOptionViewItem &option,
244  const QModelIndex &index) const
245 {
246  QWidget *editor = QStyledItemDelegate::createEditor(parent, option, index);
247  if (index.column() == 1) {
248  // value
249  QLineEdit *le = qobject_cast<QLineEdit*>(editor);
250  if (le) {
251  QObject::connect(le, SIGNAL(textEdited(QString)),
252  this, SLOT(validateInput(QString)));
253  }
254  }
255  return editor;
256 }
257 
259 {
260  QLineEdit *le = qobject_cast<QLineEdit*>(watched);
261  if (!le)
262  return QStyledItemDelegate::eventFilter(watched, event);
263 
265  Q_ASSERT(localsWidget != 0);
267  reinterpret_cast<QScriptDebuggerLocalsWidgetPrivate*>(
269 
270  if ((event->type() == QEvent::FocusIn) && lvp->completingEditor) {
271  // because QLineEdit insists on being difficult...
272  return true;
273  }
274 
275  if (event->type() != QEvent::KeyPress)
276  return QStyledItemDelegate::eventFilter(watched, event);
277  QKeyEvent *ke = static_cast<QKeyEvent*>(event);
278  if ((ke->key() == Qt::Key_Enter) || (ke->key() == Qt::Key_Return)) {
280  // ignore when script contains syntax error
281  return true;
282  }
283  }
284  if (ke->key() != Qt::Key_Tab)
285  return QStyledItemDelegate::eventFilter(watched, event);
286 
287  // trigger completion
288  lvp->complete(le);
289  return true;
290 }
291 
293  QWidget *editor, QAbstractItemModel *model,
294  const QModelIndex &index) const
295 {
296  if (index.column() == 1) {
297  // check that the syntax is OK
298  QString expression = qobject_cast<QLineEdit*>(editor)->text();
300  return;
301  }
302  QStyledItemDelegate::setModelData(editor, model, index);
303 }
304 
306  const QModelIndex &index) const
307 {
308  QStyledItemDelegate::paint(painter, option, index);
309 #if 0
310  QModelIndex parent = index.parent();
311  if (parent.isValid()) {
312  QStyledItemDelegate::paint(painter, option, index);
313  } else {
314  // this is a top-level item.
315  const QTreeView *view = qobject_cast<const QTreeView*>(widget(option));
316  Q_ASSERT(view != 0);
317 
318  QStyleOptionButton buttonOption;
319 
320  buttonOption.state = option.state;
321 #ifdef Q_WS_MAC
322  buttonOption.state |= QStyle::State_Raised;
323 #endif
324  buttonOption.state &= ~QStyle::State_HasFocus;
325 
326  buttonOption.rect = option.rect;
327  buttonOption.palette = option.palette;
328  buttonOption.features = QStyleOptionButton::None;
329  view->style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, view);
330 
331  QStyleOption branchOption;
332  static const int i = 9; // ### hardcoded in qcommonstyle.cpp
333  QRect r = option.rect;
334  branchOption.rect = QRect(r.left() + i/2, r.top() + (r.height() - i)/2, i, i);
335  branchOption.palette = option.palette;
336  branchOption.state = QStyle::State_Children;
337 
338  if (view->isExpanded(index))
339  branchOption.state |= QStyle::State_Open;
340 
341  view->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, painter, view);
342 
343  // draw text
344  QRect textrect = QRect(r.left() + i*2, r.top(), r.width() - ((5*i)/2), r.height());
345  QString text = elidedText(option.fontMetrics, textrect.width(), Qt::ElideMiddle,
346  index.data(Qt::DisplayRole).toString());
347  view->style()->drawItemText(painter, textrect, Qt::AlignCenter,
348  option.palette, view->isEnabled(), text);
349  }
350 #endif
351 }
352 
355 {
357  d->view = new QTreeView();
358  d->view->setItemDelegate(new QScriptDebuggerLocalsItemDelegate(this));
359  d->view->setEditTriggers(QAbstractItemView::DoubleClicked);
360 // d->view->setEditTriggers(QAbstractItemView::NoEditTriggers);
362  d->view->setAlternatingRowColors(true);
363  d->view->setSelectionBehavior(QAbstractItemView::SelectRows);
364  d->view->setSortingEnabled(true);
365  d->view->header()->setDefaultAlignment(Qt::AlignLeft);
366 // d->view->header()->setSortIndicatorShown(true);
367 // d->view->header()->setResizeMode(QHeaderView::ResizeToContents);
368 
369  QVBoxLayout *vbox = new QVBoxLayout(this);
370  vbox->setMargin(0);
371  vbox->addWidget(d->view);
372 }
373 
375 {
376 }
377 
382 {
384  if (!d->proxy)
385  return 0;
386  return qobject_cast<QScriptDebuggerLocalsModel*>(d->proxy->sourceModel());
387 }
388 
393 {
395  if (localsModel()) {
396  QObject::disconnect(localsModel(), 0, d->view, 0);
397  }
398  if (model) {
399  QObject::connect(model, SIGNAL(scopeObjectAvailable(QModelIndex)),
400  this, SLOT(_q_expandIndex(QModelIndex)));
401  }
402  if (!d->proxy) {
403  d->proxy = new CustomProxyModel(this);
404  d->view->sortByColumn(0, Qt::AscendingOrder);
405  }
406  d->proxy->setSourceModel(model);
407  d->view->setModel(d->proxy);
408 }
409 
414 {
416  d->view->expand(index);
417  d->view->setFirstColumnSpanned(index.row(), QModelIndex(), true);
418 }
419 
421 
422 #include "qscriptdebuggerlocalswidget.moc"
423 
424 #include "moc_qscriptdebuggerlocalswidget_p.cpp"
T qobject_cast(QObject *object)
Definition: qobject.h:375
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
QPalette palette
the widget&#39;s palette
Definition: qwidget.h:180
The QKeyEvent class describes a key event.
Definition: qevent.h:224
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QModelIndex mapToSource(const QModelIndex &proxyIndex) const
Returns the source model index corresponding to the given proxyIndex from the sorting filter model...
EventRef event
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
Gets data from the editor widget and stores it in the specified model at the item index...
QVariant data(int role=Qt::DisplayRole) const
Returns the data for the given role for the item referred to by the index.
QStyle::State state
the style flags that are used when drawing the control
Definition: qstyleoption.h:88
void _q_expandIndex(const QModelIndex &index)
#define SLOT(a)
Definition: qobjectdefs.h:226
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
The QCompleter class provides completions based on an item model.
Definition: qcompleter.h:64
virtual void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, const QString &text, QPalette::ColorRole textRole=QPalette::NoRole) const
Draws the given text in the specified rectangle using the provided painter and palette.
Definition: qstyle.cpp:532
#define Q_SLOTS
Definition: qobjectdefs.h:71
bool isExpanded(const QModelIndex &index) const
Returns true if the model item index is expanded; otherwise returns false.
Definition: qtreeview.cpp:859
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
The QString class provides a Unicode character string.
Definition: qstring.h:83
QFontMetrics fontMetrics
the font metrics that should be used when drawing text in the control
Definition: qstyleoption.h:91
T * qobject_cast(QObject *object)
Definition: qobject.h:375
The QStringListModel class provides a model that supplies strings to views.
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
virtual bool event(QEvent *)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition: qobject.cpp:1200
#define Q_D(Class)
Definition: qglobal.h:2482
void addWidget(QWidget *, int stretch=0, Qt::Alignment alignment=0)
Adds widget to the end of this box layout, with a stretch factor of stretch and alignment alignment...
The QStyledItemDelegate class provides display and editing facilities for data items from a model...
static QObjectPrivate * get(QObject *o)
Definition: qobject_p.h:177
void setLocalsModel(QScriptDebuggerLocalsModel *model)
Reimplemented Function
QModelIndex parent() const
Returns the parent of the model index, or QModelIndex() if it has no parent.
QStyle * style() const
Definition: qwidget.cpp:2742
#define Q_Q(Class)
Definition: qglobal.h:2483
int key() const
Returns the code of the key that was pressed or released.
Definition: qevent.h:231
#define SIGNAL(a)
Definition: qobjectdefs.h:227
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
Returns the widget used to edit the item specified by index for editing.
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
bool eventFilter(QObject *watched, QEvent *event)
Returns true if the given editor is a valid QWidget and the given event is handled; otherwise returns...
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QStyleOptionViewItemV3 class is used to describe the parameters necessary for drawing a frame in ...
Definition: qstyleoption.h:590
void expand(const QModelIndex &index)
Reimplemented Function
bool hasChildren(const QModelIndex &parent=QModelIndex()) const
Reimplemented Function
void setStringList(const QStringList &strings)
Sets the model&#39;s internal string list to strings.
The QStyleOption class stores the parameters used by QStyle functions.
Definition: qstyleoption.h:67
virtual bool hasChildren(const QModelIndex &parent=QModelIndex()) const
Returns true if parent has any children; otherwise returns false.
QAbstractItemModel * sourceModel() const
Returns the model that contains the data that is available through the proxy model.
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
The QTreeView class provides a default model/view implementation of a tree view.
Definition: qtreeview.h:58
QString text
the line edit&#39;s text
Definition: qlineedit.h:72
int row() const
Returns the row this model index refers to.
const QAbstractItemModel * model() const
Returns a pointer to the model containing the item that this index refers to.
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
QScriptDebuggerLocalsModel * localsModel() const
Reimplemented Function
virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const =0
Draws the given primitive element with the provided painter using the style options specified by opti...
The QScriptSyntaxCheckResult class provides the result of a script syntax check.
Definition: qscriptengine.h:75
ButtonFeatures features
a bitwise OR of the features that describe this button
Definition: qstyleoption.h:289
bool isValid() const
Returns true if this model index is valid; otherwise returns false.
#define Q_OBJECT
Definition: qobjectdefs.h:157
bool isEnabled() const
Definition: qwidget.h:948
The QAbstractItemModel class provides the abstract interface for item model classes.
QPalette palette
the palette that should be used when painting the control
Definition: qstyleoption.h:92
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Disconnects signal in object sender from method in object receiver.
Definition: qobject.cpp:2895
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
static const QWidget * widget(const QStyleOptionViewItem &option)
The QSortFilterProxyModel class provides support for sorting and filtering data passed between anothe...
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
Gets data from the editor widget and stores it in the specified model at the item index...
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
QString & append(QChar c)
Definition: qstring.cpp:1777
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Renders the delegate using the given painter and style option for the item specified by index...
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
The QModelIndex class is used to locate data in a data model.
virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const =0
Draws the given element with the provided painter with the style options specified by option...
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI...
Definition: qstyle.h:68
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
Returns the widget used to edit the item specified by index for editing.
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Renders the delegate using the given painter and style option for the item specified by index...
The QLineEdit widget is a one-line text editor.
Definition: qlineedit.h:66
quint16 index
static QScriptSyntaxCheckResult checkSyntax(const QString &program)
Checks the syntax of the given program.
The QVBoxLayout class lines up widgets vertically.
Definition: qboxlayout.h:149
The QStyleOptionViewItem class is used to describe the parameters used to draw an item in a view widg...
Definition: qstyleoption.h:539
QString & remove(int i, int len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition: qstring.cpp:1867
static QString elidedText(const QFontMetrics &fontMetrics, int width, Qt::TextElideMode mode, const QString &text)
Use QFontMetrics::elidedText() instead.
void setMargin(int)
Definition: qlayout.cpp:464
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
QString & insert(int i, QChar c)
Definition: qstring.cpp:1671
The QStyleOptionButton class is used to describe the parameters for drawing buttons.
Definition: qstyleoption.h:279
bool eventFilter(QObject *object, QEvent *event)
Returns true if the given editor is a valid QWidget and the given event is handled; otherwise returns...
void deleteLater()
Schedules this object for deletion.
Definition: qobject.cpp:2145
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QRect rect
the area that should be used for various calculations and painting
Definition: qstyleoption.h:90
int cursorPosition
the current cursor position for this line edit
Definition: qlineedit.h:77
void setPalette(const QPalette &)
Use the single-argument overload instead.
Definition: qwidget.cpp:4858
#define text
Definition: qobjectdefs.h:80
int column() const
Returns the column this model index refers to.
State state() const
Returns the state of this QScriptSyntaxCheckResult.
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:61