2022-05-26 23:18:54 +02:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
/*
|
|
|
|
* PolyMC - Minecraft Launcher
|
|
|
|
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
2017-05-22 23:42:47 +02:00
|
|
|
*
|
2022-05-26 23:18:54 +02:00
|
|
|
* 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, version 3.
|
2017-05-22 23:42:47 +02:00
|
|
|
*
|
2022-05-26 23:18:54 +02:00
|
|
|
* 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.
|
2017-05-22 23:42:47 +02:00
|
|
|
*
|
2022-05-26 23:18:54 +02:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2017-05-22 23:42:47 +02:00
|
|
|
*/
|
|
|
|
|
2022-09-30 23:37:00 +02:00
|
|
|
/*
|
|
|
|
* Parts of this code were taken from the Dolphin Emulator project, which
|
|
|
|
* is licensed under the terms of the GNU General Public License version 2
|
|
|
|
* or later.
|
|
|
|
*/
|
2018-07-15 14:51:05 +02:00
|
|
|
|
2022-09-30 23:37:00 +02:00
|
|
|
#include "InstanceView.h"
|
2022-10-01 19:38:40 +02:00
|
|
|
#include "Application.h"
|
2018-07-15 14:51:05 +02:00
|
|
|
|
2022-10-01 22:02:11 +02:00
|
|
|
#include "InstanceDelegate.h"
|
2022-09-30 23:37:00 +02:00
|
|
|
#include "InstanceList.h"
|
2022-10-02 11:12:14 +02:00
|
|
|
#include "ui/instanceview/InstanceGridProxyModel.h"
|
2022-10-02 11:40:30 +02:00
|
|
|
#include "ui/instanceview/InstanceTableProxyModel.h"
|
2013-12-24 11:47:30 +01:00
|
|
|
|
2022-09-30 23:37:00 +02:00
|
|
|
#include <QHeaderView>
|
|
|
|
#include <QSize>
|
2019-07-02 02:09:41 +02:00
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
InstanceView::InstanceView(QWidget* parent, InstanceList* instances) : QStackedWidget(parent), m_instances(instances)
|
|
|
|
{
|
2022-09-30 23:37:00 +02:00
|
|
|
prepareModel();
|
|
|
|
createTable();
|
2022-10-02 11:12:14 +02:00
|
|
|
createGrid();
|
2018-07-15 14:51:05 +02:00
|
|
|
|
2022-09-30 23:37:00 +02:00
|
|
|
addWidget(m_table);
|
2022-10-02 11:12:14 +02:00
|
|
|
addWidget(m_grid);
|
2013-12-24 11:47:30 +01:00
|
|
|
}
|
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
void InstanceView::storeState()
|
|
|
|
{
|
2022-10-01 19:21:05 +02:00
|
|
|
APPLICATION->settings()->set("InstanceViewTableHeaderState", m_table->horizontalHeader()->saveState().toBase64());
|
|
|
|
}
|
|
|
|
|
2022-10-02 11:12:14 +02:00
|
|
|
void InstanceView::switchDisplayMode(InstanceView::DisplayMode mode)
|
|
|
|
{
|
|
|
|
m_displayMode = mode;
|
|
|
|
if (mode == DisplayMode::TableMode) {
|
|
|
|
setCurrentWidget(m_table);
|
|
|
|
} else {
|
|
|
|
setCurrentWidget(m_grid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-03 17:37:54 +02:00
|
|
|
void InstanceView::editSelected(InstanceList::Column targetColumn)
|
2022-10-03 16:01:51 +02:00
|
|
|
{
|
|
|
|
auto current = currentView()->selectionModel()->currentIndex();
|
|
|
|
if (current.isValid()) {
|
2022-10-03 17:37:54 +02:00
|
|
|
currentView()->edit(current.siblingAtColumn(targetColumn));
|
2022-10-03 16:01:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
void InstanceView::prepareModel()
|
|
|
|
{
|
2022-10-02 11:12:14 +02:00
|
|
|
m_tableProxy = new InstanceTableProxyModel(this);
|
|
|
|
m_tableProxy->setSortCaseSensitivity(Qt::CaseInsensitive);
|
|
|
|
m_tableProxy->setSourceModel(m_instances);
|
|
|
|
m_tableProxy->setSortRole(InstanceList::SortRole);
|
|
|
|
connect(m_tableProxy, &QAbstractItemModel::dataChanged, this, &InstanceView::dataChanged);
|
|
|
|
m_gridProxy = new InstanceGridProxyModel(this);
|
|
|
|
m_gridProxy->setSourceModel(m_instances);
|
2022-10-02 15:07:21 +02:00
|
|
|
m_gridProxy->sort(InstanceList::LastPlayedColumn, Qt::DescendingOrder);
|
2022-10-02 11:12:14 +02:00
|
|
|
connect(m_tableProxy, &QAbstractItemModel::dataChanged, this, &InstanceView::dataChanged);
|
2014-02-02 14:27:43 +01:00
|
|
|
}
|
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
void InstanceView::createTable()
|
|
|
|
{
|
2022-09-30 23:37:00 +02:00
|
|
|
m_table = new QTableView(this);
|
2022-10-02 11:12:14 +02:00
|
|
|
m_table->setModel(m_tableProxy);
|
2022-10-02 15:00:45 +02:00
|
|
|
m_table->setItemDelegate(new InstanceDelegate(this, m_iconSize, false));
|
2013-12-24 11:47:30 +01:00
|
|
|
|
2022-09-30 23:37:00 +02:00
|
|
|
m_table->setTabKeyNavigation(false);
|
|
|
|
m_table->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
|
|
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
|
|
m_table->setEditTriggers(QAbstractItemView::EditKeyPressed);
|
|
|
|
m_table->setAlternatingRowColors(true);
|
|
|
|
m_table->setShowGrid(false);
|
|
|
|
m_table->setSortingEnabled(true);
|
|
|
|
m_table->setCurrentIndex(QModelIndex());
|
|
|
|
m_table->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
m_table->setWordWrap(false);
|
|
|
|
m_table->setFrameStyle(QFrame::NoFrame);
|
|
|
|
m_table->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
m_table->setIconSize(QSize(48, 48));
|
2013-12-24 11:47:30 +01:00
|
|
|
|
2022-09-30 23:37:00 +02:00
|
|
|
m_table->verticalHeader()->hide();
|
2022-05-02 21:34:55 +02:00
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
QHeaderView* header = m_table->horizontalHeader();
|
2022-10-01 19:21:05 +02:00
|
|
|
|
2022-09-30 23:37:00 +02:00
|
|
|
header->setSectionsMovable(true);
|
2022-10-01 22:07:38 +02:00
|
|
|
header->setSectionResizeMode(InstanceList::NameColumn, QHeaderView::Stretch);
|
|
|
|
header->setSectionResizeMode(InstanceList::GameVersionColumn, QHeaderView::Interactive);
|
|
|
|
header->setSectionResizeMode(InstanceList::PlayTimeColumn, QHeaderView::Interactive);
|
|
|
|
header->setSectionResizeMode(InstanceList::LastPlayedColumn, QHeaderView::Interactive);
|
2022-10-02 11:12:14 +02:00
|
|
|
m_table->verticalHeader()->setDefaultSectionSize(m_iconSize + 1 + 1); // padding top and bottom
|
2022-05-02 21:34:55 +02:00
|
|
|
|
2022-10-01 23:55:32 +02:00
|
|
|
if (APPLICATION->settings()->get("InstanceViewTableHeaderState").toString().isEmpty()) {
|
2022-10-01 23:44:32 +02:00
|
|
|
m_table->setColumnWidth(InstanceList::GameVersionColumn, 96 + 3 + 3);
|
|
|
|
m_table->setColumnWidth(InstanceList::PlayTimeColumn, 96 + 3 + 3);
|
|
|
|
m_table->setColumnWidth(InstanceList::LastPlayedColumn, 128 + 3 + 3);
|
2022-10-01 23:21:09 +02:00
|
|
|
m_table->sortByColumn(InstanceList::LastPlayedColumn, Qt::DescendingOrder);
|
2022-10-01 23:44:32 +02:00
|
|
|
} else {
|
|
|
|
header->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("InstanceViewTableHeaderState").toByteArray()));
|
|
|
|
}
|
2022-10-01 19:21:05 +02:00
|
|
|
|
2022-10-01 22:55:33 +02:00
|
|
|
connect(m_table, &QAbstractItemView::doubleClicked, this, &InstanceView::activateInstance);
|
2022-09-30 23:37:00 +02:00
|
|
|
connect(m_table->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &InstanceView::currentRowChanged);
|
|
|
|
connect(m_table->selectionModel(), &QItemSelectionModel::currentColumnChanged, this, &InstanceView::selectNameColumn);
|
2022-10-01 19:36:08 +02:00
|
|
|
connect(m_table, &QWidget::customContextMenuRequested, this, &InstanceView::contextMenuRequested);
|
2013-12-24 11:47:30 +01:00
|
|
|
}
|
2013-12-26 21:16:03 +01:00
|
|
|
|
2022-10-02 11:12:14 +02:00
|
|
|
void InstanceView::createGrid()
|
|
|
|
{
|
|
|
|
m_grid = new QListView(this);
|
|
|
|
m_grid->setModel(m_gridProxy);
|
|
|
|
m_grid->setModelColumn(InstanceList::NameColumn);
|
2022-10-02 15:00:45 +02:00
|
|
|
m_grid->setItemDelegate(new InstanceDelegate(this, m_iconSize, true));
|
2022-10-02 11:12:14 +02:00
|
|
|
|
|
|
|
m_grid->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
|
|
m_grid->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
|
|
m_grid->setEditTriggers(QAbstractItemView::EditKeyPressed);
|
|
|
|
m_grid->setCurrentIndex(QModelIndex());
|
|
|
|
m_grid->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
m_grid->setWordWrap(true);
|
|
|
|
m_grid->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
m_grid->setViewMode(QListView::IconMode);
|
|
|
|
m_grid->setMovement(QListView::Static);
|
|
|
|
m_grid->setResizeMode(QListView::Adjust);
|
|
|
|
m_grid->setFrameStyle(QFrame::NoFrame);
|
|
|
|
m_grid->setGridSize(QSize(m_iconSize * 2, m_iconSize * 2));
|
|
|
|
|
|
|
|
connect(m_grid, &QAbstractItemView::doubleClicked, this, &InstanceView::activateInstance);
|
|
|
|
connect(m_grid->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &InstanceView::currentRowChanged);
|
|
|
|
connect(m_grid, &QWidget::customContextMenuRequested, this, &InstanceView::contextMenuRequested);
|
|
|
|
}
|
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
InstancePtr InstanceView::currentInstance()
|
|
|
|
{
|
2022-10-02 11:12:14 +02:00
|
|
|
auto current = currentView()->selectionModel()->currentIndex();
|
2022-10-01 18:13:52 +02:00
|
|
|
if (current.isValid()) {
|
|
|
|
int row = mappedIndex(current).row();
|
|
|
|
return m_instances->at(row);
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
void InstanceView::activateInstance(const QModelIndex& index)
|
|
|
|
{
|
2022-10-01 18:13:52 +02:00
|
|
|
if (index.isValid()) {
|
|
|
|
int row = mappedIndex(index).row();
|
|
|
|
emit instanceActivated(m_instances->at(row));
|
|
|
|
}
|
2013-12-26 21:16:03 +01:00
|
|
|
}
|
2014-01-31 22:51:45 +01:00
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
void InstanceView::currentRowChanged(const QModelIndex& current, const QModelIndex& previous)
|
|
|
|
{
|
2022-10-01 18:13:52 +02:00
|
|
|
InstancePtr inst1, inst2;
|
|
|
|
if (current.isValid()) {
|
|
|
|
int row = mappedIndex(current).row();
|
|
|
|
inst1 = m_instances->at(row);
|
|
|
|
}
|
|
|
|
if (previous.isValid()) {
|
|
|
|
int row = mappedIndex(previous).row();
|
|
|
|
inst2 = m_instances->at(row);
|
2018-07-15 14:51:05 +02:00
|
|
|
}
|
2022-10-01 18:13:52 +02:00
|
|
|
emit currentInstanceChanged(inst1, inst2);
|
2014-02-02 14:27:43 +01:00
|
|
|
}
|
2014-07-12 21:13:23 +02:00
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
void InstanceView::selectNameColumn(const QModelIndex& current, const QModelIndex& previous)
|
|
|
|
{
|
2022-09-30 23:37:00 +02:00
|
|
|
// Make sure Name column is always selected
|
2022-10-03 17:37:54 +02:00
|
|
|
if (current.column() != InstanceList::NameColumn && current.column() != InstanceList::CategoryColumn)
|
|
|
|
currentView()->setCurrentIndex(current.siblingAtColumn(InstanceList::NameColumn));
|
2014-07-12 21:13:23 +02:00
|
|
|
}
|
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
void InstanceView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
|
|
|
{
|
2022-09-30 23:37:00 +02:00
|
|
|
// Notify others if data of the current instance changed
|
2022-10-02 11:12:14 +02:00
|
|
|
auto current = currentView()->selectionModel()->currentIndex();
|
2014-07-12 21:13:23 +02:00
|
|
|
|
2022-09-30 23:37:00 +02:00
|
|
|
QItemSelection foo(topLeft, bottomRight);
|
|
|
|
if (foo.contains(current)) {
|
2022-10-01 18:13:52 +02:00
|
|
|
int row = mappedIndex(current).row();
|
2022-09-30 23:37:00 +02:00
|
|
|
InstancePtr inst = m_instances->at(row);
|
|
|
|
emit currentInstanceChanged(inst, inst);
|
2018-07-15 14:51:05 +02:00
|
|
|
}
|
2014-07-12 21:13:23 +02:00
|
|
|
}
|
2022-10-01 18:13:52 +02:00
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
void InstanceView::contextMenuRequested(const QPoint pos)
|
|
|
|
{
|
2022-10-02 11:12:14 +02:00
|
|
|
QModelIndex index = currentView()->indexAt(pos);
|
2022-10-01 19:36:08 +02:00
|
|
|
|
|
|
|
if (index.isValid()) {
|
|
|
|
int row = mappedIndex(index).row();
|
|
|
|
InstancePtr inst = m_instances->at(row);
|
2022-10-02 11:12:14 +02:00
|
|
|
emit showContextMenu(currentView()->mapToParent(pos), inst);
|
2022-10-01 19:36:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-01 19:38:40 +02:00
|
|
|
QModelIndex InstanceView::mappedIndex(const QModelIndex& index) const
|
|
|
|
{
|
2022-10-02 11:12:14 +02:00
|
|
|
if (m_displayMode == DisplayMode::GridMode) {
|
|
|
|
return m_gridProxy->mapToSource(index);
|
|
|
|
}
|
|
|
|
return m_tableProxy->mapToSource(index);
|
2022-10-01 18:13:52 +02:00
|
|
|
}
|
2022-10-01 20:11:07 +02:00
|
|
|
|
2022-10-03 23:07:00 +02:00
|
|
|
void InstanceView::setFilterQuery(const QString& query)
|
|
|
|
{
|
2022-10-04 17:43:31 +02:00
|
|
|
m_gridProxy->setFilterQuery(query);
|
|
|
|
m_tableProxy->setFilterQuery(query);
|
2022-10-03 23:07:00 +02:00
|
|
|
}
|
|
|
|
|
2022-10-01 20:11:07 +02:00
|
|
|
void InstanceView::setCatDisplayed(bool enabled)
|
|
|
|
{
|
|
|
|
if (enabled) {
|
|
|
|
QDateTime now = QDateTime::currentDateTime();
|
2022-10-02 11:40:30 +02:00
|
|
|
QDateTime birthday(QDate(now.date().year(), 12, 28), QTime(0, 0));
|
2022-10-01 20:11:07 +02:00
|
|
|
QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
|
|
|
|
QString cat;
|
|
|
|
if (std::abs(now.daysTo(xmas)) <= 4) {
|
|
|
|
cat = "catmas";
|
|
|
|
} else if (std::abs(now.daysTo(birthday)) <= 12) {
|
|
|
|
cat = "cattiversary";
|
|
|
|
} else {
|
|
|
|
cat = "kitteh";
|
|
|
|
}
|
|
|
|
setStyleSheet(QString(R"(
|
2022-10-02 11:40:30 +02:00
|
|
|
* {
|
2022-10-01 20:11:07 +02:00
|
|
|
background-image: url(:/backgrounds/%1);
|
|
|
|
background-attachment: fixed;
|
|
|
|
background-clip: padding;
|
|
|
|
background-position: bottom right;
|
|
|
|
background-repeat: none;
|
2022-10-02 11:40:30 +02:00
|
|
|
background-color: palette(base);
|
2022-10-01 20:11:07 +02:00
|
|
|
})")
|
|
|
|
.arg(cat));
|
|
|
|
m_table->setAlternatingRowColors(false);
|
|
|
|
} else {
|
|
|
|
setStyleSheet(QString());
|
|
|
|
m_table->setAlternatingRowColors(true);
|
|
|
|
}
|
2022-10-02 12:43:04 +02:00
|
|
|
}
|