ecode: Implemented workspace symbol search.

This commit is contained in:
Martín Lucas Golini
2023-02-28 02:03:32 -03:00
parent ec4d5e87de
commit 52803abcba
14 changed files with 345 additions and 40 deletions
+4 -3
View File
@@ -51,11 +51,12 @@ class CommandPalette {
const std::shared_ptr<CommandPaletteModel>& getEditorModel() const;
void setCommandPaletteEditor(const std::vector<std::vector<std::string> >& commandPaletteEditor);
void
setCommandPaletteEditor( const std::vector<std::vector<std::string>>& commandPaletteEditor );
void setCurModel(const std::shared_ptr<CommandPaletteModel>& curModel);
void setCurModel( const std::shared_ptr<CommandPaletteModel>& curModel );
protected:
protected:
mutable Mutex mMatchingMutex;
std::shared_ptr<ThreadPool> mPool;
std::vector<std::vector<std::string>> mCommandPalette;
+5 -1
View File
@@ -3118,7 +3118,11 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe
{ "symbol-constant", 0xeb5d }, { "symbol-struct", 0xea91 },
{ "symbol-event", 0xea86 }, { "symbol-operator", 0xeb64 },
{ "symbol-type-parameter", 0xea92 }, { "expand-all", 0xeb95 },
{ "collapse-all", 0xeac5 },
{ "symbol-namespace", 0xea8b }, { "symbol-package", 0xea8b },
{ "symbol-string", 0xeb8d }, { "symbol-number", 0xea90 },
{ "symbol-boolean", 0xea8f }, { "symbol-array", 0xea8a },
{ "symbol-object", 0xea8b }, { "symbol-key", 0xea93 },
{ "symbol-null", 0xea8f }, { "collapse-all", 0xeac5 },
};
for ( const auto& icon : codIcons )
+156 -7
View File
@@ -3,6 +3,77 @@
namespace ecode {
class LSPSymbolInfoModel : public Model {
public:
static std::shared_ptr<LSPSymbolInfoModel>
create( UISceneNode* uiSceneNode, const std::string& query,
const std::vector<LSPSymbolInformation>& data ) {
return std::make_shared<LSPSymbolInfoModel>( uiSceneNode, query, data );
}
explicit LSPSymbolInfoModel( UISceneNode* uiSceneNode, const std::string& query,
const std::vector<LSPSymbolInformation>& info ) :
mUISceneNode( uiSceneNode ), mQuery( query ), mInfo( info ) {}
size_t rowCount( const ModelIndex& ) const override { return mInfo.size(); };
size_t columnCount( const ModelIndex& ) const override { return 2; }
Variant data( const ModelIndex& index, ModelRole role ) const override {
if ( index.row() >= (Int64)mInfo.size() )
return {};
if ( role == ModelRole::Display ) {
switch ( index.column() ) {
case 0:
return Variant( mInfo[index.row()].name.c_str() );
case 1:
return Variant( mInfo[index.row()].url.getFSPath() );
}
} else if ( role == ModelRole::Icon && index.column() == 0 ) {
return mUISceneNode->findIcon(
LSPSymbolKindHelper::toIconString( mInfo[index.row()].kind ) );
} else if ( role == ModelRole::Custom && index.column() == 1 ) {
return Variant( mInfo[index.row()].range.toString() );
}
return {};
}
void update() override { onModelUpdate(); }
const std::vector<LSPSymbolInformation>& getInfo() const { return mInfo; }
LSPSymbolInformation at( const size_t& idx ) {
eeASSERT( idx < mInfo.size() );
return mInfo[idx];
}
const std::string& getQuery() const { return mQuery; }
void append( const std::vector<LSPSymbolInformation>& res ) {
mInfo.insert( mInfo.end(), res.begin(), res.end() );
std::sort( mInfo.begin(), mInfo.end(),
[]( const LSPSymbolInformation& l, const LSPSymbolInformation& r ) {
return l.score > r.score;
} );
onModelUpdate();
}
void setQuery( const std::string& query ) {
if ( mQuery != query ) {
mQuery = query;
clear();
onModelUpdate();
}
}
void clear() { mInfo.clear(); }
protected:
UISceneNode* mUISceneNode{ nullptr };
std::string mQuery;
std::vector<LSPSymbolInformation> mInfo;
};
static int LOCATEBAR_MAX_VISIBLE_ITEMS = 18;
static int LOCATEBAR_MAX_RESULTS = 100;
@@ -10,7 +81,11 @@ FileLocator::FileLocator( UICodeEditorSplitter* editorSplitter, UISceneNode* sce
mSplitter( editorSplitter ),
mUISceneNode( sceneNode ),
mApp( app ),
mCommandPalette( mApp->getThreadPool() ) {}
mCommandPalette( mApp->getThreadPool() ) {
mApp->getPluginManager()->subscribeMessages(
"universallocator",
[&]( const PluginMessage& msg ) -> PluginRequestHandle { return processResponse( msg ); } );
}
void FileLocator::hideLocateBar() {
mLocateBarLayout->setVisible( false );
@@ -32,6 +107,7 @@ void FileLocator::updateFilesTable() {
mLocateTable->setModel(
mApp->getDirTree()->fuzzyMatchTree( mLocateInput->getText(), LOCATEBAR_MAX_RESULTS ) );
mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) );
mLocateTable->scrollToTop();
#endif
} else {
mLocateTable->setModel( mApp->getDirTree()->asModel( LOCATEBAR_MAX_RESULTS ) );
@@ -56,7 +132,6 @@ void FileLocator::updateCommandPaletteTable() {
txt.trim();
if ( txt.size() > 1 ) {
#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ )
mCommandPalette.asyncFuzzyMatch( txt.substr( 1 ), 1000, [&]( auto res ) {
mUISceneNode->runOnMainThread( [&, res] {
@@ -68,6 +143,7 @@ void FileLocator::updateCommandPaletteTable() {
#else
mLocateTable->setModel( mCommandPalette.fuzzyMatch( txt.substr(), 1000 ) );
mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) );
mLocateTable->scrollToTop();
#endif
} else if ( mCommandPalette.getCurModel() ) {
mLocateTable->setModel( mCommandPalette.getCurModel() );
@@ -118,6 +194,8 @@ void FileLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locateInpu
}
} else if ( !txt.empty() && mLocateInput->getText()[0] == '>' ) {
showCommandPalette();
} else if ( !txt.empty() && mLocateInput->getText()[0] == ':' ) {
showWorkspaceSymbol();
} else {
showLocateTable();
if ( !mApp->isDirTreeReady() )
@@ -168,15 +246,30 @@ void FileLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locateInpu
Variant vPath( modelEvent->getModel()->data(
modelEvent->getModel()->index( modelEvent->getModelIndex().row(), 1 ),
ModelRole::Display ) );
if ( vPath.isValid() && vPath.is( Variant::Type::cstr ) ) {
std::string path( vPath.asCStr() );
if ( vPath.isValid() ) {
std::string path( vPath.is( Variant::Type::cstr ) ? vPath.asCStr()
: vPath.asStdString() );
Variant rangeStr( modelEvent->getModel()->data(
modelEvent->getModel()->index( modelEvent->getModelIndex().row(), 1 ),
ModelRole::Custom ) );
auto range = rangeStr.isValid()
? TextRange::fromString( rangeStr.asStdString() )
: TextRange();
UITab* tab = mSplitter->isDocumentOpen( path, true );
if ( !tab ) {
FileInfo fileInfo( path );
if ( fileInfo.exists() && fileInfo.isRegularFile() )
mApp->loadFileFromPath( path );
mApp->loadFileFromPath( path, true, nullptr,
[range]( UICodeEditor* editor, auto ) {
if ( range.isValid() )
editor->goToLine( range.start() );
} );
} else {
tab->getTabWidget()->setTabSelected( tab );
if ( range.isValid() ) {
UICodeEditor* editor = tab->getOwnedWidget()->asType<UICodeEditor>();
editor->goToLine( range.start() );
}
}
mLocateBarLayout->execute( "close-locatebar" );
}
@@ -209,7 +302,7 @@ void FileLocator::showBar() {
mLocateTable->setVisible( true );
const String& text = mLocateInput->getText();
if ( !text.empty() && text[0] == '>' ) {
if ( !text.empty() && ( text[0] == '>' || text[0] == ':' ) ) {
Int64 selectFrom = 1;
if ( text.size() >= 2 && text[1] == ' ' )
selectFrom = 2;
@@ -228,7 +321,8 @@ void FileLocator::showBar() {
void FileLocator::showLocateBar() {
showBar();
if ( !mLocateInput->getText().empty() && mLocateInput->getText()[0] == '>' )
if ( !mLocateInput->getText().empty() &&
( mLocateInput->getText()[0] == '>' || mLocateInput->getText()[0] == ':' ) )
mLocateInput->setText( "" );
if ( mApp->getDirTree() && !mLocateTable->getModel() ) {
@@ -249,4 +343,59 @@ void FileLocator::showCommandPalette() {
updateLocateBar();
}
void FileLocator::showWorkspaceSymbol() {
showBar();
if ( mLocateInput->getText().empty() || mLocateInput->getText()[0] != ':' )
mLocateInput->setText( ": " );
requestWorkspaceSymbol();
updateLocateBar();
}
void FileLocator::requestWorkspaceSymbol() {
if ( mLocateInput->getText().empty() )
return;
auto txt( mLocateInput->getText().substr( 1 ).trim() );
if ( mWorkspaceSymbolQuery != txt.toUtf8() || mWorkspaceSymbolQuery.empty() ) {
mWorkspaceSymbolQuery = txt.toUtf8();
if ( mWorkspaceSymbolModel ) {
mWorkspaceSymbolModel->setQuery( mWorkspaceSymbolQuery );
} else {
mWorkspaceSymbolModel =
LSPSymbolInfoModel::create( mApp->getUISceneNode(), mWorkspaceSymbolQuery, {} );
}
json j = json{ json{ "query", mWorkspaceSymbolQuery } };
mApp->getPluginManager()->sendRequest( PluginMessageType::WorkspaceSymbol,
PluginMessageFormat::JSON, &j );
}
}
void FileLocator::updateWorkspaceSymbol( const std::vector<LSPSymbolInformation>& res ) {
#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ )
mUISceneNode->runOnMainThread( [&, res] {
if ( !mWorkspaceSymbolModel ) {
mWorkspaceSymbolModel =
LSPSymbolInfoModel::create( mApp->getUISceneNode(), mWorkspaceSymbolQuery, res );
} else {
mWorkspaceSymbolModel->append( res );
}
mLocateTable->setModel( mWorkspaceSymbolModel );
mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) );
mLocateTable->scrollToTop();
} );
#else
mLocateTable->setModel( mWorkspaceSymbolModel );
mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) );
mLocateTable->scrollToTop();
#endif
}
PluginRequestHandle FileLocator::processResponse( const PluginMessage& msg ) {
if ( msg.isResponse() && msg.type == PluginMessageType::WorkspaceSymbol ) {
updateWorkspaceSymbol( msg.asSymbolInformation() );
}
return {};
}
} // namespace ecode
+12
View File
@@ -2,12 +2,14 @@
#define ECODE_FILELOCATOR_HPP
#include "commandpalette.hpp"
#include "plugins/pluginmanager.hpp"
#include "widgetcommandexecuter.hpp"
#include <eepp/ee.hpp>
namespace ecode {
class App;
class LSPSymbolInfoModel;
class FileLocator {
public:
@@ -29,18 +31,28 @@ class FileLocator {
void showLocateTable();
void showWorkspaceSymbol();
protected:
UILocateBar* mLocateBarLayout{ nullptr };
UITableView* mLocateTable{ nullptr };
UITextInput* mLocateInput{ nullptr };
UICodeEditorSplitter* mSplitter{ nullptr };
UISceneNode* mUISceneNode{ nullptr };
std::shared_ptr<LSPSymbolInfoModel> mWorkspaceSymbolModel{ nullptr };
std::string mWorkspaceSymbolQuery;
App* mApp{ nullptr };
CommandPalette mCommandPalette;
void updateLocateBar();
void showBar();
PluginRequestHandle processResponse( const PluginMessage& msg );
void requestWorkspaceSymbol();
void updateWorkspaceSymbol( const std::vector<LSPSymbolInformation>& info );
};
} // namespace ecode
@@ -248,6 +248,26 @@ PluginRequestHandle LSPClientPlugin::processDocumentFormatting( const PluginMess
return ret;
}
PluginRequestHandle LSPClientPlugin::processWorkspaceSymbol( const PluginMessage& msg ) {
if ( !msg.isRequest() || !msg.isJSON() )
return {};
auto servers = mClientManager.getAllRunningServers();
if ( servers.empty() )
return {};
for ( const auto server : servers ) {
server->workspaceSymbol(
msg.asJSON().value( "query", "" ),
[&]( const PluginIDType& id, const std::vector<LSPSymbolInformation>& info ) {
mManager->sendResponse( this, PluginMessageType::WorkspaceSymbol,
PluginMessageFormat::SymbolInformation, &info, id );
} );
}
return {};
}
bool LSPClientPlugin::processDocumentFormattingResponse( const URI& uri,
std::vector<LSPTextEdit> edits ) {
auto doc = mManager->getSplitter()->findDocFromURI( uri );
@@ -467,6 +487,12 @@ PluginRequestHandle LSPClientPlugin::processMessage( const PluginMessage& msg )
processCancelRequest( msg );
break;
}
case PluginMessageType::WorkspaceSymbol: {
auto ret = processWorkspaceSymbol( msg );
if ( !ret.isEmpty() )
return ret;
break;
}
default:
break;
}
@@ -117,6 +117,8 @@ class LSPClientPlugin : public UICodeEditorPlugin {
PluginRequestHandle processDocumentFormatting( const PluginMessage& msg );
PluginRequestHandle processWorkspaceSymbol( const PluginMessage& msg );
void tryHideTooltip( UICodeEditor* editor, const Vector2i& position );
void hideTooltip( UICodeEditor* editor );
+32 -24
View File
@@ -48,6 +48,7 @@ static const char* MEMBER_TARGET_SELECTION_RANGE = "targetSelectionRange";
static const char* MEMBER_PREVIOUS_RESULT_ID = "previousResultId";
static const char* MEMBER_QUERY = "query";
static const char* MEMBER_SUCCESS = "success";
static const char* MEMBER_LIMIT = "limit";
static json newRequest( const std::string& method, const json& params = json{} ) {
json j;
@@ -392,24 +393,23 @@ static std::vector<LSPSymbolInformation> parseWorkspaceSymbols( const json& res
std::vector<LSPSymbolInformation> symbols;
symbols.reserve( res.size() );
std::transform(
res.cbegin(), res.cend(), std::back_inserter( symbols ), []( const json& symbol ) {
LSPSymbolInformation symInfo;
std::transform( res.cbegin(), res.cend(), std::back_inserter( symbols ),
[]( const json& symbol ) {
LSPSymbolInformation symInfo;
const auto& location = symbol.at( MEMBER_LOCATION );
const auto& mrange = symbol.contains( MEMBER_RANGE ) ? symbol.at( MEMBER_RANGE )
: location.at( MEMBER_RANGE );
const auto& location = symbol.at( MEMBER_LOCATION );
const auto& mrange = location.at( MEMBER_RANGE );
auto containerName = symbol.value( "containerName", "" );
if ( !containerName.empty() )
containerName.append( "::" );
symInfo.name = containerName + symbol.value( "name", "" );
symInfo.kind = (LSPSymbolKind)symbol.value( MEMBER_KIND, 1 );
symInfo.range = parseRange( mrange );
symInfo.url = URI( location.value( MEMBER_URI, "" ) );
symInfo.score = symbol.value( "score", 0.0 );
return symInfo;
} );
auto containerName = symbol.value( "containerName", "" );
if ( !containerName.empty() )
containerName.append( "::" );
symInfo.name = containerName + symbol.value( "name", "" );
symInfo.kind = (LSPSymbolKind)symbol.value( MEMBER_KIND, 1 );
symInfo.range = parseRange( mrange );
symInfo.url = URI( location.value( MEMBER_URI, "" ) );
symInfo.score = symbol.value( "score", 0.0 );
return symInfo;
} );
std::sort( symbols.begin(), symbols.end(),
[]( const LSPSymbolInformation& l, const LSPSymbolInformation& r ) {
@@ -1039,6 +1039,10 @@ bool LSPClientServer::registerDoc( const std::shared_ptr<TextDocument>& doc ) {
return true;
}
bool LSPClientServer::isRunning() {
return mProcess.isAlive() && !mProcess.isShootingDown();
}
void LSPClientServer::removeDoc( TextDocument* doc ) {
Lock l( mClientsMutex );
if ( mClients.erase( doc ) > 0 ) {
@@ -1240,18 +1244,22 @@ LSPClientServer::documentSymbols( const URI& document,
}
LSPClientServer::LSPRequestHandle LSPClientServer::workspaceSymbol( const std::string& querySymbol,
const JsonReplyHandler& h ) {
auto params = json{ { MEMBER_QUERY, querySymbol } };
const JsonReplyHandler& h,
const size_t& limit ) {
auto params = json{ { MEMBER_QUERY, querySymbol }, { MEMBER_LIMIT, limit } };
return send( newRequest( "workspace/symbol", params ), h );
}
LSPClientServer::LSPRequestHandle
LSPClientServer::workspaceSymbol( const std::string& querySymbol,
const SymbolInformationHandler& h ) {
return workspaceSymbol( querySymbol, [h]( const IdType& id, const json& json ) {
if ( h )
h( id, parseWorkspaceSymbols( json ) );
} );
LSPClientServer::workspaceSymbol( const std::string& querySymbol, const SymbolInformationHandler& h,
const size_t& limit ) {
return workspaceSymbol(
querySymbol,
[h]( const IdType& id, const json& json ) {
if ( h )
h( id, parseWorkspaceSymbols( json ) );
},
limit );
}
void fromJson( LSPWorkDoneProgressValue& value, const json& data ) {
@@ -63,6 +63,8 @@ class LSPClientServer {
bool registerDoc( const std::shared_ptr<TextDocument>& doc );
bool isRunning();
const LSPServerCapabilities& getCapabilities() const;
LSPClientServerManager* getManager() const;
@@ -161,10 +163,12 @@ class LSPClientServer {
LSPRequestHandle documentCompletion( const URI& document, const TextPosition& pos,
const CompletionHandler& h );
LSPRequestHandle workspaceSymbol( const std::string& querySymbol, const JsonReplyHandler& h );
LSPRequestHandle workspaceSymbol( const std::string& querySymbol, const JsonReplyHandler& h,
const size_t& limit = 100 );
LSPRequestHandle workspaceSymbol( const std::string& querySymbol,
const SymbolInformationHandler& h );
const SymbolInformationHandler& h,
const size_t& limit = 100 );
LSPRequestHandle selectionRange( const URI& document,
const std::vector<TextPosition>& positions,
@@ -451,4 +451,14 @@ LSPClientServerManager::getLSPClientServers( const std::string& language ) {
return servers;
}
std::vector<LSPClientServer*> LSPClientServerManager::getAllRunningServers() {
std::vector<LSPClientServer*> servers;
Lock l( mClientsMutex );
for ( auto& server : mClients ) {
if ( server.second->isRunning() )
servers.push_back( server.second.get() );
}
return servers;
}
} // namespace ecode
@@ -44,6 +44,8 @@ class LSPClientServerManager {
std::vector<LSPClientServer*> getLSPClientServers( const std::string& language );
std::vector<LSPClientServer*> getAllRunningServers();
LSPClientServer* getOneLSPClientServer( UICodeEditor* editor );
LSPClientServer* getOneLSPClientServer( const std::shared_ptr<TextDocument>& doc );
@@ -244,6 +244,68 @@ enum class LSPSymbolKind {
TypeParameter = 26,
};
class LSPSymbolKindHelper {
public:
// TODO: Complete this list
static std::string toIconString( const LSPSymbolKind& kind ) {
switch ( kind ) {
case LSPSymbolKind::Method:
return "symbol-method";
case LSPSymbolKind::Function:
return "symbol-function";
case LSPSymbolKind::Constructor:
return "symbol-constructor";
case LSPSymbolKind::Field:
return "symbol-field";
case LSPSymbolKind::Variable:
return "symbol-variable";
case LSPSymbolKind::Class:
return "symbol-class";
case LSPSymbolKind::Interface:
return "symbol-interface";
case LSPSymbolKind::Module:
return "symbol-module";
case LSPSymbolKind::Property:
return "symbol-property";
case LSPSymbolKind::Enum:
return "symbol-enum";
case LSPSymbolKind::File:
return "symbol-file";
case LSPSymbolKind::EnumMember:
return "symbol-enum-member";
case LSPSymbolKind::Constant:
return "symbol-constant";
case LSPSymbolKind::Struct:
return "symbol-struct";
case LSPSymbolKind::Event:
return "symbol-event";
case LSPSymbolKind::Operator:
return "symbol-operator";
case LSPSymbolKind::TypeParameter:
return "symbol-type-parameter";
case LSPSymbolKind::Namespace:
return "symbol-namespace";
case LSPSymbolKind::Package:
return "symbol-package";
case LSPSymbolKind::String:
return "symbol-string";
case LSPSymbolKind::Number:
return "symbol-number";
case LSPSymbolKind::Boolean:
return "symbol-boolean";
case LSPSymbolKind::Array:
return "symbol-array";
case LSPSymbolKind::Object:
return "symbol-object";
case LSPSymbolKind::Key:
return "symbol-key";
case LSPSymbolKind::Null:
return "symbol-null";
}
return "symbol-text";
}
};
struct LSPSymbolInformation {
LSPSymbolInformation() = default;
LSPSymbolInformation( const std::string& _name, LSPSymbolKind _kind, TextRange _range,
+17
View File
@@ -115,6 +115,23 @@ void PluginManager::setWorkspaceFolder( const std::string& workspaceFolder ) {
sendBroadcast( PluginMessageType::WorkspaceFolderChanged, PluginMessageFormat::JSON, &data );
}
PluginRequestHandle PluginManager::sendRequest( PluginMessageType type, PluginMessageFormat format,
const void* data ) {
if ( mClosing )
return PluginRequestHandle::empty();
SubscribedPlugins subscribedPlugins;
{
Lock l( mSubscribedPluginsMutex );
subscribedPlugins = mSubscribedPlugins;
}
for ( const auto& plugin : subscribedPlugins ) {
auto handle = plugin.second( { type, format, data } );
if ( !handle.isEmpty() )
return handle;
}
return PluginRequestHandle::empty();
}
PluginRequestHandle PluginManager::sendRequest( UICodeEditorPlugin* pluginWho,
PluginMessageType type, PluginMessageFormat format,
const void* data ) {
+9 -2
View File
@@ -73,6 +73,7 @@ enum class PluginMessageType {
SymbolReference, // Request the LSP Server to find a symbol reference in the project
ShowMessage, // The LSP server sends a request to the client to show a message on screen
ShowDocument, // The LSP server sends a request to the client to show a document
WorkspaceSymbol,
Undefined
};
@@ -85,6 +86,7 @@ enum class PluginMessageFormat {
ProjectSearchResult,
ShowMessage,
ShowDocument,
SymbolInformation
};
class PluginIDType {
@@ -172,6 +174,10 @@ struct PluginMessage {
return *static_cast<const LSPShowDocumentParams*>( data );
}
const std::vector<LSPSymbolInformation>& asSymbolInformation() const {
return *static_cast<const std::vector<LSPSymbolInformation>*>( data );
}
const PluginIDType& asPluginID() const { return *static_cast<const PluginIDType*>( data ); }
bool isResponse() const { return -1 != responseID && 0 != responseID; }
@@ -247,6 +253,9 @@ class PluginManager {
void setWorkspaceFolder( const std::string& workspaceFolder );
PluginRequestHandle sendRequest( PluginMessageType type, PluginMessageFormat format,
const void* data );
PluginRequestHandle sendRequest( UICodeEditorPlugin* pluginWho, PluginMessageType type,
PluginMessageFormat format, const void* data );
@@ -290,8 +299,6 @@ class PluginManager {
void setSplitter( UICodeEditorSplitter* splitter );
PluginRequestHandle sendRequest( const PluginMessageType& notification,
const PluginMessageFormat& format, void* data );
};
class PluginsModel : public Model {
+2 -1
View File
@@ -45,10 +45,11 @@ class FileListModel : public Model {
switch ( role ) {
case ModelRole::Icon:
return Variant( iconFor( index ) );
default:
case ModelRole::Display:
return Variant( index.column() == 0 ? mNames[index.row()].c_str()
: mFiles[index.row()].c_str() );
default:
break;
}
return {};