AppleSAWS/src/ui/diskexplorer/diskexplorer.cpp

337 lines
11 KiB
C++

/*****************************************************************************
* AppleSAWS - The Apple Software Analysis WorkShop *
* Copyright (C) 2015-2021 Mark D. Long *
* *
* 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, either version 3 of the License, or *
* (at your option) any later version. *
* *
* 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. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
*****************************************************************************/
#include "diskexplorer.h"
#include <QGridLayout>
#include <QMenuBar>
#include <QAction>
#include <QSettings>
#include <QFileDialog>
#include <QShowEvent>
#include <QDebug>
#include <QStatusBar>
#include "genericfile.h"
#include "viewerbase.h"
DiskExplorer::DiskExplorer(QWidget *parent) : QMainWindow(parent)
{
m_action_Unload_Disk_Image = nullptr;
m_hexConverter = nullptr;
m_disk = nullptr;
m_horizSizePref = -1;
m_toolsHidden = true;
// m_notesDialog = nullptr;
m_AsciiInfoDialog = nullptr;
m_hrcgDialog = nullptr;
m_action_Unload_Disk_Image = nullptr;
resize(300,800);
initUi();
}
DiskExplorer::~DiskExplorer()
{
}
void DiskExplorer::initUi()
{
QMenuBar *menuBar = new QMenuBar(this);
setMenuBar(menuBar);
QMenu *menu = new QMenu(tr("&File"),this);
menuBar->addMenu(menu);
// QAction *action_Load_Disk_Image = new QAction(tr("&Load Disk Image..."),this);
// menu->addAction(action_Load_Disk_Image);
// connect(action_Load_Disk_Image, &QAction::triggered,
// this, &DiskExplorer::showLoadDialog);
// m_action_Unload_Disk_Image = new QAction(tr("&Unload Disk Image"),this);
// m_action_Unload_Disk_Image->setEnabled(false);
// menu->addAction(m_action_Unload_Disk_Image);
// connect(m_action_Unload_Disk_Image, &QAction::triggered,
// this, &DiskExplorer::unloadDiskFile);
// menu->addSeparator();
QAction *action_Quit = new QAction(tr("&Quit"),this);
menu->addAction(action_Quit);
connect(action_Quit, &QAction::triggered, qApp, &QApplication::quit);
menu = new QMenu(tr("&Util"),this);
menuBar->addMenu(menu);
QAction *action_Hex_Converter = new QAction(tr("&Hex Converter..."),this);
menu->addAction(action_Hex_Converter);
menu->addSeparator();
m_setDiskToolsVisibleAction = new QAction(tr("Show &Disk tools"),this);
m_setDiskToolsVisibleAction->setCheckable(true);
m_setDiskToolsVisibleAction->setChecked(false);
connect(m_setDiskToolsVisibleAction, &QAction::triggered, this, &DiskExplorer::setDiskToolsVisible);
menu->addAction(m_setDiskToolsVisibleAction);
menu = new QMenu(tr("&Misc"),this);
menuBar->addMenu(menu);
QAction *action_HRCG_Commands = new QAction(tr("&HRCG Commands..."),this);
menu->addAction(action_HRCG_Commands);
if (!m_hrcgDialog) m_hrcgDialog = new HRCGControlsInfo(this);
connect(action_HRCG_Commands, &QAction::triggered, m_hrcgDialog, &HRCGControlsInfo::show);
if (!m_hexConverter) m_hexConverter = new HexConverter(this);
connect(action_Hex_Converter, &QAction::triggered, m_hexConverter, &HexConverter::show);
QAction *action_Ascii_Info = new QAction(tr("&ASCII Table..."),this);
menu->addAction(action_Ascii_Info);
m_AsciiInfoDialog = new AsciiInfoDialog(this);
connect(action_Ascii_Info, &QAction::triggered, m_AsciiInfoDialog, &AsciiInfoDialog::show);
// menu->addSeparator();
// QAction *action_Notes = new QAction(tr("&Notes..."), this);
// menu->addAction(action_Notes);
// if (!m_notesDialog) m_notesDialog = new NotesDialog(this);
// connect(action_Notes, &QAction::triggered, m_notesDialog, &NotesDialog::show);
QWidget *widget = new QWidget(nullptr);
m_gridLayout = new QGridLayout();
m_gridLayout->setVerticalSpacing(4);
m_gridLayout->setHorizontalSpacing(4);
widget->setLayout(m_gridLayout);
m_cw = new CatalogWidget(widget);
m_demw = new DiskExplorerMapWidget(35,16,widget);
m_frame = new QFrame(widget);
m_frame->setFrameStyle(QFrame::Raised);
m_frame->setMinimumSize(200,200);
QGridLayout *frameLayout = new QGridLayout(0);
m_frame->setLayout(frameLayout);
// m_hdv = new HexDumpViewer(this, 10);
// frameLayout->addWidget(m_hdv);
m_vws = m_demw->generateViewWidgetStack(); // new ViewWidgetStack(this);
frameLayout->addWidget(m_vws);
m_gridLayout->setColumnStretch(0,4);
m_gridLayout->setColumnStretch(1,1);
m_gridLayout->setColumnStretch(2,4);
m_gridLayout->addWidget(m_cw,0,0,2,1);
m_gridLayout->addWidget(m_demw,0,1,1,2);
m_key = m_demw->makeKeyWidget();
m_gridLayout->addWidget(m_key,1,1);
m_gridLayout->addWidget(m_frame,1,2);
this->setCentralWidget(widget);
// auto lo = new QGridLayout();
// this->setLayout(lo);
// lo->addWidget(widget);
connect(m_cw, &CatalogWidget::openWithDefaultViewer,
this, &DiskExplorer::handleDiskItemSelectedDefaultOpen);
// connect(m_demw, &DiskExplorerMapWidget::showSectorData,
// this, &DiskExplorer::handleShowSectorData);
QStatusBar *statusBar = new QStatusBar(this);
setStatusBar(statusBar);
m_demwStatusWidget = m_demw->getStatusWidget();
statusBar->addPermanentWidget(m_demwStatusWidget);
setDiskToolsVisible(false);
}
void DiskExplorer::unloadDiskFile()
{
if (m_disk)
{
m_cw->unloadDisk(m_disk);
m_demw->unloadDisk();
//m_hdv->setRawData(QByteArray(),0);
m_vws->setSector(nullptr);
}
}
void DiskExplorer::loadDiskFile(QString filename)
{
if (m_disk) {
unloadDiskFile();
}
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); }
QSettings settings;
settings.setValue("lastOpened",filename);
m_cw->processNewlyLoadedDisk(filename,m_disk);
m_demw->setDisk(m_disk);
} else {
emit diskFileLoadFailed(filename,m_disk);
delete m_disk;
m_disk = 0;
}
}
void DiskExplorer::handleShowSectorData(QByteArray /*data*/, int track, int sector, QVariant metadata)
{
return;
ViewWidgetStack::PreferredViewer viewer =
ViewWidgetStack::PreferredViewer::DontCare;
bool USE_SPECIFIC_VIEWER = true; // Hook for later allowing the disuse of
if (USE_SPECIFIC_VIEWER) // default viewer switching
{
if (metadata == (int) DiskSectorRole::VTOC)
{
viewer = ViewWidgetStack::PreferredViewer::VTOC;
}
else if (metadata == (int) DiskSectorRole::CatalogSector)
{
viewer = ViewWidgetStack::PreferredViewer::CatalogSector;
}
else if (metadata == (int) DiskSectorRole::TSList)
{
viewer = ViewWidgetStack::PreferredViewer::TSList;
}
else
{
viewer = ViewWidgetStack::PreferredViewer::HexDump;
}
}
auto sec = m_disk->getSector(track,sector);
m_vws->setSector(sec, viewer);
}
void DiskExplorer::showLoadDialog(bool parentToThis)
{
QSettings settings;
QString last = settings.value("lastOpened",".").toString();
QString filename = QFileDialog::getOpenFileName(parentToThis?this:nullptr,
tr("Open Disk Image"),
last,
"Disk Images (*.do *.dsk)");
if (!filename.isEmpty()) {
if (!parentToThis) { this->show(); }
loadDiskFile(filename);
}
}
void DiskExplorer::handleDiskItemSelectedDefaultOpen(Dos33DiskImage *disk, FileDescriptiveEntry fde)
{
if (fde.deleted) { return; }
GenericFile *file = disk->getFile(fde);
file->setFilename(AppleString(fde.filename).printable().trimmed());
ViewerBase *vb = new ViewerBase();
qDebug() << "Adding viewer" << vb;
m_viewerList.append(vb);
connect(vb,&ViewerBase::viewerClosing,
this, &DiskExplorer::handleViewerClosing);
vb->setFile(file);
vb->show();
}
void DiskExplorer::setDiskToolsVisible(bool visible)
{
m_toolsHidden = !visible;
if (visible)
{
m_gridLayout->setColumnStretch(0,4);
m_gridLayout->setColumnStretch(1,1);
m_gridLayout->setColumnStretch(2,4);
}
else
{
m_gridLayout->setColumnStretch(0,0);
m_gridLayout->setColumnStretch(1,0);
m_gridLayout->setColumnStretch(2,0);
}
if (m_demwStatusWidget) { m_demwStatusWidget->setVisible(visible); }
m_demw->setVisible(visible);
m_frame->setVisible(visible);
//m_hdv->setVisible(visible);
m_vws->setVisible(visible);
m_key->setVisible(visible);
if (!visible)
{
QTimer::singleShot(100, this, SLOT(doResize()));
}
}
void DiskExplorer::handleViewerClosing(ViewerBase *viewer)
{
qDebug() << "Removing viewer " << viewer;
m_viewerList.removeAll(viewer);
}
void DiskExplorer::doResize()
{
resize(m_horizSizePref, this->height());
}
void DiskExplorer::showEvent(QShowEvent *event)
{
Q_UNUSED(event);
if (m_horizSizePref == -1)
{
m_horizSizePref = this->width();
}
}
void DiskExplorer::closeEvent(QCloseEvent *)
{
foreach (ViewerBase *viewer, m_viewerList)
{
if (viewer)
{
viewer->deleteLater();
}
}
}
void DiskExplorer::resizeEvent(QResizeEvent *)
{
if (m_toolsHidden)
{
m_horizSizePref = this->width();
}
}