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