diff --git a/editors/sc-ide/core/sc_introspection.cpp b/editors/sc-ide/core/sc_introspection.cpp index 655200dec74..c201c609134 100644 --- a/editors/sc-ide/core/sc_introspection.cpp +++ b/editors/sc-ide/core/sc_introspection.cpp @@ -294,6 +294,12 @@ Introspection::ClassMethodMap Introspection::constructMethodMap(const Class * kl } return methodMap; } + +bool Method::matches(const QString& toMatch) const +{ + return toMatch.isEmpty() ? true : name.get().startsWith(toMatch, Qt::CaseInsensitive); +} + QString Method::signature( SignatureStyle style ) const { diff --git a/editors/sc-ide/core/sc_introspection.hpp b/editors/sc-ide/core/sc_introspection.hpp index b04f64f2f14..8c707f8a5b3 100644 --- a/editors/sc-ide/core/sc_introspection.hpp +++ b/editors/sc-ide/core/sc_introspection.hpp @@ -84,7 +84,8 @@ struct Method { SignatureWithArgumentsAndDefaultValues }; - QString signature( SignatureStyle style ) const; + QString signature( SignatureStyle style ) const; + bool matches(const QString& toMatch) const; Class *ownerClass; FlyweightString name; diff --git a/editors/sc-ide/widgets/code_editor/sc_editor.cpp b/editors/sc-ide/widgets/code_editor/sc_editor.cpp index 5032d92fa87..69be568061a 100644 --- a/editors/sc-ide/widgets/code_editor/sc_editor.cpp +++ b/editors/sc-ide/widgets/code_editor/sc_editor.cpp @@ -84,9 +84,11 @@ bool ScCodeEditor::event( QEvent *e ) QKeyEvent *ke = static_cast(e); switch (ke->key()) { case Qt::Key_Tab: - indent(); - e->accept(); - return true; + if (!tabChangesFocus()) { + indent(); + e->accept(); + return true; + } default: break; } diff --git a/editors/sc-ide/widgets/lookup_dialog.cpp b/editors/sc-ide/widgets/lookup_dialog.cpp index f4fc9399816..b9431b09002 100644 --- a/editors/sc-ide/widgets/lookup_dialog.cpp +++ b/editors/sc-ide/widgets/lookup_dialog.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "yaml-cpp/node.h" #include "yaml-cpp/parser.h" @@ -47,12 +48,20 @@ GenericLookupDialog::GenericLookupDialog( QWidget * parent ): mResult->setAllColumnsShowFocus(true); mResult->setHeaderHidden(true); mResult->header()->setStretchLastSection(false); - + + mPreviewDocument = new Document(false); + mPreviewEditor = new ScCodeEditor(mPreviewDocument); + mPreviewEditor->setReadOnly(true); + mPreviewEditor->setVisible(false); + mPreviewEditor->setTabChangesFocus(true); + QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(0,0,0,0); layout->setSpacing(1); - layout->addWidget(mQueryEdit); - layout->addWidget(mResult); + layout->addWidget(mQueryEdit, 0); + layout->addWidget(mResult, 2); + layout->addWidget(mPreviewEditor, 1); + setLayout(layout); connect(mQueryEdit, SIGNAL(returnPressed()), this, SLOT(performQuery())); @@ -74,6 +83,58 @@ GenericLookupDialog::GenericLookupDialog( QWidget * parent ): mQueryEdit->setFocus( Qt::OtherFocusReason ); } + +void GenericLookupDialog::setModel(QStandardItemModel* model) { + if (mResult->selectionModel()) { + disconnect(mResult->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(currentChanged(const QModelIndex &, const QModelIndex &))); + } + + mResult->setModel(model); + + if (mResult->selectionModel()) { + mPreviewEditor->setActiveAppearance(true); + connect(mResult->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(currentChanged(const QModelIndex &, const QModelIndex &))); + } else { + mPreviewEditor->setActiveAppearance(false); + } +} + +void GenericLookupDialog::currentChanged(const QModelIndex &item, const QModelIndex &oldItem) +{ + QString path = item.data( PathRole ).toString(); + int pos = item.data( CharPosRole ).toInt(); + + QFileInfo info(path); + QString cpath = info.canonicalFilePath(); + info.setFile(cpath); + + if (cpath.isEmpty()) { + MainWindow::instance()->showStatusMessage ( + tr("Cannot open file: %1 (file does not exist)").arg(path) ); + return; + } + + // Open the file + QFile file(cpath); + if(!file.open(QIODevice::ReadOnly)) { + MainWindow::instance()->showStatusMessage( + tr("Cannot open file for reading: %1").arg(cpath)); + return; + } + + QByteArray bytes( file.readAll() ); + file.close(); + + QTextStream stream(bytes); + stream.setCodec("UTF-8"); + stream.setAutoDetectUnicode(true); + + mPreviewDocument->setTextInRange( stream.readAll(), 0, -1 ); + mPreviewEditor->showPosition(pos, 0); + mPreviewEditor->selectCurrentRegion(); +} bool GenericLookupDialog::openDocumentation() { @@ -187,7 +248,7 @@ void LookupDialog::performQuery() QString queryString = mQueryEdit->text(); if (queryString.isEmpty()) { - mResult->setModel(NULL); + setModel(NULL); return; } @@ -200,12 +261,16 @@ void LookupDialog::performQuery() mIsPartialQuery = false; if (queryString[0].isUpper()) { bool success = performClassQuery(queryString); + mPreviewEditor->setVisible(success); + if (success) { focusResults(); return; } } else { bool success = performMethodQuery(queryString); + mPreviewEditor->setVisible(success); + if (success) { focusResults(); return; @@ -213,6 +278,7 @@ void LookupDialog::performQuery() } bool success = performPartialQuery(queryString); + mPreviewEditor->setVisible(success); if (success) focusResults(); } @@ -265,7 +331,7 @@ QList GenericLookupDialog::makeDialogItem( QString const & displ return ret; } -QStandardItemModel * LookupDialog::modelForClass(const QString &className) +QStandardItemModel * LookupDialog::modelForClass(const QString &className, const QString &methodName) { const Introspection & introspection = Main::scProcess()->introspection(); const Class *klass = introspection.findClass(className); @@ -281,32 +347,39 @@ QStandardItemModel * LookupDialog::modelForClass(const QString &className) QString displayPath = introspection.compactLibraryPath(klass->definition.path); - parentItem->appendRow(makeDialogItem(klass->name.get(), displayPath, - klass->definition.path.get(), - klass->definition.position, - klass->name.get(), QString(""), - true )); + if (methodName.isEmpty()) { + parentItem->appendRow(makeDialogItem(klass->name.get(), displayPath, + klass->definition.path.get(), + klass->definition.position, + klass->name.get(), QString(""), + true )); + } foreach (const Method * method, metaClass->methods) { QString signature = method->signature( Method::SignatureWithoutArguments ); QString displayPath = introspection.compactLibraryPath(method->definition.path); - - parentItem->appendRow(makeDialogItem( signature, displayPath, - method->definition.path.get(), - method->definition.position, - metaClass->name.get(), method->name.get(), - false )); + + if (method->matches(methodName)) { + parentItem->appendRow(makeDialogItem( signature, displayPath, + method->definition.path.get(), + method->definition.position, + metaClass->name.get(), method->name.get(), + false )); + } } foreach (const Method * method, klass->methods) { QString signature = method->signature( Method::SignatureWithoutArguments ); QString displayPath = introspection.compactLibraryPath(method->definition.path); - parentItem->appendRow(makeDialogItem( signature, displayPath, - method->definition.path.get(), - method->definition.position, - klass->name.get(), method->name.get(), - false )); + + if (method->matches(methodName)) { + parentItem->appendRow(makeDialogItem( signature, displayPath, + method->definition.path.get(), + method->definition.position, + klass->name.get(), method->name.get(), + false )); + } } klass = klass->superClass; @@ -394,22 +467,28 @@ QStandardItemModel * LookupDialog::modelForPartialQuery(const QString & queryStr bool LookupDialog::performClassQuery(const QString & className) { - QStandardItemModel * model = modelForClass(className); - mResult->setModel(model); + QStandardItemModel * model; + if (className.contains(QChar(':'))) { + QStringList split = className.split(":"); + model = modelForClass(split[0].trimmed(), split[1].trimmed()); + } else { + model = modelForClass(className); + } + setModel(model); return model; } bool LookupDialog::performMethodQuery(const QString & methodName) { QStandardItemModel * model = modelForMethod(methodName); - mResult->setModel(model); + setModel(model); return model; } bool LookupDialog::performPartialQuery(const QString & queryString) { QStandardItemModel * model = modelForPartialQuery(queryString); - mResult->setModel(model); + setModel(model); return model; } @@ -432,7 +511,7 @@ void ReferencesDialog::performQuery() QString queryString = mQueryEdit->text(); if (queryString.isEmpty()) { - mResult->setModel(NULL); + setModel(NULL); return; } @@ -441,13 +520,13 @@ void ReferencesDialog::performQuery() void ReferencesDialog::requestCancelled() { - mResult->setModel(NULL); + setModel(NULL); } void ReferencesDialog::onResposeFromLanguage(const QString &, const QString &responseData) { QStandardItemModel * model = parse(responseData); - mResult->setModel(model); + setModel(model); if (model) focusResults(); diff --git a/editors/sc-ide/widgets/lookup_dialog.hpp b/editors/sc-ide/widgets/lookup_dialog.hpp index 58e90d07dc1..5bad27b9c28 100644 --- a/editors/sc-ide/widgets/lookup_dialog.hpp +++ b/editors/sc-ide/widgets/lookup_dialog.hpp @@ -27,6 +27,7 @@ #include #include "../core/sc_process.hpp" +#include "code_editor/sc_editor.hpp" namespace ScIDE { @@ -44,12 +45,14 @@ class GenericLookupDialog: public QDialog explicit GenericLookupDialog(QWidget *parent = 0); void query( const QString & query ) { mQueryEdit->setText(query); this->performQuery(); } void clearQuery() { mQueryEdit->clear(); } + void setModel(QStandardItemModel*); public Q_SLOTS: bool openDocumentation(); protected Q_SLOTS: virtual void onAccepted(QModelIndex); + void currentChanged(const QModelIndex &, const QModelIndex &); private Q_SLOTS: virtual void performQuery() = 0; @@ -67,6 +70,8 @@ private Q_SLOTS: QTreeView *mResult; QLineEdit *mQueryEdit; + Document *mPreviewDocument; + ScCodeEditor *mPreviewEditor; }; class LookupDialog : public GenericLookupDialog @@ -81,7 +86,7 @@ private slots: void onAccepted(QModelIndex); private: - QStandardItemModel * modelForClass(const QString & className); + QStandardItemModel * modelForClass(const QString & className, const QString & methodName = QString()); QStandardItemModel * modelForMethod(const QString & methodName); QStandardItemModel * modelForPartialQuery(const QString & queryString); bool performClassQuery(const QString & className);