all repos — mgba @ 0a898f66b4c3cf63e32bc90d73dae33fee41a29a

mGBA Game Boy Advance Emulator

src/platform/qt/library/LibraryTree.cpp (view raw)

  1/* Copyright (c) 2014-2017 waddlesplash
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "LibraryTree.h"
  7
  8#include "utils.h"
  9
 10#include <QApplication>
 11#include <QDir>
 12
 13namespace QGBA {
 14
 15class TreeWidgetItem : public QTreeWidgetItem {
 16public:
 17	TreeWidgetItem(QTreeWidget* parent = nullptr) : QTreeWidgetItem(parent) {}
 18	void setFilesize(size_t size);
 19
 20	virtual bool operator<(const QTreeWidgetItem& other) const override;
 21protected:
 22	size_t m_size = 0;
 23};
 24
 25void TreeWidgetItem::setFilesize(size_t size) {
 26	m_size = size;
 27	setText(LibraryTree::COL_SIZE, niceSizeFormat(size));
 28}
 29
 30bool TreeWidgetItem::operator<(const QTreeWidgetItem& other) const {
 31	const int column = treeWidget()->sortColumn();
 32	return ((column == LibraryTree::COL_SIZE) ?
 33		m_size < dynamic_cast<const TreeWidgetItem*>(&other)->m_size :
 34		QTreeWidgetItem::operator<(other));
 35}
 36
 37LibraryTree::LibraryTree(LibraryController* parent)
 38	: m_widget(new QTreeWidget(parent))
 39	, m_controller(parent)
 40{
 41	m_widget->setObjectName("LibraryTree");
 42	m_widget->setSortingEnabled(true);
 43	m_widget->setAlternatingRowColors(true);
 44
 45	QTreeWidgetItem* header = new QTreeWidgetItem({
 46		QApplication::translate("LibraryTree", "Name", nullptr),
 47		QApplication::translate("LibraryTree", "Location", nullptr),
 48		QApplication::translate("LibraryTree", "Platform", nullptr),
 49		QApplication::translate("LibraryTree", "Size", nullptr),
 50		QApplication::translate("LibraryTree", "CRC32", nullptr),
 51	});
 52	header->setTextAlignment(3, Qt::AlignTrailing | Qt::AlignVCenter);
 53	m_widget->setHeaderItem(header);
 54
 55	setViewStyle(LibraryStyle::STYLE_TREE);
 56	m_widget->sortByColumn(COL_NAME, Qt::AscendingOrder);
 57
 58	QObject::connect(m_widget, &QTreeWidget::itemActivated, [this](QTreeWidgetItem* item, int) -> void {
 59		if (!m_pathNodes.values().contains(item)) {
 60			emit m_controller->startGame();
 61		}
 62	});
 63}
 64
 65void LibraryTree::resizeAllCols() {
 66	for (int i = 0; i < m_widget->columnCount(); i++) {
 67		m_widget->resizeColumnToContents(i);
 68	}
 69}
 70
 71LibraryEntryRef LibraryTree::selectedEntry() {
 72	if (!m_widget->selectedItems().empty()) {
 73		return m_items.key(m_widget->selectedItems().at(0));
 74	} else {
 75		return LibraryEntryRef();
 76	}
 77}
 78
 79void LibraryTree::selectEntry(LibraryEntryRef game) {
 80	if (!game) {
 81		return;
 82	}
 83	if (!m_widget->selectedItems().empty()) {
 84		m_widget->selectedItems().at(0)->setSelected(false);
 85	}
 86	m_items.value(game)->setSelected(true);
 87}
 88
 89void LibraryTree::setViewStyle(LibraryStyle newStyle) {
 90	if (newStyle == LibraryStyle::STYLE_LIST) {
 91		m_currentStyle = LibraryStyle::STYLE_LIST;
 92		m_widget->setIndentation(0);
 93		rebuildTree();
 94	} else {
 95		m_currentStyle = LibraryStyle::STYLE_TREE;
 96		m_widget->setIndentation(20);
 97		rebuildTree();
 98	}
 99}
100
101void LibraryTree::addEntries(QList<LibraryEntryRef> items) {
102	m_deferredTreeRebuild = true;
103	AbstractGameList::addEntries(items);
104	m_deferredTreeRebuild = false;
105	rebuildTree();
106}
107
108void LibraryTree::addEntry(LibraryEntryRef item) {
109	if (m_items.contains(item)) {
110		return;
111	}
112
113	QString folder = item->base();
114	if (!m_pathNodes.contains(folder)) {
115		QTreeWidgetItem* i = new TreeWidgetItem;
116		i->setText(0, folder.section("/", -1));
117		m_pathNodes.insert(folder, i);
118		if (m_currentStyle == LibraryStyle::STYLE_TREE) {
119			m_widget->addTopLevelItem(i);
120		}
121	}
122
123	TreeWidgetItem* i = new TreeWidgetItem;
124	i->setText(COL_NAME, item->displayTitle());
125	i->setText(COL_LOCATION, QDir::toNativeSeparators(item->base()));
126	i->setText(COL_PLATFORM, nicePlatformFormat(item->platform()));
127	i->setFilesize(item->filesize());
128	i->setTextAlignment(COL_SIZE, Qt::AlignRight);
129	i->setText(COL_CRC32, QString("%0").arg(item->crc32(), 8, 16, QChar('0')));
130	m_items.insert(item, i);
131
132	rebuildTree();
133}
134
135void LibraryTree::removeEntry(LibraryEntryRef item) {
136	if (!m_items.contains(item)) {
137		return;
138	}
139	delete m_items.take(item);
140}
141
142void LibraryTree::rebuildTree() {
143	if (m_deferredTreeRebuild) {
144		return;
145	}
146
147	LibraryEntryRef currentGame = selectedEntry();
148
149	int count = m_widget->topLevelItemCount();
150	for (int a = 0; a < count; a++) {
151		m_widget->takeTopLevelItem(0);
152	}
153
154	for (QTreeWidgetItem* i : m_pathNodes.values()) {
155		count = i->childCount();
156		for (int a = 0; a < count; a++) {
157			i->takeChild(0);
158		}
159	}
160
161	if (m_currentStyle == LibraryStyle::STYLE_TREE) {
162		for (QTreeWidgetItem* i : m_pathNodes.values()) {
163			m_widget->addTopLevelItem(i);
164		}
165		for (QTreeWidgetItem* i : m_items.values()) {
166			m_pathNodes.value(m_items.key(i)->base())->addChild(i);
167		}
168	} else {
169		for (QTreeWidgetItem* i : m_items.values()) {
170			m_widget->addTopLevelItem(i);
171		}
172	}
173
174	m_widget->expandAll();
175	resizeAllCols();
176	selectEntry(currentGame);
177}
178
179}