1 ------------------------------------------------------------------------------
3 -- GNAT ncurses Binding Samples --
5 -- Sample.Explanation --
9 ------------------------------------------------------------------------------
10 -- Copyright (c) 1998-2011,2014 Free Software Foundation, Inc. --
12 -- Permission is hereby granted, free of charge, to any person obtaining a --
13 -- copy of this software and associated documentation files (the --
14 -- "Software"), to deal in the Software without restriction, including --
15 -- without limitation the rights to use, copy, modify, merge, publish, --
16 -- distribute, distribute with modifications, sublicense, and/or sell --
17 -- copies of the Software, and to permit persons to whom the Software is --
18 -- furnished to do so, subject to the following conditions: --
20 -- The above copyright notice and this permission notice shall be included --
21 -- in all copies or substantial portions of the Software. --
23 -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS --
24 -- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF --
25 -- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. --
26 -- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, --
27 -- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR --
28 -- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR --
29 -- THE USE OR OTHER DEALINGS IN THE SOFTWARE. --
31 -- Except as contained in this notice, the name(s) of the above copyright --
32 -- holders shall not be used in advertising or otherwise to promote the --
33 -- sale, use or other dealings in this Software without prior written --
35 ------------------------------------------------------------------------------
36 -- Author: Juergen Pfeifer, 1996
39 -- $Date: 2014/09/13 19:10:18 $
40 -- Binding Version 01.00
41 ------------------------------------------------------------------------------
42 -- Poor mans help system. This scans a sequential file for key lines and
43 -- then reads the lines up to the next key. Those lines are presented in
44 -- a window as help or explanation.
46 with Ada
.Text_IO
; use Ada
.Text_IO
;
47 with Ada
.Unchecked_Deallocation
;
48 with Terminal_Interface
.Curses
; use Terminal_Interface
.Curses
;
49 with Terminal_Interface
.Curses
.Panels
; use Terminal_Interface
.Curses
.Panels
;
51 with Sample
.Keyboard_Handler
; use Sample
.Keyboard_Handler
;
52 with Sample
.Manifest
; use Sample
.Manifest
;
53 with Sample
.Function_Key_Setting
; use Sample
.Function_Key_Setting
;
54 with Sample
.Helpers
; use Sample
.Helpers
;
56 package body Sample
.Explanation
is
58 Help_Keys
: constant String := "HELPKEYS";
59 In_Help
: constant String := "INHELP";
61 File_Name
: constant String := "explain.txt";
65 type Help_Line_Access
is access Help_Line
;
66 pragma Controlled
(Help_Line_Access
);
67 type String_Access
is access String;
68 pragma Controlled
(String_Access
);
72 Prev
, Next
: Help_Line_Access
;
76 procedure Explain
(Key
: String;
79 procedure Release_String
is
80 new Ada
.Unchecked_Deallocation
(String,
82 procedure Release_Help_Line
is
83 new Ada
.Unchecked_Deallocation
(Help_Line
,
86 function Search
(Key
: String) return Help_Line_Access
;
87 procedure Release_Help
(Root
: in out Help_Line_Access
);
89 function Check_File
(Name
: String) return Boolean;
91 procedure Explain
(Key
: String)
94 Explain
(Key
, Null_Window
);
97 procedure Explain
(Key
: String;
100 -- Retrieve the text associated with this key and display it in this
101 -- window. If no window argument is passed, the routine will create
102 -- a temporary window and use it.
104 function Filter_Key
return Real_Key_Code
;
105 procedure Unknown_Key
;
107 procedure To_Window
(C
: in out Help_Line_Access
;
108 More
: in out Boolean);
110 Frame
: Window
:= Null_Window
;
117 Width
: Column_Count
;
118 Help
: Help_Line_Access
:= Search
(Key
);
119 Current
: Help_Line_Access
;
120 Top_Line
: Help_Line_Access
;
122 Has_More
: Boolean := True;
124 procedure Unknown_Key
127 Add
(W
, "Help message with ID ");
129 Add
(W
, " not found.");
130 Add
(W
, Character'Val (10));
131 Add
(W
, "Press the Function key labeled 'Quit' key to continue.");
136 H
: Help_Line_Access
:= Top_Line
;
138 if Top_Line
/= null then
139 for L
in 0 .. (Height
- 1) loop
140 Add
(W
, L
, 0, H
.all.Line
.all);
141 exit when H
.all.Next
= null;
149 function Filter_Key
return Real_Key_Code
155 if K
in Special_Key_Code
'Range then
158 if not Find_Context
(In_Help
) then
159 Push_Environment
(In_Help
, False);
160 Explain
(In_Help
, W
);
165 if not Find_Context
(Help_Keys
) then
166 Push_Environment
(Help_Keys
, False);
167 Explain
(Help_Keys
, W
);
180 procedure To_Window
(C
: in out Help_Line_Access
;
181 More
: in out Boolean)
183 L
: Line_Position
:= 0;
186 Add
(W
, L
, 0, C
.all.Line
.all);
188 exit when C
.all.Next
= null or else L
= Height
;
191 if C
.all.Next
/= null then
192 pragma Assert
(L
= Height
);
200 if W
= Null_Window
then
201 Push_Environment
("HELP");
203 Frame
:= New_Window
(Lines
- 2, Columns
, 0, 0);
205 Set_Background
(Win
=> Frame
,
208 Attr
=> Normal_Video
));
209 Set_Character_Attributes
(Win
=> Frame
,
210 Attr
=> Normal_Video
,
211 Color
=> Help_Color
);
215 Set_Character_Attributes
(Frame
, (Reverse_Video
=> True,
217 Add
(Frame
, Lines
- 3, 2, "Cursor Up/Down scrolls");
218 Set_Character_Attributes
(Frame
); -- Back to default.
219 Window_Title
(Frame
, "Explanation");
220 W
:= Derived_Window
(Frame
, Lines
- 4, Columns
- 2, 1, 1);
221 Refresh_Without_Update
(Frame
);
222 Get_Size
(W
, Height
, Width
);
225 Allow_Scrolling
(W
, True);
226 Set_Echo_Mode
(False);
232 Refresh_Without_Update
(W
);
235 Current
:= Help
; Top_Line
:= Help
;
241 exit when K
= QUIT_CODE
;
244 To_Window
(Current
, Has_More
);
246 -- This means there are more lines available, so we have to go
247 -- into a scroll manager.
250 if K
in Special_Key_Code
'Range then
252 when Key_Cursor_Down
=>
253 if Current
.all.Next
/= null then
254 Move_Cursor
(W
, Height
- 1, 0);
256 Current
:= Current
.all.Next
;
257 Top_Line
:= Top_Line
.all.Next
;
258 Add
(W
, Current
.all.Line
.all);
260 when Key_Cursor_Up
=>
261 if Top_Line
.all.Prev
/= null then
262 Move_Cursor
(W
, 0, 0);
264 Top_Line
:= Top_Line
.all.Prev
;
265 Current
:= Current
.all.Prev
;
266 Add
(W
, Top_Line
.all.Line
.all);
268 when QUIT_CODE
=> exit;
276 exit when K
= QUIT_CODE
;
283 if Frame
/= Null_Window
then
298 function Search
(Key
: String) return Help_Line_Access
301 Buffer
: String (1 .. 256);
302 Root
: Help_Line_Access
:= null;
303 Current
: Help_Line_Access
;
304 Tail
: Help_Line_Access
:= null;
306 function Next_Line
return Boolean;
308 function Next_Line
return Boolean
310 H_End
: constant String := "#END";
312 Get_Line
(F
, Buffer
, Last
);
313 if Last
= H_End
'Length and then H_End
= Buffer
(1 .. Last
) then
323 exit Outer
when not Next_Line
;
324 if Last
= (1 + Key
'Length)
325 and then Key
= Buffer
(2 .. Last
)
326 and then Buffer
(1) = '#'
329 exit when not Next_Line
;
330 exit when Buffer
(1) = '#';
331 Current
:= new Help_Line
'(null, null,
332 new String'(Buffer
(1 .. Last
)));
337 Tail
.all.Next
:= Current
;
338 Current
.all.Prev
:= Tail
;
348 procedure Release_Help
(Root
: in out Help_Line_Access
)
350 Next
: Help_Line_Access
;
353 exit when Root
= null;
354 Next
:= Root
.all.Next
;
355 Release_String
(Root
.all.Line
);
356 Release_Help_Line
(Root
);
361 procedure Explain_Context
367 procedure Notepad
(Key
: String)
369 H
: constant Help_Line_Access
:= Search
(Key
);
370 T
: Help_Line_Access
:= H
;
372 L
: Line_Position
:= 0;
382 W
:= New_Window
(N
+ 2, Columns
, Lines
- N
- 2, 0);
384 Set_Background
(Win
=> W
,
386 Color
=> Notepad_Color
,
387 Attr
=> Normal_Video
));
388 Set_Character_Attributes
(Win
=> W
,
389 Attr
=> Normal_Video
,
390 Color
=> Notepad_Color
);
394 Window_Title
(W
, "Notepad");
398 Add
(W
, L
+ 1, 1, T
.all.Line
.all, Integer (Columns
- 2));
405 Refresh_Without_Update
(W
);
406 Notepad_To_Context
(P
);
410 function Check_File
(Name
: String) return Boolean is
411 The_File
: File_Type
;
413 Open
(The_File
, In_File
, Name
);
422 if Check_File
("/usr/share/AdaCurses/" & File_Name
) then
423 Open
(F
, In_File
, "/usr/share/AdaCurses/" & File_Name
);
424 elsif Check_File
(File_Name
) then
425 Open
(F
, In_File
, File_Name
);
427 Put_Line
(Standard_Error
,
428 "The file explain.txt was not found in the current directory."
432 end Sample
.Explanation
;