/** @file\r
Entry and initialization module for the browser.\r
\r
-Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
}\r
};\r
\r
-UINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);\r
+UINTN mScanCodeNumber = ARRAY_SIZE (gScanCodeToOperation);\r
\r
SCREEN_OPERATION_T0_CONTROL_FLAG gScreenOperationToControlFlag[] = {\r
{\r
{\r
UiPageDown,\r
CfUiPageDown\r
- }, \r
+ },\r
{\r
UiHotKey,\r
CfUiHotKey\r
0xE38C1029, 0xE38F, 0x45b9, {0x8F, 0x0D, 0xE2, 0xE6, 0x0B, 0xC9, 0xB2, 0x62}\r
};\r
\r
-FORM_ENTRY_INFO gFormEntryInfo;\r
-UINTN gSequence;\r
+BOOLEAN gMisMatch;\r
EFI_SCREEN_DESCRIPTOR gStatementDimensions;\r
BOOLEAN mStatementLayoutIsChanged = TRUE;\r
USER_INPUT *gUserInput;\r
//\r
// Browser Global Strings\r
//\r
+CHAR16 *gReconnectConfirmChanges;\r
+CHAR16 *gReconnectFail;\r
+CHAR16 *gReconnectRequired;\r
+CHAR16 *gChangesOpt;\r
CHAR16 *gFormNotFound;\r
CHAR16 *gNoSubmitIf;\r
-CHAR16 *gBrwoserError;\r
+CHAR16 *gBrowserError;\r
CHAR16 *gSaveFailed;\r
+CHAR16 *gNoSubmitIfFailed;\r
+CHAR16 *gSaveProcess;\r
+CHAR16 *gSaveNoSubmitProcess;\r
+CHAR16 *gDiscardChange;\r
+CHAR16 *gJumpToFormSet;\r
+CHAR16 *gCheckError;\r
CHAR16 *gPromptForData;\r
CHAR16 *gPromptForPassword;\r
CHAR16 *gPromptForNewPassword;\r
CHAR16 *gOptionMismatch;\r
CHAR16 *gFormSuppress;\r
CHAR16 *gProtocolNotFound;\r
-\r
+CHAR16 *gConfirmDefaultMsg;\r
+CHAR16 *gConfirmSubmitMsg;\r
+CHAR16 *gConfirmDiscardMsg;\r
+CHAR16 *gConfirmResetMsg;\r
+CHAR16 *gConfirmExitMsg;\r
+CHAR16 *gConfirmSubmitMsg2nd;\r
+CHAR16 *gConfirmDefaultMsg2nd;\r
+CHAR16 *gConfirmResetMsg2nd;\r
+CHAR16 *gConfirmExitMsg2nd;\r
+CHAR16 *gConfirmOpt;\r
+CHAR16 *gConfirmOptYes;\r
+CHAR16 *gConfirmOptNo;\r
+CHAR16 *gConfirmOptOk;\r
+CHAR16 *gConfirmOptCancel;\r
+CHAR16 *gYesOption;\r
+CHAR16 *gNoOption;\r
+CHAR16 *gOkOption;\r
+CHAR16 *gCancelOption;\r
+CHAR16 *gErrorPopup;\r
+CHAR16 *gWarningPopup;\r
+CHAR16 *gInfoPopup;\r
+CHAR16 *gConfirmMsgConnect;\r
+CHAR16 *gConfirmMsgEnd;\r
+CHAR16 *gPasswordUnsupported;\r
CHAR16 gModalSkipColumn;\r
CHAR16 gPromptBlockWidth;\r
CHAR16 gOptionBlockWidth;\r
FormDisplay,\r
DriverClearDisplayPage,\r
ConfirmDataChange\r
+ },\r
+ {\r
+ EFI_HII_POPUP_PROTOCOL_REVISION,\r
+ CreatePopup\r
}\r
};\r
\r
VOID\r
)\r
{\r
+ gReconnectConfirmChanges = GetToken (STRING_TOKEN (RECONNECT_CONFIRM_CHANGES), gHiiHandle);\r
mUnknownString = GetToken (STRING_TOKEN (UNKNOWN_STRING), gHiiHandle);\r
gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);\r
+ gNoSubmitIfFailed = GetToken (STRING_TOKEN (NO_SUBMIT_IF_CHECK_FAILED), gHiiHandle);\r
+ gReconnectFail = GetToken (STRING_TOKEN (RECONNECT_FAILED), gHiiHandle);\r
+ gReconnectRequired = GetToken (STRING_TOKEN (RECONNECT_REQUIRED), gHiiHandle);\r
+ gChangesOpt = GetToken (STRING_TOKEN (RECONNECT_CHANGES_OPTIONS), gHiiHandle);\r
+ gSaveProcess = GetToken (STRING_TOKEN (DISCARD_OR_JUMP), gHiiHandle);\r
+ gSaveNoSubmitProcess = GetToken (STRING_TOKEN (DISCARD_OR_CHECK), gHiiHandle);\r
+ gDiscardChange = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_DISCARD), gHiiHandle);\r
+ gJumpToFormSet = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_JUMP), gHiiHandle);\r
+ gCheckError = GetToken (STRING_TOKEN (DISCARD_OR_CHECK_CHECK), gHiiHandle);\r
gPromptForData = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);\r
gPromptForPassword = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);\r
gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);\r
gProtocolNotFound = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);\r
gFormNotFound = GetToken (STRING_TOKEN (STATUS_BROWSER_FORM_NOT_FOUND), gHiiHandle);\r
gNoSubmitIf = GetToken (STRING_TOKEN (STATUS_BROWSER_NO_SUBMIT_IF), gHiiHandle);\r
- gBrwoserError = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle);\r
+ gBrowserError = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle);\r
+ gConfirmDefaultMsg = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE), gHiiHandle);\r
+ gConfirmDiscardMsg = GetToken (STRING_TOKEN (CONFIRM_DISCARD_MESSAGE), gHiiHandle);\r
+ gConfirmSubmitMsg = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE), gHiiHandle);\r
+ gConfirmResetMsg = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE), gHiiHandle);\r
+ gConfirmExitMsg = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE), gHiiHandle);\r
+ gConfirmDefaultMsg2nd = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE_2ND), gHiiHandle);\r
+ gConfirmSubmitMsg2nd = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE_2ND), gHiiHandle);\r
+ gConfirmResetMsg2nd = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE_2ND), gHiiHandle);\r
+ gConfirmExitMsg2nd = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE_2ND), gHiiHandle);\r
+ gConfirmOpt = GetToken (STRING_TOKEN (CONFIRM_OPTION), gHiiHandle);\r
+ gConfirmOptYes = GetToken (STRING_TOKEN (CONFIRM_OPTION_YES), gHiiHandle);\r
+ gConfirmOptNo = GetToken (STRING_TOKEN (CONFIRM_OPTION_NO), gHiiHandle);\r
+ gConfirmOptOk = GetToken (STRING_TOKEN (CONFIRM_OPTION_OK), gHiiHandle);\r
+ gConfirmOptCancel = GetToken (STRING_TOKEN (CONFIRM_OPTION_CANCEL), gHiiHandle);\r
+ gYesOption = GetToken (STRING_TOKEN (YES_SELECTABLE_OPTION), gHiiHandle);\r
+ gNoOption = GetToken (STRING_TOKEN (NO_SELECTABLE_OPTION), gHiiHandle);\r
+ gOkOption = GetToken (STRING_TOKEN (OK_SELECTABLE_OPTION), gHiiHandle);\r
+ gCancelOption = GetToken (STRING_TOKEN (CANCEL_SELECTABLE_OPTION), gHiiHandle);\r
+ gErrorPopup = GetToken (STRING_TOKEN (ERROR_POPUP_STRING), gHiiHandle);\r
+ gWarningPopup = GetToken (STRING_TOKEN (WARNING_POPUP_STRING), gHiiHandle);\r
+ gInfoPopup = GetToken (STRING_TOKEN (INFO_POPUP_STRING), gHiiHandle);\r
+ gConfirmMsgConnect = GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT), gHiiHandle);\r
+ gConfirmMsgEnd = GetToken (STRING_TOKEN (CONFIRM_OPTION_END), gHiiHandle);\r
+ gPasswordUnsupported = GetToken (STRING_TOKEN (PASSWORD_NOT_SUPPORTED ), gHiiHandle);\r
}\r
\r
/**\r
FreePool (mUnknownString);\r
FreePool (gEmptyString);\r
FreePool (gSaveFailed);\r
+ FreePool (gNoSubmitIfFailed);\r
+ FreePool (gReconnectFail);\r
+ FreePool (gReconnectRequired);\r
+ FreePool (gChangesOpt);\r
+ FreePool (gReconnectConfirmChanges);\r
+ FreePool (gSaveProcess);\r
+ FreePool (gSaveNoSubmitProcess);\r
+ FreePool (gDiscardChange);\r
+ FreePool (gJumpToFormSet);\r
+ FreePool (gCheckError);\r
FreePool (gPromptForData);\r
FreePool (gPromptForPassword);\r
FreePool (gPromptForNewPassword);\r
FreePool (gOptionMismatch);\r
FreePool (gFormSuppress);\r
FreePool (gProtocolNotFound);\r
- FreePool (gBrwoserError);\r
+ FreePool (gBrowserError);\r
FreePool (gNoSubmitIf);\r
FreePool (gFormNotFound);\r
+ FreePool (gConfirmDefaultMsg);\r
+ FreePool (gConfirmSubmitMsg);\r
+ FreePool (gConfirmDiscardMsg);\r
+ FreePool (gConfirmResetMsg);\r
+ FreePool (gConfirmExitMsg);\r
+ FreePool (gConfirmDefaultMsg2nd);\r
+ FreePool (gConfirmSubmitMsg2nd);\r
+ FreePool (gConfirmResetMsg2nd);\r
+ FreePool (gConfirmExitMsg2nd);\r
+ FreePool (gConfirmOpt);\r
+ FreePool (gConfirmOptYes);\r
+ FreePool (gConfirmOptNo);\r
+ FreePool (gConfirmOptOk);\r
+ FreePool (gConfirmOptCancel);\r
+ FreePool (gYesOption);\r
+ FreePool (gNoOption);\r
+ FreePool (gOkOption);\r
+ FreePool (gCancelOption);\r
+ FreePool (gErrorPopup);\r
+ FreePool (gWarningPopup);\r
+ FreePool (gInfoPopup);\r
+ FreePool (gConfirmMsgConnect);\r
+ FreePool (gConfirmMsgEnd);\r
+ FreePool (gPasswordUnsupported);\r
}\r
\r
/**\r
/**\r
Get the supported width for a particular op-code\r
\r
- @param Statement The curent statement.\r
+ @param MenuOption The menu option.\r
@param AdjustWidth The width which is saved for the space.\r
\r
@return Returns the number of CHAR16 characters that is support.\r
**/\r
UINT16\r
GetWidth (\r
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
- OUT UINT16 *AdjustWidth\r
+ IN UI_MENU_OPTION *MenuOption,\r
+ OUT UINT16 *AdjustWidth\r
)\r
{\r
- CHAR16 *String;\r
- UINTN Size;\r
- EFI_IFR_TEXT *TestOp;\r
+ CHAR16 *String;\r
+ UINTN Size;\r
+ EFI_IFR_TEXT *TestOp;\r
+ UINT16 ReturnWidth;\r
+ FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
+\r
+ Statement = MenuOption->ThisTag;\r
\r
//\r
// For modal form, clean the entire row.\r
//\r
((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0))\r
) {\r
- \r
+\r
//\r
// Return the space width.\r
- // \r
+ //\r
if (AdjustWidth != NULL) {\r
*AdjustWidth = 2;\r
}\r
//\r
// Keep consistent with current behavior.\r
//\r
- return (UINT16) (gPromptBlockWidth + gOptionBlockWidth - 2);\r
+ ReturnWidth = (UINT16) (gPromptBlockWidth + gOptionBlockWidth - 2);\r
+ } else {\r
+ if (AdjustWidth != NULL) {\r
+ *AdjustWidth = 1;\r
+ }\r
+\r
+ ReturnWidth = (UINT16) (gPromptBlockWidth - 1);\r
}\r
\r
- if (AdjustWidth != NULL) {\r
- *AdjustWidth = 1;\r
+ //\r
+ // For nest in statement, should the subtitle indent.\r
+ //\r
+ if (MenuOption->NestInStatement) {\r
+ ReturnWidth -= SUBTITLE_INDENT;\r
}\r
- return (UINT16) (gPromptBlockWidth - 1);\r
+\r
+ return ReturnWidth;\r
}\r
\r
/**\r
@param Index Where in InputString to start the copy process\r
@param OutputString Buffer to copy the string into\r
\r
- @return Returns the number of CHAR16 characters that were copied into the OutputString \r
+ @return Returns the number of CHAR16 characters that were copied into the OutputString\r
buffer, include extra glyph info and '\0' info.\r
\r
**/\r
if (ReturnFlag) {\r
break;\r
}\r
- } \r
+ }\r
\r
//\r
// Rewind the string from the maximum size until we see a space to break the line\r
//\r
// Need extra glyph info and '\0' info, so +2.\r
//\r
- *OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));\r
+ *OutputString = AllocateZeroPool ((StrOffset + 2) * sizeof(CHAR16));\r
if (*OutputString == NULL) {\r
return 0;\r
}\r
if (InputString[*Index + StrOffset] == CHAR_SPACE) {\r
//\r
// Skip the space info at the begin of next line.\r
- // \r
+ //\r
*Index = (UINT16) (*Index + StrOffset + 1);\r
} else if (InputString[*Index + StrOffset] == CHAR_LINEFEED) {\r
//\r
} else if (InputString[*Index + StrOffset] == CHAR_CARRIAGE_RETURN) {\r
//\r
// Skip the /r or /r/n info.\r
- // \r
+ //\r
if (InputString[*Index + StrOffset + 1] == CHAR_LINEFEED) {\r
*Index = (UINT16) (*Index + StrOffset + 2);\r
} else {\r
UI_MENU_OPTION *MenuOption;\r
UINTN Index;\r
UINTN Count;\r
- CHAR16 *String;\r
UINT16 NumberOfLines;\r
UINT16 GlyphWidth;\r
UINT16 Width;\r
PromptId = GetPrompt (Statement->OpCode);\r
ASSERT (PromptId != 0);\r
\r
- String = GetToken (PromptId, gFormData->HiiHandle);\r
- ASSERT (String != NULL);\r
-\r
- Width = GetWidth (Statement, NULL);\r
- for (; GetLineByWidth (String, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {\r
- //\r
- // If there is more string to process print on the next row and increment the Skip value\r
- //\r
- if (StrLen (&String[ArrayEntry]) != 0) {\r
- NumberOfLines++;\r
- }\r
- FreePool (OutputString);\r
- }\r
-\r
if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
- //\r
- // Add three MenuOptions for Date/Time\r
- // Data format : [01/02/2004] [11:22:33]\r
- // Line number : 0 0 1 0 0 1\r
- //\r
- NumberOfLines = 0;\r
Count = 3;\r
}\r
\r
ASSERT (MenuOption);\r
\r
MenuOption->Signature = UI_MENU_OPTION_SIGNATURE;\r
- MenuOption->Description = String;\r
+ MenuOption->Description = GetToken (PromptId, gFormData->HiiHandle);\r
MenuOption->Handle = gFormData->HiiHandle;\r
MenuOption->ThisTag = Statement;\r
MenuOption->NestInStatement = NestIn;\r
MenuOption->EntryNumber = *MenuItemCount;\r
\r
- if (Index == 2) {\r
- //\r
- // Override LineNumber for the MenuOption in Date/Time sequence\r
- //\r
- MenuOption->Skip = 1;\r
- } else {\r
- MenuOption->Skip = NumberOfLines;\r
- }\r
MenuOption->Sequence = Index;\r
\r
if ((Statement->Attribute & HII_DISPLAY_GRAYOUT) != 0) {\r
case EFI_IFR_TEXT_OP:\r
if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {\r
//\r
- // Initializing GrayOut option as TRUE for Text setup options \r
+ // Initializing GrayOut option as TRUE for Text setup options\r
// so that those options will be Gray in colour and un selectable.\r
//\r
MenuOption->GrayOut = TRUE;\r
}\r
}\r
\r
+ if (Index == 0 &&\r
+ (Statement->OpCode->OpCode != EFI_IFR_DATE_OP) &&\r
+ (Statement->OpCode->OpCode != EFI_IFR_TIME_OP)) {\r
+ Width = GetWidth (MenuOption, NULL);\r
+ for (; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {\r
+ //\r
+ // If there is more string to process print on the next row and increment the Skip value\r
+ //\r
+ if (StrLen (&MenuOption->Description[ArrayEntry]) != 0) {\r
+ NumberOfLines++;\r
+ }\r
+ FreePool (OutputString);\r
+ }\r
+ } else {\r
+ //\r
+ // Add three MenuOptions for Date/Time\r
+ // Data format : [01/02/2004] [11:22:33]\r
+ // Line number : 0 0 1 0 0 1\r
+ //\r
+ NumberOfLines = 0;\r
+ }\r
+\r
+ if (Index == 2) {\r
+ //\r
+ // Override LineNumber for the MenuOption in Date/Time sequence\r
+ //\r
+ MenuOption->Skip = 1;\r
+ } else {\r
+ MenuOption->Skip = NumberOfLines;\r
+ }\r
+\r
InsertTailList (&gMenuOption, &MenuOption->Link);\r
}\r
\r
NestStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (NestLink);\r
NestLink = GetNextNode (&Statement->NestStatementList, NestLink);\r
\r
+ //\r
+ // Skip the opcode not recognized by Display core.\r
+ //\r
+ if (NestStatement->OpCode->OpCode == EFI_IFR_GUID_OP) {\r
+ continue;\r
+ }\r
+\r
UiAddMenuOption (NestStatement, &MenuItemCount, TRUE);\r
}\r
}\r
CHAR16 *OutputString;\r
UINT16 GlyphWidth;\r
\r
- Width = (UINT16) gOptionBlockWidth;\r
+ Width = (UINT16) gOptionBlockWidth - 1;\r
GlyphWidth = 1;\r
Row = 1;\r
\r
FreePool (OutputString);\r
}\r
\r
- if ((Row > MenuOption->Skip) && \r
- (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_DATE_OP) && \r
+ if ((Row > MenuOption->Skip) &&\r
+ (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_DATE_OP) &&\r
(MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_TIME_OP)) {\r
MenuOption->Skip = Row;\r
}\r
}\r
}\r
\r
+/**\r
+ Check whether this Menu Option could be print.\r
+\r
+ Check Prompt string, option string or text two string not NULL.\r
+\r
+ This is an internal function.\r
+\r
+ @param MenuOption The MenuOption to be checked.\r
+\r
+ @retval TRUE This Menu Option is printable.\r
+ @retval FALSE This Menu Option could not be printable.\r
+\r
+**/\r
+BOOLEAN\r
+PrintableMenu (\r
+ UI_MENU_OPTION *MenuOption\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STRING OptionString;\r
+\r
+ OptionString = NULL;\r
+\r
+ if (MenuOption->Description[0] != '\0') {\r
+ return TRUE;\r
+ }\r
+\r
+ Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ return FALSE;\r
+ }\r
+ if (OptionString != NULL && OptionString[0] != '\0') {\r
+ FreePool (OptionString);\r
+ return TRUE;\r
+ }\r
+\r
+ if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo != 0)) {\r
+ OptionString = GetToken (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo, gFormData->HiiHandle);\r
+ ASSERT (OptionString != NULL);\r
+ if (OptionString[0] != '\0'){\r
+ FreePool (OptionString);\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
/**\r
Check whether this Menu Option could be highlighted.\r
\r
)\r
{\r
if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||\r
- MenuOption->GrayOut || MenuOption->ReadOnly) {\r
+ MenuOption->GrayOut || MenuOption->ReadOnly || !PrintableMenu (MenuOption)) {\r
return FALSE;\r
} else {\r
return TRUE;\r
@param GoUp The navigation direction. TRUE: up, FALSE: down.\r
@param CurrentPosition Current position.\r
@param GapToTop Gap position to top or bottom.\r
+ @param FindInForm Whether find menu in current form or beyond.\r
\r
@return The row distance from current MenuOption to next selectable MenuOption.\r
\r
@retval -1 Reach the begin of the menu, still can't find the selectable menu.\r
- @retval Value Find the selectable menu, maybe the truly selectable, maybe the l\r
- last menu showing at current form.\r
+ @retval Value Find the selectable menu, maybe the truly selectable, maybe the\r
+ first menu showing beyond current form or last menu showing in\r
+ current form.\r
+ The value is the line number between the new selected menu and the\r
+ current select menu, not include the new selected menu.\r
\r
**/\r
INTN\r
MoveToNextStatement (\r
IN BOOLEAN GoUp,\r
IN OUT LIST_ENTRY **CurrentPosition,\r
- IN UINTN GapToTop\r
+ IN UINTN GapToTop,\r
+ IN BOOLEAN FindInForm\r
)\r
{\r
INTN Distance;\r
\r
Distance = 0;\r
Pos = *CurrentPosition;\r
+\r
+ if (Pos == &gMenuOption) {\r
+ return -1;\r
+ }\r
+\r
PreMenuOption = MENU_OPTION_FROM_LINK (Pos);\r
\r
while (TRUE) {\r
if (NextMenuOption->Row == 0) {\r
UpdateOptionSkipLines (NextMenuOption);\r
}\r
- \r
- if (GoUp && (PreMenuOption != NextMenuOption)) {\r
- //\r
- // In this case, still can't find the selectable menu,\r
- // return the last one in the showing form.\r
- //\r
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {\r
+\r
+ //\r
+ // Check whether the menu is beyond current showing form,\r
+ // return the first one beyond the showing form.\r
+ //\r
+ if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {\r
+ if (FindInForm) {\r
NextMenuOption = PreMenuOption;\r
- break;\r
}\r
-\r
- //\r
- // Current Position doesn't need to be caculated when go up.\r
- // Caculate distanct at first when go up\r
- // \r
- Distance += NextMenuOption->Skip;\r
+ break;\r
}\r
\r
+ //\r
+ // return the selectable menu in the showing form.\r
+ //\r
if (IsSelectable (NextMenuOption)) {\r
break;\r
}\r
\r
+ Distance += NextMenuOption->Skip;\r
+\r
//\r
// Arrive at begin of the menu list.\r
//\r
break;\r
}\r
\r
- if (!GoUp) {\r
- //\r
- // In this case, still can't find the selectable menu,\r
- // return the last one in the showing form.\r
- //\r
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {\r
- NextMenuOption = PreMenuOption;\r
- break;\r
- }\r
-\r
- Distance += NextMenuOption->Skip;\r
- }\r
-\r
- PreMenuOption = NextMenuOption;\r
Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);\r
+ PreMenuOption = NextMenuOption;\r
}\r
\r
*CurrentPosition = &NextMenuOption->Link;\r
\r
@param MenuOption Menu option point to date/time.\r
@param OptionString Option string input for process.\r
- @param AddOptCol Whether need to update MenuOption->OptCol. \r
+ @param AddOptCol Whether need to update MenuOption->OptCol.\r
\r
**/\r
-VOID \r
+VOID\r
ProcessStringForDateTime (\r
UI_MENU_OPTION *MenuOption,\r
CHAR16 *OptionString,\r
EFI_IFR_TIME *Time;\r
\r
ASSERT (MenuOption != NULL && OptionString != NULL);\r
- \r
+\r
Statement = MenuOption->ThisTag;\r
Date = NULL;\r
Time = NULL;\r
} else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
Time = (EFI_IFR_TIME *) Statement->OpCode;\r
}\r
- \r
+\r
//\r
// If leading spaces on OptionString - remove the spaces\r
//\r
MenuOption->OptCol++;\r
}\r
}\r
- \r
+\r
for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {\r
OptionString[Count] = OptionString[Index];\r
Count++;\r
}\r
OptionString[Count] = CHAR_NULL;\r
- \r
+\r
//\r
// Enable to suppress field in the opcode base on the flag.\r
//\r
//\r
if ((Date->Flags & EFI_QF_DATE_MONTH_SUPPRESS) && (MenuOption->Sequence == 0)) {\r
//\r
- // At this point, only "<**:" in the optionstring. \r
+ // At this point, only "<**:" in the optionstring.\r
// Clean the day's ** field, after clean, the format is "< :"\r
//\r
SetUnicodeMem (&OptionString[1], 2, L' ');\r
} else if ((Date->Flags & EFI_QF_DATE_DAY_SUPPRESS) && (MenuOption->Sequence == 1)) {\r
//\r
- // At this point, only "**:" in the optionstring. \r
+ // At this point, only "**:" in the optionstring.\r
// Clean the month's "**" field, after clean, the format is " :"\r
- // \r
+ //\r
SetUnicodeMem (&OptionString[0], 2, L' ');\r
} else if ((Date->Flags & EFI_QF_DATE_YEAR_SUPPRESS) && (MenuOption->Sequence == 2)) {\r
//\r
- // At this point, only "****>" in the optionstring. \r
+ // At this point, only "****>" in the optionstring.\r
// Clean the year's "****" field, after clean, the format is " >"\r
- // \r
+ //\r
SetUnicodeMem (&OptionString[0], 4, L' ');\r
}\r
} else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
//\r
if ((Time->Flags & QF_TIME_HOUR_SUPPRESS) && (MenuOption->Sequence == 0)) {\r
//\r
- // At this point, only "<**:" in the optionstring. \r
+ // At this point, only "<**:" in the optionstring.\r
// Clean the hour's ** field, after clean, the format is "< :"\r
//\r
SetUnicodeMem (&OptionString[1], 2, L' ');\r
} else if ((Time->Flags & QF_TIME_MINUTE_SUPPRESS) && (MenuOption->Sequence == 1)) {\r
//\r
- // At this point, only "**:" in the optionstring. \r
+ // At this point, only "**:" in the optionstring.\r
// Clean the minute's "**" field, after clean, the format is " :"\r
- // \r
+ //\r
SetUnicodeMem (&OptionString[0], 2, L' ');\r
} else if ((Time->Flags & QF_TIME_SECOND_SUPPRESS) && (MenuOption->Sequence == 2)) {\r
//\r
- // At this point, only "**>" in the optionstring. \r
+ // At this point, only "**>" in the optionstring.\r
// Clean the second's "**" field, after clean, the format is " >"\r
- // \r
+ //\r
SetUnicodeMem (&OptionString[0], 2, L' ');\r
}\r
}\r
\r
/**\r
Get step info from numeric opcode.\r
- \r
+\r
@param[in] OpCode The input numeric op code.\r
\r
@return step info for this opcode.\r
UINT64 Step;\r
\r
NumericOp = (EFI_IFR_NUMERIC *) OpCode;\r
- \r
+\r
switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {\r
case EFI_IFR_NUMERIC_SIZE_1:\r
Step = NumericOp->data.u8.Step;\r
break;\r
- \r
+\r
case EFI_IFR_NUMERIC_SIZE_2:\r
Step = NumericOp->data.u16.Step;\r
break;\r
- \r
+\r
case EFI_IFR_NUMERIC_SIZE_4:\r
Step = NumericOp->data.u32.Step;\r
break;\r
- \r
+\r
case EFI_IFR_NUMERIC_SIZE_8:\r
Step = NumericOp->data.u64.Step;\r
break;\r
- \r
+\r
default:\r
Step = 0;\r
break;\r
\r
/**\r
Find the registered HotKey based on KeyData.\r
- \r
+\r
@param[in] KeyData A pointer to a buffer that describes the keystroke\r
information for the hot key.\r
\r
Link = GetFirstNode (&gFormData->HotKeyListHead);\r
while (!IsNull (&gFormData->HotKeyListHead, Link)) {\r
HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
- \r
+\r
if (HotKey->KeyData->ScanCode == KeyData->ScanCode) {\r
return HotKey;\r
}\r
\r
Link = GetNextNode (&gFormData->HotKeyListHead, Link);\r
}\r
- \r
+\r
return NULL;\r
}\r
\r
Timeout\r
);\r
}\r
- \r
+\r
WaitList[0] = Event;\r
EventNum = 1;\r
if (gFormData->FormRefreshEvent != NULL) {\r
WaitList[EventNum] = gFormData->FormRefreshEvent;\r
EventNum ++;\r
- } \r
+ }\r
\r
if (Timeout != 0) {\r
WaitList[EventNum] = TimerEvent;\r
if (Timeout != 0) {\r
gBS->CloseEvent (TimerEvent);\r
}\r
- \r
+\r
return EventType;\r
}\r
\r
return QuestionHeader->QuestionId;\r
}\r
\r
+\r
/**\r
- Find the first menu which will be show at the top.\r
+ Find the top of screen menu base on the current menu.\r
\r
- @param FormData The data info for this form.\r
- @param TopOfScreen The link_entry pointer to top menu.\r
- @param HighlightMenu The menu which will be highlight.\r
- @param SkipValue The skip value for the top menu.\r
+ @param CurPos Current input menu.\r
+ @param Rows Totol screen rows.\r
+ @param SkipValue SkipValue for this new form.\r
+\r
+ @retval TopOfScreen Top of screen menu for the new form.\r
\r
**/\r
-VOID\r
-FindTopMenu (\r
- IN FORM_DISPLAY_ENGINE_FORM *FormData,\r
- OUT LIST_ENTRY **TopOfScreen,\r
- OUT LIST_ENTRY **HighlightMenu,\r
- OUT INTN *SkipValue\r
+LIST_ENTRY *\r
+FindTopOfScreenMenu (\r
+ IN LIST_ENTRY *CurPos,\r
+ IN UINTN Rows,\r
+ OUT UINTN *SkipValue\r
)\r
{\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *NewPos;\r
- UINTN TopRow;\r
- UINTN BottomRow;\r
- UINTN Index;\r
- UI_MENU_OPTION *SavedMenuOption;\r
- UINTN EndRow;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *TopOfScreen;\r
+ UI_MENU_OPTION *PreviousMenuOption;\r
\r
- TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;\r
- BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;\r
+ Link = CurPos;\r
+ PreviousMenuOption = NULL;\r
\r
- //\r
- // If not has input highlight statement, just return the first one in this form.\r
- //\r
- if (FormData->HighLightedStatement == NULL) {\r
- *TopOfScreen = gMenuOption.ForwardLink;\r
- *HighlightMenu = gMenuOption.ForwardLink;\r
- if (!IsListEmpty (&gMenuOption)) {\r
- MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow);\r
+ while (Link->BackLink != &gMenuOption) {\r
+ Link = Link->BackLink;\r
+ PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+ if (PreviousMenuOption->Row == 0) {\r
+ UpdateOptionSkipLines (PreviousMenuOption);\r
}\r
- *SkipValue = 0;\r
- return;\r
- }\r
-\r
- //\r
- // Now base on the input highlight menu to find the top menu in this page.\r
- // Will base on the highlight menu show at the bottom to find the top menu.\r
- //\r
- NewPos = gMenuOption.ForwardLink;\r
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-\r
- while ((SavedMenuOption->ThisTag != FormData->HighLightedStatement) ||\r
- (SavedMenuOption->Sequence != gSequence)) {\r
- NewPos = NewPos->ForwardLink;\r
- if (NewPos == &gMenuOption) {\r
- //\r
- // Not Found it, break\r
- //\r
+ if (Rows <= PreviousMenuOption->Skip) {\r
break;\r
}\r
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
- }\r
- ASSERT (SavedMenuOption->ThisTag == FormData->HighLightedStatement);\r
-\r
- *HighlightMenu = NewPos;\r
-\r
- AdjustDateAndTimePosition(FALSE, &NewPos);\r
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
- UpdateOptionSkipLines (SavedMenuOption);\r
-\r
- //\r
- // If highlight opcode is date/time, keep the highlight row info not change.\r
- //\r
- if ((SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP || SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP) &&\r
- (gHighligthMenuInfo.QuestionId != 0) && \r
- (gHighligthMenuInfo.QuestionId == GetQuestionIdInfo(SavedMenuOption->ThisTag->OpCode))) {\r
- //\r
- // Still show the highlight menu before exit from display engine.\r
- //\r
- EndRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;\r
- } else {\r
- EndRow = BottomRow;\r
- }\r
-\r
- //\r
- // Base on the selected menu will show at the bottome of next page, \r
- // select the menu show at the top of the next page. \r
- //\r
- Link = NewPos;\r
- for (Index = TopRow + SavedMenuOption->Skip; Index <= EndRow; ) {\r
- Link = Link->BackLink;\r
- //\r
- // Already find the first menu in this form, means highlight menu \r
- // will show in first page of this form.\r
- //\r
- if (Link == &gMenuOption) {\r
- *TopOfScreen = gMenuOption.ForwardLink;\r
- *SkipValue = 0;\r
- return;\r
- }\r
- SavedMenuOption = MENU_OPTION_FROM_LINK (Link);\r
- UpdateOptionSkipLines (SavedMenuOption);\r
- Index += SavedMenuOption->Skip;\r
+ Rows = Rows - PreviousMenuOption->Skip;\r
}\r
\r
- //\r
- // Found the menu which will show at the top of the page.\r
- //\r
- if (Link == NewPos) {\r
- //\r
- // The menu can show more than one pages, just show the menu at the top of the page.\r
- //\r
- *SkipValue = 0;\r
- *TopOfScreen = Link;\r
- } else {\r
- //\r
- // Check whether need to skip some line for menu shows at the top of the page.\r
- //\r
- *SkipValue = Index - EndRow;\r
- if (*SkipValue > 0 && *SkipValue < (INTN) SavedMenuOption->Skip) {\r
- *TopOfScreen = Link;\r
+ if (Link->BackLink == &gMenuOption) {\r
+ TopOfScreen = gMenuOption.ForwardLink;\r
+ if (PreviousMenuOption != NULL && Rows < PreviousMenuOption->Skip) {\r
+ *SkipValue = PreviousMenuOption->Skip - Rows;\r
} else {\r
- *SkipValue = 0;\r
- *TopOfScreen = Link->ForwardLink;\r
+ *SkipValue = 0;\r
}\r
+ } else {\r
+ TopOfScreen = Link;\r
+ *SkipValue = PreviousMenuOption->Skip - Rows;\r
}\r
+\r
+ return TopOfScreen;\r
}\r
\r
/**\r
- Update highlight menu info.\r
+ Get the index info for this opcode.\r
+\r
+ @param OpCode The input opcode for the statement.\r
\r
- @param MenuOption The menu opton which is highlight.\r
+ @retval The index of this statement.\r
\r
**/\r
-VOID\r
-UpdateHighlightMenuInfo (\r
- IN UI_MENU_OPTION *MenuOption\r
+UINTN\r
+GetIndexInfoForOpcode (\r
+ IN EFI_IFR_OP_HEADER *OpCode\r
)\r
{\r
- FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
+ LIST_ENTRY *NewPos;\r
+ UI_MENU_OPTION *MenuOption;\r
+ UINTN Index;\r
\r
- //\r
- // This is the current selected statement\r
- //\r
- Statement = MenuOption->ThisTag;\r
+ NewPos = gMenuOption.ForwardLink;\r
+ Index = 0;\r
\r
- //\r
- // Get the highlight statement.\r
- //\r
- gUserInput->SelectedStatement = Statement;\r
- gSequence = (UINT16) MenuOption->Sequence;\r
+ for (NewPos = gMenuOption.ForwardLink; NewPos != &gMenuOption; NewPos = NewPos->ForwardLink){\r
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
\r
- //\r
- // Record highlight row info for date/time opcode.\r
- //\r
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
- gHighligthMenuInfo.QuestionId = GetQuestionIdInfo(Statement->OpCode);\r
- gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row;\r
- } else {\r
- gHighligthMenuInfo.QuestionId = 0;\r
- gHighligthMenuInfo.DisplayRow = 0;\r
+ if (CompareMem (MenuOption->ThisTag->OpCode, OpCode, OpCode->Length) == 0) {\r
+ if (MenuOption->ThisTag->OpCode == OpCode) {\r
+ return Index;\r
+ }\r
+\r
+ Index ++;\r
+ }\r
}\r
\r
- RefreshKeyHelp(gFormData, Statement, FALSE);\r
+ return Index;\r
}\r
\r
/**\r
- Update attribut for this menu.\r
+ Is this the saved highlight statement.\r
\r
- @param MenuOption The menu opton which this attribut used to.\r
- @param Highlight Whether this menu will be highlight.\r
+ @param HighLightedStatement The input highlight statement.\r
+\r
+ @retval TRUE This is the highlight statement.\r
+ @retval FALSE This is not the highlight statement.\r
\r
**/\r
-VOID\r
-SetDisplayAttribute (\r
- IN UI_MENU_OPTION *MenuOption,\r
- IN BOOLEAN Highlight\r
+BOOLEAN\r
+IsSavedHighlightStatement (\r
+ IN FORM_DISPLAY_ENGINE_STATEMENT *HighLightedStatement\r
)\r
{\r
- FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
- \r
- Statement = MenuOption->ThisTag;\r
-\r
- if (Highlight) {\r
- gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());\r
- return;\r
- }\r
-\r
- if (MenuOption->GrayOut) {\r
- gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());\r
- } else {\r
- if (Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {\r
- gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());\r
+ if ((gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) &&\r
+ (gFormData->FormId == gHighligthMenuInfo.FormId)) {\r
+ if (gHighligthMenuInfo.HLTQuestionId != 0) {\r
+ return (BOOLEAN) (gHighligthMenuInfo.HLTQuestionId == GetQuestionIdInfo (HighLightedStatement->OpCode));\r
} else {\r
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
+ if (CompareMem (gHighligthMenuInfo.HLTOpCode, HighLightedStatement->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) {\r
+ if (gHighligthMenuInfo.HLTIndex == 0 || gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode(HighLightedStatement->OpCode)) {\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Is this the highlight menu.\r
+\r
+ @param MenuOption The input Menu option.\r
+\r
+ @retval TRUE This is the highlight menu option.\r
+ @retval FALSE This is not the highlight menu option.\r
+\r
+**/\r
+BOOLEAN\r
+IsHighLightMenuOption (\r
+ IN UI_MENU_OPTION *MenuOption\r
+ )\r
+{\r
+ if (gHighligthMenuInfo.HLTQuestionId != 0) {\r
+ if (GetQuestionIdInfo(MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.HLTQuestionId) {\r
+ return (BOOLEAN) (MenuOption->Sequence == gHighligthMenuInfo.HLTSequence);\r
+ }\r
+ } else {\r
+ if(CompareMem (gHighligthMenuInfo.HLTOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) {\r
+ if (gHighligthMenuInfo.HLTIndex == 0 || gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode(MenuOption->ThisTag->OpCode)) {\r
+ return (BOOLEAN) (MenuOption->Sequence == gHighligthMenuInfo.HLTSequence);\r
+ } else {\r
+ return FALSE;\r
+ }\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Find the highlight menu.\r
+\r
+ If the input is NULL, base on the record highlight info in\r
+ gHighligthMenuInfo to find the last highlight menu.\r
+\r
+ @param HighLightedStatement The input highlight statement.\r
+\r
+ @retval The highlight menu index.\r
+\r
+**/\r
+LIST_ENTRY *\r
+FindHighLightMenuOption (\r
+ IN FORM_DISPLAY_ENGINE_STATEMENT *HighLightedStatement\r
+ )\r
+{\r
+ LIST_ENTRY *NewPos;\r
+ UI_MENU_OPTION *MenuOption;\r
+\r
+ NewPos = gMenuOption.ForwardLink;\r
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+\r
+ if (HighLightedStatement != NULL) {\r
+ while (MenuOption->ThisTag != HighLightedStatement) {\r
+ NewPos = NewPos->ForwardLink;\r
+ if (NewPos == &gMenuOption) {\r
+ //\r
+ // Not Found it, break\r
+ //\r
+ break;\r
+ }\r
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ }\r
+\r
+ //\r
+ // Must find the highlight statement.\r
+ //\r
+ ASSERT (NewPos != &gMenuOption);\r
+\r
+ } else {\r
+ while (!IsHighLightMenuOption (MenuOption)) {\r
+ NewPos = NewPos->ForwardLink;\r
+ if (NewPos == &gMenuOption) {\r
+ //\r
+ // Not Found it, break\r
+ //\r
+ break;\r
+ }\r
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ }\r
+\r
+ //\r
+ // Highlight statement has disappear (suppressed/disableed)\r
+ //\r
+ if (NewPos == &gMenuOption) {\r
+ NewPos = NULL;\r
+ }\r
+ }\r
+\r
+ return NewPos;\r
+}\r
+\r
+/**\r
+ Is this the Top of screen menu.\r
+\r
+ @param MenuOption The input Menu option.\r
+\r
+ @retval TRUE This is the Top of screen menu option.\r
+ @retval FALSE This is not the Top of screen menu option.\r
+\r
+**/\r
+BOOLEAN\r
+IsTopOfScreeMenuOption (\r
+ IN UI_MENU_OPTION *MenuOption\r
+ )\r
+{\r
+ if (gHighligthMenuInfo.TOSQuestionId != 0) {\r
+ return (BOOLEAN) (GetQuestionIdInfo(MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.TOSQuestionId);\r
+ }\r
+\r
+ if(CompareMem (gHighligthMenuInfo.TOSOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.TOSOpCode->Length) == 0) {\r
+ if (gHighligthMenuInfo.TOSIndex == 0 || gHighligthMenuInfo.TOSIndex == GetIndexInfoForOpcode(MenuOption->ThisTag->OpCode)) {\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Calculate the distance between two menus and include the skip value of StartMenu.\r
+\r
+ @param StartMenu The link_entry pointer to start menu.\r
+ @param EndMenu The link_entry pointer to end menu.\r
+\r
+**/\r
+UINTN\r
+GetDistanceBetweenMenus(\r
+ IN LIST_ENTRY *StartMenu,\r
+ IN LIST_ENTRY *EndMenu\r
+)\r
+{\r
+ LIST_ENTRY *Link;\r
+ UI_MENU_OPTION *MenuOption;\r
+ UINTN Distance;\r
+\r
+ Distance = 0;\r
+\r
+ Link = StartMenu;\r
+ while (Link != EndMenu) {\r
+ MenuOption = MENU_OPTION_FROM_LINK (Link);\r
+ if (MenuOption->Row == 0) {\r
+ UpdateOptionSkipLines (MenuOption);\r
+ }\r
+ Distance += MenuOption->Skip;\r
+ Link = Link->BackLink;\r
+ }\r
+ return Distance;\r
+}\r
+\r
+/**\r
+ Find the top of screen menu base on the previous record menu info.\r
+\r
+ @param HighLightMenu The link_entry pointer to highlight menu.\r
+\r
+ @retval Return the the link_entry pointer top of screen menu.\r
+\r
+**/\r
+LIST_ENTRY *\r
+FindTopOfScreenMenuOption (\r
+ IN LIST_ENTRY *HighLightMenu\r
+ )\r
+{\r
+ LIST_ENTRY *NewPos;\r
+ UI_MENU_OPTION *MenuOption;\r
+ UINTN TopRow;\r
+ UINTN BottomRow;\r
+\r
+ TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;\r
+ BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;\r
+\r
+ NewPos = gMenuOption.ForwardLink;\r
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+\r
+ while (!IsTopOfScreeMenuOption(MenuOption)) {\r
+ NewPos = NewPos->ForwardLink;\r
+ if (NewPos == &gMenuOption) {\r
+ //\r
+ // Not Found it, break\r
+ //\r
+ break;\r
+ }\r
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ }\r
+\r
+ //\r
+ // Last time top of screen menu has disappeared.\r
+ //\r
+ if (NewPos == &gMenuOption) {\r
+ return NULL;\r
+ }\r
+ //\r
+ // Check whether highlight menu and top of screen menu can be shown within one page,\r
+ // if can't, return NULL to re-calcaulate the top of scrren menu. Because some new menus\r
+ // may be dynamically inserted between highlightmenu and previous top of screen menu,\r
+ // So previous record top of screen menu is not appropriate for current display.\r
+ //\r
+ if (GetDistanceBetweenMenus (HighLightMenu, NewPos) + 1 > BottomRow - TopRow) {\r
+ return NULL;\r
+ }\r
+\r
+ return NewPos;\r
+}\r
+\r
+/**\r
+ Find the first menu which will be show at the top.\r
+\r
+ @param FormData The data info for this form.\r
+ @param TopOfScreen The link_entry pointer to top menu.\r
+ @param HighlightMenu The menu which will be highlight.\r
+ @param SkipValue The skip value for the top menu.\r
+\r
+**/\r
+VOID\r
+FindTopMenu (\r
+ IN FORM_DISPLAY_ENGINE_FORM *FormData,\r
+ OUT LIST_ENTRY **TopOfScreen,\r
+ OUT LIST_ENTRY **HighlightMenu,\r
+ OUT UINTN *SkipValue\r
+ )\r
+{\r
+ UINTN TopRow;\r
+ UINTN BottomRow;\r
+ UI_MENU_OPTION *MenuOption;\r
+ UINTN TmpValue;\r
+\r
+ TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;\r
+ BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;\r
+ //\r
+ // When option mismatch happens,there exist two cases,one is reenter the form, just like the if case below,\r
+ // and the other is exit current form and enter last form, it can be covered by the else case.\r
+ //\r
+ if (gMisMatch && gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle && gFormData->FormId == gHighligthMenuInfo.FormId) {\r
+ //\r
+ // Reenter caused by option mismatch or auto exit caused by refresh form(refresh interval/guid),\r
+ // base on the record highlight info to find the highlight menu.\r
+ //\r
+\r
+ *HighlightMenu = FindHighLightMenuOption(NULL);\r
+ if (*HighlightMenu != NULL) {\r
+ //\r
+ // Update skip info for this highlight menu.\r
+ //\r
+ MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);\r
+ UpdateOptionSkipLines (MenuOption);\r
+\r
+ //\r
+ // Found the last time highlight menu.\r
+ //\r
+ *TopOfScreen = FindTopOfScreenMenuOption(*HighlightMenu);\r
+ if (*TopOfScreen != NULL) {\r
+ //\r
+ // Found the last time selectable top of screen menu.\r
+ //\r
+ AdjustDateAndTimePosition(TRUE, TopOfScreen);\r
+ MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen);\r
+ UpdateOptionSkipLines (MenuOption);\r
+\r
+ *SkipValue = gHighligthMenuInfo.SkipValue;\r
+ } else {\r
+ //\r
+ // Not found last time top of screen menu, so base on current highlight menu\r
+ // to find the new top of screen menu.\r
+ // Make the current highlight menu at the bottom of the form to calculate the\r
+ // top of screen menu.\r
+ //\r
+ if (MenuOption->Skip >= BottomRow - TopRow) {\r
+ *TopOfScreen = *HighlightMenu;\r
+ TmpValue = 0;\r
+ } else {\r
+ *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);\r
+ }\r
+\r
+ *SkipValue = TmpValue;\r
+ }\r
+ } else {\r
+ //\r
+ // Last time highlight menu has disappear, find the first highlightable menu as the default one.\r
+ //\r
+ *HighlightMenu = gMenuOption.ForwardLink;\r
+ if (!IsListEmpty (&gMenuOption)) {\r
+ MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);\r
+ }\r
+ *TopOfScreen = gMenuOption.ForwardLink;\r
+ *SkipValue = 0;\r
+ }\r
+\r
+ } else if (FormData->HighLightedStatement != NULL) {\r
+ if (IsSavedHighlightStatement (FormData->HighLightedStatement)) {\r
+ //\r
+ // Input highlight menu is same as last time highlight menu.\r
+ // Base on last time highlight menu to set the top of screen menu and highlight menu.\r
+ //\r
+ *HighlightMenu = FindHighLightMenuOption(NULL);\r
+ ASSERT (*HighlightMenu != NULL);\r
+\r
+ //\r
+ // Update skip info for this highlight menu.\r
+ //\r
+ MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);\r
+ UpdateOptionSkipLines (MenuOption);\r
+\r
+ *TopOfScreen = FindTopOfScreenMenuOption(*HighlightMenu);\r
+ if (*TopOfScreen == NULL) {\r
+ //\r
+ // Not found last time top of screen menu, so base on current highlight menu\r
+ // to find the new top of screen menu.\r
+ // Make the current highlight menu at the bottom of the form to calculate the\r
+ // top of screen menu.\r
+ //\r
+ if (MenuOption->Skip >= BottomRow - TopRow) {\r
+ *TopOfScreen = *HighlightMenu;\r
+ TmpValue = 0;\r
+ } else {\r
+ *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);\r
+ }\r
+\r
+ *SkipValue = TmpValue;\r
+ } else {\r
+ AdjustDateAndTimePosition(TRUE, TopOfScreen);\r
+ MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen);\r
+ UpdateOptionSkipLines (MenuOption);\r
+\r
+ *SkipValue = gHighligthMenuInfo.SkipValue;\r
+ }\r
+ AdjustDateAndTimePosition(TRUE, TopOfScreen);\r
+ } else {\r
+ //\r
+ // Input highlight menu is not save as last time highlight menu.\r
+ //\r
+ *HighlightMenu = FindHighLightMenuOption(FormData->HighLightedStatement);\r
+ MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);\r
+ UpdateOptionSkipLines (MenuOption);\r
+\r
+ //\r
+ // Make the current highlight menu at the bottom of the form to calculate the\r
+ // top of screen menu.\r
+ //\r
+ if (MenuOption->Skip >= BottomRow - TopRow) {\r
+ *TopOfScreen = *HighlightMenu;\r
+ TmpValue = 0;\r
+ } else {\r
+ *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);\r
+ }\r
+\r
+ *SkipValue = TmpValue;\r
+ }\r
+ AdjustDateAndTimePosition(TRUE, TopOfScreen);\r
+ } else {\r
+ //\r
+ // If not has input highlight statement, just return the first one in this form.\r
+ //\r
+ *TopOfScreen = gMenuOption.ForwardLink;\r
+ *HighlightMenu = gMenuOption.ForwardLink;\r
+ if (!IsListEmpty (&gMenuOption)) {\r
+ MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);\r
+ }\r
+ *SkipValue = 0;\r
+ }\r
+\r
+ gMisMatch = FALSE;\r
+\r
+ //\r
+ // First enter to show the menu, update highlight info.\r
+ //\r
+ UpdateHighlightMenuInfo (*HighlightMenu, *TopOfScreen, *SkipValue);\r
+}\r
+\r
+/**\r
+ Record the highlight menu and top of screen menu info.\r
+\r
+ @param Highlight The menu opton which is highlight.\r
+ @param TopOfScreen The menu opton which is at the top of the form.\r
+ @param SkipValue The skip line info for the top of screen menu.\r
+\r
+**/\r
+VOID\r
+UpdateHighlightMenuInfo (\r
+ IN LIST_ENTRY *Highlight,\r
+ IN LIST_ENTRY *TopOfScreen,\r
+ IN UINTN SkipValue\r
+ )\r
+{\r
+ UI_MENU_OPTION *MenuOption;\r
+ FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
+\r
+ gHighligthMenuInfo.HiiHandle = gFormData->HiiHandle;\r
+ gHighligthMenuInfo.FormId = gFormData->FormId;\r
+ gHighligthMenuInfo.SkipValue = (UINT16)SkipValue;\r
+\r
+ if (!IsListEmpty (&gMenuOption)) {\r
+ MenuOption = MENU_OPTION_FROM_LINK (Highlight);\r
+ Statement = MenuOption->ThisTag;\r
+\r
+ gUserInput->SelectedStatement = Statement;\r
+\r
+ gHighligthMenuInfo.HLTSequence = MenuOption->Sequence;\r
+ gHighligthMenuInfo.HLTQuestionId = GetQuestionIdInfo(Statement->OpCode);\r
+ if (gHighligthMenuInfo.HLTQuestionId == 0) {\r
+ //\r
+ // if question id == 0, save the opcode buffer..\r
+ //\r
+ if (gHighligthMenuInfo.HLTOpCode != NULL) {\r
+ FreePool (gHighligthMenuInfo.HLTOpCode);\r
+ }\r
+ gHighligthMenuInfo.HLTOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode);\r
+ ASSERT (gHighligthMenuInfo.HLTOpCode != NULL);\r
+\r
+ gHighligthMenuInfo.HLTIndex = GetIndexInfoForOpcode(Statement->OpCode);\r
+ }\r
+\r
+ MenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
+ Statement = MenuOption->ThisTag;\r
+\r
+ gHighligthMenuInfo.TOSQuestionId = GetQuestionIdInfo(Statement->OpCode);\r
+ if (gHighligthMenuInfo.TOSQuestionId == 0) {\r
+ //\r
+ // if question id == 0, save the opcode buffer..\r
+ //\r
+ if (gHighligthMenuInfo.TOSOpCode != NULL) {\r
+ FreePool (gHighligthMenuInfo.TOSOpCode);\r
+ }\r
+ gHighligthMenuInfo.TOSOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode);\r
+ ASSERT (gHighligthMenuInfo.TOSOpCode != NULL);\r
+\r
+ gHighligthMenuInfo.TOSIndex = GetIndexInfoForOpcode(Statement->OpCode);\r
+ }\r
+ } else {\r
+ gUserInput->SelectedStatement = NULL;\r
+\r
+ gHighligthMenuInfo.HLTSequence = 0;\r
+ gHighligthMenuInfo.HLTQuestionId = 0;\r
+ if (gHighligthMenuInfo.HLTOpCode != NULL) {\r
+ FreePool (gHighligthMenuInfo.HLTOpCode);\r
+ }\r
+ gHighligthMenuInfo.HLTOpCode = NULL;\r
+ gHighligthMenuInfo.HLTIndex = 0;\r
+\r
+ gHighligthMenuInfo.TOSQuestionId = 0;\r
+ if (gHighligthMenuInfo.TOSOpCode != NULL) {\r
+ FreePool (gHighligthMenuInfo.TOSOpCode);\r
+ }\r
+ gHighligthMenuInfo.TOSOpCode = NULL;\r
+ gHighligthMenuInfo.TOSIndex = 0;\r
+ }\r
+}\r
+\r
+/**\r
+ Update attribut for this menu.\r
+\r
+ @param MenuOption The menu opton which this attribut used to.\r
+ @param Highlight Whether this menu will be highlight.\r
+\r
+**/\r
+VOID\r
+SetDisplayAttribute (\r
+ IN UI_MENU_OPTION *MenuOption,\r
+ IN BOOLEAN Highlight\r
+ )\r
+{\r
+ FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
+\r
+ Statement = MenuOption->ThisTag;\r
+\r
+ if (Highlight) {\r
+ gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());\r
+ return;\r
+ }\r
+\r
+ if (MenuOption->GrayOut) {\r
+ gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());\r
+ } else {\r
+ if (Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {\r
+ gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());\r
+ } else {\r
+ gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
}\r
}\r
}\r
PrintStringAtWithWidth (Col, Row, String, Width);\r
return;\r
}\r
- \r
+\r
//\r
// Print the highlight menu string.\r
// First print the highlight string.\r
- // \r
+ //\r
SetDisplayAttribute(MenuOption, TRUE);\r
Length = PrintStringAt (Col, Row, String);\r
\r
@retval FALSE This menu option can't have option string.\r
\r
**/\r
-BOOLEAN \r
+BOOLEAN\r
HasOptionString (\r
IN UI_MENU_OPTION *MenuOption\r
)\r
return TRUE;\r
}\r
\r
+/**\r
+ Double confirm with user about the action.\r
+\r
+ @param Action The user input action.\r
+\r
+ @retval TRUE User confirm with the input or not need user confirm.\r
+ @retval FALSE User want ignore this input.\r
+\r
+**/\r
+BOOLEAN\r
+FxConfirmPopup (\r
+ IN UINT32 Action\r
+ )\r
+{\r
+ EFI_INPUT_KEY Key;\r
+ CHAR16 *CfmStr;\r
+ UINTN CfmStrLen;\r
+ UINT32 CheckFlags;\r
+ BOOLEAN RetVal;\r
+ UINTN CatLen;\r
+ UINTN MaxLen;\r
+\r
+ CfmStrLen = 0;\r
+ CatLen = StrLen (gConfirmMsgConnect);\r
+\r
+ //\r
+ // Below action need extra popup dialog to confirm.\r
+ //\r
+ CheckFlags = BROWSER_ACTION_DISCARD |\r
+ BROWSER_ACTION_DEFAULT |\r
+ BROWSER_ACTION_SUBMIT |\r
+ BROWSER_ACTION_RESET |\r
+ BROWSER_ACTION_EXIT;\r
+\r
+ //\r
+ // Not need to confirm with user, just return TRUE.\r
+ //\r
+ if ((Action & CheckFlags) == 0) {\r
+ return TRUE;\r
+ }\r
+\r
+ if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {\r
+ CfmStrLen += StrLen (gConfirmDiscardMsg);\r
+ }\r
+\r
+ if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
+ if (CfmStrLen != 0) {\r
+ CfmStrLen += CatLen;\r
+ }\r
+\r
+ CfmStrLen += StrLen (gConfirmDefaultMsg);\r
+ }\r
+\r
+ if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {\r
+ if (CfmStrLen != 0) {\r
+ CfmStrLen += CatLen;\r
+ }\r
+\r
+ CfmStrLen += StrLen (gConfirmSubmitMsg);\r
+ }\r
+\r
+ if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {\r
+ if (CfmStrLen != 0) {\r
+ CfmStrLen += CatLen;\r
+ }\r
+\r
+ CfmStrLen += StrLen (gConfirmResetMsg);\r
+ }\r
+\r
+ if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {\r
+ if (CfmStrLen != 0) {\r
+ CfmStrLen += CatLen;\r
+ }\r
+\r
+ CfmStrLen += StrLen (gConfirmExitMsg);\r
+ }\r
+\r
+ //\r
+ // Allocate buffer to save the string.\r
+ // String + "?" + "\0"\r
+ //\r
+ MaxLen = CfmStrLen + 1 + 1;\r
+ CfmStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
+ ASSERT (CfmStr != NULL);\r
+\r
+ if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {\r
+ StrCpyS (CfmStr, MaxLen, gConfirmDiscardMsg);\r
+ }\r
+\r
+ if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
+ if (CfmStr[0] != 0) {\r
+ StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);\r
+ StrCatS (CfmStr, MaxLen, gConfirmDefaultMsg2nd);\r
+ } else {\r
+ StrCpyS (CfmStr, MaxLen, gConfirmDefaultMsg);\r
+ }\r
+ }\r
+\r
+ if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {\r
+ if (CfmStr[0] != 0) {\r
+ StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);\r
+ StrCatS (CfmStr, MaxLen, gConfirmSubmitMsg2nd);\r
+ } else {\r
+ StrCpyS (CfmStr, MaxLen, gConfirmSubmitMsg);\r
+ }\r
+ }\r
+\r
+ if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {\r
+ if (CfmStr[0] != 0) {\r
+ StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);\r
+ StrCatS (CfmStr, MaxLen, gConfirmResetMsg2nd);\r
+ } else {\r
+ StrCpyS (CfmStr, MaxLen, gConfirmResetMsg);\r
+ }\r
+ }\r
+\r
+ if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {\r
+ if (CfmStr[0] != 0) {\r
+ StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);\r
+ StrCatS (CfmStr, MaxLen, gConfirmExitMsg2nd);\r
+ } else {\r
+ StrCpyS (CfmStr, MaxLen, gConfirmExitMsg);\r
+ }\r
+ }\r
+\r
+ StrCatS (CfmStr, MaxLen, gConfirmMsgEnd);\r
+\r
+ do {\r
+ CreateDialog (&Key, gEmptyString, CfmStr, gConfirmOpt, gEmptyString, NULL);\r
+ } while (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) &&\r
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptNo[0] | UPPER_LOWER_CASE_OFFSET)) &&\r
+ (Key.ScanCode != SCAN_ESC));\r
+\r
+ if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) {\r
+ RetVal = TRUE;\r
+ } else {\r
+ RetVal = FALSE;\r
+ }\r
+\r
+ FreePool (CfmStr);\r
+\r
+ return RetVal;\r
+}\r
\r
/**\r
Print string for this menu option.\r
@param MenuOption The menu opton which this attribut used to.\r
@param SkipWidth The skip width between the left to the start of the prompt.\r
@param BeginCol The begin column for one menu.\r
- @param SkipLine The skip line for this menu. \r
+ @param SkipLine The skip line for this menu.\r
@param BottomRow The bottom row for this form.\r
@param Highlight Whether this menu will be highlight.\r
+ @param UpdateCol Whether need to update the column info for Date/Time.\r
\r
@retval EFI_SUCESSS Process the user selection success.\r
\r
IN UINTN BeginCol,\r
IN UINTN SkipLine,\r
IN UINTN BottomRow,\r
- IN BOOLEAN Highlight\r
+ IN BOOLEAN Highlight,\r
+ IN BOOLEAN UpdateCol\r
)\r
{\r
FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
UINTN Temp3;\r
EFI_STATUS Status;\r
UINTN Row;\r
+ BOOLEAN IsProcessingFirstRow;\r
UINTN Col;\r
UINTN PromptLineNum;\r
UINTN OptionLineNum;\r
PromptLineNum = 0;\r
OptionLineNum = 0;\r
MaxRow = 0;\r
+ IsProcessingFirstRow = TRUE;\r
\r
//\r
// Set default color.\r
//\r
// Adjust option string for date/time opcode.\r
//\r
- ProcessStringForDateTime(MenuOption, OptionString, TRUE);\r
+ ProcessStringForDateTime(MenuOption, OptionString, UpdateCol);\r
}\r
- \r
+\r
Width = (UINT16) gOptionBlockWidth - 1;\r
Row = MenuOption->Row;\r
GlyphWidth = 1;\r
OptionLineNum = 0;\r
- \r
+\r
for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
if (((Temp2 == 0)) && (Row <= BottomRow)) {\r
if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
} else {\r
//\r
// For date/ time, print the first and second past (year for date and second for time)\r
- // \r
- DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, StrLen (OutputString), Highlight);\r
+ // The OutputString has a NARROW_CHAR or WIDE_CHAR at the begin of the string,\r
+ // so need to - 1 to remove it, otherwise, it will clean 1 extr char follow it.\r
+ DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, StrLen (OutputString) - 1, Highlight);\r
}\r
} else {\r
DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight);\r
}\r
OptionLineNum++;\r
}\r
- \r
+\r
//\r
// If there is more string to process print on the next row and increment the Skip value\r
//\r
}\r
}\r
}\r
- \r
+\r
FreePool (OutputString);\r
if (Temp2 != 0) {\r
Temp2--;\r
}\r
}\r
- \r
+\r
Highlight = FALSE;\r
\r
FreePool (OptionString);\r
//\r
// 2. Paint the description.\r
//\r
- PromptWidth = GetWidth (Statement, &AdjustValue);\r
+ PromptWidth = GetWidth (MenuOption, &AdjustValue);\r
Row = MenuOption->Row;\r
GlyphWidth = 1;\r
PromptLineNum = 0;\r
PrintStringAtWithWidth (BeginCol, Row, L"", PromptWidth + AdjustValue + SkipWidth);\r
PromptLineNum++;\r
} else {\r
- for (Index = 0; GetLineByWidth (MenuOption->Description, PromptWidth, &GlyphWidth, &Index, &OutputString) != 0x0000;) { \r
- if ((Temp == 0) && (Row <= BottomRow)) { \r
+ for (Index = 0; GetLineByWidth (MenuOption->Description, PromptWidth, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
+ if ((Temp == 0) && (Row <= BottomRow)) {\r
//\r
- // 1.Clean the start LEFT_SKIPPED_COLUMNS \r
+ // 1.Clean the start LEFT_SKIPPED_COLUMNS\r
//\r
PrintStringAtWithWidth (BeginCol, Row, L"", SkipWidth);\r
- \r
- if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2) {\r
+\r
+ if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2 && IsProcessingFirstRow) {\r
//\r
// Print Arrow for Goto button.\r
//\r
Row,\r
GEOMETRICSHAPE_RIGHT_TRIANGLE\r
);\r
+ IsProcessingFirstRow = FALSE;\r
}\r
DisplayMenuString (MenuOption, MenuOption->Col, Row, OutputString, PromptWidth + AdjustValue, Highlight);\r
PromptLineNum ++;\r
//\r
if ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo != 0)) {\r
StringPtr = GetToken (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo, gFormData->HiiHandle);\r
- \r
+\r
Width = (UINT16) gOptionBlockWidth - 1;\r
Row = MenuOption->Row;\r
GlyphWidth = 1;\r
OptionLineNum = 0;\r
\r
- for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) { \r
+ for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
if ((Temp3 == 0) && (Row <= BottomRow)) {\r
DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight);\r
OptionLineNum++;\r
if (StrLen (&StringPtr[Index]) != 0) {\r
if (Temp3 == 0) {\r
Row++;\r
+ //\r
+ // If the rows for text two is greater than or equal to the skip value, increase the skip value\r
+ //\r
+ if ((Row - MenuOption->Row) >= MenuOption->Skip) {\r
+ MenuOption->Skip++;\r
+ }\r
}\r
}\r
- \r
+\r
FreePool (OutputString);\r
if (Temp3 != 0) {\r
Temp3--;\r
Row = (OptionLineNum < PromptLineNum ? OptionLineNum : PromptLineNum) + MenuOption->Row;\r
Width = (UINT16) (OptionLineNum < PromptLineNum ? gOptionBlockWidth : PromptWidth + AdjustValue + SkipWidth);\r
MaxRow = (OptionLineNum < PromptLineNum ? PromptLineNum : OptionLineNum) + MenuOption->Row - 1;\r
- \r
+\r
while (Row <= MaxRow) {\r
DisplayMenuString (MenuOption, Col, Row++, L"", Width, FALSE);\r
}\r
IN FORM_DISPLAY_ENGINE_FORM *FormData\r
)\r
{\r
- INTN SkipValue;\r
+ UINTN SkipValue;\r
INTN Difference;\r
UINTN DistanceValue;\r
UINTN Row;\r
UINTN Temp2;\r
UINTN TopRow;\r
UINTN BottomRow;\r
- UINTN OriginalRow;\r
UINTN Index;\r
- UINT16 Width;\r
CHAR16 *StringPtr;\r
+ CHAR16 *StringRightPtr;\r
+ CHAR16 *StringErrorPtr;\r
CHAR16 *OptionString;\r
- CHAR16 *OutputString;\r
CHAR16 *HelpString;\r
CHAR16 *HelpHeaderString;\r
CHAR16 *HelpBottomString;\r
UI_MENU_OPTION *MenuOption;\r
UI_MENU_OPTION *NextMenuOption;\r
UI_MENU_OPTION *SavedMenuOption;\r
- UI_MENU_OPTION *PreviousMenuOption;\r
UI_CONTROL_FLAG ControlFlag;\r
UI_SCREEN_OPERATION ScreenOperation;\r
- UINT16 DefaultId;\r
FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
BROWSER_HOT_KEY *HotKey;\r
UINTN HelpPageIndex;\r
UINTN HelpHeaderLine;\r
UINTN HelpBottomLine;\r
BOOLEAN MultiHelpPage;\r
- UINT16 GlyphWidth;\r
UINT16 EachLineWidth;\r
UINT16 HeaderLineWidth;\r
UINT16 BottomLineWidth;\r
EFI_STRING_ID HelpInfo;\r
UI_EVENT_TYPE EventType;\r
- FORM_DISPLAY_ENGINE_STATEMENT *InitialHighlight;\r
BOOLEAN SkipHighLight;\r
+ EFI_HII_VALUE *StatementValue;\r
\r
EventType = UIEventNone;\r
Status = EFI_SUCCESS;\r
OptionString = NULL;\r
ScreenOperation = UiNoOperation;\r
NewLine = TRUE;\r
- DefaultId = 0;\r
HelpPageCount = 0;\r
HelpLine = 0;\r
RowCount = 0;\r
EachLineWidth = 0;\r
HeaderLineWidth = 0;\r
BottomLineWidth = 0;\r
- OutputString = NULL;\r
UpArrow = FALSE;\r
DownArrow = FALSE;\r
SkipValue = 0;\r
SkipHighLight = FALSE;\r
\r
NextMenuOption = NULL;\r
- PreviousMenuOption = NULL;\r
SavedMenuOption = NULL;\r
HotKey = NULL;\r
Repaint = TRUE;\r
MenuOption = NULL;\r
gModalSkipColumn = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6;\r
- InitialHighlight = gFormData->HighLightedStatement;\r
\r
ZeroMem (&Key, sizeof (EFI_INPUT_KEY));\r
\r
- //\r
- // Left right\r
- // |<-.->|<-.........->|<- .........->|<-...........->|\r
- // Skip Prompt Option Help \r
- //\r
- Width = (CHAR16) ((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3);\r
- gOptionBlockWidth = Width + 1; \r
- gHelpBlockWidth = (CHAR16) (Width - LEFT_SKIPPED_COLUMNS);\r
- gPromptBlockWidth = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * Width - 1);\r
-\r
TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;\r
BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT - 1;\r
\r
}\r
\r
FindTopMenu(FormData, &TopOfScreen, &NewPos, &SkipValue);\r
+ if (!IsListEmpty (&gMenuOption)) {\r
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ gUserInput->SelectedStatement = NextMenuOption->ThisTag;\r
+ }\r
\r
gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
\r
while (TRUE) {\r
switch (ControlFlag) {\r
case CfInitialization:\r
- if ((gOldFormEntry.HiiHandle != FormData->HiiHandle) || \r
+ if ((gOldFormEntry.HiiHandle != FormData->HiiHandle) ||\r
(!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))) {\r
//\r
// Clear Statement range if different formset is painted.\r
Row = TopRow;\r
\r
gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
- \r
+\r
//\r
// 1. Check whether need to print the arrow up.\r
//\r
}\r
\r
if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {\r
- Status = DisplayOneMenu (MenuOption, \r
- LEFT_SKIPPED_COLUMNS,\r
- gStatementDimensions.LeftColumn + gModalSkipColumn, \r
- Link == TopOfScreen ? SkipValue : 0, \r
+ Status = DisplayOneMenu (MenuOption,\r
+ MenuOption->Col - gStatementDimensions.LeftColumn,\r
+ gStatementDimensions.LeftColumn + gModalSkipColumn,\r
+ Link == TopOfScreen ? SkipValue : 0,\r
BottomRow,\r
- (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption))\r
+ (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption)),\r
+ TRUE\r
);\r
} else {\r
- Status = DisplayOneMenu (MenuOption, \r
- LEFT_SKIPPED_COLUMNS,\r
- gStatementDimensions.LeftColumn, \r
- Link == TopOfScreen ? SkipValue : 0, \r
+ Status = DisplayOneMenu (MenuOption,\r
+ MenuOption->Col - gStatementDimensions.LeftColumn,\r
+ gStatementDimensions.LeftColumn,\r
+ Link == TopOfScreen ? SkipValue : 0,\r
BottomRow,\r
- (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption))\r
- ); \r
+ (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption)),\r
+ TRUE\r
+ );\r
}\r
\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if (gMisMatch) {\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return Status;\r
+ }\r
}\r
//\r
// 3. Update the row info which will be used by next menu.\r
}\r
\r
MenuOption = NULL;\r
-\r
- if (IsListEmpty (&gMenuOption)) { \r
- ControlFlag = CfReadKey;\r
- }\r
}\r
break;\r
\r
//\r
ControlFlag = CfUpdateHelpString;\r
\r
+ ASSERT (NewPos != NULL);\r
+ UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
+\r
if (SkipHighLight) {\r
- MenuOption = SavedMenuOption;\r
SkipHighLight = FALSE;\r
- UpdateHighlightMenuInfo (MenuOption);\r
+ MenuOption = SavedMenuOption;\r
+ RefreshKeyHelp(gFormData, SavedMenuOption->ThisTag, FALSE);\r
+ break;\r
+ }\r
+\r
+ if (IsListEmpty (&gMenuOption)) {\r
+ //\r
+ // No menu option, just update the hotkey filed.\r
+ //\r
+ RefreshKeyHelp(gFormData, NULL, FALSE);\r
break;\r
}\r
\r
Temp2 = 0;\r
}\r
\r
- if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {\r
+ if (MenuOption == NULL || NewPos != &MenuOption->Link) {\r
if (MenuOption != NULL) {\r
//\r
- // Remove highlight on last Menu Option\r
+ // Remove the old highlight menu.\r
//\r
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);\r
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);\r
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
- if (OptionString != NULL) {\r
- if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||\r
- (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)\r
- ) {\r
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);\r
- }\r
-\r
- Width = (UINT16) gOptionBlockWidth;\r
- OriginalRow = MenuOption->Row;\r
- GlyphWidth = 1;\r
-\r
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {\r
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);\r
- }\r
- //\r
- // If there is more string to process print on the next row and increment the Skip value\r
- //\r
- if (StrLen (&OptionString[Index]) != 0) {\r
- if (Temp == 0) {\r
- MenuOption->Row++;\r
- }\r
- }\r
-\r
- FreePool (OutputString);\r
- if (Temp != 0) {\r
- Temp--;\r
- }\r
- }\r
-\r
- MenuOption->Row = OriginalRow;\r
-\r
- FreePool (OptionString);\r
- } else {\r
- if (NewLine) {\r
- if (MenuOption->GrayOut) {\r
- gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());\r
- } else if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {\r
- gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());\r
- }\r
-\r
- OriginalRow = MenuOption->Row;\r
- Width = GetWidth (MenuOption->ThisTag, NULL);\r
- GlyphWidth = 1;\r
-\r
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {\r
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);\r
- }\r
- //\r
- // If there is more string to process print on the next row and increment the Skip value\r
- //\r
- if (StrLen (&MenuOption->Description[Index]) != 0) {\r
- if (Temp == 0) {\r
- MenuOption->Row++;\r
- }\r
- }\r
-\r
- FreePool (OutputString);\r
- if (Temp != 0) {\r
- Temp--;\r
- }\r
- }\r
-\r
- MenuOption->Row = OriginalRow;\r
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
- }\r
- }\r
+ Status = DisplayOneMenu (MenuOption,\r
+ MenuOption->Col - gStatementDimensions.LeftColumn,\r
+ gStatementDimensions.LeftColumn,\r
+ Temp,\r
+ BottomRow,\r
+ FALSE,\r
+ FALSE\r
+ );\r
}\r
\r
//\r
// This is the current selected statement\r
//\r
MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
- Statement = MenuOption->ThisTag;\r
-\r
- UpdateHighlightMenuInfo (MenuOption);\r
+ RefreshKeyHelp(gFormData, MenuOption->ThisTag, FALSE);\r
\r
if (!IsSelectable (MenuOption)) {\r
break;\r
}\r
\r
- //\r
- // Set reverse attribute\r
- //\r
- gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());\r
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);\r
-\r
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);\r
- if (OptionString != NULL) {\r
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);\r
- }\r
- Width = (UINT16) gOptionBlockWidth;\r
-\r
- OriginalRow = MenuOption->Row;\r
- GlyphWidth = 1;\r
-\r
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {\r
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);\r
- }\r
- //\r
- // If there is more string to process print on the next row and increment the Skip value\r
- //\r
- if (StrLen (&OptionString[Index]) != 0) {\r
- if (Temp2 == 0) {\r
- MenuOption->Row++;\r
- }\r
- }\r
-\r
- FreePool (OutputString);\r
- if (Temp2 != 0) {\r
- Temp2--;\r
- }\r
- }\r
-\r
- MenuOption->Row = OriginalRow;\r
-\r
- FreePool (OptionString);\r
- } else {\r
- if (NewLine) {\r
- OriginalRow = MenuOption->Row;\r
-\r
- Width = GetWidth (Statement, NULL);\r
- GlyphWidth = 1;\r
-\r
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {\r
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);\r
- }\r
- //\r
- // If there is more string to process print on the next row and increment the Skip value\r
- //\r
- if (StrLen (&MenuOption->Description[Index]) != 0) {\r
- if (Temp2 == 0) {\r
- MenuOption->Row++;\r
- }\r
- }\r
-\r
- FreePool (OutputString);\r
- if (Temp2 != 0) {\r
- Temp2--;\r
- }\r
- }\r
-\r
- MenuOption->Row = OriginalRow;\r
-\r
- }\r
- }\r
-\r
- //\r
- // Clear reverse attribute\r
- //\r
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
+ Status = DisplayOneMenu (MenuOption,\r
+ MenuOption->Col - gStatementDimensions.LeftColumn,\r
+ gStatementDimensions.LeftColumn,\r
+ Temp2,\r
+ BottomRow,\r
+ TRUE,\r
+ FALSE\r
+ );\r
}\r
break;\r
\r
break;\r
}\r
\r
+ //\r
+ // NewLine means only update highlight menu (remove old highlight and highlith\r
+ // the new one), not need to full repain the form.\r
+ //\r
if (Repaint || NewLine) {\r
- //\r
- // Don't print anything if it is a NULL help token\r
- //\r
- ASSERT(MenuOption != NULL);\r
- HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;\r
- if (HelpInfo == 0 || !IsSelectable (MenuOption)) {\r
+ if (IsListEmpty (&gMenuOption)) {\r
+ //\r
+ // Don't print anything if no mwnu option.\r
+ //\r
StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
} else {\r
- StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);\r
+ //\r
+ // Don't print anything if it is a NULL help token\r
+ //\r
+ ASSERT(MenuOption != NULL);\r
+ HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;\r
+ Statement = MenuOption->ThisTag;\r
+ StatementValue = &Statement->CurrentValue;\r
+ if (HelpInfo == 0 || !IsSelectable (MenuOption)) {\r
+ if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP && StatementValue->Value.date.Month== 0xff)||(Statement->OpCode->OpCode == EFI_IFR_TIME_OP && StatementValue->Value.time.Hour == 0xff)){\r
+ StringPtr = GetToken (STRING_TOKEN (GET_TIME_FAIL), gHiiHandle);\r
+ } else {\r
+ StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
+ }\r
+ } else {\r
+ if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP && StatementValue->Value.date.Month== 0xff)||(Statement->OpCode->OpCode == EFI_IFR_TIME_OP && StatementValue->Value.time.Hour == 0xff)){\r
+ StringRightPtr = GetToken (HelpInfo, gFormData->HiiHandle);\r
+ StringErrorPtr = GetToken (STRING_TOKEN (GET_TIME_FAIL), gHiiHandle);\r
+ StringPtr = AllocateZeroPool ((StrLen (StringRightPtr) + StrLen (StringErrorPtr)+ 1 ) * sizeof (CHAR16));\r
+ StrCpyS (StringPtr, StrLen (StringRightPtr) + StrLen (StringErrorPtr) + 1, StringRightPtr);\r
+ StrCatS (StringPtr, StrLen (StringRightPtr) + StrLen (StringErrorPtr) + 1, StringErrorPtr);\r
+ FreePool (StringRightPtr);\r
+ FreePool (StringErrorPtr);\r
+ } else {\r
+ StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);\r
+ }\r
+ }\r
}\r
\r
RowCount = BottomRow - TopRow + 1;\r
//\r
if (HelpLine > 2 * RowCount - 2) {\r
HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;\r
- if ((HelpLine - RowCount + 1) % (RowCount - 2) > 1) {\r
+ if ((HelpLine - RowCount + 1) % (RowCount - 2) != 0) {\r
HelpPageCount += 1;\r
}\r
} else {\r
//\r
// Check whether need to show the 'More(U/u)' at the begin.\r
// Base on current direct info, here shows aligned to the right side of the column.\r
- // If the direction is multi line and aligned to right side may have problem, so \r
+ // If the direction is multi line and aligned to right side may have problem, so\r
// add ASSERT code here.\r
//\r
if (HelpPageIndex > 0) {\r
gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());\r
for (Index = 0; Index < HelpHeaderLine; Index++) {\r
ASSERT (HelpHeaderLine == 1);\r
- ASSERT (GetStringWidth (HelpHeaderString) / 2 < (UINTN) (gHelpBlockWidth - 1));\r
+ ASSERT (GetStringWidth (HelpHeaderString) / 2 < ((UINT32) gHelpBlockWidth - 1));\r
PrintStringAtWithWidth (\r
gStatementDimensions.RightColumn - gHelpBlockWidth,\r
Index + TopRow,\r
);\r
}\r
} else {\r
- for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) && \r
+ for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) &&\r
(Index + HelpPageIndex * (RowCount - 2) + 1 < HelpLine); Index++) {\r
PrintStringAtWithWidth (\r
gStatementDimensions.RightColumn - gHelpBlockWidth,\r
}\r
gST->ConOut->SetCursorPosition(gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);\r
}\r
- } \r
+ }\r
}\r
\r
//\r
// Check whether need to print the 'More(D/d)' at the bottom.\r
// Base on current direct info, here shows aligned to the right side of the column.\r
- // If the direction is multi line and aligned to right side may have problem, so \r
+ // If the direction is multi line and aligned to right side may have problem, so\r
// add ASSERT code here.\r
//\r
if (HelpPageIndex < HelpPageCount - 1 && MultiHelpPage) {\r
gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());\r
for (Index = 0; Index < HelpBottomLine; Index++) {\r
ASSERT (HelpBottomLine == 1);\r
- ASSERT (GetStringWidth (HelpBottomString) / 2 < (UINTN) (gHelpBlockWidth - 1)); \r
+ ASSERT (GetStringWidth (HelpBottomString) / 2 < ((UINT32) gHelpBlockWidth - 1));\r
PrintStringAtWithWidth (\r
gStatementDimensions.RightColumn - gHelpBlockWidth,\r
BottomRow + Index - HelpBottomLine + 1,\r
if (Status != EFI_NOT_READY) {\r
continue;\r
}\r
- \r
+\r
EventType = UiWaitForEvent(gST->ConIn->WaitForKey);\r
if (EventType == UIEventKey) {\r
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
}\r
\r
if (EventType == UIEventDriver) {\r
+ gMisMatch = TRUE;\r
gUserInput->Action = BROWSER_ACTION_NONE;\r
ControlFlag = CfExit;\r
break;\r
}\r
- \r
+\r
if (EventType == UIEventTimeOut) {\r
gUserInput->Action = BROWSER_ACTION_FORM_EXIT;\r
ControlFlag = CfExit;\r
// If the screen has no menu items, and the user didn't select UiReset\r
// ignore the selection and go back to reading keys.\r
//\r
+ ASSERT(MenuOption != NULL);\r
if(IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) {\r
ControlFlag = CfReadKey;\r
break;\r
}\r
\r
- ASSERT(MenuOption != NULL);\r
Statement = MenuOption->ThisTag;\r
if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP)\r
|| (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)\r
} else {\r
gDirection = SCAN_LEFT;\r
}\r
- \r
+\r
Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);\r
if (OptionString != NULL) {\r
FreePool (OptionString);\r
ControlFlag = CfReadKey;\r
break;\r
}\r
- \r
+\r
ASSERT(MenuOption != NULL);\r
if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut && !MenuOption->ReadOnly) {\r
ScreenOperation = UiSelect;\r
break;\r
}\r
}\r
- \r
+\r
if (((FormData->Attribute & HII_DISPLAY_MODAL) != 0) && (Key.ScanCode == SCAN_ESC || Index == mScanCodeNumber)) {\r
//\r
// ModalForm has no ESC key and Hot Key.\r
break;\r
\r
case CfScreenOperation:\r
- if (ScreenOperation != UiReset) {\r
+ if ((ScreenOperation != UiReset) && (ScreenOperation != UiHotKey)) {\r
//\r
- // If the screen has no menu items, and the user didn't select UiReset\r
+ // If the screen has no menu items, and the user didn't select UiReset or UiHotKey\r
// ignore the selection and go back to reading keys.\r
//\r
if (IsListEmpty (&gMenuOption)) {\r
}\r
\r
for (Index = 0;\r
- Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);\r
+ Index < ARRAY_SIZE (gScreenOperationToControlFlag);\r
Index++\r
) {\r
if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {\r
//\r
RefreshKeyHelp (gFormData, Statement, TRUE);\r
Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);\r
- \r
+\r
if (OptionString != NULL) {\r
FreePool (OptionString);\r
}\r
- \r
+\r
if (EFI_ERROR (Status)) {\r
Repaint = TRUE;\r
NewLine = TRUE;\r
break;\r
}\r
\r
- //\r
- // When user press ESC, it will try to show another menu, should clean the gSequence info.\r
- //\r
- if (gSequence != 0) {\r
- gSequence = 0;\r
- }\r
-\r
gUserInput->Action = BROWSER_ACTION_FORM_EXIT;\r
ControlFlag = CfExit;\r
break;\r
\r
case CfUiHotKey:\r
ControlFlag = CfRepaint;\r
- \r
- gUserInput->Action = HotKey->Action;\r
- ControlFlag = CfExit;\r
+\r
+ ASSERT (HotKey != NULL);\r
+\r
+ if (FxConfirmPopup(HotKey->Action)) {\r
+ gUserInput->Action = HotKey->Action;\r
+ if ((HotKey->Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
+ gUserInput->DefaultId = HotKey->DefaultId;\r
+ }\r
+ ControlFlag = CfExit;\r
+ } else {\r
+ Repaint = TRUE;\r
+ NewLine = TRUE;\r
+ ControlFlag = CfRepaint;\r
+ }\r
+\r
break;\r
\r
case CfUiLeft:\r
\r
case CfUiUp:\r
ControlFlag = CfRepaint;\r
+ NewLine = TRUE;\r
\r
SavedListEntry = NewPos;\r
-\r
ASSERT(NewPos != NULL);\r
- //\r
- // Adjust Date/Time position before we advance forward.\r
- //\r
- AdjustDateAndTimePosition (TRUE, &NewPos);\r
- if (NewPos->BackLink != &gMenuOption) {\r
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
- ASSERT (MenuOption != NULL);\r
- NewLine = TRUE;\r
- NewPos = NewPos->BackLink;\r
-\r
- PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
- if (PreviousMenuOption->Row == 0) {\r
- UpdateOptionSkipLines (PreviousMenuOption);\r
- }\r
- DistanceValue = PreviousMenuOption->Skip;\r
- Difference = 0;\r
- if (MenuOption->Row >= DistanceValue + TopRow) {\r
- Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);\r
- }\r
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
- \r
- if (Difference < 0) {\r
- //\r
- // We hit the begining MenuOption that can be focused\r
- // so we simply scroll to the top.\r
- //\r
- if (TopOfScreen != gMenuOption.ForwardLink) {\r
- TopOfScreen = gMenuOption.ForwardLink;\r
- Repaint = TRUE;\r
- } else {\r
- //\r
- // Scroll up to the last page when we have arrived at top page.\r
- //\r
- NewPos = &gMenuOption;\r
- TopOfScreen = &gMenuOption;\r
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
- ScreenOperation = UiPageUp;\r
- ControlFlag = CfScreenOperation;\r
- break;\r
- }\r
- } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {\r
- //\r
- // Previous focus MenuOption is above the TopOfScreen, so we need to scroll\r
- //\r
- TopOfScreen = NewPos;\r
- Repaint = TRUE;\r
- SkipValue = 0;\r
- } else if (!IsSelectable (NextMenuOption)) {\r
- //\r
- // Continue to go up until scroll to next page or the selectable option is found.\r
- //\r
- ScreenOperation = UiUp;\r
- ControlFlag = CfScreenOperation;\r
- }\r
-\r
- //\r
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
- //\r
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
- AdjustDateAndTimePosition (TRUE, &NewPos);\r
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
- UpdateStatusBar (INPUT_ERROR, FALSE);\r
- } else {\r
- //\r
- // Scroll up to the last page.\r
- //\r
- NewPos = &gMenuOption;\r
- TopOfScreen = &gMenuOption;\r
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
- ScreenOperation = UiPageUp;\r
- ControlFlag = CfScreenOperation;\r
- }\r
- break;\r
-\r
- case CfUiPageUp:\r
- //\r
- // SkipValue means lines is skipped when show the top menu option.\r
- //\r
- ControlFlag = CfRepaint;\r
-\r
- ASSERT(NewPos != NULL);\r
- //\r
- // Already at the first menu option, Check the skip value.\r
- //\r
- if (NewPos->BackLink == &gMenuOption) {\r
- if (SkipValue == 0) {\r
- NewLine = FALSE;\r
- Repaint = FALSE;\r
- } else {\r
- NewLine = TRUE;\r
- Repaint = TRUE;\r
- SkipValue = 0;\r
- }\r
- break;\r
- }\r
\r
- NewLine = TRUE;\r
- Repaint = TRUE;\r
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ ASSERT (MenuOption != NULL);\r
\r
//\r
- // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one\r
- // form of options to be show, so just update the SkipValue to show the next\r
- // parts of options.\r
+ // Adjust Date/Time position before we advance forward.\r
//\r
- if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {\r
- SkipValue -= BottomRow - TopRow + 1;\r
- break;\r
- }\r
+ AdjustDateAndTimePosition (TRUE, &NewPos);\r
\r
- Link = TopOfScreen;\r
+ NewPos = NewPos->BackLink;\r
//\r
- // First minus the menu of the top screen, it's value is SkipValue.\r
+ // Find next selectable menu or the first menu beyond current form.\r
//\r
- Index = (BottomRow + 1) - SkipValue;\r
- while ((Index > TopRow) && (Link->BackLink != &gMenuOption)) {\r
- Link = Link->BackLink;\r
- PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);\r
- if (PreviousMenuOption->Row == 0) {\r
- UpdateOptionSkipLines (PreviousMenuOption);\r
- } \r
- if (Index < PreviousMenuOption->Skip) {\r
- break;\r
- }\r
- Index = Index - PreviousMenuOption->Skip;\r
- }\r
- \r
- if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {\r
- SkipValue = 0;\r
- if (TopOfScreen == &gMenuOption) {\r
+ Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow, FALSE);\r
+ if (Difference < 0) {\r
+ //\r
+ // We hit the begining MenuOption that can be focused\r
+ // so we simply scroll to the top.\r
+ //\r
+ Repaint = TRUE;\r
+ if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) {\r
TopOfScreen = gMenuOption.ForwardLink;\r
- NewPos = gMenuOption.BackLink;\r
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);\r
- Repaint = FALSE;\r
- } else if (TopOfScreen != Link) {\r
- TopOfScreen = Link;\r
- NewPos = Link;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ NewPos = SavedListEntry;\r
+ SkipValue = 0;\r
} else {\r
//\r
- // Finally we know that NewPos is the last MenuOption can be focused.\r
+ // Scroll up to the last page when we have arrived at top page.\r
//\r
- Repaint = FALSE;\r
- NewPos = Link;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ TopOfScreen = FindTopOfScreenMenu (gMenuOption.BackLink, BottomRow - TopRow, &SkipValue);\r
+ NewPos = gMenuOption.BackLink;\r
+ MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow, TRUE);\r
}\r
} else {\r
- if (Index > TopRow) {\r
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+\r
+ if (MenuOption->Row < TopRow + Difference + NextMenuOption->Skip) {\r
//\r
- // At here, only case "Index < PreviousMenuOption->Skip" can reach here.\r
+ // Previous focus MenuOption is above the TopOfScreen, so we need to scroll\r
//\r
- SkipValue = PreviousMenuOption->Skip - (Index - TopRow);\r
- } else if (Index == TopRow) {\r
- SkipValue = 0;\r
- } else {\r
- SkipValue = TopRow - Index;\r
+ TopOfScreen = NewPos;\r
+ Repaint = TRUE;\r
+ SkipValue = 0;\r
}\r
\r
//\r
- // Move to the option in Next page.\r
+ // Check whether new highlight menu is selectable, if not, keep highlight on the old one.\r
//\r
- if (TopOfScreen == &gMenuOption) {\r
- NewPos = gMenuOption.BackLink;\r
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);\r
- } else {\r
- NewPos = Link;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ // BottomRow - TopRow + 1 means the total rows current forms supported.\r
+ // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu\r
+ // and new top menu. New top menu will all shows in next form, but last highlight menu\r
+ // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the\r
+ // last highlight menu.\r
+ //\r
+ if (!IsSelectable(NextMenuOption) && IsSelectable(MenuOption) &&\r
+ (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1)) {\r
+ NewPos = SavedListEntry;\r
}\r
+ }\r
+\r
+ UpdateStatusBar (INPUT_ERROR, FALSE);\r
\r
+ //\r
+ // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
+ //\r
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
+ AdjustDateAndTimePosition (TRUE, &NewPos);\r
+\r
+ UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
+ break;\r
+\r
+ case CfUiPageUp:\r
+ //\r
+ // SkipValue means lines is skipped when show the top menu option.\r
+ //\r
+ ControlFlag = CfRepaint;\r
+ NewLine = TRUE;\r
+ Repaint = TRUE;\r
+\r
+ Link = TopOfScreen;\r
+ //\r
+ // First minus the menu of the top screen, it's value is SkipValue.\r
+ //\r
+ if (SkipValue >= BottomRow - TopRow + 1) {\r
//\r
- // There are more MenuOption needing scrolling up.\r
+ // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one\r
+ // form of options to be show, so just update the SkipValue to show the next\r
+ // parts of options.\r
//\r
- TopOfScreen = Link;\r
- MenuOption = NULL;\r
+ SkipValue -= BottomRow - TopRow + 1;\r
+ NewPos = TopOfScreen;\r
+ break;\r
+ } else {\r
+ Index = (BottomRow + 1) - SkipValue - TopRow;\r
}\r
\r
+ TopOfScreen = FindTopOfScreenMenu(TopOfScreen, Index, &SkipValue);\r
+ NewPos = TopOfScreen;\r
+ MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, FALSE);\r
+\r
+ UpdateStatusBar (INPUT_ERROR, FALSE);\r
+\r
//\r
// If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
// Don't do this when we are already in the first page.\r
//\r
AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
AdjustDateAndTimePosition (TRUE, &NewPos);\r
+\r
+ UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
break;\r
\r
case CfUiPageDown:\r
//\r
// SkipValue means lines is skipped when show the top menu option.\r
//\r
- ControlFlag = CfRepaint;\r
-\r
- ASSERT (NewPos != NULL);\r
- if (NewPos->ForwardLink == &gMenuOption) {\r
- NewLine = FALSE;\r
- Repaint = FALSE;\r
- break;\r
- }\r
+ ControlFlag = CfRepaint;\r
+ NewLine = TRUE;\r
+ Repaint = TRUE;\r
\r
- NewLine = TRUE;\r
- Repaint = TRUE;\r
Link = TopOfScreen;\r
NextMenuOption = MENU_OPTION_FROM_LINK (Link);\r
Index = TopRow + NextMenuOption->Skip - SkipValue;\r
\r
if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {\r
//\r
- // Finally we know that NewPos is the last MenuOption can be focused.\r
+ // Highlight on the last menu which can be highlight.\r
//\r
Repaint = FALSE;\r
- MoveToNextStatement (TRUE, &Link, Index - TopRow);\r
+ MoveToNextStatement (TRUE, &Link, Index - TopRow, TRUE);\r
} else {\r
//\r
// Calculate the skip line for top of screen menu.\r
} else {\r
SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));\r
}\r
-\r
TopOfScreen = Link;\r
MenuOption = NULL;\r
//\r
// Move to the Next selectable menu.\r
//\r
- MoveToNextStatement (FALSE, &Link, BottomRow - TopRow);\r
+ MoveToNextStatement (FALSE, &Link, BottomRow - TopRow, TRUE);\r
}\r
\r
//\r
//\r
NewPos = Link;\r
\r
+ UpdateStatusBar (INPUT_ERROR, FALSE);\r
+\r
//\r
// If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
// Don't do this when we are already in the last page.\r
//\r
AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
AdjustDateAndTimePosition (TRUE, &NewPos);\r
+\r
+ UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
break;\r
\r
case CfUiDown:\r
// NewPos points to the menu which is highlighted now.\r
//\r
ControlFlag = CfRepaint;\r
+ NewLine = TRUE;\r
+\r
+ if (NewPos == TopOfScreen) {\r
+ Temp2 = SkipValue;\r
+ } else {\r
+ Temp2 = 0;\r
+ }\r
\r
+ SavedListEntry = NewPos;\r
//\r
// Since the behavior of hitting the down arrow on a Date/Time op-code is intended\r
// to be one that progresses to the next set of op-codes, we need to advance to the last\r
// op-code is the last entry in the menu, we need to rewind back to the first op-code of\r
// the Date/Time op-code.\r
//\r
- SavedListEntry = NewPos;\r
AdjustDateAndTimePosition (FALSE, &NewPos);\r
\r
- if (NewPos->ForwardLink != &gMenuOption) {\r
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
- NewLine = TRUE;\r
- NewPos = NewPos->ForwardLink;\r
-\r
- Difference = 0;\r
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ NewPos = NewPos->ForwardLink;\r
+ //\r
+ // Find the next selectable menu.\r
+ //\r
+ if (MenuOption->Row + MenuOption->Skip - Temp2 > BottomRow + 1) {\r
+ if (gMenuOption.ForwardLink == NewPos || &gMenuOption == NewPos) {\r
+ Difference = -1;\r
+ } else {\r
+ Difference = 0;\r
+ }\r
+ } else {\r
+ Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow + 1 - (MenuOption->Row + MenuOption->Skip - Temp2), FALSE);\r
+ }\r
+ if (Difference < 0) {\r
//\r
- // Current menu not at the bottom of the form.\r
+ // Scroll to the first page.\r
//\r
- if (BottomRow >= MenuOption->Row + MenuOption->Skip) {\r
- //\r
- // Find the next selectable menu.\r
- //\r
- Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);\r
- //\r
- // We hit the end of MenuOption that can be focused\r
- // so we simply scroll to the first page.\r
- //\r
- if (Difference < 0) {\r
- //\r
- // Scroll to the first page.\r
- //\r
- if (TopOfScreen != gMenuOption.ForwardLink) {\r
- TopOfScreen = gMenuOption.ForwardLink;\r
- Repaint = TRUE;\r
- MenuOption = NULL;\r
- } else {\r
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
- }\r
- NewPos = gMenuOption.ForwardLink;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
-\r
- SkipValue = 0;\r
- //\r
- // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.\r
- //\r
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
- AdjustDateAndTimePosition (TRUE, &NewPos);\r
- break;\r
- }\r
- }\r
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
- if (NextMenuOption->Row == 0) {\r
- UpdateOptionSkipLines (NextMenuOption);\r
- }\r
- DistanceValue = Difference + NextMenuOption->Skip;\r
-\r
- Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;\r
- if ((MenuOption->Row + MenuOption->Skip == BottomRow + 1) &&\r
- (NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP ||\r
- NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)\r
- ) {\r
- Temp ++;\r
+ if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) {\r
+ TopOfScreen = gMenuOption.ForwardLink;\r
+ Repaint = TRUE;\r
+ MenuOption = NULL;\r
+ } else {\r
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
}\r
+ NewPos = gMenuOption.ForwardLink;\r
+ MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, TRUE);\r
\r
+ SkipValue = 0;\r
//\r
- // If we are going to scroll, update TopOfScreen\r
+ // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.\r
//\r
- if (Temp > BottomRow) {\r
- do {\r
- //\r
- // Is the current top of screen a zero-advance op-code?\r
- // If so, keep moving forward till we hit a >0 advance op-code\r
- //\r
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
-\r
- //\r
- // If bottom op-code is more than one line or top op-code is more than one line\r
- //\r
- if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {\r
- //\r
- // Is the bottom op-code greater than or equal in size to the top op-code?\r
- //\r
- if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {\r
- //\r
- // Skip the top op-code\r
- //\r
- TopOfScreen = TopOfScreen->ForwardLink;\r
- Difference = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);\r
-\r
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
-\r
- //\r
- // If we have a remainder, skip that many more op-codes until we drain the remainder\r
- //\r
- while (Difference >= (INTN) SavedMenuOption->Skip) {\r
- //\r
- // Since the Difference is greater than or equal to this op-code's skip value, skip it\r
- //\r
- Difference = Difference - (INTN) SavedMenuOption->Skip;\r
- TopOfScreen = TopOfScreen->ForwardLink;\r
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
- }\r
- //\r
- // Since we will act on this op-code in the next routine, and increment the\r
- // SkipValue, set the skips to one less than what is required.\r
- //\r
- SkipValue = Difference - 1;\r
- } else {\r
- //\r
- // Since we will act on this op-code in the next routine, and increment the\r
- // SkipValue, set the skips to one less than what is required.\r
- //\r
- SkipValue += (Temp - BottomRow) - 1;\r
- }\r
- } else {\r
- if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {\r
- TopOfScreen = TopOfScreen->ForwardLink;\r
- break;\r
- }\r
- }\r
- //\r
- // If the op-code at the top of the screen is more than one line, let's not skip it yet\r
- // Let's set a skip flag to smoothly scroll the top of the screen.\r
- //\r
- if (SavedMenuOption->Skip > 1) {\r
- if (SavedMenuOption == NextMenuOption) {\r
- SkipValue = 0;\r
- } else {\r
- SkipValue++;\r
- }\r
- } else if (SavedMenuOption->Skip == 1) {\r
- SkipValue = 0;\r
- } else {\r
- SkipValue = 0;\r
- TopOfScreen = TopOfScreen->ForwardLink;\r
- }\r
- } while (SavedMenuOption->Skip == 0);\r
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
+ AdjustDateAndTimePosition (TRUE, &NewPos);\r
\r
- Repaint = TRUE;\r
- } else if (!IsSelectable (NextMenuOption)) {\r
- //\r
- // Continue to go down until scroll to next page or the selectable option is found.\r
- //\r
- ScreenOperation = UiDown;\r
- ControlFlag = CfScreenOperation;\r
- }\r
+ UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
+ break;\r
+ }\r
\r
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+ //\r
+ // Get next selected menu info.\r
+ //\r
+ AdjustDateAndTimePosition (FALSE, &NewPos);\r
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ if (NextMenuOption->Row == 0) {\r
+ UpdateOptionSkipLines (NextMenuOption);\r
+ }\r
\r
- UpdateStatusBar (INPUT_ERROR, FALSE);\r
+ //\r
+ // Calculate new highlight menu end row.\r
+ //\r
+ Temp = (MenuOption->Row + MenuOption->Skip - Temp2) + Difference + NextMenuOption->Skip - 1;\r
+ if (Temp > BottomRow) {\r
+ //\r
+ // Get the top screen menu info.\r
+ //\r
+ AdjustDateAndTimePosition (FALSE, &TopOfScreen);\r
+ SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
\r
- } else {\r
//\r
- // Scroll to the first page.\r
+ // Current Top screen menu occupy (SavedMenuOption->Skip - SkipValue) rows.\r
+ // Full shows the new selected menu need to skip (Temp - BottomRow - 1) rows.\r
//\r
- if (TopOfScreen != gMenuOption.ForwardLink) {\r
- TopOfScreen = gMenuOption.ForwardLink;\r
- Repaint = TRUE;\r
- MenuOption = NULL;\r
+ if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {\r
+ //\r
+ // Skip the top op-code\r
+ //\r
+ TopOfScreen = TopOfScreen->ForwardLink;\r
+ DistanceValue = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);\r
+\r
+ SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
+\r
+ //\r
+ // If we have a remainder, skip that many more op-codes until we drain the remainder\r
+ // Special case is the selected highlight menu has more than one form of menus.\r
+ //\r
+ while (DistanceValue >= SavedMenuOption->Skip && TopOfScreen != NewPos) {\r
+ //\r
+ // Since the Difference is greater than or equal to this op-code's skip value, skip it\r
+ //\r
+ DistanceValue = DistanceValue - (INTN) SavedMenuOption->Skip;\r
+ TopOfScreen = TopOfScreen->ForwardLink;\r
+ SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
+ }\r
+ //\r
+ // Since we will act on this op-code in the next routine, and increment the\r
+ // SkipValue, set the skips to one less than what is required.\r
+ //\r
+ if (TopOfScreen != NewPos) {\r
+ SkipValue = DistanceValue;\r
+ } else {\r
+ SkipValue = 0;\r
+ }\r
} else {\r
//\r
- // Need to remove the current highlight menu.\r
- // MenuOption saved the last highlight menu info.\r
+ // Since we will act on this op-code in the next routine, and increment the\r
+ // SkipValue, set the skips to one less than what is required.\r
//\r
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+ SkipValue += Temp - BottomRow;\r
}\r
-\r
- SkipValue = 0;\r
- NewLine = TRUE;\r
+ Repaint = TRUE;\r
+ } else if (!IsSelectable (NextMenuOption)) {\r
//\r
- // Get the next highlight menu.\r
+ // Continue to go down until scroll to next page or the selectable option is found.\r
//\r
- NewPos = gMenuOption.ForwardLink;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ ScreenOperation = UiDown;\r
+ ControlFlag = CfScreenOperation;\r
+ break;\r
+ }\r
+\r
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+\r
+ //\r
+ // Check whether new highlight menu is selectable, if not, keep highlight on the old one.\r
+ //\r
+ // BottomRow - TopRow + 1 means the total rows current forms supported.\r
+ // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu\r
+ // and new top menu. New top menu will all shows in next form, but last highlight menu\r
+ // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the\r
+ // last highlight menu.\r
+ //\r
+ if (!IsSelectable (NextMenuOption) && IsSelectable (MenuOption) &&\r
+ (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1)) {\r
+ NewPos = SavedListEntry;\r
}\r
\r
+ UpdateStatusBar (INPUT_ERROR, FALSE);\r
+\r
//\r
// If we are at the end of the list and sitting on a Date/Time op, rewind to the head.\r
//\r
AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
AdjustDateAndTimePosition (TRUE, &NewPos);\r
+\r
+ UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
break;\r
\r
case CfUiNoOperation:\r
}\r
}\r
\r
+/**\r
+ Free the UI Menu Option structure data.\r
+\r
+ @param MenuOptionList Point to the menu option list which need to be free.\r
+\r
+**/\r
+VOID\r
+FreeMenuOptionData(\r
+ LIST_ENTRY *MenuOptionList\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ UI_MENU_OPTION *Option;\r
+\r
+ //\r
+ // Free menu option list\r
+ //\r
+ while (!IsListEmpty (MenuOptionList)) {\r
+ Link = GetFirstNode (MenuOptionList);\r
+ Option = MENU_OPTION_FROM_LINK (Link);\r
+ if (Option->Description != NULL){\r
+ FreePool(Option->Description);\r
+ }\r
+ RemoveEntryList (&Option->Link);\r
+ FreePool (Option);\r
+ }\r
+}\r
+\r
/**\r
\r
Base on the browser status info to show an pop up message.\r
VOID\r
)\r
{\r
- CHAR16 *ErrorInfo;\r
- EFI_INPUT_KEY Key;\r
+ CHAR16 *ErrorInfo;\r
+ EFI_INPUT_KEY Key;\r
+ EFI_EVENT WaitList[2];\r
+ EFI_EVENT RefreshIntervalEvent;\r
+ EFI_EVENT TimeOutEvent;\r
+ UINT8 TimeOut;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ WARNING_IF_CONTEXT EventContext;\r
+ EFI_IFR_OP_HEADER *OpCodeBuf;\r
+ EFI_STRING_ID StringToken;\r
+ CHAR16 DiscardChange;\r
+ CHAR16 JumpToFormSet;\r
+ CHAR16 *PrintString;\r
\r
if (gFormData->BrowserStatus == BROWSER_SUCCESS) {\r
return;\r
}\r
\r
- if (gFormData->ErrorString != NULL) {\r
+ StringToken = 0;\r
+ TimeOutEvent = NULL;\r
+ RefreshIntervalEvent = NULL;\r
+ OpCodeBuf = NULL;\r
+ if (gFormData->HighLightedStatement != NULL) {\r
+ OpCodeBuf = gFormData->HighLightedStatement->OpCode;\r
+ }\r
+\r
+ if (gFormData->BrowserStatus == (BROWSER_WARNING_IF)) {\r
+ ASSERT (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_WARNING_IF_OP);\r
+\r
+ TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeBuf)->TimeOut;\r
+ StringToken = ((EFI_IFR_WARNING_IF *) OpCodeBuf)->Warning;\r
+ } else {\r
+ TimeOut = 0;\r
+ if ((gFormData->BrowserStatus == (BROWSER_NO_SUBMIT_IF)) &&\r
+ (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_NO_SUBMIT_IF_OP)) {\r
+ StringToken = ((EFI_IFR_NO_SUBMIT_IF *) OpCodeBuf)->Error;\r
+ } else if ((gFormData->BrowserStatus == (BROWSER_INCONSISTENT_IF)) &&\r
+ (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_INCONSISTENT_IF_OP)) {\r
+ StringToken = ((EFI_IFR_INCONSISTENT_IF *) OpCodeBuf)->Error;\r
+ }\r
+ }\r
+\r
+ if (StringToken != 0) {\r
+ ErrorInfo = GetToken (StringToken, gFormData->HiiHandle);\r
+ } else if (gFormData->ErrorString != NULL) {\r
+ //\r
+ // Only used to compatible with old setup browser.\r
+ // Not use this field in new browser core.\r
+ //\r
ErrorInfo = gFormData->ErrorString;\r
} else {\r
switch (gFormData->BrowserStatus) {\r
ErrorInfo = gSaveFailed;\r
break;\r
\r
- case BROWSER_NO_SUBMIT_IF:\r
- ErrorInfo = gNoSubmitIf;\r
- break;\r
-\r
case BROWSER_FORM_NOT_FOUND:\r
ErrorInfo = gFormNotFound;\r
break;\r
ErrorInfo = gProtocolNotFound;\r
break;\r
\r
+ case BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF:\r
+ ErrorInfo = gNoSubmitIfFailed;\r
+ break;\r
+\r
+ case BROWSER_RECONNECT_FAIL:\r
+ ErrorInfo = gReconnectFail;\r
+ break;\r
+\r
+ case BROWSER_RECONNECT_SAVE_CHANGES:\r
+ ErrorInfo = gReconnectConfirmChanges;\r
+ break;\r
+\r
+ case BROWSER_RECONNECT_REQUIRED:\r
+ ErrorInfo = gReconnectRequired;\r
+ break;\r
+\r
default:\r
- ErrorInfo = gBrwoserError;\r
+ ErrorInfo = gBrowserError;\r
break;\r
}\r
}\r
\r
- //\r
- // Error occur, prompt error message.\r
- //\r
- do {\r
- CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);\r
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+ switch (gFormData->BrowserStatus) {\r
+ case BROWSER_SUBMIT_FAIL:\r
+ case BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF:\r
+ case BROWSER_RECONNECT_SAVE_CHANGES:\r
+ ASSERT (gUserInput != NULL);\r
+ if (gFormData->BrowserStatus == (BROWSER_SUBMIT_FAIL)) {\r
+ PrintString = gSaveProcess;\r
+ JumpToFormSet = gJumpToFormSet[0];\r
+ DiscardChange = gDiscardChange[0];\r
+ } else if (gFormData->BrowserStatus == (BROWSER_RECONNECT_SAVE_CHANGES)){\r
+ PrintString = gChangesOpt;\r
+ JumpToFormSet = gConfirmOptYes[0];\r
+ DiscardChange = gConfirmOptNo[0];\r
+ } else {\r
+ PrintString = gSaveNoSubmitProcess;\r
+ JumpToFormSet = gCheckError[0];\r
+ DiscardChange = gDiscardChange[0];\r
+ }\r
+\r
+ do {\r
+ CreateDialog (&Key, gEmptyString, ErrorInfo, PrintString, gEmptyString, NULL);\r
+ } while (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (DiscardChange | UPPER_LOWER_CASE_OFFSET)) &&\r
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (JumpToFormSet | UPPER_LOWER_CASE_OFFSET)));\r
+\r
+ if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (DiscardChange | UPPER_LOWER_CASE_OFFSET)) {\r
+ gUserInput->Action = BROWSER_ACTION_DISCARD;\r
+ } else {\r
+ gUserInput->Action = BROWSER_ACTION_GOTO;\r
+ }\r
+ break;\r
+\r
+ default:\r
+ if (TimeOut == 0) {\r
+ do {\r
+ CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);\r
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+ } else {\r
+ Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK, EmptyEventProcess, NULL, &TimeOutEvent);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ EventContext.SyncEvent = TimeOutEvent;\r
+ EventContext.TimeOut = &TimeOut;\r
+ EventContext.ErrorInfo = ErrorInfo;\r
+\r
+ Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshTimeOutProcess, &EventContext, &RefreshIntervalEvent);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Show the dialog first to avoid long time not reaction.\r
+ //\r
+ gBS->SignalEvent (RefreshIntervalEvent);\r
+\r
+ Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, ONE_SECOND);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ while (TRUE) {\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ if (!EFI_ERROR (Status) && Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
+ break;\r
+ }\r
+\r
+ if (Status != EFI_NOT_READY) {\r
+ continue;\r
+ }\r
+\r
+ WaitList[0] = TimeOutEvent;\r
+ WaitList[1] = gST->ConIn->WaitForKey;\r
+\r
+ Status = gBS->WaitForEvent (2, WaitList, &Index);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (Index == 0) {\r
+ //\r
+ // Timeout occur, close the hoot time out event.\r
+ //\r
+ break;\r
+ }\r
+ }\r
+\r
+ gBS->CloseEvent (TimeOutEvent);\r
+ gBS->CloseEvent (RefreshIntervalEvent);\r
+ }\r
+ break;\r
+ }\r
+\r
+ if (StringToken != 0) {\r
+ FreePool (ErrorInfo);\r
+ }\r
}\r
\r
/**\r
Display one form, and return user input.\r
- \r
+\r
@param FormData Form Data to be shown.\r
@param UserInputData User input data.\r
- \r
+\r
@retval EFI_SUCCESS 1.Form Data is shown, and user input is got.\r
2.Error info has show and return.\r
@retval EFI_INVALID_PARAMETER The input screen dimension is not valid\r
@retval EFI_NOT_FOUND New form data has some error.\r
**/\r
EFI_STATUS\r
-EFIAPI \r
+EFIAPI\r
FormDisplay (\r
IN FORM_DISPLAY_ENGINE_FORM *FormData,\r
OUT USER_INPUT *UserInputData\r
// Process the status info first.\r
//\r
BrowserStatusProcess();\r
- if (UserInputData == NULL) {\r
+ if (gFormData->BrowserStatus != BROWSER_SUCCESS) {\r
//\r
- // UserInputData == NULL, means only need to print the error info, return here.\r
+ // gFormData->BrowserStatus != BROWSER_SUCCESS, means only need to print the error info, return here.\r
//\r
return EFI_SUCCESS;\r
}\r
\r
- ConvertStatementToMenu();\r
-\r
Status = DisplayPageFrame (FormData, &gStatementDimensions);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
+ //\r
+ // Global Widths should be initialized before any MenuOption creation\r
+ // or the GetWidth() used in UiAddMenuOption() will return incorrect value.\r
+ //\r
+ //\r
+ // Left right\r
+ // |<-.->|<-.........->|<- .........->|<-...........->|\r
+ // Skip Prompt Option Help\r
+ //\r
+ gOptionBlockWidth = (CHAR16) ((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3) + 1;\r
+ gHelpBlockWidth = (CHAR16) (gOptionBlockWidth - 1 - LEFT_SKIPPED_COLUMNS);\r
+ gPromptBlockWidth = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * (gOptionBlockWidth - 1) - 1);\r
+\r
+ ConvertStatementToMenu();\r
+\r
//\r
// Check whether layout is changed.\r
//\r
- if (mIsFirstForm \r
+ if (mIsFirstForm\r
|| (gOldFormEntry.HiiHandle != FormData->HiiHandle)\r
|| (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))\r
|| (gOldFormEntry.FormId != FormData->FormId)) {\r
}\r
\r
Status = UiDisplayMenu(FormData);\r
- \r
+\r
//\r
// Backup last form info.\r
//\r
CopyGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid);\r
gOldFormEntry.FormId = FormData->FormId;\r
\r
+ //\r
+ //Free the Ui menu option list.\r
+ //\r
+ FreeMenuOptionData(&gMenuOption);\r
+\r
return Status;\r
}\r
\r
Clear Screen to the initial state.\r
**/\r
VOID\r
-EFIAPI \r
+EFIAPI\r
DriverClearDisplayPage (\r
VOID\r
)\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ //\r
+ // Install HII Popup Protocol.\r
+ //\r
+ Status = gBS->InstallProtocolInterface (\r
+ &mPrivateData.Handle,\r
+ &gEfiHiiPopupProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ &mPrivateData.HiiPopup\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
InitializeDisplayStrings();\r
- \r
+\r
ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo));\r
ZeroMem (&gOldFormEntry, sizeof (gOldFormEntry));\r
\r
//\r
// Use BrowserEx2 protocol to register HotKey.\r
- // \r
+ //\r
Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2);\r
if (!EFI_ERROR (Status)) {\r
//\r
NewString = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_TEN_STRING), NULL);\r
ASSERT (NewString != NULL);\r
FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);\r
+ FreePool (NewString);\r
\r
HotKey.ScanCode = SCAN_F9;\r
NewString = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_NINE_STRING), NULL);\r
ASSERT (NewString != NULL);\r
FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);\r
+ FreePool (NewString);\r
}\r
\r
return EFI_SUCCESS;\r
\r
FreeDisplayStrings ();\r
\r
+ if (gHighligthMenuInfo.HLTOpCode != NULL) {\r
+ FreePool (gHighligthMenuInfo.HLTOpCode);\r
+ }\r
+\r
+ if (gHighligthMenuInfo.TOSOpCode != NULL) {\r
+ FreePool (gHighligthMenuInfo.TOSOpCode);\r
+ }\r
+\r
return EFI_SUCCESS;\r
}\r