]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c
ShellPkg/[hex]edit: use SimpleTextInEx to read console
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / Edit / MainTextEditor.c
CommitLineData
632820d1 1/** @file\r
2 Implements editor interface functions.\r
3\r
5563281f 4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>\r
632820d1 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "TextEditor.h"\r
16#include "EditStatusBar.h"\r
17#include "EditInputBar.h"\r
5a2beb74 18#include "EditMenuBar.h"\r
19\r
20//\r
21// the first time editor launch\r
22//\r
23BOOLEAN EditorFirst;\r
24\r
25//\r
26// it's time editor should exit\r
27//\r
28BOOLEAN EditorExit;\r
29\r
30BOOLEAN EditorMouseAction;\r
31\r
32extern EFI_EDITOR_FILE_BUFFER FileBuffer;\r
33\r
34extern BOOLEAN FileBufferNeedRefresh;\r
35\r
36extern BOOLEAN FileBufferOnlyLineNeedRefresh;\r
37\r
38extern BOOLEAN FileBufferMouseNeedRefresh;\r
39\r
40extern EFI_EDITOR_FILE_BUFFER FileBufferBackupVar;\r
41\r
42EFI_EDITOR_GLOBAL_EDITOR MainEditor;\r
43\r
632820d1 44\r
45/**\r
46 Load a file from disk to editor\r
47\r
48 @retval EFI_SUCCESS The operation was successful.\r
49 @retval EFI_LOAD_ERROR A load error occured.\r
50 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
51**/\r
52EFI_STATUS\r
632820d1 53MainCommandOpenFile (\r
54 VOID\r
55 );\r
56\r
57/**\r
58 Switch a file from ASCII to UNICODE or vise-versa.\r
59\r
60 @retval EFI_SUCCESS The switch was ok or a warning was presented.\r
61**/\r
62EFI_STATUS\r
632820d1 63MainCommandSwitchFileType (\r
64 VOID\r
65 );\r
66\r
67/**\r
68 move cursor to specified lines\r
69\r
70 @retval EFI_SUCCESS The operation was successful.\r
71**/\r
72EFI_STATUS\r
632820d1 73MainCommandGotoLine (\r
74 VOID\r
75 );\r
76\r
77/**\r
78 Save current file to disk, you can save to current file name or\r
79 save to another file name.\r
80 \r
81 @retval EFI_SUCCESS The file was saved correctly.\r
82 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
83 @retval EFI_LOAD_ERROR A file access error occured.\r
84**/\r
85EFI_STATUS\r
632820d1 86MainCommandSaveFile (\r
87 VOID\r
88 );\r
89\r
5a2beb74 90/**\r
feccc28a 91 Show help information for the editor.\r
5a2beb74 92\r
93 @retval EFI_SUCCESS The operation was successful.\r
94**/\r
95EFI_STATUS\r
96MainCommandDisplayHelp (\r
97 VOID\r
98 );\r
99\r
632820d1 100/**\r
101 exit editor\r
102\r
103 @retval EFI_SUCCESS The operation was successful.\r
104 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
105 @retval EFI_LOAD_ERROR A load error occured.\r
106**/\r
107EFI_STATUS\r
632820d1 108MainCommandExit (\r
109 VOID\r
110 );\r
111\r
112/**\r
113 search string in file buffer\r
114\r
115 @retval EFI_SUCCESS The operation was successful.\r
116 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
117 @retval EFI_LOAD_ERROR A load error occured.\r
118**/\r
119EFI_STATUS\r
632820d1 120MainCommandSearch (\r
121 VOID\r
122 );\r
123\r
ae724571 124/**\r
632820d1 125 search string in file buffer, and replace it with another str\r
126\r
127 @retval EFI_SUCCESS The operation was successful.\r
128 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
129 @retval EFI_LOAD_ERROR A load error occured.\r
130**/\r
131EFI_STATUS\r
632820d1 132MainCommandSearchReplace (\r
133 VOID\r
134 );\r
135\r
136/**\r
137 cut current line to clipboard\r
138\r
139 @retval EFI_SUCCESS The operation was successful.\r
140 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
141 @retval EFI_LOAD_ERROR A load error occured.\r
142**/\r
143EFI_STATUS\r
632820d1 144MainCommandCutLine (\r
145 VOID\r
146 );\r
147\r
148/**\r
149 paste line to file buffer.\r
150\r
151 @retval EFI_SUCCESS The operation was successful.\r
152 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
153 @retval EFI_LOAD_ERROR A load error occured.\r
154**/\r
155EFI_STATUS\r
632820d1 156MainCommandPasteLine (\r
157 VOID\r
158 );\r
159\r
5a2beb74 160/**\r
161 Help info that will be displayed.\r
162**/\r
163EFI_STRING_ID MainMenuHelpInfo[] = {\r
164 STRING_TOKEN(STR_EDIT_HELP_TITLE),\r
165 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
166 STRING_TOKEN(STR_EDIT_HELP_LIST_TITLE),\r
167 STRING_TOKEN(STR_EDIT_HELP_DIV),\r
168 STRING_TOKEN(STR_EDIT_HELP_GO_TO_LINE),\r
169 STRING_TOKEN(STR_EDIT_HELP_SAVE_FILE),\r
170 STRING_TOKEN(STR_EDIT_HELP_EXIT),\r
171 STRING_TOKEN(STR_EDIT_HELP_SEARCH),\r
172 STRING_TOKEN(STR_EDIT_HELP_SEARCH_REPLACE),\r
173 STRING_TOKEN(STR_EDIT_HELP_CUT_LINE),\r
174 STRING_TOKEN(STR_EDIT_HELP_PASTE_LINE),\r
175 STRING_TOKEN(STR_EDIT_HELP_OPEN_FILE),\r
176 STRING_TOKEN(STR_EDIT_HELP_FILE_TYPE),\r
177 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
178 STRING_TOKEN(STR_EDIT_HELP_EXIT_HELP),\r
179 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
180 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
181 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
182 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
183 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
184 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
185 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
186 STRING_TOKEN(STR_EDIT_HELP_DIV),\r
1870\r
188};\r
189\r
190MENU_ITEM_FUNCTION MainControlBasedMenuFunctions[] = {\r
191 NULL,\r
192 NULL, /* Ctrl - A */\r
193 NULL, /* Ctrl - B */\r
194 NULL, /* Ctrl - C */\r
195 NULL, /* Ctrl - D */\r
196 MainCommandDisplayHelp, /* Ctrl - E */\r
197 MainCommandSearch, /* Ctrl - F */\r
198 MainCommandGotoLine, /* Ctrl - G */\r
199 NULL, /* Ctrl - H */\r
200 NULL, /* Ctrl - I */\r
201 NULL, /* Ctrl - J */\r
202 MainCommandCutLine, /* Ctrl - K */\r
203 NULL, /* Ctrl - L */\r
204 NULL, /* Ctrl - M */\r
205 NULL, /* Ctrl - N */\r
206 MainCommandOpenFile, /* Ctrl - O */\r
207 NULL, /* Ctrl - P */\r
208 MainCommandExit, /* Ctrl - Q */\r
209 MainCommandSearchReplace, /* Ctrl - R */\r
210 MainCommandSaveFile, /* Ctrl - S */\r
211 MainCommandSwitchFileType, /* Ctrl - T */\r
212 MainCommandPasteLine, /* Ctrl - U */\r
213 NULL, /* Ctrl - V */\r
214 NULL, /* Ctrl - W */\r
215 NULL, /* Ctrl - X */\r
216 NULL, /* Ctrl - Y */\r
217 NULL, /* Ctrl - Z */\r
218};\r
219\r
632820d1 220EDITOR_MENU_ITEM MainMenuItems[] = {\r
221 {\r
222 STRING_TOKEN(STR_EDIT_LIBMENUBAR_GO_TO_LINE),\r
223 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1),\r
224 MainCommandGotoLine\r
225 },\r
226 {\r
227 STRING_TOKEN(STR_EDIT_LIBMENUBAR_SAVE_FILE),\r
228 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2),\r
229 MainCommandSaveFile\r
230 },\r
231 {\r
232 STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT),\r
233 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3),\r
234 MainCommandExit\r
235 },\r
236\r
237 {\r
238 STRING_TOKEN(STR_EDIT_LIBMENUBAR_SEARCH),\r
239 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4),\r
240 MainCommandSearch\r
241 },\r
242 {\r
243 STRING_TOKEN(STR_EDIT_LIBMENUBAR_SEARCH_REPLACE),\r
244 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5),\r
245 MainCommandSearchReplace\r
246 },\r
247 {\r
248 STRING_TOKEN(STR_EDIT_LIBMENUBAR_CUT_LINE),\r
249 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6),\r
250 MainCommandCutLine\r
251 },\r
252 {\r
253 STRING_TOKEN(STR_EDIT_LIBMENUBAR_PASTE_LINE),\r
254 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7),\r
255 MainCommandPasteLine\r
256 },\r
257\r
258 {\r
259 STRING_TOKEN(STR_EDIT_LIBMENUBAR_OPEN_FILE),\r
260 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8),\r
261 MainCommandOpenFile\r
262 },\r
263 {\r
264 STRING_TOKEN(STR_EDIT_LIBMENUBAR_FILE_TYPE),\r
265 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9),\r
266 MainCommandSwitchFileType\r
267 },\r
5a2beb74 268 {\r
269 STRING_TOKEN(STR_EDIT_LIBMENUBAR_FILE_TYPE),\r
270 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F11),\r
271 MainCommandSwitchFileType\r
272 },\r
632820d1 273\r
274 {\r
275 0,\r
276 0,\r
277 NULL\r
278 }\r
279};\r
280\r
281\r
282/**\r
283 Load a file from disk to editor\r
284\r
285 @retval EFI_SUCCESS The operation was successful.\r
286 @retval EFI_LOAD_ERROR A load error occured.\r
287 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
288**/\r
289EFI_STATUS\r
632820d1 290MainCommandOpenFile (\r
291 VOID\r
292 )\r
293{\r
294 BOOLEAN Done;\r
295 EFI_STATUS Status;\r
296\r
297 //\r
298 // This command will open a file from current working directory.\r
299 // Read-only file can also be opened. But it can not be modified.\r
300 // Below is the scenario of Open File command:\r
301 // 1.IF currently opened file has not been modIFied, directly go to step .\r
302 // IF currently opened file has been modified,\r
303 // an Input Bar will be prompted as :\r
304 // "File Modified. Save ( Yes/No/Cancel) ?"\r
305 // IF user press 'y' or 'Y', currently opened file will be saved.\r
306 // IF user press 'n' or 'N', currently opened file will\r
307 // not be saved.\r
308 // IF user press 'c' or 'C' or ESC, Open File command ends and\r
309 // currently opened file is still opened.\r
310 //\r
311 // 2. An Input Bar will be prompted as : "File Name to Open: "\r
312 // IF user press ESC, Open File command ends and\r
313 // currently opened file is still opened.\r
314 // Any other inputs with a Return will\r
315 // cause currently opened file close.\r
316 //\r
317 // 3. IF user input file name is an existing file , this file will be read\r
318 // and opened.\r
319 // IF user input file name is a new file, this file will be created\r
320 // and opened. This file's type ( UNICODE or ASCII ) is the same\r
321 // with the old file.\r
322 // if current file is modified, so you need to choose\r
323 // whether to save it first.\r
324 //\r
325 if (MainEditor.FileBuffer->FileModified) {\r
326\r
327 Status = InputBarSetPrompt (L"File modified. Save (Yes/No/Cancel) ? ");\r
328 if (EFI_ERROR (Status)) {\r
329 return Status;\r
330 }\r
331 //\r
332 // the answer is just one character\r
333 //\r
334 Status = InputBarSetStringSize (1);\r
335 if (EFI_ERROR (Status)) {\r
336 return Status;\r
337 }\r
338 //\r
339 // loop for user's answer\r
340 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'\r
341 //\r
342 Done = FALSE;\r
343 while (!Done) {\r
344 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
345 StatusBarSetRefresh();\r
346\r
347 //\r
348 // ESC pressed\r
349 //\r
350 if (Status == EFI_NOT_READY) {\r
351 return EFI_SUCCESS;\r
352 }\r
353\r
354 switch (InputBarGetString()[0]) {\r
355 case L'y':\r
356 case L'Y':\r
357 //\r
358 // want to save this file first\r
359 //\r
360 Status = FileBufferSave (MainEditor.FileBuffer->FileName);\r
361 if (EFI_ERROR (Status)) {\r
362 return Status;\r
363 }\r
364\r
980d554e 365 MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0);\r
632820d1 366 FileBufferRestorePosition ();\r
367 Done = TRUE;\r
368 break;\r
369\r
370 case L'n':\r
371 case L'N':\r
372 //\r
373 // the file won't be saved\r
374 //\r
375 Done = TRUE;\r
376 break;\r
377\r
378 case L'c':\r
379 case L'C':\r
380 return EFI_SUCCESS;\r
381 }\r
382 }\r
383 }\r
384 //\r
385 // TO get the open file name\r
386 //\r
387 Status = InputBarSetPrompt (L"File Name to Open: ");\r
388 if (EFI_ERROR (Status)) {\r
389 FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);\r
390 return Status;\r
391 }\r
392\r
393 Status = InputBarSetStringSize (100);\r
394 if (EFI_ERROR (Status)) {\r
395 FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);\r
396 return Status;\r
397 }\r
398\r
399 while (1) {\r
400 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
401 StatusBarSetRefresh();\r
402\r
403 //\r
404 // ESC pressed\r
405 //\r
406 if (Status == EFI_NOT_READY) {\r
407 return EFI_SUCCESS;\r
408 }\r
409 //\r
410 // The input string length should > 0\r
411 //\r
412 if (StrLen (InputBarGetString()) > 0) {\r
413 //\r
414 // CHECK if filename is valid\r
415 //\r
416 if (!IsValidFileName (InputBarGetString())) {\r
417 FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);\r
418 StatusBarSetStatusString (L"Invalid File Name");\r
419 return EFI_SUCCESS;\r
420 }\r
421\r
422 break;\r
423 }\r
424 }\r
425 //\r
426 // read from disk\r
427 //\r
428 Status = FileBufferRead (InputBarGetString(), FALSE);\r
429\r
430 if (EFI_ERROR (Status)) {\r
431 FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);\r
432 return EFI_LOAD_ERROR;\r
433 }\r
434\r
435 return EFI_SUCCESS;\r
436}\r
437\r
438/**\r
439 Switch a file from ASCII to UNICODE or vise-versa.\r
440\r
441 @retval EFI_SUCCESS The switch was ok or a warning was presented.\r
442**/\r
443EFI_STATUS\r
632820d1 444MainCommandSwitchFileType (\r
445 VOID\r
446 )\r
447{\r
448 //\r
449 // Below is the scenario of File Type command:\r
450 // After File Type is executed, file type will be changed to another type\r
451 // if file is read-only, can not be modified\r
452 //\r
453 if (MainEditor.FileBuffer->ReadOnly) {\r
454 StatusBarSetStatusString (L"Read Only File Can Not Be Modified");\r
455 return EFI_SUCCESS;\r
456 }\r
457\r
458 if (MainEditor.FileBuffer->FileType == FileTypeUnicode) {\r
459 MainEditor.FileBuffer->FileType = FileTypeAscii;\r
460 } else {\r
461 MainEditor.FileBuffer->FileType = FileTypeUnicode;\r
462 }\r
463\r
464 MainEditor.FileBuffer->FileModified = TRUE;\r
465\r
466 return EFI_SUCCESS;\r
467}\r
468\r
469/**\r
470 cut current line to clipboard\r
471\r
472 @retval EFI_SUCCESS The operation was successful.\r
473 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
474 @retval EFI_LOAD_ERROR A load error occured.\r
475**/\r
476EFI_STATUS\r
632820d1 477MainCommandCutLine (\r
478 VOID\r
479 )\r
480{\r
481 EFI_STATUS Status;\r
482 EFI_EDITOR_LINE *Line;\r
483\r
484 //\r
485 // This command will cut current line ( where cursor is on ) to clip board.\r
486 // And cursor will move to the beginning of next line.\r
487 // Below is the scenario of Cut Line command:\r
488 // 1. IF cursor is on valid line, current line will be cut to clip board.\r
489 // IF cursor is not on valid line, an Status String will be prompted :\r
490 // "Nothing to Cut".\r
491 //\r
0d807dae 492 Line = NULL;\r
632820d1 493 Status = FileBufferCutLine (&Line);\r
494 if (Status == EFI_NOT_FOUND) {\r
495 return EFI_SUCCESS;\r
496 }\r
497\r
498 if (EFI_ERROR (Status)) {\r
499 return Status;\r
500 }\r
501\r
502 MainEditor.CutLine = Line;\r
503\r
504 return EFI_SUCCESS;\r
505}\r
506\r
507/**\r
508 paste line to file buffer.\r
509\r
510 @retval EFI_SUCCESS The operation was successful.\r
511 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
512 @retval EFI_LOAD_ERROR A load error occured.\r
513**/\r
514EFI_STATUS\r
632820d1 515MainCommandPasteLine (\r
516 VOID\r
517 )\r
518{\r
519 EFI_STATUS Status;\r
520\r
521 //\r
522 // Below is the scenario of Paste Line command:\r
523 // 1. IF nothing is on clipboard, a Status String will be prompted :\r
524 // "No Line to Paste" and Paste Line command ends.\r
525 // IF something is on clipboard, insert it above current line.\r
526 // nothing on clipboard\r
527 //\r
528 if (MainEditor.CutLine == NULL) {\r
529 StatusBarSetStatusString (L"No Line to Paste");\r
530 return EFI_SUCCESS;\r
531 }\r
532\r
533 Status = FileBufferPasteLine ();\r
534\r
535 return Status;\r
536}\r
537\r
538\r
539/**\r
540 search string in file buffer\r
541\r
542 @retval EFI_SUCCESS The operation was successful.\r
543 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
544 @retval EFI_LOAD_ERROR A load error occured.\r
545**/\r
546EFI_STATUS\r
632820d1 547MainCommandSearch (\r
548 VOID\r
549 )\r
550{\r
551 EFI_STATUS Status;\r
552 CHAR16 *Buffer;\r
553 BOOLEAN Done;\r
554 UINTN Offset;\r
555\r
556 //\r
557 // Below is the scenario of Search command:\r
558 // 1. An Input Bar will be prompted : "Enter Search String:".\r
559 // IF user press ESC, Search command ends.\r
560 // IF user just press Enter, Search command ends.\r
561 // IF user inputs the search string, do Step 2.\r
562 //\r
563 // 2. IF input search string is found, cursor will move to the first\r
564 // occurrence and do Step 3.\r
565 // IF input search string is not found, a Status String\r
566 // "Search String Not Found" will be prompted and Search command ends.\r
567 //\r
568 // 3. An Input Bar will be prompted: "Find Next (Yes/No/Cancel ) ?".\r
569 // IF user press ESC, Search command ends.\r
570 // IF user press 'y' or 'Y', do Step 2.\r
571 // IF user press 'n' or 'N', Search command ends.\r
572 // IF user press 'c' or 'C', Search command ends.\r
573 //\r
574 Status = InputBarSetPrompt (L"Enter Search String: ");\r
575 if (EFI_ERROR (Status)) {\r
576 return Status;\r
577 }\r
578\r
579 Status = InputBarSetStringSize (40);\r
580 if (EFI_ERROR (Status)) {\r
581 return Status;\r
582 }\r
583\r
584 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
585 StatusBarSetRefresh();\r
586\r
587 //\r
588 // ESC\r
589 //\r
590 if (Status == EFI_NOT_READY) {\r
591 return EFI_SUCCESS;\r
592 }\r
593 //\r
594 // just enter pressed\r
595 //\r
596 if (StrLen (InputBarGetString()) == 0) {\r
597 return EFI_SUCCESS;\r
598 }\r
599\r
600 Buffer = CatSPrint (NULL, L"%s", InputBarGetString());\r
601 if (Buffer == NULL) {\r
602 return EFI_OUT_OF_RESOURCES;\r
603 }\r
604 //\r
605 // the first time , search from current position\r
606 //\r
607 Offset = 0;\r
608 do {\r
609 //\r
610 // since search may be continued to search multiple times\r
611 // so we need to backup editor each time\r
612 //\r
613 MainEditorBackup ();\r
614\r
615 Status = FileBufferSearch (Buffer, Offset);\r
616\r
617 if (Status == EFI_NOT_FOUND) {\r
618 break;\r
619 }\r
620 //\r
621 // Find next\r
622 //\r
623 Status = InputBarSetPrompt (L"Find Next (Yes/No) ?");\r
624 if (EFI_ERROR (Status)) {\r
625 FreePool (Buffer);\r
626 return Status;\r
627 }\r
628\r
629 Status = InputBarSetStringSize (1);\r
630 if (EFI_ERROR (Status)) {\r
631 FreePool (Buffer);\r
632 return Status;\r
633 }\r
634\r
635 Done = FALSE;\r
636 while (!Done) {\r
637 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
638 StatusBarSetRefresh();\r
639\r
640 //\r
641 // ESC pressed\r
642 //\r
643 if (Status == EFI_NOT_READY) {\r
644 FreePool (Buffer);\r
645 return EFI_SUCCESS;\r
646 }\r
647\r
648 switch (InputBarGetString()[0]) {\r
649 case L'y':\r
650 case L'Y':\r
651 Done = TRUE;\r
652 break;\r
653\r
654 case L'n':\r
655 case L'N':\r
656 FreePool (Buffer);\r
657 return EFI_SUCCESS;\r
658\r
659 }\r
660 //\r
661 // end of which\r
662 //\r
663 }\r
664 //\r
665 // end of while !Done\r
666 // for search second, third time, search from current position + strlen\r
667 //\r
668 Offset = StrLen (Buffer);\r
669\r
670 } while (1);\r
671 //\r
672 // end of do\r
673 //\r
674 FreePool (Buffer);\r
675 StatusBarSetStatusString (L"Search String Not Found");\r
676\r
677 return EFI_SUCCESS;\r
678}\r
679\r
ae724571 680/**\r
681 Search string in file buffer, and replace it with another str.\r
632820d1 682\r
683 @retval EFI_SUCCESS The operation was successful.\r
684 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
685 @retval EFI_LOAD_ERROR A load error occured.\r
686**/\r
687EFI_STATUS\r
632820d1 688MainCommandSearchReplace (\r
689 VOID\r
690 )\r
691{\r
692 EFI_STATUS Status;\r
693 CHAR16 *Search;\r
694 CHAR16 *Replace;\r
695 BOOLEAN Done;\r
696 BOOLEAN First;\r
697 BOOLEAN ReplaceOption;\r
698 UINTN SearchLen;\r
699 UINTN ReplaceLen;\r
700 BOOLEAN ReplaceAll;\r
701\r
702 ReplaceOption = FALSE;\r
703\r
704 //\r
705 // Below is the scenario of Search/Replace command:\r
706 // 1. An Input Bar is prompted : "Enter Search String:".\r
707 // IF user press ESC, Search/Replace command ends.\r
708 // IF user just press Enter, Search/Replace command ends.\r
709 // IF user inputs the search string S, do Step 2.\r
710 //\r
711 // 2. An Input Bar is prompted: "Replace With:".\r
712 // IF user press ESC, Search/Replace command ends.\r
713 // IF user inputs the replace string R, do Step 3.\r
714 //\r
715 // 3. IF input search string is not found, an Status String\r
716 // "Search String Not Found" will be prompted\r
717 // and Search/Replace command ends\r
718 // IF input search string is found, do Step 4.\r
719 //\r
720 // 4. An Input Bar will be prompted: "Replace ( Yes/No/All/Cancel )?"\r
721 // IF user press 'y' or 'Y', S will be replaced with R and do Step 5\r
722 // IF user press 'n' or 'N', S will not be replaced and do Step 5.\r
723 // IF user press 'a' or 'A', all the S from file current position on\r
724 // will be replaced with R and Search/Replace command ends.\r
725 // IF user press 'c' or 'C' or ESC, Search/Replace command ends.\r
726 //\r
727 // 5. An Input Bar will be prompted: "Find Next (Yes/No/Cancel) ?".\r
728 // IF user press ESC, Search/Replace command ends.\r
729 // IF user press 'y' or 'Y', do Step 3.\r
730 // IF user press 'n' or 'N', Search/Replace command ends.\r
731 // IF user press 'c' or 'C', Search/Replace command ends.\r
732 // input search string\r
733 //\r
734 Status = InputBarSetPrompt (L"Enter Search String: ");\r
735 if (EFI_ERROR (Status)) {\r
736 return Status;\r
737 }\r
738\r
739 Status = InputBarSetStringSize (40);\r
740 if (EFI_ERROR (Status)) {\r
741 return Status;\r
742 }\r
743\r
744 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
745 StatusBarSetRefresh();\r
746\r
747 //\r
748 // ESC\r
749 //\r
750 if (Status == EFI_NOT_READY) {\r
751 return EFI_SUCCESS;\r
752 }\r
753 //\r
754 // if just pressed enter\r
755 //\r
756 if (StrLen (InputBarGetString()) == 0) {\r
757 return EFI_SUCCESS;\r
758 }\r
759\r
760 Search = CatSPrint (NULL, L"%s", InputBarGetString());\r
761 if (Search == NULL) {\r
762 return EFI_OUT_OF_RESOURCES;\r
763 }\r
764\r
765 SearchLen = StrLen (Search);\r
766\r
767 //\r
768 // input replace string\r
769 //\r
770 Status = InputBarSetPrompt (L"Replace With: ");\r
771 if (EFI_ERROR (Status)) {\r
772 return Status;\r
773 }\r
774\r
775 Status = InputBarSetStringSize (40);\r
776 if (EFI_ERROR (Status)) {\r
777 return Status;\r
778 }\r
779\r
780 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
781 StatusBarSetRefresh();\r
782\r
783 //\r
784 // ESC\r
785 //\r
786 if (Status == EFI_NOT_READY) {\r
787 return EFI_SUCCESS;\r
788 }\r
789\r
790 Replace = CatSPrint (NULL, L"%s", InputBarGetString());\r
791 if (Replace == NULL) {\r
792 FreePool (Search);\r
793 return EFI_OUT_OF_RESOURCES;\r
794 }\r
795\r
796 ReplaceLen = StrLen (Replace);\r
797\r
798 First = TRUE;\r
799 ReplaceAll = FALSE;\r
800 do {\r
801 //\r
802 // since search may be continued to search multiple times\r
803 // so we need to backup editor each time\r
804 //\r
805 MainEditorBackup ();\r
806\r
807 if (First) {\r
808 Status = FileBufferSearch (Search, 0);\r
809 } else {\r
810 //\r
811 // if just replace, so skip this replace string\r
812 // if replace string is an empty string, so skip to next character\r
813 //\r
814 if (ReplaceOption) {\r
815 Status = FileBufferSearch (Search, (ReplaceLen == 0) ? 1 : ReplaceLen);\r
816 } else {\r
817 Status = FileBufferSearch (Search, SearchLen);\r
818 }\r
819 }\r
820\r
821 if (Status == EFI_NOT_FOUND) {\r
822 break;\r
823 }\r
824 //\r
825 // replace or not?\r
826 //\r
827 Status = InputBarSetPrompt (L"Replace (Yes/No/All/Cancel) ?");\r
828\r
829 if (EFI_ERROR (Status)) {\r
830 FreePool (Search);\r
831 FreePool (Replace);\r
832 return Status;\r
833 }\r
834\r
835 Status = InputBarSetStringSize (1);\r
836 if (EFI_ERROR (Status)) {\r
837 FreePool (Search);\r
838 FreePool (Replace);\r
839 return Status;\r
840 }\r
841\r
842 Done = FALSE;\r
843 while (!Done) {\r
844 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
845 StatusBarSetRefresh();\r
846\r
847 //\r
848 // ESC pressed\r
849 //\r
850 if (Status == EFI_NOT_READY) {\r
851 FreePool (Search);\r
852 FreePool (Replace);\r
853 return EFI_SUCCESS;\r
854 }\r
855\r
856 switch (InputBarGetString()[0]) {\r
857 case L'y':\r
858 case L'Y':\r
859 Done = TRUE;\r
860 ReplaceOption = TRUE;\r
861 break;\r
862\r
863 case L'n':\r
864 case L'N':\r
865 Done = TRUE;\r
866 ReplaceOption = FALSE;\r
867 break;\r
868\r
869 case L'a':\r
870 case L'A':\r
871 Done = TRUE;\r
872 ReplaceOption = TRUE;\r
873 ReplaceAll = TRUE;\r
874 break;\r
875\r
876 case L'c':\r
877 case L'C':\r
878 FreePool (Search);\r
879 FreePool (Replace);\r
880 return EFI_SUCCESS;\r
881\r
882 }\r
883 //\r
884 // end of which\r
885 //\r
886 }\r
887 //\r
888 // end of while !Done\r
889 // Decide to Replace\r
890 //\r
891 if (ReplaceOption) {\r
892 //\r
893 // file is read-only\r
894 //\r
895 if (MainEditor.FileBuffer->ReadOnly) {\r
896 StatusBarSetStatusString (L"Read Only File Can Not Be Modified");\r
897 return EFI_SUCCESS;\r
898 }\r
899 //\r
900 // replace all\r
901 //\r
902 if (ReplaceAll) {\r
903 Status = FileBufferReplaceAll (Search, Replace, 0);\r
904 FreePool (Search);\r
905 FreePool (Replace);\r
906 return Status;\r
907 }\r
908 //\r
909 // replace\r
910 //\r
911 Status = FileBufferReplace (Replace, SearchLen);\r
912 if (EFI_ERROR (Status)) {\r
913 FreePool (Search);\r
914 FreePool (Replace);\r
915 return Status;\r
916 }\r
917 }\r
918 //\r
919 // Find next\r
920 //\r
921 Status = InputBarSetPrompt (L"Find Next (Yes/No) ?");\r
922 if (EFI_ERROR (Status)) {\r
923 FreePool (Search);\r
924 FreePool (Replace);\r
925 return Status;\r
926 }\r
927\r
928 Status = InputBarSetStringSize (1);\r
929 if (EFI_ERROR (Status)) {\r
930 FreePool (Search);\r
931 FreePool (Replace);\r
932 return Status;\r
933 }\r
934\r
935 Done = FALSE;\r
936 while (!Done) {\r
937 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
938 StatusBarSetRefresh();\r
939\r
940 //\r
941 // ESC pressed\r
942 //\r
943 if (Status == EFI_NOT_READY) {\r
944 FreePool (Search);\r
945 FreePool (Replace);\r
946 return EFI_SUCCESS;\r
947 }\r
948\r
949 switch (InputBarGetString()[0]) {\r
950 case L'y':\r
951 case L'Y':\r
952 Done = TRUE;\r
953 break;\r
954\r
955 case L'n':\r
956 case L'N':\r
957 FreePool (Search);\r
958 FreePool (Replace);\r
959 return EFI_SUCCESS;\r
960\r
961 }\r
962 //\r
963 // end of which\r
964 //\r
965 }\r
966 //\r
967 // end of while !Done\r
968 //\r
969 First = FALSE;\r
970\r
971 } while (1);\r
972 //\r
973 // end of do\r
974 //\r
975 FreePool (Search);\r
976 FreePool (Replace);\r
977\r
978 StatusBarSetStatusString (L"Search String Not Found");\r
979\r
980 return EFI_SUCCESS;\r
981}\r
982\r
983/**\r
984 exit editor\r
985\r
986 @retval EFI_SUCCESS The operation was successful.\r
987 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
988 @retval EFI_LOAD_ERROR A load error occured.\r
989**/\r
990EFI_STATUS\r
632820d1 991MainCommandExit (\r
992 VOID\r
993 )\r
994{\r
995 EFI_STATUS Status;\r
996\r
997 //\r
998 // Below is the scenario of Exit command:\r
999 // 1. IF currently opened file is not modified, exit the editor and\r
1000 // Exit command ends.\r
1001 // IF currently opened file is modified, do Step 2\r
1002 //\r
1003 // 2. An Input Bar will be prompted:\r
1004 // "File modified. Save ( Yes/No/Cancel )?"\r
1005 // IF user press 'y' or 'Y', currently opened file will be saved\r
1006 // and Editor exits\r
1007 // IF user press 'n' or 'N', currently opened file will not be saved\r
1008 // and Editor exits.\r
1009 // IF user press 'c' or 'C' or ESC, Exit command ends.\r
1010 // if file has been modified, so will prompt user whether to save the changes\r
1011 //\r
1012 if (MainEditor.FileBuffer->FileModified) {\r
1013\r
1014 Status = InputBarSetPrompt (L"File modified. Save (Yes/No/Cancel) ? ");\r
1015 if (EFI_ERROR (Status)) {\r
1016 return Status;\r
1017 }\r
1018\r
1019 Status = InputBarSetStringSize (1);\r
1020 if (EFI_ERROR (Status)) {\r
1021 return Status;\r
1022 }\r
1023\r
1024 while (1) {\r
1025 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
1026 StatusBarSetRefresh();\r
1027\r
1028 //\r
1029 // ESC pressed\r
1030 //\r
1031 if (Status == EFI_NOT_READY) {\r
1032 return EFI_SUCCESS;\r
1033 }\r
1034\r
1035 switch (InputBarGetString()[0]) {\r
1036 case L'y':\r
1037 case L'Y':\r
1038 //\r
1039 // write file back to disk\r
1040 //\r
1041 Status = FileBufferSave (MainEditor.FileBuffer->FileName);\r
1042 if (!EFI_ERROR (Status)) {\r
1043 EditorExit = TRUE;\r
1044 }\r
1045\r
1046 return Status;\r
1047\r
1048 case L'n':\r
1049 case L'N':\r
1050 EditorExit = TRUE;\r
1051 return EFI_SUCCESS;\r
1052\r
1053 case L'c':\r
1054 case L'C':\r
1055 return EFI_SUCCESS;\r
1056\r
1057 }\r
1058 }\r
1059 }\r
1060\r
1061 EditorExit = TRUE;\r
1062 return EFI_SUCCESS;\r
1063\r
1064}\r
1065\r
1066/**\r
1067 move cursor to specified lines\r
1068\r
1069 @retval EFI_SUCCESS The operation was successful.\r
1070**/\r
1071EFI_STATUS\r
632820d1 1072MainCommandGotoLine (\r
1073 VOID\r
1074 )\r
1075{\r
1076 EFI_STATUS Status;\r
1077 UINTN Row;\r
1078\r
1079 //\r
1080 // Below is the scenario of Go To Line command:\r
1081 // 1. An Input Bar will be prompted : "Go To Line:".\r
1082 // IF user press ESC, Go To Line command ends.\r
1083 // IF user just press Enter, cursor remains unchanged.\r
1084 // IF user inputs line number, do Step 2.\r
1085 //\r
1086 // 2. IF input line number is valid, move cursor to the beginning\r
1087 // of specified line and Go To Line command ends.\r
1088 // IF input line number is invalid, a Status String will be prompted:\r
1089 // "No Such Line" and Go To Line command ends.\r
1090 //\r
1091 Status = InputBarSetPrompt (L"Go To Line: ");\r
1092 if (EFI_ERROR (Status)) {\r
1093 return Status;\r
1094 }\r
1095 //\r
1096 // line number's digit <= 6\r
1097 //\r
1098 Status = InputBarSetStringSize (6);\r
1099 if (EFI_ERROR (Status)) {\r
1100 return Status;\r
1101 }\r
1102\r
1103 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
1104 StatusBarSetRefresh();\r
1105\r
1106 //\r
1107 // press ESC\r
1108 //\r
1109 if (Status == EFI_NOT_READY) {\r
1110 return EFI_SUCCESS;\r
1111 }\r
1112 //\r
1113 // if JUST press enter\r
1114 //\r
1115 if (StrLen (InputBarGetString()) == 0) {\r
1116 return EFI_SUCCESS;\r
1117 }\r
1118\r
1119 Row = ShellStrToUintn (InputBarGetString());\r
1120\r
1121 //\r
1122 // invalid line number\r
1123 //\r
1124 if (Row > MainEditor.FileBuffer->NumLines || Row <= 0) {\r
1125 StatusBarSetStatusString (L"No Such Line");\r
1126 return EFI_SUCCESS;\r
1127 }\r
1128 //\r
1129 // move cursor to that line's start\r
1130 //\r
1131 FileBufferMovePosition (Row, 1);\r
1132\r
1133 return EFI_SUCCESS;\r
1134}\r
1135\r
1136/**\r
1137 Save current file to disk, you can save to current file name or\r
1138 save to another file name.\r
1139 \r
1140 @retval EFI_SUCCESS The file was saved correctly.\r
1141 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
1142 @retval EFI_LOAD_ERROR A file access error occured.\r
1143**/\r
1144EFI_STATUS\r
632820d1 1145MainCommandSaveFile (\r
1146 VOID\r
1147 )\r
1148{\r
1149 EFI_STATUS Status;\r
1150 CHAR16 *FileName;\r
1151 BOOLEAN OldFile;\r
1152 CHAR16 *Str;\r
1153 SHELL_FILE_HANDLE FileHandle; \r
1154 EFI_FILE_INFO *Info;\r
1155\r
1156 //\r
1157 // This command will save currently opened file to disk.\r
1158 // You can choose save to another file name or just save to\r
1159 // current file name.\r
1160 // Below is the scenario of Save File command:\r
1161 // ( Suppose the old file name is A )\r
1162 // 1. An Input Bar will be prompted: "File To Save: [ old file name]"\r
1163 // IF user press ESC, Save File command ends .\r
1164 // IF user press Enter, input file name will be A.\r
1165 // IF user inputs a new file name B, input file name will be B.\r
1166 //\r
1167 // 2. IF input file name is A, go to do Step 3.\r
1168 // IF input file name is B, go to do Step 4.\r
1169 //\r
1170 // 3. IF A is read only, Status Bar will show "Access Denied" and\r
1171 // Save File commands ends.\r
1172 // IF A is not read only, save file buffer to disk and remove modified\r
1173 // flag in Title Bar , then Save File command ends.\r
1174 //\r
1175 // 4. IF B does not exist, create this file and save file buffer to it.\r
1176 // Go to do Step 7.\r
1177 // IF B exits, do Step 5.\r
1178 //\r
1179 // 5.An Input Bar will be prompted:\r
1180 // "File Exists. Overwrite ( Yes/No/Cancel )?"\r
1181 // IF user press 'y' or 'Y', do Step 6.\r
1182 // IF user press 'n' or 'N', Save File commands ends.\r
1183 // IF user press 'c' or 'C' or ESC, Save File commands ends.\r
1184 //\r
1185 // 6. IF B is a read-only file, Status Bar will show "Access Denied" and\r
1186 // Save File commands ends.\r
1187 // IF B can be read and write, save file buffer to B.\r
1188 //\r
1189 // 7. Update File Name field in Title Bar to B and remove the modified\r
1190 // flag in Title Bar.\r
1191 //\r
1192 Str = CatSPrint (NULL, L"File to Save: [%s]", MainEditor.FileBuffer->FileName);\r
1193 if (Str == NULL) {\r
1194 return EFI_OUT_OF_RESOURCES;\r
1195 }\r
1196\r
1197 if (StrLen (Str) >= 50) {\r
1198 //\r
1199 // replace the long file name with "..."\r
1200 //\r
1201 Str[46] = L'.';\r
1202 Str[47] = L'.';\r
1203 Str[48] = L'.';\r
1204 Str[49] = L']';\r
1205 Str[50] = CHAR_NULL;\r
1206 }\r
1207\r
1208 Status = InputBarSetPrompt (Str);\r
1209 FreePool(Str);\r
1210\r
1211 if (EFI_ERROR (Status)) {\r
1212 return Status;\r
1213 }\r
1214\r
1215\r
1216 Status = InputBarSetStringSize (100);\r
1217 if (EFI_ERROR (Status)) {\r
1218 return Status;\r
1219 }\r
1220 //\r
1221 // get new file name\r
1222 //\r
1223 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
1224 StatusBarSetRefresh();\r
1225\r
1226 //\r
1227 // if user pressed ESC\r
1228 //\r
1229 if (Status == EFI_NOT_READY) {\r
1230 return EFI_SUCCESS;\r
1231 }\r
1232\r
1233 //\r
1234 // if just enter pressed, so think save to current file name\r
1235 //\r
1236 if (StrLen (InputBarGetString()) == 0) {\r
1237 FileName = CatSPrint (NULL, L"%s", MainEditor.FileBuffer->FileName);\r
1238 } else {\r
1239 FileName = CatSPrint (NULL, L"%s", InputBarGetString());\r
1240 }\r
1241\r
1242 if (FileName == NULL) {\r
1243 return EFI_OUT_OF_RESOURCES;\r
1244 }\r
1245\r
1246 if (!IsValidFileName (FileName)) {\r
1247 StatusBarSetStatusString (L"Invalid File Name");\r
1248 FreePool (FileName);\r
1249 return EFI_SUCCESS;\r
1250 }\r
1251\r
1252 OldFile = FALSE;\r
1253\r
1254 //\r
1255 // save to the old file\r
1256 //\r
1257 if (StringNoCaseCompare (&FileName, &MainEditor.FileBuffer->FileName) == 0) {\r
1258 OldFile = TRUE;\r
1259 }\r
1260\r
1261 if (OldFile) {\r
1262 //\r
1263 // if the file is read only, so can not write back to it.\r
1264 //\r
1265 if (MainEditor.FileBuffer->ReadOnly == TRUE) {\r
1266 StatusBarSetStatusString (L"Access Denied");\r
1267 FreePool (FileName);\r
1268 return EFI_SUCCESS;\r
1269 }\r
1270 } else {\r
1271 //\r
1272 // if the file exists\r
1273 //\r
1274 if (ShellFileExists(FileName) != EFI_NOT_FOUND) {\r
1275 //\r
1276 // check for read only\r
1277 //\r
1278 Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0);\r
1279 if (EFI_ERROR(Status)) {\r
1280 StatusBarSetStatusString (L"Open Failed");\r
1281 FreePool (FileName);\r
1282 return EFI_SUCCESS;\r
1283 } \r
1284\r
1285 Info = ShellGetFileInfo(FileHandle);\r
1286 if (Info == NULL) {\r
1287 StatusBarSetStatusString (L"Access Denied");\r
1288 FreePool (FileName);\r
1289 return (EFI_SUCCESS);\r
1290 } \r
1291 \r
1292 if (Info->Attribute & EFI_FILE_READ_ONLY) {\r
1293 StatusBarSetStatusString (L"Access Denied - Read Only");\r
1294 FreePool (Info);\r
1295 FreePool (FileName);\r
1296 return (EFI_SUCCESS);\r
1297 }\r
1298 FreePool (Info);\r
1299\r
1300 //\r
1301 // ask user whether to overwrite this file\r
1302 //\r
1303 Status = InputBarSetPrompt (L"File exists. Overwrite (Yes/No/Cancel) ? ");\r
1304 if (EFI_ERROR (Status)) {\r
1305 SHELL_FREE_NON_NULL (FileName);\r
1306 return Status;\r
1307 }\r
1308\r
1309 Status = InputBarSetStringSize (1);\r
1310 if (EFI_ERROR (Status)) {\r
1311 SHELL_FREE_NON_NULL (FileName);\r
1312 return Status;\r
1313 }\r
1314\r
1315 while (TRUE) {\r
1316 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
1317 StatusBarSetRefresh();\r
1318\r
1319 //\r
1320 // ESC pressed\r
1321 //\r
1322 if (Status == EFI_NOT_READY) {\r
1323 SHELL_FREE_NON_NULL (FileName);\r
1324 return EFI_SUCCESS;\r
1325 }\r
1326\r
1327 switch (InputBarGetString()[0]) {\r
1328 case L'y':\r
1329 case L'Y':\r
1330 break;\r
1331\r
1332 case L'n':\r
1333 case L'N':\r
1334 case L'c':\r
1335 case L'C':\r
1336 SHELL_FREE_NON_NULL (FileName);\r
1337 return EFI_SUCCESS;\r
1338 } // end switch\r
1339 } // while (!done)\r
1340 } // file does exist\r
1341 } // if old file name same\r
1342\r
1343 //\r
1344 // save file to disk with specified name\r
1345 //\r
1346 FileBufferSetModified();\r
1347 Status = FileBufferSave (FileName);\r
1348 SHELL_FREE_NON_NULL (FileName);\r
1349\r
1350 return Status;\r
1351}\r
1352\r
5a2beb74 1353/**\r
feccc28a 1354 Show help information for the editor.\r
632820d1 1355\r
5a2beb74 1356 @retval EFI_SUCCESS The operation was successful.\r
1357**/\r
1358EFI_STATUS\r
1359MainCommandDisplayHelp (\r
1360 VOID\r
1361 )\r
1362{\r
feccc28a 1363 INT32 CurrentLine;\r
1364 CHAR16 *InfoString;\r
5563281f
RN
1365 EFI_KEY_DATA KeyData;\r
1366 EFI_STATUS Status;\r
1367 UINTN EventIndex;\r
5a2beb74 1368 \r
feccc28a 1369 //\r
5a2beb74 1370 // print helpInfo \r
feccc28a 1371 //\r
5a2beb74 1372 for (CurrentLine = 0; 0 != MainMenuHelpInfo[CurrentLine]; CurrentLine++) {\r
1373 InfoString = HiiGetString(gShellDebug1HiiHandle, MainMenuHelpInfo[CurrentLine], NULL);\r
feccc28a 1374 ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString); \r
5a2beb74 1375 }\r
5563281f 1376\r
feccc28a 1377 //\r
5a2beb74 1378 // scan for ctrl+w\r
feccc28a 1379 //\r
5563281f
RN
1380 while (TRUE) {\r
1381 Status = gBS->WaitForEvent (1, &MainEditor.TextInputEx->WaitForKeyEx, &EventIndex);\r
1382 if (EFI_ERROR (Status) || (EventIndex != 0)) {\r
1383 continue;\r
1384 }\r
1385 Status = MainEditor.TextInputEx->ReadKeyStrokeEx (MainEditor.TextInputEx, &KeyData);\r
1386 if (EFI_ERROR (Status)) {\r
1387 continue;\r
1388 }\r
632820d1 1389\r
5563281f
RN
1390 if ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) {\r
1391 //\r
1392 // For consoles that don't support shift state reporting,\r
1393 // CTRL+W is translated to L'W' - L'A' + 1.\r
1394 //\r
1395 if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) {\r
1396 break;\r
1397 }\r
1398 } else if (((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) &&\r
1399 ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) {\r
1400 //\r
1401 // For consoles that supports shift state reporting,\r
1402 // make sure that only CONTROL shift key is pressed.\r
1403 //\r
1404 if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) {\r
1405 break;\r
1406 }\r
1407 }\r
1408 }\r
feccc28a 1409 //\r
5a2beb74 1410 // update screen with file buffer's info\r
feccc28a 1411 //\r
5a2beb74 1412 FileBufferRestorePosition ();\r
1413 FileBufferNeedRefresh = TRUE;\r
1414 FileBufferOnlyLineNeedRefresh = FALSE;\r
1415 FileBufferRefresh (); \r
632820d1 1416\r
5a2beb74 1417 return EFI_SUCCESS;\r
1418}\r
632820d1 1419\r
5a2beb74 1420EFI_EDITOR_COLOR_ATTRIBUTES OriginalColors;\r
1421INTN OriginalMode;\r
632820d1 1422\r
632820d1 1423\r
1424//\r
1425// basic initialization for MainEditor\r
1426//\r
1427EFI_EDITOR_GLOBAL_EDITOR MainEditorConst = {\r
1428 &FileBuffer,\r
1429 {\r
ce68d3bc 1430 {0, 0}\r
632820d1 1431 },\r
1432 {\r
1433 0,\r
1434 0\r
1435 },\r
1436 NULL,\r
5563281f 1437 NULL,\r
632820d1 1438 FALSE,\r
1439 NULL\r
1440};\r
1441\r
1442/**\r
1443 The initialization function for MainEditor.\r
1444\r
1445 @retval EFI_SUCCESS The operation was successful.\r
1446 @retval EFI_LOAD_ERROR A load error occured.\r
1447**/\r
1448EFI_STATUS\r
632820d1 1449MainEditorInit (\r
1450 VOID\r
1451 )\r
1452{\r
1453 EFI_STATUS Status;\r
1454 EFI_HANDLE *HandleBuffer;\r
1455 UINTN HandleCount;\r
1456 UINTN Index;\r
1457\r
1458 //\r
1459 // basic initialization\r
1460 //\r
1461 CopyMem (&MainEditor, &MainEditorConst, sizeof (MainEditor));\r
1462\r
1463 //\r
1464 // set screen attributes\r
1465 //\r
1466 MainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff;\r
1467\r
1468 MainEditor.ColorAttributes.Colors.Background = (UINT8) (gST->ConOut->Mode->Attribute >> 4);\r
1469 OriginalColors = MainEditor.ColorAttributes.Colors;\r
1470\r
1471 OriginalMode = gST->ConOut->Mode->Mode;\r
1472\r
1473 //\r
1474 // query screen size\r
1475 //\r
1476 gST->ConOut->QueryMode (\r
1477 gST->ConOut,\r
1478 gST->ConOut->Mode->Mode,\r
1479 &(MainEditor.ScreenSize.Column),\r
1480 &(MainEditor.ScreenSize.Row)\r
1481 );\r
1482\r
5563281f
RN
1483 //\r
1484 // Find TextInEx in System Table ConsoleInHandle\r
1485 // Per UEFI Spec, TextInEx is required for a console capable platform.\r
1486 //\r
1487 Status = gBS->HandleProtocol (\r
1488 gST->ConsoleInHandle,\r
1489 &gEfiSimpleTextInputExProtocolGuid,\r
1490 (VOID**)&MainEditor.TextInputEx\r
1491 );\r
1492 if (EFI_ERROR (Status)) {\r
1493 return Status;\r
1494 }\r
1495\r
632820d1 1496 //\r
1497 // Find mouse in System Table ConsoleInHandle\r
1498 //\r
1499 Status = gBS->HandleProtocol (\r
1500 gST->ConIn,\r
1501 &gEfiSimplePointerProtocolGuid,\r
1502 (VOID**)&MainEditor.MouseInterface\r
1503 );\r
1504 if (EFI_ERROR (Status)) {\r
1505 //\r
1506 // If there is no Simple Pointer Protocol on System Table\r
1507 //\r
1508 HandleBuffer = NULL;\r
1509 MainEditor.MouseInterface = NULL;\r
1510 Status = gBS->LocateHandleBuffer (\r
1511 ByProtocol,\r
1512 &gEfiSimplePointerProtocolGuid,\r
1513 NULL,\r
1514 &HandleCount,\r
1515 &HandleBuffer\r
1516 );\r
1517 if (!EFI_ERROR (Status) && HandleCount > 0) {\r
1518 //\r
1519 // Try to find the first available mouse device\r
1520 //\r
1521 for (Index = 0; Index < HandleCount; Index++) {\r
1522 Status = gBS->HandleProtocol (\r
1523 HandleBuffer[Index],\r
1524 &gEfiSimplePointerProtocolGuid,\r
1525 (VOID**)&MainEditor.MouseInterface\r
1526 );\r
1527 if (!EFI_ERROR (Status)) {\r
1528 break;\r
1529 }\r
1530 }\r
1531 }\r
1532 if (HandleBuffer != NULL) {\r
1533 FreePool (HandleBuffer);\r
1534 }\r
1535 }\r
1536\r
1537 if (!EFI_ERROR (Status) && MainEditor.MouseInterface != NULL) {\r
1538 MainEditor.MouseAccumulatorX = 0;\r
1539 MainEditor.MouseAccumulatorY = 0;\r
1540 MainEditor.MouseSupported = TRUE;\r
1541 }\r
1542\r
1543 //\r
1544 // below will call the five components' init function\r
1545 //\r
caa6c0cc 1546 Status = MainTitleBarInit (L"UEFI EDIT");\r
632820d1 1547 if (EFI_ERROR (Status)) {\r
1548 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_TITLEBAR), gShellDebug1HiiHandle);\r
1549 return EFI_LOAD_ERROR;\r
1550 }\r
1551\r
5a2beb74 1552 Status = ControlHotKeyInit (MainControlBasedMenuFunctions);\r
632820d1 1553 Status = MenuBarInit (MainMenuItems);\r
1554 if (EFI_ERROR (Status)) {\r
1555 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_MAINMENU), gShellDebug1HiiHandle);\r
1556 return EFI_LOAD_ERROR;\r
1557 }\r
1558\r
1559 Status = StatusBarInit ();\r
1560 if (EFI_ERROR (Status)) {\r
1561 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_STATUSBAR), gShellDebug1HiiHandle);\r
1562 return EFI_LOAD_ERROR;\r
1563 }\r
1564\r
5563281f 1565 InputBarInit (MainEditor.TextInputEx);\r
632820d1 1566\r
1567 Status = FileBufferInit ();\r
1568 if (EFI_ERROR (Status)) {\r
1569 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_FILEBUFFER), gShellDebug1HiiHandle);\r
1570 return EFI_LOAD_ERROR;\r
1571 }\r
1572 //\r
1573 // clear whole screen and enable cursor\r
1574 //\r
1575 gST->ConOut->ClearScreen (gST->ConOut);\r
1576 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
1577\r
1578 //\r
1579 // initialize EditorFirst and EditorExit\r
1580 //\r
1581 EditorFirst = TRUE;\r
1582 EditorExit = FALSE;\r
1583 EditorMouseAction = FALSE;\r
1584\r
1585 return EFI_SUCCESS;\r
1586}\r
1587\r
1588/**\r
1589 The cleanup function for MainEditor.\r
1590\r
1591 @retval EFI_SUCCESS The operation was successful.\r
1592 @retval EFI_LOAD_ERROR A load error occured.\r
1593**/\r
1594EFI_STATUS\r
632820d1 1595MainEditorCleanup (\r
1596 VOID\r
1597 )\r
1598{\r
1599 EFI_STATUS Status;\r
1600\r
1601 //\r
1602 // call the five components' cleanup function\r
1603 // if error, do not exit\r
1604 // just print some warning\r
1605 //\r
1606 MainTitleBarCleanup();\r
1607 StatusBarCleanup();\r
1608 InputBarCleanup();\r
1609 MenuBarCleanup ();\r
1610\r
1611 Status = FileBufferCleanup ();\r
1612 if (EFI_ERROR (Status)) {\r
1613 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_FILEBUFFER_CLEANUP), gShellDebug1HiiHandle);\r
1614 }\r
1615 //\r
1616 // restore old mode\r
1617 //\r
1618 if (OriginalMode != gST->ConOut->Mode->Mode) {\r
1619 gST->ConOut->SetMode (gST->ConOut, OriginalMode);\r
1620 }\r
1621 //\r
1622 // restore old screen color\r
1623 //\r
1624 gST->ConOut->SetAttribute (\r
1625 gST->ConOut,\r
1626 EFI_TEXT_ATTR (OriginalColors.Foreground, OriginalColors.Background)\r
1627 );\r
1628\r
1629 gST->ConOut->ClearScreen (gST->ConOut);\r
1630\r
1631 return EFI_SUCCESS;\r
1632}\r
1633\r
1634/**\r
1635 Refresh the main editor component.\r
1636**/\r
1637VOID\r
632820d1 1638MainEditorRefresh (\r
1639 VOID\r
1640 )\r
1641{\r
1642 //\r
1643 // The Stall value is from experience. NOT from spec. avoids 'flicker'\r
1644 //\r
1645 gBS->Stall (50);\r
1646\r
1647 //\r
1648 // call the components refresh function\r
1649 //\r
1650 if (EditorFirst \r
1651 || StrCmp (FileBufferBackupVar.FileName, FileBuffer.FileName) != 0 \r
1652 || FileBufferBackupVar.FileType != FileBuffer.FileType \r
1653 || FileBufferBackupVar.FileModified != FileBuffer.FileModified \r
1654 || FileBufferBackupVar.ReadOnly != FileBuffer.ReadOnly) {\r
1655\r
980d554e 1656 MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0);\r
632820d1 1657 FileBufferRestorePosition ();\r
632820d1 1658 }\r
fb9dd832 1659\r
632820d1 1660 if (EditorFirst\r
1661 || FileBufferBackupVar.FilePosition.Row != FileBuffer.FilePosition.Row \r
1662 || FileBufferBackupVar.FilePosition.Column != FileBuffer.FilePosition.Column \r
1663 || FileBufferBackupVar.ModeInsert != FileBuffer.ModeInsert\r
1664 || StatusBarGetRefresh()) {\r
1665\r
1666 StatusBarRefresh (EditorFirst, MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column, MainEditor.FileBuffer->FilePosition.Row, MainEditor.FileBuffer->FilePosition.Column, MainEditor.FileBuffer->ModeInsert);\r
1667 FileBufferRestorePosition ();\r
632820d1 1668 }\r
1669\r
1670 if (EditorFirst) {\r
632820d1 1671 FileBufferRestorePosition ();\r
1672 }\r
1673\r
fb9dd832
QS
1674 FileBufferRefresh ();\r
1675\r
632820d1 1676 //\r
1677 // EditorFirst is now set to FALSE\r
1678 //\r
1679 EditorFirst = FALSE;\r
1680}\r
1681\r
1682/**\r
1683 Get's the resultant location of the cursor based on the relative movement of the Mouse.\r
1684\r
1685 @param[in] GuidX The relative mouse movement.\r
1686\r
1687 @return The X location of the mouse.\r
1688**/\r
1689INT32\r
632820d1 1690GetTextX (\r
1691 IN INT32 GuidX\r
1692 )\r
1693{\r
1694 INT32 Gap;\r
1695\r
1696 MainEditor.MouseAccumulatorX += GuidX;\r
1697 Gap = (MainEditor.MouseAccumulatorX * (INT32) MainEditor.ScreenSize.Column) / (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionX);\r
1698 MainEditor.MouseAccumulatorX = (MainEditor.MouseAccumulatorX * (INT32) MainEditor.ScreenSize.Column) % (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionX);\r
1699 MainEditor.MouseAccumulatorX = MainEditor.MouseAccumulatorX / (INT32) MainEditor.ScreenSize.Column;\r
1700 return Gap;\r
1701}\r
1702\r
1703/**\r
1704 Get's the resultant location of the cursor based on the relative movement of the Mouse.\r
1705\r
1706 @param[in] GuidY The relative mouse movement.\r
1707\r
1708 @return The Y location of the mouse.\r
1709**/\r
1710INT32\r
632820d1 1711GetTextY (\r
1712 IN INT32 GuidY\r
1713 )\r
1714{\r
1715 INT32 Gap;\r
1716\r
1717 MainEditor.MouseAccumulatorY += GuidY;\r
1718 Gap = (MainEditor.MouseAccumulatorY * (INT32) MainEditor.ScreenSize.Row) / (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionY);\r
1719 MainEditor.MouseAccumulatorY = (MainEditor.MouseAccumulatorY * (INT32) MainEditor.ScreenSize.Row) % (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionY);\r
1720 MainEditor.MouseAccumulatorY = MainEditor.MouseAccumulatorY / (INT32) MainEditor.ScreenSize.Row;\r
1721\r
1722 return Gap;\r
1723}\r
1724\r
1725/**\r
1726 Support mouse movement. Move the cursor.\r
1727\r
664fd587 1728 @param[in] MouseState The current mouse state.\r
632820d1 1729\r
1730 @retval EFI_SUCCESS The operation was successful.\r
1731 @retval EFI_NOT_FOUND There was no mouse support found.\r
1732**/\r
632820d1 1733EFI_STATUS\r
632820d1 1734MainEditorHandleMouseInput (\r
664fd587 1735 IN EFI_SIMPLE_POINTER_STATE MouseState\r
632820d1 1736 )\r
1737{\r
1738\r
1739 INT32 TextX;\r
1740 INT32 TextY;\r
1741 UINTN FRow;\r
1742 UINTN FCol;\r
664fd587
RN
1743\r
1744 LIST_ENTRY *Link;\r
632820d1 1745 EFI_EDITOR_LINE *Line;\r
664fd587 1746\r
632820d1 1747 UINTN Index;\r
1748 BOOLEAN Action;\r
1749\r
1750 //\r
1751 // mouse action means:\r
1752 // mouse movement\r
1753 // mouse left button\r
1754 //\r
1755 Action = FALSE;\r
1756\r
1757 //\r
1758 // have mouse movement\r
1759 //\r
1760 if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {\r
1761 //\r
1762 // handle\r
1763 //\r
1764 TextX = GetTextX (MouseState.RelativeMovementX);\r
1765 TextY = GetTextY (MouseState.RelativeMovementY);\r
1766\r
1767 FileBufferAdjustMousePosition (TextX, TextY);\r
1768\r
1769 Action = TRUE;\r
1770\r
1771 }\r
1772\r
1773 //\r
1774 // if left button pushed down\r
1775 //\r
1776 if (MouseState.LeftButton) {\r
1777\r
1778 FCol = MainEditor.FileBuffer->MousePosition.Column - 1 + 1;\r
1779\r
1780 FRow = MainEditor.FileBuffer->FilePosition.Row +\r
1781 MainEditor.FileBuffer->MousePosition.Row -\r
1782 MainEditor.FileBuffer->DisplayPosition.Row;\r
1783\r
1784 //\r
1785 // beyond the file line length\r
1786 //\r
1787 if (MainEditor.FileBuffer->NumLines < FRow) {\r
1788 FRow = MainEditor.FileBuffer->NumLines;\r
1789 }\r
1790\r
1791 Link = MainEditor.FileBuffer->ListHead->ForwardLink;\r
1792 for (Index = 0; Index < FRow - 1; Index++) {\r
1793 Link = Link->ForwardLink;\r
1794 }\r
1795\r
1796 Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);\r
1797\r
1798 //\r
1799 // beyond the line's column length\r
1800 //\r
664fd587
RN
1801 if (FCol > Line->Size + 1) {\r
1802 FCol = Line->Size + 1;\r
632820d1 1803 }\r
1804\r
1805 FileBufferMovePosition (FRow, FCol);\r
1806\r
1807 MainEditor.FileBuffer->MousePosition.Row = MainEditor.FileBuffer->DisplayPosition.Row;\r
1808\r
1809 MainEditor.FileBuffer->MousePosition.Column = MainEditor.FileBuffer->DisplayPosition.Column;\r
1810\r
1811 Action = TRUE;\r
1812 }\r
1813 //\r
1814 // mouse has action\r
1815 //\r
1816 if (Action) {\r
1817 return EFI_SUCCESS;\r
1818 }\r
1819\r
1820 //\r
1821 // no mouse action\r
1822 //\r
1823 return EFI_NOT_FOUND;\r
1824}\r
1825\r
1826/**\r
1827 Handle user key input. This routes to other functions for the actions.\r
1828\r
1829 @retval EFI_SUCCESS The operation was successful.\r
1830 @retval EFI_LOAD_ERROR A load error occured.\r
1831 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
1832**/\r
1833EFI_STATUS\r
632820d1 1834MainEditorKeyInput (\r
1835 VOID\r
1836 )\r
1837{\r
5563281f 1838 EFI_KEY_DATA KeyData;\r
632820d1 1839 EFI_STATUS Status;\r
1840 EFI_SIMPLE_POINTER_STATE MouseState;\r
5563281f
RN
1841 UINTN EventIndex;\r
1842 BOOLEAN NoShiftState;\r
632820d1 1843\r
1844 do {\r
1845\r
1846 Status = EFI_SUCCESS;\r
1847 EditorMouseAction = FALSE;\r
1848\r
1849 //\r
1850 // backup some key elements, so that can aVOID some refresh work\r
1851 //\r
1852 MainEditorBackup ();\r
1853\r
1854 //\r
1855 // change priority of checking mouse/keyboard activity dynamically\r
1856 // so prevent starvation of keyboard.\r
1857 // if last time, mouse moves then this time check keyboard\r
1858 //\r
1859 if (MainEditor.MouseSupported) {\r
1860 Status = MainEditor.MouseInterface->GetState (\r
1861 MainEditor.MouseInterface,\r
1862 &MouseState\r
1863 );\r
1864 if (!EFI_ERROR (Status)) {\r
1865\r
664fd587 1866 Status = MainEditorHandleMouseInput (MouseState);\r
632820d1 1867\r
1868 if (!EFI_ERROR (Status)) {\r
1869 EditorMouseAction = TRUE;\r
1870 FileBufferMouseNeedRefresh = TRUE;\r
1871 } else if (Status == EFI_LOAD_ERROR) {\r
1872 StatusBarSetStatusString (L"Invalid Mouse Movement ");\r
1873 }\r
1874 }\r
1875 }\r
1876\r
5563281f
RN
1877 Status = gBS->WaitForEvent (1, &MainEditor.TextInputEx->WaitForKeyEx, &EventIndex);\r
1878 if (!EFI_ERROR (Status) && EventIndex == 0) {\r
1879 Status = MainEditor.TextInputEx->ReadKeyStrokeEx (MainEditor.TextInputEx, &KeyData);\r
1880 if (!EFI_ERROR (Status)) {\r
1881 //\r
1882 // dispatch to different components' key handling function\r
1883 // so not everywhere has to set this variable\r
1884 //\r
1885 FileBufferMouseNeedRefresh = TRUE;\r
632820d1 1886 //\r
5563281f 1887 // clear previous status string\r
632820d1 1888 //\r
5563281f
RN
1889 StatusBarSetRefresh();\r
1890 //\r
1891 // NoShiftState: TRUE when no shift key is pressed.\r
1892 //\r
1893 NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID);\r
1894 //\r
1895 // dispatch to different components' key handling function\r
1896 //\r
1897 if (EFI_NOT_FOUND != MenuBarDispatchControlHotKey(&KeyData)) {\r
1898 Status = EFI_SUCCESS;\r
1899 } else if (NoShiftState && ((KeyData.Key.ScanCode == SCAN_NULL) || ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN)))) {\r
1900 Status = FileBufferHandleInput (&KeyData.Key);\r
1901 } else if (NoShiftState && (KeyData.Key.ScanCode >= SCAN_F1) && (KeyData.Key.ScanCode <= SCAN_F12)) {\r
1902 Status = MenuBarDispatchFunctionKey (&KeyData.Key);\r
1903 } else {\r
1904 StatusBarSetStatusString (L"Unknown Command");\r
1905 FileBufferMouseNeedRefresh = FALSE; \r
1906 }\r
1907 \r
1908 if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {\r
1909 //\r
1910 // not already has some error status\r
1911 //\r
1912 if (StatusBarGetString() != NULL && StrCmp (L"", StatusBarGetString()) == 0) {\r
1913 StatusBarSetStatusString (L"Disk Error. Try Again");\r
1914 }\r
632820d1 1915 }\r
632820d1 1916\r
5563281f
RN
1917 }\r
1918 //\r
1919 // after handling, refresh editor\r
1920 //\r
1921 MainEditorRefresh ();\r
632820d1 1922 }\r
632820d1 1923\r
1924 } while (Status != EFI_OUT_OF_RESOURCES && !EditorExit);\r
1925\r
1926 return Status;\r
1927}\r
1928\r
1929/**\r
1930 Set clipboard\r
1931\r
1932 @param[in] Line A pointer to the line to be set to clipboard\r
1933\r
1934 @retval EFI_SUCCESS The operation was successful.\r
1935 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
1936**/\r
1937EFI_STATUS\r
632820d1 1938MainEditorSetCutLine (\r
1939 EFI_EDITOR_LINE *Line\r
1940 )\r
1941{\r
1942 if (Line == NULL) {\r
1943 return EFI_SUCCESS;\r
1944 }\r
1945\r
1946 if (MainEditor.CutLine != NULL) {\r
1947 //\r
1948 // free the old clipboard\r
1949 //\r
1950 LineFree (MainEditor.CutLine);\r
1951 }\r
1952 //\r
1953 // duplicate the line to clipboard\r
1954 //\r
1955 MainEditor.CutLine = LineDup (Line);\r
1956 if (MainEditor.CutLine == NULL) {\r
1957 return EFI_OUT_OF_RESOURCES;\r
1958 }\r
1959\r
1960 return EFI_SUCCESS;\r
1961}\r
1962\r
1963/**\r
1964 Backup function for MainEditor\r
1965\r
1966 @retval EFI_SUCCESS The operation was successful.\r
1967**/\r
1968EFI_STATUS\r
632820d1 1969MainEditorBackup (\r
1970 VOID\r
1971 )\r
1972{\r
1973 FileBufferBackup ();\r
1974 \r
1975 return EFI_SUCCESS;\r
1976}\r