Option = QUESTION_OPTION_FROM_LINK (Link);\r
\r
if ((CompareHiiValue (&Option->Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {\r
- return Option;\r
+ //\r
+ // Check the suppressif condition, only a valid option can be return.\r
+ //\r
+ if ((Option->SuppressExpression == NULL) ||\r
+ ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse))) {\r
+ return Option;\r
+ }\r
}\r
\r
Link = GetNextNode (&Question->OptionListHead, Link);\r
}\r
}\r
\r
+/**\r
+ Check whether this value already in the array, if yes, return the index.\r
+\r
+ @param Array The data array.\r
+ @param Type Type of the data in this array.\r
+ @param Value The value to be find.\r
+ @param Index The index in the array which has same value with Value.\r
+ \r
+ @retval TRUE Found the value in the array.\r
+ @retval FALSE Not found the value.\r
+\r
+**/\r
+BOOLEAN \r
+FindArrayData (\r
+ IN VOID *Array,\r
+ IN UINT8 Type,\r
+ IN UINT64 Value,\r
+ OUT UINTN *Index OPTIONAL\r
+ )\r
+{\r
+ UINTN Count;\r
+ UINT64 TmpValue;\r
+ \r
+ ASSERT (Array != NULL);\r
+\r
+ Count = 0;\r
+ TmpValue = 0;\r
+\r
+ while ((TmpValue = GetArrayData (Array, Type, Count)) != 0) {\r
+ if (Value == TmpValue) {\r
+ if (Index != NULL) {\r
+ *Index = Count;\r
+ }\r
+ return TRUE;\r
+ }\r
+\r
+ Count ++;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
\r
/**\r
Print Question Value according to it's storage width and display attributes.\r
LIST_ENTRY *Link;\r
EFI_HII_VALUE HiiValue;\r
EFI_HII_VALUE *QuestionValue;\r
- BOOLEAN Suppress;\r
UINT16 Maximum;\r
QUESTION_OPTION *Option;\r
UINTN Index2;\r
Index2 = 0;\r
while (!IsNull (&Question->OptionListHead, Link) && Index2 < Question->MaxContainers) {\r
Option = QUESTION_OPTION_FROM_LINK (Link);\r
+ Link = GetNextNode (&Question->OptionListHead, Link);\r
+ if ((Option->SuppressExpression != NULL) &&\r
+ ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {\r
+ continue;\r
+ }\r
SetArrayData (ValueArray, ValueType, Index2, Option->Value.Value.u64);\r
Index2++;\r
- Link = GetNextNode (&Question->OptionListHead, Link);\r
}\r
SetArrayData (ValueArray, ValueType, Index2, 0);\r
\r
- Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
+ Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);\r
UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
\r
FreePool (*OptionString);\r
return EFI_NOT_FOUND;\r
}\r
\r
- Suppress = FALSE;\r
+ Character[0] = LEFT_ONEOF_DELIMITER;\r
+ NewStrCat (OptionString[0], Character);\r
+ StringPtr = GetToken (OneOfOption->Text, Selection->Handle);\r
+ ASSERT (StringPtr != NULL);\r
+ NewStrCat (OptionString[0], StringPtr);\r
+ Character[0] = RIGHT_ONEOF_DELIMITER;\r
+ NewStrCat (OptionString[0], Character);\r
+ Character[0] = CHAR_CARRIAGE_RETURN;\r
+ NewStrCat (OptionString[0], Character);\r
+ FreePool (StringPtr);\r
+ }\r
+\r
+ //\r
+ // Search the other options, try to find the one not in the container.\r
+ //\r
+ Link = GetFirstNode (&Question->OptionListHead);\r
+ while (!IsNull (&Question->OptionListHead, Link)) {\r
+ OneOfOption = QUESTION_OPTION_FROM_LINK (Link);\r
+ Link = GetNextNode (&Question->OptionListHead, Link);\r
if ((OneOfOption->SuppressExpression != NULL) &&\r
- (EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress)) {\r
- //\r
- // This option is suppressed\r
- //\r
- Suppress = TRUE;\r
+ ((EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {\r
+ continue;\r
}\r
\r
- if (!Suppress) {\r
- Character[0] = LEFT_ONEOF_DELIMITER;\r
- NewStrCat (OptionString[0], Character);\r
- StringPtr = GetToken (OneOfOption->Text, Selection->Handle);\r
- ASSERT (StringPtr != NULL);\r
- NewStrCat (OptionString[0], StringPtr);\r
- Character[0] = RIGHT_ONEOF_DELIMITER;\r
- NewStrCat (OptionString[0], Character);\r
- Character[0] = CHAR_CARRIAGE_RETURN;\r
- NewStrCat (OptionString[0], Character);\r
-\r
- FreePool (StringPtr);\r
+ if (FindArrayData (ValueArray, ValueType, OneOfOption->Value.Value.u64, NULL)) {\r
+ continue;\r
}\r
+\r
+ SetArrayData (ValueArray, ValueType, Index++, OneOfOption->Value.Value.u64);\r
+\r
+ Character[0] = LEFT_ONEOF_DELIMITER;\r
+ NewStrCat (OptionString[0], Character);\r
+ StringPtr = GetToken (OneOfOption->Text, Selection->Handle);\r
+ ASSERT (StringPtr != NULL);\r
+ NewStrCat (OptionString[0], StringPtr);\r
+ Character[0] = RIGHT_ONEOF_DELIMITER;\r
+ NewStrCat (OptionString[0], Character);\r
+ Character[0] = CHAR_CARRIAGE_RETURN;\r
+ NewStrCat (OptionString[0], Character);\r
+ FreePool (StringPtr);\r
}\r
}\r
break;\r
if ((Option->SuppressExpression == NULL) ||\r
(EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)) {\r
CopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
- SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
+ SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);\r
UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
break;\r
}\r
return EFI_NOT_FOUND;\r
}\r
\r
- if ((OneOfOption->SuppressExpression != NULL) &&\r
- ((EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {\r
- //\r
- // This option is suppressed\r
- //\r
- Suppress = TRUE;\r
- } else {\r
- Suppress = FALSE;\r
- }\r
-\r
- if (Suppress) {\r
- //\r
- // Current selected option happen to be suppressed,\r
- // enforce to select on a non-suppressed option\r
- //\r
- Link = GetFirstNode (&Question->OptionListHead);\r
- while (!IsNull (&Question->OptionListHead, Link)) {\r
- OneOfOption = QUESTION_OPTION_FROM_LINK (Link);\r
-\r
- if ((OneOfOption->SuppressExpression == NULL) ||\r
- (EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)) {\r
- Suppress = FALSE;\r
- CopyMem (QuestionValue, &OneOfOption->Value, sizeof (EFI_HII_VALUE));\r
- SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
- UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);\r
- break;\r
- }\r
-\r
- Link = GetNextNode (&Question->OptionListHead, Link);\r
- }\r
- }\r
-\r
- if (!Suppress) {\r
- Character[0] = LEFT_ONEOF_DELIMITER;\r
- NewStrCat (OptionString[0], Character);\r
- StringPtr = GetToken (OneOfOption->Text, Selection->Handle);\r
- ASSERT (StringPtr != NULL);\r
- NewStrCat (OptionString[0], StringPtr);\r
- Character[0] = RIGHT_ONEOF_DELIMITER;\r
- NewStrCat (OptionString[0], Character);\r
+ Character[0] = LEFT_ONEOF_DELIMITER;\r
+ NewStrCat (OptionString[0], Character);\r
+ StringPtr = GetToken (OneOfOption->Text, Selection->Handle);\r
+ ASSERT (StringPtr != NULL);\r
+ NewStrCat (OptionString[0], StringPtr);\r
+ Character[0] = RIGHT_ONEOF_DELIMITER;\r
+ NewStrCat (OptionString[0], Character);\r
\r
- FreePool (StringPtr);\r
- }\r
+ FreePool (StringPtr);\r
}\r
break;\r
\r
//\r
// Save Question value\r
//\r
- Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
+ Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);\r
UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
}\r
\r
HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);\r
} else {\r
CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));\r
- SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
+ SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);\r
\r
UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
}\r
PasswordCallback (Selection, MenuOption, StringPtr);\r
} else {\r
CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));\r
- SetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE);\r
+ SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithHiiDriver);\r
}\r
}\r
} else {\r
\r
@param StringPtr The entire help string.\r
@param FormattedString The oupput formatted string.\r
+ @param EachLineWidth The max string length of each line in the formatted string.\r
@param RowCount TRUE: if Question is selected.\r
\r
**/\r
ProcessHelpString (\r
IN CHAR16 *StringPtr,\r
OUT CHAR16 **FormattedString,\r
+ OUT UINT16 *EachLineWidth,\r
IN UINTN RowCount\r
)\r
{\r
- UINTN BlockWidth;\r
- UINTN AllocateSize;\r
- //\r
- // [PrevCurrIndex, CurrIndex) forms a range of a screen-line\r
- //\r
- UINTN CurrIndex;\r
- UINTN PrevCurrIndex;\r
- UINTN LineCount;\r
- UINTN VirtualLineCount;\r
- //\r
- // GlyphOffset stores glyph width of current screen-line\r
- //\r
- UINTN GlyphOffset;\r
- //\r
- // GlyphWidth equals to 2 if we meet width directive\r
- //\r
- UINTN GlyphWidth;\r
- //\r
- // during scanning, we remember the position of last space character\r
- // in case that if next word cannot put in current line, we could restore back to the position\r
- // of last space character\r
- // while we should also remmeber the glyph width of the last space character for restoring\r
- //\r
- UINTN LastSpaceIndex;\r
- UINTN LastSpaceGlyphWidth;\r
+ UINTN Index;\r
+ CHAR16 *OutputString;\r
+ UINTN TotalRowNum;\r
+ UINTN CheckedNum;\r
+ UINT16 GlyphWidth;\r
+ UINT16 LineWidth;\r
+ UINT16 MaxStringLen;\r
+ UINT16 StringLen;\r
+\r
+ TotalRowNum = 0;\r
+ CheckedNum = 0;\r
+ GlyphWidth = 1;\r
+ Index = 0;\r
+ MaxStringLen = 0;\r
+ StringLen = 0;\r
+\r
//\r
- // every time we begin to form a new screen-line, we should remember glyph width of single character\r
- // of last line\r
+ // Set default help string width.\r
//\r
- UINTN LineStartGlyphWidth;\r
- UINTN *IndexArray;\r
- UINTN *OldIndexArray;\r
-\r
- BlockWidth = (UINTN) gHelpBlockWidth - 1;\r
+ LineWidth = (UINT16) (gHelpBlockWidth - 1);\r
\r
//\r
- // every three elements of IndexArray form a screen-line of string:[ IndexArray[i*3], IndexArray[i*3+1] )\r
- // IndexArray[i*3+2] stores the initial glyph width of single character. to save this is because we want\r
- // to bring the width directive of the last line to current screen-line.\r
- // e.g.: "\wideabcde ... fghi", if "fghi" also has width directive but is splitted to the next screen-line\r
- // different from that of "\wideabcde", we should remember the width directive.\r
+ // Get row number of the String.\r
//\r
- AllocateSize = 0x20;\r
- IndexArray = AllocatePool (AllocateSize * sizeof (UINTN) * 3);\r
- ASSERT (IndexArray != NULL);\r
-\r
- if (*FormattedString != NULL) {\r
- FreePool (*FormattedString);\r
- *FormattedString = NULL;\r
- }\r
-\r
- for (PrevCurrIndex = 0, CurrIndex = 0, LineCount = 0, LastSpaceIndex = 0,\r
- IndexArray[0] = 0, GlyphWidth = 1, GlyphOffset = 0, LastSpaceGlyphWidth = 1, LineStartGlyphWidth = 1;\r
- (StringPtr[CurrIndex] != CHAR_NULL);\r
- CurrIndex ++) {\r
-\r
- if (LineCount == AllocateSize) {\r
- AllocateSize += 0x10;\r
- OldIndexArray = IndexArray;\r
- IndexArray = AllocatePool (AllocateSize * sizeof (UINTN) * 3);\r
- ASSERT (IndexArray != NULL);\r
-\r
- CopyMem (IndexArray, OldIndexArray, LineCount * sizeof (UINTN) * 3);\r
- FreePool (OldIndexArray);\r
+ while ((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {\r
+ if (StringLen > MaxStringLen) {\r
+ MaxStringLen = StringLen;\r
}\r
- switch (StringPtr[CurrIndex]) {\r
-\r
- case NARROW_CHAR:\r
- case WIDE_CHAR:\r
- GlyphWidth = ((StringPtr[CurrIndex] == WIDE_CHAR) ? 2 : 1);\r
- if (CurrIndex == 0) {\r
- LineStartGlyphWidth = GlyphWidth;\r
- }\r
- break;\r
-\r
- //\r
- // char is '\n'\r
- // "\r\n" isn't handled here, handled by case CHAR_CARRIAGE_RETURN\r
- //\r
- case CHAR_LINEFEED:\r
- //\r
- // Store a range of string as a line\r
- //\r
- IndexArray[LineCount*3] = PrevCurrIndex;\r
- IndexArray[LineCount*3+1] = CurrIndex;\r
- IndexArray[LineCount*3+2] = LineStartGlyphWidth;\r
- LineCount ++;\r
- //\r
- // Reset offset and save begin position of line\r
- //\r
- GlyphOffset = 0;\r
- LineStartGlyphWidth = GlyphWidth;\r
- PrevCurrIndex = CurrIndex + 1;\r
- break;\r
\r
- //\r
- // char is '\r'\r
- // "\r\n" and "\r" both are handled here\r
- //\r
- case CHAR_CARRIAGE_RETURN:\r
- if (StringPtr[CurrIndex + 1] == CHAR_LINEFEED) {\r
- //\r
- // next char is '\n'\r
- //\r
- IndexArray[LineCount*3] = PrevCurrIndex;\r
- IndexArray[LineCount*3+1] = CurrIndex;\r
- IndexArray[LineCount*3+2] = LineStartGlyphWidth;\r
- LineCount ++;\r
- CurrIndex ++;\r
- }\r
- GlyphOffset = 0;\r
- LineStartGlyphWidth = GlyphWidth;\r
- PrevCurrIndex = CurrIndex + 1;\r
- break;\r
-\r
- //\r
- // char is space or other char\r
- //\r
- default:\r
- GlyphOffset += GlyphWidth;\r
- if (GlyphOffset >= BlockWidth) {\r
- if (LastSpaceIndex > PrevCurrIndex) {\r
- //\r
- // LastSpaceIndex points to space inside current screen-line,\r
- // restore to LastSpaceIndex\r
- // (Otherwise the word is too long to fit one screen-line, just cut it)\r
- //\r
- CurrIndex = LastSpaceIndex;\r
- GlyphWidth = LastSpaceGlyphWidth;\r
- } else if (GlyphOffset > BlockWidth) {\r
- //\r
- // the word is too long to fit one screen-line and we don't get the chance\r
- // of GlyphOffset == BlockWidth because GlyphWidth = 2\r
- //\r
- CurrIndex --;\r
- }\r
-\r
- IndexArray[LineCount*3] = PrevCurrIndex;\r
- IndexArray[LineCount*3+1] = CurrIndex + 1;\r
- IndexArray[LineCount*3+2] = LineStartGlyphWidth;\r
- LineStartGlyphWidth = GlyphWidth;\r
- LineCount ++;\r
- //\r
- // Reset offset and save begin position of line\r
- //\r
- GlyphOffset = 0;\r
- PrevCurrIndex = CurrIndex + 1;\r
- }\r
-\r
- //\r
- // LastSpaceIndex: remember position of last space\r
- //\r
- if (StringPtr[CurrIndex] == CHAR_SPACE) {\r
- LastSpaceIndex = CurrIndex;\r
- LastSpaceGlyphWidth = GlyphWidth;\r
- }\r
- break;\r
- }\r
- }\r
-\r
- if (GlyphOffset > 0) {\r
- IndexArray[LineCount*3] = PrevCurrIndex;\r
- IndexArray[LineCount*3+1] = CurrIndex;\r
- IndexArray[LineCount*3+2] = GlyphWidth;\r
- LineCount ++;\r
+ TotalRowNum ++;\r
+ FreePool (OutputString);\r
}\r
+ *EachLineWidth = MaxStringLen;\r
\r
- if (LineCount == 0) {\r
- //\r
- // in case we meet null string\r
- //\r
- IndexArray[0] = 0;\r
- IndexArray[1] = 1;\r
- //\r
- // we assume null string's glyph width is 1\r
- //\r
- IndexArray[1] = 1;\r
- LineCount ++;\r
- }\r
-\r
- VirtualLineCount = RowCount * (LineCount / RowCount + (LineCount % RowCount > 0));\r
- *FormattedString = AllocateZeroPool (VirtualLineCount * (BlockWidth + 1) * sizeof (CHAR16) * 2);\r
+ *FormattedString = AllocateZeroPool (TotalRowNum * MaxStringLen * sizeof (CHAR16));\r
ASSERT (*FormattedString != NULL);\r
\r
- for (CurrIndex = 0; CurrIndex < LineCount; CurrIndex ++) {\r
- *(*FormattedString + CurrIndex * 2 * (BlockWidth + 1)) = (CHAR16) ((IndexArray[CurrIndex*3+2] == 2) ? WIDE_CHAR : NARROW_CHAR);\r
- StrnCpy (\r
- *FormattedString + CurrIndex * 2 * (BlockWidth + 1) + 1,\r
- StringPtr + IndexArray[CurrIndex*3],\r
- IndexArray[CurrIndex*3+1]-IndexArray[CurrIndex*3]\r
- );\r
+ //\r
+ // Generate formatted help string array.\r
+ //\r
+ GlyphWidth = 1;\r
+ Index = 0;\r
+ while((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {\r
+ CopyMem (*FormattedString + CheckedNum * MaxStringLen, OutputString, StringLen * sizeof (CHAR16));\r
+ CheckedNum ++;\r
+ FreePool (OutputString);\r
}\r
\r
- FreePool (IndexArray);\r
-\r
- return LineCount;\r
+ return TotalRowNum; \r
}\r