mirror of
https://github.com/markdavidlong/AppleSAWS.git
synced 2025-04-16 16:42:23 +00:00
continuing work on new stuff
This commit is contained in:
parent
247977d158
commit
20165005c2
@ -38,13 +38,16 @@ DEFINES += WS_VIDEO
|
||||
SOURCES += \
|
||||
src/intbasic/IntBasicFile.cxx \
|
||||
src/main.cpp \
|
||||
src/diskfiles/dos33/diskfile.cxx \
|
||||
src/diskfiles/dos33/dos33diskimage.cxx \
|
||||
src/diskfiles/dos33/sector.cxx \
|
||||
src/diskfiles/dos33/vtoc.cxx \
|
||||
src/diskfiles/dos33/catalogsector.cxx \
|
||||
src/diskfiles/dos33/tracksectorlist.cxx \
|
||||
src/diskfiles/dos33/filedescriptiveentry.cxx \
|
||||
src/diskfiles/dos33/genericfile.cxx \
|
||||
src/diskfiles/dos33/tspair.cpp \
|
||||
src/diskfiles/dos33/dos33imagemodel.cpp \
|
||||
src/diskfiles/dos33/dos33treeitem.cpp \
|
||||
src/memory/attributedmemory.cpp \
|
||||
src/memory/memorycell.cpp \
|
||||
src/memory/memrole.cpp \
|
||||
@ -102,13 +105,16 @@ SOURCES += \
|
||||
|
||||
|
||||
HEADERS += \
|
||||
src/diskfiles/dos33/diskfile.h \
|
||||
src/diskfiles/dos33/dos33diskimage.h \
|
||||
src/diskfiles/dos33/sector.h \
|
||||
src/diskfiles/dos33/vtoc.h \
|
||||
src/diskfiles/dos33/catalogsector.h \
|
||||
src/diskfiles/dos33/tracksectorlist.h \
|
||||
src/diskfiles/dos33/filedescriptiveentry.h \
|
||||
src/diskfiles/dos33/genericfile.h \
|
||||
src/diskfiles/dos33/tspair.h \
|
||||
src/diskfiles/dos33/dos33imagemodel.h\
|
||||
src/diskfiles/dos33/dos33treeitem.h\
|
||||
src/intbasic/IntBasicFile.h \
|
||||
src/memory/attributedmemory.h \
|
||||
src/memory/memorycell.h \
|
||||
@ -192,4 +198,5 @@ FORMS += \
|
||||
src/ui/widgets/notesdialog.ui
|
||||
|
||||
RESOURCES += \
|
||||
src/resource/resources.qrc
|
||||
src/resource/resources.qrc \
|
||||
src/qdarkstyle/style.qrc
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "binaryfile.h"
|
||||
#include "genericfile.h"
|
||||
#include "diskfile.h"
|
||||
#include "dos33diskimage.h"
|
||||
#include "catalogsector.h"
|
||||
#include "applesoftfile.h"
|
||||
#include "startupdialog.h"
|
||||
|
@ -48,6 +48,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
***
|
||||
|
||||
I have included a nice dark stylesheet based off of Colin Duquesnoy's QDarkStyleSheet
|
||||
from https://github.com/ColinDuquesnoy/QDarkStyleSheet
|
||||
|
||||
Its licensing information can be found at https://github.com/ColinDuquesnoy/QDarkStyleSheet/blob/master/LICENSE.rst
|
||||
|
||||
***
|
||||
|
||||
And, of course, this program is released under the MIT License:
|
||||
|
||||
|
||||
|
@ -10,4 +10,15 @@
|
||||
<qresource prefix="/images">
|
||||
<file>redblob.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/">
|
||||
<file>I_RED.png</file>
|
||||
<file>A_GREY.png</file>
|
||||
<file>A_YELLOW.png</file>
|
||||
<file>B_GREEN.png</file>
|
||||
<file>B_GREY.png</file>
|
||||
<file>R_MAGENTA.png</file>
|
||||
<file>S_ORANGE.png</file>
|
||||
<file>T_CYAN.png</file>
|
||||
<file>disk.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -22,7 +22,7 @@ SequenceOutputView::SequenceOutputView(QWidget *parent) : QPlainTextEdit(parent)
|
||||
void SequenceOutputView::lineNumberAreaPaintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(lineNumberArea);
|
||||
painter.fillRect(event->rect(), Qt::lightGray);
|
||||
|
||||
QTextBlock block = firstVisibleBlock();
|
||||
int blockNumber = block.blockNumber();
|
||||
int top = qRound(blockBoundingGeometry(block).translated(contentOffset()).top());
|
||||
@ -30,9 +30,9 @@ void SequenceOutputView::lineNumberAreaPaintEvent(QPaintEvent *event)
|
||||
while (block.isValid() && top <= event->rect().bottom()) {
|
||||
if (block.isVisible() && bottom >= event->rect().top()) {
|
||||
QString number = QString::number(blockNumber + 1);
|
||||
painter.setPen(Qt::black);
|
||||
painter.drawText(0, top, lineNumberArea->width()-10, fontMetrics().height(),
|
||||
Qt::AlignRight, number);
|
||||
painter.drawText(0, top, lineNumberArea->width()-10,
|
||||
fontMetrics().height(),
|
||||
Qt::AlignRight | Qt::AlignHCenter, number);
|
||||
}
|
||||
|
||||
block = block.next();
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QTextBlock>
|
||||
#include <QRegularExpression>
|
||||
#include <QStyle>
|
||||
|
||||
class SOVNumberPanel;
|
||||
|
||||
@ -38,12 +39,16 @@ class SOVNumberPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SOVNumberPanel(SequenceOutputView *sov) : QWidget(sov), m_sov(sov) { }
|
||||
explicit SOVNumberPanel(SequenceOutputView *sov) : QWidget(sov), m_sov(sov) {
|
||||
setAttribute(Qt::WA_StyledBackground, true);
|
||||
|
||||
}
|
||||
QSize sizeHint() const override { return QSize(m_sov->lineNumberAreaWidth(), 0); }
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override {
|
||||
m_sov->lineNumberAreaPaintEvent(event);}
|
||||
m_sov->lineNumberAreaPaintEvent(event);
|
||||
}
|
||||
SequenceOutputView *m_sov;
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
|
||||
|
||||
protected:
|
||||
SequenceEvent *m_seqevent;
|
||||
QString m_category;
|
||||
|
@ -6,6 +6,14 @@ SequenceViewer::SequenceViewer(QWidget *parent) :
|
||||
ui(new Ui::SequenceViewer)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->vsplitter->setStretchFactor(0,1);
|
||||
ui->vsplitter->setStretchFactor(1,1);
|
||||
ui->vsplitter->setSizes(QList<int>({4000, 4000}));
|
||||
|
||||
ui->hsplitter->setStretchFactor(0,5);
|
||||
ui->hsplitter->setStretchFactor(1,1);
|
||||
ui->hsplitter->setSizes(QList<int>({40000, 10000}));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -27,16 +27,12 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<widget class="QSplitter" name="hsplitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="SequenceOutputView" name="viewer" native="true">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background:black</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<widget class="SequenceOutputView" name="viewer" native="true"/>
|
||||
<widget class="QSplitter" name="vsplitter">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
@ -53,9 +49,6 @@
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background:lightgrey </string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="properties" native="true">
|
||||
<property name="minimumSize">
|
||||
@ -64,9 +57,6 @@
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background:lightgray</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -32,7 +32,7 @@ CatalogWidget::~CatalogWidget()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void CatalogWidget::prepForNewDisk(QString filename, DiskFile *disk)
|
||||
void CatalogWidget::prepForNewDisk(QString filename, Dos33DiskImage *disk)
|
||||
{
|
||||
m_disk = disk;
|
||||
m_diskname = filename;
|
||||
@ -75,7 +75,7 @@ QString CatalogWidget::createToolTip(FileDescriptiveEntry &fde) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
void CatalogWidget::processNewlyLoadedDisk(QString diskfilename, DiskFile *disk)
|
||||
void CatalogWidget::processNewlyLoadedDisk(QString diskfilename, Dos33DiskImage *disk)
|
||||
{
|
||||
// qDebug() << "### Start processNewlyLoadedDisk";
|
||||
if (m_disk == disk) {
|
||||
@ -134,7 +134,7 @@ void CatalogWidget::processNewlyLoadedDisk(QString diskfilename, DiskFile *disk)
|
||||
// qDebug() << "### End processNewlyLoadedDisk";
|
||||
}
|
||||
|
||||
void CatalogWidget::unloadDisk(DiskFile *disk)
|
||||
void CatalogWidget::unloadDisk(Dos33DiskImage *disk)
|
||||
{
|
||||
if (m_disk == disk) {
|
||||
m_disk = 0;
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <QWidget>
|
||||
#include <QListWidgetItem>
|
||||
|
||||
#include "diskfile.h"
|
||||
#include "dos33diskimage.h"
|
||||
|
||||
namespace Ui {
|
||||
class CatalogWidget;
|
||||
@ -20,13 +20,13 @@ public:
|
||||
~CatalogWidget();
|
||||
|
||||
public slots:
|
||||
void prepForNewDisk(QString filename, DiskFile *disk);
|
||||
void processNewlyLoadedDisk(QString filename, DiskFile *disk);
|
||||
void unloadDisk(DiskFile *disk);
|
||||
void prepForNewDisk(QString filename, Dos33DiskImage *disk);
|
||||
void processNewlyLoadedDisk(QString filename, Dos33DiskImage *disk);
|
||||
void unloadDisk(Dos33DiskImage *disk);
|
||||
|
||||
signals:
|
||||
void newFileSelected(DiskFile *disk, FileDescriptiveEntry entry);
|
||||
void openWithDefaultViewer(DiskFile *disk, FileDescriptiveEntry fde);
|
||||
void newFileSelected(Dos33DiskImage *disk, FileDescriptiveEntry entry);
|
||||
void openWithDefaultViewer(Dos33DiskImage *disk, FileDescriptiveEntry fde);
|
||||
|
||||
protected:
|
||||
QString createToolTip(FileDescriptiveEntry &fde);
|
||||
@ -39,7 +39,7 @@ private:
|
||||
|
||||
Ui::CatalogWidget *ui;
|
||||
|
||||
DiskFile *m_disk;
|
||||
Dos33DiskImage *m_disk;
|
||||
QString m_diskname;
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,12 @@
|
||||
#include "centralappwindow.h"
|
||||
#include "sequenceviewer.h"
|
||||
|
||||
#include "dos33diskimage.h"
|
||||
#include "dos33imagemodel.h"
|
||||
|
||||
#include "sequencetoolbox.h"
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QAction>
|
||||
#include <QMenuBar>
|
||||
#include <QMenu>
|
||||
@ -8,9 +14,23 @@
|
||||
#include <QSplitter>
|
||||
#include <QDockWidget>
|
||||
#include <QGridLayout>
|
||||
#include <QStatusBar>
|
||||
|
||||
#include <QFile>
|
||||
|
||||
CentralAppWindow::CentralAppWindow(QWidget *parent) : QMainWindow(parent)
|
||||
{
|
||||
QFile f(":qdarkstyle/style.qss");
|
||||
|
||||
if (!f.exists()) {
|
||||
printf("Unable to set stylesheet, file not found\n");
|
||||
}
|
||||
else {
|
||||
f.open(QFile::ReadOnly | QFile::Text);
|
||||
QTextStream ts(&f);
|
||||
this->setStyleSheet(ts.readAll());
|
||||
}
|
||||
|
||||
createActions();
|
||||
initMenuBar();
|
||||
initToolBars();
|
||||
@ -36,7 +56,8 @@ void CentralAppWindow::initMenuBar()
|
||||
|
||||
void CentralAppWindow::initStatusBar()
|
||||
{
|
||||
|
||||
m_status_bar = new QStatusBar(this);
|
||||
setStatusBar(m_status_bar);
|
||||
}
|
||||
|
||||
void CentralAppWindow::initToolBars()
|
||||
@ -53,22 +74,53 @@ void CentralAppWindow::initToolBars()
|
||||
void CentralAppWindow::initDockWidgets()
|
||||
{
|
||||
QDockWidget *container = new QDockWidget(this);
|
||||
container->setLayout(new QGridLayout());
|
||||
// container->setLayout(new QGridLayout());
|
||||
container->setMinimumWidth(200);
|
||||
container->setFeatures(QDockWidget::DockWidgetMovable);
|
||||
|
||||
m_project_area = new QWidget(container);
|
||||
m_project_area->setMinimumSize(200,200);
|
||||
m_project_area->setStyleSheet("background:black");
|
||||
m_directory_area = new QWidget(container);
|
||||
m_directory_area->setMinimumSize(200,200);
|
||||
m_directory_area->setStyleSheet("background:black");
|
||||
m_project_area->setMinimumSize(300,200);
|
||||
|
||||
m_directory_area = new QTreeView(container);
|
||||
m_directory_area->setFont(QFont("Pr Number 3", 12));
|
||||
m_directory_area->setMinimumSize(300,200);
|
||||
|
||||
QSplitter *split = new QSplitter(container);
|
||||
container->setWidget(split);
|
||||
split->setOrientation(Qt::Vertical);
|
||||
split->addWidget(m_directory_area);
|
||||
split->addWidget(m_project_area);
|
||||
container->setWidget(split);
|
||||
split->setStretchFactor(0,1);
|
||||
split->setStretchFactor(1,1);
|
||||
split->setSizes(QList<int>({4000, 4000}));
|
||||
|
||||
|
||||
Dos33DiskImage *img = new Dos33DiskImage("c:/develop/git/AppleSAWS/disk-images/ApplesoftToolkit.dsk");
|
||||
|
||||
auto model = new Dos33ImageModel();
|
||||
model->addDiskImage(img,"ApplesoftToolkit.dsk");
|
||||
|
||||
img = new Dos33DiskImage("c:/develop/git/AppleSAWS/disk-images/dos.3.3.system.master.dsk");
|
||||
model->addDiskImage(img);
|
||||
|
||||
img = new Dos33DiskImage("c:/develop/git/AppleSAWS/disk-images/Print Shop Companion - Side 1.dsk");
|
||||
model->addDiskImage(img);
|
||||
m_directory_area->setModel(model);
|
||||
|
||||
addDockWidget(Qt::LeftDockWidgetArea,container);
|
||||
|
||||
|
||||
|
||||
QDockWidget *stb = new QDockWidget(this);
|
||||
stb->setMinimumWidth(200);
|
||||
stb->setFeatures(QDockWidget::DockWidgetMovable);
|
||||
stb->setLayout(new QGridLayout());
|
||||
|
||||
m_toolbox = new SequenceToolBox(this);
|
||||
|
||||
|
||||
|
||||
addDockWidget(Qt::RightDockWidgetArea,stb);
|
||||
|
||||
|
||||
}
|
||||
|
@ -4,12 +4,15 @@
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "mainapptoolbar.h"
|
||||
|
||||
class QTreeView;
|
||||
class QAction;
|
||||
class QStatusBar;
|
||||
class SequenceToolBox;
|
||||
|
||||
class CentralAppWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CentralAppWindow(QWidget *parent = nullptr);
|
||||
|
||||
@ -24,9 +27,11 @@ private:
|
||||
QAction *m_quitAction;
|
||||
|
||||
MainAppToolbar *m_mainToolBar;
|
||||
QWidget *m_directory_area;
|
||||
QTreeView *m_directory_area;
|
||||
QWidget *m_project_area;
|
||||
QStatusBar *m_status_bar;
|
||||
|
||||
SequenceToolBox *m_toolbox;
|
||||
};
|
||||
|
||||
#endif // CENTRALAPPWINDOW_H
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
MainAppToolbar::MainAppToolbar(QWidget *parent) : QToolBar(parent)
|
||||
{
|
||||
setStyleSheet("background: #4f4f4f; color: #ffffff; font-size: 12pt");
|
||||
// setStyleSheet("background: #4f4f4f; color: #ffffff; font-size: 12pt");
|
||||
setMovable(false);
|
||||
setFloatable(false);
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ void DiskExplorer::loadDiskFile(QString filename)
|
||||
unloadDiskFile();
|
||||
}
|
||||
|
||||
m_disk = new DiskFile();
|
||||
m_disk = new Dos33DiskImage();
|
||||
m_cw->prepForNewDisk(filename,m_disk);
|
||||
if (m_disk->read(filename)) {
|
||||
if (m_action_Unload_Disk_Image) { m_action_Unload_Disk_Image->setEnabled(true); }
|
||||
@ -195,7 +195,7 @@ void DiskExplorer::showLoadDialog(bool parentToThis)
|
||||
}
|
||||
}
|
||||
|
||||
void DiskExplorer::handleDiskItemSelectedDefaultOpen(DiskFile *disk, FileDescriptiveEntry fde)
|
||||
void DiskExplorer::handleDiskItemSelectedDefaultOpen(Dos33DiskImage *disk, FileDescriptiveEntry fde)
|
||||
{
|
||||
if (fde.deleted) { return; }
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "catalogwidget.h"
|
||||
#include "DiskExplorerMapWidget.h"
|
||||
#include "diskfile.h"
|
||||
#include "dos33diskimage.h"
|
||||
#include "hrcgcontrolsinfo.h"
|
||||
#include "hexconverter.h"
|
||||
#include "hexdumpviewer.h"
|
||||
@ -25,10 +25,10 @@ public:
|
||||
virtual ~DiskExplorer();
|
||||
|
||||
signals:
|
||||
void diskFileLoading(QString filename, DiskFile *file);
|
||||
void diskFileLoaded(QString filename, DiskFile *file);
|
||||
void diskFileLoadFailed(QString filename, DiskFile *file);
|
||||
void diskFileUnloading(DiskFile *file);
|
||||
void diskFileLoading(QString filename, Dos33DiskImage *file);
|
||||
void diskFileLoaded(QString filename, Dos33DiskImage *file);
|
||||
void diskFileLoadFailed(QString filename, Dos33DiskImage *file);
|
||||
void diskFileUnloading(Dos33DiskImage *file);
|
||||
void diskFileUnloaded();
|
||||
|
||||
public slots:
|
||||
@ -38,7 +38,7 @@ public slots:
|
||||
|
||||
private slots:
|
||||
void handleShowSectorData(QByteArray data, int track, int sector, QVariant metadata);
|
||||
void handleDiskItemSelectedDefaultOpen(DiskFile *disk, FileDescriptiveEntry fde);
|
||||
void handleDiskItemSelectedDefaultOpen(Dos33DiskImage *disk, FileDescriptiveEntry fde);
|
||||
|
||||
void setDiskToolsVisible(bool visible);
|
||||
|
||||
@ -64,7 +64,7 @@ private:
|
||||
|
||||
QWidget *m_demwStatusWidget;
|
||||
|
||||
DiskFile *m_disk;
|
||||
Dos33DiskImage *m_disk;
|
||||
|
||||
HRCGControlsInfo *m_hrcgDialog;
|
||||
HexConverter *m_hexConverter;
|
||||
|
@ -146,7 +146,7 @@ void DiskExplorerMapWidget::setButtonBgColor(int track, int sector, QColor color
|
||||
buttonAt(track,sector)->setBgColor(color);
|
||||
}
|
||||
|
||||
void DiskExplorerMapWidget::setDisk(DiskFile *disk)
|
||||
void DiskExplorerMapWidget::setDisk(Dos33DiskImage *disk)
|
||||
{
|
||||
if (disk)
|
||||
{
|
||||
@ -375,7 +375,7 @@ void DiskExplorerMapWidget::mapDiskToButtons()
|
||||
|
||||
valid = tsl.getNextTSList().isValid();
|
||||
|
||||
tsl = m_disk->getSector(tsl.getNextTSList()).promoteToTrackSectorList();
|
||||
tsl = m_disk->getSector(tsl.getNextTSList()).asTrackSectorList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <QLabel>
|
||||
|
||||
|
||||
#include "diskfile.h"
|
||||
#include "dos33diskimage.h"
|
||||
|
||||
|
||||
class DEButton : public QPushButton
|
||||
@ -99,7 +99,7 @@ public:
|
||||
buttonAt(track,sector)->setText(text);
|
||||
}
|
||||
|
||||
void setDisk(DiskFile *disk);
|
||||
void setDisk(Dos33DiskImage *disk);
|
||||
void unloadDisk();
|
||||
|
||||
void setAllButtonsEnabled(bool enabled);
|
||||
@ -157,7 +157,7 @@ private:
|
||||
QColor m_typeSFileColor;
|
||||
|
||||
QButtonGroup *m_bgroup;
|
||||
DiskFile *m_disk;
|
||||
Dos33DiskImage *m_disk;
|
||||
|
||||
bool m_deferredSetup;
|
||||
|
||||
|
@ -124,9 +124,9 @@ QString HexDumpViewer::valToAppleAscii(quint8 val)
|
||||
QString htmlstr = charval.toHtmlEscaped();
|
||||
|
||||
QString retval;
|
||||
if (attribute == Inverse) { retval = QString("<font color=\"blue\"><b>%1</b></font>").arg(htmlstr); }
|
||||
else if (attribute == Flash) { retval = QString("<font color=\"green\"><b><i>%1</i></b></font>").arg(htmlstr);}
|
||||
else if (attribute == NormalLow) { retval = QString("<font color=\"red\"><i>%1</i></font>").arg(htmlstr);}
|
||||
if (attribute == TextAttribute::Inverse) { retval = QString("<font color=\"blue\"><b>%1</b></font>").arg(htmlstr); }
|
||||
else if (attribute == TextAttribute::Flash) { retval = QString("<font color=\"green\"><b><i>%1</i></b></font>").arg(htmlstr);}
|
||||
else if (attribute == TextAttribute::NormalLow) { retval = QString("<font color=\"red\"><i>%1</i></font>").arg(htmlstr);}
|
||||
else { retval = QString("%1").arg(htmlstr);}
|
||||
|
||||
return retval;
|
||||
|
Loading…
x
Reference in New Issue
Block a user