home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-01-28 | 60.7 KB | 2,206 lines | [TEXT/CWIE] |
- /*
- HASPreferences.c from Hsoi's App Shell © 1995-1997 John C. Daub. All rights reserved.
-
- This file contains all the stuff to deal with preferences: setting them up,
- reading them in, writing them out. Plus, it contains the "registration"
- dialog stuff.
- */
-
-
-
- // to give credit where credit is due, my preferences code was based upon/derrived from
- // inspried by, etc, John Norstad's prefs code that he used in NewsWatcher. I highly
- // recommend getting the source to NewsWatcher (espcially if you use NewsWatcher, but
- // get it anyway) and looking it over. You'll learn a LOT.
-
- // also, some of this prefs code (notably the print prefs and it's releated code, such
- // as HsoiDoArrowUpDown) is derrived upon work by Tom Bender from his Tex-Edit+ 1.6.3 source.
- // it started out being directly Tom's work (just translated from Pascal to C), but due to
- // some things in Tom's code that just can't translate too easily (plus some difficulties
- // Tom had in handling longer decimals (things out past the tenths place)), the code has
- // changed a fair amount to be what it is now. Of course, I just wish my modifications didn't
- // require the #inclusion of ANSI C headers and needing to link in the ANSI libraries....oh well.
-
- // and the function HsoiGetDoubleItem() was given to me by Scott Pogorelc (scottp@cais.cais.com)
- // and i updated it for use with the new Universal Headers. Thanx Scott!
-
- // NOTE: There is one bug in the prefs code that i know of: the topic popup menu "truncates"
- // to just a short arrow menu when the new dialog is brought up....this bug made itself
- // known after i added in the printing prefs...I'm not sure why it's happening, but I'm
- // not really going to pursue it. In a future release of HAS, I want to throw out this
- // prefs code anyways in place of another technique. Instead of using a popup menu, I'd
- // like to have an "icon driven" prefs dialog...like the CW prefs dialog. So, much of
- // this will soon be moot as I'll sooner or later be trashing it. But, if you happen to
- // find out why this bug is happening, please let me know!
-
- // and there is one other bug in the prefs code...in the Text prefs pane, do this:
- // in the font size edit box, enter an odd size (like 13...just something that's not a
- // value already in the size popup menu). now, click-hold on the size popup menu.
- // select this odd font size (it'll be the first item) and let go of the mouse. the
- // value in the size edit box should revert to 9 (or whatever the size/number that's
- // the first item in the popup). i know why this is happening, but i can't quite
- // figure out how to fix it...i'm sure it's a problem that leaked in as i butchered
- // Norstad's original code...I do need to fix this...but it can wait for right now.
-
- #pragma mark ••• #includes •••
-
- #ifndef _WASTE_
- #include "WASTE.h"
- #endif
- #include "HASGlobals.h"
- #ifndef __HSOIS_APP_SHELL__
- #include "HASMain.h"
- #endif
- #include "HASUtilDialogs.h"
- #include "HASDialogs.h"
- #include "HASPreferences.h"
- #include "HASUtilPStrings.h"
- #include "HASUtilities.h"
-
- #include "WASTE_Objects.h"
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- #pragma mark -
- #pragma mark ••• Constants •••
-
- // can't enum this since it's a floating point value, but just needed a nice constant
-
- const double kMaxMargin = 6.00;
-
- #pragma mark -
- #pragma mark ••• Globalss •••
-
- // various static globals to help us keep track of things..
-
- static short sCurRadio = 0;
- static short sDefaultFontID = 0;
- static short sDefaultSize = 0;
- static short curDlgNum = rPrefsGeneralDLOG; // start out on the "first page"
- static Str255 sFontSize = NIL_STRING;
- static Boolean sNewPrefs = 0; // true: create prefs file so do registration dlog, false: pref file
- // already exists, don't do registration dlog
- static UserItemUPP frameItemsUPP = nil;
-
-
- #pragma mark -
- #pragma mark ••• Utils •••
-
- /* some utility functions */
-
- short HsoiSetPopupValue (ControlRef ctl, Str255 str, Boolean isNumber)
- {
- PopupPrivateDataHandle data;
- long checkVal, itemVal;
- MenuRef menu;
- short numItems, item;
- Str255 tempStr;
-
- //COPLAND - the following line breaks under STRICT macros since .contrlData isn't
- // a member of an OpaqueControlReference
-
- // get the popup data
-
- data = (PopupPrivateDataHandle)(*ctl)->contrlData;
-
- // if the string is a number, convert it
-
- if (isNumber)
- StringToNum(str, &checkVal);
-
- // get the menuref from the popup data
-
- menu = (*data)->mHandle;
-
- // see how many items are in the menu
-
- numItems = CountMenuItems(menu);
-
- // and loop through the menu looking for a menu item that matches "str"
-
- for (item = 1; item <= numItems; item++)
- {
- // get the menu text
-
- GetMenuItemText(menu, item, tempStr);
-
- // if it's a number we're looking for...
-
- if (isNumber)
- {
- // ...convert the menu item to a number...
-
- StringToNum(tempStr, &itemVal);
-
- // ...if they're equal...
-
- if (checkVal == itemVal)
- {
- // ...then set the value of the control
-
- SetControlValue(ctl, item);
- return item;
- }
- }
- // ..else if we're instead looking for a string..
-
- else if (EqualString(str, tempStr, false, true))
- {
- //...if we have a match, set the value
-
- SetControlValue(ctl, item);
- return item;
- }
- }
- return 0;
- }
-
- // returns a pascal type string from a popup menu
-
- void HsoiGetPopupPString (ControlRef ctl, short item, Str255 str)
- {
- PopupPrivateDataHandle data;
-
- // get the popup menu
-
- //COPLAND - the following line breaks under STRICT macros since .controlData
- // isn't a member of an OpaqueControlReference
- data = (PopupPrivateDataHandle)(*ctl)->contrlData;
-
- // readjust the value of "item" if necessary
-
- if (item == kCurrentPopupItem)
- item = GetControlValue(ctl);
-
- // and then get the text of the menu item
-
- GetMenuItemText((*data)->mHandle, item, str);
- }
-
- // this will set the style a menu item's text is drawn in
-
- void HsoiSetPopupItemStyle (ControlRef ctl, short item, short style)
- {
- PopupPrivateDataHandle data;
-
- //COPLAND - the following line breaks under STRICT macros since .contrlData
- // isn't a member of an OpaqueControlReference
- data = (PopupPrivateDataHandle)(*ctl)->contrlData;
- if (item == kCurrentPopupItem)
- item = GetControlValue(ctl);
- SetItemStyle((*data)->mHandle, item, style);
- }
-
-
- // used in our prefs dialog filter to track popup menu usage
-
- short HsoiTrackPopup (ControlRef ctl, Point where, Str255 checkItem, Boolean isNumber)
- {
- PopupPrivateDataHandle data;
- MenuRef menu;
- long checkVal;
- short itemsAdded, part, newValue, oldValue;
- Str255 tempStr;
- register short i;
-
- //COPLAND - the following line breaks under STRICT macros since .controlData
- // isn't a member of an OpaqueControlReference
-
- // get the popup menu data from the control
-
- data = (PopupPrivateDataHandle)(*ctl)->contrlData;
-
- // get the menuref
-
- menu = (*data)->mHandle;
-
- // reset itemsAdded to zero (cause we haven't added anything)
-
- itemsAdded = 0;
-
- // if we have a string and it's not nil...
-
- if (checkItem && *checkItem)
- {
-
- // set the popup value
-
- oldValue = HsoiSetPopupValue(ctl, checkItem, isNumber);
-
-
- if (oldValue == 0)
- {
- // if it's a number...
-
- if (isNumber)
- {
- // convert to a string then insert into the menu
-
- StringToNum(checkItem, &checkVal);
- NumToString(checkVal, tempStr);
- InsertMenuItem(menu, tempStr, 0);
- }
- else
- {
- // it's a number, just insert it
-
- InsertMenuItem(menu, checkItem, 0);
- }
-
- // insert a spacer menu item
-
- InsertMenuItem(menu, "\p(-", 1);
-
- // readjust the oldValue
-
- oldValue = 1;
-
- // we added 2 items (the menu item and the spacer)
-
- itemsAdded = 2;
-
- // and set the control value as such
-
- SetControlValue(ctl, oldValue);
- }
- }
- else // we don't have a string and/or it's nil
- {
- oldValue = 0;
- }
-
- // track the popup menu (toolbox does this)
-
- part = TrackControl(ctl, where, (ControlActionUPP)-1);
-
- // get the new value of the controls
-
- newValue = GetControlValue(ctl);
-
- // readjust the new value of the control
-
- if (part != 0 && oldValue != newValue)
- {
- newValue = newValue - itemsAdded;
- }
- else
- {
- newValue = 0;
- }
-
- // if we added anything to the popup menu, remove it before we return
-
- if (itemsAdded)
- {
- for (i = 0; i < itemsAdded; i++)
- {
- DeleteMenuItem(menu, 1);
- }
- SetControlValue(ctl, newValue);
- }
- return newValue;
- }
-
-
- // this goes through the font popup menu in the prefs dialog and adjusts
- // the look and value of the popup
-
- static void HsoiSetNewFont (DialogRef dlg, short fontNum)
- {
- short numItems, i;
- Str255 itemStr, fontName;
- ControlRef ctl;
- long size;
-
- // Select the right font in the font popup menu.
-
- ctl = HsoiDlgGetControl(dlg, iPrefsTextFontPopup );
- GetFontName(fontNum, fontName);
- HsoiSetPopupValue(ctl, fontName, false);
-
- // Adjust the size popup so the nice sizes are outlined.
-
- // get the control
-
- ctl = HsoiDlgGetControl(dlg, iPrefsTextSizePopup);
-
- // find the number of items in the popup
-
- numItems = GetControlMaximum(ctl);
-
- // and loop through the list...depending on the fontName (the font),
- // draw the size popup items in plain or outline style to signify
- // a supported size
-
- for (i = 1; i <= numItems; i++)
- {
- HsoiGetPopupPString(ctl, i, itemStr);
- StringToNum(itemStr, &size);
- if (RealFont(fontNum, (short)size))
- {
- HsoiSetPopupItemStyle(ctl, i, outline);
- }
- else
- {
- HsoiSetPopupItemStyle(ctl, i, 0);
- }
- }
-
- return;
- }
-
- // from the font popup menu, get the selected font's ID number
-
- static short HsoiFontIDFromPopup( DialogRef dlg, short item )
- {
- ControlRef ctl;
- short fontNum;
- Str255 fontName;
-
- ctl = HsoiDlgGetControl( dlg, item );
- HsoiGetPopupPString( ctl, kCurrentPopupItem, fontName );
- GetFNum( fontName, &fontNum );
-
- return fontNum;
- }
-
- // adjust the radio button group in the prefs dialog.
-
- void HsoiSetPrefsRadioButton( DialogRef dlg, short buttonNumber )
- {
- // if the buttonNumber is the currently selected button, don't bother.
-
- if ( buttonNumber != sCurRadio )
- {
- // and if it's another button, first turn off the current button
- // and then turn on the new button
-
- if ( sCurRadio != 0 )
- HsoiSetDialogItemState( dlg, sCurRadio, false );
-
- sCurRadio = buttonNumber;
-
- if ( (sCurRadio >= kPrefsTextFirstRadio ) && ( sCurRadio <= kPrefsTextLastRadio ) )
- HsoiSetDialogItemState( dlg, sCurRadio, true );
- }
-
- return;
- }
-
- // this puts a little frame around the color swatch in the text prefs dialog
- // (just a nice cosmetic effect)
-
- void HsoiFrameColorRect( DialogRef dlg, HASPreferences *prefs )
- {
- #pragma unused( prefs )
-
- Rect borderRect;
-
- // get the item rect
-
- HsoiGetDialogItemRect( dlg, iPrefsTextGetColor, &borderRect );
-
- // grow out from that rect 2 pixels
-
- InsetRect(&borderRect, -2, -2);
-
- // normal the pen
-
- PenNormal();
-
- // make sure the pen size is just 1 x 1 pixel
-
- PenSize(1, 1);
-
- // frame it
-
- FrameRect(&borderRect );
-
- // and again make sure the size is 1x1 for other drawing operations
-
- PenSize(1, 1);
-
-
- return;
- }
-
- // fill something into the color user item rect in the text prefs dialog
- // (nice user feedback as to which color is selected)
-
- void HsoiPaintColorRect( DialogRef dlg, HASPreferences *prefs )
- {
- RGBColor oldForeColor, newForeColor;
- GrafPtr oldPort;
- Rect colorRect;
-
- // set up the port
-
- GetPort( &oldPort );
- SetGrafPortOfDialog( dlg );
-
- // draw the frame around the rect
-
- HsoiFrameColorRect( dlg, prefs );
-
- // get the original color
-
- GetForeColor( &oldForeColor );
-
- // get the new color from the prefs
-
- newForeColor = prefs->defColor;
-
- // set the fore color
-
- RGBForeColor( &newForeColor );
-
- // get the rect
-
- HsoiGetDialogItemRect( dlg, iPrefsTextGetColor, &colorRect );
-
- // and paint it in the new color
-
- PaintRect( &colorRect );
-
- // restore the old color and port
-
- RGBForeColor( &oldForeColor );
- SetPort( oldPort );
-
- return;
- }
-
-
- #pragma mark -
- #pragma mark ••• Prefs Pane Handlers •••
-
- // the function/procedures to handle each dialog box
-
- // this takes care of the general prefs dialog
-
-
- static void HsoiGeneralPrefs( HASPreferences *prefs, DialogRef dlg, short item )
- {
- switch ( item )
- {
-
- // intialization (called before the dialog is brought up
-
- case kInit:
-
- // set the checkmarks based upon the prefs setting
-
- HsoiDlgSetCheck( dlg, iPrefsGenCreateWIND, prefs->createWindow );
- HsoiDlgSetCheck( dlg, iPrefsGenHelpSound, prefs->playHelpSound );
- HsoiDlgSetCheck( dlg, iPrefsGenDoSplash, prefs->doSplashScreen );
-
- // the speech stuff is dependant if they have the speech manager or
- // not. if they have it, make sure the item is enalbed and then
- // set the check according to the prefs setting
-
- if ( gHasSpeechManager )
- {
- // make sure it's enabled
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsGenStartupSpeech ), kCtlActive );
- HsoiDlgSetCheck( dlg, iPrefsGenStartupSpeech, prefs->doStartupSpeech );
- }
- else // no speech manager, make sure the dialog item is disabled, and of course
- // set the item to be unchecked since they can't use it
- {
- // make sure it's disabled
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsGenStartupSpeech ), kCtlInactive );
- HsoiDlgSetCheck( dlg, iPrefsGenStartupSpeech, 0 );
- }
-
- break; // end: case kInit
-
-
- // what to do when the dialog is "brought down"
-
- case kTerm:
-
- // just save the checkmark settings/values in the prefs
-
- prefs->createWindow = HsoiDlgGetCheck( dlg, iPrefsGenCreateWIND );
- prefs->playHelpSound = HsoiDlgGetCheck( dlg, iPrefsGenHelpSound );
- prefs->doSplashScreen = HsoiDlgGetCheck( dlg, iPrefsGenDoSplash );
- prefs->doStartupSpeech = HsoiDlgGetCheck( dlg, iPrefsGenStartupSpeech );
-
- break; // end: case kTerm
-
- // now, during the dialog, what to do
-
- // in this dialog, whatever they select, just toggle the checkmark
-
- case iPrefsGenCreateWIND:
- case iPrefsGenHelpSound:
- case iPrefsGenDoSplash:
- case iPrefsGenStartupSpeech:
-
- HsoiDlgToggleCheck( dlg, item );
-
- break; // end case kPrefsGenXXXX
-
-
- } // end: switch ( item )
-
- return;
- }
-
- // the handler for the text prefs dialog
-
-
- static void HsoiTextPrefs( HASPreferences *prefs, DialogRef dlg, short item )
- {
- short radio;
- Boolean hasFace, hasFeature;
- Str255 tempStr;
- long num;
- Boolean checked;
- short i;
-
- switch ( item )
- {
-
- // what to do at initalization, before the dialog is brought up
-
- case kInit:
-
- // set up the font popup and size popup and edittext item
-
- GetFNum(prefs->defFont, &sDefaultFontID);
- sDefaultSize = prefs->defSize;
- HsoiSetNewFont(dlg, sDefaultFontID);
- HsoiDlgSetNumber(dlg, iPrefsTextSizeEditBox, sDefaultSize);
- SelectDialogItemText(dlg, iPrefsTextSizeEditBox, 0, MAXSHORT);
-
- // set up the text face/style checkboxes
-
- // if the defFace == 0, it's plain style, so just check that one
- // and be sure all the rest are unchecked
-
- if ( prefs->defFace == 0 )
- {
- HsoiDlgSetCheck( dlg, iPrefsTextPlainCheck, true );
- HsoiDlgSetCheck( dlg, iPrefsTextBoldCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextItalicCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextUnderlineCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextOutlineCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextShadowCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextCondenseCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextExtendCheck, false );
- }
- else
- // it's not 0 (plain style), so we can be sure this needs to be unchecked
- HsoiDlgSetCheck( dlg, iPrefsTextPlainCheck, false );
-
- // check the defFace for style attributes. depending if it's
- // there or not (hasFace is a Boolean), the checkbox will
- // be checked appropriately
-
- hasFace = prefs->defFace & bold;
- HsoiDlgSetCheck( dlg, iPrefsTextBoldCheck, hasFace );
-
- hasFace = prefs->defFace & italic;
- HsoiDlgSetCheck( dlg, iPrefsTextItalicCheck, hasFace );
-
- hasFace = prefs->defFace & underline;
- HsoiDlgSetCheck( dlg, iPrefsTextUnderlineCheck, hasFace );
-
- hasFace = prefs->defFace & outline;
- HsoiDlgSetCheck( dlg, iPrefsTextOutlineCheck, hasFace );
-
- hasFace = prefs->defFace & shadow;
- HsoiDlgSetCheck( dlg, iPrefsTextShadowCheck, hasFace );
-
- hasFace = prefs->defFace & condense;
- HsoiDlgSetCheck( dlg, iPrefsTextCondenseCheck, hasFace );
-
- hasFace = prefs->defFace & extend;
- HsoiDlgSetCheck( dlg, iPrefsTextExtendCheck, hasFace );
-
- // set up the little color rect
- // doesn't really work here, unfortuneately, due to updating stuff, so
- // this call is really handled in HsoiDoPrefsDialog() right after ShowWindow()
-
- // i probably could install this as a UserItemUPP to make it easier.....
-
- HsoiPaintColorRect( dlg, prefs );
-
- // set up the radio buttons
-
- sCurRadio = 0;
-
- if ( prefs->defAlign == weFlushLeft )
- radio = iPrefsTextLeftRadio;
- else if ( prefs->defAlign == weFlushRight )
- radio = iPrefsTextRightRadio;
- else if ( prefs->defAlign == weFlushDefault )
- radio = kPrefsTextDefaultRadio;
- else if ( prefs->defAlign == weCenter )
- radio = iPrefsTextCenterRadio;
- else if ( prefs->defAlign == weJustify )
- radio = iPrefsTextFullRadio;
- else
- radio = kPrefsTextDefaultRadio;
-
- HsoiSetPrefsRadioButton( dlg, radio );
-
- // set up the features flags
-
- HsoiDlgSetCheck( dlg, iPrefsTextTabHooks, prefs->useTabHooks );
-
- // if tab hooks are used, they can only be used with left alignment/justification
- // therefore, if this check box becomes marked we must 1. make sure the left
- // alignment button gets turned on, 2. all the alignnment radio buttons get dimmed
- // (cuase they cannot select anything without messing up tab hooks). And if tab
- // hooks becomes unchecked, make sure to enable the radio buttons, but no need
- // to select a new alignment style
-
- checked = HsoiDlgGetCheck( dlg, iPrefsTextTabHooks );
-
- if ( checked )
- {
- HsoiSetPrefsRadioButton( dlg, iPrefsTextLeftRadio );
- for ( i = kPrefsTextFirstRadio; i <= kPrefsTextLastRadio; i++ )
- {
- HiliteControl( HsoiDlgGetControl( dlg, i ), kCtlInactive );
- }
- }
- else
- {
- for ( i = kPrefsTextFirstRadio; i <= kPrefsTextLastRadio; i++ )
- {
- HiliteControl( HsoiDlgGetControl( dlg, i ), kCtlActive );
- }
- }
-
-
- // and cycle through the defFeatures to see what to have and not to have
- // (works the same as the face stuff above)
-
- hasFeature = BTST( prefs->defFeatures, weFAutoScroll );
- HsoiDlgSetCheck( dlg, iPrefsTextAutoScroll, hasFeature );
-
- hasFeature = BTST( prefs->defFeatures, weFOutlineHilite );
- HsoiDlgSetCheck( dlg, iPrefsTextOutlineHilite, hasFeature );
-
- hasFeature = BTST( prefs->defFeatures, weFReadOnly );
- HsoiDlgSetCheck( dlg, iPrefsTextReadOnly, hasFeature );
-
- hasFeature = BTST( prefs->defFeatures, weFIntCutAndPaste );
- HsoiDlgSetCheck( dlg, iPrefsTextIntCutAndPaste, hasFeature );
-
- // if the user's computer doesn't have drag and drop support, we shouldn't
- // allow them to set this bit
-
- if ( gHasDragAndDrop )
- {
- // make sure it's enabled
-
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsTextDragAndDrop ), kCtlActive );
-
- // set the check mark
-
- hasFeature = BTST( prefs->defFeatures, weFDragAndDrop );
- HsoiDlgSetCheck( dlg, iPrefsTextDragAndDrop, hasFeature );
- }
- else
- {
- // make sure it's disabled
-
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsTextDragAndDrop ), kCtlInactive );
-
- // make sure it has no check mark
-
- HsoiDlgSetCheck( dlg, iPrefsTextDragAndDrop, false );
-
- }
-
- hasFeature = BTST( prefs->defFeatures, weFDrawOffscreen );
- HsoiDlgSetCheck( dlg, iPrefsTextOffscreenDrawing, hasFeature );
-
- // install the frame rect proc for the user items (it's nice and cosmetic!)
-
- HsoiSetDialogItemProc( dlg, iPrefsTextStyleUserItem, frameItemsUPP );
- HsoiSetDialogItemProc( dlg, iPrefsTextAlignUserItem, frameItemsUPP );
- HsoiSetDialogItemProc( dlg, iPrefsTextFeaturesUserItem, frameItemsUPP );
-
-
- break; // case kInit
-
- // what to do when the dialog is brought down....
-
- case kTerm:
-
- // get the font and size data
-
- GetFontName( sDefaultFontID, prefs->defFont );
- prefs->defSize = sDefaultSize;
-
- // get the text style/face info
-
- prefs->defFace = 0; // initialize it to zero to allow proper addition
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextPlainCheck ) )
- prefs->defFace = 0;
- else // plain isn't checked
- {
- if ( HsoiDlgGetCheck( dlg, iPrefsTextBoldCheck ) )
- prefs->defFace += bold;
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextItalicCheck ) )
- prefs->defFace += italic;
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextUnderlineCheck ) )
- prefs->defFace += underline;
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextOutlineCheck ) )
- prefs->defFace += outline;
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextShadowCheck ) )
- prefs->defFace += shadow;
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextCondenseCheck ) )
- prefs->defFace += condense;
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextExtendCheck ) )
- prefs->defFace += extend;
-
- } // end: else plain isn't checked
-
- // the color value is gotten in "case iPrefsTextGetColor" below
-
- // get the radio button setting
-
- if ( HsoiDlgGetRadio( dlg, iPrefsTextLeftRadio ) )
- prefs->defAlign = weFlushLeft;
- else if ( HsoiDlgGetRadio( dlg, iPrefsTextRightRadio ) )
- prefs->defAlign = weFlushRight;
- else if ( HsoiDlgGetRadio( dlg, iPrefsTextCenterRadio ) )
- prefs->defAlign = weCenter;
- else if ( HsoiDlgGetRadio( dlg, iPrefsTextFullRadio ) )
- prefs->defAlign = weJustify;
- // add a "else if kPrefsTextDefaultRadio" in here when defaults are added
-
- else // just in case nothing comes up right, set it to the default
- prefs->defAlign = weFlushDefault;
-
- // and now the features
-
- prefs->useTabHooks = HsoiDlgGetCheck( dlg, iPrefsTextTabHooks );
-
- // set the features to 0 to start out...
-
- prefs->defFeatures = 0;
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextAutoScroll ) )
- BSET( prefs->defFeatures, weFAutoScroll );
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextOutlineHilite ) )
- BSET( prefs->defFeatures, weFOutlineHilite );
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextReadOnly ) )
- BSET( prefs->defFeatures, weFReadOnly );
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextIntCutAndPaste ) )
- BSET( prefs->defFeatures, weFIntCutAndPaste );
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextDragAndDrop ) )
- BSET( prefs->defFeatures, weFDragAndDrop );
-
- if ( HsoiDlgGetCheck( dlg, iPrefsTextOffscreenDrawing ) )
- BSET( prefs->defFeatures, weFDrawOffscreen );
-
- break; // case kTerm
-
- // and now handle things during the dialog
-
- case iPrefsTextFontPopup:
-
- sDefaultFontID = HsoiFontIDFromPopup( dlg, item );
- HsoiSetNewFont( dlg, sDefaultFontID );
-
- break;
-
- case iPrefsTextSizePopup:
-
- HsoiGetPopupPString( HsoiDlgGetControl( dlg, item ), kCurrentPopupItem, tempStr );
- HsoiDlgSetPString( dlg, iPrefsTextSizeEditBox, tempStr );
- SelectDialogItemText( dlg, iPrefsTextSizeEditBox, 0, MAXSHORT );
-
- // fall through!!
-
- case iPrefsTextSizeEditBox:
-
- HsoiDlgGetPString( dlg, iPrefsTextSizeEditBox, tempStr );
- StringToNum( tempStr, &num );
- if ( num != 0 && num != sDefaultSize )
- sDefaultSize = num;
-
- break;
-
- case iPrefsTextPlainCheck:
- HsoiDlgToggleCheck( dlg, item );
- HsoiDlgSetCheck( dlg, iPrefsTextBoldCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextItalicCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextUnderlineCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextOutlineCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextShadowCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextCondenseCheck, false );
- HsoiDlgSetCheck( dlg, iPrefsTextExtendCheck, false );
- break;
-
- case iPrefsTextBoldCheck:
- case iPrefsTextItalicCheck:
- case iPrefsTextUnderlineCheck:
- case iPrefsTextOutlineCheck:
- case iPrefsTextShadowCheck:
- case iPrefsTextCondenseCheck:
- case iPrefsTextExtendCheck:
-
- HsoiDlgToggleCheck( dlg, item );
- HsoiDlgSetCheck( dlg, iPrefsTextPlainCheck, false );
-
- break;
-
-
- case iPrefsTextGetColor:
- {
- Boolean newColorSelected;
- Str255 prompt;
- Point where = { -1, -1 };
- RGBColor oldColor;
- RGBColor newColor;
-
- oldColor = prefs->defColor;
-
- // get the prompt string
-
- GetIndString( prompt, rGetColorStrings, strDefaultTextColor );
-
- // get the color (we ought to change this to PickColor to take advantage
- // of the new color picker)
-
- newColorSelected = GetColor( where, prompt, &oldColor, &newColor );
-
- if ( newColorSelected )
- prefs->defColor = newColor;
-
- // now redraw the color rect
-
- HsoiPaintColorRect( dlg, prefs );
-
- }
- break;
-
-
- case iPrefsTextLeftRadio:
- case iPrefsTextRightRadio:
- case iPrefsTextCenterRadio:
- case iPrefsTextFullRadio:
-
- HsoiSetPrefsRadioButton( dlg, item );
-
- break;
-
- case iPrefsTextTabHooks:
- {
- Boolean checked;
- short i;
-
- HsoiDlgToggleCheck( dlg, item );
-
- // if tab hooks are used, they can only be used with left alignment/justification
- // therefore, if this check box becomes marked we must 1. make sure the left
- // alignment button gets turned on, 2. all the alignnment radio buttons get dimmed
- // (cuase they cannot select anything without messing up tab hooks). And if tab
- // hooks becomes unchecked, make sure to enable the radio buttons, but no need
- // to select a new alignment style
-
- checked = HsoiDlgGetCheck( dlg, item ); // remember, item == iPrefsTextTabHooks
-
- if ( checked )
- {
- HsoiSetPrefsRadioButton( dlg, iPrefsTextLeftRadio );
- for ( i = kPrefsTextFirstRadio; i <= kPrefsTextLastRadio; i++ )
- {
- HiliteControl( HsoiDlgGetControl( dlg, i ), kCtlInactive );
- }
- }
- else
- {
- for ( i = kPrefsTextFirstRadio; i <= kPrefsTextLastRadio; i++ )
- {
- HiliteControl( HsoiDlgGetControl( dlg, i ), kCtlActive );
- }
- }
-
-
- }
- break;
-
- case iPrefsTextAutoScroll:
- case iPrefsTextOutlineHilite:
- case iPrefsTextReadOnly:
- case iPrefsTextIntCutAndPaste:
- case iPrefsTextDragAndDrop:
- case iPrefsTextOffscreenDrawing:
-
- HsoiDlgToggleCheck( dlg, item );
-
- break;
-
- } // end: switch ( item )
-
- return;
- }
-
- // take care of notification manager prefs. this is pretty straight forward (similar
- // to the general prefs dialog handler in it's function)
-
- static void HsoiNMPrefs( HASPreferences *prefs, DialogRef dlg, short item )
- {
- switch ( item )
- {
- case kInit:
- {
- if ( gHasNotification )
- {
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsNMIcon ), kCtlActive );
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsNMDiamond ), kCtlActive );
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsNMSound ), kCtlActive );
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsNMAlert ), kCtlActive );
-
- HsoiDlgSetCheck( dlg, iPrefsNMIcon, prefs->useIconNM );
- HsoiDlgSetCheck( dlg, iPrefsNMDiamond, prefs->useDiamondNM );
- HsoiDlgSetCheck( dlg, iPrefsNMSound, prefs->useSoundNM );
- HsoiDlgSetCheck( dlg, iPrefsNMAlert, prefs->useAlertNM );
- }
- else
- {
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsNMIcon ), kCtlInactive );
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsNMDiamond ), kCtlInactive );
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsNMSound ), kCtlInactive );
- HiliteControl( HsoiDlgGetControl( dlg, iPrefsNMAlert ), kCtlInactive );
-
- HsoiDlgSetCheck( dlg, iPrefsNMIcon, 0 );
- HsoiDlgSetCheck( dlg, iPrefsNMDiamond, 0 );
- HsoiDlgSetCheck( dlg, iPrefsNMSound, 0 );
- HsoiDlgSetCheck( dlg, iPrefsNMAlert, 0 );
- }
-
- }
- break; // end: case kInit
-
- case kTerm:
- prefs->useIconNM = HsoiDlgGetCheck( dlg, iPrefsNMIcon );
- prefs->useDiamondNM = HsoiDlgGetCheck( dlg, iPrefsNMDiamond );
- prefs->useSoundNM = HsoiDlgGetCheck( dlg, iPrefsNMSound );
- prefs->useAlertNM = HsoiDlgGetCheck( dlg, iPrefsNMAlert );
-
- break; // end: case kTerm
-
-
- case iPrefsNMIcon:
- case iPrefsNMDiamond:
- case iPrefsNMSound:
- case iPrefsNMAlert:
-
- HsoiDlgToggleCheck( dlg, item );
-
- break;
-
-
- } // end: switch ( item )
-
- return;
- }
-
- // handle the print prefs dialog
-
- static void HsoiPrintPrefs( HASPreferences *prefs, DialogRef dlg, short item )
- {
- Boolean legal;
- double xx;
-
- switch ( item )
- {
- case kInit:
- {
- // set up the checkboxes
-
- HsoiDlgSetCheck( dlg, iPrefsPrintPageNum, prefs->printPageNumbers );
- HsoiDlgSetCheck( dlg, iPrefsPrintDblSpace, prefs->printDoubleSpaced );
-
- // set the margin edit text's to the proper sizes
-
- SetDialogItemText( HsoiGetDialogItemHandle( dlg, iPrefsPrintTextTop ), prefs->printTopMargin );
- SetDialogItemText( HsoiGetDialogItemHandle( dlg, iPrefsPrintTextBottom ), prefs->printBottomMargin );
- SetDialogItemText( HsoiGetDialogItemHandle( dlg, iPrefsPrintTextLeft), prefs->printLeftMargin );
- SetDialogItemText( HsoiGetDialogItemHandle( dlg, iPrefsPrintTextRight), prefs->printRightMargin );
-
- // and install our framing proc
-
- HsoiSetDialogItemProc( dlg, iPrefsPrintLineItem, frameItemsUPP );
- HsoiSetDialogItemProc( dlg, iPrefsPrintMarginFrame, frameItemsUPP );
-
- // and go ahead and select all the text in the first edit text
-
- SelectDialogItemText( dlg, iPrefsPrintTextTop, 0, MAXSHORT );
- }
- break; // end: case kInit
-
- case kTerm:
-
- // get the values of the check boxes
-
- prefs->printPageNumbers = HsoiDlgGetCheck( dlg, iPrefsPrintPageNum );
- prefs->printDoubleSpaced = HsoiDlgGetCheck( dlg, iPrefsPrintDblSpace );
-
- // get the margin settings
-
- GetDialogItemText( HsoiGetDialogItemHandle( dlg, iPrefsPrintTextTop ), prefs->printTopMargin );
- GetDialogItemText( HsoiGetDialogItemHandle( dlg, iPrefsPrintTextBottom ), prefs->printBottomMargin );
- GetDialogItemText( HsoiGetDialogItemHandle( dlg, iPrefsPrintTextLeft ), prefs->printLeftMargin );
- GetDialogItemText( HsoiGetDialogItemHandle( dlg, iPrefsPrintTextRight), prefs->printRightMargin );
-
- break; // end: case kTerm
-
-
- case iPrefsPrintPageNum:
- case iPrefsPrintDblSpace:
-
- HsoiDlgToggleCheck( dlg, item );
-
- break;
-
- case iPrefsPrintTopUpUserItem:
- HsoiGetDialogItemValue( dlg, iPrefsPrintTextTop, 0.00, kMaxMargin, &legal, &xx );
- HsoiDoArrowUpDown( dlg, iPrefsPrintTopUpUserItem, iPrefsPrintTextTop, iPrefsPrintTopArrowIcon, 0.01, 0.00, kMaxMargin, true, &xx );
- break;
-
- case iPrefsPrintTopDownUserItem:
- HsoiGetDialogItemValue( dlg, iPrefsPrintTextTop, 0.00, kMaxMargin, &legal, &xx );
- HsoiDoArrowUpDown( dlg, iPrefsPrintTopDownUserItem, iPrefsPrintTextTop, iPrefsPrintTopArrowIcon, -0.01, 0.00, kMaxMargin, true, &xx );
- break;
-
- case iPrefsPrintBotUpUserItem:
- HsoiGetDialogItemValue( dlg, iPrefsPrintTextBottom, 0.00, kMaxMargin, &legal, &xx );
- HsoiDoArrowUpDown( dlg, iPrefsPrintBotUpUserItem, iPrefsPrintTextBottom, iPrefsPrintBotArrowIcon, 0.01, 0.00, kMaxMargin, true, &xx );
- break;
-
- case iPrefsPrintBotDownUserItem:
- HsoiGetDialogItemValue( dlg, iPrefsPrintTextBottom, 0.00, kMaxMargin, &legal, &xx );
- HsoiDoArrowUpDown( dlg, iPrefsPrintBotDownUserItem, iPrefsPrintTextBottom, iPrefsPrintBotArrowIcon, -0.01, 0.00, kMaxMargin, true, &xx );
- break;
-
- case iPrefsPrintLeftUpUserItem:
- HsoiGetDialogItemValue( dlg, iPrefsPrintTextLeft, 0.00, kMaxMargin, &legal, &xx );
- HsoiDoArrowUpDown( dlg, iPrefsPrintLeftUpUserItem, iPrefsPrintTextLeft, iPrefsPrintLeftArrowIcon, 0.01, 0.00, kMaxMargin, true, &xx );
- break;
-
- case iPrefsPrintLeftDownUserItem:
- HsoiGetDialogItemValue( dlg, iPrefsPrintTextLeft, 0.00, kMaxMargin, &legal, &xx );
- HsoiDoArrowUpDown( dlg, iPrefsPrintLeftDownUserItem, iPrefsPrintTextLeft, iPrefsPrintLeftArrowIcon, -0.01, 0.00, kMaxMargin, true, &xx );
- break;
-
- case iPrefsPrintRightUpUserItem:
- HsoiGetDialogItemValue( dlg, iPrefsPrintTextRight, 0.00, kMaxMargin, &legal, &xx );
- HsoiDoArrowUpDown( dlg, iPrefsPrintRightUpUserItem, iPrefsPrintTextRight, iPrefsPrintRightArrowIcon, 0.01, 0.00, kMaxMargin, true, &xx );
- break;
-
- case iPrefsPrintRightDownUserItem:
- HsoiGetDialogItemValue( dlg, iPrefsPrintTextRight, 0.00, kMaxMargin, &legal, &xx );
- HsoiDoArrowUpDown( dlg, iPrefsPrintRightDownUserItem, iPrefsPrintTextRight, iPrefsPrintRightArrowIcon, -0.01, 0.00, kMaxMargin, true, &xx );
- break;
-
- } // end: switch ( item )
-
- return;
- }
-
-
- #pragma mark -
- #pragma mark ••• Prefs Dialog •••
-
-
-
- /* the prefs dialog filter */
-
- pascal Boolean hsoiPrefsDialogFilter( DialogRef theDialog, EventRecord *theDialogEvent, short *theDialogItem )
- {
- #pragma unused( theDialogItem )
-
- Boolean retval;
- short part;
- WindowRef theWindow;
- Point where;
- short itemNumber;
- Str255 str;
- Boolean numeric;
- ControlRef popupCtl;
- extern short curDlgNum;
- GrafPtr oldPort;
- char theKey;
-
- GetPort( &oldPort );
- SetGrafPortOfDialog( theDialog );
-
- retval = false;
-
- // Norstad handles tracking the cursor here...we don't cause we just call
- // SetDialogTrackCursor() back in DoPrefsDialog() to track the cursor. Luv System 7
-
- // but, let's track the mouseDown events just in case they depress the popup menus
-
- if ( theDialogEvent->what == mouseDown )
- {
- part = FindWindow( theDialogEvent->where, &theWindow );
-
- if ( (part == inContent) && ( theWindow == GetDialogWindow(theDialog) ) )
- {
- where = theDialogEvent->where;
- GlobalToLocal( &where );
- itemNumber = FindDialogItem( theDialog, where );
- itemNumber += 1; // gotta add 1 to it, see TN 112
-
- // this is really skanky...
-
- if ( itemNumber > 0 )
- {
- if ( ( curDlgNum == rPrefsTextDLOG ) && ( itemNumber == iPrefsTextSizePopup ) )
- {
-
- SelectDialogItemText( theDialog, iPrefsTextSizeEditBox, 0, MAXSHORT );
- HsoiDlgGetPString( theDialog, iPrefsTextSizeEditBox, str );
- popupCtl = HsoiDlgGetControl( theDialog, itemNumber );
- numeric = 1;
-
- if ( HsoiTrackPopup( popupCtl, where, str, numeric ) )
- {
- *theDialogItem = itemNumber;
- // SetDialogItemText( HsoiGetDialogItemHandle(theDialog, iPrefsTextSizeEditBox), str );
- retval = true;
- }
- else
- {
- retval = false;
- }
- }
- }
- }
- }
-
- // now, let's handle some keydown stuff...you could filter all keys out if you want to,
- // but the really important part is in the text dialog. the edit text field in there
- // is for font size, which should only accept certain values (numerics, and not a lot
- // of them...don't want 40000000 point size now do we). So, this will filter things out
-
- if ( (( theDialogEvent->what == keyDown ) || ( theDialogEvent->what == autoKey )) &&
- ( curDlgNum == rPrefsTextDLOG ) )
- {
- theKey = theDialogEvent->message & charCodeMask;
-
- // the first line of this "if" is the important one to filter out non-numeric keys,
- // however, that also filters out a lot of important keys, like return/enter, esc,
- // and editing keys - keys necessary for regular dialog stuff. so, we must make exceptions.
-
- if ( !(theKey > 0x2F && theKey < 0x3A) && // it's not a number
- ( theKey != kEnterKey ) && // it's not the Enter key
- ( theKey != kReturnKey ) && // it's not the return key
- ( theKey != kEscKey ) && // it's not the escape key
- ( theKey != kBackSpace ) && // it's not backspace
- ( theKey != kDeleteKey ) && // it's not delete
- ( theKey != kLeftArrow ) && // it's not an arrow key (for editing)
- ( theKey != kRightArrow ) &&
- ( theKey != kUpArrow ) &&
- ( theKey != kDownArrow ) )
- {
- // not a kosher key..let's complain
-
- SysBeep( 1 );
- retval = true; // we handled it so no passing to the DM
- }
- else // it's a kosher keypress
- retval = false; // let the DM handle it
-
-
- // now an additional bit of filtering. we wouldn't want the user to be able to
- // enter a font size greater (or less) than the sizes we're supporting (in this case,
- // from 1 to 500 inclusive). So, we must make sure they don't do it. You can see one
- // way to handle this in the OtherFontSize dialog, but this is another, and due to
- // the complexity of the prefs, we'll go with this alternative method.
- // the jist: if a kosher key, if a number (cause there are other kosher keys than just
- // numerics), and if the dialog is the text one (redundant to do this), then we'll
- // see if the keypress would make a number that would give us an invalid font size.
- // if it would, vomit, if not let the keypress fall to the DM
-
- // unfortunately, this is INCOMPLETE right now...there's a catch..i forgot about what
- // could happen if there was a selection range and/or the insertion point wasn't at
- // the end of the text....those present all other sorts of problems...
- // if you can figure out a way to handle all this, great! tell me! :) Otherwise,
- // for now, it'll just sit and wait....
-
- if ( (retval == false) && (theKey > 0x2F && theKey < 0x3A) && (curDlgNum == rPrefsTextDLOG) )
- {
- Str255 editText;
- long fontSize;
- short strLength;
-
- // now, since we know it's the prefs text dialog, we can "hard code" a few things
- // (like we know exactly the item number in the DITL for the edit box...if you wanted
- // to make this more flexible, you'd have to add a lot of programmer-defined data
- // structures, etc to keep track of things...i don't wanna bother cause i really
- // don't need it here). it'd be a good learning exercise for ya :)
-
- // first, we get the currently existing text in the edit text item:
-
- GetDialogItemText( HsoiGetDialogItemHandle( theDialog, iPrefsTextSizeEditBox ), editText );
-
- // now the fun part: since the existing text doesn't have the new key on the end of
- // it, we'll append it there ourselves to check if it'd make a (in)valid size.
-
- strLength = editText[0]; // get the length of the string
-
- // now append the key (cause we have it via the charCodeMask) to the end:
-
- editText[ strLength + 1] = theKey;
-
- // convert to a number
-
- StringToNum( editText, &fontSize );
-
- // and now choose to vomit...
-
- // as you can tell, this little part of the dialog filter isn't finished yet...
-
- }
-
-
- }
-
- // due to these lovely system 7 functions, there really isn't much for us to have
- // to handle in the filter, except to
-
- if ( !retval )
- retval = hsoiMyStandardDialogFilter( theDialog, theDialogEvent, theDialogItem );
-
-
- // however, we will need to put something in here to filter things out...i think the
- // only keydown's that need to get filtered out...well, hmm...i guess any and all
- // keydown's ought to get filtered out...except if the text prefs is up, then there
- // is one edit text box, and then they should only be allowed to enter numerics
-
- // on that note...we can just duplicate the otherFontSizeDialogFilter for this, but
- // in both this one and in otherFontSizeDialogFilter, we ought to see about adding
- // in stuff to limit the text size entered...like up to 3 characters...plus, we'll
- // need to check the cut and paste stuff...first, cannot paste stuff longer than
- // 3 characters, but also, cannot paste anything but pure numbers! boy, this'll
- // be a fun filter, eh?
-
- SetPort( oldPort );
-
- return retval;
- }
-
- /* where it all begins... */
-
-
- void HsoiDoPrefsDialog( void )
- {
- typedef void (*prefsFuncPtr) ( HASPreferences *prefs, DialogRef dlg, short item );
-
- static prefsFuncPtr prefsFuncPtrs[] = {
- HsoiGeneralPrefs,
- HsoiTextPrefs,
- HsoiNMPrefs,
- HsoiPrintPrefs
- };
-
- short newDlgNum;
- prefsFuncPtr theFunc;
- HASPreferences *prefs;
- DialogRef curDlg;
- DialogRef prevDlg = nil;
- short item;
- OSErr err;
- Handle controlH;
- ModalFilterUPP prefsDialogFilterProc;
-
- // if we have a sound playing, stop it
-
- if ( SoundIsPlaying() )
- StopCurrentSound();
-
- // create a working prefs instance
-
- prefs = (HASPreferences *)NewPtrClear( sizeof( HASPreferences ) );
- err = MemError();
- if ( err != noErr )
- {
- // stick some error handling in here
-
- prefs = nil;
-
- // probably ought to return err or something here too.
-
- // or, just impliment Norstad's method of memory handling, etc.
- }
-
- *prefs = gMyPrefs;
-
- // get our frame item UPP (get it now, but use it only in the text prefs
- // (it gets installed in HsoiTextPrefs)
-
- if ( frameItemsUPP == nil )
- frameItemsUPP = NewUserItemProc( HsoiDrawGroupBox );
-
- while ( true )
- {
- // get the dialog
- curDlg = GetNewDialog( curDlgNum, nil, MOVE_TO_FRONT );
-
- // set the topic popup menu to the initial dialog
-
- controlH = HsoiGetDialogItemHandle( curDlg, iPrefsTopicPopup );
- SetControlValue( (ControlRef)controlH, curDlgNum - rPrefsGeneralDLOG + 1 );
-
- // set the proper function callback routine
-
- theFunc = prefsFuncPtrs[ curDlgNum - rPrefsGeneralDLOG ];
-
- // call that proper function callback to set it to it's initial values
-
- (*theFunc)(prefs, curDlg, kInit );
-
- // show the dialog
-
- ShowWindow( GetDialogWindow(curDlg) );
-
- // if curDlgNum is the text prefs dialog, paint the "default" text color
- // setting rect
-
- if ( curDlgNum == rPrefsTextDLOG )
- HsoiPaintColorRect( curDlg, prefs );
-
- // if need be, get rid of the previous dialog box
-
- if ( prevDlg != nil )
- DisposeDialog( prevDlg );
-
- // get the modal filter proc
-
- prefsDialogFilterProc = NewModalFilterProc( hsoiPrefsDialogFilter );
-
- // let the system know to track the cursor movement
- // don't need to call SetDialogDefault/CancelItem() at all cause that's
- // handled in the filter via HsoiMyStandardDialogFilter()
-
- SetDialogTracksCursor( curDlg, true );
-
- // do the dialog
-
- while ( true )
- {
- ModalDialog( prefsDialogFilterProc, &item );
-
- if ( item == cancel )
- break;
-
- if ( item == ok )
- {
- if ( curDlgNum == rPrefsTextDLOG )
- {
- Str255 editText;
- long fontSize;
-
- // check for illegal font sizes in the prefs text dialog
-
- GetDialogItemText( HsoiGetDialogItemHandle( curDlg, iPrefsTextSizeEditBox ), editText );
- StringToNum( editText, &fontSize );
-
- if ( (fontSize > kMaxFontSize) || (fontSize < kMinFontSize) )
- {
- HsoiDoIllegalFontSize();
- SelectDialogItemText( curDlg, iPrefsTextSizeEditBox, 0, MAXSHORT );
-
- continue;
- }
- else
- break;
- }
- else
- break;
- }
-
-
- if ( item == iPrefsTopicPopup )
- {
- controlH = HsoiGetDialogItemHandle( curDlg, iPrefsTopicPopup );
- newDlgNum = GetControlValue( (ControlRef)controlH ) + rPrefsGeneralDLOG - 1;
-
- if ( newDlgNum == curDlgNum )
- continue;
-
- // check for illegal font sizes if they try to leave the text dialog....
-
- if ( (curDlgNum == rPrefsTextDLOG) && (newDlgNum != rPrefsTextDLOG) )
- {
- Str255 editText;
- long fontSize;
-
- GetDialogItemText( HsoiGetDialogItemHandle( curDlg, iPrefsTextSizeEditBox ), editText );
- StringToNum( editText, &fontSize );
-
- if ( (fontSize > kMaxFontSize) || (fontSize < kMinFontSize) )
- {
- HsoiDoIllegalFontSize();
-
- // we need to set the popup back to the text prefs
-
- SetControlValue( (ControlRef)controlH, 2 );
-
- // and select the edit text
-
- SelectDialogItemText( curDlg, iPrefsTextSizeEditBox, 0, MAXSHORT );
-
- continue;
- }
- else
- break;
- }
-
- break;
- } // end if ( item == iPrefsTopicPopup )
-
- // not a "special" case, so let the individual dialog pane functions
- // handle the item hit
-
- (*theFunc)(prefs, curDlg, item);
- }
-
- // call the termination stuff
-
- (*theFunc)(prefs, curDlg, kTerm);
-
- // and if ok or cancel, break out of this loop
-
- if ( item == ok || item == cancel )
- break;
-
- // reset the dlg stuff so we know what's current
-
- curDlgNum = newDlgNum;
- prevDlg = curDlg;
-
- } // end: while ( true )
-
- // dump our routine descriptors
-
- DisposeRoutineDescriptor( prefsDialogFilterProc );
- DisposeRoutineDescriptor( frameItemsUPP );
-
- // dump the dialog
- DisposeDialog( curDlg );
-
- if ( item == ok )
- {
- // notify of any possible messages (e.g. changes take effect on next restart)
-
- // set the global prefs in memory to the changes made in here
-
- gMyPrefs = *prefs;
-
- // most likely we have new prefs settings so schedule the new prefs to be
- // written out to file
-
- gWritePrefs = true;
- }
-
- // don't need to write out a new prefs file since nothing changed (we hope)
-
- if ( item == cancel )
- gWritePrefs = false;
-
- // remember to chuck this so we don't have a memory leak
-
- DisposePtr( (Ptr)prefs );
-
- return;
- }
-
- #pragma mark -
- #pragma mark ••• Prefs File Handlers •••
-
- /*
- * Now to deal with other preference related things, like reading and writing the prefs file
- * and other stuff like that there
- */
-
-
-
- // let's initialize the prefs related things. we do a few things here:
- // 1. we try to find where the prefs file is 2. if there was no prefs file found, we'll
- // have to create a new prefs file, so let's do the registration dialog. 3. read the
- // prefs into memory.
-
- void HsoiInitPrefs( void )
- {
- Boolean readOK;
-
- HsoiLocatePrefsFile();
-
- if ( sNewPrefs )
- {
- gWritePrefs = true;
- HsoiDoRegistration();
- }
-
- readOK = HsoiReadPrefs();
-
- return;
- }
-
- // try to find the prefs file
-
- void HsoiLocatePrefsFile( void )
- {
- OSErr err;
- FInfo fndrInfo;
- FSSpec oldFile;
- FCBPBRec pBlock;
- FSSpec prefsFolder;
- CInfoPBRec pb;
-
- sNewPrefs = false; // assume we don't need new prefs
-
- // check to see if there is a prefs file in the same folder as the application.
- // if so, use that prefs file
-
- pBlock.ioNamePtr = nil;
- pBlock.ioVRefNum = 0;
- pBlock.ioRefNum = LMGetCurApRefNum();
- pBlock.ioFCBIndx = 0;
- err = PBGetFCBInfoSync(&pBlock );
- if (err == noErr)
- {
- err = FSMakeFSSpec(pBlock.ioFCBVRefNum, pBlock.ioFCBParID, PREF_FILE_NAME, &gPrefsFileSpec);
- if ( err == fnfErr )
- sNewPrefs = true;
- if (err == noErr)
- {
- err = FSpGetFInfo(&gPrefsFileSpec, &fndrInfo);
- if (err == noErr)
- {
- sNewPrefs = false;
- goto exit;
- }
- }
- }
-
-
- // Construct gPrefsFileSpec = FSSpec for "Hsoi's App Shell Demo Prefs" file
- // in Preferences folder.
-
- err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
- &gPrefsFileSpec.vRefNum, &gPrefsFileSpec.parID);
- if (err != noErr)
- {
- // do some better error handling...
- SysBeep(1);
- SysBeep(2);
- ExitToShell();
- }
-
- HsoipStringCopy( PREF_FILE_NAME, gPrefsFileSpec.name );
-
- // Check to see if "Hsoi's App Shell Demo Prefs" exists in the Preferences
- // folder. If it does exist, use that one.
-
- err = FSpGetFInfo(&gPrefsFileSpec, &fndrInfo);
- if ( err == fnfErr )
- sNewPrefs = true;
- if (err == noErr)
- {
- sNewPrefs = false;
- goto exit;
- }
-
- // If "Hsoi's App Shell Demo Prefs" does not exist in the Preferences
- // folder, next try "HAS Demo Preferences" in the Preferences folder. If that
- // exists, rename it "Hsoi's App Shell Demo Prefs".
-
- err = FSMakeFSSpec(gPrefsFileSpec.vRefNum, gPrefsFileSpec.parID, PREF_FILE_NAME_OLD, &oldFile);
- if ( err == fnfErr )
- sNewPrefs = true;
- if (err == noErr)
- {
- sNewPrefs = false;
- FSpRename(&oldFile, PREF_FILE_NAME);
- return;
- }
-
- // If this fails, next try "HAS Demo Preferences" in the System folder. If that
- // exists, move it to the Preferences folder and rename it "Hsoi's App Shell Demo Prefs".
-
- err = FindFolder(kOnSystemDisk, kSystemFolderType, kCreateFolder, &oldFile.vRefNum,
- &oldFile.parID);
- if (err != noErr)
- return;
-
- pb.dirInfo.ioNamePtr = prefsFolder.name;
- pb.dirInfo.ioVRefNum = gPrefsFileSpec.vRefNum;
- pb.dirInfo.ioFDirIndex = -1;
- pb.dirInfo.ioDrDirID = gPrefsFileSpec.parID;
-
- err = PBGetCatInfoSync( &pb );
- if (err != noErr)
- return;
-
- prefsFolder.vRefNum = pb.dirInfo.ioVRefNum;
- prefsFolder.parID = pb.dirInfo.ioDrParID;
-
- err = FSpCatMove(&oldFile, &prefsFolder);
- if ( err == fnfErr )
- sNewPrefs = true;
- if (err != noErr)
- return;
-
- oldFile.vRefNum = gPrefsFileSpec.vRefNum;
- oldFile.parID = gPrefsFileSpec.parID;
-
- err = FSpRename(&oldFile, PREF_FILE_NAME);
- if (err != noErr)
- return;
-
- err = FSpGetFInfo(&gPrefsFileSpec, &fndrInfo);
- if (err != noErr)
- return;
-
- fndrInfo.fdFlags &= ~(1 << 8); /* clear hasBeenInited to force Finder to
- assign new icon location */
- FSpSetFInfo(&gPrefsFileSpec, &fndrInfo);
- sNewPrefs = false;
-
- return;
-
- exit:
-
- if (fndrInfo.fdCreator == PREF_CREATOR_TYPE && fndrInfo.fdType == TYPE_PREFERENCES)
- return;
-
- // else we hit an error...bad error handling here, but eh...
-
- SysBeep(1);SysBeep(2);SysBeep(3);
- ExitToShell();
-
- }
-
- /*
- this reads in the prefs settings from the prefs file. one neat thing it does (and
- you can see this same philosophy in the way all the prefs releated stuff is set up)
- is allow for compatability between releases. here's how it works.
-
- you make your application, you release it to the world and a lot of people start to
- use it. you continue to work on the app, and in a future release, you added more
- prefs settings. The way things are designed in HAS allows you to seemlessly update
- things. Old prefs files (from previous versions of your app) will still be read
- in and those settings utilized, and any new features you have get initialized to
- your default settings.
-
- if you'd like to see this in action, go down to the line where the APP_VERS_STR
- is copied into the gMyPrefs variable. change APP_VERS_STR to a previous version
- of HAS (like "\p0.9a3"...i.e. HsoipStringCopy( "\p0.9a3", gMyPrefs.prefVers );)
-
- Now, trash your prefs file, launch the HAS Demo (you'll obviously have to compile
- things again), then quit (to get the prefs to write out). Now come back into
- the code and change that line back to APP_VERS_STR.
-
- oh, and you might want to throw something in in the
- if ( need10a1Defaults )
- statement like: DebugStr( "\pNeeded 1.0a1 defaults" ); to really watch things
- happen.
-
- you should see things kick in.
-
- get it? look over the code and as you add prefs and stuff, you'll get the
- idea.
-
- for an even better view of seeing this in some heavy action, check out the
- source code to John Norstad's NewsWatcher (upon which all this prefs stuff
- was derrived).
-
- As a side note, in all this backwards compatability, if you remove some
- prefs feature, don't remove it's struct member. for example, if i no
- longer wished to use the notification manager, you'd think to remove all
- the NM stuff from the prefs struct. do NOT do this...else in backwards
- compatability, when reading in the struct (see how FSRead is done), values
- will get assigned to god knows what....be careful! just allow them to be
- read in, but ignore them....
-
- */
-
- Boolean HsoiReadPrefs( void )
- {
- OSErr err;
- short fRefNum = 0;
- long prefRecSize;
- Boolean need09a2Defaults = true;
- Boolean need09a3Defaults = true;
- Boolean need10a1Defaults = true;
- Boolean need10a2Defaults = true;
- Boolean need10a3Defaults = true;
- Boolean haveFont;
- short fontNum;
-
- // open the prefs file
-
- err = FSpOpenDF( &gPrefsFileSpec, fsRdPerm, &fRefNum );
-
- if ( err == noErr )
- {
- // get the size of the prefs rec
-
- prefRecSize = sizeof( HASPreferences );
-
- // read all the file in in one big chunk
-
- err = FSRead( fRefNum, &prefRecSize, (Ptr)&gMyPrefs );
- if ( (err == noErr) && (prefRecSize == sizeof( HASPreferences )) )
- {
- // if it succeeded, we obviously don't need 0.9a2 defaults (cause
- // that was the first version to use prefs)
-
- need09a2Defaults = false;
-
- // now cycle through, checking the version number to find what
- // version the prefs are
-
- if ( EqualString( gMyPrefs.prefVers, "\p0.9a3", false, false ) )
- {
- need09a3Defaults = false;
- }
-
- if ( EqualString( gMyPrefs.prefVers, "\p1.0a1", false, false ) )
- {
- need09a3Defaults = false;
- need10a1Defaults = false;
- }
-
- if ( EqualString( gMyPrefs.prefVers, "\p1.0a2", false, false ) )
- {
- need09a3Defaults = false;
- need10a1Defaults = false;
- need10a2Defaults = false;
- }
-
- if ( EqualString( gMyPrefs.prefVers, "\p1.0a3", false, false ) )
- {
- need09a3Defaults = false;
- need10a1Defaults = false;
- need10a2Defaults = false;
- need10a3Defaults = false;
- }
-
- /* and you could continue this with subsequent versions like this:
-
- else if ( EqualString( gMyPrefs.prefVers, "\p1.0a4", false, false ) )
- {
- need09a3Defaults = false;
- need10a1Defaults = false;
- need10a2Defaults = false;
- need10a3Defaults = false;
- need10a4Defaults = false;
- }
- else if ( EqualString( gMyPrefs.prefVers, "\p1.0b1", false, false ) ||
- ( EqualString( gMyPrefs.prefVers, "\p1.0r1", false, false ) ) ) // prefs struct didn't change between these versions
- {
- need09a3Defaults = false;
- need10a1Defaults = false;
- need10a2Defaults = false;
- need10a3Defaults = false;
- need10b1Defaults = false;
- need10r1Defaults = false;
- }
- */
- }
- else // if ( err == noErr && count == sizeof( HASPrefernces ) )
- {
- FSClose( fRefNum );
- fRefNum = 0;
- }
- }
- else // if err == noErr
- {
- fRefNum = 0;
- }
-
- // now, depending on what defaults we need, assign them to our prefs struct instance
- // so we have some default values
-
- if ( need09a2Defaults )
- {
- // version string
-
- HsoipStringCopy( APP_VERS_STR, gMyPrefs.prefVers );
-
- // default user name and user org
- // handled in the HsoiInitPrefs() stuff
-
- // HsoipStringCopy( DEFAULT_USERNAME, gMyPrefs.userName );
- // HsoipStringCopy( DEFAULT_ORGANIZATION, gMyPrefs.userOrg );
-
- // default text stuff
-
- HsoipStringCopy( "\pGeneva", gMyPrefs.defFont );
- gMyPrefs.defFace = normal;
- gMyPrefs.defSize = 12;
- gMyPrefs.defColor.red = 0x0000;
- gMyPrefs.defColor.green = 0x0000;
- gMyPrefs.defColor.blue = 0x0000;
- gMyPrefs.defAlign = weFlushLeft;
-
-
- // set the features
-
- gMyPrefs.useTabHooks = false;
- BSET( gMyPrefs.defFeatures, weFAutoScroll );
- BSET( gMyPrefs.defFeatures, weFOutlineHilite );
- BSET( gMyPrefs.defFeatures, weFIntCutAndPaste );
- BSET( gMyPrefs.defFeatures, weFDragAndDrop );
- BSET( gMyPrefs.defFeatures, weFDrawOffscreen );
-
- // set the notification manager stuff
-
- if ( gHasNotification )
- {
- gMyPrefs.useIconNM = true;
- gMyPrefs.useDiamondNM = true;
- gMyPrefs.useSoundNM = true;
- gMyPrefs.useAlertNM = true;
- }
- else
- {
- gMyPrefs.useIconNM = false;
- gMyPrefs.useDiamondNM = false;
- gMyPrefs.useSoundNM = false;
- gMyPrefs.useAlertNM = false;
- }
-
- // and the general prefs
-
- gMyPrefs.createWindow = true;
- gMyPrefs.playHelpSound = true;
- gMyPrefs.doSplashScreen = true;
- gMyPrefs.doStartupSpeech = gHasSpeechManager;
-
- // make sure the prefs will be written out when we quit
-
- gWritePrefs = true;
- }
-
- if ( need09a3Defaults )
- {
- // nothing really to add, but just make sure we have the
- // new version string
-
- HsoipStringCopy( APP_VERS_STR, gMyPrefs.prefVers );
- gWritePrefs = true;
- }
-
- if ( need10a1Defaults )
- {
- // nothing really to add, but just make sure we have the
- // new version string
-
- HsoipStringCopy( APP_VERS_STR, gMyPrefs.prefVers );
- gWritePrefs = true;
- }
-
- if ( need10a2Defaults )
- {
- gMyPrefs.printPageNumbers = true;
- HsoipStringCopy( "\p1.0", gMyPrefs.printLeftMargin );
- HsoipStringCopy( "\p1.0", gMyPrefs.printRightMargin );
- HsoipStringCopy( "\p1.0", gMyPrefs.printTopMargin );
- HsoipStringCopy( "\p1.0", gMyPrefs.printBottomMargin );
- gMyPrefs.printDoubleSpaced = true;
- HsoipStringCopy( "\p", gMyPrefs.sVoiceStr );
- gMyPrefs.sVoiceRate = 0;
- gMyPrefs.sVoiceMod = 0;
- gMyPrefs.sVoicePitch = 0;
-
- HsoipStringCopy( APP_VERS_STR, gMyPrefs.prefVers );
- gWritePrefs = true;
-
- }
-
- if ( need10a3Defaults )
- {
- // nothing really to add, but just make sure we have the
- // new version string
-
- HsoipStringCopy( APP_VERS_STR, gMyPrefs.prefVers );
- gWritePrefs = true;
- }
-
- /* and if you had more things...
-
- if ( need10a4Defaults )
- {
- gMyPrefs.newFeature = false;
- gMyPrefs.anotherThing = -1;
- }
-
- etc...
- */
-
- // make sure the prefVers is set right...it should already be set by the
- // above stuff, but hey...we'll make sure (good for sanity checking and
- // debugging purposes).
-
- HsoipStringCopy( APP_VERS_STR, gMyPrefs.prefVers );
-
- // make sure we have the desired font on the system (it might have been deleted, not available,
- // the user might use a font manager like Suitcase therefore it's not around right now, etc)
-
- haveFont = HsoiGetFontNumber( gMyPrefs.defFont, &fontNum );
-
- if ( !haveFont )
- {
- ParamText( "\pThe font", gMyPrefs.defFont, "\pdoes not exist on this system.",
- "\pGeneva will be used instead" );
-
- NoteAlert( rPrefsErrorAlert, HsoiGetMyStandardDialogFilter() );
-
- HsoipStringCopy( "\pGeneva", gMyPrefs.defFont );
- }
-
- if ( fRefNum == 0 )
- return true;
-
- FSClose( fRefNum );
-
- return true;
-
- exit:
-
- if ( fRefNum != 0 )
- FSClose( fRefNum );
-
- return false;
- }
-
- // simply enough, write the prefs to the file
-
- void HsoiWritePrefs( void )
- {
- OSErr err;
- short fRefNum = 0, resRefNum = 0;
- long count;
- Str255 numString;
- Handle strHandle;
- short strID;
- ResType strType;
- Str255 strName;
- Boolean newPrefs = false;
-
- // open the prefs file
-
- err = FSpOpenDF( &gPrefsFileSpec, fsRdWrPerm, &fRefNum );
-
- // if it doesn't exist, create it
-
- if (err == fnfErr)
- {
- FSpCreateResFile(&gPrefsFileSpec, PREF_CREATOR_TYPE, TYPE_PREFERENCES, smSystemScript );
- err = ResError();
- if ( err != noErr )
- goto exit;
- else
- {
- // created it, open it
-
- err = FSpOpenDF( &gPrefsFileSpec, fsRdWrPerm, &fRefNum );
- newPrefs = true;
- }
- }
- if (err != noErr)
- goto exit;
-
- // write the prefs settings in one big block to the file
-
- count = sizeof( HASPreferences );
- err = FSWrite(fRefNum, &count, &gMyPrefs);
- if (err != noErr)
- goto exit;
-
-
- FSClose(fRefNum);
-
- if ( newPrefs )
- {
- // now add the message string resource to the file (if they click on the prefs file,
- // it'll give them this message instead of something generic and/or launching your app
-
- resRefNum = FSpOpenResFile( &gPrefsFileSpec, fsRdWrPerm );
- err = ResError();
- if ( err != noErr )
- goto exit;
-
- // the following is pretty much taken directly from IM: Toolbox Essentials, 7-29 and is
- // similar to what i use in HsoiWriteTextFile() to add the name string resource
-
-
- UseResFile( gAppResourceFork );
-
- strHandle = GetResource( 'STR ', strMessageString );
-
- if ( strHandle != nil )
- {
- GetResInfo( strHandle, &strID, &strType, strName );
- DetachResource( strHandle );
-
- UseResFile( resRefNum );
- AddResource( strHandle, strType, -16397, strName );
-
- if ( ResError() == noErr )
- WriteResource( strHandle );
- }
-
- CloseResFile( resRefNum );
- }
-
- FlushVol( nil, gPrefsFileSpec.vRefNum);
- return;
-
- exit:
-
- // we should only get here if there was an error...
-
- if (fRefNum != 0)
- FSClose(fRefNum);
- if ( resRefNum != 0 )
- CloseResFile( resRefNum );
- FlushVol(nil, gPrefsFileSpec.vRefNum);
- NumToString( err, numString );
- ParamText( "\pAn error occured while attempting to write to the preferences file",
- NIL_STRING, "\pError =", numString );
- StopAlert( rPrefsErrorAlert, HsoiGetMyStandardDialogFilter() );
-
- return;
- }
-
- #pragma mark -
- #pragma mark ••• Registration •••
-
- // does our registration dialog
-
- void HsoiDoRegistration( void )
- {
- DialogRef regDialog;
- short itemHit;
- Handle editTextH;
- Str255 tempStr;
- StringHandle appName;
-
- // get the dialog
-
- regDialog = GetNewDialog( rRegistrationDialog, nil, MOVE_TO_FRONT );
-
- if ( regDialog == nil )
- {
- // if it messed up, just make the user and org names the "defaults"
-
- HsoipStringCopy( DEFAULT_USERNAME, gMyPrefs.userName );
- HsoipStringCopy( DEFAULT_ORGANIZATION, gMyPrefs.userOrg );
-
- return;
- }
-
- // set the tracking
-
- SetDialogDefaultItem( regDialog, ok );
- SetDialogCancelItem( regDialog, cancel );
- SetDialogTracksCursor( regDialog, true );
-
- // get the app name
-
- appName = GetString( strAppNameString );
- DetachResource( (Handle)appName );
- ParamText( *appName, NIL_STRING, NIL_STRING, NIL_STRING );
-
- // set the user name field to some default setting
-
- editTextH = HsoiGetDialogItemHandle( regDialog, iRegDialogUserName );
- HLock( editTextH );
- SetDialogItemText( editTextH, DEFAULT_USERNAME );
- HUnlock( editTextH );
-
- // set the org field to the default
-
- editTextH = HsoiGetDialogItemHandle( regDialog, iRegDialogOrgName );
- HLock( editTextH );
- SetDialogItemText( editTextH, DEFAULT_ORGANIZATION );
- HUnlock( editTextH );
-
- // select the text to look nice
-
- SelectDialogItemText( (DialogRef)regDialog, iRegDialogUserName, 0, MAXSHORT );
-
- // show the window
-
- ShowWindow( GetDialogWindow(regDialog) );
-
- // do modal dialog
-
- do
- {
- ModalDialog( HsoiGetMyStandardDialogFilter(), &itemHit );
- } while ( (itemHit != ok) && (itemHit != cancel) );
-
- // if they hit ok...
-
- if ( itemHit == ok )
- {
- // get the text.
-
- // when getting the text, just in case the entered nothing, we'll copy in
- // some defaults just so there's something there.
-
- // do the user
-
- editTextH = HsoiGetDialogItemHandle( regDialog, iRegDialogUserName );
- GetDialogItemText( editTextH, tempStr );
- if ( tempStr[0] == 0 ) // they entered nothing
- HsoipStringCopy( DEFAULT_USERNAME, gMyPrefs.userName );
- else
- HsoipStringCopy( tempStr, gMyPrefs.userName );
-
- // do the org
-
- editTextH = HsoiGetDialogItemHandle( regDialog, iRegDialogOrgName );
- GetDialogItemText( editTextH, tempStr );
- if ( tempStr[0] == 0 )
- HsoipStringCopy( DEFAULT_ORGANIZATION, gMyPrefs.userOrg );
- else
- HsoipStringCopy( tempStr, gMyPrefs.userOrg );
- }
-
- // if they canceled, copy the default settings in...again, so something is there
-
- if (itemHit == cancel )
- {
- HsoipStringCopy( DEFAULT_USERNAME, gMyPrefs.userName );
- HsoipStringCopy( DEFAULT_ORGANIZATION, gMyPrefs.userOrg );
- }
-
- // dump the dialog
-
- DisposeDialog( regDialog );
-
- return;
- }