Added context menu to the resource browser; fixed search results not displaying correctly
This commit is contained in:
parent
137c10f28f
commit
fe9a074029
|
@ -186,7 +186,8 @@ HEADERS += \
|
|||
CUIRelay.h \
|
||||
Widgets/CSelectResourcePanel.h \
|
||||
Widgets/CFilteredResourceModel.h \
|
||||
ResourceBrowser/CResourceDelegate.h
|
||||
ResourceBrowser/CResourceDelegate.h \
|
||||
ResourceBrowser/CResourceTableContextMenu.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
|
@ -255,7 +256,8 @@ SOURCES += \
|
|||
WorldEditor/CWorldEditorSidebar.cpp \
|
||||
CProgressDialog.cpp \
|
||||
Widgets/CSelectResourcePanel.cpp \
|
||||
ResourceBrowser/CResourceDelegate.cpp
|
||||
ResourceBrowser/CResourceDelegate.cpp \
|
||||
ResourceBrowser/CResourceTableContextMenu.cpp
|
||||
|
||||
# UI Files
|
||||
FORMS += \
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
#include "ui_CResourceBrowser.h"
|
||||
#include "CProgressDialog.h"
|
||||
#include "CResourceDelegate.h"
|
||||
#include "CResourceTableContextMenu.h"
|
||||
#include "Editor/CEditorApplication.h"
|
||||
#include <Core/GameProject/AssetNameGeneration.h>
|
||||
#include <Core/GameProject/CAssetNameMap.h>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QFileDialog>
|
||||
#include <QMenu>
|
||||
|
@ -109,8 +111,11 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent)
|
|||
pGroup->addAction(pEdStoreAction);
|
||||
#endif
|
||||
|
||||
// Create context menu for the resource table
|
||||
new CResourceTableContextMenu(this, mpUI->ResourceTableView, mpModel, mpProxyModel);
|
||||
|
||||
// Set up connections
|
||||
connect(mpUI->SearchBar, SIGNAL(textChanged(QString)), this, SLOT(OnSearchStringChanged()));
|
||||
connect(mpUI->SearchBar, SIGNAL(StoppedTyping(QString)), this, SLOT(OnSearchStringChanged(QString)));
|
||||
connect(mpUI->ResourceTreeButton, SIGNAL(pressed()), this, SLOT(SetResourceTreeView()));
|
||||
connect(mpUI->ResourceListButton, SIGNAL(pressed()), this, SLOT(SetResourceListView()));
|
||||
connect(mpUI->SortComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSortModeChanged(int)));
|
||||
|
@ -118,7 +123,6 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent)
|
|||
connect(mpUI->ResourceTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnDoubleClickTable(QModelIndex)));
|
||||
connect(mpUI->ResourceTableView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(OnResourceSelectionChanged(QModelIndex, QModelIndex)));
|
||||
connect(mpProxyModel, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), mpUI->ResourceTableView, SLOT(resizeRowsToContents()));
|
||||
connect(&mUpdateFilterTimer, SIGNAL(timeout()), this, SLOT(UpdateFilter()));
|
||||
connect(mpFilterAllBox, SIGNAL(toggled(bool)), this, SLOT(OnFilterTypeBoxTicked(bool)));
|
||||
connect(gpEdApp, SIGNAL(ActiveProjectChanged(CGameProject*)), this, SLOT(UpdateStore()));
|
||||
}
|
||||
|
@ -202,7 +206,7 @@ void CResourceBrowser::CreateFilterCheckboxes()
|
|||
void CResourceBrowser::RefreshResources()
|
||||
{
|
||||
// Fill resource table
|
||||
mpModel->FillEntryList(mpSelectedDir, mAssetListMode);
|
||||
mpModel->FillEntryList(mpSelectedDir, mAssetListMode || mSearching);
|
||||
}
|
||||
|
||||
void CResourceBrowser::RefreshDirectories()
|
||||
|
@ -261,10 +265,22 @@ void CResourceBrowser::OnSortModeChanged(int Index)
|
|||
mpProxyModel->SetSortMode(Mode);
|
||||
}
|
||||
|
||||
void CResourceBrowser::OnSearchStringChanged()
|
||||
void CResourceBrowser::OnSearchStringChanged(QString SearchString)
|
||||
{
|
||||
const int kUpdateWaitTime = 500;
|
||||
mUpdateFilterTimer.start(kUpdateWaitTime);
|
||||
bool WasSearching = mSearching;
|
||||
mSearching = !SearchString.isEmpty();
|
||||
|
||||
// Check if we need to change to/from asset list mode to display/stop displaying search results
|
||||
if (!mAssetListMode)
|
||||
{
|
||||
if ( (mSearching && !WasSearching) ||
|
||||
(!mSearching && WasSearching) )
|
||||
{
|
||||
RefreshResources();
|
||||
}
|
||||
}
|
||||
|
||||
UpdateFilter();
|
||||
}
|
||||
|
||||
void CResourceBrowser::OnDirectorySelectionChanged(const QModelIndex& rkNewIndex, const QModelIndex& /*rkPrevIndex*/)
|
||||
|
@ -320,6 +336,10 @@ void CResourceBrowser::UpdateStore()
|
|||
{
|
||||
mpStore = pNewStore;
|
||||
|
||||
// Clear search
|
||||
mpUI->SearchBar->clear();
|
||||
mSearching = false;
|
||||
|
||||
// Refresh type filter list
|
||||
CreateFilterCheckboxes();
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ class CResourceBrowser : public QWidget
|
|||
CResourceBrowserDelegate *mpDelegate;
|
||||
CVirtualDirectory *mpSelectedDir;
|
||||
CVirtualDirectoryModel *mpDirectoryModel;
|
||||
QTimer mUpdateFilterTimer;
|
||||
bool mEditorStore;
|
||||
bool mAssetListMode;
|
||||
bool mSearching;
|
||||
|
@ -51,6 +50,7 @@ public:
|
|||
void CreateFilterCheckboxes();
|
||||
|
||||
// Accessors
|
||||
inline CResourceStore* CurrentStore() const { return mpStore; }
|
||||
inline CResourceEntry* SelectedEntry() const { return mpSelectedEntry; }
|
||||
inline bool InAssetListMode() const { return mAssetListMode || mSearching; }
|
||||
|
||||
|
@ -61,7 +61,7 @@ public slots:
|
|||
void SetResourceTreeView();
|
||||
void SetResourceListView();
|
||||
void OnSortModeChanged(int Index);
|
||||
void OnSearchStringChanged();
|
||||
void OnSearchStringChanged(QString SearchString);
|
||||
void OnDirectorySelectionChanged(const QModelIndex& rkNewIndex, const QModelIndex& rkPrevIndex);
|
||||
void OnDoubleClickTable(QModelIndex Index);
|
||||
void OnResourceSelectionChanged(const QModelIndex& rkNewIndex, const QModelIndex& rkPrevIndex);
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="SearchBar">
|
||||
<widget class="CTimedLineEdit" name="SearchBar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>5</horstretch>
|
||||
|
@ -185,7 +185,7 @@
|
|||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="">
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="FilterCheckboxScrollArea">
|
||||
|
@ -269,6 +269,9 @@
|
|||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
|
@ -301,6 +304,13 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>CTimedLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>Editor/Widgets/CTimedLineEdit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../Icons.qrc"/>
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
#include "CResourceTableContextMenu.h"
|
||||
#include "CResourceBrowser.h"
|
||||
#include "Editor/CEditorApplication.h"
|
||||
#include <QClipboard>
|
||||
|
||||
CResourceTableContextMenu::CResourceTableContextMenu(CResourceBrowser *pBrowser, QTableView *pView, CResourceTableModel *pModel, CResourceProxyModel *pProxy)
|
||||
: QMenu(pView)
|
||||
, mpBrowser(pBrowser)
|
||||
, mpTable(pView)
|
||||
, mpModel(pModel)
|
||||
, mpProxy(pProxy)
|
||||
, mpEntry(nullptr)
|
||||
, mpDirectory(nullptr)
|
||||
{
|
||||
// Connect to the view
|
||||
connect(pView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(ShowMenu(QPoint)));
|
||||
|
||||
// Create actions
|
||||
mpOpenAction = addAction("Open", this, SLOT(Open()));
|
||||
mpOpenInExternalAppAction = addAction("Open in external application", this, SLOT(OpenInExternalApp()));
|
||||
mpOpenContainingFolderAction = addAction("Open containing folder", this, SLOT(OpenContainingFolder()));
|
||||
addSeparator();
|
||||
mpCopyNameAction = addAction("Copy name", this, SLOT(CopyName()));
|
||||
mpCopyPathAction = addAction("Copy path", this, SLOT(CopyPath()));
|
||||
mpCopyIDAction = addAction("Copy asset ID", this, SLOT(CopyID()));
|
||||
}
|
||||
|
||||
void CResourceTableContextMenu::ShowMenu(const QPoint& rkPos)
|
||||
{
|
||||
// Fetch the entry/directory
|
||||
QModelIndex ProxyIndex = mpTable->indexAt(rkPos);
|
||||
mIndex = mpProxy->mapToSource(ProxyIndex);
|
||||
mpEntry = mpModel->IndexEntry(mIndex);
|
||||
mpDirectory = mpModel->IndexDirectory(mIndex);
|
||||
|
||||
// Show/hide menu options
|
||||
bool IsRes = (mpEntry != nullptr);
|
||||
mpOpenInExternalAppAction->setVisible(IsRes);
|
||||
mpCopyIDAction->setVisible(IsRes);
|
||||
|
||||
// Exec menu
|
||||
QPoint GlobalPos = mpTable->viewport()->mapToGlobal(rkPos);
|
||||
exec(GlobalPos);
|
||||
}
|
||||
|
||||
// Menu Options
|
||||
void CResourceTableContextMenu::Open()
|
||||
{
|
||||
if (mpEntry)
|
||||
gpEdApp->EditResource(mpEntry);
|
||||
else
|
||||
mpBrowser->SelectDirectory(mpDirectory);
|
||||
}
|
||||
|
||||
void CResourceTableContextMenu::OpenInExternalApp()
|
||||
{
|
||||
ASSERT(mpEntry);
|
||||
UICommon::OpenInExternalApplication( TO_QSTRING(mpEntry->CookedAssetPath()) );
|
||||
}
|
||||
|
||||
void CResourceTableContextMenu::OpenContainingFolder()
|
||||
{
|
||||
if (mpEntry)
|
||||
{
|
||||
QString Path = TO_QSTRING( mpEntry->CookedAssetPath() );
|
||||
UICommon::OpenContainingFolder(Path);
|
||||
}
|
||||
else
|
||||
{
|
||||
TString BasePath = mpBrowser->CurrentStore()->ResourcesDir();
|
||||
QString Path = TO_QSTRING( BasePath + mpDirectory->FullPath() );
|
||||
UICommon::OpenContainingFolder(Path);
|
||||
}
|
||||
}
|
||||
|
||||
void CResourceTableContextMenu::CopyName()
|
||||
{
|
||||
if (mpEntry)
|
||||
gpEdApp->clipboard()->setText( TO_QSTRING(mpEntry->Name()) );
|
||||
else
|
||||
gpEdApp->clipboard()->setText( TO_QSTRING(mpDirectory->Name()) );
|
||||
}
|
||||
|
||||
void CResourceTableContextMenu::CopyPath()
|
||||
{
|
||||
if (mpEntry)
|
||||
gpEdApp->clipboard()->setText( TO_QSTRING(mpEntry->CookedAssetPath(true)) );
|
||||
else
|
||||
gpEdApp->clipboard()->setText( TO_QSTRING(mpDirectory->FullPath()) );
|
||||
}
|
||||
|
||||
void CResourceTableContextMenu::CopyID()
|
||||
{
|
||||
ASSERT(mpEntry);
|
||||
gpEdApp->clipboard()->setText( TO_QSTRING(mpEntry->ID().ToString()) );
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef CRESOURCETABLECONTEXTMENU_H
|
||||
#define CRESOURCETABLECONTEXTMENU_H
|
||||
|
||||
#include "CResourceTableModel.h"
|
||||
#include "CResourceProxyModel.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QTableView>
|
||||
|
||||
class CResourceTableContextMenu : public QMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
CResourceBrowser *mpBrowser;
|
||||
QTableView *mpTable;
|
||||
CResourceTableModel *mpModel;
|
||||
CResourceProxyModel *mpProxy;
|
||||
|
||||
QModelIndex mIndex;
|
||||
CResourceEntry *mpEntry;
|
||||
CVirtualDirectory *mpDirectory;
|
||||
|
||||
// Actions
|
||||
QAction *mpOpenAction;
|
||||
QAction *mpOpenInExternalAppAction;
|
||||
QAction *mpOpenContainingFolderAction;
|
||||
|
||||
QAction *mpCopyNameAction;
|
||||
QAction *mpCopyPathAction;
|
||||
QAction *mpCopyIDAction;
|
||||
|
||||
public:
|
||||
CResourceTableContextMenu(CResourceBrowser *pBrowser, QTableView *pView, CResourceTableModel *pModel, CResourceProxyModel *pProxy);
|
||||
|
||||
public slots:
|
||||
void ShowMenu(const QPoint& rkPos);
|
||||
|
||||
// Menu Options
|
||||
void Open();
|
||||
void OpenInExternalApp();
|
||||
void OpenContainingFolder();
|
||||
void CopyName();
|
||||
void CopyPath();
|
||||
void CopyID();
|
||||
};
|
||||
|
||||
#endif // CRESOURCETABLECONTEXTMENU_H
|
|
@ -1,61 +1,24 @@
|
|||
#include "UICommon.h"
|
||||
#include <QDesktopServices>
|
||||
#include <QProcess>
|
||||
|
||||
namespace UICommon
|
||||
{
|
||||
|
||||
QMap<QString,QString> FilterMap = {
|
||||
{ "AFSM", "AI Finite State Machine (*.AFSM)" },
|
||||
{ "ANIM", "Animation (*.ANIM)" },
|
||||
{ "ANCS", "Animation Character Set (*.ANCS)" },
|
||||
{ "AGSC", "Audio Group (*.AGSC)" },
|
||||
{ "ATBL", "Audio Lookup Table (*.ATBL)" },
|
||||
{ "CAUD", "Audio Metadata (*.CAUD)" },
|
||||
{ "CHAR", "Character (*.CHAR)" },
|
||||
{ "CINF", "Skeleton (*.CINF)" },
|
||||
{ "CMDL", "Model (*.CMDL)" },
|
||||
{ "CRSC", "Collision Response Data (*.CRSC)" },
|
||||
{ "CSKR", "Skin Rules (*.CSKR)" },
|
||||
{ "CSMP", "Audio Sample (*.CSMP)" },
|
||||
{ "CSNG", "MIDI Data (*.CSNG)" },
|
||||
{ "CTWK", "Tweaks (*.CTWK)" },
|
||||
{ "DCLN", "Collision Mesh (*.DCLN)" },
|
||||
{ "DGRP", "Dependency Group (*.DGRP)" },
|
||||
{ "DPSC", "Decal (*.DPSC)" },
|
||||
{ "DSP" , "Music Track (*.DSP)" },
|
||||
{ "DUMB", "Binary Data Dump (*.DUMB)" },
|
||||
{ "ELSC", "Electric Particle (*.ELSC)" },
|
||||
{ "EVNT", "Animation Event Data (*.EVNT)" },
|
||||
{ "FRME", "GUI Frame (*.FRME)" },
|
||||
{ "FSM2", "AI Finite State Machine (*.FSM2)" },
|
||||
{ "FONT", "Font (*.FONT)" },
|
||||
{ "HINT", "Hint System Data (*.HINT)" },
|
||||
{ "MAPA", "Area Map (*.MAPA)" },
|
||||
{ "MAPW", "World Map (*.MAPW)" },
|
||||
{ "MAPU", "Universe Map (*.MAPU)" },
|
||||
{ "MLVL", "World (*.MLVL)" },
|
||||
{ "MREA", "Area (*.MREA)" },
|
||||
{ "NTWK", "Tweaks (*.NTWK)" },
|
||||
{ "PATH", "AI Navigation Mesh (*.PATH)" },
|
||||
{ "PAK" , "Package (*.pak)" },
|
||||
{ "PART", "Particle (*.PART)" },
|
||||
{ "SAVW", "World Save Data (*.SAVW)" },
|
||||
{ "SCAN", "Scannable Object Info (*.SCAN)" },
|
||||
{ "STRG", "String Table (*.STRG)" },
|
||||
{ "STRM", "Audio Stream (*.STRM)" },
|
||||
{ "SWHC", "Swoosh Particle (*.SWHC)" },
|
||||
{ "THP" , "Video (*.thp)" },
|
||||
{ "TXTR", "Texture (*.TXTR)" },
|
||||
{ "WPSC", "Projectile (*.WPSC)" }
|
||||
};
|
||||
|
||||
QString ExtensionFilterString(const QString& rkExtension)
|
||||
void OpenContainingFolder(const QString& rkPath)
|
||||
{
|
||||
QMap<QString,QString>::const_iterator it = FilterMap.find(rkExtension.toUpper());
|
||||
#if WIN32
|
||||
QStringList Args;
|
||||
Args << "/select," << QDir::toNativeSeparators(rkPath);
|
||||
QProcess::startDetached("explorer", Args);
|
||||
#else
|
||||
#error OpenContainingFolder() not implemented!
|
||||
#endif
|
||||
}
|
||||
|
||||
if (it != FilterMap.end())
|
||||
return it.value();
|
||||
else
|
||||
return "Unknown Extension (*." + rkExtension + ")";
|
||||
bool OpenInExternalApplication(const QString& rkPath)
|
||||
{
|
||||
return QDesktopServices::openUrl( QString("file:///") + QDir::toNativeSeparators(rkPath) );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,8 +38,10 @@
|
|||
|
||||
namespace UICommon
|
||||
{
|
||||
extern QMap<QString,QString> FilterMap;
|
||||
QString ExtensionFilterString(const QString& rkExtension);
|
||||
|
||||
// Utility
|
||||
void OpenContainingFolder(const QString& rkPath);
|
||||
bool OpenInExternalApplication(const QString& rkPath);
|
||||
|
||||
// TString/TWideString <-> QString
|
||||
inline QString ToQString(const TString& rkStr)
|
||||
|
|
Loading…
Reference in New Issue