示例#1
0
/* Set start and end times from a given seconds */
static void
SetSaneTimes(UInt32 secs, TimeType *startP, TimeType *endP)
{
    DateTimeType date_time;

    TimSecondsToDateTime(secs, &date_time);
    if (secs % 60)
        TimAdjust(&date_time, (60 - (secs % 60)));
    startP->hours = date_time.hour;
    startP->minutes = date_time.minute;
    if (startP->hours != 23) {
      endP->hours = startP->hours+1;
      endP->minutes = startP->minutes;
    } else {
      endP->hours = startP->hours;
      endP->minutes = 59;
    }
}
示例#2
0
/***********************************************************************
 *
 * FUNCTION:    SelectTimeZone
 *
 * DESCRIPTION: Display a form showing a time zone and allow the user
 *              to select a different time zone. This is the time zone
 *					 dialog as seen in Date & Dime panel
 *
 * PARAMETERS:
 *		ioTimeZoneP				<->	pointer to time zone to change
 *		ioLocaleInTimeZoneP	<->	Ptr to locale found in time zone.
 *		titleP					 ->	String title for the dialog.
 *		showTimes				 -> 	True => show current and new times
 *		anyLocale				 ->	True => ignore ioLocaleInTimeZoneP on entry.
 *
 * RETURNED:
 *		true if the OK button was pressed (in which case *ioTimeZoneP and
 *		*ioCountryInTimeZoneP might be changed).
 *
 * HISTORY:
 *		03/02/00	peter	Created by Peter Epstein.
 *		04/03/00	peter	Allow NULL currentTimeP.
 *		04/12/00	peter API changed to get rid of trigger text
 *		04/14/00	peter Update current & new time as time passes
 *		07/31/00	kwk	Use SysTicksPerSecond() routine vs. sysTicksPerSecond macro.
 *					kwk	Re-wrote to use set of resources (name, offset, country),
 *							scrollbar vs. arrows, etc.
 *		08/01/00	kwk	Support scroll-to-key. Fixed scrollbar/list sync bugs.
 *		08/02/00	kwk	New API w/ioCountryInTimeZoneP and anyCountry parameters.
 *					kwk	Call FrmHandleEvent _after_ our event handling code has
 *							decided that it doesn't want to handle the event, not before.
 *		08/03/00	kwk	Call LstSetListChoices before calling LstGetVisibleItems,
 *							as otherwise accessing the time zone picker from the
 *							Setup app (when <showTimes> is false) gives you a two-
 *							line high display because LstGetVisibleItems returns 0.
 *		08/18/00	kwk	Play error sound if user writes letter that doesn't
 *							match any entries.
 *					kwk	Don't select item if doing scroll-to-view for entry
 *							that matches the letter the user wrote.
 *		08/21/00	kwk	Scroll-to-view with text entry now scrolls to the top
 *							of the list, versus the middle.
 *		10/09/00	peter	Get rid of scroll bar and let list do the scrolling.
 *		11/17/00	CS		Change ioCountryInTimeZoneP to ioLocaleInTimeZoneP,
 *							(and anyCountry to anyLocale, but that doesn't matter),
 *							since CountryType is only a UInt8, and this may
 *							change someday.
 *
 ***********************************************************************/
