From 2c2e5a5874a485575d0f354c20caec34913213e7 Mon Sep 17 00:00:00 2001 From: mlong Date: Fri, 19 Feb 2021 14:57:05 -0600 Subject: [PATCH] Continuing work on disk explorer support widgets --- AppleSAWS.pro | 10 + disk-images/missing_ring_good.dsk | Bin 143360 -> 143360 bytes src/diskfiles/dos33/catalogsector.cxx | 18 +- src/diskfiles/dos33/catalogsector.h | 7 +- src/diskfiles/dos33/dos33diskimage.cxx | 114 ++--- src/diskfiles/dos33/dos33diskimage.h | 1 + src/diskfiles/dos33/genericfile.cxx | 13 +- src/diskfiles/dos33/sector.cxx | 2 + src/diskfiles/dos33/sector.h | 7 +- src/diskfiles/dos33/tracksectorlist.cxx | 4 + src/diskfiles/dos33/vtoc.cxx | 5 +- src/diskfiles/dos33/vtoc.h | 2 +- src/diskfiles/rawdiskimage.cpp | 2 + src/diskfiles/tspair.h | 5 +- src/main.cpp | 2 +- src/ui/catalogwidget.cxx | 6 +- src/ui/diskexplorer/DiskExplorer.cpp | 85 ++-- src/ui/diskexplorer/DiskExplorer.h | 7 +- src/ui/diskexplorer/DiskExplorerMapWidget.cpp | 396 +++++++++++++----- src/ui/diskexplorer/DiskExplorerMapWidget.h | 40 +- src/ui/diskexplorer/catalogsectorview.cpp | 110 +++++ src/ui/diskexplorer/catalogsectorview.h | 28 ++ src/ui/diskexplorer/catalogsectorview.ui | 194 +++++++++ src/ui/diskexplorer/tslistview.cpp | 35 ++ src/ui/diskexplorer/tslistview.h | 23 + src/ui/diskexplorer/viewwidgetstack.cpp | 61 +++ src/ui/diskexplorer/viewwidgetstack.h | 41 ++ src/ui/diskexplorer/vtocview.cpp | 104 +++++ src/ui/diskexplorer/vtocview.h | 31 ++ src/ui/diskexplorer/vtocview.ui | 200 +++++++++ 30 files changed, 1343 insertions(+), 210 deletions(-) create mode 100644 src/ui/diskexplorer/catalogsectorview.cpp create mode 100644 src/ui/diskexplorer/catalogsectorview.h create mode 100644 src/ui/diskexplorer/catalogsectorview.ui create mode 100644 src/ui/diskexplorer/tslistview.cpp create mode 100644 src/ui/diskexplorer/tslistview.h create mode 100644 src/ui/diskexplorer/viewwidgetstack.cpp create mode 100644 src/ui/diskexplorer/viewwidgetstack.h create mode 100644 src/ui/diskexplorer/vtocview.cpp create mode 100644 src/ui/diskexplorer/vtocview.h create mode 100644 src/ui/diskexplorer/vtocview.ui diff --git a/AppleSAWS.pro b/AppleSAWS.pro index 957552a..7e434da 100644 --- a/AppleSAWS.pro +++ b/AppleSAWS.pro @@ -65,6 +65,10 @@ SOURCES += \ src/sequence/textblockuserdata.cpp \ src/ui/central/centralappwindow.cpp \ src/ui/central/mainapptoolbar.cpp \ + src/ui/diskexplorer/catalogsectorview.cpp \ + src/ui/diskexplorer/tslistview.cpp \ + src/ui/diskexplorer/viewwidgetstack.cpp \ + src/ui/diskexplorer/vtocview.cpp \ src/ui/startupdialog.cpp \ src/ui/viewers/intbasicfileviewer.cxx \ src/ui/widgets/notesdialog.cpp \ @@ -136,6 +140,10 @@ HEADERS += \ src/sequence/textblockuserdata.h \ src/ui/central/centralappwindow.h \ src/ui/central/mainapptoolbar.h \ + src/ui/diskexplorer/catalogsectorview.h \ + src/ui/diskexplorer/tslistview.h \ + src/ui/diskexplorer/viewwidgetstack.h \ + src/ui/diskexplorer/vtocview.h \ src/ui/startupdialog.h \ src/ui/viewers/intbasicfileviewer.h \ src/ui/widgets/notesdialog.h \ @@ -187,6 +195,8 @@ HEADERS += \ FORMS += \ src/sequence/sequenceviewer.ui \ src/ui/catalogwidget.ui \ + src/ui/diskexplorer/catalogsectorview.ui \ + src/ui/diskexplorer/vtocview.ui \ src/ui/startupdialog.ui \ src/ui/viewers/applesoftfileviewer.ui \ src/ui/viewers/disassemblerviewer.ui \ diff --git a/disk-images/missing_ring_good.dsk b/disk-images/missing_ring_good.dsk index 30dacff213081955abb2c8d7a62848150c162221..c0e047103c2a3c878e45b3328b9c3d065d94f6af 100644 GIT binary patch delta 138 zcmZp8z|ru4V?lat(offset + 0x20)); - fde.setFirstTSListSector(first); - qDebug() << " New track: " << (quint8) fde.firstTSListSector().track(); - qDebug() << " Sector: " << fde.firstTSListSector().sector(); +// TSPair first = fde.firstTSListSector(); +// first.setTrack(m_data->at(offset + 0x20)); +// fde.setFirstTSListSector(first); +// qDebug() << " New track: " << (quint8) fde.firstTSListSector().track(); +// qDebug() << " Sector: " << fde.firstTSListSector().sector(); } return fde; } + +TSPair CatalogSector::sectorLocation() const { + return TSPair(m_data->track(),m_data->sector()); +} diff --git a/src/diskfiles/dos33/catalogsector.h b/src/diskfiles/dos33/catalogsector.h index 43af6b8..97b0430 100644 --- a/src/diskfiles/dos33/catalogsector.h +++ b/src/diskfiles/dos33/catalogsector.h @@ -19,7 +19,8 @@ class CatalogSector public: CatalogSector(Sector *sector); - FileDescriptiveEntry &getFDE(quint8 number) { + FileDescriptiveEntry getFDE(quint8 number) { + if (m_fdes.length() == 0) { return FileDescriptiveEntry(); } if (number >= m_fdes.length()) { number = m_fdes.length() - 1; } @@ -34,9 +35,11 @@ public: Sector *getSector() const { return m_data; } -private: FileDescriptiveEntry makeFDE(int offset); + TSPair sectorLocation() const; +private: + private: Sector *m_data; QList m_fdes; diff --git a/src/diskfiles/dos33/dos33diskimage.cxx b/src/diskfiles/dos33/dos33diskimage.cxx index 5aa4847..67c11a6 100644 --- a/src/diskfiles/dos33/dos33diskimage.cxx +++ b/src/diskfiles/dos33/dos33diskimage.cxx @@ -13,6 +13,7 @@ #include "IntBasicFile.h" #include "relocatablefile.h" #include "textfile.h" +#include "sector.h" Dos33DiskImage::Dos33DiskImage(QString filename) { @@ -21,20 +22,26 @@ Dos33DiskImage::Dos33DiskImage(QString filename) if (!filename.isEmpty()) { read(filename); + //TODO: Cross reference & dbl. check sec/track with VTOC } + auto dummy_data = new SectorData; + dummy_data->resize(256); + m_dummy_sector.setData(dummy_data); } Dos33DiskImage::Dos33DiskImage(RawDiskImage *rawImage) { m_disk_image = rawImage; + //TODO: Cross reference & dbl. check sec/track with VTOC + } Dos33DiskImage::~Dos33DiskImage() { -// foreach (GenericFile *file, m_files) -// { -// delete file; -// } + // foreach (GenericFile *file, m_files) + // { + // delete file; + // } } bool Dos33DiskImage::read(QString filename) @@ -59,58 +66,63 @@ bool Dos33DiskImage::read(QString filename) return retval; -// m_fullImageName = filename; -// m_imageName = QFileInfo(filename).fileName(); -// QFile infile(filename); -// QCryptographicHash hash(QCryptographicHash::Md5); + // m_fullImageName = filename; + // m_imageName = QFileInfo(filename).fileName(); + // QFile infile(filename); + // QCryptographicHash hash(QCryptographicHash::Md5); -// if (infile.open(QIODevice::ReadOnly)) -// { -// QByteArray contents = infile.readAll(); -// int expectedsize = sectorsPerTrack() * tracks() * 256; -// if (contents.size() != expectedsize) -// { -// if (contents.size() == 35*16*256) { m_sectors_per_track = 16; } -// else if (contents.size() == 35*13*256) { m_sectors_per_track = 13; } -// else qWarning() << QString("Size mismatch in file! Expected %1, got %2") -// .arg(expectedsize) -// .arg(contents.size()); -// } + // if (infile.open(QIODevice::ReadOnly)) + // { + // QByteArray contents = infile.readAll(); + // int expectedsize = sectorsPerTrack() * tracks() * 256; + // if (contents.size() != expectedsize) + // { + // if (contents.size() == 35*16*256) { m_sectors_per_track = 16; } + // else if (contents.size() == 35*13*256) { m_sectors_per_track = 13; } + // else qWarning() << QString("Size mismatch in file! Expected %1, got %2") + // .arg(expectedsize) + // .arg(contents.size()); + // } -// QDataStream qds(contents); -// for (int track = 0; track < 35; track++) -// { -// for (int sector = 0; sector < m_sectors_per_track; sector++) -// { -// char buffer[256]; -// if (qds.readRawData(buffer,256) == 256) -// { -// TSPair tmpts(track,sector); -// Sector newSec; -// newSec.setTrackSector(tmpts); -// newSec.setData(QByteArray(buffer,256)); -// m_contents[tmpts] = newSec; -// } -// else -// { -// qDebug() << "Invalid sector read!"; -// return false; -// } -// } -// } -// hash.addData(contents); + // QDataStream qds(contents); + // for (int track = 0; track < 35; track++) + // { + // for (int sector = 0; sector < m_sectors_per_track; sector++) + // { + // char buffer[256]; + // if (qds.readRawData(buffer,256) == 256) + // { + // TSPair tmpts(track,sector); + // Sector newSec; + // newSec.setTrackSector(tmpts); + // newSec.setData(QByteArray(buffer,256)); + // m_contents[tmpts] = newSec; + // } + // else + // { + // qDebug() << "Invalid sector read!"; + // return false; + // } + // } + // } + // hash.addData(contents); -// m_hash = hash.result(); -// // qDebug() << "Hash: " << m_hash; + // m_hash = hash.result(); + // // qDebug() << "Hash: " << m_hash; -// return true; -// } -// else -// qDebug() << "Could not open file " << filename; -// return false; + // return true; + // } + // else + // qDebug() << "Could not open file " << filename; + // return false; } -Sector &Dos33DiskImage::getSector(TSPair ts) { return m_contents[ts]; } +Sector &Dos33DiskImage::getSector(TSPair ts) { + if (m_contents.contains(ts)) + return m_contents[ts]; + else + return m_dummy_sector; +} Sector &Dos33DiskImage::getSector(int track, int sector) { return getSector(TSPair(track,sector)); @@ -184,7 +196,7 @@ GenericFile *Dos33DiskImage::getFile(FileDescriptiveEntry fde) } else { - retval = new GenericFile(this,fde); + retval = new GenericFile(this,fde); } retval->updateFromFDE(fde); m_files[fde] = retval; diff --git a/src/diskfiles/dos33/dos33diskimage.h b/src/diskfiles/dos33/dos33diskimage.h index 42f6c31..fca764f 100644 --- a/src/diskfiles/dos33/dos33diskimage.h +++ b/src/diskfiles/dos33/dos33diskimage.h @@ -63,6 +63,7 @@ private: QMap m_files; QByteArray m_hash; + Sector m_dummy_sector; // Returned for non-existant sectors on disk }; diff --git a/src/diskfiles/dos33/genericfile.cxx b/src/diskfiles/dos33/genericfile.cxx index 3cda6c7..1b1726c 100644 --- a/src/diskfiles/dos33/genericfile.cxx +++ b/src/diskfiles/dos33/genericfile.cxx @@ -13,6 +13,11 @@ quint16 GenericFile::rawDataWordAt(int offset) quint8 GenericFile::dataAt(int offset) { + if (offset >= data().size()) + { + qWarning("Data offset (%d) > size (%d)",offset,data().size()); + return 0; + } return data().at(offset); } @@ -26,10 +31,10 @@ QByteArray GenericFile::data() { if (m_local_data.size() == 0) { - if (m_data_cache.size() == 0) - { - m_data_cache = rawData().asQByteArray(); - } + if (m_data_cache.size() == 0) + { + m_data_cache = rawData().asQByteArray(); + } } else { diff --git a/src/diskfiles/dos33/sector.cxx b/src/diskfiles/dos33/sector.cxx index dda00b8..9ba2e76 100644 --- a/src/diskfiles/dos33/sector.cxx +++ b/src/diskfiles/dos33/sector.cxx @@ -7,6 +7,8 @@ quint8 Sector::operator[](uint offset) const { if (offset > 255) { offset = 255; } + if ((int) offset >= m_raw_data->size()) return 0; + return m_raw_data->at(offset); } diff --git a/src/diskfiles/dos33/sector.h b/src/diskfiles/dos33/sector.h index bb8c7eb..f320c94 100644 --- a/src/diskfiles/dos33/sector.h +++ b/src/diskfiles/dos33/sector.h @@ -14,7 +14,6 @@ class Sector public: Sector(SectorData *data = nullptr) { - // m_data.resize(256); setData(data); m_track = 255; m_sector = 255; @@ -54,7 +53,11 @@ public: void setSector(int sector) { m_sector = sector; } quint8 operator[](uint offset) const; - quint8 at(int offset) { return m_raw_data->at(offset); } + quint8 at(int offset) { + if (offset >= m_raw_data->size()) return 0; + + return m_raw_data->at(offset); + } void dump(); diff --git a/src/diskfiles/dos33/tracksectorlist.cxx b/src/diskfiles/dos33/tracksectorlist.cxx index 82e446f..1896993 100644 --- a/src/diskfiles/dos33/tracksectorlist.cxx +++ b/src/diskfiles/dos33/tracksectorlist.cxx @@ -40,6 +40,10 @@ QList TrackSectorList::getValidTSPairs() const foreach (auto item, m_ts_pairs_for_data) { if (item.isValid()) { retval.append(item); } + else + { + break; + } } return retval; diff --git a/src/diskfiles/dos33/vtoc.cxx b/src/diskfiles/dos33/vtoc.cxx index 864da2f..6749e21 100644 --- a/src/diskfiles/dos33/vtoc.cxx +++ b/src/diskfiles/dos33/vtoc.cxx @@ -13,6 +13,7 @@ VTOC::VTOC(Sector *data) TSPair VTOC::firstCatalogSector() { // return TSPair(0x11,0x0f); // Force to look at the normal location + return TSPair(m_data->at(0x01), m_data->at(0x02)); } @@ -40,7 +41,7 @@ quint8 VTOC::tracksPerDisk() { return m_data->at(0x34); } -quint8 VTOC::sectorsPerDisk() { +quint8 VTOC::sectorsPerTrack() { return m_data->at(0x35); } @@ -118,7 +119,7 @@ void VTOC::dump() qDebug() << " Last track where sectors were allocated: " << QString::number(lastTrackAllocated()); qDebug() << " Direction of track allocations (+/- 1): " << QString::number(directionOfAllocation()); qDebug() << " Number tracks per disk: " << QString::number(tracksPerDisk()); - qDebug() << " Number sectors per disk: " << QString::number(sectorsPerDisk()); + qDebug() << " Number sectors per disk: " << QString::number(sectorsPerTrack()); qDebug() << " Number bytes/sector: " << QString::number(bytesPerSector()); qDebug() << " Track Usage (.=free, 0-F=used):"; for (quint8 track = 0; track < m_data->at(0x34);track++) diff --git a/src/diskfiles/dos33/vtoc.h b/src/diskfiles/dos33/vtoc.h index ddb4a31..bf7f8c2 100644 --- a/src/diskfiles/dos33/vtoc.h +++ b/src/diskfiles/dos33/vtoc.h @@ -21,7 +21,7 @@ public: quint8 lastTrackAllocated(); qint8 directionOfAllocation(); quint8 tracksPerDisk(); - quint8 sectorsPerDisk(); + quint8 sectorsPerTrack(); qint16 bytesPerSector(); bool isSectorInUse(TSPair ts) const; diff --git a/src/diskfiles/rawdiskimage.cpp b/src/diskfiles/rawdiskimage.cpp index d480772..839ad33 100644 --- a/src/diskfiles/rawdiskimage.cpp +++ b/src/diskfiles/rawdiskimage.cpp @@ -59,6 +59,8 @@ bool RawDiskImage::read(QString filename) if (infile.open(QIODevice::ReadOnly)) { QByteArray contents = infile.readAll(); + + int expectedsize = sectorsPerTrack() * numTracks() * 256; if (contents.size() != expectedsize) { diff --git a/src/diskfiles/tspair.h b/src/diskfiles/tspair.h index b84a830..0cf3b09 100644 --- a/src/diskfiles/tspair.h +++ b/src/diskfiles/tspair.h @@ -30,9 +30,10 @@ public: bool isValid() const { - auto retval= (m_track != 0xff && m_track < 35) && m_sector < 16; + auto retval = (m_track == 0xff || m_track < 35) && m_sector < 16; - return retval; } + return retval; + } int track() const { return m_track; } int sector() const { return m_sector; } diff --git a/src/main.cpp b/src/main.cpp index 34038c9..c9ec35d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ int main(int argc, char** argv) { QApplication a(argc, argv); + QCoreApplication::setOrganizationName("LydianScaleSoftware"); QCoreApplication::setOrganizationDomain("lydianscale.com"); QCoreApplication::setApplicationName("AppleSAWS"); @@ -28,6 +29,5 @@ int main(int argc, char** argv) w.show(); return a.exec(); - } diff --git a/src/ui/catalogwidget.cxx b/src/ui/catalogwidget.cxx index 3c4f09c..60106a7 100644 --- a/src/ui/catalogwidget.cxx +++ b/src/ui/catalogwidget.cxx @@ -40,6 +40,8 @@ void CatalogWidget::prepForNewDisk(QString filename, Dos33DiskImage *disk) QString CatalogWidget::createToolTip(FileDescriptiveEntry &fde) { QString retval; + +return retval; retval += AppleString(fde.filename).printable().trimmed() + (fde.deleted?"(Deleted)":"") + "\n"; retval += QString("Type: %1\n").arg(fde.fileTypeIdentifier()); @@ -68,8 +70,8 @@ QString CatalogWidget::createToolTip(FileDescriptiveEntry &fde) { .arg(uabytes); } } else { - retval += QString("Data Length: $%1 (%2)\n").arg((quint16) (file->data().length()),4,16,QChar('0')) - .arg(file->data().length()); + retval += QString("Data Length: $%1 (%2)\n").arg((quint16) (file->rawData().length()),4,16,QChar('0')) + .arg(file->rawData().length()); } // delete file; return retval; diff --git a/src/ui/diskexplorer/DiskExplorer.cpp b/src/ui/diskexplorer/DiskExplorer.cpp index 4aa65d9..a75e37d 100644 --- a/src/ui/diskexplorer/DiskExplorer.cpp +++ b/src/ui/diskexplorer/DiskExplorer.cpp @@ -19,7 +19,7 @@ DiskExplorer::DiskExplorer(QWidget *parent) : QMainWindow(parent) m_disk = nullptr; m_horizSizePref = -1; m_toolsHidden = true; - // m_notesDialog = nullptr; + // m_notesDialog = nullptr; m_AsciiInfoDialog = nullptr; m_hrcgDialog = nullptr; @@ -36,24 +36,24 @@ DiskExplorer::~DiskExplorer() void DiskExplorer::initUi() { QMenuBar *menuBar = new QMenuBar(this); - setMenuBar(menuBar); + 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); + // 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); + // 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); + // 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); + // connect(m_action_Unload_Disk_Image, &QAction::triggered, + // this, &DiskExplorer::unloadDiskFile); -// menu->addSeparator(); + // menu->addSeparator(); QAction *action_Quit = new QAction(tr("&Quit"),this); menu->addAction(action_Quit); @@ -93,12 +93,12 @@ void DiskExplorer::initUi() m_AsciiInfoDialog = new AsciiInfoDialog(this); connect(action_Ascii_Info, &QAction::triggered, m_AsciiInfoDialog, &AsciiInfoDialog::show); -// menu->addSeparator(); + // 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); + // 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(); @@ -112,9 +112,12 @@ void DiskExplorer::initUi() 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_hdv = new HexDumpViewer(this, 10); + // frameLayout->addWidget(m_hdv); + + m_vws = new ViewWidgetStack(this); + frameLayout->addWidget(m_vws); m_gridLayout->setColumnStretch(0,4); m_gridLayout->setColumnStretch(1,1); @@ -127,9 +130,9 @@ void DiskExplorer::initUi() m_gridLayout->addWidget(m_frame,1,2); this->setCentralWidget(widget); -// auto lo = new QGridLayout(); -// this->setLayout(lo); -// lo->addWidget(widget); + // auto lo = new QGridLayout(); + // this->setLayout(lo); + // lo->addWidget(widget); connect(m_cw, &CatalogWidget::openWithDefaultViewer, @@ -153,7 +156,8 @@ void DiskExplorer::unloadDiskFile() { m_cw->unloadDisk(m_disk); m_demw->unloadDisk(); - m_hdv->setRawData(QByteArray(),0); + //m_hdv->setRawData(QByteArray(),0); + m_vws->setSector(nullptr); } } @@ -178,12 +182,34 @@ void DiskExplorer::loadDiskFile(QString filename) } } -void DiskExplorer::handleShowSectorData(QByteArray data, int track, int sector, QVariant metadata) +void DiskExplorer::handleShowSectorData(QByteArray /*data*/, int track, int sector, QVariant metadata) { - Q_UNUSED(track) - Q_UNUSED(sector) - Q_UNUSED(metadata) - m_hdv->setRawData(data,0); + + 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) @@ -238,7 +264,8 @@ void DiskExplorer::setDiskToolsVisible(bool visible) m_demw->setVisible(visible); m_frame->setVisible(visible); - m_hdv->setVisible(visible); + //m_hdv->setVisible(visible); + m_vws->setVisible(visible); m_key->setVisible(visible); if (!visible) diff --git a/src/ui/diskexplorer/DiskExplorer.h b/src/ui/diskexplorer/DiskExplorer.h index 05efdf6..3b2a449 100644 --- a/src/ui/diskexplorer/DiskExplorer.h +++ b/src/ui/diskexplorer/DiskExplorer.h @@ -8,11 +8,13 @@ #include "dos33diskimage.h" #include "hrcgcontrolsinfo.h" #include "hexconverter.h" -#include "hexdumpviewer.h" +//#include "hexdumpviewer.h" #include "viewerbase.h" #include "asciiinfodialog.h" //#include "notesdialog.h" +#include "viewwidgetstack.h" + #include #include @@ -58,7 +60,8 @@ private: CatalogWidget *m_cw; DiskExplorerMapWidget *m_demw; QFrame *m_frame; - HexDumpViewer *m_hdv; + // HexDumpViewer *m_hdv; + ViewWidgetStack *m_vws; QWidget *m_key; QGridLayout *m_gridLayout; diff --git a/src/ui/diskexplorer/DiskExplorerMapWidget.cpp b/src/ui/diskexplorer/DiskExplorerMapWidget.cpp index bcd669e..7e9fcc7 100644 --- a/src/ui/diskexplorer/DiskExplorerMapWidget.cpp +++ b/src/ui/diskexplorer/DiskExplorerMapWidget.cpp @@ -25,7 +25,6 @@ DiskExplorerMapWidget::DiskExplorerMapWidget(int numtracks, int numsectors, QWid setWindowTitle("Disk Explorer"); QGridLayout *gridlayout = new QGridLayout(this); - // gridlayout->setSizeConstraint(QLayout::SetFixedSize); gridlayout->setSizeConstraint(QLayout::SetMinimumSize); gridlayout->setHorizontalSpacing(1); gridlayout->setVerticalSpacing(1); @@ -65,7 +64,7 @@ DiskExplorerMapWidget::DiskExplorerMapWidget(int numtracks, int numsectors, QWid gridlayout->addWidget(tb,sec+2,track+1); } } - gridlayout->addWidget(new QLabel("Stretchy Row"),18,0,1,5); + gridlayout->addWidget(new QLabel(""),18,0,1,5); // Stretchy Row gridlayout->setRowStretch(18,900); @@ -107,13 +106,23 @@ QString DiskExplorerMapWidget::getSectorDescription(int track, int sector) else { QString desc = "xxx"; - if (m_sectorDescriptions.contains(DETSPair(track,sector))) + if (m_descriptions.contains(TSPair(track,sector))) { - desc = m_sectorDescriptions[DETSPair(track,sector)]; + desc = m_descriptions[TSPair(track,sector)]; + } + else + { + if (m_roles[TSPair(track,sector)] == DiskSectorRole::Unknown) + { + desc = "Unused"; + } + else + { + desc = "Marked as used, but use unknown"; + } } return desc.simplified(); } - } void DiskExplorerMapWidget::handleButtonCheck(int track, int sector, bool checked) @@ -123,14 +132,13 @@ void DiskExplorerMapWidget::handleButtonCheck(int track, int sector, bool checke if (m_currentChecked) { // Do anything needed to clean up after previous button click - // m_currentClicked->setHighlighted(false); } if (checked) { Sector sec = m_disk->getSector(track,sector); QByteArray *data = sec.rawData(); - emit showSectorData(*data,track,sector,QVariant()); + emit showSectorData(*data,track,sector,QVariant((int) m_roles[TSPair(track,sector)])); m_trackSectorLabel->setText( QString("Track: %1 Sector: %2 (%3)") .arg(track) @@ -138,7 +146,7 @@ void DiskExplorerMapWidget::handleButtonCheck(int track, int sector, bool checke .arg(getSectorDescription(track,sector))); } else{ - emit showSectorData(QByteArray(),-1,-1,QVariant()); + emit showSectorData(QByteArray(),-1,-1,QVariant(-1)); m_trackSectorLabel->setText("No Track/Sector selected"); } @@ -154,7 +162,7 @@ void DiskExplorerMapWidget::setDisk(Dos33DiskImage *disk) { if (disk) { - m_sectorDescriptions.clear(); + m_descriptions.clear(); m_disk = disk; setWindowTitle(QString("Disk Explorer - %1").arg(m_disk->getDiskImageName())); @@ -164,7 +172,10 @@ void DiskExplorerMapWidget::setDisk(Dos33DiskImage *disk) { if (m_disk) { - mapDiskToButtons(); + defineRoles(); + checkForUsedButUnknown(); + mapButtonsFromRoles(); + //mapDiskToButtons(); } } else @@ -178,7 +189,7 @@ void DiskExplorerMapWidget::unloadDisk() { if (m_disk) { - m_sectorDescriptions.clear(); + m_descriptions.clear(); m_bgroup->setExclusive(false); for (int track = 0; track < m_numtracks; track++) { @@ -268,123 +279,305 @@ void DiskExplorerMapWidget::initColors() m_intBasicFileColor = QColor("#00d0d0"); m_binaryFileColor = QColor("#d060d0"); m_textFileColor = QColor("#F05060"); - m_reloFileColor = QColor("#d00000"); - m_typeAFileColor = QColor("#c040a0"); + m_reloFileColor = QColor("#d00000"); + m_typeAFileColor = QColor("#c040a0"); m_typeBFileColor = QColor("#c03030"); m_typeSFileColor = QColor("#20a0a0"); } -void DiskExplorerMapWidget::mapDiskToButtons() +void DiskExplorerMapWidget::defineRoles(TSPair vtoc) { - setAllButtonsEnabled(true); - m_bgroup->setExclusive(false); + m_descriptions.clear(); + m_numbers.clear(); + m_roles.clear(); - int idx = 0; - for (int track = 0; track < 3; track++) + int buttonNumber = 0; + + for (auto track = 0; track < m_numtracks; track++) { - for (int sec = 0; sec < m_numsectors; sec++) + for (auto sec = 0; sec < m_numsectors; sec++) { + TSPair ts(track,sec); if (track == 0) - buttonAt(track,sec)->setBgColor(m_bootSectorColor); + { + if (setButtonRole(ts,DiskSectorRole::BootSector)) + { + setButtonNumber(ts,buttonNumber++); + setDescription(ts,"Boot Sector"); + } + } + else if (track <= 2) + { + if (setButtonRole(ts,DiskSectorRole::DosImage)) + { + setButtonNumber(ts,buttonNumber++); + setDescription(ts,"DOS Image"); + } + } else - buttonAt(track,sec)->setBgColor(m_dosImageColor); - buttonAt(track,sec)->setText(QString("%1").arg(idx++)); + { + setButtonRole(ts,DiskSectorRole::Unknown); + } } } - buttonAt(17,0)->setBgColor(m_vtocColor); - buttonAt(17,0)->setText(QString("%1").arg(idx++)); + if (setButtonRole(vtoc, DiskSectorRole::VTOC)) + { + setButtonNumber(vtoc,buttonNumber++); + setDescription(vtoc,"VTOC"); + } - int catseccount = 0; + mapCatalogSectors(buttonNumber); +} + +void DiskExplorerMapWidget::mapCatalogSectors(int &buttonNumber) +{ + int catSectorCount = 0; foreach (CatalogSector cs, m_disk->getCatalogSectors()) { - // qDebug() << "LOOP 1"; - Sector *sec = cs.getSector(); - - QString desc = QString("Catalog Sector #%1").arg(++catseccount); - m_sectorDescriptions.insert(DETSPair(sec->track(),sec->sector()),desc); - - buttonAt(sec->track(),sec->sector())->setBgColor(m_dirEntryColor); - buttonAt(sec->track(),sec->sector())->setText(QString("%1").arg(idx++)); - - foreach(FileDescriptiveEntry fde, cs.getFDEs()) + TSPair ts(cs.sectorLocation()); + if (setButtonRole(ts,DiskSectorRole::CatalogSector)) { - // qDebug() << "LOOP 2"; - Sector *s = &(m_disk->getSector(fde.firstTSListSector())); - TrackSectorList tsl(s); + QString desc = QString("Catalog Sector #%1").arg(++catSectorCount); + setDescription(ts,desc); + setButtonNumber(ts,buttonNumber++); - int tsltr = fde.firstTSListSector().track(); - int tslse = fde.firstTSListSector().sector(); - - if (!fde.firstTSListSector().isValid()) + int fdeNum = 0; + foreach (FileDescriptiveEntry fde, cs.getFDEs()) { - qDebug() << "Invalid first tse entry. Skipping TSList."; + mapFDE(fde, fdeNum++, buttonNumber); + } + } + else + { + qDebug("Not processing remap-attempted Catalog Sector"); + } + + } +} + +void DiskExplorerMapWidget::mapFDE(FileDescriptiveEntry &fde, int /*fdeNum*/, int &buttonNumber) +{ + TSPair ts_list = fde.firstTSListSector(); + + int tslCount = 0; + + if (fde.lengthInSectors == 0) + { + qDebug("FDE Reports 0 sectors used, not looking at T/S List"); + return; + } + mapTSListSector(ts_list,fde,buttonNumber, tslCount); +} + +void DiskExplorerMapWidget::mapTSListSector(TSPair location, + FileDescriptiveEntry &fde, + int &buttonNumber, int &tslCount) +{ + // Don't follow deleted links. + if (location.track() == 0xff) return; + + + if (location == TSPair(0,0)) + { + return; + } + + if (!location.isValid()) + { + qDebug("Invalid mapTSListSector location: %d/%d. Not parsing.", + location.track(),location.sector()); + return; + } + + if (m_roles[location] != DiskSectorRole::Unknown) + { + qDebug("Not processing FDE for previously processed sector at %d/%d", + location.track(), location.sector()); + return; + } + + Sector *s = &(m_disk->getSector(location)); + TrackSectorList tsl(s); + + if (setButtonRole(location,DiskSectorRole::TSList)) + { + tslCount++; + QString desc = QString("T/S List #%1 for %2").arg(tslCount) + .arg(fde.filename.printable()); + setDescription(location, desc); + setButtonNumber(location,buttonNumber++); + + int sectorcount = 0; + auto pairs = tsl.getValidTSPairs(); + + foreach(TSPair tsp, pairs) + { + if (tsp.isValid()) + { + auto filetype = getFileTypeFromID(fde.fileTypeIdentifier()); + if (setButtonRole(tsp,filetype)) + { + setButtonNumber(tsp,buttonNumber++); + QString description = QString("Sector #%1.%2 of %3") + .arg(tslCount) + .arg(++sectorcount) + .arg(fde.filename.printable()); + setDescription(tsp,description); + } + } + else + { + qDebug("Invalid value in T/S List"); + } + } + + TSPair next = tsl.getNextTSList(); + mapTSListSector(next, fde, buttonNumber, tslCount); + } + + +} + +DiskSectorRole DiskExplorerMapWidget::getFileTypeFromID(QString id) +{ + DiskSectorRole role = DiskSectorRole::Used; + + if (id == "I") role = DiskSectorRole::IntBasicFile; + else if (id == "A") role = DiskSectorRole::ApplesoftFile; + else if (id== "R") role = DiskSectorRole::RelocatableFile; + else if (id == "B") role = DiskSectorRole::BinaryFile; + else if (id== "S") role = DiskSectorRole::TypeSFile; + else if (id == "T") role = DiskSectorRole::TextFile; + else if (id == "a") role = DiskSectorRole::TypeAFile; + else if (id == "b") role = DiskSectorRole::TypeBFile; + + return role; +} + + +bool DiskExplorerMapWidget::setButtonRole(TSPair ts, DiskSectorRole role) +{ + if (m_roles.contains(ts) && m_roles[ts] != DiskSectorRole::Unknown) + { + qDebug("Trying to remap button %d (Role: %d) with new role %d.", + m_numbers[ts], (int) m_roles[ts], (int) role); + return false; + } + + m_roles[ts] = role; + return true; + +} + +void DiskExplorerMapWidget::setButtonNumber(TSPair ts, int number) +{ + m_numbers[ts] = number; +} + +void DiskExplorerMapWidget::setDescription(TSPair ts, QString description) +{ + m_descriptions[ts] = description; +} + +void DiskExplorerMapWidget::mapButtonsFromRoles() +{ + for (auto track = 0; track < m_numtracks; track++) + { + for (auto sec = 0; sec < m_numsectors; sec++) + { + auto button = buttonAt(track,sec); + TSPair ts(track,sec); + + QColor buttonColor; + + switch (m_roles[ts]) + { + case DiskSectorRole::BootSector: + buttonColor = m_bootSectorColor; break; + case DiskSectorRole::DosImage: + buttonColor = m_dosImageColor; + break; + case DiskSectorRole::VTOC: + buttonColor = m_vtocColor; + break; + case DiskSectorRole::CatalogSector: + buttonColor = m_dirEntryColor; + break; + case DiskSectorRole::TSList: + buttonColor = m_tsListColor; + break; + case DiskSectorRole::ApplesoftFile: + buttonColor = m_applesoftFileColor; + break; + case DiskSectorRole::IntBasicFile: + buttonColor = m_intBasicFileColor; + break; + case DiskSectorRole::TextFile: + buttonColor = m_textFileColor; + break; + case DiskSectorRole::RelocatableFile: + buttonColor = m_reloFileColor; + break; + case DiskSectorRole::BinaryFile: + buttonColor = m_binaryFileColor; + break; + case DiskSectorRole::TypeAFile: + buttonColor = m_typeAFileColor; + break; + case DiskSectorRole::TypeBFile: + buttonColor = m_typeBFileColor; + break; + case DiskSectorRole::TypeSFile: + buttonColor = m_typeSFileColor; + break; + case DiskSectorRole::Used: + buttonColor = m_defaultColor.lighter(120); + break; + case DiskSectorRole::Unknown: + default: + buttonColor = m_defaultColor; } - int tslcount = 0; - while (tsltr != 0 /*&& tslcount < 1*/) + button->setBgColor(buttonColor); + if (m_roles.contains(ts)) { - qDebug() << "LOOP 3"; - tslcount++; - - buttonAt(tsltr,tslse)->setBgColor(m_tsListColor); - buttonAt(tsltr,tslse)->setText(QString("%1").arg(idx)); - // qDebug() << "Button" << idx << "=" << tsltr << "," << tslse << " " << fde.filename.printable() << "TSL"; - - QString description = QString("T/S List #%1 for %2").arg(tslcount).arg(fde.filename.printable()); - m_sectorDescriptions.insert(DETSPair(tsltr,tslse),description); - - idx++; - - bool valid = true; - - int sectorcount = 0; - auto pairs = tsl.getDataTSPairs(); - // int jdx = 0; -/*if (false) */ foreach(TSPair tsp, pairs) + if (m_roles[ts] != DiskSectorRole::Used && m_roles[ts] != DiskSectorRole::Unknown) { - - // qDebug() << "LOOP 4" << jdx++ << "of" << pairs.count() << "pairs"; -//QCoreApplication::processEvents(QEventLoop::AllEvents); - int se = tsp.sector(); - int tr = tsp.track(); - - if (valid && tsp.isValid() && (se != 0 && tr != 0)) { - QString description = QString("Sector #%1.%2 of %3") - .arg(tslcount) - .arg(++sectorcount) - .arg(fde.filename.printable()); - m_sectorDescriptions.insert(DETSPair(tr,se),description); - - QColor color; - if (fde.fileTypeIdentifier() == "I") color = m_intBasicFileColor; - else if (fde.fileTypeIdentifier() == "A") color = m_applesoftFileColor; - else if (fde.fileTypeIdentifier() == "R") color = m_reloFileColor; - else if (fde.fileTypeIdentifier() == "B") color = m_binaryFileColor; - else if (fde.fileTypeIdentifier() == "S") color = m_typeSFileColor; - else if (fde.fileTypeIdentifier() == "T") color = m_textFileColor; - else if (fde.fileTypeIdentifier() == "a") color = m_typeAFileColor; - else if (fde.fileTypeIdentifier() == "b") color = m_typeBFileColor; - else qDebug() << "Unknown file type: " << fde.fileTypeIdentifier(); - buttonAt(tr,se)->setBgColor(color); - setButtonText(tr,se,QString("%1").arg(idx)); - qDebug() << "Button" << idx << "=" << tr << "," << se << " " << fde.filename.printable(); - fde.dump(); - } - idx++; + setButtonText(track,sec,QString("%1").arg(m_numbers[ts])); + } + else + { + if (m_roles[ts] == DiskSectorRole::Used) + { + setButtonText(track,sec,"?"); + } } - tsltr = tsl.getNextTSList().track(); - tslse = tsl.getNextTSList().sector(); - - valid = tsl.getNextTSList().isValid(); - - tsl = m_disk->getSector(tsl.getNextTSList()).asTrackSectorList(); } } } - m_bgroup->setExclusive(true); +} +void DiskExplorerMapWidget::checkForUsedButUnknown(TSPair vtoc) +{ + auto vtocsector = m_disk->getSector(vtoc).promoteToVTOC(); + + for (auto track = 0; track < m_numtracks; track++) + { + for (auto sec = 0; sec < m_numsectors; sec++) + { + TSPair ts(track,sec); + + if (m_roles[ts] == DiskSectorRole::Unknown) + { + if (vtocsector.isSectorInUse(ts)) + { + m_roles[ts] = DiskSectorRole::Used; + } + } + } + } } void DiskExplorerMapWidget::showEvent(QShowEvent *) @@ -393,7 +586,10 @@ void DiskExplorerMapWidget::showEvent(QShowEvent *) { if (m_disk) { - mapDiskToButtons(); + defineRoles(); + checkForUsedButUnknown(); + mapButtonsFromRoles(); + //mapDiskToButtons(); } m_deferredSetup = false; } diff --git a/src/ui/diskexplorer/DiskExplorerMapWidget.h b/src/ui/diskexplorer/DiskExplorerMapWidget.h index 0b2aa50..8bfea7b 100644 --- a/src/ui/diskexplorer/DiskExplorerMapWidget.h +++ b/src/ui/diskexplorer/DiskExplorerMapWidget.h @@ -1,6 +1,8 @@ #ifndef DISKEXPLORERMAPWIDGET_H #define DISKEXPLORERMAPWIDGET_H +#include "dos33diskimage.h" + #include #include #include @@ -11,8 +13,6 @@ #include -#include "dos33diskimage.h" - class DEButton : public QToolButton { @@ -113,9 +113,25 @@ private: }; +enum class DiskSectorRole { + Unknown, + Used, + BootSector, + DosImage, + VTOC, + CatalogSector, + TSList, -typedef QPair DETSPair; + ApplesoftFile, + IntBasicFile, + BinaryFile, + TextFile, + RelocatableFile, + TypeAFile, + TypeBFile, + TypeSFile +}; class DiskExplorerMapWidget : public QWidget { @@ -144,7 +160,11 @@ public slots: void handleButtonCheck(int track, int sector, bool checked); protected: - void mapDiskToButtons(); + void mapButtonsFromRoles(); + void defineRoles(TSPair vtoc = TSPair(17,0)); + bool setButtonRole(TSPair ts, DiskSectorRole role); + void setButtonNumber(TSPair ts, int number); + DEButton *buttonAt(int track, int sector); void initColors(); @@ -163,6 +183,13 @@ protected: void makeStatusWidget(); QString getSectorDescription(int track, int sector); + void mapCatalogSectors(int &buttonNumber); + void setDescription(TSPair ts, QString description); + void mapFDE(FileDescriptiveEntry &fde, int fdeNum, int &buttonNumber); + void mapTSListSector(TSPair location, FileDescriptiveEntry &fde, + int &buttonNumber, int &tslCount); + DiskSectorRole getFileTypeFromID(QString id); + void checkForUsedButUnknown(TSPair vtoc = TSPair(17,0)); private: QMap > m_buttons; @@ -195,7 +222,10 @@ private: QLabel *m_trackSectorLabel; QWidget *m_statusWidget; - QMap< DETSPair, QString> m_sectorDescriptions; + QMap m_descriptions; + QMap m_roles; + QMap m_numbers; }; + #endif // DISKEXPLORERMAPWIDGET_H diff --git a/src/ui/diskexplorer/catalogsectorview.cpp b/src/ui/diskexplorer/catalogsectorview.cpp new file mode 100644 index 0000000..39ecdb8 --- /dev/null +++ b/src/ui/diskexplorer/catalogsectorview.cpp @@ -0,0 +1,110 @@ +#include "catalogsectorview.h" +#include "ui_catalogsectorview.h" +#include "sector.h" + +#include + +CatalogSectorView::CatalogSectorView(QWidget *parent) : + QWidget(parent), + ui(new Ui::CatalogSectorView) +{ + ui->setupUi(this); + for (int row = 0; row < 7; row++) + { + for (int col = 0; col < 4; col++) + { + auto item = new QTableWidgetItem(""); + item->setForeground(Qt::black); + item->setFont(QFont("Print Char 21",8)); + item->setFlags(Qt::NoItemFlags); + ui->fdeTable->setItem(row,col,item); + } + } + QHeaderView *verticalHeader = ui->fdeTable->verticalHeader(); + verticalHeader->setSectionResizeMode(QHeaderView::Fixed); + verticalHeader->setDefaultSectionSize(20); +} + +CatalogSectorView::~CatalogSectorView() +{ + delete ui; +} + +void CatalogSectorView::setSector(Sector *sec) +{ + + m_sector = sec; + + if (sec) + { + auto cs = sec->asCatalogSector(); + + ui->csLabel->setText(QString("Catalog Sector at (%1/%2)") + .arg(sec->track()).arg(sec->sector())); + + auto table = ui->fdeTable; + for (int row = 0; row < 7; row++) + { + auto tsCell = table->item(row,0); + auto sizeCell = table->item(row,1); + auto typeCell = table->item(row,2); + auto nameCell = table->item(row,3); + + FileDescriptiveEntry fde = cs.makeFDE(row*0x23+0x0B); + + if (fde.deleted) + { + auto delstr = QString("Del (%1/%2)").arg((quint8) fde.filename[29]) + .arg(fde.firstTSListSector().sector()); + tsCell->setText(delstr); + } + else + { + auto tsstr = QString("%1/%2").arg(fde.firstTSListSector().track()) + .arg(fde.firstTSListSector().sector()); + tsCell->setText(tsstr); + } + + auto type = fde.fileTypeIdentifier(); + if (fde.isLocked()) { type += " Locked"; } + typeCell->setText(type); + + auto name = fde.filename; + if (fde.deleted) + { + name.truncate(29); + nameCell->setForeground(Qt::red); + nameCell->setText(name.appleFontPrintable()); + } + else + { + nameCell->setForeground(Qt::black); + nameCell->setText(name.appleFontPrintable()); + } + + auto size = fde.lengthInSectors; + sizeCell->setText(QString::number(size)); + } + + auto next = cs.nextCatalogSector(); + ui->nextCSLabel->setText( + QString("Next Catalog Sector: (%1/%2)") + .arg(next.track()).arg(next.sector())); + + } + else + { + ui->csLabel->setText("Catalog Sector"); + auto table = ui->fdeTable; + for (int row = 0; row < 7; row++) + { + for (int col = 0; col < 4; col++) + { + auto cell = table->item(row,col); + cell->setText(""); + + } + } + ui->nextCSLabel->setText(""); + } +} diff --git a/src/ui/diskexplorer/catalogsectorview.h b/src/ui/diskexplorer/catalogsectorview.h new file mode 100644 index 0000000..171bea3 --- /dev/null +++ b/src/ui/diskexplorer/catalogsectorview.h @@ -0,0 +1,28 @@ +#ifndef CATALOGSECTORVIEW_H +#define CATALOGSECTORVIEW_H + +#include + +class Sector; + +namespace Ui { +class CatalogSectorView; +} + +class CatalogSectorView : public QWidget +{ + Q_OBJECT + +public: + explicit CatalogSectorView(QWidget *parent = nullptr); + ~CatalogSectorView(); + + void setSector(Sector *sec); + +private: + Ui::CatalogSectorView *ui; + + Sector *m_sector; +}; + +#endif // CATALOGSECTORVIEW_H diff --git a/src/ui/diskexplorer/catalogsectorview.ui b/src/ui/diskexplorer/catalogsectorview.ui new file mode 100644 index 0000000..e57bd87 --- /dev/null +++ b/src/ui/diskexplorer/catalogsectorview.ui @@ -0,0 +1,194 @@ + + + CatalogSectorView + + + + 0 + 0 + 583 + 273 + + + + Catalog Sector + + + + + + Catalog Sector at (xx/yy) + + + + + + + Next Catalog Sector at (xx/yy) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + true + + + false + + + false + + + 7 + + + 4 + + + false + + + true + + + false + + + false + + + + FDE 1 + + + + + FDE 2 + + + + + FDE 3 + + + + + FDE 4 + + + + + FDE 5 + + + + + FDE 6 + + + + + FDE 7 + + + + + 1st Trk/Sec + + + + + # Sectors + + + + + Type/Lock + + + + + Filename + + + + + + + + + Print Char 21 + + + + + + + + + + Print Char 21 + + + + + + + + + + Print Char 21 + + + + + + + + + + Print Char 21 + + + + + + + + + + Print Char 21 + + + + + + + + + + Print Char 21 + + + + + + + + + + Print Char 21 + + + + + + + + + + diff --git a/src/ui/diskexplorer/tslistview.cpp b/src/ui/diskexplorer/tslistview.cpp new file mode 100644 index 0000000..8f1dfc8 --- /dev/null +++ b/src/ui/diskexplorer/tslistview.cpp @@ -0,0 +1,35 @@ +#include "tslistview.h" +#include "sector.h" + +TSListView::TSListView(QWidget *parent) : QTextBrowser(parent) +{ + +} + +void TSListView::setSector(Sector *sec) +{ + m_sector = sec; + if (sec) + { + QString text; + auto tslist = sec->asTrackSectorList(); + int count = 0; + text += QString("%1 T/S pair(s) (%3 valid) Next T/S List @ (%4/%5)\n\n") + .arg(tslist.getDataTSPairs().count()) + .arg(tslist.getValidTSPairs().count()) + .arg(tslist.getNextTSList().track()) + .arg(tslist.getNextTSList().sector()); + foreach(auto ts, tslist.getDataTSPairs()) + { + text += QString("T/S %1: (%2/%3)\n") + .arg(count++) + .arg(ts.track()) + .arg(ts.sector()); + } + setPlainText(text); + } + else + { + setText(""); + } +} diff --git a/src/ui/diskexplorer/tslistview.h b/src/ui/diskexplorer/tslistview.h new file mode 100644 index 0000000..8b839a0 --- /dev/null +++ b/src/ui/diskexplorer/tslistview.h @@ -0,0 +1,23 @@ +#ifndef TSLISTVIEW_H +#define TSLISTVIEW_H + +#include + +class Sector; + +class TSListView : public QTextBrowser +{ + Q_OBJECT +public: + explicit TSListView(QWidget *parent = nullptr); + + void setSector(Sector *sec); + +signals: + +private: + Sector *m_sector; + +}; + +#endif // TSLISTVIEW_H diff --git a/src/ui/diskexplorer/viewwidgetstack.cpp b/src/ui/diskexplorer/viewwidgetstack.cpp new file mode 100644 index 0000000..6fa8492 --- /dev/null +++ b/src/ui/diskexplorer/viewwidgetstack.cpp @@ -0,0 +1,61 @@ +#include "viewwidgetstack.h" +#include "hexdumpviewer.h" +#include "vtocview.h" +#include "catalogsectorview.h" +#include "tslistview.h" + +ViewWidgetStack::ViewWidgetStack(QWidget *parent) : QTabWidget(parent) +{ + makeWidgets(); + setSector(nullptr); +} + +void ViewWidgetStack::setSector(Sector *sec, PreferredViewer viewer) +{ + if (sec) + { + m_hdv->setRawData(*(sec->rawData())); + } + else + { + m_hdv->setRawData(QByteArray(),0); + } + m_cs_view->setSector(sec); + m_vtoc_view->setSector(sec); + m_tsl_view->setSector(sec); + + if (viewer == PreferredViewer::VTOC) + { + setCurrentWidget(m_vtoc_view); + } + else if (viewer == PreferredViewer::TSList) + { + setCurrentWidget(m_tsl_view); + } + else if (viewer == PreferredViewer::CatalogSector) + { + setCurrentWidget(m_cs_view); + } + else if (viewer == PreferredViewer::HexDump) + { + setCurrentWidget(m_hdv); + } + +} + +void ViewWidgetStack::makeWidgets() +{ + m_hdv = new HexDumpViewer(this,10); + addTab(m_hdv,"View Raw Data"); + + m_vtoc_view = new VTOCView(this); + addTab(m_vtoc_view,"View as VTOC"); + + m_cs_view = new CatalogSectorView(this); + addTab(m_cs_view,"View as Catalog"); + + m_tsl_view = new TSListView(this); + addTab(m_tsl_view,"View as T/S List"); + + setCurrentWidget(m_hdv); +} diff --git a/src/ui/diskexplorer/viewwidgetstack.h b/src/ui/diskexplorer/viewwidgetstack.h new file mode 100644 index 0000000..0f5b595 --- /dev/null +++ b/src/ui/diskexplorer/viewwidgetstack.h @@ -0,0 +1,41 @@ +#ifndef VIEWWIDGETSTACK_H +#define VIEWWIDGETSTACK_H + +#include + +class Sector; +class HexDumpViewer; +class VTOCView; +class CatalogSectorView; +class TSListView; + +class ViewWidgetStack : public QTabWidget +{ + Q_OBJECT + +public: + + enum class PreferredViewer { + DontCare = 0, + HexDump, + VTOC, + CatalogSector, + TSList + }; + + explicit ViewWidgetStack(QWidget *parent = nullptr); + +public slots: + void setSector(Sector *sec, PreferredViewer viewer = PreferredViewer::DontCare); + +private: + void makeWidgets(); + + HexDumpViewer *m_hdv; + VTOCView *m_vtoc_view; + CatalogSectorView *m_cs_view; + TSListView *m_tsl_view; + +}; + +#endif // VIEWWIDGETSTACK_H diff --git a/src/ui/diskexplorer/vtocview.cpp b/src/ui/diskexplorer/vtocview.cpp new file mode 100644 index 0000000..c485e27 --- /dev/null +++ b/src/ui/diskexplorer/vtocview.cpp @@ -0,0 +1,104 @@ +#include "vtocview.h" +#include "ui_vtocview.h" +#include "sector.h" + +VTOCView::VTOCView(QWidget *parent) : + QWidget(parent), + ui(new Ui::VTOCView) +{ + ui->setupUi(this); +} + +VTOCView::~VTOCView() +{ + delete ui; +} +void VTOCView::setSector(Sector *sec) +{ + m_sector = sec; + + if (sec) + { + ui->m_mainLabel->setText( + QString("VTOC interpretation of T/S (%1/%2)") + .arg(sec->track()).arg(sec->sector())); + auto v = sec->promoteToVTOC(); + auto ts = v.firstCatalogSector(); + ui->m_1stCatLabel->setText(QString("%1/%2").arg(ts.track()).arg(ts.sector())); + + ui->m_dosVersionLabel->setText(QString("%1").arg(v.dosVersion())); + + ui->m_volumeLabel->setText(QString("%1").arg(v.volumeNumber())); + + ui->m_tsPairCountLabel->setText(QString("%1").arg(v.maxTSPairs())); + + ui->m_lastAllocTrackLabel->setText(QString("%1").arg(v.lastTrackAllocated())); + + ui->m_allocDirLabel->setText(QString("%1").arg(v.directionOfAllocation())); + + ui->m_tracksPerDiskLabel->setText(QString("%1").arg(v.tracksPerDisk())); + + ui->m_sectorsPerTrackLabel->setText(QString("%1").arg(v.sectorsPerTrack())); + + ui->m_bytesPerSectorLabel->setText(QString("%1").arg(v.bytesPerSector())); + + QString usage; + usage += " "; + for (int x = 0; x < v.tracksPerDisk(); x++) + { + usage += QString::number(x/10); + usage += " "; + } + usage += "\n"; + usage += " "; + + for (int x = 0; x < v.tracksPerDisk(); x++) + { + usage += QString::number(x%10); + usage += " "; + } + usage += "\n\n" ; + for (int y = 0; ym_usageTextBrowser->setText(""); + ui->m_usageTextBrowser->setWordWrapMode(QTextOption::NoWrap); + auto format = ui->m_usageTextBrowser->currentCharFormat(); + format.setFont(QFont("courier new",6)); + ui->m_usageTextBrowser->setCurrentCharFormat(format); + ui->m_usageTextBrowser->insertPlainText(usage); + + } + else + { + ui->m_mainLabel->setText("VTOC"); + ui->m_1stCatLabel->setText("--"); + ui->m_bytesPerSectorLabel->setText("--"); + ui->m_dosVersionLabel->setText("--"); + ui->m_lastAllocTrackLabel->setText("--");; + ui->m_sectorsPerTrackLabel->setText("--");; + ui->m_tracksPerDiskLabel->setText("--");; + ui->m_tsPairCountLabel->setText("--");; + ui->m_volumeLabel->setText("--"); + ui->m_allocDirLabel->setText("--"); + + ui->m_usageTextBrowser->setText(" No Sector is Selected"); + + } + + + +} + +QString VTOCView::makeUsage() +{ +return QString(); +} diff --git a/src/ui/diskexplorer/vtocview.h b/src/ui/diskexplorer/vtocview.h new file mode 100644 index 0000000..c0fe585 --- /dev/null +++ b/src/ui/diskexplorer/vtocview.h @@ -0,0 +1,31 @@ +#ifndef VTOCVIEW_H +#define VTOCVIEW_H + +#include + +class Sector; + +namespace Ui { +class VTOCView; +} + +class VTOCView : public QWidget +{ + Q_OBJECT + +public: + explicit VTOCView(QWidget *parent = nullptr); + ~VTOCView(); + + void setSector(Sector *sec); + +protected: + QString makeUsage(); + +private: + Ui::VTOCView *ui; + Sector *m_sector; + +}; + +#endif // VTOCVIEW_H diff --git a/src/ui/diskexplorer/vtocview.ui b/src/ui/diskexplorer/vtocview.ui new file mode 100644 index 0000000..78b24a5 --- /dev/null +++ b/src/ui/diskexplorer/vtocview.ui @@ -0,0 +1,200 @@ + + + VTOCView + + + + 0 + 0 + 560 + 300 + + + + VTOC View + + + + + + Qt::Horizontal + + + + + + + 1st Catalog T/S + + + + + + + -- + + + + + + + Dos Version + + + + + + + -- + + + + + + + Volume # + + + + + + + -- + + + + + + + T/S Pairs per T/S List + + + + + + + -- + + + + + + + Last Alloc'd Track + + + + + + + -- + + + + + + + Tracks/Disk + + + + + + + -- + + + + + + + Sectors/Track + + + + + + + -- + + + + + + + Bytes/Sector + + + + + + + -- + + + + + + + Direction of Alloc. + + + + + + + -- + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Reported Track Usage + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + + + + + + + VTOC + + + + + + + +