ciderpress/app/ArchiveInfoDialog.cpp
Andy McFadden d8223dbcfd Relocate method comments
This moves method comments from the .cpp file to the .h file,
where users of the methods can find them.  This also makes it
possible for the IDE to show the comments when you mouse-hover over
the method name, though Visual Studio is a bit weak in this regard.

Also, added "override" keywords on overridden methods.  Reasonably
current versions of popular compilers seem to support this.

Also, don't have the return type on a separate line in the .cpp file.
The motivation for the practice -- quickly finding a method definition
with "^name" -- is less useful in C++ than C, and modern IDEs provide
more convenient ways to do the same thing.

Also, do some more conversion from unsigned types to uintXX_t.

This commit is primarily for the "app" directory.
2014-11-21 22:33:39 -08:00

404 lines
13 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 "../nufxlib/NufxLib.h"
/*
* ===========================================================================
* ArchiveInfoDialog
* ===========================================================================
*/
BEGIN_MESSAGE_MAP(ArchiveInfoDialog, CDialog)
ON_COMMAND(IDHELP, OnHelp)
END_MESSAGE_MAP()
void ArchiveInfoDialog::OnHelp(void)
{
WinHelp(HELP_TOPIC_ARCHIVE_INFO, HELP_CONTEXT);
}
/*
* ===========================================================================
* NufxArchiveInfoDialog
* ===========================================================================
*/
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 != NULL);
pNuArchive = fpArchive->GetNuArchivePointer();
ASSERT(pNuArchive != NULL);
(void) NuGetMasterHeader(pNuArchive, &pMasterHeader);
ASSERT(pMasterHeader != NULL);
pWnd = GetDlgItem(IDC_AI_FILENAME);
CString pathName(fpArchive->GetPathName());
pWnd->SetWindowText(pathName);
pWnd = GetDlgItem(IDC_AINUFX_RECORDS);
nerr = NuGetAttr(pNuArchive, kNuAttrNumRecords, &attr);
if (nerr == kNuErrNone)
tmpStr.Format(L"%ld", attr);
else
tmpStr = notAvailable;
pWnd->SetWindowText(tmpStr);
pWnd = GetDlgItem(IDC_AINUFX_FORMAT);
nerr = NuGetAttr(pNuArchive, kNuAttrArchiveType, &attr);
switch (attr) {
case kNuArchiveNuFX: tmpStr = L"NuFX"; break;
case kNuArchiveNuFXInBNY: tmpStr = L"NuFX in Binary II"; break;
case kNuArchiveNuFXSelfEx: tmpStr = L"Self-extracting NuFX"; break;
case kNuArchiveNuFXSelfExInBNY: tmpStr = L"Self-extracting NuFX in Binary II";
break;
case kNuArchiveBNY: tmpStr = L"Binary II"; break;
default:
tmpStr = L"(unknown)";
break;
};
pWnd->SetWindowText(tmpStr);
pWnd = GetDlgItem(IDC_AINUFX_MASTERVERSION);
tmpStr.Format(L"%ld", pMasterHeader->mhMasterVersion);
pWnd->SetWindowText(tmpStr);
pWnd = GetDlgItem(IDC_AINUFX_CREATEWHEN);
when = NufxArchive::DateTimeToSeconds(&pMasterHeader->mhArchiveCreateWhen);
tmpStr.Format(L"%.24hs", ctime(&when));
pWnd->SetWindowText(tmpStr);
pWnd = GetDlgItem(IDC_AINUFX_MODIFYWHEN);
when = NufxArchive::DateTimeToSeconds(&pMasterHeader->mhArchiveModWhen);
tmpStr.Format(L"%.24hs", ctime(&when));
pWnd->SetWindowText(tmpStr);
pWnd = GetDlgItem(IDC_AINUFX_JUNKSKIPPED);
nerr = NuGetAttr(pNuArchive, kNuAttrJunkOffset, &attr);
if (nerr == kNuErrNone)
tmpStr.Format(L"%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()
BOOL DiskArchiveInfoDialog::OnInitDialog(void)
{
CWnd* pWnd;
CString tmpStr;
const DiskImg* pDiskImg;
const DiskFS* pDiskFS;
ASSERT(fpArchive != NULL);
pDiskImg = fpArchive->GetDiskImg();
ASSERT(pDiskImg != NULL);
pDiskFS = fpArchive->GetDiskFS();
ASSERT(pDiskFS != NULL);
/*
* Volume characteristics.
*/
pWnd = GetDlgItem(IDC_AI_FILENAME);
pWnd->SetWindowText(fpArchive->GetPathName());
pWnd = GetDlgItem(IDC_AIDISK_OUTERFORMAT);
CStringW outerFormat(DiskImg::ToString(pDiskImg->GetOuterFormat()));
pWnd->SetWindowText(outerFormat);
pWnd = GetDlgItem(IDC_AIDISK_FILEFORMAT);
CStringW fileFormat(DiskImg::ToString(pDiskImg->GetFileFormat()));
pWnd->SetWindowText(fileFormat);
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 != NULL)
tmpStr.Format(L"%hs, layout is \"%hs\"",
DiskImg::ToString(physicalFormat), pNibbleDescr->description);
else
tmpStr = DiskImg::ToString(physicalFormat); // unexpected
pWnd->SetWindowText(tmpStr);
} else {
CString physicalFormat(DiskImg::ToString(physicalFormat));
pWnd->SetWindowText(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, L"", &idx);
ASSERT(idx > 0); // must have at least the top-level DiskFS
pCombo->SetCurSel(0);
if (idx == 1)
pCombo->EnableWindow(FALSE);
return ArchiveInfoDialog::OnInitDialog();
}
void DiskArchiveInfoDialog::AddSubVolumes(const DiskFS* pDiskFS,
const WCHAR* 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(NULL);
tmpStr = prefix;
tmpStr += L" ";
while (pSubVol != NULL) {
AddSubVolumes(pSubVol->GetDiskFS(), tmpStr, pIdx);
pSubVol = pDiskFS->GetNextSubVolume(pSubVol);
}
}
void DiskArchiveInfoDialog::OnSubVolSelChange(void)
{
CComboBox* pCombo = (CComboBox*) GetDlgItem(IDC_AIDISK_SUBVOLSEL);
ASSERT(pCombo != NULL);
//LOGI("+++ SELECTION IS NOW %d", pCombo->GetCurSel());
const DiskFS* pDiskFS;
pDiskFS = (DiskFS*) pCombo->GetItemData(pCombo->GetCurSel());
ASSERT(pDiskFS != NULL);
FillInVolumeInfo(pDiskFS);
}
void DiskArchiveInfoDialog::FillInVolumeInfo(const DiskFS* pDiskFS)
{
const DiskImg* pDiskImg = pDiskFS->GetDiskImg();
CString unknown = L"(unknown)";
CString tmpStr;
DIError dierr;
CWnd* pWnd;
pWnd = GetDlgItem(IDC_AIDISK_SECTORORDER);
CStringW sectorOrderW(DiskImg::ToString(pDiskImg->GetSectorOrder()));
pWnd->SetWindowText(sectorOrderW);
pWnd = GetDlgItem(IDC_AIDISK_FSFORMAT);
CStringW fsFormat(DiskImg::ToString(pDiskImg->GetFSFormat()));
pWnd->SetWindowText(fsFormat);
pWnd = GetDlgItem(IDC_AIDISK_FILECOUNT);
tmpStr.Format(L"%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(L"%ld blocks (%ls)",
totalUnits, (LPCWSTR) reducedSize);
if (totalUnits != pDiskImg->GetNumBlocks()) {
CString tmpStr2;
tmpStr2.Format(L", image has room for %ld blocks",
pDiskImg->GetNumBlocks());
tmpStr += tmpStr2;
}
pWnd->SetWindowText(tmpStr);
pWnd = GetDlgItem(IDC_AIDISK_FREESPACE);
GetReducedSize(freeUnits, unitSize, &reducedSize);
tmpStr.Format(L"%ld blocks (%ls)",
freeUnits, (LPCWSTR) reducedSize);
pWnd->SetWindowText(tmpStr);
} else {
ASSERT(unitSize == DiskImgLib::kSectorSize);
pWnd = GetDlgItem(IDC_AIDISK_CAPACITY);
GetReducedSize(totalUnits, unitSize, &reducedSize);
tmpStr.Format(L"%ld sectors (%ls)",
totalUnits, (LPCWSTR) reducedSize);
pWnd->SetWindowText(tmpStr);
pWnd = GetDlgItem(IDC_AIDISK_FREESPACE);
GetReducedSize(freeUnits, unitSize, &reducedSize);
tmpStr.Format(L"%ld sectors (%ls)",
freeUnits, (LPCWSTR) 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(L"%ld blocks (%ls)",
totalUnits, (LPCWSTR) reducedSize);
} else if (pDiskImg->GetHasSectors()) {
tmpStr.Format(L"%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() ? L"Yes" : L"No";
pWnd->SetWindowText(tmpStr);
pWnd = GetDlgItem(IDC_AIDISK_DAMAGED);
tmpStr = pDiskFS->GetFSDamaged() ? L"Yes" : L"No";
pWnd->SetWindowText(tmpStr);
const char* cp;
WCHAR* outp;
pWnd = GetDlgItem(IDC_AIDISK_NOTES);
cp = pDiskImg->GetNotes();
// GetBuffer wants length in code units, which will be 2x since it's
// wide chars. The 2x mult below is for worst-case linefeed conversion.
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);
}
void DiskArchiveInfoDialog::GetReducedSize(long numUnits, int unitSize,
CString* pOut) const
{
LONGLONG sizeInBytes = numUnits;
sizeInBytes *= unitSize;
long reducedSize;
if (sizeInBytes < 0) {
ASSERT(false);
pOut->Format(L"<bogus>");
return;
}
if (sizeInBytes >= 1024*1024*1024) {
reducedSize = (long) (sizeInBytes / (1024*1024));
pOut->Format(L"%.2fGB", reducedSize / 1024.0);
} else if (sizeInBytes >= 1024*1024) {
reducedSize = (long) (sizeInBytes / 1024);
pOut->Format(L"%.2fMB", reducedSize / 1024.0);
} else {
pOut->Format(L"%.2fKB", ((long) sizeInBytes) / 1024.0);
}
}
/*
* ===========================================================================
* BnyArchiveInfoDialog
* ===========================================================================
*/
BOOL BnyArchiveInfoDialog::OnInitDialog(void)
{
CWnd* pWnd;
CString tmpStr;
ASSERT(fpArchive != NULL);
pWnd = GetDlgItem(IDC_AI_FILENAME);
pWnd->SetWindowText(fpArchive->GetPathName());
tmpStr.Format(L"%ld", fpArchive->GetNumEntries());
pWnd = GetDlgItem(IDC_AIBNY_RECORDS);
pWnd->SetWindowText(tmpStr);
return ArchiveInfoDialog::OnInitDialog();
}
/*
* ===========================================================================
* AcuArchiveInfoDialog
* ===========================================================================
*/
BOOL AcuArchiveInfoDialog::OnInitDialog(void)
{
CWnd* pWnd;
CString tmpStr;
ASSERT(fpArchive != NULL);
pWnd = GetDlgItem(IDC_AI_FILENAME);
pWnd->SetWindowText(fpArchive->GetPathName());
tmpStr.Format(L"%ld", fpArchive->GetNumEntries());
pWnd = GetDlgItem(IDC_AIBNY_RECORDS);
pWnd->SetWindowText(tmpStr);
return ArchiveInfoDialog::OnInitDialog();
}