Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Archive preview support #2056

Merged
merged 5 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ jobs:
qt-modules: qtpositioning qtwebchannel qtwebengine qtwebsockets
mo2-third-parties:
7z zlib gtest libbsarch libloot openssl bzip2 python lz4 spdlog
boost boost-di sip pyqt pybind11 ss licenses explorerpp
boost boost-di sip pyqt pybind11 ss licenses explorerpp DirectXTex
mo2-dependencies: usvfs cmake_common uibase githubpp bsatk esptk archive lootcli game_gamebryo
3 changes: 2 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ mo2_configure_executable(organizer
EXTRA_TRANSLATIONS ${MO2_SUPER_PATH}/game_gamebryo/src ${MO2_UIBASE_PATH}/src
PRIVATE_DEPENDS
uibase githubpp bsatk esptk archive usvfs lootcli boost::program_options
Qt::WebEngineWidgets Qt::WebSockets)
DirectXTex libbsarch Qt::WebEngineWidgets Qt::WebSockets)
target_link_libraries(organizer PUBLIC Shlwapi)
target_include_directories(organizer PUBLIC ${DDS_ROOT})
mo2_install_target(organizer)

install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/dlls.manifest.qt6"
Expand Down
8 changes: 2 additions & 6 deletions src/filetree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,16 +246,12 @@ void FileTree::activate(FileTreeItem* item)
return;
}

if (item->isFromArchive()) {
log::warn("cannot activate file from archive '{}'", item->filename());
return;
}

const auto tryPreview = m_core.settings().interface().doubleClicksOpenPreviews();

if (tryPreview) {
const QFileInfo fi(item->realPath());
if (m_plugins.previewGenerator().previewSupported(fi.suffix().toLower())) {
if (m_plugins.previewGenerator().previewSupported(fi.suffix().toLower(),
item->isFromArchive())) {
preview(item);
return;
}
Expand Down
6 changes: 1 addition & 5 deletions src/modinfodialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,8 @@ const int max_scan_for_context_menu = 50;
bool canPreviewFile(const PluginContainer& pluginContainer, bool isArchive,
const QString& filename)
{
if (isArchive) {
return false;
}

const auto ext = QFileInfo(filename).suffix().toLower();
return pluginContainer.previewGenerator().previewSupported(ext);
return pluginContainer.previewGenerator().previewSupported(ext, isArchive);
}

bool isExecutableFilename(const QString& filename)
Expand Down
2 changes: 1 addition & 1 deletion src/modinfodialogimages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ void ImagesTab::select(std::size_t i, Visibility v)
ui->imagesPath->setText(QDir::toNativeSeparators(f->path()));
ui->imagesExplore->setEnabled(true);
if (plugin().previewGenerator().previewSupported(
QFileInfo(f->path()).suffix().toLower()))
QFileInfo(f->path()).suffix().toLower(), false))
ui->previewPluginButton->setEnabled(true);
else
ui->previewPluginButton->setEnabled(false);
Expand Down
27 changes: 24 additions & 3 deletions src/organizercore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
#include <tuple>
#include <utility>

#include "bs_archive.h"

#include "organizerproxy.h"

using namespace MOShared;
Expand Down Expand Up @@ -1053,7 +1055,7 @@ bool OrganizerCore::previewFileWithAlternatives(QWidget* parent, QString fileNam
// set up preview dialog
PreviewDialog preview(fileName, parent);

auto addFunc = [&](int originId) {
auto addFunc = [&](int originId, std::wstring archiveName = L"") {
FilesOrigin& origin = directoryStructure()->getOriginByID(originId);
QString filePath =
QDir::fromNativeSeparators(ToQString(origin.getPath())) + "/" + fileName;
Expand All @@ -1066,14 +1068,33 @@ bool OrganizerCore::previewFileWithAlternatives(QWidget* parent, QString fileNam
} else {
preview.addVariant(ToQString(origin.getName()), wid);
}
} else if (archiveName != L"") {
auto archiveFile = directoryStructure()->searchFile(archiveName);
if (archiveFile.get() != nullptr) {
try {
libbsarch::bs_archive archiveLoader;
archiveLoader.load_from_disk(archiveFile->getFullPath());
libbsarch::memory_blob fileData =
archiveLoader.extract_to_memory(fileName.toStdWString());
QByteArray convertedFileData((char*)(fileData.data), fileData.size);
QWidget* wid = m_PluginContainer->previewGenerator().genArchivePreview(
convertedFileData, filePath);
if (wid == nullptr) {
reportError(tr("failed to generate preview for %1").arg(filePath));
} else {
preview.addVariant(ToQString(origin.getName()), wid);
}
} catch (std::exception& e) {
}
}
}
};

if (selectedOrigin == -1) {
// don't bother with the vector of origins, just add them as they come
addFunc(file->getOrigin());
addFunc(file->getOrigin(), file->isFromArchive() ? file->getArchive().name() : L"");
for (const auto& alt : file->getAlternatives()) {
addFunc(alt.originID());
addFunc(alt.originID(), alt.isFromArchive() ? alt.archive().name() : L"");
}
} else {
std::vector<int> origins;
Expand Down
22 changes: 20 additions & 2 deletions src/previewgenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,16 @@ PreviewGenerator::PreviewGenerator(const PluginContainer& pluginContainer)
m_MaxSize = QGuiApplication::primaryScreen()->size() * 0.8;
}

bool PreviewGenerator::previewSupported(const QString& fileExtension) const
bool PreviewGenerator::previewSupported(const QString& fileExtension,
const bool& isArchive) const
{
auto& previews = m_PluginContainer.plugins<IPluginPreview>();
for (auto* preview : previews) {
if (preview->supportedExtensions().contains(fileExtension)) {
return true;
if (!isArchive)
return true;
if (preview->supportsArchives())
return true;
}
}
return false;
Expand All @@ -58,3 +62,17 @@ QWidget* PreviewGenerator::genPreview(const QString& fileName) const
}
return nullptr;
}

QWidget* PreviewGenerator::genArchivePreview(const QByteArray& fileData,
const QString& fileName) const
{
const QString ext = QFileInfo(fileName).suffix().toLower();
auto& previews = m_PluginContainer.plugins<IPluginPreview>();
for (auto* preview : previews) {
if (m_PluginContainer.isEnabled(preview) &&
preview->supportedExtensions().contains(ext) && preview->supportsArchives()) {
return preview->genDataPreview(fileData, fileName, m_MaxSize);
}
}
return nullptr;
}
4 changes: 3 additions & 1 deletion src/previewgenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ class PreviewGenerator
public:
PreviewGenerator(const PluginContainer& pluginContainer);

bool previewSupported(const QString& fileExtension) const;
bool previewSupported(const QString& fileExtension, const bool& isArchive) const;

QWidget* genPreview(const QString& fileName) const;

QWidget* genArchivePreview(const QByteArray& fileData, const QString& fileName) const;

private:
const PluginContainer& m_PluginContainer;
QSize m_MaxSize;
Expand Down
Loading