]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c
Base on the type field to get the width of value field for option opcode.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / ProcessOptions.c
index c91ba48d2172da8c5304b3214146167b9bcf4940..fecb98e8bf9a275b2716f8298803b22c012062b4 100644 (file)
@@ -91,7 +91,13 @@ ValueToOption (
     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
@@ -190,6 +196,47 @@ SetArrayData (
   }\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
@@ -396,7 +443,6 @@ ProcessOptions (
   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
@@ -476,13 +522,17 @@ ProcessOptions (
           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
@@ -490,28 +540,46 @@ ProcessOptions (
           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
@@ -551,7 +619,7 @@ ProcessOptions (
           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
@@ -564,50 +632,15 @@ ProcessOptions (
         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
@@ -640,7 +673,7 @@ ProcessOptions (
       //\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
@@ -753,7 +786,7 @@ ProcessOptions (
           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
@@ -940,7 +973,7 @@ ProcessOptions (
             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
@@ -978,6 +1011,7 @@ ProcessOptions (
 \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
@@ -985,203 +1019,57 @@ UINTN
 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