mirror of
https://github.com/fadden/ciderpress.git
synced 2024-12-22 05:29:43 +00:00
434 lines
12 KiB
C++
434 lines
12 KiB
C++
/*
|
|
* CiderPress
|
|
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
|
* See the file LICENSE for distribution terms.
|
|
*/
|
|
/*
|
|
* Implementation of the various ArchiveInfo dialog classes.
|
|
*/
|
|
#include "StdAfx.h"
|
|
#include "HelpTopics.h"
|
|
#include "ArchiveInfoDialog.h"
|
|
#include "../prebuilt/NufxLib.h"
|
|
|
|
/*
|
|
* ===========================================================================
|
|
* ArchiveInfoDialog
|
|
* ===========================================================================
|
|
*/
|
|
|
|
BEGIN_MESSAGE_MAP(ArchiveInfoDialog, CDialog)
|
|
ON_COMMAND(IDHELP, OnHelp)
|
|
END_MESSAGE_MAP()
|
|
|
|
/*
|
|
* Show general help for the archive info dialogs.
|
|
*/
|
|
void
|
|
ArchiveInfoDialog::OnHelp(void)
|
|
{
|
|
WinHelp(HELP_TOPIC_ARCHIVE_INFO, HELP_CONTEXT);
|
|
}
|
|
|
|
|
|
/*
|
|
* ===========================================================================
|
|
* NufxArchiveInfoDialog
|
|
* ===========================================================================
|
|
*/
|
|
|
|
/*
|
|
* Set up fields with NuFX archive info.
|
|
*/
|
|
BOOL
|
|
NufxArchiveInfoDialog::OnInitDialog(void)
|
|
{
|
|
CString notAvailable = "(not available)";
|
|
NuArchive* pNuArchive;
|
|
const NuMasterHeader* pMasterHeader;
|
|
CWnd* pWnd;
|
|
CString tmpStr;
|
|
NuAttr attr;
|
|
NuError nerr;
|
|
time_t when;
|
|
|
|
ASSERT(fpArchive != nil);
|
|
|
|
pNuArchive = fpArchive->GetNuArchivePointer();
|
|
ASSERT(pNuArchive != nil);
|
|
(void) NuGetMasterHeader(pNuArchive, &pMasterHeader);
|
|
ASSERT(pMasterHeader != nil);
|
|
|
|
pWnd = GetDlgItem(IDC_AI_FILENAME);
|
|
pWnd->SetWindowText(fpArchive->GetPathName());
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_RECORDS);
|
|
nerr = NuGetAttr(pNuArchive, kNuAttrNumRecords, &attr);
|
|
if (nerr == kNuErrNone)
|
|
tmpStr.Format("%ld", attr);
|
|
else
|
|
tmpStr = notAvailable;
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_FORMAT);
|
|
nerr = NuGetAttr(pNuArchive, kNuAttrArchiveType, &attr);
|
|
switch (attr) {
|
|
case kNuArchiveNuFX: tmpStr = "NuFX"; break;
|
|
case kNuArchiveNuFXInBNY: tmpStr = "NuFX in Binary II"; break;
|
|
case kNuArchiveNuFXSelfEx: tmpStr = "Self-extracting NuFX"; break;
|
|
case kNuArchiveNuFXSelfExInBNY: tmpStr = "Self-extracting NuFX in Binary II";
|
|
break;
|
|
case kNuArchiveBNY: tmpStr = "Binary II"; break;
|
|
default:
|
|
tmpStr = "(unknown)";
|
|
break;
|
|
};
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_MASTERVERSION);
|
|
tmpStr.Format("%ld", pMasterHeader->mhMasterVersion);
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_CREATEWHEN);
|
|
when = NufxArchive::DateTimeToSeconds(&pMasterHeader->mhArchiveCreateWhen);
|
|
tmpStr.Format("%.24s", ctime(&when));
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_MODIFYWHEN);
|
|
when = NufxArchive::DateTimeToSeconds(&pMasterHeader->mhArchiveModWhen);
|
|
tmpStr.Format("%.24s", ctime(&when));
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_JUNKSKIPPED);
|
|
nerr = NuGetAttr(pNuArchive, kNuAttrJunkOffset, &attr);
|
|
if (nerr == kNuErrNone)
|
|
tmpStr.Format("%ld bytes", attr);
|
|
else
|
|
tmpStr = notAvailable;
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
return ArchiveInfoDialog::OnInitDialog();
|
|
}
|
|
|
|
|
|
/*
|
|
* ===========================================================================
|
|
* DiskArchiveInfoDialog
|
|
* ===========================================================================
|
|
*/
|
|
|
|
BEGIN_MESSAGE_MAP(DiskArchiveInfoDialog, ArchiveInfoDialog)
|
|
ON_CBN_SELCHANGE(IDC_AIDISK_SUBVOLSEL, OnSubVolSelChange)
|
|
END_MESSAGE_MAP()
|
|
|
|
/*
|
|
* Set up fields with disk archive info.
|
|
*/
|
|
BOOL
|
|
DiskArchiveInfoDialog::OnInitDialog(void)
|
|
{
|
|
CWnd* pWnd;
|
|
CString tmpStr;
|
|
const DiskImg* pDiskImg;
|
|
const DiskFS* pDiskFS;
|
|
|
|
ASSERT(fpArchive != nil);
|
|
|
|
pDiskImg = fpArchive->GetDiskImg();
|
|
ASSERT(pDiskImg != nil);
|
|
pDiskFS = fpArchive->GetDiskFS();
|
|
ASSERT(pDiskFS != nil);
|
|
|
|
/*
|
|
* Volume characteristics.
|
|
*/
|
|
pWnd = GetDlgItem(IDC_AI_FILENAME);
|
|
pWnd->SetWindowText(fpArchive->GetPathName());
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_OUTERFORMAT);
|
|
pWnd->SetWindowText(DiskImg::ToString(pDiskImg->GetOuterFormat()));
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FILEFORMAT);
|
|
pWnd->SetWindowText(DiskImg::ToString(pDiskImg->GetFileFormat()));
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_PHYSICALFORMAT);
|
|
DiskImg::PhysicalFormat physicalFormat = pDiskImg->GetPhysicalFormat();
|
|
if (physicalFormat == DiskImg::kPhysicalFormatNib525_6656 ||
|
|
physicalFormat == DiskImg::kPhysicalFormatNib525_6384 ||
|
|
physicalFormat == DiskImg::kPhysicalFormatNib525_Var)
|
|
{
|
|
CString tmpStr;
|
|
const DiskImg::NibbleDescr* pNibbleDescr = pDiskImg->GetNibbleDescr();
|
|
if (pNibbleDescr != nil)
|
|
tmpStr.Format("%s, layout is \"%s\"",
|
|
DiskImg::ToString(physicalFormat), pNibbleDescr->description);
|
|
else
|
|
tmpStr = DiskImg::ToString(physicalFormat); // unexpected
|
|
pWnd->SetWindowText(tmpStr);
|
|
} else {
|
|
pWnd->SetWindowText(DiskImg::ToString(physicalFormat));
|
|
}
|
|
|
|
FillInVolumeInfo(pDiskFS);
|
|
|
|
/*
|
|
* Configure the sub-volume drop down menu. If there's only one item,
|
|
* we disable it.
|
|
*/
|
|
CComboBox* pCombo = (CComboBox*) GetDlgItem(IDC_AIDISK_SUBVOLSEL);
|
|
int idx = 0;
|
|
|
|
AddSubVolumes(pDiskFS, "", &idx);
|
|
ASSERT(idx > 0); // must have at least the top-level DiskFS
|
|
|
|
pCombo->SetCurSel(0);
|
|
if (idx == 1)
|
|
pCombo->EnableWindow(FALSE);
|
|
|
|
return ArchiveInfoDialog::OnInitDialog();
|
|
}
|
|
|
|
/*
|
|
* Recursively add sub-volumes to the list.
|
|
*/
|
|
void
|
|
DiskArchiveInfoDialog::AddSubVolumes(const DiskFS* pDiskFS, const char* prefix,
|
|
int* pIdx)
|
|
{
|
|
CComboBox* pCombo = (CComboBox*) GetDlgItem(IDC_AIDISK_SUBVOLSEL);
|
|
CString tmpStr;
|
|
|
|
/*
|
|
* Add the current DiskFS.
|
|
*/
|
|
tmpStr = prefix;
|
|
tmpStr += pDiskFS->GetVolumeID();
|
|
pCombo->AddString(tmpStr);
|
|
pCombo->SetItemData(*pIdx, (unsigned long) pDiskFS);
|
|
(*pIdx)++;
|
|
|
|
/*
|
|
* Add everything beneath the current level.
|
|
*/
|
|
DiskFS::SubVolume* pSubVol;
|
|
pSubVol = pDiskFS->GetNextSubVolume(nil);
|
|
tmpStr = prefix;
|
|
tmpStr += " ";
|
|
while (pSubVol != nil) {
|
|
AddSubVolumes(pSubVol->GetDiskFS(), tmpStr, pIdx);
|
|
|
|
pSubVol = pDiskFS->GetNextSubVolume(pSubVol);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* The user has changed their selection in the sub-volume pulldown menu.
|
|
*/
|
|
void
|
|
DiskArchiveInfoDialog::OnSubVolSelChange(void)
|
|
{
|
|
CComboBox* pCombo = (CComboBox*) GetDlgItem(IDC_AIDISK_SUBVOLSEL);
|
|
ASSERT(pCombo != nil);
|
|
//WMSG1("+++ SELECTION IS NOW %d\n", pCombo->GetCurSel());
|
|
|
|
const DiskFS* pDiskFS;
|
|
pDiskFS = (DiskFS*) pCombo->GetItemData(pCombo->GetCurSel());
|
|
ASSERT(pDiskFS != nil);
|
|
FillInVolumeInfo(pDiskFS);
|
|
}
|
|
|
|
/*
|
|
* Fill in the volume-specific info fields.
|
|
*/
|
|
void
|
|
DiskArchiveInfoDialog::FillInVolumeInfo(const DiskFS* pDiskFS)
|
|
{
|
|
const DiskImg* pDiskImg = pDiskFS->GetDiskImg();
|
|
CString unknown = "(unknown)";
|
|
CString tmpStr;
|
|
DIError dierr;
|
|
CWnd* pWnd;
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_SECTORORDER);
|
|
pWnd->SetWindowText(DiskImg::ToString(pDiskImg->GetSectorOrder()));
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FSFORMAT);
|
|
pWnd->SetWindowText(DiskImg::ToString(pDiskImg->GetFSFormat()));
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FILECOUNT);
|
|
tmpStr.Format("%ld", pDiskFS->GetFileCount());
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
long totalUnits, freeUnits;
|
|
int unitSize;
|
|
CString reducedSize;
|
|
|
|
dierr = pDiskFS->GetFreeSpaceCount(&totalUnits, &freeUnits, &unitSize);
|
|
if (dierr == kDIErrNone) {
|
|
|
|
/* got the space; break it down by disk type */
|
|
if (unitSize == DiskImgLib::kBlockSize) {
|
|
pWnd = GetDlgItem(IDC_AIDISK_CAPACITY);
|
|
GetReducedSize(totalUnits, unitSize, &reducedSize);
|
|
tmpStr.Format("%ld blocks (%s)",
|
|
totalUnits, reducedSize);
|
|
if (totalUnits != pDiskImg->GetNumBlocks()) {
|
|
CString tmpStr2;
|
|
tmpStr2.Format(", image has room for %ld blocks",
|
|
pDiskImg->GetNumBlocks());
|
|
tmpStr += tmpStr2;
|
|
}
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FREESPACE);
|
|
GetReducedSize(freeUnits, unitSize, &reducedSize);
|
|
tmpStr.Format("%ld blocks (%s)",
|
|
freeUnits, reducedSize);
|
|
pWnd->SetWindowText(tmpStr);
|
|
} else {
|
|
ASSERT(unitSize == DiskImgLib::kSectorSize);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_CAPACITY);
|
|
GetReducedSize(totalUnits, unitSize, &reducedSize);
|
|
tmpStr.Format("%ld sectors (%s)",
|
|
totalUnits, reducedSize);
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FREESPACE);
|
|
GetReducedSize(freeUnits, unitSize, &reducedSize);
|
|
tmpStr.Format("%ld sectors (%s)",
|
|
freeUnits, reducedSize);
|
|
pWnd->SetWindowText(tmpStr);
|
|
}
|
|
} else {
|
|
/* "free space" not supported; fill in what we do know */
|
|
pWnd = GetDlgItem(IDC_AIDISK_CAPACITY);
|
|
if (pDiskImg->GetHasBlocks()) {
|
|
totalUnits = pDiskImg->GetNumBlocks();
|
|
GetReducedSize(totalUnits, DiskImgLib::kBlockSize, &reducedSize);
|
|
tmpStr.Format("%ld blocks (%s)",
|
|
totalUnits, reducedSize);
|
|
} else if (pDiskImg->GetHasSectors()) {
|
|
tmpStr.Format("%ld tracks, %d sectors per track",
|
|
pDiskImg->GetNumTracks(), pDiskImg->GetNumSectPerTrack());
|
|
} else {
|
|
tmpStr = unknown;
|
|
}
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FREESPACE);
|
|
pWnd->SetWindowText(unknown);
|
|
}
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_WRITEABLE);
|
|
tmpStr = pDiskFS->GetReadWriteSupported() ? "Yes" : "No";
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_DAMAGED);
|
|
tmpStr = pDiskFS->GetFSDamaged() ? "Yes" : "No";
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
const char* cp;
|
|
char* outp;
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_NOTES);
|
|
cp = pDiskImg->GetNotes();
|
|
outp = tmpStr.GetBuffer(strlen(cp) * 2 +1);
|
|
/* convert '\n' to '\r\n' */
|
|
while (*cp != '\0') {
|
|
if (*cp == '\n')
|
|
*outp++ = '\r';
|
|
*outp++ = *cp++;
|
|
}
|
|
*outp = '\0';
|
|
tmpStr.ReleaseBuffer();
|
|
/* drop the trailing linefeed */
|
|
if (!tmpStr.IsEmpty() && tmpStr.GetAt(tmpStr.GetLength()-1) == '\n')
|
|
tmpStr.TrimRight(); // trim the whitespace chars off
|
|
pWnd->SetWindowText(tmpStr);
|
|
}
|
|
|
|
/*
|
|
* Reduce a size to something meaningful (KB, MB, GB).
|
|
*/
|
|
void
|
|
DiskArchiveInfoDialog::GetReducedSize(long numUnits, int unitSize,
|
|
CString* pOut) const
|
|
{
|
|
LONGLONG sizeInBytes = numUnits;
|
|
sizeInBytes *= unitSize;
|
|
long reducedSize;
|
|
|
|
if (sizeInBytes < 0) {
|
|
ASSERT(false);
|
|
pOut->Format("<bogus>");
|
|
return;
|
|
}
|
|
|
|
if (sizeInBytes >= 1024*1024*1024) {
|
|
reducedSize = (long) (sizeInBytes / (1024*1024));
|
|
pOut->Format("%.2fGB", reducedSize / 1024.0);
|
|
} else if (sizeInBytes >= 1024*1024) {
|
|
reducedSize = (long) (sizeInBytes / 1024);
|
|
pOut->Format("%.2fMB", reducedSize / 1024.0);
|
|
} else {
|
|
pOut->Format("%.2fKB", ((long) sizeInBytes) / 1024.0);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ===========================================================================
|
|
* BnyArchiveInfoDialog
|
|
* ===========================================================================
|
|
*/
|
|
|
|
/*
|
|
* Set up fields with Binary II info.
|
|
*
|
|
* Binary II files are pretty dull.
|
|
*/
|
|
BOOL
|
|
BnyArchiveInfoDialog::OnInitDialog(void)
|
|
{
|
|
CWnd* pWnd;
|
|
CString tmpStr;
|
|
|
|
ASSERT(fpArchive != nil);
|
|
|
|
pWnd = GetDlgItem(IDC_AI_FILENAME);
|
|
pWnd->SetWindowText(fpArchive->GetPathName());
|
|
tmpStr.Format("%ld", fpArchive->GetNumEntries());
|
|
pWnd = GetDlgItem(IDC_AIBNY_RECORDS);
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
return ArchiveInfoDialog::OnInitDialog();
|
|
}
|
|
|
|
|
|
/*
|
|
* ===========================================================================
|
|
* AcuArchiveInfoDialog
|
|
* ===========================================================================
|
|
*/
|
|
|
|
/*
|
|
* Set up fields with ACU info.
|
|
*/
|
|
BOOL
|
|
AcuArchiveInfoDialog::OnInitDialog(void)
|
|
{
|
|
CWnd* pWnd;
|
|
CString tmpStr;
|
|
|
|
ASSERT(fpArchive != nil);
|
|
|
|
pWnd = GetDlgItem(IDC_AI_FILENAME);
|
|
pWnd->SetWindowText(fpArchive->GetPathName());
|
|
tmpStr.Format("%ld", fpArchive->GetNumEntries());
|
|
pWnd = GetDlgItem(IDC_AIBNY_RECORDS);
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
return ArchiveInfoDialog::OnInitDialog();
|
|
}
|