ciderpress/app/PrefsDialog.cpp
Andy McFadden 4638d03d6c Shift responsibility for file associations to the installer
In the past, CiderPress managed its own file associations.  This is
the feature that launches CiderPress when you double-click on a ".shk"
file.  The installer ran "CiderPress -install" and "-uninstall" during
installation and removal to give CP a chance to establish and clean
up the necessary registry entries.

The code built with VS6 works fine.  The code built with VS2013 fails
with an access denied error.  It appears there have been some access
policy changes, and the older code is getting "grandfathered in".  This
is really something that the installer ought to be handling, though,
so rather than figure out how to fix CiderPress, I'm removing the
file type association code from CiderPress and letting DeployMaster
handle it.

This may be slightly less convenient for anyone who had reason to
change type associations frequently.  Modern versions of Windows have
relatively easy to use control panel UIs for adjusting types, and
the "advanced installation" feature of DeployMaster allows you to
un-check the types that you don't want to have associated with
CiderPress.

(...with one minor hitch: DeployMaster 4.2.2 only shows the first 9
associations, and CiderPress has 18.)

This change renders most of the registry-handling code obsolete, as
well as the "-install" / "-uninstall" handling.  I'm 99% sure I want
to go this way, but I'm keeping things #ifdefed rather than deleted
for the moment.
2014-12-11 14:22:39 -08:00

512 lines
16 KiB
C++

