Qt: Refactor out library viewer

This commit is contained in:
Vicki Pfau 2017-01-24 16:04:18 -08:00
parent 369592d892
commit b5c103e187
9 changed files with 230 additions and 59 deletions

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
/* Copyright (c) 2013-2017 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -7,27 +7,19 @@
#include <mgba-util/vfs.h>
#include "ConfigController.h"
using namespace QGBA;
ArchiveInspector::ArchiveInspector(const QString& filename, QWidget* parent)
: QDialog(parent)
, m_model(ConfigController::configDir() + "/library.sqlite3")
{
m_ui.setupUi(this);
connect(&m_model, &LibraryModel::doneLoading, [this]() {
connect(m_ui.archiveView, &LibraryView::doneLoading, [this]() {
m_ui.loading->hide();
});
m_model.loadDirectory(filename);
m_model.constrainBase(filename);
m_ui.archiveListing->setModel(&m_model);
connect(m_ui.archiveView, SIGNAL(accepted()), this, SIGNAL(accepted()));
m_ui.archiveView->setDirectory(filename);
}
VFile* ArchiveInspector::selectedVFile() const {
QModelIndex index = m_ui.archiveListing->selectionModel()->currentIndex();
if (!index.isValid()) {
return nullptr;
}
return m_model.openVFile(index);
return m_ui.archiveView->selectedVFile();
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
/* Copyright (c) 2013-2017 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -6,8 +6,6 @@
#ifndef QGBA_ARCHIVE_INSPECTOR
#define QGBA_ARCHIVE_INSPECTOR
#include "LibraryModel.h"
#include "ui_ArchiveInspector.h"
struct VFile;
@ -24,8 +22,6 @@ public:
private:
Ui::ArchiveInspector m_ui;
LibraryModel m_model;
};
}

View File

@ -6,33 +6,41 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<width>600</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Open in archive...</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Open</set>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QLabel" name="loading">
<property name="text">
<string>Loading...</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Open</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QListView" name="archiveListing"/>
<widget class="QGBA::LibraryView" name="archiveView" native="true"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QGBA::LibraryView</class>
<extends>QWidget</extends>
<header>LibraryView.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
@ -67,21 +75,5 @@
</hint>
</hints>
</connection>
<connection>
<sender>archiveListing</sender>
<signal>doubleClicked(QModelIndex)</signal>
<receiver>ArchiveInspector</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>199</x>
<y>129</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -120,6 +120,7 @@ set(UI_FILES
DebuggerConsole.ui
GIFView.ui
IOViewer.ui
LibraryView.ui
LoadSaveState.ui
LogView.ui
MemoryView.ui
@ -191,7 +192,8 @@ endif()
if(USE_SQLITE3)
list(APPEND SOURCE_FILES
ArchiveInspector.cpp
LibraryModel.cpp)
LibraryModel.cpp
LibraryView.cpp)
endif()
qt5_add_resources(RESOURCES resources.qrc)

View File

@ -5,15 +5,61 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LibraryModel.h"
#include <QFontMetrics>
#include <mgba-util/vfs.h>
using namespace QGBA;
Q_DECLARE_METATYPE(mLibraryEntry);
QMap<QString, LibraryModel::LibraryColumn> LibraryModel::s_columns;
LibraryModel::LibraryModel(const QString& path, QObject* parent)
: QAbstractItemModel(parent)
{
if (s_columns.empty()) {
s_columns["filename"] = {
tr("Filename"),
[](const mLibraryEntry& e) -> QString {
return e.filename;
}
};
s_columns["size"] = {
tr("Size"),
[](const mLibraryEntry& e) -> QString {
double size = e.filesize;
QString unit = "B";
if (size > 1024.0) {
size /= 1024.0;
unit = "kiB";
}
if (size > 1024.0) {
size /= 1024.0;
unit = "MiB";
}
return QString("%0 %1").arg(size, 0, 'f', 1).arg(unit);
}
};
s_columns["platform"] = {
tr("Platform"),
[](const mLibraryEntry& e) -> QString {
int platform = e.platform;
switch (platform) {
#ifdef M_CORE_GBA
case PLATFORM_GBA:
return tr("GBA");
#endif
#ifdef M_CORE_GB
case PLATFORM_GB:
return tr("GB");
#endif
default:
return tr("?");
}
}
};
}
if (!path.isNull()) {
m_library = mLibraryLoad(path.toUtf8().constData());
} else {
@ -21,6 +67,9 @@ LibraryModel::LibraryModel(const QString& path, QObject* parent)
}
memset(&m_constraints, 0, sizeof(m_constraints));
m_constraints.platform = PLATFORM_NONE;
m_columns.append(s_columns["filename"]);
m_columns.append(s_columns["platform"]);
m_columns.append(s_columns["size"]);
if (!m_library) {
return;
@ -75,16 +124,19 @@ QVariant LibraryModel::data(const QModelIndex& index, int role) const {
if (role == Qt::UserRole) {
return QVariant::fromValue(entry);
}
if (role != Qt::DisplayRole) {
if (index.column() >= m_columns.count()) {
return QVariant();
}
switch (index.column()) {
case 0:
return entry.filename;
case 1:
return (unsigned long long) entry.filesize;
switch (role) {
case Qt::DisplayRole:
return m_columns[index.column()].value(entry);
case Qt::SizeHintRole: {
QFontMetrics fm((QFont()));
return fm.size(Qt::TextSingleLine, m_columns[index.column()].value(entry));
}
default:
return QVariant();
}
return QVariant();
}
QVariant LibraryModel::headerData(int section, Qt::Orientation orientation, int role) const {
@ -92,12 +144,10 @@ QVariant LibraryModel::headerData(int section, Qt::Orientation orientation, int
return QAbstractItemModel::headerData(section, orientation, role);
}
if (orientation == Qt::Horizontal) {
switch (section) {
case 0:
return tr("Filename");
case 1:
return tr("Size");
if (section >= m_columns.count()) {
return QVariant();
}
return m_columns[section].name;
}
return section;
}
@ -117,7 +167,7 @@ int LibraryModel::columnCount(const QModelIndex& parent) const {
if (parent.isValid()) {
return 0;
}
return 2;
return m_columns.count();
}
int LibraryModel::rowCount(const QModelIndex& parent) const {

View File

@ -50,11 +50,19 @@ private slots:
void directoryLoaded(const QString& path);
private:
struct LibraryColumn {
QString name;
std::function<QString(const mLibraryEntry&)> value;
};
mLibrary* m_library;
mLibraryEntry m_constraints;
LibraryLoader* m_loader;
QThread m_loaderThread;
QStringList m_queue;
QList<LibraryColumn> m_columns;
static QMap<QString, LibraryColumn> s_columns;
};
class LibraryLoader : public QObject {

View File

@ -0,0 +1,42 @@
/* Copyright (c) 2013-2017 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LibraryView.h"
#include <mgba-util/vfs.h>
#include "ConfigController.h"
using namespace QGBA;
LibraryView::LibraryView(QWidget* parent)
: QWidget(parent)
, m_model(ConfigController::configDir() + "/library.sqlite3")
{
m_ui.setupUi(this);
connect(&m_model, SIGNAL(doneLoading()), this, SIGNAL(doneLoading()));
connect(&m_model, SIGNAL(doneLoading()), this, SLOT(resizeColumns()));
connect(m_ui.listing, SIGNAL(activated(const QModelIndex&)), this, SIGNAL(accepted()));
m_ui.listing->horizontalHeader()->setSectionsMovable(true);
m_ui.listing->setModel(&m_model);
resizeColumns();
}
void LibraryView::setDirectory(const QString& filename) {
m_model.loadDirectory(filename);
m_model.constrainBase(filename);
}
VFile* LibraryView::selectedVFile() const {
QModelIndex index = m_ui.listing->selectionModel()->currentIndex();
if (!index.isValid()) {
return nullptr;
}
return m_model.openVFile(index);
}
void LibraryView::resizeColumns() {
m_ui.listing->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
}

View File

@ -0,0 +1,43 @@
/* Copyright (c) 2013-2017 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef QGBA_LIBRARY_VIEW
#define QGBA_LIBRARY_VIEW
#include "LibraryModel.h"
#include "ui_LibraryView.h"
struct VFile;
namespace QGBA {
class LibraryView : public QWidget {
Q_OBJECT
public:
LibraryView(QWidget* parent = nullptr);
VFile* selectedVFile() const;
signals:
void doneLoading();
void accepted();
public slots:
void setDirectory(const QString&);
private slots:
void resizeColumns();
private:
Ui::LibraryView m_ui;
LibraryModel m_model;
};
}
#endif

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LibraryView</class>
<widget class="QWidget" name="LibraryView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Library</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTableView" name="listing">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>0</number>
</attribute>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>