Boolean SelectTimeZone(Int16 *ioTimeZoneP, LmLocaleType* ioLocaleInTimeZoneP,
				const Char *titleP, Boolean showTimes, Boolean anyLocale)
{
	FormType* originalForm;
	FormType* dialog;
	EventType event;
	Boolean confirmed = false;
	Boolean done = false;
	Boolean adjustTimes = false;
	Boolean foundLocale = false;
	MemHandle currentTimeHandle, newTimeHandle;
	ListPtr listP;
	Int16 oldTimeZone, newTimeZone, testTimeZone;
	LmLocaleType newTimeZoneLocale;
	Int16 delta, closestDelta, timeZoneIndex, closestIndex;
	DateTimeType currentTime, newTime;
	TimeZoneEntryType* tzArrayP;
	UInt16 numTimeZones;
	MemHandle tzNamesH;
	
	if (showTimes)
	{
		TimSecondsToDateTime(TimGetSeconds(), &currentTime);
	}
	
	oldTimeZone = *ioTimeZoneP;
	newTimeZone = oldTimeZone;
	newTimeZoneLocale = *ioLocaleInTimeZoneP;
	
	originalForm = FrmGetActiveForm();
	dialog = (FormType *) FrmInitForm (TimeZoneDialogForm); 
	listP = FrmGetObjectPtr (dialog, FrmGetObjectIndex (dialog, TimeZoneDialogTimeZoneList));
	
	if (titleP)
	{
		FrmSetTitle (dialog, (Char *) titleP);
	}
	
	FrmSetActiveForm (dialog);
	
	// We need to call LstSetListChoices before calling LstSetHeight below, as otherwise
	// LstGetVisibleItems will return 0.
	tzArrayP = PrvCreateTimeZoneArray(&tzNamesH, &numTimeZones);
	LstSetListChoices(listP, (Char**)tzArrayP, numTimeZones);
	
	if (showTimes)
	{
		currentTimeHandle = MemHandleNew(timeStringLength + 1 + dowLongDateStrLength + 1);
		ErrFatalDisplayIf (!currentTimeHandle, "Out of memory");
		newTimeHandle = MemHandleNew(timeStringLength + 1 + dowLongDateStrLength + 1);
		ErrFatalDisplayIf (!newTimeHandle, "Out of memory");

		PrvSetTimeField(dialog, TimeZoneDialogCurrentTimeField, currentTimeHandle, &currentTime, false);
	}
	else
	{
		// Hide the current and new time.
		FrmHideObject(dialog, FrmGetObjectIndex (dialog, TimeZoneDialogCurrentTimeLabel));
		FrmHideObject(dialog, FrmGetObjectIndex (dialog, TimeZoneDialogCurrentTimeField));
		FrmHideObject(dialog, FrmGetObjectIndex (dialog, TimeZoneDialogNewTimeLabel));
		FrmHideObject(dialog, FrmGetObjectIndex (dialog, TimeZoneDialogNewTimeField));
		
		// Make the list show more items to take up extra the space.
		LstSetHeight(listP, LstGetVisibleItems(listP) + extraTimeZonesToShowWhenNoTimes);
	}
	
	// Find the time zone in the list closest to the current time zone, and that
	// matches <*ioLocaleInTimeZoneP> if <anyLocale> is false.
	closestDelta = hoursInMinutes * hoursPerDay;		// so big that all others will be smaller
	for (timeZoneIndex = 0; timeZoneIndex < numTimeZones; timeZoneIndex++)
	{
		Boolean checkDelta = anyLocale;
		testTimeZone = tzArrayP[timeZoneIndex].tzOffset;
		delta = Abs(testTimeZone - oldTimeZone);
		
		if (!anyLocale)
		{
			if (tzArrayP[timeZoneIndex].tzCountry == ioLocaleInTimeZoneP->country)
			{
				// If we haven't previously found a matching locale, reset the
				// delta so that this entry overrides any previous best entry.
				if (!foundLocale)
				{
					foundLocale = true;
					closestDelta = hoursInMinutes * hoursPerDay;
				}
				
				checkDelta = true;
			}
			
			// If we haven't yet found a matching locale, go for the closest delta.
			else
			{
				checkDelta = !foundLocale;
			}
		}
		
		// If we want to check the time zone delta, do it now.
		if (checkDelta && (delta < closestDelta))
		{
			closestIndex = timeZoneIndex;
			closestDelta = delta;
		}
	}
	
	// Scroll so that time zone is in the center of the screen and select it if it's an exact match.
	LstSetTopItem(listP, max(0, closestIndex - (LstGetVisibleItems(listP) / 2)));
	if ((closestDelta == 0) && (anyLocale || foundLocale))
	{
		LstSetSelection(listP, closestIndex);
		if (showTimes)
		{
			newTime = currentTime;
			PrvSetTimeField(dialog, TimeZoneDialogNewTimeField, newTimeHandle, &newTime, false);
		}
	}
	else
	{
		LstSetSelection(listP, noListSelection);
	}
	
	LstSetDrawFunction(listP, PrvTimeZoneListDrawItem);
	
	FrmDrawForm (dialog);
	
	while (!done)
	{
		Boolean handled = false;
		EvtGetEvent(&event, SysTicksPerSecond());		// so we can update the current and new time

		if (SysHandleEvent ((EventType *)&event))
		{
			continue;
		}
		
		if (event.eType == nilEvent)
		{
			if (showTimes)
			{
				PrvUpdateTimeFields(	dialog,
										&currentTime,
										&newTime,
										currentTimeHandle,
										newTimeHandle,
										TimeZoneDialogCurrentTimeField,
										TimeZoneDialogNewTimeField);
			}
		}
		
		else if (event.eType == ctlSelectEvent)
		{
			handled = true;
			
			switch (event.data.ctlSelect.controlID)
			{
				case TimeZoneDialogOKButton:
					// Set the new time zone.
					*ioTimeZoneP = newTimeZone;
					*ioLocaleInTimeZoneP = newTimeZoneLocale;

					done = true;
					confirmed = true;
				break;

				case TimeZoneDialogCancelButton:
					done = true;
				break;
				
				default:
					ErrNonFatalDisplay("Unknown control in form");
				break;
			}
		}
		
		// User tapped on a time zone in the list.
		else if (event.eType == lstSelectEvent)
		{
			UInt16 localeIndex;
			
			ErrNonFatalDisplayIf(event.data.lstSelect.listID != TimeZoneDialogTimeZoneList,
										"Unknown list in form");
			
			newTimeZone = tzArrayP[event.data.lstSelect.selection].tzOffset;
			newTimeZoneLocale.country =
				tzArrayP[event.data.lstSelect.selection].tzCountry;
			newTimeZoneLocale.language = lmAnyLanguage;
			if (LmLocaleToIndex(&newTimeZoneLocale, &localeIndex) == errNone)
			{
				if (LmGetLocaleSetting(	localeIndex,
												lmChoiceLocale,
												&newTimeZoneLocale,
												sizeof(newTimeZoneLocale)))
				{
					ErrNonFatalDisplay("Can\'t get locale");
				}
			}
			adjustTimes = showTimes;
			handled = true;
		}

		else if (event.eType == keyDownEvent)
		{
			if	(!TxtCharIsHardKey(event.data.keyDown.modifiers, event.data.keyDown.chr))
			{
				//	Hard scroll buttons
				if (EvtKeydownIsVirtual(&event))
				{
					if (event.data.keyDown.chr == vchrPageUp)
					{
						handled = true;
						LstScrollList(listP, winUp, LstGetVisibleItems(listP) - 1);
					}
					else if (event.data.keyDown.chr == vchrPageDown)
					{
						handled = true;
						LstScrollList(listP, winDown, LstGetVisibleItems(listP) - 1);
					}
				}
				else if (TxtCharIsPrint(event.data.keyDown.chr))
				{
					Int16 index;
					
					handled = true;
					index = PrvSearchTimeZoneNames(tzArrayP, numTimeZones, event.data.keyDown.chr);
					
					if (index != noListSelection)
					{
						Int16 delta = index - listP->topItem;
						if (delta < 0)
						{
							LstScrollList(listP, winUp, -delta);
						}
						else if (delta > 0)
						{
							LstScrollList(listP, winDown, delta);
						}
					}
					else
					{
						SndPlaySystemSound(sndError);
					}
				}
			}
		}

		else if (event.eType == appStopEvent)
		{
			EvtAddEventToQueue (&event);
			done = true;
			break;
		}
		
		// If we didn't handle the event, give the form code a crack at it.
		// This simulates the "normal" method of installing an event handler
		// for a form, which gets called, and then if it returns false, the
		// FrmHandleEvent routine gets called.
		if (!handled)
		{
			FrmHandleEvent(dialog, &event); 
		}
		
		// If something changed, and we need to update our time display,
		// do it now.
		if (adjustTimes)
		{
			adjustTimes = false;
			newTime = currentTime;
			TimAdjust(&newTime, (Int32)(newTimeZone - oldTimeZone) * minutesInSeconds);
			PrvSetTimeField(dialog, TimeZoneDialogNewTimeField, newTimeHandle, &newTime, true);
		}
	}	// end while true
		
	if (showTimes)
	{
		FldSetTextHandle(FrmGetObjectPtr (dialog, FrmGetObjectIndex (dialog, TimeZoneDialogCurrentTimeField)), NULL);
		FldSetTextHandle(FrmGetObjectPtr (dialog, FrmGetObjectIndex (dialog, TimeZoneDialogNewTimeField)), NULL);
		MemHandleFree(currentTimeHandle);
		MemHandleFree(newTimeHandle);
	}
	
	FrmEraseForm (dialog);
	FrmDeleteForm (dialog);
	FrmSetActiveForm(originalForm);

	PrvDeleteTimeZoneArray(tzArrayP, tzNamesH);

	return confirmed;
} // SelectTimeZone