/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
#include "stdafx.h"
#include "PrefsDialog.h"
#include "ChooseDirDialog.h"
#ifdef CAN_UPDATE_FILE_ASSOC
#include "EditAssocDialog.h"
#endif
#include "Main.h"
#include "NufxArchive.h"
#include "resource.h"
#include <afxpriv.h> // need WM_COMMANDHELP
/*
* ===========================================================================
* PrefsGeneralPage
* ===========================================================================
*/
BEGIN_MESSAGE_MAP(PrefsGeneralPage, CPropertyPage)
ON_CONTROL_RANGE(BN_CLICKED, IDC_COL_PATHNAME, IDC_COL_ACCESS, OnChangeRange)
ON_BN_CLICKED(IDC_PREF_SHRINKIT_COMPAT, OnChange)
ON_BN_CLICKED(IDC_PREF_REDUCE_SHK_ERROR_CHECKS, OnChange)
ON_BN_CLICKED(IDC_PREF_SHK_BAD_MAC, OnChange)
ON_BN_CLICKED(IDC_PREF_COERCE_DOS, OnChange)
ON_BN_CLICKED(IDC_PREF_SPACES_TO_UNDER, OnChange)
ON_BN_CLICKED(IDC_PREF_PASTE_JUNKPATHS, OnChange)
ON_BN_CLICKED(IDC_PREF_SUCCESS_BEEP, OnChange)
ON_BN_CLICKED(IDC_COL_DEFAULTS, OnDefaults)
#ifdef CAN_UPDATE_FILE_ASSOC
ON_BN_CLICKED(IDC_PREF_ASSOCIATIONS, OnAssociations)
#endif
ON_MESSAGE(WM_HELP, OnHelpInfo)
ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
END_MESSAGE_MAP()
void PrefsGeneralPage::OnChange(void)
{
/*
* They clicked on a checkbox, just mark the page as dirty so the "apply"
* button will be enabled.
*/
SetModified(TRUE);
}
void PrefsGeneralPage::OnChangeRange(UINT nID)
{
SetModified(TRUE);
}
void PrefsGeneralPage::OnDefaults(void)
{
/*
* Since we don't actually set column widths here, we need to tell the main
* window that the defaults button was pushed. It needs to reset all column
* widths to defaults, and then take into account any checking and un-checking
* that was done after "defaults" was pushed.
*/
LOGD("OnDefaults");
CButton* pButton;
fDefaultsPushed = true;
ASSERT(IDC_COL_ACCESS == IDC_COL_PATHNAME + (kNumVisibleColumns-1));
/* assumes that the controls are numbered sequentially */
for (int i = 0; i < kNumVisibleColumns; i++) {
pButton = (CButton*) GetDlgItem(IDC_COL_PATHNAME+i);
ASSERT(pButton != NULL);
pButton->SetCheck(1); // 0=unchecked, 1=checked, 2=indeterminate
}
SetModified(TRUE);
}
#ifdef CAN_UPDATE_FILE_ASSOC
void PrefsGeneralPage::OnAssociations(void)
{
EditAssocDialog assocDlg;
assocDlg.fOurAssociations = fOurAssociations;
fOurAssociations = NULL;
if (assocDlg.DoModal() == IDOK) {
/*
* Make a copy of the changes and mark us as modified so
* the Apply/Cancel buttons behave as expected. (We don't make
* a copy so much as steal the data from the dialog object.)
*/
delete[] fOurAssociations;
fOurAssociations = assocDlg.fOurAssociations;
assocDlg.fOurAssociations = NULL;
SetModified(TRUE);
}
}
#endif
void PrefsGeneralPage::DoDataExchange(CDataExchange* pDX)
{
/*
* The various column checkboxes are independent. We still do the xfer
* for "pathname" even though it's disabled.
*/
fReady = true;
ASSERT(NELEM(fColumn) == 9);
DDX_Check(pDX, IDC_COL_PATHNAME, fColumn[0]);
DDX_Check(pDX, IDC_COL_TYPE, fColumn[1]);
DDX_Check(pDX, IDC_COL_AUXTYPE, fColumn[2]);
DDX_Check(pDX, IDC_COL_MODDATE, fColumn[3]);
DDX_Check(pDX, IDC_COL_FORMAT, fColumn[4]);
DDX_Check(pDX, IDC_COL_SIZE, fColumn[5]);
DDX_Check(pDX, IDC_COL_RATIO, fColumn[6]);
DDX_Check(pDX, IDC_COL_PACKED, fColumn[7]);
DDX_Check(pDX, IDC_COL_ACCESS, fColumn[8]);
DDX_Check(pDX, IDC_PREF_SHRINKIT_COMPAT, fMimicShrinkIt);
DDX_Check(pDX, IDC_PREF_SHK_BAD_MAC, fBadMacSHK);
DDX_Check(pDX, IDC_PREF_REDUCE_SHK_ERROR_CHECKS, fReduceSHKErrorChecks);
DDX_Check(pDX, IDC_PREF_COERCE_DOS, fCoerceDOSFilenames);
DDX_Check(pDX, IDC_PREF_SPACES_TO_UNDER, fSpacesToUnder);
DDX_Check(pDX, IDC_PREF_PASTE_JUNKPATHS, fPasteJunkPaths);
DDX_Check(pDX, IDC_PREF_SUCCESS_BEEP, fBeepOnSuccess);
}
/*
* ===========================================================================
* PrefsDiskImagePage
* ===========================================================================
*/
BEGIN_MESSAGE_MAP(PrefsDiskImagePage, CPropertyPage)
ON_BN_CLICKED(IDC_PDISK_CONFIRM_FORMAT, OnChange)
ON_BN_CLICKED(IDC_PDISK_OPENVOL_RO, OnChange)
ON_BN_CLICKED(IDC_PDISK_OPENVOL_PHYS0, OnChange)
ON_BN_CLICKED(IDC_PDISK_PRODOS_ALLOWLOWER, OnChange)
ON_BN_CLICKED(IDC_PDISK_PRODOS_USESPARSE, OnChange)
ON_MESSAGE(WM_HELP, OnHelpInfo)
ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
END_MESSAGE_MAP()
BOOL PrefsDiskImagePage::OnInitDialog(void)
{
//LOGI("OnInit!");
return CPropertyPage::OnInitDialog();
}
void PrefsDiskImagePage::OnChange(void)
{
LOGD("OnChange");
SetModified(TRUE); // enable the "apply" button
}
//void PrefsDiskImagePage::OnChangeRange(UINT nID)
//{
// LOGD("OnChangeRange id=%d", nID);
// SetModified(TRUE);
//}
void PrefsDiskImagePage::DoDataExchange(CDataExchange* pDX)
{
fReady = true;
DDX_Check(pDX, IDC_PDISK_CONFIRM_FORMAT, fQueryImageFormat);
DDX_Check(pDX, IDC_PDISK_OPENVOL_RO, fOpenVolumeRO);
DDX_Check(pDX, IDC_PDISK_OPENVOL_PHYS0, fOpenVolumePhys0);
DDX_Check(pDX, IDC_PDISK_PRODOS_ALLOWLOWER, fProDOSAllowLower);
DDX_Check(pDX, IDC_PDISK_PRODOS_USESPARSE, fProDOSUseSparse);
}
/*
* ===========================================================================
* PrefsCompressionPage
* ===========================================================================
*/
BEGIN_MESSAGE_MAP(PrefsCompressionPage, CPropertyPage)
ON_CONTROL_RANGE(BN_CLICKED, IDC_DEFC_UNCOMPRESSED, IDC_DEFC_BZIP2, OnChangeRange)
ON_MESSAGE(WM_HELP, OnHelpInfo)
ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
END_MESSAGE_MAP()
BOOL PrefsCompressionPage::OnInitDialog(void)
{
if (!NufxArchive::IsCompressionSupported(kNuThreadFormatHuffmanSQ)) {
DisableWnd(IDC_DEFC_SQUEEZE);
if (fCompressType == kNuThreadFormatHuffmanSQ)
fCompressType = kNuThreadFormatUncompressed;
}
if (!NufxArchive::IsCompressionSupported(kNuThreadFormatLZW1)) {
DisableWnd(IDC_DEFC_LZW1);
if (fCompressType == kNuThreadFormatLZW1)
fCompressType = kNuThreadFormatUncompressed;
}
if (!NufxArchive::IsCompressionSupported(kNuThreadFormatLZW2)) {
DisableWnd(IDC_DEFC_LZW2);
if (fCompressType == kNuThreadFormatLZW2) {
fCompressType = kNuThreadFormatUncompressed;
}
}
if (!NufxArchive::IsCompressionSupported(kNuThreadFormatLZC12)) {
DisableWnd(IDC_DEFC_LZC12);
if (fCompressType == kNuThreadFormatLZC12)
fCompressType = kNuThreadFormatUncompressed;
}
if (!NufxArchive::IsCompressionSupported(kNuThreadFormatLZC16)) {
DisableWnd(IDC_DEFC_LZC16);
if (fCompressType == kNuThreadFormatLZC16)
fCompressType = kNuThreadFormatUncompressed;
}
if (!NufxArchive::IsCompressionSupported(kNuThreadFormatDeflate)) {
DisableWnd(IDC_DEFC_DEFLATE);
if (fCompressType == kNuThreadFormatDeflate)
fCompressType = kNuThreadFormatUncompressed;
}
if (!NufxArchive::IsCompressionSupported(kNuThreadFormatBzip2)) {
DisableWnd(IDC_DEFC_BZIP2);
if (fCompressType == kNuThreadFormatBzip2)
fCompressType = kNuThreadFormatUncompressed;
}
/* now invoke DoDataExchange with our modified fCompressType */
return CPropertyPage::OnInitDialog();
}
void PrefsCompressionPage::DisableWnd(int id)
{
CWnd* pWnd;
pWnd = GetDlgItem(id);
if (pWnd == NULL) {
ASSERT(false);
return;
}
pWnd->EnableWindow(FALSE);
}
void PrefsCompressionPage::OnChangeRange(UINT nID)
{
SetModified(TRUE); // enable the "apply" button
}
void PrefsCompressionPage::DoDataExchange(CDataExchange* pDX)
{
/*
* Compression types match the NuThreadFormat enum in NufxLib.h, starting
* with IDC_DEFC_UNCOMPRESSED.
*/
LOGV("OnInit comp!");
fReady = true;
DDX_Radio(pDX, IDC_DEFC_UNCOMPRESSED, fCompressType);
}
/*
* ===========================================================================
* PrefsFviewPage
* ===========================================================================
*/
BEGIN_MESSAGE_MAP(PrefsFviewPage, CPropertyPage)
ON_CONTROL_RANGE(BN_CLICKED, IDC_PVIEW_NOWRAP_TEXT, IDC_PVIEW_HIRES_BW, OnChangeRange)
ON_CONTROL_RANGE(BN_CLICKED, IDC_PVIEW_HITEXT, IDC_PVIEW_TEXT8, OnChangeRange)
ON_EN_CHANGE(IDC_PVIEW_SIZE_EDIT, OnChange)
ON_CBN_SELCHANGE(IDC_PVIEW_DHR_CONV_COMBO, OnChange)
ON_MESSAGE(WM_HELP, OnHelpInfo)
ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
END_MESSAGE_MAP()
BOOL PrefsFviewPage::OnInitDialog(void)
{
CSpinButtonCtrl* pSpin;
LOGV("Configuring spin");
pSpin = (CSpinButtonCtrl*) GetDlgItem(IDC_PVIEW_SIZE_SPIN);
ASSERT(pSpin != NULL);
UDACCEL uda;
uda.nSec = 0;
uda.nInc = 64;
pSpin->SetRange(1, 32767);
pSpin->SetAccel(1, &uda);
LOGD("OnInit done!");
return CPropertyPage::OnInitDialog();
}
void PrefsFviewPage::OnChange(void)
{
LOGD("OnChange");
SetModified(TRUE); // enable the "apply" button
}
void PrefsFviewPage::OnChangeRange(UINT nID)
{
LOGD("OnChangeRange id=%d", nID);
SetModified(TRUE);
}
void PrefsFviewPage::DoDataExchange(CDataExchange* pDX)
{
fReady = true;
//DDX_Check(pDX, IDC_PVIEW_EOL_RAW, fEOLConvRaw);
DDX_Check(pDX, IDC_PVIEW_NOWRAP_TEXT, fNoWrapText);
DDX_Check(pDX, IDC_PVIEW_BOLD_HEXDUMP, fHighlightHexDump);
DDX_Check(pDX, IDC_PVIEW_BOLD_BASIC, fHighlightBASIC);
DDX_Check(pDX, IDC_PVIEW_DISASM_ONEBYTEBRKCOP, fConvDisasmOneByteBrkCop);
DDX_Check(pDX, IDC_PVIEW_HIRES_BW, fConvHiResBlackWhite);
DDX_CBIndex(pDX, IDC_PVIEW_DHR_CONV_COMBO, fConvDHRAlgorithm);
DDX_Check(pDX, IDC_PVIEW_HITEXT, fConvTextEOL_HA);
DDX_Check(pDX, IDC_PVIEW_CPMTEXT, fConvCPMText);
DDX_Check(pDX, IDC_PVIEW_PASCALTEXT, fConvPascalText);
DDX_Check(pDX, IDC_PVIEW_PASCALCODE, fConvPascalCode);
DDX_Check(pDX, IDC_PVIEW_APPLESOFT, fConvApplesoft);
DDX_Check(pDX, IDC_PVIEW_INTEGER, fConvInteger);
DDX_Check(pDX, IDC_PVIEW_GWP, fConvGWP);
DDX_Check(pDX, IDC_PVIEW_TEXT8, fConvText8);
DDX_Check(pDX, IDC_PVIEW_AWP, fConvAWP);
DDX_Check(pDX, IDC_PVIEW_ADB, fConvADB);
DDX_Check(pDX, IDC_PVIEW_ASP, fConvASP);
DDX_Check(pDX, IDC_PVIEW_SCASSEM, fConvSCAssem);
DDX_Check(pDX, IDC_PVIEW_DISASM, fConvDisasm);
DDX_Check(pDX, IDC_PVIEW_HIRES, fConvHiRes);
DDX_Check(pDX, IDC_PVIEW_DHR, fConvDHR);
DDX_Check(pDX, IDC_PVIEW_SHR, fConvSHR);
DDX_Check(pDX, IDC_PVIEW_PRINTSHOP, fConvPrintShop);
DDX_Check(pDX, IDC_PVIEW_MACPAINT, fConvMacPaint);
DDX_Check(pDX, IDC_PVIEW_PRODOSFOLDER, fConvProDOSFolder);
DDX_Check(pDX, IDC_PVIEW_RESOURCES, fConvResources);
DDX_Check(pDX, IDC_PVIEW_RELAX_GFX, fRelaxGfxTypeCheck);
DDX_Text(pDX, IDC_PVIEW_SIZE_EDIT, fMaxViewFileSizeKB);
DDV_MinMaxUInt(pDX, fMaxViewFileSizeKB, 1, 32767);
}
/*
* ===========================================================================
* PrefsFilesPage
* ===========================================================================
*/
BEGIN_MESSAGE_MAP(PrefsFilesPage, CPropertyPage)
ON_EN_CHANGE(IDC_PREF_TEMP_FOLDER, OnChange)
ON_EN_CHANGE(IDC_PREF_EXTVIEWER_EXTS, OnChange)
ON_BN_CLICKED(IDC_PREF_CHOOSE_TEMP_FOLDER, OnChooseFolder)
ON_MESSAGE(WM_HELP, OnHelpInfo)
ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
END_MESSAGE_MAP()
BOOL PrefsFilesPage::OnInitDialog(void)
{
fChooseFolderButton.ReplaceDlgCtrl(this, IDC_PREF_CHOOSE_TEMP_FOLDER);
fChooseFolderButton.SetBitmapID(IDB_CHOOSE_FOLDER);
return CPropertyPage::OnInitDialog();
}
void PrefsFilesPage::OnChange(void)
{
SetModified(TRUE); // enable the "apply" button
}
void PrefsFilesPage::DoDataExchange(CDataExchange* pDX)
{
fReady = true;
DDX_Text(pDX, IDC_PREF_TEMP_FOLDER, fTempPath);
DDX_Text(pDX, IDC_PREF_EXTVIEWER_EXTS, fExtViewerExts);
/* validate the path field */
if (pDX->m_bSaveAndValidate) {
if (fTempPath.IsEmpty()) {
CString appName;
appName.LoadString(IDS_MB_APP_NAME);
MessageBox(L"You must specify a path for temp files",
appName, MB_OK);
pDX->Fail();
}
// we *could* try to validate the path here...
}
}
void PrefsFilesPage::OnChooseFolder(void)
{
/*
* They want to choose the folder from a menu hierarchy. Show them a list.
*/
ChooseDirDialog chooseDir(this);
CWnd* pEditWnd;
CString editPath;
/* get the currently-showing text from the edit field */
pEditWnd = GetDlgItem(IDC_PREF_TEMP_FOLDER);
ASSERT(pEditWnd != NULL);
pEditWnd->GetWindowText(editPath);
chooseDir.SetPathName(editPath);
if (chooseDir.DoModal() == IDOK) {
const WCHAR* ccp = chooseDir.GetPathName();
LOGD("New temp path chosen = '%ls'", ccp);
pEditWnd->SetWindowText(ccp);
// activate the "apply" button
OnChange();
}
}
/*
* ===========================================================================
* PrefsSheet
* ===========================================================================
*/
BEGIN_MESSAGE_MAP(PrefsSheet, CPropertySheet)
ON_WM_NCCREATE()
ON_BN_CLICKED(ID_APPLY_NOW, OnApplyNow)
ON_COMMAND(ID_HELP, OnIDHelp)
ON_MESSAGE(WM_HELP, OnHelpInfo)
END_MESSAGE_MAP()
PrefsSheet::PrefsSheet(CWnd* pParentWnd) :
CPropertySheet(L"Preferences", pParentWnd)
{
AddPage(&fGeneralPage);
AddPage(&fDiskImagePage);
AddPage(&fFviewPage);
AddPage(&fCompressionPage);
AddPage(&fFilesPage);
/* this happens automatically with appropriate ID_HELP handlers */
//m_psh.dwFlags |= PSH_HASHELP;
}
BOOL PrefsSheet::OnNcCreate(LPCREATESTRUCT cs)
{
LOGV("PrefsSheet OnNcCreate");
BOOL val = CPropertySheet::OnNcCreate(cs);
ModifyStyleEx(0, WS_EX_CONTEXTHELP);
return val;
}
void PrefsSheet::OnApplyNow(void)
{
BOOL result;
if (fGeneralPage.fReady) {
//LOGI("Apply to general?");
result = fGeneralPage.UpdateData(TRUE);
if (!result)
return;
}
if (fDiskImagePage.fReady) {
//LOGI("Apply to disk images?");
result = fDiskImagePage.UpdateData(TRUE);
if (!result)
return;
}
if (fCompressionPage.fReady) {
//LOGI("Apply to compression?");
result = fCompressionPage.UpdateData(TRUE);
if (!result)
return;
}
if (fFviewPage.fReady) {
//LOGI("Apply to fview?");
result = fFviewPage.UpdateData(TRUE);
if (!result)
return;
}
if (fFilesPage.fReady) {
//LOGI("Apply to fview?");
result = fFilesPage.UpdateData(TRUE);
if (!result)
return;
}
/* reset all to "unmodified" state */
LOGD("All 'applies' were successful");
((MainWindow*) AfxGetMainWnd())->ApplyNow(this);
fGeneralPage.SetModified(FALSE);
fGeneralPage.fDefaultsPushed = false;
fDiskImagePage.SetModified(FALSE);
fCompressionPage.SetModified(FALSE);
fFviewPage.SetModified(FALSE);
fFilesPage.SetModified(FALSE);
}
void PrefsSheet::OnIDHelp(void)
{
LOGD("PrefsSheet OnIDHelp");
SendMessage(WM_COMMANDHELP);
}