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 "main_window.hpp"
23 #include "../core/sc_introspection.hpp"
24 #include "../core/main.hpp"
26 #include <QVBoxLayout>
27 #include <QHeaderView>
29 #include <QDesktopWidget>
30 #include <QApplication>
35 GenericLookupDialog::GenericLookupDialog( QWidget
* parent
):
36 QDialog(parent
, Qt::Popup
| Qt::FramelessWindowHint
)
38 mQueryEdit
= new QLineEdit(this);
40 mResult
= new QTreeView(this);
41 mResult
->setRootIsDecorated(false);
42 mResult
->setAllColumnsShowFocus(true);
43 mResult
->setHeaderHidden(true);
44 mResult
->header()->setStretchLastSection(false);
46 QVBoxLayout
*layout
= new QVBoxLayout
;
47 layout
->setContentsMargins(4,4,4,4);
48 layout
->setSpacing(1);
49 layout
->addWidget(mQueryEdit
);
50 layout
->addWidget(mResult
);
53 connect(mQueryEdit
, SIGNAL(returnPressed()), this, SLOT(performQuery()));
54 connect(mResult
, SIGNAL(doubleClicked(QModelIndex
)), this, SLOT(onAccepted(QModelIndex
)));
55 connect(mResult
, SIGNAL(activated(QModelIndex
)), this, SLOT(onAccepted(QModelIndex
)));
57 mResult
->installEventFilter(this);
59 QRect
bounds(0,0,600,300);
61 QRect parentRect
= parent
->rect();
62 bounds
.moveCenter( parent
->mapToGlobal( parentRect
.center() ) );
64 QRect availableBounds
= QApplication::desktop()->availableGeometry(this);
65 bounds
.moveCenter( availableBounds
.center() );
70 mQueryEdit
->setFocus( Qt::OtherFocusReason
);
73 void GenericLookupDialog::onAccepted(QModelIndex currentIndex
)
75 QStandardItemModel
* model
= qobject_cast
<QStandardItemModel
*>(mResult
->model());
76 currentIndex
= currentIndex
.sibling(currentIndex
.row(), 0);
77 QStandardItem
*currentItem
= model
->itemFromIndex(currentIndex
);
83 QString path
= currentItem
->data( PathRole
).toString();
84 int pos
= currentItem
->data( CharPosRole
).toInt();
86 Main::documentManager()->open(path
, pos
);
90 bool GenericLookupDialog::eventFilter( QObject
*object
, QEvent
*event
)
92 if (object
== mResult
&& event
->type() == QEvent::KeyPress
) {
93 QKeyEvent
*ke
= static_cast<QKeyEvent
*>(event
);
97 onAccepted(mResult
->currentIndex());
103 return QDialog::eventFilter(object
,event
);
106 void GenericLookupDialog::paintEvent( QPaintEvent
* )
108 QPainter
painter(this);
109 painter
.setBrush(Qt::NoBrush
);
110 painter
.setPen(palette().color(QPalette::Dark
));
111 painter
.drawRect(rect().adjusted(0,0,-1,-1));
114 void GenericLookupDialog::focusResults()
116 mResult
->header()->resizeSections(QHeaderView::ResizeToContents
);
117 mResult
->setFocus(Qt::OtherFocusReason
);
119 QStandardItemModel
* model
= qobject_cast
<QStandardItemModel
*>(mResult
->model());
120 QStandardItem
* firstItem
= model
->item(0, 0);
122 QModelIndex firstIndex
= model
->indexFromItem(firstItem
);
123 mResult
->setCurrentIndex(firstIndex
);
127 using namespace ScLanguage
;
131 LookupDialog::LookupDialog( QWidget
* parent
):
132 GenericLookupDialog(parent
)
134 setWindowTitle(tr("Look Up Class or Method Definition"));
136 mQueryEdit
->setText(tr("Enter symbol to look up"));
137 mQueryEdit
->selectAll();
140 void LookupDialog::performQuery()
142 QString queryString
= mQueryEdit
->text();
144 if (queryString
.isEmpty()) {
145 mResult
->setModel(NULL
);
149 const Introspection
& introspection
= Main::scProcess()->introspection();
150 if (!introspection
.introspectionAvailable()) {
151 MainWindow::instance()->showStatusMessage("Introspection Data not available");
155 if (queryString
[0].isUpper()) {
156 bool success
= performClassQuery(queryString
);
162 bool success
= performMethodQuery(queryString
);
169 bool success
= performPartialQuery(queryString
);
174 QList
<QStandardItem
*> GenericLookupDialog::makeDialogItem( QString
const & name
, QString
const & displayPath
,
175 QString
const & path
, int position
)
177 QStandardItem
* item
= new QStandardItem( name
);
178 item
->setData( path
, PathRole
);
179 item
->setData( position
, CharPosRole
);
180 QStandardItem
* pathItem
= new QStandardItem(displayPath
);
182 QList
<QStandardItem
*> ret
;
183 ret
<< item
<< pathItem
;
188 QStandardItemModel
* LookupDialog::modelForClass(const QString
&className
)
190 const Introspection
& introspection
= Main::scProcess()->introspection();
191 const Class
*klass
= introspection
.findClass(className
);
196 QStandardItemModel
* model
= new QStandardItemModel(this);
197 QStandardItem
*parentItem
= model
->invisibleRootItem();
200 Class
*metaClass
= klass
->metaClass
;
202 QString displayPath
= introspection
.compactLibraryPath(klass
->definition
.path
);
204 parentItem
->appendRow(makeDialogItem(klass
->name
.get(), displayPath
,
205 klass
->definition
.path
.get(),
206 klass
->definition
.position
));
208 foreach (const Method
* method
, metaClass
->methods
) {
209 QString signature
= method
->signature( Method::SignatureWithoutArguments
);
210 QString displayPath
= introspection
.compactLibraryPath(method
->definition
.path
);
212 parentItem
->appendRow(makeDialogItem( signature
, displayPath
,
213 method
->definition
.path
.get(),
214 method
->definition
.position
));
217 foreach (const Method
* method
, klass
->methods
) {
218 QString signature
= method
->signature( Method::SignatureWithoutArguments
);
219 QString displayPath
= introspection
.compactLibraryPath(method
->definition
.path
);
221 parentItem
->appendRow(makeDialogItem( signature
, displayPath
,
222 method
->definition
.path
.get(),
223 method
->definition
.position
));
226 klass
= klass
->superClass
;
232 QStandardItemModel
* LookupDialog::modelForMethod(const QString
& methodName
)
234 const Introspection
& introspection
= Main::scProcess()->introspection();
236 const MethodMap
& methods
= introspection
.methodMap();
237 pair
<MethodMap::const_iterator
, MethodMap::const_iterator
> matchingMethods
= methods
.equal_range(methodName
);
239 if (matchingMethods
.first
== matchingMethods
.second
)
242 QStandardItemModel
* model
= new QStandardItemModel(this);
243 QStandardItem
*parentItem
= model
->invisibleRootItem();
245 for (MethodMap::const_iterator it
= matchingMethods
.first
; it
!= matchingMethods
.second
; ++it
) {
246 Method
*method
= it
->second
.data();
247 QString signature
= method
->signature( Method::SignatureWithoutArguments
);
249 const QString
& path
= method
->definition
.path
;
250 QString displayPath
= introspection
.compactLibraryPath(path
);
252 parentItem
->appendRow(makeDialogItem( signature
, displayPath
,
253 method
->definition
.path
.get(),
254 method
->definition
.position
));
261 QStandardItemModel
* LookupDialog::modelForCaseInsensitiveQuery(const QString
& queryString
)
263 const Introspection
& introspection
= Main::scProcess()->introspection();
264 vector
<const Class
*> classes
= introspection
.findClassPartial(queryString
);
265 vector
<const Method
*> methods
= introspection
.findMethodPartial(queryString
);
266 typedef vector
<const Method
*>::const_iterator MethodIterator
;
267 typedef vector
<const Class
*>::const_iterator ClassIterator
;
269 if (classes
.empty() && methods
.empty()) {
270 MainWindow::instance()->showStatusMessage("No result for query");
274 QStandardItemModel
* model
= new QStandardItemModel(this);
275 QStandardItem
*parentItem
= model
->invisibleRootItem();
277 for (MethodIterator it
= methods
.begin(); it
!= methods
.end(); ++it
) {
278 const Method
*method
= *it
;
279 QString signature
= method
->signature( Method::SignatureWithoutArguments
);
281 const QString
& path
= method
->definition
.path
;
282 QString displayPath
= introspection
.compactLibraryPath(path
);
284 parentItem
->appendRow(makeDialogItem( signature
, displayPath
,
285 method
->definition
.path
.get(),
286 method
->definition
.position
));
289 for (ClassIterator it
= classes
.begin(); it
!= classes
.end(); ++it
) {
290 const Class
* klass
= *it
;
291 QString displayPath
= introspection
.compactLibraryPath(klass
->definition
.path
);
293 parentItem
->appendRow(makeDialogItem(klass
->name
.get(), displayPath
,
294 klass
->definition
.path
.get(),
295 klass
->definition
.position
));
302 bool LookupDialog::performClassQuery(const QString
& className
)
304 QStandardItemModel
* model
= modelForClass(className
);
305 mResult
->setModel(model
);
309 bool LookupDialog::performMethodQuery(const QString
& methodName
)
311 QStandardItemModel
* model
= modelForMethod(methodName
);
312 mResult
->setModel(model
);
316 bool LookupDialog::performPartialQuery(const QString
& queryString
)
318 QStandardItemModel
* model
= modelForCaseInsensitiveQuery(queryString
);
319 mResult
->setModel(model
);