2 Implements editor interface functions.
4 Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved. <BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "TextEditor.h"
16 #include "EditStatusBar.h"
17 #include "EditInputBar.h"
18 #include "EditMenuBar.h"
21 // the first time editor launch
26 // it's time editor should exit
30 BOOLEAN EditorMouseAction
;
32 extern EFI_EDITOR_FILE_BUFFER FileBuffer
;
34 extern BOOLEAN FileBufferNeedRefresh
;
36 extern BOOLEAN FileBufferOnlyLineNeedRefresh
;
38 extern BOOLEAN FileBufferMouseNeedRefresh
;
40 extern EFI_EDITOR_FILE_BUFFER FileBufferBackupVar
;
42 EFI_EDITOR_GLOBAL_EDITOR MainEditor
;
43 EFI_EDITOR_GLOBAL_EDITOR MainEditorBackupVar
;
47 Load a file from disk to editor
49 @retval EFI_SUCCESS The operation was successful.
50 @retval EFI_LOAD_ERROR A load error occured.
51 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
59 Switch a file from ASCII to UNICODE or vise-versa.
61 @retval EFI_SUCCESS The switch was ok or a warning was presented.
64 MainCommandSwitchFileType (
69 move cursor to specified lines
71 @retval EFI_SUCCESS The operation was successful.
79 Save current file to disk, you can save to current file name or
80 save to another file name.
82 @retval EFI_SUCCESS The file was saved correctly.
83 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
84 @retval EFI_LOAD_ERROR A file access error occured.
92 Show help information for the editor.
94 @retval EFI_SUCCESS The operation was successful.
97 MainCommandDisplayHelp (
104 @retval EFI_SUCCESS The operation was successful.
105 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
106 @retval EFI_LOAD_ERROR A load error occured.
114 search string in file buffer
116 @retval EFI_SUCCESS The operation was successful.
117 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
118 @retval EFI_LOAD_ERROR A load error occured.
126 search string in file buffer, and replace it with another str
128 @retval EFI_SUCCESS The operation was successful.
129 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
130 @retval EFI_LOAD_ERROR A load error occured.
133 MainCommandSearchReplace (
138 cut current line to clipboard
140 @retval EFI_SUCCESS The operation was successful.
141 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
142 @retval EFI_LOAD_ERROR A load error occured.
150 paste line to file buffer.
152 @retval EFI_SUCCESS The operation was successful.
153 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
154 @retval EFI_LOAD_ERROR A load error occured.
157 MainCommandPasteLine (
162 Help info that will be displayed.
164 EFI_STRING_ID MainMenuHelpInfo
[] = {
165 STRING_TOKEN(STR_EDIT_HELP_TITLE
),
166 STRING_TOKEN(STR_EDIT_HELP_BLANK
),
167 STRING_TOKEN(STR_EDIT_HELP_LIST_TITLE
),
168 STRING_TOKEN(STR_EDIT_HELP_DIV
),
169 STRING_TOKEN(STR_EDIT_HELP_GO_TO_LINE
),
170 STRING_TOKEN(STR_EDIT_HELP_SAVE_FILE
),
171 STRING_TOKEN(STR_EDIT_HELP_EXIT
),
172 STRING_TOKEN(STR_EDIT_HELP_SEARCH
),
173 STRING_TOKEN(STR_EDIT_HELP_SEARCH_REPLACE
),
174 STRING_TOKEN(STR_EDIT_HELP_CUT_LINE
),
175 STRING_TOKEN(STR_EDIT_HELP_PASTE_LINE
),
176 STRING_TOKEN(STR_EDIT_HELP_OPEN_FILE
),
177 STRING_TOKEN(STR_EDIT_HELP_FILE_TYPE
),
178 STRING_TOKEN(STR_EDIT_HELP_BLANK
),
179 STRING_TOKEN(STR_EDIT_HELP_EXIT_HELP
),
180 STRING_TOKEN(STR_EDIT_HELP_BLANK
),
181 STRING_TOKEN(STR_EDIT_HELP_BLANK
),
182 STRING_TOKEN(STR_EDIT_HELP_BLANK
),
183 STRING_TOKEN(STR_EDIT_HELP_BLANK
),
184 STRING_TOKEN(STR_EDIT_HELP_BLANK
),
185 STRING_TOKEN(STR_EDIT_HELP_BLANK
),
186 STRING_TOKEN(STR_EDIT_HELP_BLANK
),
187 STRING_TOKEN(STR_EDIT_HELP_DIV
),
191 MENU_ITEM_FUNCTION MainControlBasedMenuFunctions
[] = {
197 MainCommandDisplayHelp
, /* Ctrl - E */
198 MainCommandSearch
, /* Ctrl - F */
199 MainCommandGotoLine
, /* Ctrl - G */
203 MainCommandCutLine
, /* Ctrl - K */
207 MainCommandOpenFile
, /* Ctrl - O */
209 MainCommandExit
, /* Ctrl - Q */
210 MainCommandSearchReplace
, /* Ctrl - R */
211 MainCommandSaveFile
, /* Ctrl - S */
212 MainCommandSwitchFileType
, /* Ctrl - T */
213 MainCommandPasteLine
, /* Ctrl - U */
221 EDITOR_MENU_ITEM MainMenuItems
[] = {
223 STRING_TOKEN(STR_EDIT_LIBMENUBAR_GO_TO_LINE
),
224 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1
),
228 STRING_TOKEN(STR_EDIT_LIBMENUBAR_SAVE_FILE
),
229 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2
),
233 STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT
),
234 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3
),
239 STRING_TOKEN(STR_EDIT_LIBMENUBAR_SEARCH
),
240 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4
),
244 STRING_TOKEN(STR_EDIT_LIBMENUBAR_SEARCH_REPLACE
),
245 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5
),
246 MainCommandSearchReplace
249 STRING_TOKEN(STR_EDIT_LIBMENUBAR_CUT_LINE
),
250 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6
),
254 STRING_TOKEN(STR_EDIT_LIBMENUBAR_PASTE_LINE
),
255 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7
),
260 STRING_TOKEN(STR_EDIT_LIBMENUBAR_OPEN_FILE
),
261 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8
),
265 STRING_TOKEN(STR_EDIT_LIBMENUBAR_FILE_TYPE
),
266 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9
),
267 MainCommandSwitchFileType
270 STRING_TOKEN(STR_EDIT_LIBMENUBAR_FILE_TYPE
),
271 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F11
),
272 MainCommandSwitchFileType
284 Load a file from disk to editor
286 @retval EFI_SUCCESS The operation was successful.
287 @retval EFI_LOAD_ERROR A load error occured.
288 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
291 MainCommandOpenFile (
299 // This command will open a file from current working directory.
300 // Read-only file can also be opened. But it can not be modified.
301 // Below is the scenario of Open File command:
302 // 1.IF currently opened file has not been modIFied, directly go to step .
303 // IF currently opened file has been modified,
304 // an Input Bar will be prompted as :
305 // "File Modified. Save ( Yes/No/Cancel) ?"
306 // IF user press 'y' or 'Y', currently opened file will be saved.
307 // IF user press 'n' or 'N', currently opened file will
309 // IF user press 'c' or 'C' or ESC, Open File command ends and
310 // currently opened file is still opened.
312 // 2. An Input Bar will be prompted as : "File Name to Open: "
313 // IF user press ESC, Open File command ends and
314 // currently opened file is still opened.
315 // Any other inputs with a Return will
316 // cause currently opened file close.
318 // 3. IF user input file name is an existing file , this file will be read
320 // IF user input file name is a new file, this file will be created
321 // and opened. This file's type ( UNICODE or ASCII ) is the same
322 // with the old file.
323 // if current file is modified, so you need to choose
324 // whether to save it first.
326 if (MainEditor
.FileBuffer
->FileModified
) {
328 Status
= InputBarSetPrompt (L
"File modified. Save (Yes/No/Cancel) ? ");
329 if (EFI_ERROR (Status
)) {
333 // the answer is just one character
335 Status
= InputBarSetStringSize (1);
336 if (EFI_ERROR (Status
)) {
340 // loop for user's answer
341 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
345 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
346 StatusBarSetRefresh();
351 if (Status
== EFI_NOT_READY
) {
355 switch (InputBarGetString()[0]) {
359 // want to save this file first
361 Status
= FileBufferSave (MainEditor
.FileBuffer
->FileName
);
362 if (EFI_ERROR (Status
)) {
366 MainTitleBarRefresh (MainEditor
.FileBuffer
->FileName
, MainEditor
.FileBuffer
->FileType
, MainEditor
.FileBuffer
->ReadOnly
, MainEditor
.FileBuffer
->FileModified
, MainEditor
.ScreenSize
.Column
, MainEditor
.ScreenSize
.Row
, 0, 0);
367 FileBufferRestorePosition ();
374 // the file won't be saved
386 // TO get the open file name
388 Status
= InputBarSetPrompt (L
"File Name to Open: ");
389 if (EFI_ERROR (Status
)) {
390 FileBufferRead (MainEditor
.FileBuffer
->FileName
, TRUE
);
394 Status
= InputBarSetStringSize (100);
395 if (EFI_ERROR (Status
)) {
396 FileBufferRead (MainEditor
.FileBuffer
->FileName
, TRUE
);
401 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
402 StatusBarSetRefresh();
407 if (Status
== EFI_NOT_READY
) {
411 // The input string length should > 0
413 if (StrLen (InputBarGetString()) > 0) {
415 // CHECK if filename is valid
417 if (!IsValidFileName (InputBarGetString())) {
418 FileBufferRead (MainEditor
.FileBuffer
->FileName
, TRUE
);
419 StatusBarSetStatusString (L
"Invalid File Name");
429 Status
= FileBufferRead (InputBarGetString(), FALSE
);
431 if (EFI_ERROR (Status
)) {
432 FileBufferRead (MainEditor
.FileBuffer
->FileName
, TRUE
);
433 return EFI_LOAD_ERROR
;
440 Switch a file from ASCII to UNICODE or vise-versa.
442 @retval EFI_SUCCESS The switch was ok or a warning was presented.
445 MainCommandSwitchFileType (
450 // Below is the scenario of File Type command:
451 // After File Type is executed, file type will be changed to another type
452 // if file is read-only, can not be modified
454 if (MainEditor
.FileBuffer
->ReadOnly
) {
455 StatusBarSetStatusString (L
"Read Only File Can Not Be Modified");
459 if (MainEditor
.FileBuffer
->FileType
== FileTypeUnicode
) {
460 MainEditor
.FileBuffer
->FileType
= FileTypeAscii
;
462 MainEditor
.FileBuffer
->FileType
= FileTypeUnicode
;
465 MainEditor
.FileBuffer
->FileModified
= TRUE
;
471 cut current line to clipboard
473 @retval EFI_SUCCESS The operation was successful.
474 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
475 @retval EFI_LOAD_ERROR A load error occured.
483 EFI_EDITOR_LINE
*Line
;
486 // This command will cut current line ( where cursor is on ) to clip board.
487 // And cursor will move to the beginning of next line.
488 // Below is the scenario of Cut Line command:
489 // 1. IF cursor is on valid line, current line will be cut to clip board.
490 // IF cursor is not on valid line, an Status String will be prompted :
494 Status
= FileBufferCutLine (&Line
);
495 if (Status
== EFI_NOT_FOUND
) {
499 if (EFI_ERROR (Status
)) {
503 MainEditor
.CutLine
= Line
;
509 paste line to file buffer.
511 @retval EFI_SUCCESS The operation was successful.
512 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
513 @retval EFI_LOAD_ERROR A load error occured.
516 MainCommandPasteLine (
523 // Below is the scenario of Paste Line command:
524 // 1. IF nothing is on clipboard, a Status String will be prompted :
525 // "No Line to Paste" and Paste Line command ends.
526 // IF something is on clipboard, insert it above current line.
527 // nothing on clipboard
529 if (MainEditor
.CutLine
== NULL
) {
530 StatusBarSetStatusString (L
"No Line to Paste");
534 Status
= FileBufferPasteLine ();
541 search string in file buffer
543 @retval EFI_SUCCESS The operation was successful.
544 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
545 @retval EFI_LOAD_ERROR A load error occured.
558 // Below is the scenario of Search command:
559 // 1. An Input Bar will be prompted : "Enter Search String:".
560 // IF user press ESC, Search command ends.
561 // IF user just press Enter, Search command ends.
562 // IF user inputs the search string, do Step 2.
564 // 2. IF input search string is found, cursor will move to the first
565 // occurrence and do Step 3.
566 // IF input search string is not found, a Status String
567 // "Search String Not Found" will be prompted and Search command ends.
569 // 3. An Input Bar will be prompted: "Find Next (Yes/No/Cancel ) ?".
570 // IF user press ESC, Search command ends.
571 // IF user press 'y' or 'Y', do Step 2.
572 // IF user press 'n' or 'N', Search command ends.
573 // IF user press 'c' or 'C', Search command ends.
575 Status
= InputBarSetPrompt (L
"Enter Search String: ");
576 if (EFI_ERROR (Status
)) {
580 Status
= InputBarSetStringSize (40);
581 if (EFI_ERROR (Status
)) {
585 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
586 StatusBarSetRefresh();
591 if (Status
== EFI_NOT_READY
) {
595 // just enter pressed
597 if (StrLen (InputBarGetString()) == 0) {
601 Buffer
= CatSPrint (NULL
, L
"%s", InputBarGetString());
602 if (Buffer
== NULL
) {
603 return EFI_OUT_OF_RESOURCES
;
606 // the first time , search from current position
611 // since search may be continued to search multiple times
612 // so we need to backup editor each time
616 Status
= FileBufferSearch (Buffer
, Offset
);
618 if (Status
== EFI_NOT_FOUND
) {
624 Status
= InputBarSetPrompt (L
"Find Next (Yes/No) ?");
625 if (EFI_ERROR (Status
)) {
630 Status
= InputBarSetStringSize (1);
631 if (EFI_ERROR (Status
)) {
638 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
639 StatusBarSetRefresh();
644 if (Status
== EFI_NOT_READY
) {
649 switch (InputBarGetString()[0]) {
666 // end of while !Done
667 // for search second, third time, search from current position + strlen
669 Offset
= StrLen (Buffer
);
676 StatusBarSetStatusString (L
"Search String Not Found");
682 Search string in file buffer, and replace it with another str.
684 @retval EFI_SUCCESS The operation was successful.
685 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
686 @retval EFI_LOAD_ERROR A load error occured.
689 MainCommandSearchReplace (
698 BOOLEAN ReplaceOption
;
703 ReplaceOption
= FALSE
;
706 // Below is the scenario of Search/Replace command:
707 // 1. An Input Bar is prompted : "Enter Search String:".
708 // IF user press ESC, Search/Replace command ends.
709 // IF user just press Enter, Search/Replace command ends.
710 // IF user inputs the search string S, do Step 2.
712 // 2. An Input Bar is prompted: "Replace With:".
713 // IF user press ESC, Search/Replace command ends.
714 // IF user inputs the replace string R, do Step 3.
716 // 3. IF input search string is not found, an Status String
717 // "Search String Not Found" will be prompted
718 // and Search/Replace command ends
719 // IF input search string is found, do Step 4.
721 // 4. An Input Bar will be prompted: "Replace ( Yes/No/All/Cancel )?"
722 // IF user press 'y' or 'Y', S will be replaced with R and do Step 5
723 // IF user press 'n' or 'N', S will not be replaced and do Step 5.
724 // IF user press 'a' or 'A', all the S from file current position on
725 // will be replaced with R and Search/Replace command ends.
726 // IF user press 'c' or 'C' or ESC, Search/Replace command ends.
728 // 5. An Input Bar will be prompted: "Find Next (Yes/No/Cancel) ?".
729 // IF user press ESC, Search/Replace command ends.
730 // IF user press 'y' or 'Y', do Step 3.
731 // IF user press 'n' or 'N', Search/Replace command ends.
732 // IF user press 'c' or 'C', Search/Replace command ends.
733 // input search string
735 Status
= InputBarSetPrompt (L
"Enter Search String: ");
736 if (EFI_ERROR (Status
)) {
740 Status
= InputBarSetStringSize (40);
741 if (EFI_ERROR (Status
)) {
745 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
746 StatusBarSetRefresh();
751 if (Status
== EFI_NOT_READY
) {
755 // if just pressed enter
757 if (StrLen (InputBarGetString()) == 0) {
761 Search
= CatSPrint (NULL
, L
"%s", InputBarGetString());
762 if (Search
== NULL
) {
763 return EFI_OUT_OF_RESOURCES
;
766 SearchLen
= StrLen (Search
);
769 // input replace string
771 Status
= InputBarSetPrompt (L
"Replace With: ");
772 if (EFI_ERROR (Status
)) {
776 Status
= InputBarSetStringSize (40);
777 if (EFI_ERROR (Status
)) {
781 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
782 StatusBarSetRefresh();
787 if (Status
== EFI_NOT_READY
) {
791 Replace
= CatSPrint (NULL
, L
"%s", InputBarGetString());
792 if (Replace
== NULL
) {
794 return EFI_OUT_OF_RESOURCES
;
797 ReplaceLen
= StrLen (Replace
);
803 // since search may be continued to search multiple times
804 // so we need to backup editor each time
809 Status
= FileBufferSearch (Search
, 0);
812 // if just replace, so skip this replace string
813 // if replace string is an empty string, so skip to next character
816 Status
= FileBufferSearch (Search
, (ReplaceLen
== 0) ? 1 : ReplaceLen
);
818 Status
= FileBufferSearch (Search
, SearchLen
);
822 if (Status
== EFI_NOT_FOUND
) {
828 Status
= InputBarSetPrompt (L
"Replace (Yes/No/All/Cancel) ?");
830 if (EFI_ERROR (Status
)) {
836 Status
= InputBarSetStringSize (1);
837 if (EFI_ERROR (Status
)) {
845 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
846 StatusBarSetRefresh();
851 if (Status
== EFI_NOT_READY
) {
857 switch (InputBarGetString()[0]) {
861 ReplaceOption
= TRUE
;
867 ReplaceOption
= FALSE
;
873 ReplaceOption
= TRUE
;
889 // end of while !Done
896 if (MainEditor
.FileBuffer
->ReadOnly
) {
897 StatusBarSetStatusString (L
"Read Only File Can Not Be Modified");
904 Status
= FileBufferReplaceAll (Search
, Replace
, 0);
912 Status
= FileBufferReplace (Replace
, SearchLen
);
913 if (EFI_ERROR (Status
)) {
922 Status
= InputBarSetPrompt (L
"Find Next (Yes/No) ?");
923 if (EFI_ERROR (Status
)) {
929 Status
= InputBarSetStringSize (1);
930 if (EFI_ERROR (Status
)) {
938 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
939 StatusBarSetRefresh();
944 if (Status
== EFI_NOT_READY
) {
950 switch (InputBarGetString()[0]) {
968 // end of while !Done
979 StatusBarSetStatusString (L
"Search String Not Found");
987 @retval EFI_SUCCESS The operation was successful.
988 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
989 @retval EFI_LOAD_ERROR A load error occured.
999 // Below is the scenario of Exit command:
1000 // 1. IF currently opened file is not modified, exit the editor and
1001 // Exit command ends.
1002 // IF currently opened file is modified, do Step 2
1004 // 2. An Input Bar will be prompted:
1005 // "File modified. Save ( Yes/No/Cancel )?"
1006 // IF user press 'y' or 'Y', currently opened file will be saved
1008 // IF user press 'n' or 'N', currently opened file will not be saved
1009 // and Editor exits.
1010 // IF user press 'c' or 'C' or ESC, Exit command ends.
1011 // if file has been modified, so will prompt user whether to save the changes
1013 if (MainEditor
.FileBuffer
->FileModified
) {
1015 Status
= InputBarSetPrompt (L
"File modified. Save (Yes/No/Cancel) ? ");
1016 if (EFI_ERROR (Status
)) {
1020 Status
= InputBarSetStringSize (1);
1021 if (EFI_ERROR (Status
)) {
1026 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
1027 StatusBarSetRefresh();
1032 if (Status
== EFI_NOT_READY
) {
1036 switch (InputBarGetString()[0]) {
1040 // write file back to disk
1042 Status
= FileBufferSave (MainEditor
.FileBuffer
->FileName
);
1043 if (!EFI_ERROR (Status
)) {
1068 move cursor to specified lines
1070 @retval EFI_SUCCESS The operation was successful.
1073 MainCommandGotoLine (
1081 // Below is the scenario of Go To Line command:
1082 // 1. An Input Bar will be prompted : "Go To Line:".
1083 // IF user press ESC, Go To Line command ends.
1084 // IF user just press Enter, cursor remains unchanged.
1085 // IF user inputs line number, do Step 2.
1087 // 2. IF input line number is valid, move cursor to the beginning
1088 // of specified line and Go To Line command ends.
1089 // IF input line number is invalid, a Status String will be prompted:
1090 // "No Such Line" and Go To Line command ends.
1092 Status
= InputBarSetPrompt (L
"Go To Line: ");
1093 if (EFI_ERROR (Status
)) {
1097 // line number's digit <= 6
1099 Status
= InputBarSetStringSize (6);
1100 if (EFI_ERROR (Status
)) {
1104 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
1105 StatusBarSetRefresh();
1110 if (Status
== EFI_NOT_READY
) {
1114 // if JUST press enter
1116 if (StrLen (InputBarGetString()) == 0) {
1120 Row
= ShellStrToUintn (InputBarGetString());
1123 // invalid line number
1125 if (Row
> MainEditor
.FileBuffer
->NumLines
|| Row
<= 0) {
1126 StatusBarSetStatusString (L
"No Such Line");
1130 // move cursor to that line's start
1132 FileBufferMovePosition (Row
, 1);
1138 Save current file to disk, you can save to current file name or
1139 save to another file name.
1141 @retval EFI_SUCCESS The file was saved correctly.
1142 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1143 @retval EFI_LOAD_ERROR A file access error occured.
1146 MainCommandSaveFile (
1154 SHELL_FILE_HANDLE FileHandle
;
1155 EFI_FILE_INFO
*Info
;
1158 // This command will save currently opened file to disk.
1159 // You can choose save to another file name or just save to
1160 // current file name.
1161 // Below is the scenario of Save File command:
1162 // ( Suppose the old file name is A )
1163 // 1. An Input Bar will be prompted: "File To Save: [ old file name]"
1164 // IF user press ESC, Save File command ends .
1165 // IF user press Enter, input file name will be A.
1166 // IF user inputs a new file name B, input file name will be B.
1168 // 2. IF input file name is A, go to do Step 3.
1169 // IF input file name is B, go to do Step 4.
1171 // 3. IF A is read only, Status Bar will show "Access Denied" and
1172 // Save File commands ends.
1173 // IF A is not read only, save file buffer to disk and remove modified
1174 // flag in Title Bar , then Save File command ends.
1176 // 4. IF B does not exist, create this file and save file buffer to it.
1178 // IF B exits, do Step 5.
1180 // 5.An Input Bar will be prompted:
1181 // "File Exists. Overwrite ( Yes/No/Cancel )?"
1182 // IF user press 'y' or 'Y', do Step 6.
1183 // IF user press 'n' or 'N', Save File commands ends.
1184 // IF user press 'c' or 'C' or ESC, Save File commands ends.
1186 // 6. IF B is a read-only file, Status Bar will show "Access Denied" and
1187 // Save File commands ends.
1188 // IF B can be read and write, save file buffer to B.
1190 // 7. Update File Name field in Title Bar to B and remove the modified
1191 // flag in Title Bar.
1193 Str
= CatSPrint (NULL
, L
"File to Save: [%s]", MainEditor
.FileBuffer
->FileName
);
1195 return EFI_OUT_OF_RESOURCES
;
1198 if (StrLen (Str
) >= 50) {
1200 // replace the long file name with "..."
1206 Str
[50] = CHAR_NULL
;
1209 Status
= InputBarSetPrompt (Str
);
1212 if (EFI_ERROR (Status
)) {
1217 Status
= InputBarSetStringSize (100);
1218 if (EFI_ERROR (Status
)) {
1222 // get new file name
1224 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
1225 StatusBarSetRefresh();
1228 // if user pressed ESC
1230 if (Status
== EFI_NOT_READY
) {
1235 // if just enter pressed, so think save to current file name
1237 if (StrLen (InputBarGetString()) == 0) {
1238 FileName
= CatSPrint (NULL
, L
"%s", MainEditor
.FileBuffer
->FileName
);
1240 FileName
= CatSPrint (NULL
, L
"%s", InputBarGetString());
1243 if (FileName
== NULL
) {
1244 return EFI_OUT_OF_RESOURCES
;
1247 if (!IsValidFileName (FileName
)) {
1248 StatusBarSetStatusString (L
"Invalid File Name");
1249 FreePool (FileName
);
1256 // save to the old file
1258 if (StringNoCaseCompare (&FileName
, &MainEditor
.FileBuffer
->FileName
) == 0) {
1264 // if the file is read only, so can not write back to it.
1266 if (MainEditor
.FileBuffer
->ReadOnly
== TRUE
) {
1267 StatusBarSetStatusString (L
"Access Denied");
1268 FreePool (FileName
);
1273 // if the file exists
1275 if (ShellFileExists(FileName
) != EFI_NOT_FOUND
) {
1277 // check for read only
1279 Status
= ShellOpenFileByName(FileName
, &FileHandle
, EFI_FILE_MODE_READ
, 0);
1280 if (EFI_ERROR(Status
)) {
1281 StatusBarSetStatusString (L
"Open Failed");
1282 FreePool (FileName
);
1286 Info
= ShellGetFileInfo(FileHandle
);
1288 StatusBarSetStatusString (L
"Access Denied");
1289 FreePool (FileName
);
1290 return (EFI_SUCCESS
);
1293 if (Info
->Attribute
& EFI_FILE_READ_ONLY
) {
1294 StatusBarSetStatusString (L
"Access Denied - Read Only");
1296 FreePool (FileName
);
1297 return (EFI_SUCCESS
);
1302 // ask user whether to overwrite this file
1304 Status
= InputBarSetPrompt (L
"File exists. Overwrite (Yes/No/Cancel) ? ");
1305 if (EFI_ERROR (Status
)) {
1306 SHELL_FREE_NON_NULL (FileName
);
1310 Status
= InputBarSetStringSize (1);
1311 if (EFI_ERROR (Status
)) {
1312 SHELL_FREE_NON_NULL (FileName
);
1317 Status
= InputBarRefresh (MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
);
1318 StatusBarSetRefresh();
1323 if (Status
== EFI_NOT_READY
) {
1324 SHELL_FREE_NON_NULL (FileName
);
1328 switch (InputBarGetString()[0]) {
1337 SHELL_FREE_NON_NULL (FileName
);
1341 } // file does exist
1342 } // if old file name same
1345 // save file to disk with specified name
1347 FileBufferSetModified();
1348 Status
= FileBufferSave (FileName
);
1349 SHELL_FREE_NON_NULL (FileName
);
1355 Show help information for the editor.
1357 @retval EFI_SUCCESS The operation was successful.
1360 MainCommandDisplayHelp (
1371 for (CurrentLine
= 0; 0 != MainMenuHelpInfo
[CurrentLine
]; CurrentLine
++) {
1372 InfoString
= HiiGetString(gShellDebug1HiiHandle
, MainMenuHelpInfo
[CurrentLine
], NULL
);
1373 ShellPrintEx (0, CurrentLine
+1, L
"%E%s%N", InfoString
);
1380 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
1381 } while(SCAN_CONTROL_W
!= Key
.UnicodeChar
);
1384 // update screen with file buffer's info
1386 FileBufferRestorePosition ();
1387 FileBufferNeedRefresh
= TRUE
;
1388 FileBufferOnlyLineNeedRefresh
= FALSE
;
1389 FileBufferRefresh ();
1394 EFI_EDITOR_COLOR_ATTRIBUTES OriginalColors
;
1399 // basic initialization for MainEditor
1401 EFI_EDITOR_GLOBAL_EDITOR MainEditorConst
= {
1416 The initialization function for MainEditor.
1418 @retval EFI_SUCCESS The operation was successful.
1419 @retval EFI_LOAD_ERROR A load error occured.
1428 EFI_HANDLE
*HandleBuffer
;
1433 // basic initialization
1435 CopyMem (&MainEditor
, &MainEditorConst
, sizeof (MainEditor
));
1438 // set screen attributes
1440 MainEditor
.ColorAttributes
.Colors
.Foreground
= gST
->ConOut
->Mode
->Attribute
& 0x000000ff;
1442 MainEditor
.ColorAttributes
.Colors
.Background
= (UINT8
) (gST
->ConOut
->Mode
->Attribute
>> 4);
1443 OriginalColors
= MainEditor
.ColorAttributes
.Colors
;
1445 OriginalMode
= gST
->ConOut
->Mode
->Mode
;
1448 // query screen size
1450 gST
->ConOut
->QueryMode (
1452 gST
->ConOut
->Mode
->Mode
,
1453 &(MainEditor
.ScreenSize
.Column
),
1454 &(MainEditor
.ScreenSize
.Row
)
1458 // Find mouse in System Table ConsoleInHandle
1460 Status
= gBS
->HandleProtocol (
1462 &gEfiSimplePointerProtocolGuid
,
1463 (VOID
**)&MainEditor
.MouseInterface
1465 if (EFI_ERROR (Status
)) {
1467 // If there is no Simple Pointer Protocol on System Table
1469 HandleBuffer
= NULL
;
1470 MainEditor
.MouseInterface
= NULL
;
1471 Status
= gBS
->LocateHandleBuffer (
1473 &gEfiSimplePointerProtocolGuid
,
1478 if (!EFI_ERROR (Status
) && HandleCount
> 0) {
1480 // Try to find the first available mouse device
1482 for (Index
= 0; Index
< HandleCount
; Index
++) {
1483 Status
= gBS
->HandleProtocol (
1484 HandleBuffer
[Index
],
1485 &gEfiSimplePointerProtocolGuid
,
1486 (VOID
**)&MainEditor
.MouseInterface
1488 if (!EFI_ERROR (Status
)) {
1493 if (HandleBuffer
!= NULL
) {
1494 FreePool (HandleBuffer
);
1498 if (!EFI_ERROR (Status
) && MainEditor
.MouseInterface
!= NULL
) {
1499 MainEditor
.MouseAccumulatorX
= 0;
1500 MainEditor
.MouseAccumulatorY
= 0;
1501 MainEditor
.MouseSupported
= TRUE
;
1505 // below will call the five components' init function
1507 Status
= MainTitleBarInit (L
"UEFI EDIT");
1508 if (EFI_ERROR (Status
)) {
1509 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_EDIT_LIBEDITOR_TITLEBAR
), gShellDebug1HiiHandle
);
1510 return EFI_LOAD_ERROR
;
1513 Status
= ControlHotKeyInit (MainControlBasedMenuFunctions
);
1514 Status
= MenuBarInit (MainMenuItems
);
1515 if (EFI_ERROR (Status
)) {
1516 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_EDIT_LIBEDITOR_MAINMENU
), gShellDebug1HiiHandle
);
1517 return EFI_LOAD_ERROR
;
1520 Status
= StatusBarInit ();
1521 if (EFI_ERROR (Status
)) {
1522 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_EDIT_LIBEDITOR_STATUSBAR
), gShellDebug1HiiHandle
);
1523 return EFI_LOAD_ERROR
;
1528 Status
= FileBufferInit ();
1529 if (EFI_ERROR (Status
)) {
1530 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_EDIT_LIBEDITOR_FILEBUFFER
), gShellDebug1HiiHandle
);
1531 return EFI_LOAD_ERROR
;
1534 // clear whole screen and enable cursor
1536 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1537 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
1540 // initialize EditorFirst and EditorExit
1544 EditorMouseAction
= FALSE
;
1550 The cleanup function for MainEditor.
1552 @retval EFI_SUCCESS The operation was successful.
1553 @retval EFI_LOAD_ERROR A load error occured.
1564 // call the five components' cleanup function
1565 // if error, do not exit
1566 // just print some warning
1568 MainTitleBarCleanup();
1573 Status
= FileBufferCleanup ();
1574 if (EFI_ERROR (Status
)) {
1575 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_EDIT_LIBEDITOR_FILEBUFFER_CLEANUP
), gShellDebug1HiiHandle
);
1580 if (OriginalMode
!= gST
->ConOut
->Mode
->Mode
) {
1581 gST
->ConOut
->SetMode (gST
->ConOut
, OriginalMode
);
1584 // restore old screen color
1586 gST
->ConOut
->SetAttribute (
1588 EFI_TEXT_ATTR (OriginalColors
.Foreground
, OriginalColors
.Background
)
1591 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1597 Refresh the main editor component.
1606 // The Stall value is from experience. NOT from spec. avoids 'flicker'
1611 // call the components refresh function
1614 || StrCmp (FileBufferBackupVar
.FileName
, FileBuffer
.FileName
) != 0
1615 || FileBufferBackupVar
.FileType
!= FileBuffer
.FileType
1616 || FileBufferBackupVar
.FileModified
!= FileBuffer
.FileModified
1617 || FileBufferBackupVar
.ReadOnly
!= FileBuffer
.ReadOnly
) {
1619 MainTitleBarRefresh (MainEditor
.FileBuffer
->FileName
, MainEditor
.FileBuffer
->FileType
, MainEditor
.FileBuffer
->ReadOnly
, MainEditor
.FileBuffer
->FileModified
, MainEditor
.ScreenSize
.Column
, MainEditor
.ScreenSize
.Row
, 0, 0);
1620 FileBufferRestorePosition ();
1624 || FileBufferBackupVar
.FilePosition
.Row
!= FileBuffer
.FilePosition
.Row
1625 || FileBufferBackupVar
.FilePosition
.Column
!= FileBuffer
.FilePosition
.Column
1626 || FileBufferBackupVar
.ModeInsert
!= FileBuffer
.ModeInsert
1627 || StatusBarGetRefresh()) {
1629 StatusBarRefresh (EditorFirst
, MainEditor
.ScreenSize
.Row
, MainEditor
.ScreenSize
.Column
, MainEditor
.FileBuffer
->FilePosition
.Row
, MainEditor
.FileBuffer
->FilePosition
.Column
, MainEditor
.FileBuffer
->ModeInsert
);
1630 FileBufferRestorePosition ();
1634 FileBufferRestorePosition ();
1637 FileBufferRefresh ();
1640 // EditorFirst is now set to FALSE
1642 EditorFirst
= FALSE
;
1646 Get's the resultant location of the cursor based on the relative movement of the Mouse.
1648 @param[in] GuidX The relative mouse movement.
1650 @return The X location of the mouse.
1660 MainEditor
.MouseAccumulatorX
+= GuidX
;
1661 Gap
= (MainEditor
.MouseAccumulatorX
* (INT32
) MainEditor
.ScreenSize
.Column
) / (INT32
) (50 * (INT32
) MainEditor
.MouseInterface
->Mode
->ResolutionX
);
1662 MainEditor
.MouseAccumulatorX
= (MainEditor
.MouseAccumulatorX
* (INT32
) MainEditor
.ScreenSize
.Column
) % (INT32
) (50 * (INT32
) MainEditor
.MouseInterface
->Mode
->ResolutionX
);
1663 MainEditor
.MouseAccumulatorX
= MainEditor
.MouseAccumulatorX
/ (INT32
) MainEditor
.ScreenSize
.Column
;
1668 Get's the resultant location of the cursor based on the relative movement of the Mouse.
1670 @param[in] GuidY The relative mouse movement.
1672 @return The Y location of the mouse.
1682 MainEditor
.MouseAccumulatorY
+= GuidY
;
1683 Gap
= (MainEditor
.MouseAccumulatorY
* (INT32
) MainEditor
.ScreenSize
.Row
) / (INT32
) (50 * (INT32
) MainEditor
.MouseInterface
->Mode
->ResolutionY
);
1684 MainEditor
.MouseAccumulatorY
= (MainEditor
.MouseAccumulatorY
* (INT32
) MainEditor
.ScreenSize
.Row
) % (INT32
) (50 * (INT32
) MainEditor
.MouseInterface
->Mode
->ResolutionY
);
1685 MainEditor
.MouseAccumulatorY
= MainEditor
.MouseAccumulatorY
/ (INT32
) MainEditor
.ScreenSize
.Row
;
1691 Support mouse movement. Move the cursor.
1693 @param[in] MouseState The current mouse state.
1694 @param[out] BeforeLeftButtonDown TRUE if the left button down. Helps with selections.
1696 @retval EFI_SUCCESS The operation was successful.
1697 @retval EFI_NOT_FOUND There was no mouse support found.
1701 MainEditorHandleMouseInput (
1702 IN EFI_SIMPLE_POINTER_STATE MouseState
,
1703 OUT BOOLEAN
*BeforeLeftButtonDown
1712 EFI_EDITOR_LINE
*Line
;
1717 // mouse action means:
1719 // mouse left button
1724 // have mouse movement
1726 if (MouseState
.RelativeMovementX
|| MouseState
.RelativeMovementY
) {
1730 TextX
= GetTextX (MouseState
.RelativeMovementX
);
1731 TextY
= GetTextY (MouseState
.RelativeMovementY
);
1733 FileBufferAdjustMousePosition (TextX
, TextY
);
1740 // if left button pushed down
1742 if (MouseState
.LeftButton
) {
1744 FCol
= MainEditor
.FileBuffer
->MousePosition
.Column
- 1 + 1;
1746 FRow
= MainEditor
.FileBuffer
->FilePosition
.Row
+
1747 MainEditor
.FileBuffer
->MousePosition
.Row
-
1748 MainEditor
.FileBuffer
->DisplayPosition
.Row
;
1751 // beyond the file line length
1753 if (MainEditor
.FileBuffer
->NumLines
< FRow
) {
1754 FRow
= MainEditor
.FileBuffer
->NumLines
;
1757 Link
= MainEditor
.FileBuffer
->ListHead
->ForwardLink
;
1758 for (Index
= 0; Index
< FRow
- 1; Index
++) {
1759 Link
= Link
->ForwardLink
;
1762 Line
= CR (Link
, EFI_EDITOR_LINE
, Link
, LINE_LIST_SIGNATURE
);
1766 // beyond the line's column length
1768 if (FCol
> Line
->Size
) {
1769 if (*BeforeLeftButtonDown
) {
1771 if (Line
->Size
== 0) {
1774 FCol
= SHELL_EDIT_MAX_LINE_SIZE
;
1784 FCol
= Line
->Size
+ 1;
1788 FileBufferMovePosition (FRow
, FCol
);
1790 MainEditor
.FileBuffer
->MousePosition
.Row
= MainEditor
.FileBuffer
->DisplayPosition
.Row
;
1792 MainEditor
.FileBuffer
->MousePosition
.Column
= MainEditor
.FileBuffer
->DisplayPosition
.Column
;
1794 *BeforeLeftButtonDown
= TRUE
;
1799 // else of if LButton
1803 if (*BeforeLeftButtonDown
) {
1809 *BeforeLeftButtonDown
= FALSE
;
1822 return EFI_NOT_FOUND
;
1826 Handle user key input. This routes to other functions for the actions.
1828 @retval EFI_SUCCESS The operation was successful.
1829 @retval EFI_LOAD_ERROR A load error occured.
1830 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1834 MainEditorKeyInput (
1840 EFI_SIMPLE_POINTER_STATE MouseState
;
1841 BOOLEAN BeforeMouseIsDown
;
1842 BOOLEAN MouseIsDown
;
1847 UINTN SelectStartBackup
;
1848 UINTN SelectEndBackup
;
1851 // variable initialization
1855 MouseIsDown
= FALSE
;
1861 Status
= EFI_SUCCESS
;
1862 EditorMouseAction
= FALSE
;
1865 // backup some key elements, so that can aVOID some refresh work
1867 MainEditorBackup ();
1870 // change priority of checking mouse/keyboard activity dynamically
1871 // so prevent starvation of keyboard.
1872 // if last time, mouse moves then this time check keyboard
1874 if (MainEditor
.MouseSupported
) {
1875 Status
= MainEditor
.MouseInterface
->GetState (
1876 MainEditor
.MouseInterface
,
1879 if (!EFI_ERROR (Status
)) {
1880 BeforeMouseIsDown
= MouseIsDown
;
1882 Status
= MainEditorHandleMouseInput (MouseState
, &MouseIsDown
);
1884 if (!EFI_ERROR (Status
)) {
1885 if (!BeforeMouseIsDown
) {
1890 FRow
= FileBuffer
.FilePosition
.Row
;
1891 FCol
= FileBuffer
.FilePosition
.Column
;
1892 SelectStartBackup
= MainEditor
.SelectStart
;
1893 SelectEndBackup
= MainEditor
.SelectEnd
;
1899 SelectStartBackup
= MainEditor
.SelectStart
;
1900 SelectEndBackup
= MainEditor
.SelectEnd
;
1907 if (MouseState
.RelativeMovementX
|| MouseState
.RelativeMovementY
) {
1908 MainEditor
.SelectStart
= 0;
1909 MainEditor
.SelectEnd
= 0;
1910 MainEditor
.SelectStart
= (FRow
- 1) * SHELL_EDIT_MAX_LINE_SIZE
+ FCol
;
1917 (FileBuffer
.FilePosition
.Row
- 1) *
1918 SHELL_EDIT_MAX_LINE_SIZE
+
1919 FileBuffer
.FilePosition
.Column
1920 ) >= MainEditor
.SelectStart
1922 MainEditor
.SelectEnd
= (FileBuffer
.FilePosition
.Row
- 1) *
1923 SHELL_EDIT_MAX_LINE_SIZE
+
1924 FileBuffer
.FilePosition
.Column
;
1926 MainEditor
.SelectEnd
= 0;
1930 // end of if RelativeX/Y
1937 if (FileBufferGetTotalSize () == 0) {
1938 MainEditor
.SelectStart
= 0;
1939 MainEditor
.SelectEnd
= 0;
1945 (FileBuffer
.FilePosition
.Row
- 1) *
1946 SHELL_EDIT_MAX_LINE_SIZE
+
1947 FileBuffer
.FilePosition
.Column
1948 ) >= MainEditor
.SelectStart
1950 MainEditor
.SelectEnd
= (FileBuffer
.FilePosition
.Row
- 1) *
1951 SHELL_EDIT_MAX_LINE_SIZE
+
1952 FileBuffer
.FilePosition
.Column
;
1954 MainEditor
.SelectEnd
= 0;
1957 if (MainEditor
.SelectEnd
== 0) {
1958 MainEditor
.SelectStart
= 0;
1966 if (SelectStartBackup
!= MainEditor
.SelectStart
|| SelectEndBackup
!= MainEditor
.SelectEnd
) {
1967 if ((SelectStartBackup
- 1) / SHELL_EDIT_MAX_LINE_SIZE
!= (MainEditor
.SelectStart
- 1) / SHELL_EDIT_MAX_LINE_SIZE
) {
1968 FileBufferNeedRefresh
= TRUE
;
1970 if ((SelectEndBackup
- 1) / SHELL_EDIT_MAX_LINE_SIZE
!= (MainEditor
.SelectEnd
- 1) / SHELL_EDIT_MAX_LINE_SIZE
) {
1971 FileBufferNeedRefresh
= TRUE
;
1973 FileBufferOnlyLineNeedRefresh
= TRUE
;
1979 EditorMouseAction
= TRUE
;
1980 FileBufferMouseNeedRefresh
= TRUE
;
1981 } else if (Status
== EFI_LOAD_ERROR
) {
1982 StatusBarSetStatusString (L
"Invalid Mouse Movement ");
1987 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
1988 if (!EFI_ERROR (Status
)) {
1990 // dispatch to different components' key handling function
1991 // so not everywhere has to set this variable
1993 FileBufferMouseNeedRefresh
= TRUE
;
1995 // clear previous status string
1997 StatusBarSetRefresh();
2000 // dispatch to different components' key handling function
2002 if (EFI_NOT_FOUND
!= MenuBarDispatchControlHotKey(&Key
)) {
2003 Status
= EFI_SUCCESS
;
2004 } else if ((Key
.ScanCode
== SCAN_NULL
) || ((Key
.ScanCode
>= SCAN_UP
) && (Key
.ScanCode
<= SCAN_PAGE_DOWN
))) {
2005 Status
= FileBufferHandleInput (&Key
);
2006 } else if ((Key
.ScanCode
>= SCAN_F1
) && (Key
.ScanCode
<= SCAN_F12
)) {
2007 Status
= MenuBarDispatchFunctionKey (&Key
);
2009 StatusBarSetStatusString (L
"Unknown Command");
2010 FileBufferMouseNeedRefresh
= FALSE
;
2013 if (Status
!= EFI_SUCCESS
&& Status
!= EFI_OUT_OF_RESOURCES
) {
2015 // not already has some error status
2017 if (StatusBarGetString() != NULL
&& StrCmp (L
"", StatusBarGetString()) == 0) {
2018 StatusBarSetStatusString (L
"Disk Error. Try Again");
2024 // after handling, refresh editor
2026 MainEditorRefresh ();
2028 } while (Status
!= EFI_OUT_OF_RESOURCES
&& !EditorExit
);
2036 @param[in] Line A pointer to the line to be set to clipboard
2038 @retval EFI_SUCCESS The operation was successful.
2039 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
2043 MainEditorSetCutLine (
2044 EFI_EDITOR_LINE
*Line
2051 if (MainEditor
.CutLine
!= NULL
) {
2053 // free the old clipboard
2055 LineFree (MainEditor
.CutLine
);
2058 // duplicate the line to clipboard
2060 MainEditor
.CutLine
= LineDup (Line
);
2061 if (MainEditor
.CutLine
== NULL
) {
2062 return EFI_OUT_OF_RESOURCES
;
2069 Backup function for MainEditor
2071 @retval EFI_SUCCESS The operation was successful.
2079 MainEditorBackupVar
.SelectStart
= MainEditor
.SelectStart
;
2080 MainEditorBackupVar
.SelectEnd
= MainEditor
.SelectEnd
;
2081 FileBufferBackup ();