scide: Main - provide shortcut to access elements of Main singleton
[supercollider.git] / editors / sc-ide / widgets / lookup_dialog.cpp
bloba690f088c9632bd89f53c6d7a5388adbe2daca12
1 /*
2 SuperCollider Qt IDE
3 Copyright (c) 2012 Jakob Leben & Tim Blechmann
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "lookup_dialog.hpp"
22 #include "../core/sc_introspection.hpp"
23 #include "../core/main.hpp"
25 #include <QVBoxLayout>
26 #include <QHeaderView>
27 #include <QKeyEvent>
28 #include <QDesktopWidget>
29 #include <QApplication>
30 #include <QPainter>
32 namespace ScIDE {
34 LookupDialog::LookupDialog( QWidget * parent ):
35 QDialog(parent, Qt::Popup | Qt::FramelessWindowHint)
37 setWindowTitle(tr("Look Up Class or Method Definition"));
39 mQueryEdit = new QLineEdit(this);
40 mQueryEdit->setText(tr("Enter symbol to look up"));
41 mQueryEdit->selectAll();
43 mResultList = new QTreeWidget(this);
44 mResultList->setRootIsDecorated(false);
45 mResultList->setAllColumnsShowFocus(true);
46 mResultList->setHeaderHidden(true);
47 mResultList->header()->setStretchLastSection(false);
48 mResultList->setColumnCount(2);
51 QVBoxLayout *layout = new QVBoxLayout;
52 layout->setContentsMargins(4,4,4,4);
53 layout->setSpacing(1);
54 layout->addWidget(mQueryEdit);
55 layout->addWidget(mResultList);
56 setLayout(layout);
58 connect(mQueryEdit, SIGNAL(returnPressed()), this, SLOT(performQuery()));
59 connect(mResultList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(accept()));
60 connect(this, SIGNAL(accepted()), this, SLOT(onAccepted()));
62 mResultList->installEventFilter(this);
64 QRect bounds(0,0,600,300);
65 if (parent) {
66 QRect parentRect = parent->rect();
67 bounds.moveCenter( parent->mapToGlobal( parentRect.center() ) );
68 } else {
69 QRect availableBounds = QApplication::desktop()->availableGeometry(this);
70 bounds.moveCenter( availableBounds.center() );
73 setGeometry(bounds);
75 mQueryEdit->setFocus( Qt::OtherFocusReason );
79 void LookupDialog::performQuery()
81 QString queryString = mQueryEdit->text();
83 if (queryString.isEmpty()) {
84 mResultList->clear();
85 return;
88 bool result;
89 if (queryString[0].isUpper())
90 result = performClassQuery(queryString);
91 else
92 result = performMethodQuery(queryString);
94 if (result) {
95 mResultList->header()->resizeSections(QHeaderView::ResizeToContents);
96 mResultList->setFocus(Qt::OtherFocusReason);
97 mResultList->setCurrentItem( mResultList->topLevelItem(0) );
98 mResultList->scrollToItem( mResultList->topLevelItem(0) );
102 bool LookupDialog::performClassQuery(const QString & className)
104 using namespace ScLanguage;
106 mResultList->clear();
108 const Introspection & introspection = Main::scProcess()->introspection();
110 const Class *klass = introspection.findClass(className);
111 if (!klass)
112 return false;
114 QColor pathColor = palette().color(QPalette::Light);
116 while (klass) {
117 Class *metaClass = klass->metaClass;
119 QString displayPath = introspection.compactLibraryPath(klass->definition.path);
121 QTreeWidgetItem *classItem = new QTreeWidgetItem( QStringList() << klass->name.get() << displayPath );
122 classItem->setData( 0, Qt::UserRole, klass->definition.path.get() );
123 classItem->setData( 0, Qt::UserRole+1, klass->definition.position );
124 classItem->setData( 1, Qt::ForegroundRole, pathColor );
125 mResultList->addTopLevelItem(classItem);
127 foreach (const Method * method, metaClass->methods) {
128 QString signature = method->signature( Method::SignatureWithoutArguments );
129 QString displayPath = introspection.compactLibraryPath(method->definition.path);
131 QTreeWidgetItem *methodItem = new QTreeWidgetItem( QStringList() << signature << displayPath );
132 methodItem->setData( 0, Qt::UserRole, method->definition.path.get() );
133 methodItem->setData( 0, Qt::UserRole+1, method->definition.position );
134 methodItem->setData( 1, Qt::ForegroundRole, pathColor );
135 mResultList->addTopLevelItem(methodItem);
138 foreach (const Method * method, klass->methods) {
139 QString signature = method->signature( Method::SignatureWithoutArguments );
140 QString displayPath = introspection.compactLibraryPath(method->definition.path);
142 QTreeWidgetItem *methodItem = new QTreeWidgetItem( QStringList() << signature << displayPath );
143 methodItem->setData( 0, Qt::UserRole, method->definition.path.get() );
144 methodItem->setData( 0, Qt::UserRole+1, method->definition.position );
145 methodItem->setData( 1, Qt::ForegroundRole, pathColor );
146 mResultList->addTopLevelItem(methodItem);
149 klass = klass->superClass;
152 return true;
155 bool LookupDialog::performMethodQuery(const QString & methodName)
157 using namespace ScLanguage;
158 using std::pair;
160 mResultList->clear();
162 const Introspection & introspection = Main::scProcess()->introspection();
163 const MethodMap & methods = introspection.methodMap();
165 pair<MethodMap::const_iterator, MethodMap::const_iterator> matchingMethods =
166 methods.equal_range(methodName);
168 if (matchingMethods.first == matchingMethods.second) {
169 qWarning("Method not defined!");
170 return false;
173 QColor pathColor = palette().color(QPalette::Light);
175 for (MethodMap::const_iterator it = matchingMethods.first;
176 it != matchingMethods.second; ++it) {
177 Method *method = it->second.data();
179 const QString & path = method->definition.path;
180 QString displayPath = introspection.compactLibraryPath(path);
182 QTreeWidgetItem *item = new QTreeWidgetItem (
183 mResultList,
184 QStringList()
185 << method->signature(Method::SignatureWithoutArguments)
186 << displayPath
189 item->setData( 0, Qt::UserRole, path );
190 item->setData( 0, Qt::UserRole + 1, method->definition.position );
191 item->setData( 1, Qt::ForegroundRole, pathColor );
194 mResultList->model()->sort(0);
196 return true;
199 void LookupDialog::onAccepted()
201 QTreeWidgetItem *currentItem = mResultList->currentItem();
202 if (!currentItem)
203 return;
205 QString path = currentItem->data( 0, Qt::UserRole ).toString();
206 int pos = currentItem->data( 0, Qt::UserRole + 1 ).toInt();
208 Main::documentManager()->open(path, pos);
211 bool LookupDialog::eventFilter( QObject *object, QEvent *event )
213 if (object == mResultList && event->type() == QEvent::KeyPress) {
214 QKeyEvent *ke = static_cast<QKeyEvent*>(event);
215 switch(ke->key()){
216 case Qt::Key_Enter:
217 case Qt::Key_Return:
218 accept();
219 return true;
220 default:;
224 return QDialog::eventFilter(object,event);
227 void LookupDialog::paintEvent( QPaintEvent * )
229 QPainter painter(this);
230 painter.setBrush(Qt::NoBrush);
231 painter.setPen(palette().color(QPalette::Dark));
232 painter.drawRect(rect().adjusted(0,0,-1,-1));
235 } // namespace ScIDE