/* Copyright (c) Microsoft Corporation. Licensed under the MIT License. */ /*************************************************************************** Author: ShonK Project: Kauai Reviewed: Copyright (c) Microsoft Corporation Standard dialogs. ***************************************************************************/ #include "frame.h" ASSERTNAME RTCLASS(DLG) /*************************************************************************** Constructor for a dialog object. ***************************************************************************/ DLG::DLG(long rid) : GG(size(DIT)) { _rid = rid; } /*************************************************************************** Static method to create a new DLG. Does NewObj then calls _FInit. ***************************************************************************/ PDLG DLG::PdlgNew(long rid, PFNDLG pfn, void *pv) { PDLG pdlg; if ((pdlg = NewObj DLG(rid)) == pvNil) return pvNil; pdlg->_pfn = pfn; pdlg->_pv = pv; if (!pdlg->_FInit()) ReleasePpo(&pdlg); return pdlg; } /*************************************************************************** Get the values for [iditMin, iditLim) from the actual dialog and put them in the GGDIT. ***************************************************************************/ bool DLG::FGetValues(long iditMin, long iditLim) { AssertThis(0); long idit; DIT dit; long lw; STN stn; AssertIn(iditMin, 0, iditLim); if (_pgob == pvNil) { Bug("why are you calling this when the dialog doesn't exist?"); return fFalse; } iditLim = LwMin(iditLim, IvMac()); for (idit = iditMin; idit < iditLim; idit++) { GetDit(idit, &dit); switch (dit.ditk) { case ditkCheckBox: lw = _FGetCheckBox(idit); goto LPutLw; case ditkRadioGroup: lw = _LwGetRadioGroup(idit); LPutLw: PutRgb(idit, 0, size(lw), &lw); break; case ditkEditText: case ditkCombo: _GetEditText(idit, &stn); if (!FPutStn(idit, &stn)) return fFalse; break; } } return fTrue; } /*************************************************************************** Set the values for [iditMin, iditLim) from the GGDIT into the actual dialog. ***************************************************************************/ void DLG::SetValues(long iditMin, long iditLim) { AssertThis(0); long idit; DIT dit; STN stn; long lw; long cb, cbT, ib; byte *prgb; if (_pgob == pvNil) { Bug("why are you calling this when the dialog doesn't exist?"); return; } iditLim = LwMin(iditLim, IvMac()); for (idit = iditMin; idit < iditLim; idit++) { GetDit(idit, &dit); switch (dit.ditk) { case ditkCheckBox: GetRgb(idit, 0, size(lw), &lw); _SetCheckBox(idit, lw); break; case ditkRadioGroup: GetRgb(idit, 0, size(lw), &lw); _SetRadioGroup(idit, lw); break; case ditkEditText: GetStn(idit, &stn); _SetEditText(idit, &stn); break; case ditkCombo: _ClearList(idit); cb = Cb(idit); if (cb <= 0) { stn.SetNil(); _SetEditText(idit, &stn); break; } prgb = (byte *)PvLock(idit); if (!stn.FSetData(prgb, cb, &cbT)) { Bug("bad combo item"); cbT = cb; } _SetEditText(idit, &stn); for (ib = cbT; ib < cb; ) { if (!stn.FSetData(prgb + ib, cb - ib, &cbT)) { BugVar("bad combo item", &ib); break; } ib += cbT; _FAddToList(idit, &stn); } Unlock(); break; } } } /*************************************************************************** Get the item number from a system item number. ***************************************************************************/ long DLG::IditFromSit(long sit) { long idit; DIT dit; for (idit = IvMac(); idit-- != 0; ) { GetDit(idit, &dit); if (sit >= dit.sitMin && sit < dit.sitLim) return idit; } return ivNil; } /*************************************************************************** Calls the PFNDLG (if not nil) to notify of a change. PFNDLG should return true if the dialog should be dismissed. The PFNDLG is free to change *pidit. If a nil PFNDLG was specified (in PdlgNew), this returns true (dismisses the dialog) on any button hit. ***************************************************************************/ bool DLG::_FDitChange(long *pidit) { if (pvNil == _pfn) { DIT dit; if (ivNil == *pidit) return fFalse; GetDit(*pidit, &dit); return dit.ditk == ditkButton; } return (*_pfn)(this, pidit, _pv); } /*************************************************************************** Get the stn (for an edit item). ***************************************************************************/ void DLG::GetStn(long idit, PSTN pstn) { AssertThis(0); AssertIn(idit, 0, IvMac()); AssertPo(pstn, 0); long cb; #ifdef DEBUG DIT dit; GetDit(idit, &dit); Assert(ditkEditText == dit.ditk || dit.ditk == ditkCombo, "not a text item or combo"); #endif //DEBUG cb = Cb(idit); if (cb <= 0) pstn->SetNil(); else { AssertDo(pstn->FSetData(PvLock(idit), cb, &cb), 0); Unlock(); } } /*************************************************************************** Put the stn into the DLG. ***************************************************************************/ bool DLG::FPutStn(long idit, PSTN pstn) { AssertThis(0); AssertIn(idit, 0, IvMac()); AssertPo(pstn, 0); DIT dit; long cbOld, cbNew; GetDit(idit, &dit); cbOld = Cb(idit); cbNew = pstn->CbData(); switch (dit.ditk) { default: Bug("not a text item or combo"); return fFalse; case ditkEditText: if (cbOld != cbNew && !FPut(idit, cbNew, pvNil)) return fFalse; break; case ditkCombo: if (cbOld > 0) { STN stn; if (!stn.FSetData(PvLock(idit), cbOld, &cbOld)) { Bug("why did setting the data fail?"); cbOld = Cb(idit); } Unlock(); } if (cbOld > cbNew) DeleteRgb(idit, 0, cbOld - cbNew); else if (cbOld < cbNew && !FInsertRgb(idit, 0, cbNew - cbOld, pvNil)) return fFalse; break; } pstn->GetData(PvLock(idit)); Unlock(); return fTrue; } /*************************************************************************** Get the value of a radio group. ***************************************************************************/ long DLG::LwGetRadio(long idit) { AssertThis(0); AssertIn(idit, 0, IvMac()); long lw; #ifdef DEBUG DIT dit; GetDit(idit, &dit); Assert(ditkRadioGroup == dit.ditk, "not a radio group"); #endif //DEBUG GetRgb(idit, 0, size(long), &lw); return lw; } /*************************************************************************** Set the value of the radio group. ***************************************************************************/ void DLG::PutRadio(long idit, long lw) { AssertThis(0); AssertIn(idit, 0, IvMac()); #ifdef DEBUG DIT dit; GetDit(idit, &dit); Assert(ditkRadioGroup == dit.ditk, "not a radio group"); AssertIn(lw, 0, dit.sitLim - dit.sitMin); #endif //DEBUG PutRgb(idit, 0, size(long), &lw); } /*************************************************************************** Get the value of a check box. ***************************************************************************/ bool DLG::FGetCheck(long idit) { AssertThis(0); AssertIn(idit, 0, IvMac()); long lw; #ifdef DEBUG DIT dit; GetDit(idit, &dit); Assert(ditkCheckBox == dit.ditk, "not a check box"); #endif //DEBUG GetRgb(idit, 0, size(long), &lw); return lw; } /*************************************************************************** Set the value of a check box item. ***************************************************************************/ void DLG::PutCheck(long idit, bool fOn) { AssertThis(0); AssertIn(idit, 0, IvMac()); long lw; #ifdef DEBUG DIT dit; GetDit(idit, &dit); Assert(ditkCheckBox == dit.ditk, "not a check box"); #endif //DEBUG lw = FPure(fOn); PutRgb(idit, 0, size(long), &lw); } /*************************************************************************** Get the indicated edit item from the dialog and convert it to a long. If the string is empty, sets *plw to zero and sets *pfEmpty (if pfEmpty is not nil) and returns false. If the string doesn't parse as a number, returns false. ***************************************************************************/ bool DLG::FGetLwFromEdit(long idit, long *plw, bool *pfEmpty) { AssertThis(0); AssertVarMem(plw); AssertNilOrVarMem(pfEmpty); STN stn; GetStn(idit, &stn); if (0 == stn.Cch()) { if (pvNil != pfEmpty) *pfEmpty = fTrue; *plw = 0; return fFalse; } if (pvNil != pfEmpty) *pfEmpty = fFalse; if (!stn.FGetLw(plw, 0)) { TrashVar(plw); return fFalse; } return fTrue; } /*************************************************************************** Put the long into the indicated edit item (in decimal). ***************************************************************************/ bool DLG::FPutLwInEdit(long idit, long lw) { AssertThis(0); STN stn; stn.FFormatSz(PszLit("%d"), lw); return FPutStn(idit, &stn); } /*************************************************************************** Add the string to the given list item. ***************************************************************************/ bool DLG::FAddToList(long idit, PSTN pstn) { AssertThis(0); long cb, cbTot; #ifdef DEBUG DIT dit; GetDit(idit, &dit); Assert(ditkCombo == dit.ditk, "not a combo"); #endif //DEBUG cbTot = Cb(idit); if (cbTot == 0) { STN stn; stn.SetNil(); if (!FPut(idit, cbTot = stn.CbData(), pvNil)) return fFalse; stn.GetData(PvLock(idit)); Unlock(); } cb = pstn->CbData(); if (!FInsertRgb(idit, cbTot, cb, pvNil)) return fFalse; pstn->GetData(PvAddBv(PvLock(idit), cbTot)); Unlock(); return fTrue; } /*************************************************************************** Empty the list of options for the list item. ***************************************************************************/ void DLG::ClearList(long idit) { AssertThis(0); AssertIn(idit, 0, IvMac()); long cbOld, cbNew; STN stn; #ifdef DEBUG DIT dit; GetDit(idit, &dit); Assert(ditkCombo == dit.ditk, "not a combo"); #endif //DEBUG cbOld = Cb(idit); if (cbOld <= 0) return; if (!stn.FSetData(PvLock(idit), cbOld, &cbNew)) { Bug("why did setting the data fail?"); cbNew = 0; } Unlock(); if (cbOld > cbNew) DeleteRgb(idit, cbNew, cbOld - cbNew); }