From 42661cc24735d492e61f1b3df22418cace0e4386 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sun, 4 May 2014 11:31:24 -0700 Subject: [PATCH] Port plResBrowser to Qt5 --- Sources/Tools/plResBrowser/CMakeLists.txt | 85 ++- Sources/Tools/plResBrowser/plResBrowser.cpp | 418 +++++++++++-- Sources/Tools/plResBrowser/plResBrowser.h | 76 +++ .../plResBrowser/plResBrowserWndProc.cpp | 432 ------------- Sources/Tools/plResBrowser/plResTreeView.cpp | 497 +++------------ Sources/Tools/plResBrowser/plResTreeView.h | 51 +- .../Tools/plResBrowser/plWinRegistryTools.cpp | 73 ++- .../Tools/plResBrowser/plWinRegistryTools.h | 21 +- Sources/Tools/plResBrowser/res/FindDialog.ui | 76 +++ Sources/Tools/plResBrowser/res/ResBrowser.ui | 591 ++++++++++++++++++ .../Tools/plResBrowser/res/plResBrowser.qrc | 5 + .../Tools/plResBrowser/res/plResBrowser.rc | 203 +----- Sources/Tools/plResBrowser/res/resource.h | 68 -- 13 files changed, 1322 insertions(+), 1274 deletions(-) create mode 100644 Sources/Tools/plResBrowser/plResBrowser.h delete mode 100644 Sources/Tools/plResBrowser/plResBrowserWndProc.cpp create mode 100644 Sources/Tools/plResBrowser/res/FindDialog.ui create mode 100644 Sources/Tools/plResBrowser/res/ResBrowser.ui create mode 100644 Sources/Tools/plResBrowser/res/plResBrowser.qrc delete mode 100644 Sources/Tools/plResBrowser/res/resource.h diff --git a/Sources/Tools/plResBrowser/CMakeLists.txt b/Sources/Tools/plResBrowser/CMakeLists.txt index c08bed60..624b3401 100644 --- a/Sources/Tools/plResBrowser/CMakeLists.txt +++ b/Sources/Tools/plResBrowser/CMakeLists.txt @@ -8,64 +8,55 @@ include_directories("../../Plasma/PubUtilLib/inc") include_directories("../../Plasma/PubUtilLib") set(plResBrowser_HEADERS - plResTreeView.h - plWinRegistryTools.h + plResBrowser.h + plResTreeView.h ) +qt5_wrap_cpp(plResBrowser_MOC ${plResBrowser_HEADERS}) set(plResBrowser_SOURCES - plResBrowser.cpp - plResBrowserWndProc.cpp - plResTreeView.cpp - plWinRegistryTools.cpp - ) - -set(plResBrowser_RESOURCES - res/plResBrowser.rc - res/resource.h + plResBrowser.cpp + plResTreeView.cpp +) + +if(WIN32) + set(plResBrowser_HEADERS ${plResBrowser_HEADERS} + plWinRegistryTools.h + ) + + set(plResBrowser_SOURCES ${plResBrowser_SOURCES} + res/plResBrowser.rc + plWinRegistryTools.cpp + ) +endif() + +set(plResBrowser_RCC_SOURCES + res/plResBrowser.qrc +) +qt5_add_resources(plResBrowser_RCC ${plResBrowser_RCC_SOURCES}) + +set(plResBrowser_UIC_SOURCES + res/FindDialog.ui + res/ResBrowser.ui +) +qt5_wrap_ui(plResBrowser_UIC ${plResBrowser_UIC_SOURCES}) - res/dataicon.ico - res/icon1.ico - res/icon2.ico - res/indexico.ico - res/mergedda.ico - res/mergedin.ico - ) - -add_executable(plResBrowser WIN32 ${plResBrowser_SOURCES} ${plResBrowser_HEADERS} ${plResBrowser_RESOURCES}) +# For generated ui_*.h files +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +add_executable(plResBrowser WIN32 ${plResBrowser_SOURCES} ${plResBrowser_HEADERS} + ${plResBrowser_RCC} ${plResBrowser_UIC} ${plResBrowser_MOC}) target_link_libraries(plResBrowser CoreLib) -target_link_libraries(plResBrowser plFile) -target_link_libraries(plResBrowser plMessage) target_link_libraries(plResBrowser plResMgr) -target_link_libraries(plResBrowser plScene) -target_link_libraries(plResBrowser plStatusLog) -target_link_libraries(plResBrowser plUnifiedTime) -target_link_libraries(plResBrowser pnDispatch) -target_link_libraries(plResBrowser pnFactory) -target_link_libraries(plResBrowser pnKeyedObject) -target_link_libraries(plResBrowser pnMessage) -target_link_libraries(plResBrowser pnNetCommon) -target_link_libraries(plResBrowser pnNucleusInc) target_link_libraries(plResBrowser pnSceneObject) -target_link_libraries(plResBrowser pnTimer) -target_link_libraries(plResBrowser pnUtils) -target_link_libraries(plResBrowser pnUUID) - -if (WIN32) - target_link_libraries(plResBrowser rpcrt4) - target_link_libraries(plResBrowser version) - target_link_libraries(plResBrowser vfw32) - target_link_libraries(plResBrowser ws2_32) - target_link_libraries(plResBrowser winmm) - target_link_libraries(plResBrowser strmiids) - target_link_libraries(plResBrowser comctl32) - target_link_libraries(plResBrowser shlwapi) -endif(WIN32) +target_link_libraries(plResBrowser Qt5::Widgets) if(USE_VLD) target_link_libraries(plResBrowser ${VLD_LIBRARY}) endif() -source_group("Source Files" FILES ${plResBrowser_SOURCES}) +source_group("Source Files" FILES ${plResBrowser_SOURCES} ${plResBrowser_MOC}) source_group("Header Files" FILES ${plResBrowser_HEADERS}) -source_group("Resource Files" FILES ${plResBrowser_RESOURCES}) +source_group("Resource Files" FILES ${plResBrowser_RCC_SOURCES} ${plResBrowser_RCC} + ${plResBrowser_UIC_SOURCES} ${plResBrowser_UIC}) diff --git a/Sources/Tools/plResBrowser/plResBrowser.cpp b/Sources/Tools/plResBrowser/plResBrowser.cpp index abf61b92..3f88ce11 100644 --- a/Sources/Tools/plResBrowser/plResBrowser.cpp +++ b/Sources/Tools/plResBrowser/plResBrowser.cpp @@ -39,12 +39,13 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com Mead, WA 99021 *==LICENSE==*/ -#define CLASSNAME "plResBrowser" // Used in WinInit() -#define WINDOWNAME "plResBrowser" -#include "HeadSpin.h" -#include "hsWindows.h" -#include "res/resource.h" +#include "plResBrowser.h" +#include "ui_ResBrowser.h" + +#if HS_BUILD_FOR_WIN32 +# include "plWinRegistryTools.h" +#endif #include "pnAllCreatables.h" #include "plResMgr/plResMgrCreatable.h" @@ -53,81 +54,374 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plMessage/plResMgrHelperMsg.h" REGISTER_CREATABLE(plResMgrHelperMsg); +#include "plResMgr/plRegistryHelpers.h" +#include "plResMgr/plRegistryNode.h" +#include "plResMgr/plPageInfo.h" +#include "pnKeyedObject/plUoid.h" +#include "pnKeyedObject/plKey.h" +#include "pnKeyedObject/plKeyImp.h" + +#include +#include +#include +#include +#include +#include +#include -HINSTANCE gInstance; -char *gCommandLine = nil; -HWND gMainWindow = nil; +static void IAboutDialog(QWidget *parent) +{ + QDialog dlg(parent); + QLabel *image = new QLabel(&dlg); + image->setPixmap(QPixmap(":/icon1.ico")); + QLabel *text = new QLabel(QObject::tr(R"(plResBrowser +A simple Plasma 2.0 packfile browsing utility +Copyright (C) 2002 Cyan Worlds, Inc. -LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ); -BOOL WinInit( HINSTANCE hInst, int nCmdShow ); +Who needs log files?)"), &dlg); + QPushButton *ok = new QPushButton(QObject::tr("OK"), &dlg); + ok->setDefault(true); + QHBoxLayout *layout = new QHBoxLayout(&dlg); + layout->setMargin(8); + layout->setSpacing(10); + layout->addWidget(image); + layout->addWidget(text); + layout->addWidget(ok); -int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) + dlg.connect(ok, &QPushButton::clicked, &dlg, &QDialog::accept); + dlg.exec(); +} + +plResBrowser::plResBrowser() + : QMainWindow() { - MSG msg; - HACCEL accelTable = LoadAccelerators( hInstance, MAKEINTRESOURCE( IDR_ACCELERATOR1 ) ); + fUI = new Ui_ResBrowser; + fUI->setupUi(this); + setAcceptDrops(true); - plResMgrSettings::Get().SetFilterNewerPageVersions( false ); - plResMgrSettings::Get().SetFilterOlderPageVersions( false ); + // Use window background color for read-only text fields + // Note that we don't set them disabled, so you can still copy their contents + QPalette pal = fUI->fAgeName->palette(); + pal.setColor(QPalette::Text, fUI->label->palette().color(QPalette::Text)); + pal.setColor(QPalette::Base, fUI->label->palette().color(QPalette::Window)); + fUI->fAgeName->setPalette(pal); + fUI->fPageName->setPalette(pal); + fUI->fLocation->setPalette(pal); + fUI->fDataVersion->setPalette(pal); + fUI->fChecksum->setPalette(pal); + fUI->fChecksumType->setPalette(pal); + fUI->fObjectName->setPalette(pal); + fUI->fObjectClass->setPalette(pal); + fUI->fStartPos->setPalette(pal); + fUI->fObjectSize->setPalette(pal); - gCommandLine = (char *)lpCmdLine; - plResManager *rMgr = new plResManager; - hsgResMgr::Init( rMgr ); + connect(fUI->fOpenAction, SIGNAL(triggered()), SLOT(OpenFile())); + connect(fUI->fOpenDirectoryAction, SIGNAL(triggered()), SLOT(OpenDirectory())); + connect(fUI->fSaveSelectedAction, SIGNAL(triggered()), SLOT(SaveSelectedObject())); + connect(fUI->fFindAction, SIGNAL(triggered()), fUI->fTreeView, SLOT(FindObject())); + connect(fUI->fFindNextAction, SIGNAL(triggered()), fUI->fTreeView, SLOT(FindNextObject())); + connect(fUI->fShowOnlyLoadableAction, SIGNAL(triggered()), SLOT(RefreshTree())); + connect(fUI->fExitAction, SIGNAL(triggered()), SLOT(close())); + connect(fUI->fAboutAction, &QAction::triggered, std::bind(&IAboutDialog, this)); + + connect(fUI->fTreeView, &QTreeWidget::currentItemChanged, + std::bind(&plResBrowser::UpdateInfoPage, this)); + connect(fUI->fHexValues, SIGNAL(clicked()), SLOT(UpdateInfoPage())); + connect(fUI->fFindButton, SIGNAL(clicked()), fUI->fTreeView, SLOT(FindObject())); + connect(fUI->fFindNextButton, SIGNAL(clicked()), fUI->fTreeView, SLOT(FindNextObject())); + connect(fUI->fSaveButton, SIGNAL(clicked()), SLOT(SaveSelectedObject())); + + RegisterFileTypes(); + plResMgrSettings::Get().SetLoadPagesOnInit(false); + + QStringList args = qApp->arguments(); + if (args.size() > 1) + { + plFileName path = args[1].toUtf8().constData(); + if (path.GetFileExt() == "prp") + LoadPrpFile(args[1]); + } +} + +plResBrowser::~plResBrowser() +{ + delete fUI; +} + +void plResBrowser::SetWindowTitle(const QString &title) +{ + setWindowTitle(QString("plResBrowser%1").arg(title.isEmpty() ? "" : " - " + title)); +} + +void plResBrowser::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasUrls()) + event->acceptProposedAction(); +} + +void plResBrowser::dropEvent(QDropEvent *event) +{ + QList urls = event->mimeData()->urls(); + if (urls.size() == 0) + return; + + fUI->fTreeView->clear(); + hsgResMgr::Reset(); + plResManager *mgr = static_cast(hsgResMgr::ResMgr()); + + QString path = urls[0].toLocalFile(); + + if (urls.size() == 1 && urls[0].isLocalFile() && path.lastIndexOf('.') == -1) + { + // Must be a directory + std::vector prpFiles = plFileSystem::ListDir(path.toUtf8().constData(), "*.prp"); + for (auto iter = prpFiles.begin(); iter != prpFiles.end(); ++iter) + mgr->AddSinglePage(*iter); + } + else + { + for (const QUrl &url : urls) + { + if (!url.isLocalFile()) + continue; + + plFileName fileName = url.toLocalFile().toUtf8().constData(); + if (fileName.GetFileExt() == "prp") + { + mgr->AddSinglePage(fileName); + path = fileName.StripFileName().AsString().c_str(); + } + } + } + + fUI->fTreeView->LoadFromRegistry(fUI->fShowOnlyLoadableAction->isChecked()); + SetWindowTitle(path); +} + +void plResBrowser::OpenFile() +{ + QString fileName = QFileDialog::getOpenFileName(this, tr("Choose a file to browse"), + QString(), "Plasma 2 Pack Files (*.prp);;All files (*.*)"); - if( !WinInit( hInstance, nCmdShow ) ) - return -1; + if (!fileName.isEmpty()) + LoadPrpFile(fileName); +} - while( GetMessage( &msg, NULL, 0, 0 ) ) +void plResBrowser::OpenDirectory() +{ + QString path = QFileDialog::getExistingDirectory(this, + tr("Select a Plasma 2 Data Directory:"), + QDir::current().absolutePath(), + QFileDialog::ShowDirsOnly | QFileDialog::ReadOnly); + + if (!path.isEmpty()) + LoadResourcePath(path); +} + +void plResBrowser::SaveSelectedObject() +{ + plResTreeViewItem *item = static_cast(fUI->fTreeView->currentItem()); + plKey itemKey = item ? item->GetKey() : nullptr; + if (!itemKey) + return; + + QString fileName = QFileDialog::getSaveFileName(this, tr("Export object"), + QString("%1.bin").arg(itemKey->GetName().c_str()), + "Binary Files (*.bin);;All files (*.*)"); + + if (!fileName.isEmpty()) { - if( !TranslateAccelerator( gMainWindow, accelTable, &msg ) ) + plKeyImp *keyImp = static_cast(itemKey); + + if (keyImp->GetDataLen() <= 0) + return; + + plResManager *resMgr = static_cast(hsgResMgr::ResMgr()); + plRegistryPageNode *pageNode = resMgr->FindPage(keyImp->GetUoid().GetLocation()); + + hsStream *stream = pageNode->OpenStream(); + if (!stream) + return; + + uint8_t *buffer = new uint8_t[keyImp->GetDataLen()]; + if (buffer) { - TranslateMessage( &msg ); - DispatchMessage( &msg ); + stream->SetPosition(keyImp->GetStartPos()); + stream->Read(keyImp->GetDataLen(), buffer); } + + if (!buffer) + return; + + hsUNIXStream outStream; + outStream.Open(fileName.toUtf8().constData(), "wb"); + outStream.Write(keyImp->GetDataLen(), buffer); + outStream.Close(); + + delete[] buffer; } +} - hsgResMgr::Shutdown(); +void plResBrowser::RefreshTree() +{ + fUI->fTreeView->clear(); + fUI->fTreeView->LoadFromRegistry(fUI->fShowOnlyLoadableAction->isChecked()); +} + +void plResBrowser::UpdateInfoPage() +{ + const bool showAsHex = fUI->fHexValues->isChecked(); + + fUI->fObjectName->setText(""); + fUI->fObjectClass->setText(""); + fUI->fObjectSize->setText(""); + fUI->fStartPos->setText(""); + fUI->fSaveSelectedAction->setEnabled(false); + fUI->fSaveButton->setEnabled(false); + + plResTreeViewItem *item = static_cast(fUI->fTreeView->currentItem()); + if (item) + { + if (item->GetPage()) + { + const plPageInfo &pageInfo = item->GetPage()->GetPageInfo(); + fUI->fAgeName->setText(pageInfo.GetAge().c_str()); + fUI->fPageName->setText(pageInfo.GetPage().c_str()); + fUI->fLocation->setText(pageInfo.GetLocation().StringIze().c_str()); + + fUI->fReserved->setChecked((pageInfo.GetLocation().GetFlags() & plLocation::kReserved) != 0); + fUI->fBuiltIn->setChecked((pageInfo.GetLocation().GetFlags() & plLocation::kBuiltIn) != 0); + fUI->fVolatile->setChecked((pageInfo.GetLocation().GetFlags() & plLocation::kVolatile) != 0); + fUI->fLocalOnly->setChecked((pageInfo.GetLocation().GetFlags() & plLocation::kLocalOnly) != 0); + + fUI->fDataVersion->setText(QString::number(pageInfo.GetMajorVersion())); + + if (showAsHex) + fUI->fChecksum->setText(QString("0x%1").arg(pageInfo.GetChecksum(), 0, 16)); + else + fUI->fChecksum->setText(QString::number(pageInfo.GetChecksum())); + + fUI->fChecksumType->setText("Basic (file size)"); + } + + if (item->GetKey()) + { + plKey key = item->GetKey(); + fUI->fObjectName->setText(key->GetUoid().GetObjectName().c_str()); + + const char *cname = plFactory::GetNameOfClass(key->GetUoid().GetClassType()); + fUI->fObjectClass->setText(QString("%1 (%2)").arg(cname ? cname : "") + .arg(key->GetUoid().GetClassType())); + + plKeyImp *imp = static_cast(key); + if (showAsHex) + fUI->fStartPos->setText(QString("0x%1").arg(imp->GetStartPos(), 0, 16)); + else + fUI->fStartPos->setText(QString::number(imp->GetStartPos())); + + if (imp->GetDataLen() < 1024) + fUI->fObjectSize->setText(QString("%1 bytes").arg(imp->GetDataLen())); + else if (imp->GetDataLen() < 1024 * 1024) + fUI->fObjectSize->setText(QString("%1 kB").arg(imp->GetDataLen() / 1024.f, 0, 'f', 2)); + else + fUI->fObjectSize->setText(QString("%1 MB").arg(imp->GetDataLen() / 1024.f / 1024.f, 0, 'f', 2)); + + fUI->fSaveSelectedAction->setEnabled(true); + fUI->fSaveButton->setEnabled(true); + } + } +} + +void plResBrowser::RegisterFileTypes() +{ + // Only meaningful on Windows currently... For Linux, consider creating + // a .desktop file as part of the make install process + +#if HS_BUILD_FOR_WIN32 + static bool sFileTypesRegistered = false; + if (sFileTypesRegistered) + return; + + // Make sure our file types are created + QString path = QCoreApplication::applicationFilePath(); + + //plWinRegistryTools::AssociateFileType("PlasmaIdxFile", "Plasma 2 Index File", path, 1); + //plWinRegistryTools::AssociateFileType("PlasmaDatFile", "Plasma 2 Data File", path, 2); + //plWinRegistryTools::AssociateFileType("PlasmaPatchFile", "Plasma 2 Patch File", path, 3); + plWinRegistryTools::AssociateFileType("PlasmaPackFile", "Plasma 2 Packfile", path, 4); - return 0; + // Check our file extensions + QString prpAssoc = plWinRegistryTools::GetCurrentFileExtensionAssociation(".prp"); + + if (prpAssoc != "PlasmaPackFile") + { + int retn = QMessageBox::question(this, tr("plResBrowser File Type Association"), + tr("The Plasma 2 packed data file extension .prp is not currently associated " + "with plResBrowser. Would you like to associate it now?")); + if (retn == QMessageBox::Yes) + { + // Associate 'em + plWinRegistryTools::AssociateFileExtension(".prp", "PlasmaPackFile"); + } + } + + sFileTypesRegistered = true; +#endif } -BOOL WinInit(HINSTANCE hInst, int nCmdShow) +void plResBrowser::LoadPrpFile(const QString &fileName) { - gInstance = hInst; - - // Fill out WNDCLASS info - WNDCLASS wndClass; - wndClass.style = 0; // CS_HREDRAW | CS_VREDRAW; - wndClass.lpfnWndProc = WndProc; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = hInst; - wndClass.hIcon = LoadIcon( hInst, MAKEINTRESOURCE( IDI_APPICON ) ); - - wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndClass.hbrBackground = (HBRUSH)GetSysColorBrush( COLOR_3DFACE ); - wndClass.lpszMenuName = MAKEINTRESOURCE( IDR_APPMENU ); - wndClass.lpszClassName = CLASSNAME; - - // can only run one at a time anyway, so just quit if another is running - if (!RegisterClass(&wndClass)) - return FALSE; - - DWORD dwStyle = WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; - DWORD dwExStyle = WS_EX_ACCEPTFILES; - - // Create a window - gMainWindow = CreateWindowEx(dwExStyle, CLASSNAME, WINDOWNAME, - dwStyle, 10, 10, - 800, - 600, - NULL, NULL, hInst, NULL); - - return TRUE; + fUI->fTreeView->clear(); + hsgResMgr::Reset(); + + // Load that source + plResManager *mgr = static_cast(hsgResMgr::ResMgr()); + mgr->AddSinglePage(fileName.toUtf8().constData()); + fUI->fTreeView->LoadFromRegistry(fUI->fShowOnlyLoadableAction->isChecked()); + + SetWindowTitle(fileName); } -/* Enable themes in Windows XP and later */ -#pragma comment(linker,"\"/manifestdependency:type='win32' \ -name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ -processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +void plResBrowser::LoadResourcePath(const QString &path) +{ + fUI->fTreeView->clear(); + hsgResMgr::Reset(); + + // Load that source + plResManager *mgr = static_cast(hsgResMgr::ResMgr()); + + std::vector prpFiles = plFileSystem::ListDir(path.toUtf8().constData(), "*.prp"); + for (auto iter = prpFiles.begin(); iter != prpFiles.end(); ++iter) + mgr->AddSinglePage(*iter); + + fUI->fTreeView->LoadFromRegistry(fUI->fShowOnlyLoadableAction->isChecked()); + + SetWindowTitle(path); +} + + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + app.setApplicationName("plResBrowser"); + app.setWindowIcon(QIcon(":/icon1.ico")); + + plResMgrSettings::Get().SetFilterNewerPageVersions(false); + plResMgrSettings::Get().SetFilterOlderPageVersions(false); + + plResManager *rMgr = new plResManager; + hsgResMgr::Init(rMgr); + + int retn; + { + plResBrowser mainWindow; + mainWindow.show(); + retn = app.exec(); + } + + hsgResMgr::Shutdown(); + + return retn; +} diff --git a/Sources/Tools/plResBrowser/plResBrowser.h b/Sources/Tools/plResBrowser/plResBrowser.h new file mode 100644 index 00000000..9372db17 --- /dev/null +++ b/Sources/Tools/plResBrowser/plResBrowser.h @@ -0,0 +1,76 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ +#ifndef _plResBrowser_h +#define _plResBrowser_h + +#include + +class plResBrowser : public QMainWindow +{ + Q_OBJECT + +public: + plResBrowser(); + virtual ~plResBrowser(); + + void SetWindowTitle(const QString &title); + +protected: + virtual void dragEnterEvent(QDragEnterEvent *event) override; + virtual void dropEvent(QDropEvent *event) override; + +private slots: + void OpenFile(); + void OpenDirectory(); + void SaveSelectedObject(); + void RefreshTree(); + void UpdateInfoPage(); + +private: + class Ui_ResBrowser *fUI; + + void RegisterFileTypes(); + void LoadPrpFile(const QString &fileName); + void LoadResourcePath(const QString &path); +}; + +#endif diff --git a/Sources/Tools/plResBrowser/plResBrowserWndProc.cpp b/Sources/Tools/plResBrowser/plResBrowserWndProc.cpp deleted file mode 100644 index a4966f67..00000000 --- a/Sources/Tools/plResBrowser/plResBrowserWndProc.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -#include "HeadSpin.h" -#include "hsWindows.h" -#include "hsTemplates.h" -#include "res/resource.h" -#include -#include -#include -#include -#include - -#include "plResTreeView.h" -#include "plResMgr/plResManager.h" -#include "plResMgr/plResMgrSettings.h" -#include "plWinRegistryTools.h" - -#define IDC_REGTREEVIEW 1000 - -extern HINSTANCE gInstance; -extern char *gCommandLine; - -HWND gTreeView; -HWND gInfoDlg; - -class plWaitCursor -{ - HCURSOR fOrig; - public: - plWaitCursor() - { - fOrig = ::SetCursor( ::LoadCursor( nil, IDC_WAIT ) ); - } - - ~plWaitCursor() - { - ::SetCursor( fOrig ); - } -}; - -void SetWindowTitle( HWND hWnd, char *path ) -{ - char fun[ MAX_PATH + 50 ]; - - - sprintf( fun, "plResBrowser%s%s", path != nil ? " - " : "", path != nil ? path : "" ); - SetWindowText( hWnd, fun ); -} - -INT_PTR CALLBACK AboutDialogProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) -{ - if( msg == WM_COMMAND ) - EndDialog( hWnd, 0 ); - return 0; -} - -LRESULT CALLBACK HandleCommand( HWND hWnd, WPARAM wParam, LPARAM lParam ) -{ - OPENFILENAME openInfo; - char fileName[ MAX_PATH ]; - char path[ MAX_PATH ]; - - static bool filter = true; - - - switch( LOWORD( wParam ) ) - { - case ID_FILE_EXIT: - PostQuitMessage( 0 ); - break; - - case ID_FILE_OPENDIRECTORY: - - BROWSEINFO bInfo; - LPITEMIDLIST itemList; - LPMALLOC shMalloc; - - - memset( &bInfo, 0, sizeof( bInfo ) ); - bInfo.hwndOwner = hWnd; - bInfo.pidlRoot = NULL; - bInfo.pszDisplayName = path; - bInfo.lpszTitle = "Select a Plasma 2 Data Directory:"; - bInfo.ulFlags = BIF_EDITBOX; - - itemList = SHBrowseForFolder( &bInfo ); - if( itemList != NULL ) - { - plWaitCursor myWaitCursor; - - SHGetPathFromIDList( itemList, path ); - SHGetMalloc( &shMalloc ); - shMalloc->Free( itemList ); - shMalloc->Release(); - - hsgResMgr::Reset(); - plResTreeView::ClearTreeView( gTreeView ); - - // Load that source - plResManager *mgr = (plResManager *)hsgResMgr::ResMgr(); - - std::vector prpFiles = plFileSystem::ListDir(path, "*.prp"); - for (auto iter = prpFiles.begin(); iter != prpFiles.end(); ++iter) - mgr->AddSinglePage(*iter); - - plResTreeView::FillTreeViewFromRegistry( gTreeView ); - - SetWindowTitle( hWnd, path ); - } - - break; - - case ID_FILE_OPEN: - fileName[ 0 ] = 0; - - memset( &openInfo, 0, sizeof( OPENFILENAME ) ); - openInfo.hInstance = gInstance; - openInfo.hwndOwner = hWnd; - openInfo.lStructSize = sizeof( OPENFILENAME ); - openInfo.lpstrFile = fileName; - openInfo.nMaxFile = sizeof( fileName ); - openInfo.lpstrFilter = "Plasma 2 Pack Files\0*.prp\0All Files\0*.*\0"; - openInfo.lpstrTitle = "Choose a file to browse:"; - openInfo.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; - - if( GetOpenFileName( &openInfo ) ) - { - plWaitCursor myWaitCursor; - - hsgResMgr::Reset(); - plResTreeView::ClearTreeView( gTreeView ); - - // Load that source - plResManager *mgr = (plResManager *)hsgResMgr::ResMgr(); - mgr->AddSinglePage(fileName); - plResTreeView::FillTreeViewFromRegistry( gTreeView ); - - SetWindowTitle( hWnd, fileName ); - } - - break; - - case ID_FILE_ABOUT: - DialogBox( gInstance, MAKEINTRESOURCE( IDD_ABOUT ), hWnd, AboutDialogProc ); - break; - - case ID_FILE_FINDOBJECT: - plResTreeView::FindObject( gTreeView ); - break; - - case ID_FILE_FINDNEXT: - plResTreeView::FindNextObject( gTreeView ); - break; - - case ID_FILE_VERIFYPAGE: - plResTreeView::VerifyCurrentPage( gTreeView ); - break; - - case IDC_SHOWASHEX: - plResTreeView::UpdateInfoDlg( gTreeView ); - break; - - case ID_FILE_ONLYLOAD: - filter = !filter; - plResTreeView::FilterLoadables( filter, gTreeView ); - { - HMENU menu = ::GetMenu( hWnd ); - menu = ::GetSubMenu( menu, 0 ); - ::CheckMenuItem( menu, ID_FILE_ONLYLOAD, MF_BYCOMMAND | ( filter ? MF_CHECKED : MF_UNCHECKED ) ); - } - break; - - case ID_FILE_SAVESELECTED: - plResTreeView::SaveSelectedObject(gTreeView); - break; - - default: - return DefWindowProc( hWnd, WM_COMMAND, wParam, lParam ); - } - - return 0; -} - -void SizeControls( HWND parent ) -{ - RECT clientRect, infoRect; - - - GetClientRect( parent, &clientRect ); - GetClientRect( gInfoDlg, &infoRect ); - - SetWindowPos( gTreeView, NULL, 0, 0, clientRect.right - infoRect.right - 4, clientRect.bottom, 0 ); - - OffsetRect( &infoRect, clientRect.right - infoRect.right, ( clientRect.bottom >> 1 ) - ( infoRect.bottom >> 1 ) ); - SetWindowPos( gInfoDlg, NULL, infoRect.left, infoRect.top, 0, 0, SWP_NOSIZE ); -} - -void InitWindowControls( HWND hWnd ) -{ - RECT clientRect; - - - GetClientRect( hWnd, &clientRect ); - - gTreeView = CreateWindowEx( WS_EX_CLIENTEDGE, WC_TREEVIEW, "Tree View", WS_VISIBLE | WS_CHILD | WS_BORDER | - TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_SHOWSELALWAYS, - 0, 0, 0, 0, - hWnd, (HMENU)IDC_REGTREEVIEW, gInstance, NULL ); - - - gInfoDlg = CreateDialog( gInstance, MAKEINTRESOURCE( IDD_INFODLG ), hWnd, plResTreeView::InfoDlgProc ); - - SizeControls( hWnd ); -} - -static bool sFileTypesRegistered = false; - -void RegisterFileTypes( HWND mainWnd ) -{ - if( sFileTypesRegistered ) - return; - - // Make sure our file types are created - char path[ MAX_PATH ]; - - if( ::GetModuleFileName( nil, path, sizeof( path ) ) == 0 ) - return; - - //plWinRegistryTools::AssociateFileType( "PlasmaIdxFile", "Plasma 2 Index File", path, 1 ); - //plWinRegistryTools::AssociateFileType( "PlasmaDatFile", "Plasma 2 Data File", path, 2 ); - //plWinRegistryTools::AssociateFileType( "PlasmaPatchFile", "Plasma 2 Patch File", path, 3 ); - plWinRegistryTools::AssociateFileType( "PlasmaPackFile", "Plasma 2 Packfile", path, 4 ); - - // Check our file extensions - char prpAssoc[ 512 ]; - bool needToRegister = true; - if( plWinRegistryTools::GetCurrentFileExtensionAssociation( ".prp", prpAssoc, sizeof( prpAssoc ) ) ) - { - if( strcmp( prpAssoc, "PlasmaPackFile" ) == 0 ) - needToRegister = false; - } - - if( needToRegister ) - { - if( MessageBox( nil, "The Plasma 2 packed data file extension .prp is not currently associated with " - "plResBrowser. Would you like to associate it now?", "plResBrowser File Type Association", - MB_YESNO | MB_ICONQUESTION) == IDYES ) - { - // Associate 'em - plWinRegistryTools::AssociateFileExtension( ".prp", "PlasmaPackFile" ); - } - } - - sFileTypesRegistered = true; -} - -LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) -{ - switch( message ) - { - case WM_CREATE: - InitCommonControls(); - InitWindowControls( hWnd ); - RegisterFileTypes( hWnd ); - plResMgrSettings::Get().SetLoadPagesOnInit(false); - - { - plResTreeView::FilterLoadables( true, gTreeView ); - HMENU menu = ::GetMenu( hWnd ); - menu = ::GetSubMenu( menu, 0 ); - ::CheckMenuItem( menu, ID_FILE_ONLYLOAD, MF_BYCOMMAND | MF_CHECKED ); - } - - if( gCommandLine != nil ) - { - plWaitCursor myWaitCursor; - - char path[ MAX_PATH ]; - if( gCommandLine[ 0 ] == '"' ) - { - strcpy( path, gCommandLine + 1 ); - char *c = strchr( path, '"' ); - if( c != nil ) - *c = 0; - } - else - strcpy( path, gCommandLine ); - - if( stricmp( PathFindExtension( path ), ".prp" ) == 0 ) - { - hsgResMgr::Reset(); - plResTreeView::ClearTreeView( gTreeView ); - plResManager *mgr = (plResManager *)hsgResMgr::ResMgr(); - mgr->AddSinglePage(path); - plResTreeView::FillTreeViewFromRegistry( gTreeView ); - - SetWindowTitle( hWnd, path ); - } - } - break; - - case WM_CLOSE: - DestroyWindow( hWnd ); - break; - case WM_DESTROY: - plResTreeView::ClearTreeView( gTreeView ); - PostQuitMessage(0); - break; - - case WM_SIZING: - case WM_SIZE: - SizeControls( hWnd ); - break; - - case WM_NOTIFY: - if( wParam == IDC_REGTREEVIEW ) - { - NMHDR *hdr = (NMHDR *)lParam; - if( hdr->code == TVN_SELCHANGED ) - { - plResTreeView::UpdateInfoDlg( gTreeView ); - //NMTREEVIEW *tv = (NMTREEVIEW *)hdr; - - } - else if( hdr->code == NM_DBLCLK ) - { - plResTreeView::SelectionDblClicked( gTreeView ); - } - } - break; - - case WM_DROPFILES: - { - int i, j, fileCount = DragQueryFile( (HDROP)wParam, -1, nil, 0 ); - char path[ MAX_PATH ]; - - plWaitCursor myWaitCursor; - - hsgResMgr::Reset(); - plResTreeView::ClearTreeView( gTreeView ); - plResManager *mgr = (plResManager *)hsgResMgr::ResMgr(); - - if( fileCount == 1 && DragQueryFile( (HDROP)wParam, 0, path, sizeof( path ) ) > 0 && - ( (char *)PathFindExtension( path ) )[ 0 ] == 0 ) - { - // Must be a directory - std::vector prpFiles = plFileSystem::ListDir(path, "*.prp"); - for (auto iter = prpFiles.begin(); iter != prpFiles.end(); ++iter) - mgr->AddSinglePage(*iter); - } - else - { - hsTArray filesAdded; - - filesAdded.Reset(); - for( i = 0; i < fileCount; i++ ) - { - if( DragQueryFile( (HDROP)wParam, i, path, sizeof( path ) ) > 0 ) - { - // Check for duplicates - for( j = 0; j < filesAdded.GetCount(); j++ ) - { - if( stricmp( filesAdded[ j ], path ) == 0 ) - break; - } - if( j < filesAdded.GetCount() ) - continue; - - if( stricmp( PathFindExtension( path ), ".prp" ) == 0 ) - { - mgr->AddSinglePage(path); - filesAdded.Append( hsStrcpy( path ) ); - } - } - } - - for( j = 0; j < filesAdded.GetCount(); j++ ) - delete [] filesAdded[ j ]; - } - plResTreeView::FillTreeViewFromRegistry( gTreeView ); - - PathRemoveFileSpec( path ); - SetWindowTitle( hWnd, path ); - } - break; - - case WM_COMMAND: - return HandleCommand( hWnd, wParam, lParam ); - } - - return DefWindowProc( hWnd, message, wParam, lParam ); -} - diff --git a/Sources/Tools/plResBrowser/plResTreeView.cpp b/Sources/Tools/plResBrowser/plResTreeView.cpp index fdca3da2..cd1afd71 100644 --- a/Sources/Tools/plResBrowser/plResTreeView.cpp +++ b/Sources/Tools/plResBrowser/plResTreeView.cpp @@ -40,9 +40,9 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com *==LICENSE==*/ #include "HeadSpin.h" -#include "hsWindows.h" #include "plResTreeView.h" +#include "ui_FindDialog.h" #include "plResMgr/plResManager.h" #include "plResMgr/plRegistryHelpers.h" @@ -53,470 +53,141 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pnKeyedObject/plKeyImp.h" #include "pnFactory/plFactory.h" -#include -#include -#include "res/resource.h" - - -extern HINSTANCE gInstance; -HWND plResTreeView::fInfoDlg = nil; -bool plResTreeView::fFilter = false; - -static char gSearchString[ 512 ]; -static HTREEITEM fFoundItem = nil; - -extern void ViewPatchDetails( plKey &patchKey ); - - -INT_PTR CALLBACK FindDialogProc( HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam ) -{ - switch( msg ) - { - case WM_INITDIALOG: - return true; - - case WM_COMMAND: - if( LOWORD( wParam ) == IDOK ) - { - GetDlgItemText( dlg, IDC_SEARCHSTRING, gSearchString, sizeof( gSearchString ) ); - fFoundItem = nil; - EndDialog( dlg, IDOK ); - } - else if( LOWORD( wParam ) == IDCANCEL ) - EndDialog( dlg, IDCANCEL ); - - return -1; - } - - return 0; -} - +#include +#include +#include struct plKeyInfo { plKey fKey; - plRegistryPageNode *fPage; - - plKeyInfo( plKey k, plRegistryPageNode *p ) : fKey( k ), fPage( p ) {} -}; - -// How's this for functionality? -class plResDlgLoader : public plRegistryPageIterator, public plRegistryKeyIterator -{ - protected: - - HWND fTree; - HTREEITEM fCurrItem, fCurrTypeItem; - uint16_t fCurrType; - bool fFilter; - - plRegistryPageNode *fCurrPage; - - - HTREEITEM AddLeaf(HWND hTree, HTREEITEM hParent, const char *text, plKeyInfo *info ) - { - TVITEM tvi = {0}; - tvi.mask = TVIF_TEXT | TVIF_PARAM; - tvi.pszText = text ? (char*)text : (char*)""; - tvi.cchTextMax = text ? strlen(text) : 7; - tvi.lParam = (LPARAM)info; - - TVINSERTSTRUCT tvins = {0}; - tvins.item = tvi; - tvins.hParent = hParent; - tvins.hInsertAfter = TVI_SORT; - - return TreeView_InsertItem(hTree, &tvins); - } - - public: - - plResDlgLoader( HWND hTree, bool filter ) - { - fFilter = filter; - fTree = hTree; - ((plResManager *)hsgResMgr::ResMgr())->IterateAllPages( this ); - } - - virtual bool EatPage( plRegistryPageNode *page ) - { - char str[ 512 ]; - - - fCurrPage = page; - const plPageInfo &info = page->GetPageInfo(); - sprintf( str, "%s->%s", info.GetAge().c_str(), info.GetPage().c_str()); - fCurrItem = AddLeaf( fTree, NULL, str, new plKeyInfo( nil, fCurrPage ) ); - - fCurrType = (uint16_t)-1; - page->LoadKeys(); - page->IterateKeys( this ); - return true; - } - - virtual bool EatKey( const plKey& key ) - { - if( fCurrType != key->GetUoid().GetClassType() ) - { - fCurrType = key->GetUoid().GetClassType(); - const char *className = plFactory::GetNameOfClass( fCurrType ); - fCurrTypeItem = AddLeaf( fTree, fCurrItem, className != nil ? className : "", nil ); - } - - if( !fFilter ) - AddLeaf( fTree, fCurrTypeItem, key->GetUoid().GetObjectName().c_str(), new plKeyInfo( key, fCurrPage ) ); - return true; - } + plRegistryPageNode *fPage; }; -void plResTreeView::FillTreeViewFromRegistry( HWND hWnd ) +plResTreeViewItem::~plResTreeViewItem() { - plResDlgLoader loader( hWnd, fFilter ); + delete fData; } -HTREEITEM IGetNextTreeItem( HWND tree, HTREEITEM item ) +plKey plResTreeViewItem::GetKey() const { - // First try child items of this one - HTREEITEM next = TreeView_GetChild( tree, item ); - if( next == nil ) - // If no child items, try next sibling - next = TreeView_GetNextSibling( tree, item ); - if( next == nil ) - { - // If no siblings, go up to the parent and keep searching until we find a parent with a sibling - next = item; - while( true ) - { - next = TreeView_GetParent( tree, next ); - if( next == nil ) - { - // No parent; not found, so stop - break; - } - else if( TreeView_GetNextSibling( tree, next ) != nil ) - { - next = TreeView_GetNextSibling( tree, next ); - break; - } - } - } - - return next; + return fData ? fData->fKey : nullptr; } -void plResTreeView::FindNextObject( HWND tree ) +plRegistryPageNode *plResTreeViewItem::GetPage() const { - if( fFoundItem == nil ) - FindObject( tree ); - else - { - fFoundItem = IGetNextTreeItem( tree, fFoundItem ); - IFindNextObject( tree ); - } + return fData ? fData->fPage : nullptr; } -void plResTreeView::FindObject( HWND tree ) + +// How's this for functionality? +class plResDlgLoader : public plRegistryPageIterator, public plRegistryKeyIterator { - if( DialogBox( gInstance, MAKEINTRESOURCE( IDD_FINDOBJ ), tree, FindDialogProc ) == IDOK ) +protected: + plResTreeView *fTree; + plResTreeViewItem *fCurrItem; + plResTreeViewItem *fCurrTypeItem; + uint16_t fCurrType; + bool fFilter; + + plRegistryPageNode *fCurrPage; + +public: + plResDlgLoader(plResTreeView *tree, bool filter) + : fFilter(filter), fTree(tree) { - fFoundItem = TreeView_GetRoot( tree ); - IFindNextObject( tree ); + static_cast(hsgResMgr::ResMgr())->IterateAllPages(this); } -} -void plResTreeView::IFindNextObject( HWND tree ) -{ - while( fFoundItem != nil ) + virtual bool EatPage(plRegistryPageNode *page) { - // Get the item - TVITEM itemInfo; - itemInfo.mask = TVIF_PARAM | TVIF_HANDLE; - itemInfo.hItem = fFoundItem; - TreeView_GetItem( tree, &itemInfo ); - plKeyInfo *keyInfo = (plKeyInfo *)itemInfo.lParam; - if( keyInfo != nil && keyInfo->fKey != nil ) - { - if( keyInfo->fKey->GetUoid().GetObjectName().Compare( gSearchString, plString::kCaseInsensitive ) >= 0 ) - { - /// FOUND - TreeView_SelectItem( tree, fFoundItem ); - return; - } - } - - // Keep searching. First try child items of this one - fFoundItem = IGetNextTreeItem( tree, fFoundItem ); + fCurrPage = page; + const plPageInfo &info = page->GetPageInfo(); + QString name = QString("%1->%2").arg(info.GetAge().c_str()).arg(info.GetPage().c_str()); + fCurrItem = new plResTreeViewItem(fTree, name, new plKeyInfo { nullptr, fCurrPage }); + + fCurrType = static_cast(-1); + page->LoadKeys(); + page->IterateKeys(this); + return true; } - MessageBox( tree, "No objects found", "Find Object", MB_OK ); -} - -void IDeleteRecurse( HWND tree, HTREEITEM item ) -{ - while( item != nil ) + virtual bool EatKey(const plKey &key) { - HTREEITEM child = TreeView_GetChild( tree, item ); - if( child != nil ) - IDeleteRecurse( tree, child ); - - TVITEM itemInfo; - itemInfo.mask = TVIF_PARAM | TVIF_HANDLE; - itemInfo.hItem = item; - TreeView_GetItem( tree, &itemInfo ); - plKeyInfo *keyInfo = (plKeyInfo *)itemInfo.lParam; - if( keyInfo != nil ) + if (fCurrType != key->GetUoid().GetClassType()) { - delete keyInfo; - itemInfo.lParam = 0; - TreeView_SetItem( tree, &itemInfo ); + fCurrType = key->GetUoid().GetClassType(); + const char *className = plFactory::GetNameOfClass(fCurrType); + fCurrTypeItem = new plResTreeViewItem(fCurrItem, className ? className : "", nullptr); } - item = TreeView_GetNextSibling( tree, item ); + if (!fFilter) { + new plResTreeViewItem(fCurrTypeItem, key->GetUoid().GetObjectName().c_str(), + new plKeyInfo { key, fCurrPage }); + } + return true; } -} +}; -void plResTreeView::ClearTreeView( HWND hWnd ) +void plResTreeView::LoadFromRegistry(bool filter) { - HTREEITEM root = TreeView_GetRoot( hWnd ); - if( root != nil ) - IDeleteRecurse( hWnd, root ); - - TreeView_DeleteAllItems( hWnd ); + plResDlgLoader loader(this, filter); + sortItems(0, Qt::AscendingOrder); } -void plResTreeView::SelectionDblClicked( HWND treeCtrl ) +static QTreeWidgetItem *IGetNextTreeItem(QTreeWidgetItem *item) { - HTREEITEM sel = TreeView_GetSelection( treeCtrl ); - if( sel != nil ) - { - TVITEM item; - - item.mask = TVIF_PARAM | TVIF_HANDLE; - item.hItem = sel; - if( !TreeView_GetItem( treeCtrl, &item ) ) - return; - } -} + if (!item) + return nullptr; -void plResTreeView::FilterLoadables( bool filter, HWND treeCtrl ) -{ - fFilter = filter; - ClearTreeView( treeCtrl ); - FillTreeViewFromRegistry( treeCtrl ); + QTreeWidgetItemIterator iter(item); + return *(++iter); } -INT_PTR CALLBACK plResTreeView::InfoDlgProc( HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam ) +void plResTreeView::FindObject() { - switch( msg ) - { - case WM_INITDIALOG: - fInfoDlg = dlg; - break; - - case WM_COMMAND: - return SendMessage( GetParent( dlg ), msg, wParam, lParam ); - } + QDialog findDialog(this); + Ui_FindDialog ui; + ui.setupUi(&findDialog); - return 0; -} + findDialog.layout()->setSizeConstraint(QLayout::SetFixedSize); -void plResTreeView::VerifyCurrentPage( HWND treeCtrl ) -{ - HTREEITEM sel = TreeView_GetSelection( treeCtrl ); - if( sel != nil ) + if (findDialog.exec() == QDialog::Accepted) { - TVITEM item; - - item.mask = TVIF_PARAM | TVIF_HANDLE; - item.hItem = sel; - if( !TreeView_GetItem( treeCtrl, &item ) ) - return; - - plKeyInfo *info = (plKeyInfo *)item.lParam; - if( info != nil ) - { - if( info->fPage != nil ) - { - // TODO: FIXME - /* - /// HACK. Live with it - class plHackResManager : public plResManager - { - public: - plRegistry *GetRegistry( void ) { return IGetRegistry(); } - }; - - plRegistry *registry = ((plHackResManager *)hsgResMgr::ResMgr())->GetRegistry(); - - plRegistry::plPageCond result = registry->VerifyOnePage( info->fPage ); - - char msg[ 512 ]; - if( result == plRegistry::kOK || result == plRegistry::kTooNew ) - strcpy( msg, "Page verifies OK" ); - else if( result == plRegistry::kChecksumInvalid ) - strcpy( msg, "Checksums for page are invalid" ); - else if( result == plRegistry::kOutOfDate ) - strcpy( msg, "Page is older than the current data version" ); - - hsMessageBox( msg, "Verification Results", hsMessageBoxNormal ); - */ - } - } + fFoundItem = invisibleRootItem(); + fSearchString = ui.fObjectName->text().toUtf8().constData(); + IFindNextObject(); } } -void plResTreeView::UpdateInfoDlg( HWND treeCtrl ) +void plResTreeView::FindNextObject() { - bool showAsHex = (bool)IsDlgButtonChecked( fInfoDlg, IDC_SHOWASHEX ); - - SetDlgItemText( fInfoDlg, IDC_NAME, "" ); - SetDlgItemText( fInfoDlg, IDC_CLASS, "" ); - SetDlgItemText( fInfoDlg, IDC_LENGTH, "" ); - SetDlgItemText( fInfoDlg, IDC_STARTPOS, "" ); - EnableWindow( GetDlgItem( fInfoDlg, ID_FILE_VERIFYPAGE ), FALSE ); - - HTREEITEM sel = TreeView_GetSelection( treeCtrl ); - if( sel != nil ) + if (!fFoundItem) + FindObject(); + else { - TVITEM item; - - item.mask = TVIF_PARAM | TVIF_HANDLE; - item.hItem = sel; - if( !TreeView_GetItem( treeCtrl, &item ) ) - return; - - plKeyInfo *info = (plKeyInfo *)item.lParam; - if( info != nil ) - { - if( info->fPage != nil ) - { - const plPageInfo &pageInfo = info->fPage->GetPageInfo(); - char tempStr[ 32 ]; - - SetDlgItemText( fInfoDlg, IDC_AGE, pageInfo.GetAge().c_str()); - SetDlgItemText( fInfoDlg, IDC_PAGE, pageInfo.GetPage().c_str()); - - SetDlgItemText( fInfoDlg, IDC_LOCATION, pageInfo.GetLocation().StringIze().c_str() ); - - CheckDlgButton(fInfoDlg, IDC_RESERVED, (pageInfo.GetLocation().GetFlags() & plLocation::kReserved) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(fInfoDlg, IDC_BUILTIN, (pageInfo.GetLocation().GetFlags() & plLocation::kBuiltIn) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(fInfoDlg, IDC_VOLATILE, (pageInfo.GetLocation().GetFlags() & plLocation::kVolatile) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(fInfoDlg, IDC_LOCAL_ONLY, (pageInfo.GetLocation().GetFlags() & plLocation::kLocalOnly) ? BST_CHECKED : BST_UNCHECKED); - - sprintf( tempStr, "%d", pageInfo.GetMajorVersion()); - SetDlgItemText( fInfoDlg, IDC_DATAVERSION, tempStr ); - - SetDlgItemText( fInfoDlg, IDC_CHECKSUMTYPE, "Basic (file size)" ); - EnableWindow( GetDlgItem( fInfoDlg, ID_FILE_VERIFYPAGE ), TRUE ); - } - - if( info->fKey != nil ) - { - char str[ 128 ]; - - - SetDlgItemText( fInfoDlg, IDC_NAME, info->fKey->GetUoid().GetObjectName().c_str() ); - - const char *name = plFactory::GetNameOfClass( info->fKey->GetUoid().GetClassType() ); - sprintf( str, "%s (%d)", name != nil ? name : "", info->fKey->GetUoid().GetClassType() ); - SetDlgItemText( fInfoDlg, IDC_CLASS, str ); - - plKeyImp *imp = (plKeyImp *)info->fKey; - EnableWindow( GetDlgItem( fInfoDlg, IDC_STARTPOS_LABEL ), true ); - EnableWindow( GetDlgItem( fInfoDlg, IDC_SIZE_LABEL ), true ); - - if( showAsHex ) - sprintf( str, "0x%X", imp->GetStartPos() ); - else - sprintf( str, "%d", imp->GetStartPos() ); - SetDlgItemText( fInfoDlg, IDC_STARTPOS, str ); - - if( imp->GetDataLen() < 1024 ) - sprintf( str, "%d bytes", imp->GetDataLen() ); - else if( imp->GetDataLen() < 1024 * 1024 ) - sprintf( str, "%4.2f kB", imp->GetDataLen() / 1024.f ); - else - sprintf( str, "%4.2f MB", imp->GetDataLen() / 1024.f / 1024.f ); - - SetDlgItemText( fInfoDlg, IDC_LENGTH, str ); - } - } + fFoundItem = IGetNextTreeItem(fFoundItem); + IFindNextObject(); } } -#include "hsStream.h" -#include - -void plResTreeView::SaveSelectedObject(HWND treeCtrl) +void plResTreeView::IFindNextObject() { - // TODO: FIXME - /* - plKey itemKey = nil; - - HTREEITEM sel = TreeView_GetSelection(treeCtrl); - if (sel != nil) + while (fFoundItem) { - TVITEM item; - item.mask = TVIF_PARAM | TVIF_HANDLE; - item.hItem = sel; - if (TreeView_GetItem(treeCtrl, &item)) + // Get the item + plKey key = fFoundItem->type() == plResTreeViewItem::Type + ? static_cast(fFoundItem)->GetKey() + : nullptr; + if (key && key->GetUoid().GetObjectName().Find(fSearchString, plString::kCaseInsensitive) >= 0) { - plKeyInfo *info = (plKeyInfo*)item.lParam; - if (info != nil) - itemKey = info->fKey; - } - } - - if (!itemKey) - return; - - char fileName[MAX_PATH]; - sprintf(fileName, "%s.bin", itemKey->GetName()); - - OPENFILENAME openInfo; - memset( &openInfo, 0, sizeof( OPENFILENAME ) ); -// openInfo.hInstance = gInstance; -// openInfo.hwndOwner = hWnd; - openInfo.lStructSize = sizeof( OPENFILENAME ); - openInfo.lpstrFile = fileName; - openInfo.nMaxFile = sizeof( fileName ); - openInfo.lpstrFilter = "Binary Files\0*.bin\0All Files\0*.*\0"; -// openInfo.lpstrTitle = "Choose a pack index file to browse:"; -// openInfo.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; - - if (GetSaveFileName(&openInfo)) - { - plKeyImp* keyImp = (plKeyImp*)itemKey; - - if (keyImp->GetDataLen() <= 0) + /// FOUND + setCurrentItem(fFoundItem); return; - - plResManager* resMgr = (plResManager*)hsgResMgr::ResMgr(); - const plPageInfo& pageInfo = resMgr->FindPage(keyImp->GetUoid().GetLocation())->GetPageInfo(); - - plRegistryDataStream *stream = registry->OpenPageDataStream( keyImp->GetUoid().GetLocation(), false ); - if( stream == nil ) - return; - - hsStream *dataStream = stream->GetStream(); - uint8_t *buffer = new uint8_t[ keyImp->GetDataLen() ]; - if( buffer != nil ) - { - dataStream->SetPosition( keyImp->GetStartPos() ); - dataStream->Read( keyImp->GetDataLen(), buffer ); } - delete stream; - - if( buffer == nil ) - return; - - hsUNIXStream outStream; - outStream.Open(fileName, "wb"); - outStream.Write(keyImp->GetDataLen(), buffer); - outStream.Close(); - delete [] buffer; + // Keep searching. First try child items of this one + fFoundItem = IGetNextTreeItem(fFoundItem); } - */ -} + QMessageBox::critical(this, tr("Find Objects"), tr("No objects found")); +} diff --git a/Sources/Tools/plResBrowser/plResTreeView.h b/Sources/Tools/plResBrowser/plResTreeView.h index 9281e714..fb9e9a3e 100644 --- a/Sources/Tools/plResBrowser/plResTreeView.h +++ b/Sources/Tools/plResBrowser/plResTreeView.h @@ -42,34 +42,53 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #ifndef _plResTreeView_h #define _plResTreeView_h -class plResTreeView +#include "plString.h" + +#include + +struct plKeyInfo; +class plKey; +class plRegistryPageNode; + +class plResTreeViewItem : public QTreeWidgetItem { - protected: +public: + enum { Type = UserType }; - static HWND fInfoDlg; - static bool fFilter; + plResTreeViewItem(QTreeWidget *parent, const QString &text, plKeyInfo *key) + : QTreeWidgetItem(parent, QStringList { text }, Type), fData(key) { } + plResTreeViewItem(QTreeWidgetItem *parent, const QString &text, plKeyInfo *key) + : QTreeWidgetItem(parent, QStringList { text }, Type), fData(key) { } - static void IFindNextObject( HWND tree ); + virtual ~plResTreeViewItem(); - public: + plKey GetKey() const; + plRegistryPageNode *GetPage() const; - static void FindObject( HWND tree ); - static void FindNextObject( HWND tree ); +private: + plKeyInfo *fData; +}; - static void FillTreeViewFromRegistry( HWND hWnd ); - static void ClearTreeView( HWND hWnd ); - static INT_PTR CALLBACK InfoDlgProc( HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam ); +class plResTreeView : public QTreeWidget +{ + Q_OBJECT - static void UpdateInfoDlg( HWND treeCtrl ); +public: + plResTreeView(QWidget *parent = nullptr) + : QTreeWidget(parent), fFoundItem(nullptr) { } - static void VerifyCurrentPage( HWND treeCtrl ); + void LoadFromRegistry(bool filter); - static void SelectionDblClicked( HWND treeCtrl ); +public slots: + void FindObject(); + void FindNextObject(); - static void FilterLoadables( bool filter, HWND treeCtrl ); +private: + QTreeWidgetItem *fFoundItem; + plString fSearchString; - static void SaveSelectedObject(HWND treeCtrl); + void IFindNextObject(); }; #endif //_plResTreeView_h diff --git a/Sources/Tools/plResBrowser/plWinRegistryTools.cpp b/Sources/Tools/plResBrowser/plWinRegistryTools.cpp index 46ef0538..07704756 100644 --- a/Sources/Tools/plResBrowser/plWinRegistryTools.cpp +++ b/Sources/Tools/plResBrowser/plWinRegistryTools.cpp @@ -52,6 +52,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "hsWindows.h" #include "plWinRegistryTools.h" +#include +#include ////////////////////////////////////////////////////////////////////////////// @@ -62,27 +64,31 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com // Sets the given registry key to the given string value. If valueName = nil, // sets the (default) value -static bool ISetRegKey( const char *keyName, const char *value, const char *valueName = nil ) +static bool ISetRegKey(const QString &keyName, const QString &value, const QString &valueName = QString()) { HKEY regKey; DWORD result; // Create the key (just opens if it already exists) - if( ::RegCreateKeyEx( HKEY_CLASSES_ROOT, keyName, 0, nil, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, - nil, ®Key, &result ) != ERROR_SUCCESS ) + if (::RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName.toStdWString().c_str(), 0, + nullptr, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, + nullptr, ®Key, &result) != ERROR_SUCCESS) { - hsStatusMessageF( "Warning: Registry database open failed for key '%s'.\n", keyName ); + hsStatusMessageF("Warning: Registry database open failed for key '%s'.\n", qPrintable(keyName)); return false; } // Assign the "default" subkey value - LONG lResult = ::RegSetValueEx( regKey, valueName, 0, REG_SZ, (const BYTE *)value, ( lstrlen( value ) + 1 ) * sizeof( TCHAR ) ); + std::wstring wValue = value.toStdWString(); + LONG lResult = ::RegSetValueExW(regKey, valueName.toStdWString().c_str(), 0, + REG_SZ, reinterpret_cast(wValue.c_str()), + (wValue.size() + 1) * sizeof(wchar_t)); - if( ::RegCloseKey( regKey ) == ERROR_SUCCESS && lResult == ERROR_SUCCESS ) + if (::RegCloseKey(regKey) == ERROR_SUCCESS && lResult == ERROR_SUCCESS) return true; - hsStatusMessageF( "Warning: Registry database update failed for key '%s'.\n", keyName ); + hsStatusMessageF("Warning: Registry database update failed for key '%s'.\n", qPrintable(keyName)); return false; } @@ -108,28 +114,26 @@ static bool ISetRegKey( const char *keyName, const char *value, const char * // |--- command (value = command line) // -bool plWinRegistryTools::AssociateFileType( const char *fileTypeID, const char *fileTypeName, const char *appPath, int iconIndex ) +bool plWinRegistryTools::AssociateFileType(const QString &fileTypeID, const QString &fileTypeName, + const QString &appPath, int iconIndex) { - char keyName[ 512 ], keyValue[ 512 ]; - - // Root key - if( !ISetRegKey( fileTypeID, fileTypeName ) ) + if (!ISetRegKey(fileTypeID, fileTypeName)) return false; // DefaultIcon key, if we want one - if( iconIndex != -1 ) + if (iconIndex != -1) { - sprintf( keyName, "%s\\DefaultIcon", fileTypeID ); - sprintf( keyValue, "%s,%d", appPath, iconIndex ); - if( !ISetRegKey( keyName, keyValue ) ) + QString keyName = QString(R"(%1\DefaultIcon)").arg(fileTypeID); + QString keyValue = QString("%1,%2").arg(appPath).arg(iconIndex); + if (!ISetRegKey(keyName, keyValue)) return false; } // shell/open/command key - sprintf( keyName, "%s\\shell\\open\\command", fileTypeID ); - sprintf( keyValue, "\"%s\" \"%%1\"", appPath ); - if( !ISetRegKey( keyName, keyValue ) ) + QString keyName = QString(R"(%1\shell\open\command)").arg(fileTypeID); + QString keyValue = QString(R"("%1" "%2")").arg(appPath, "%1"); + if (!ISetRegKey(keyName, keyValue)) return false; // Success! @@ -148,32 +152,33 @@ bool plWinRegistryTools::AssociateFileType( const char *fileTypeID, const cha // where fileExtension includes the leading . and fileTypeID is the same // typeID registered with the above function -bool plWinRegistryTools::AssociateFileExtension( const char *fileExtension, const char *fileTypeID ) +bool plWinRegistryTools::AssociateFileExtension(const QString &fileExtension, const QString &fileTypeID) { - return ISetRegKey( fileExtension, fileTypeID ); + return ISetRegKey(fileExtension, fileTypeID); } //// GetCurrentFileExtensionAssociation ////////////////////////////////////// // Obtains the current fileTypeID associated with the given file extension, // or a null string if it isn't yet associated. -bool plWinRegistryTools::GetCurrentFileExtensionAssociation( const char *extension, char *buffer, int bufferLen ) +QString plWinRegistryTools::GetCurrentFileExtensionAssociation(const QString &extension) { - long dataLen; - - - buffer[ 0 ] = 0; - dataLen = bufferLen; + long dataLen = 512; + wchar_t buffer[512]; + buffer[0] = 0; - LONG retVal = ::RegQueryValue( HKEY_CLASSES_ROOT, extension, buffer, &dataLen ); - if( retVal != ERROR_SUCCESS ) + LONG retVal = ::RegQueryValueW(HKEY_CLASSES_ROOT, extension.toStdWString().c_str(), buffer, &dataLen); + if (retVal != ERROR_SUCCESS) { - char msg[ 512 ]; - FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, retVal, 0, msg, sizeof( msg ), nil ); - hsStatusMessageF( "Error querying registry key '%s' : %s\n", extension, msg ); - return false; + char msg[512]; + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, retVal, 0, msg, arrsize(msg), nullptr); + hsStatusMessageF("Error querying registry key '%s' : %s\n", qPrintable(extension), msg); + return QString(); } - return true; + if (dataLen < 512 && buffer[dataLen] == 0) + dataLen -= 1; + + return QString::fromWCharArray(buffer, dataLen); } diff --git a/Sources/Tools/plResBrowser/plWinRegistryTools.h b/Sources/Tools/plResBrowser/plWinRegistryTools.h index faa77949..e8c61ce1 100644 --- a/Sources/Tools/plResBrowser/plWinRegistryTools.h +++ b/Sources/Tools/plResBrowser/plWinRegistryTools.h @@ -51,18 +51,25 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #ifndef _plWinRegistryTools_h #define _plWinRegistryTools_h +class QString; + class plWinRegistryTools { public: - // Associates a given file type in the Win32 registry with the given application. Also assigns a default icon if iconIndex != -1 - static bool AssociateFileType( const char *fileTypeID, const char *fileTypeName, const char *appPath, int iconIndex = -1 ); + /* Associates a given file type in the Win32 registry with the given + application. Also assigns a default icon if iconIndex != -1 */ + static bool AssociateFileType(const QString &fileTypeID, const QString &fileTypeName, + const QString &appPath, int iconIndex = -1); - // Assigns a given file extension to a previously registered Win32 file type (using the above function) - static bool AssociateFileExtension( const char *fileExtension, const char *fileTypeID ); + /* Assigns a given file extension to a previously registered Win32 + file type (using the above function) */ + static bool AssociateFileExtension(const QString &fileExtension, + const QString &fileTypeID); - // Obtains the current fileTypeID associated with the given file extension, or a null string if it isn't yet associated - static bool GetCurrentFileExtensionAssociation( const char *extension, char *buffer, int bufferLen ); + /* Obtains the current fileTypeID associated with the given file + extension, or a null string if it isn't yet associated */ + static QString GetCurrentFileExtensionAssociation(const QString &extension); }; -#endif //_plWinRegistryTools_h \ No newline at end of file +#endif //_plWinRegistryTools_h diff --git a/Sources/Tools/plResBrowser/res/FindDialog.ui b/Sources/Tools/plResBrowser/res/FindDialog.ui new file mode 100644 index 00000000..cc41e350 --- /dev/null +++ b/Sources/Tools/plResBrowser/res/FindDialog.ui @@ -0,0 +1,76 @@ + + + FindDialog + + + + 0 + 0 + 320 + 71 + + + + Find Object + + + + + + Object Name + + + + + + + + + + + + Qt::Vertical + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + FindDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + FindDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/Sources/Tools/plResBrowser/res/ResBrowser.ui b/Sources/Tools/plResBrowser/res/ResBrowser.ui new file mode 100644 index 00000000..b020eae8 --- /dev/null +++ b/Sources/Tools/plResBrowser/res/ResBrowser.ui @@ -0,0 +1,591 @@ + + + ResBrowser + + + + 0 + 0 + 800 + 600 + + + + plResBrowser + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + false + + + + 1 + + + + + + + + + + 0 + 0 + 800 + 21 + + + + + &File + + + + + + + + + + + + + + + &Help + + + + + + + + + + 300 + 520 + + + + QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable + + + Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea + + + Properties + + + 2 + + + + + 0 + 0 + + + + + 300 + 0 + + + + + 300 + 16777215 + + + + + + + Page Information + + + + + + Age: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + true + + + + + + + true + + + + + + + Data Version: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Location: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Page + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + Checksum: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + + 0 + 0 + + + + Local Only + + + + + + + + 0 + 0 + + + + Reserved + + + + + + + + 0 + 0 + + + + Volatile + + + + + + + + 0 + 0 + + + + Built-In + + + + + + + + + true + + + + + + + Checksum Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 40 + + + + + + + + + + + Object Information + + + + + + Start Pos: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Class: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + true + + + + + + + Size: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 20 + + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 0 + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + View values as he&x + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Fin&d + + + + + + + Find &Next + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + &Save Object + + + + + + + + + + + &Open... + + + + + Open &Directory... + + + + + false + + + &Save Selected Object + + + + + &Find Object... + + + Ctrl+F + + + + + Find &Next + + + F3 + + + + + true + + + Show Only &Loadable + + + + + E&xit + + + + + &About... + + + + + + plResTreeView + QTreeWidget +
plResTreeView.h
+
+
+ + +
diff --git a/Sources/Tools/plResBrowser/res/plResBrowser.qrc b/Sources/Tools/plResBrowser/res/plResBrowser.qrc new file mode 100644 index 00000000..81055f95 --- /dev/null +++ b/Sources/Tools/plResBrowser/res/plResBrowser.qrc @@ -0,0 +1,5 @@ + + + icon1.ico + + diff --git a/Sources/Tools/plResBrowser/res/plResBrowser.rc b/Sources/Tools/plResBrowser/res/plResBrowser.rc index f63d2146..267a81d9 100644 --- a/Sources/Tools/plResBrowser/res/plResBrowser.rc +++ b/Sources/Tools/plResBrowser/res/plResBrowser.rc @@ -1,25 +1,15 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define WIN32_LEAN_AND_MEAN -#include -#define IDC_STATIC (-1) // all static controls - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - ///////////////////////////////////////////////////////////////////////////// // -// Icon +// Icons // +#define IDI_APPICON 101 +#define IDI_INDEXICON 108 +#define IDI_DATAICON 109 +#define IDI_PATCHICON 110 +#define IDI_MERGEDDATAICON 111 +#define IDI_MERGEDINDEXICON 112 + // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_APPICON ICON "icon1.ico" @@ -28,180 +18,3 @@ IDI_DATAICON ICON "indexico.ico" IDI_PATCHICON ICON "dataicon.ico" IDI_MERGEDDATAICON ICON "mergedda.ico" IDI_MERGEDINDEXICON ICON "mergedin.ico" - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_APPMENU MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "&Open...", ID_FILE_OPEN - MENUITEM "Open &Directory...", ID_FILE_OPENDIRECTORY - MENUITEM SEPARATOR - MENUITEM "Save Selected Object", ID_FILE_SAVESELECTED - MENUITEM SEPARATOR - MENUITEM "Find Object...\tCtrl+F", ID_FILE_FINDOBJECT - MENUITEM "Find Next\tF3", ID_FILE_FINDNEXT - MENUITEM "Show Only Loadable", ID_FILE_ONLYLOAD - MENUITEM SEPARATOR - MENUITEM "About...", ID_FILE_ABOUT - MENUITEM "Exit", ID_FILE_EXIT - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_INFODLG DIALOGEX 0, 0, 186, 281 -STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - GROUPBOX "Object Information",IDC_STATIC,4,168,178,67 - RTEXT "Name:",IDC_STATIC,17,180,22,8 - LTEXT "",IDC_NAME,42,179,129,10,SS_SUNKEN | NOT WS_GROUP - GROUPBOX "Page Information",IDC_STATIC,4,2,178,163 - RTEXT "Age:",IDC_STATIC,45,14,16,8 - LTEXT "",IDC_AGE,63,14,107,10,SS_SUNKEN | NOT WS_GROUP - RTEXT "Page:",IDC_STATIC,41,28,20,8 - LTEXT "",IDC_PAGE,63,28,107,10,SS_SUNKEN | NOT WS_GROUP - RTEXT "Location:",IDC_STATIC,31,43,30,8 - LTEXT "",IDC_LOCATION,64,43,74,10,SS_SUNKEN | NOT WS_GROUP - CONTROL "Reserved",IDC_RESERVED,"Button",BS_AUTOCHECKBOX | - WS_DISABLED | WS_TABSTOP,64,66,10,10 - RTEXT "Class:",IDC_STATIC,19,195,20,8 - LTEXT "",IDC_CLASS,42,194,129,10,SS_SUNKEN | NOT WS_GROUP - RTEXT "Start Pos:",IDC_STARTPOS_LABEL,7,221,32,8 - LTEXT "",IDC_STARTPOS,42,220,55,10,SS_SUNKEN | NOT WS_GROUP - RTEXT "Size:",IDC_SIZE_LABEL,103,221,17,8 - LTEXT "",IDC_LENGTH,124,220,47,10,SS_SUNKEN | NOT WS_GROUP - LTEXT "Reserved",IDC_STATIC,76,67,31,8 - PUSHBUTTON "Find",ID_FILE_FINDOBJECT,4,259,50,14 - PUSHBUTTON "Find Next",ID_FILE_FINDNEXT,58,259,50,14 - RTEXT "Data Version:",IDC_STATIC,17,79,44,8 - LTEXT "",IDC_DATAVERSION,64,79,48,10,SS_SUNKEN | NOT WS_GROUP - RTEXT "Checksum:",IDC_STATIC,25,139,36,8 - LTEXT "",IDC_IDXCHECKSUM,64,139,53,10,SS_SUNKEN | NOT WS_GROUP - PUSHBUTTON "Verify Page",ID_FILE_VERIFYPAGE,130,259,50,14 - RTEXT "Checksum type:",IDC_STATIC,9,151,52,8 - LTEXT "",IDC_CHECKSUMTYPE,64,152,89,10,SS_SUNKEN | NOT - WS_GROUP - CONTROL "View values as hex",IDC_SHOWASHEX,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,105,241,77,10 - CONTROL "",IDC_LOCAL_ONLY,"Button",BS_AUTOCHECKBOX | WS_DISABLED | - WS_TABSTOP,64,57,11,8 - LTEXT "Local Only",IDC_STATIC,76,57,34,8 - CONTROL "",IDC_BUILTIN,"Button",BS_AUTOCHECKBOX | WS_DISABLED | - WS_TABSTOP,116,67,11,8 - CONTROL "",IDC_VOLATILE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | - WS_TABSTOP,116,57,11,8 - LTEXT "Built-In",IDC_STATIC,129,67,22,8 - LTEXT "Volatile",IDC_STATIC,129,57,24,8 -END - -IDD_ABOUT DIALOG 0, 0, 247, 57 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "About plResBrowser" -FONT 8, "MS Sans Serif" -BEGIN - DEFPUSHBUTTON "OK",IDOK,190,7,50,14 - ICON IDI_APPICON,IDC_STATIC,11,8,21,20 - LTEXT "plResBrowser\nA simple Plasma 2.0 packfile browsing utility\nCopyright (C) 2002 Cyan Worlds, Inc.\n\nWho needs log files?", - IDC_STATIC,40,7,140,43 -END - -IDD_FINDOBJ DIALOG 0, 0, 228, 46 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Find Object" -FONT 8, "MS Sans Serif" -BEGIN - EDITTEXT IDC_SEARCHSTRING,13,19,146,14,ES_AUTOHSCROLL - DEFPUSHBUTTON "Find",IDOK,171,7,50,14 - PUSHBUTTON "Cancel",IDCANCEL,171,24,50,14 - GROUPBOX "Object Name",IDC_STATIC,7,7,157,32 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_ABOUT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 240 - TOPMARGIN, 7 - BOTTOMMARGIN, 50 - END - - IDD_FINDOBJ, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 221 - TOPMARGIN, 7 - BOTTOMMARGIN, 39 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - -IDR_ACCELERATOR1 ACCELERATORS -BEGIN - "F", ID_FILE_FINDOBJECT, VIRTKEY, CONTROL, NOINVERT - VK_F3, ID_FILE_FINDNEXT, VIRTKEY, NOINVERT -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Sources/Tools/plResBrowser/res/resource.h b/Sources/Tools/plResBrowser/res/resource.h deleted file mode 100644 index ea16ff89..00000000 --- a/Sources/Tools/plResBrowser/res/resource.h +++ /dev/null @@ -1,68 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by plResBrowser.rc -// -#define IDI_ICON1 101 -#define IDI_APPICON 101 -#define IDR_APPMENU 102 -#define IDD_INFODLG 103 -#define IDD_ABOUT 104 -#define IDR_ACCELERATOR1 106 -#define IDD_FINDOBJ 107 -#define IDI_INDEXICON 108 -#define IDI_DATAICON 109 -#define IDI_PATCHICON 110 -#define IDI_MERGEDDATAICON 111 -#define IDI_MERGEDINDEXICON 112 -#define IDC_NAME 1000 -#define IDC_AGE 1001 -#define IDC_CHAPTER 1002 -#define IDC_PAGE 1003 -#define IDC_LOCATION 1004 -#define IDC_RESERVED 1005 -#define IDC_CLASS 1006 -#define IDC_STARTPOS 1007 -#define IDC_LENGTH 1008 -#define IDC_CANLOAD 1009 -#define IDC_STARTPOS_LABEL 1010 -#define IDC_SIZE_LABEL 1011 -#define IDC_INTERLEAVED 1012 -#define IDC_RELVERSION 1013 -#define IDC_SEARCHSTRING 1014 -#define IDC_DATAVERSION 1014 -#define IDC_IDXCHECKSUM 1015 -#define IDC_DATACHECKSUM 1016 -#define IDC_CHECKSUMTYPE 1017 -#define IDC_SHOWASHEX 1018 -#define IDC_SCROLLBAR 1019 -#define IDC_PARTIALPATCH 1019 -#define IDC_FRAME 1020 -#define IDC_HEADERPATCH 1020 -#define IDC_COPIED 1021 -#define IDC_NEW 1022 -#define IDC_ZOOM 1023 -#define IDC_ZOOMSLIDER 1024 -#define IDC_SEGINFO 1025 -#define IDC_LOCAL_ONLY 1025 -#define IDC_BUILTIN 1026 -#define IDC_VOLATILE 1027 -#define ID_FILE_OPEN 40001 -#define ID_FILE_EXIT 40002 -#define ID_FILE_OPENDIRECTORY 40003 -#define ID_FILE_ABOUT 40004 -#define ID_FILE_FINDOBJECT 40005 -#define ID_FILE_FINDNEXT 40006 -#define ID_FILE_VERIFYPAGE 40007 -#define ID_FILE_ONLYLOAD 40008 -#define ID_FILE_SAVESELECTED 40009 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 110 -#define _APS_NEXT_COMMAND_VALUE 40010 -#define _APS_NEXT_CONTROL_VALUE 1026 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif