ciderpress/app/ArchiveInfoDialog.cpp

434 lines
12 KiB
C++
Raw Normal View History

2007-03-27 17:47:10 +00:00
/*
* 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();
}