mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 15:39:41 +00:00
Huge rewrite, implementing all the new ideas for the launcher
This commit is contained in:
parent
4189704b5f
commit
d1a75253d7
12 changed files with 163 additions and 185 deletions
|
@ -1,20 +1,21 @@
|
||||||
set(LAUNCHER
|
set(LAUNCHER
|
||||||
datafilesdialog.cpp
|
datafilespage.cpp
|
||||||
lineedit.cpp
|
lineedit.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
maindialog.cpp
|
maindialog.cpp
|
||||||
settingsdialog.cpp
|
playpage.cpp
|
||||||
datafilesdialog.h
|
|
||||||
lineedit.h
|
datafilespage.hpp
|
||||||
maindialog.h
|
lineedit.hpp
|
||||||
settingsdialog.h
|
maindialog.hpp
|
||||||
|
playpage.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(MOC_HDRS
|
SET(MOC_HDRS
|
||||||
datafilesdialog.h
|
datafilespage.hpp
|
||||||
lineedit.h
|
lineedit.hpp
|
||||||
maindialog.h
|
maindialog.hpp
|
||||||
settingsdialog.h
|
playpage.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(apps\\launcher FILES ${ESMTOOL})
|
source_group(apps\\launcher FILES ${ESMTOOL})
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
#include <components/esm/esm_reader.hpp>
|
#include <components/esm/esm_reader.hpp>
|
||||||
|
|
||||||
#include "datafilesdialog.h"
|
#include "datafilesdialog.h"
|
||||||
//#include "pluginitemmodel.h"
|
|
||||||
//#include "datafilesmodel.h"
|
|
||||||
//#include "datafilesitem.h"
|
|
||||||
|
|
||||||
using namespace ESM;
|
using namespace ESM;
|
||||||
|
|
||||||
|
@ -172,11 +169,33 @@ DataFilesDialog::DataFilesDialog()
|
||||||
connect(masterselectmodel, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(masterSelectionChanged(const QItemSelection&, const QItemSelection&)));
|
connect(masterselectmodel, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(masterSelectionChanged(const QItemSelection&, const QItemSelection&)));
|
||||||
connect(plugintable, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)));
|
connect(plugintable, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)));
|
||||||
connect(plugintable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckstate(QModelIndex)));
|
connect(plugintable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckstate(QModelIndex)));
|
||||||
|
connect(pluginsmodel, SIGNAL(rowsAboutToBeMoved(const QModelIndex&, int, int, const QModelIndex&, int)), this, SLOT(test()));
|
||||||
|
|
||||||
// Adjust the dialog width
|
// Adjust the dialog width
|
||||||
setMinimumWidth(500);
|
setMinimumWidth(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DataFilesDialog::test()
|
||||||
|
{
|
||||||
|
qDebug() << "Breaky Breaky!";
|
||||||
|
/*QModelIndexList deselectedindexes = deselected.indexes();
|
||||||
|
|
||||||
|
if (!deselectedindexes.isEmpty()) {
|
||||||
|
foreach (const QModelIndex ¤tindex, deselectedindexes) {
|
||||||
|
qDebug() << "Data is: " << currentindex.data();
|
||||||
|
qDebug() << "Row is: "<< currentindex.row();
|
||||||
|
QList<QStandardItem *> itemlist = pluginsmodel->findItems(QVariant(currentindex.data()).toString());
|
||||||
|
|
||||||
|
if (!itemlist.isEmpty())
|
||||||
|
{
|
||||||
|
foreach (const QStandardItem *currentitem, itemlist) {
|
||||||
|
pluginselectmodel->select(currentitem->index(), QItemSelectionModel::Toggle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
void DataFilesDialog::appendPlugins(const QModelIndex &masterindex)
|
void DataFilesDialog::appendPlugins(const QModelIndex &masterindex)
|
||||||
{
|
{
|
||||||
// Find the plugins in the datafilesmodel and append them to the pluginsmodel
|
// Find the plugins in the datafilesmodel and append them to the pluginsmodel
|
||||||
|
|
|
@ -16,7 +16,6 @@ class QSortFilterProxyModel;
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
|
|
||||||
class PluginItemModel;
|
|
||||||
class QTreeView;
|
class QTreeView;
|
||||||
class QTableView;
|
class QTableView;
|
||||||
class QStandardItemModel;
|
class QStandardItemModel;
|
||||||
|
@ -68,6 +67,7 @@ public slots:
|
||||||
void showContextMenu(const QPoint &point);
|
void showContextMenu(const QPoint &point);
|
||||||
|
|
||||||
void actionCheckstate();
|
void actionCheckstate();
|
||||||
|
void test();
|
||||||
//void setupView();
|
//void setupView();
|
||||||
|
|
||||||
void masterSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
|
void masterSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
|
||||||
|
|
|
@ -8,18 +8,15 @@ DEPENDPATH += .
|
||||||
INCLUDEPATH += .
|
INCLUDEPATH += .
|
||||||
|
|
||||||
# Input
|
# Input
|
||||||
HEADERS += datafilesdialog.h \
|
HEADERS += datafilespage.hpp \
|
||||||
datafilesitem.h \
|
lineedit.hpp \
|
||||||
datafilesmodel.h \
|
maindialog.hpp \
|
||||||
lineedit.h \
|
playpage.hpp
|
||||||
maindialog.h \
|
|
||||||
settingsdialog.h
|
SOURCES += datafilespage.cpp \
|
||||||
SOURCES += datafilesdialog.cpp \
|
|
||||||
datafilesitem.cpp \
|
|
||||||
datafilesmodel.cpp \
|
|
||||||
lineedit.cpp \
|
lineedit.cpp \
|
||||||
main.cpp \
|
|
||||||
maindialog.cpp \
|
maindialog.cpp \
|
||||||
qrc_resources.cxx \
|
playpage.cpp
|
||||||
settingsdialog.cpp
|
qrc_resources.cxx
|
||||||
|
|
||||||
RESOURCES += resources.qrc
|
RESOURCES += resources.qrc
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "lineedit.h"
|
#include "lineedit.hpp"
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (c) 2007 Trolltech ASA <info@trolltech.com>
|
|
||||||
**
|
|
||||||
** Use, modification and distribution is allowed without limitation,
|
|
||||||
** warranty, liability or support of any kind.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef LINEEDIT_H
|
|
||||||
#define LINEEDIT_H
|
|
||||||
|
|
||||||
#include <QLineEdit>
|
|
||||||
|
|
||||||
class QToolButton;
|
|
||||||
|
|
||||||
class LineEdit : public QLineEdit
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
LineEdit(QWidget *parent = 0);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void resizeEvent(QResizeEvent *);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void updateCloseButton(const QString &text);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QToolButton *clearButton;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // LIENEDIT_H
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
#include "maindialog.h"
|
#include "maindialog.hpp"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,121 +1,141 @@
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include "maindialog.h"
|
#include "maindialog.hpp"
|
||||||
#include "datafilesdialog.h"
|
#include "playpage.hpp"
|
||||||
#include "settingsdialog.h"
|
#include "datafilespage.hpp"
|
||||||
|
|
||||||
MainDialog::MainDialog()
|
MainDialog::MainDialog()
|
||||||
{
|
{
|
||||||
|
mIconWidget = new QListWidget;
|
||||||
QLabel *header = new QLabel(this);
|
mIconWidget->setViewMode(QListView::IconMode);
|
||||||
header->setMinimumSize(QSize(400, 150));
|
mIconWidget->setWrapping(false);
|
||||||
header->setPixmap(QPixmap(":resources/openmw_header.png"));
|
|
||||||
|
|
||||||
// Buttons
|
|
||||||
QPushButton *buttonStart = new QPushButton(this);
|
|
||||||
buttonStart->setMinimumSize(QSize(200, 40));
|
|
||||||
buttonStart->setText(tr("Start OpenMW"));
|
|
||||||
|
|
||||||
QPushButton *buttonDataFiles = new QPushButton(this);
|
mIconWidget->setStyleSheet("QListWidget { background-image: url(background.png); background-color: white; background-repeat: no-repeat; background-attachment: scroll; background-position: right; } QListWidgetItem { alignment: center; }");
|
||||||
buttonDataFiles->setMinimumSize(QSize(200, 40));
|
mIconWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // Just to be sure
|
||||||
buttonDataFiles->setText(tr("Data Files"));
|
|
||||||
|
//mIconWidget->setItemDelegate(new ListViewDelegate());
|
||||||
|
mIconWidget->setAttribute(Qt::WA_MacShowFocusRect); // Show a focus frame around the icons on Mac
|
||||||
|
//mIconWidget->setLayoutMode(QListView::SinglePass);
|
||||||
|
mIconWidget->setUniformItemSizes(true);
|
||||||
|
|
||||||
|
mIconWidget->setIconSize(QSize(48, 48));
|
||||||
|
mIconWidget->setMovement(QListView::Static);
|
||||||
|
|
||||||
|
mIconWidget->setMinimumWidth(400);
|
||||||
|
mIconWidget->setFixedHeight(80);
|
||||||
|
mIconWidget->setSpacing(4);
|
||||||
|
mIconWidget->setCurrentRow(0);
|
||||||
|
//QSize itemSize(80, 80);
|
||||||
|
|
||||||
|
//mIconWidget->setGridSize ( itemSize );
|
||||||
|
|
||||||
|
mIconWidget->setFlow(QListView::LeftToRight);
|
||||||
|
|
||||||
QPushButton *buttonSettings = new QPushButton(this);
|
QGroupBox *groupBox = new QGroupBox(this);
|
||||||
buttonSettings->setText(tr("Settings"));
|
QVBoxLayout *groupLayout = new QVBoxLayout(groupBox);
|
||||||
buttonSettings->setIcon(QIcon::fromTheme("preferences-other"));
|
|
||||||
|
// TODO: TESTING
|
||||||
|
|
||||||
|
/*mProfileModel = new QStringListModel();
|
||||||
|
QStringList profileList;
|
||||||
|
profileList << "Default" << "Warrior" << "Redemption" << "Cool stuff bro!";
|
||||||
|
mProfileModel->setStringList(profileList);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Various pages
|
||||||
|
mPlayPage = new PlayPage(this);
|
||||||
|
//mPlayPage->mProfileModel->setStringList(profileList);
|
||||||
|
|
||||||
|
mDataFilesPage = new DataFilesPage(this);
|
||||||
|
//mDataFilesPage->mProfileComboBox->setModel(mProfileModel);
|
||||||
|
|
||||||
|
mPagesWidget = new QStackedWidget(groupBox);
|
||||||
|
mPagesWidget->addWidget(mPlayPage);
|
||||||
|
mPagesWidget->addWidget(new PlayPage);
|
||||||
|
mPagesWidget->addWidget(mDataFilesPage);
|
||||||
|
//mPagesWidget->addWidget(new QueryPage);
|
||||||
|
|
||||||
|
groupLayout->addWidget(mPagesWidget);
|
||||||
|
|
||||||
|
QPushButton *playButton = new QPushButton(tr("Play"));
|
||||||
|
|
||||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
|
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
|
||||||
buttonBox->setStandardButtons(QDialogButtonBox::Close);
|
buttonBox->setStandardButtons(QDialogButtonBox::Close);
|
||||||
buttonBox->addButton(buttonSettings, QDialogButtonBox::ActionRole);
|
buttonBox->addButton(playButton, QDialogButtonBox::ActionRole);
|
||||||
|
|
||||||
|
//QSpacerItem *vSpacer1 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||||
|
|
||||||
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
||||||
QVBoxLayout *buttonsLayout = new QVBoxLayout();
|
dialogLayout->addWidget(mIconWidget);
|
||||||
QHBoxLayout *bodyLayout = new QHBoxLayout();
|
//dialogLayout->addItem(vSpacer1);
|
||||||
QHBoxLayout *dialogButtonsLayout = new QHBoxLayout();
|
dialogLayout->addWidget(groupBox);
|
||||||
|
|
||||||
QSpacerItem *hSpacer1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
dialogLayout->addWidget(buttonBox);
|
||||||
QSpacerItem *hSpacer2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
//mainLayout->addStretch(1);
|
||||||
QSpacerItem *hSpacer3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
//mainLayout->addSpacing(12);
|
||||||
|
|
||||||
QSpacerItem *vSpacer1 = new QSpacerItem(40, 150, QSizePolicy::Minimum, QSizePolicy::Fixed);
|
|
||||||
QSpacerItem *vSpacer2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
||||||
|
|
||||||
buttonsLayout->addItem(vSpacer1);
|
|
||||||
buttonsLayout->addWidget(buttonStart);
|
|
||||||
buttonsLayout->addWidget(buttonDataFiles);
|
|
||||||
buttonsLayout->addItem(vSpacer2);
|
|
||||||
|
|
||||||
bodyLayout->addItem(hSpacer1);
|
|
||||||
bodyLayout->addLayout(buttonsLayout);
|
|
||||||
bodyLayout->addItem(hSpacer2);
|
|
||||||
|
|
||||||
dialogButtonsLayout->addItem(hSpacer3);
|
|
||||||
dialogButtonsLayout->addWidget(buttonBox);
|
|
||||||
|
|
||||||
dialogLayout->addLayout(bodyLayout);
|
|
||||||
dialogLayout->addLayout(dialogButtonsLayout);
|
|
||||||
|
|
||||||
setMinimumSize(QSize(400, 310));
|
|
||||||
setMaximumSize(QSize(400, 310));
|
|
||||||
|
|
||||||
setWindowTitle(tr("OpenMW Launcher"));
|
setWindowTitle(tr("OpenMW Launcher"));
|
||||||
QPixmap pixmap(":resources/openmw_icon.png");
|
setMinimumSize(QSize(550, 450));
|
||||||
setWindowIcon(QIcon(pixmap));
|
|
||||||
|
|
||||||
// Signals and slots
|
createIcons();
|
||||||
connect(buttonStart, SIGNAL(clicked()), this, SLOT(start()));
|
|
||||||
connect(buttonDataFiles, SIGNAL(clicked()), this, SLOT(showDataFiles()));
|
|
||||||
connect(buttonSettings, SIGNAL(clicked()), this, SLOT(showSettings()));
|
|
||||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
|
||||||
|
|
||||||
openmw = new QProcess(NULL);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainDialog::start()
|
void MainDialog::createIcons()
|
||||||
{
|
{
|
||||||
// Start the game!
|
//QSize itemSize(80, 66);
|
||||||
openmw->start("./openmw");
|
|
||||||
connect(openmw, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
|
QListWidgetItem *configButton = new QListWidgetItem(mIconWidget);
|
||||||
|
configButton->setIcon(QIcon(":resources/openmw-icon.png"));
|
||||||
|
configButton->setText(tr("Play"));
|
||||||
|
configButton->setTextAlignment(Qt::AlignCenter);
|
||||||
|
configButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
|
|
||||||
|
//configButton->setSizeHint(itemSize);
|
||||||
|
|
||||||
|
QListWidgetItem *updateButton = new QListWidgetItem(mIconWidget);
|
||||||
|
updateButton->setIcon(QIcon::fromTheme("video-display"));
|
||||||
|
updateButton->setText(tr("Graphics"));
|
||||||
|
updateButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom | Qt::AlignAbsolute);
|
||||||
|
updateButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
|
|
||||||
|
//updateButton->setSizeHint(itemSize);
|
||||||
|
|
||||||
|
QListWidgetItem *queryButton = new QListWidgetItem(mIconWidget);
|
||||||
|
queryButton->setIcon(QIcon(":resources/openmw-plugin-icon.png"));
|
||||||
|
queryButton->setText(tr("Data Files"));
|
||||||
|
queryButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||||
|
queryButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
|
|
||||||
|
//queryButton->setSizeHint(itemSize);
|
||||||
|
|
||||||
|
connect(mIconWidget,
|
||||||
|
SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
|
||||||
|
this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainDialog::finished(int exitCode, QProcess::ExitStatus exitStatus)
|
void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous)
|
||||||
{
|
{
|
||||||
QString debuginfo = openmw->readAllStandardOutput();
|
if (!current)
|
||||||
|
current = previous;
|
||||||
if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
|
|
||||||
// Close the launcher if the game is quitted
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exitCode != 0) {
|
|
||||||
// An error occured whilst starting OpenMW
|
|
||||||
|
|
||||||
// First check if readAllStandardOutput is empty
|
mPagesWidget->setCurrentIndex(mIconWidget->row(current));
|
||||||
// Finished gets signaled twice sometimes
|
|
||||||
|
if (previous) {
|
||||||
|
QString previousPage = previous->data(Qt::DisplayRole).toString();
|
||||||
|
QString currentPage = current->data(Qt::DisplayRole).toString();
|
||||||
|
|
||||||
if (!debuginfo.isEmpty())
|
// The user switched from Data Files to Play
|
||||||
{
|
if (previousPage == QString("Data Files") && currentPage == QString("Play")) {
|
||||||
QMessageBox msgBox;
|
mPlayPage->mProfileModel->setStringList(mDataFilesPage->mProfileModel->stringList());
|
||||||
msgBox.setWindowTitle("Error");
|
mPlayPage->mProfileComboBox->setCurrentIndex(mDataFilesPage->mProfileComboBox->currentIndex());
|
||||||
msgBox.setIcon(QMessageBox::Warning);
|
}
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("\nAn error occured while starting OpenMW."));
|
// The user switched from Play to Data Files
|
||||||
msgBox.setDetailedText(debuginfo);
|
if (previousPage == QString("Play") && currentPage == QString("Data Files")) {
|
||||||
msgBox.exec();
|
mDataFilesPage->mProfileComboBox->setCurrentIndex(mPlayPage->mProfileComboBox->currentIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainDialog::showDataFiles()
|
|
||||||
{
|
|
||||||
DataFilesDialog dialog;
|
|
||||||
dialog.exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainDialog::showSettings()
|
|
||||||
{
|
|
||||||
SettingsDialog dialog;
|
|
||||||
dialog.exec();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
#ifndef MAINDIALOG_H
|
|
||||||
#define MAINDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QProcess>
|
|
||||||
|
|
||||||
class MainDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
MainDialog();
|
|
||||||
|
|
||||||
QProcess *openmw;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
void start();
|
|
||||||
void showDataFiles();
|
|
||||||
void showSettings();
|
|
||||||
void finished(int, QProcess::ExitStatus exitStatus);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,7 +1,8 @@
|
||||||
<!DOCTYPE RCC><RCC version="1.0">
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
<qresource>
|
<qresource>
|
||||||
<file>resources/clear.png</file>
|
<file>resources/clear.png</file>
|
||||||
<file>resources/openmw_header.png</file>
|
<file>resources/openmw-icon.png</file>
|
||||||
<file>resources/openmw_icon.png</file>
|
<file>resources/openmw-plugin-icon.png</file>
|
||||||
|
<file>resources/openmw-header.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 106 KiB |
Binary file not shown.
Before Width: | Height: | Size: 59 KiB |
Loading…
Reference in a new issue