aboutsummaryrefslogtreecommitdiffstats
path: root/lib/toolbar/src/toolbar_toolconfig.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/toolbar/src/toolbar_toolconfig.erl')
-rw-r--r--lib/toolbar/src/toolbar_toolconfig.erl544
1 files changed, 544 insertions, 0 deletions
diff --git a/lib/toolbar/src/toolbar_toolconfig.erl b/lib/toolbar/src/toolbar_toolconfig.erl
new file mode 100644
index 0000000000..7d8f2b4d21
--- /dev/null
+++ b/lib/toolbar/src/toolbar_toolconfig.erl
@@ -0,0 +1,544 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(toolbar_toolconfig).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Erlang Toolbar
+%
+%%% Description %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Tool configuration tool, edit and creates .tool files
+% This tool works separately from the toolbar.
+%
+%%% External data types %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% toolinfo() -- Tool configuration information
+-include("toolbar.hrl").
+%
+%%% Internal data types %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% tfwindow() -- Toolfile configuration window
+-record(tfwindow,
+ {window,
+ fileentry,
+ toolentry,moduleentry,functionentry,
+ iconentry,messageentry,htmlentry,
+ label}).
+%
+%%% Exports %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+-export([start/0]).
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-export([init/0]). % spawn
+
+
+%%% Exported functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%----------------------------------------
+% start() => pid()
+%----------------------------------------
+start() ->
+ spawn(toolbar_toolconfig,init,[]).
+
+
+%%% Internal functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%=============================================================================
+% Main loop
+%=============================================================================
+
+%----------------------------------------
+% init()
+%----------------------------------------
+init() ->
+
+ %% Start GS (or get the pid if it is already running)
+ S = gs:start(),
+
+ %% Draw the window
+ Window = draw_window(S),
+
+ loop(S,Window).
+
+%----------------------------------------
+% loop(S,Window)
+% S - pid() GS
+% Window - tfwindow()
+%----------------------------------------
+loop(S,Window) ->
+ receive
+
+ %% 'Return' pressed in the 'File' entry
+ {gs,_Obj,keypress,file,['Return'|_]} ->
+
+ %% Check if a file name is specified
+ case string:strip(gs:read(Window#tfwindow.fileentry,text)) of
+
+ %% No file name specified, move focus to next entry
+ "" ->
+ move_focus(Window,file);
+
+ %% A name is specified
+ String ->
+
+ %% Add a .tool suffix to the file name if necessary
+ FileName = tool_file(String),
+
+ %% Write the complete file name to the file entry
+ gs:config(Window#tfwindow.fileentry,{text,FileName}),
+
+ %% Try to open the file
+ case file:consult(FileName) of
+
+ %% File exists and seems ok
+ {ok,[{version,Vsn},T]} ->
+
+ %% Check the syntax of the file contents
+ %% (All mandatory information specified,
+ %% correct types, etc)
+ case toolbar_lib:tool_info_syntax(Vsn,T) of
+
+ %% Ok -- Show the file contents in the window
+ %% and move focus to the next entry
+ {ok,Info} ->
+ display(Window,"File: "++FileName++
+ " opened"),
+ clear_info(Window),
+ show_info(Window,Info),
+ move_focus(Window,file);
+
+ %% Erronous version number -- Notify user
+ {error,version} ->
+ Win = Window#tfwindow.window,
+ tool_utils:notify(Win,[FileName,
+ "File has wrong version number"]);
+
+ %% Other error -- Notify user
+ _Error ->
+ Win = Window#tfwindow.window,
+ tool_utils:notify(Win,[FileName,
+ "File is on erronous format"])
+ end;
+
+ %% The file can not be read, show default values
+ %% according to the file name in the window and
+ %% move focus to the next entry
+ _ ->
+ display(Window,"File: "++FileName ++
+ " could not be read, new file"),
+ Tool = filename:basename(FileName,".tool"),
+ clear_info(Window),
+ show_info(Window,[{tool,Tool},
+ {start,{list_to_atom(Tool),
+ start,[]}},
+ {icon,Tool++".gif"},
+ {html,Tool++".html"}]),
+ move_focus(Window,file)
+ end
+ end,
+ loop(S,Window);
+
+ %% 'Return' pressed in another entry, move focus to next entry
+ {gs,_Obj,keypress,Focus,['Return'|_]} ->
+ move_focus(Window,Focus),
+ loop(S,Window);
+
+ %% Any oher keypress, clear the display
+ {gs,_Obj,keypress,_Data,_Args} ->
+ display_clear(Window),
+ loop(S,Window);
+
+ %% 'Clear' button pressed, clear the window
+ {gs,_Obj,click,_Data,["Clear"|_]} ->
+ clear_info(Window),
+ loop(S,Window);
+
+ %% 'Save' button pressed, save the given information to file
+ {gs,_Obj,click,_Data,["Save"|_]} ->
+
+ %% Check if a file name is specified
+ case string:strip(gs:read(Window#tfwindow.fileentry,text)) of
+
+ %% No file name specified, notify user
+ "" ->
+ Win = Window#tfwindow.window,
+ tool_utils:notify(Win,
+ "A file name must be specified");
+
+ %% A name is specified
+ String ->
+
+ %% Add a .tool suffix to the file name if necessary
+ FileName = tool_file(String),
+
+ %% Write the complete file name to the file entry
+ gs:config(Window#tfwindow.fileentry,{text,FileName}),
+
+ %% Check the other information given
+ case check_info(Window) of
+
+ %% If given info is correct, try to save
+ %% it to the file
+ {ok,ToolInfo} ->
+ Win = Window#tfwindow.window,
+ case save_info(Win,FileName,ToolInfo) of
+
+ %% Ok, display confirmation
+ ok ->
+ display(Window,
+ "Tool information saved to "++
+ FileName);
+
+ %% Cancel, do nothing
+ cancel ->
+ ignore;
+
+ %% Error, display error message
+ {error,Reason} ->
+ display(Window,
+ toolbar_lib:error_string(Reason)++
+ FileName)
+ end;
+
+ %% Given info incorrect, notify user
+ {error,Reason} ->
+ Win = Window#tfwindow.window,
+ Str = toolbar_lib:error_string(Reason),
+ tool_utils:notify(Win,Str)
+ end
+ end,
+ loop(S,Window);
+
+ %% 'Stop' button, close window and exit
+ {gs,_Obj,click,_Data,["Stop"|_]} ->
+ gs:destroy(Window#tfwindow.window),
+ finished;
+
+ %% Window closed, exit
+ {gs,_Obj,destroy,_Data,_Args} ->
+ finished;
+
+ Other ->
+ io:format("toolbar_toolconfig: unexp msg: ~p~n",[Other]),
+ loop(S,Window)
+ end.
+
+
+%=============================================================================
+% Graphics
+%=============================================================================
+
+%----------------------------------------
+% draw_window(S)
+% S - pid() GS
+% Draw the main window.
+%----------------------------------------
+draw_window(S) ->
+
+ %% ----- Open a new window -----
+ Win = gs:create(window,S,[{width,400},{height,390},
+ {title,"Create Tool File"}]),
+
+ %% ----- Top frame containing a 'File name' label and entry -----
+ Top = gs:create(frame,Win,[{x,0},{y,0},{width,400},{height,60},{bw,2},
+ {keypress,true}]),
+
+ %% File name
+ gs:create(label,Top,[{x,10},{y,10},{width,80},{height,30},{align,e},
+ {keypress,true},
+ {label,{text,"File name:"}}]),
+ File = gs:create(entry,Top,[{x,110},{y,10},{width,280},{height,30},
+ {keypress,true},{data,file}]),
+
+ %% ----- Middle frame containing other labels and entries -----
+ Mid = gs:create(frame,Win,[{x,0},{y,60},{width,400},{height,250},{bw,2},
+ {keypress,true}]),
+
+ %% Tool name
+ gs:create(label,Mid,[{x,10},{y,10},{width,80},{height,30},{align,e},
+ {keypress,true},
+ {label,{text,"Tool name:"}}]),
+ Tool = gs:create(entry,Mid,[{x,110},{y,10},{width,280},{height,30},
+ {keypress,true},{data,tool}]),
+
+ %% Start function
+ gs:create(label,Mid,[{x,10},{y,60},{width,80},{height,30},{align,e},
+ {keypress,true},
+ {label,{text,"Start:"}}]),
+ Mod = gs:create(entry,Mid,[{x,110},{y,60},{width,135},{height,30},
+ {keypress,true},{data,module}]),
+ Fun = gs:create(entry,Mid,[{x,245},{y,60},{width,135},{height,30},
+ {keypress,true},{data,function}]),
+
+ %% Icon file
+ gs:create(label,Mid,[{x,10},{y,110},{width,80},{height,30},{align,e},
+ {keypress,true},
+ {label,{text,"Icon file:"}}]),
+ Icon = gs:create(entry,Mid,[{x,110},{y,110},{width,280},{height,30},
+ {keypress,true},{data,icon}]),
+
+ %% Message
+ gs:create(label,Mid,[{x,10},{y,160},{width,80},{height,30},{align,e},
+ {keypress,true},
+ {label,{text,"Message:"}}]),
+ Msg = gs:create(entry,Mid,[{x,110},{y,160},{width,280},{height,30},
+ {keypress,true},{data,message}]),
+
+ %% HTML file
+ gs:create(label,Mid,[{x,10},{y,210},{width,80},{height,30},{align,e},
+ {keypress,true},
+ {label,{text,"HTML:"}}]),
+ Html = gs:create(entry,Mid,[{x,110},{y,210},{width,280},{height,30},
+ {keypress,true},{data,html}]),
+
+ %% ----- Bottom frame containing the buttons -----
+ Bot = gs:create(frame,Win,[{x,0},{y,310},{width,400},{height,50},
+ {bw,2},{keypress,true}]),
+
+ gs:create(button,Bot,[{x,75},{y,10},{width,50},{height,30},
+ {keypress,true},
+ {label,{text,"Clear"}}]),
+ gs:create(button,Bot,[{x,175},{y,10},{width,50},{height,30},
+ {keypress,true},
+ {label,{text,"Save"}}]),
+ gs:create(button,Bot,[{x,275},{y,10},{width,50},{height,30},
+ {keypress,true},
+ {label,{text,"Stop"}}]),
+
+ %% ----- Label for displaying help messages -----
+ Lbl = gs:create(label,Win,[{x,0},{y,360},{width,400},{height,30},{bw,2},
+ {relief,raised},
+ {keypress,true},
+ {align,c},{label,{text,""}}]),
+
+ gs:config(Win,{map,true}),
+ gs:config(File,{setfocus,true}),
+
+ #tfwindow{window=Win,
+ fileentry=File,
+ toolentry=Tool,
+ moduleentry=Mod,
+ functionentry=Fun,
+ iconentry=Icon,
+ messageentry=Msg,
+ htmlentry=Html,
+ label=Lbl}.
+
+%----------------------------------------
+% move_focus(Window,Focus)
+% Window - tfwindow()
+% Focus - file | tool | module | function | icon | message | html | none
+% Move the input focus to the entry following Focus
+%----------------------------------------
+move_focus(Window,file) ->
+ gs:config(Window#tfwindow.toolentry,{setfocus,true});
+move_focus(Window,tool) ->
+ gs:config(Window#tfwindow.moduleentry,{setfocus,true});
+move_focus(Window,module) ->
+ gs:config(Window#tfwindow.functionentry,{setfocus,true});
+move_focus(Window,function) ->
+ gs:config(Window#tfwindow.iconentry,{setfocus,true});
+move_focus(Window,icon) ->
+ gs:config(Window#tfwindow.messageentry,{setfocus,true});
+move_focus(Window,message) ->
+ gs:config(Window#tfwindow.htmlentry,{setfocus,true});
+move_focus(Window,html) ->
+ gs:config(Window#tfwindow.htmlentry,{setfocus,false});
+move_focus(_Window,none) ->
+ true.
+
+%----------------------------------------
+% display(Window,Text)
+% Window - tfwindow()
+% Text - string()
+% Display a help message in the window
+%----------------------------------------
+display(Window,Text) ->
+ gs:config(Window#tfwindow.label,{label,{text,Text}}).
+
+%----------------------------------------
+% display_clear(Window)
+% Window - tfwindow()
+% Clear the help message display
+%----------------------------------------
+display_clear(Window) ->
+ display(Window,"").
+
+%----------------------------------------
+% clear_info(Window)
+% Window - tfwindow()
+% Clear the entries of Window (except the file entry)
+%----------------------------------------
+clear_info(Window) ->
+ gs:config(Window#tfwindow.toolentry,{text,""}),
+ gs:config(Window#tfwindow.moduleentry,{text,""}),
+ gs:config(Window#tfwindow.functionentry,{text,""}),
+ gs:config(Window#tfwindow.iconentry,{text,""}),
+ gs:config(Window#tfwindow.messageentry,{text,""}),
+ gs:config(Window#tfwindow.htmlentry,{text,""}).
+
+%----------------------------------------
+% show_info(Window,List)
+% Window - tfwindow()
+% List - [{Key,Val}]
+% Key - tool, Val - string()
+% Key - start, Val - {atom(),atom(),_}
+% Key - icon, Val - string()
+% Key - message, Val - string()
+% Key - html, Val - string()
+% Display the different Val's in the appropriate entries of Window
+%----------------------------------------
+show_info(_Window,[]) ->
+ ok;
+show_info(Window,[{tool,Tool}|Rest]) ->
+ gs:config(Window#tfwindow.toolentry,{text,Tool}),
+ show_info(Window,Rest);
+show_info(Window,[{start,{M,F,_}}|Rest]) ->
+ gs:config(Window#tfwindow.moduleentry,{text,M}),
+ gs:config(Window#tfwindow.functionentry,{text,F}),
+ show_info(Window,Rest);
+show_info(Window,[{icon,Icon}|Rest]) ->
+ gs:config(Window#tfwindow.iconentry,{text,Icon}),
+ show_info(Window,Rest);
+show_info(Window,[{message,Message}|Rest]) ->
+ gs:config(Window#tfwindow.messageentry,{text,Message}),
+ show_info(Window,Rest);
+show_info(Window,[{html,Html}|Rest]) ->
+ gs:config(Window#tfwindow.htmlentry,{text,Html}),
+ show_info(Window,Rest).
+
+
+%=============================================================================
+% Retrieve user specified information
+%=============================================================================
+
+%----------------------------------------
+% check_info(Window) => {ok,ToolInfo} | {error,Reason}
+% Window - tfwindow()
+% ToolInfo - toolinfo()
+% Reason - noname | nostart
+% Check the information given in the entries and insert it into ToolInfo
+% if all mandatory information is given.
+%----------------------------------------
+check_info(Window) ->
+
+ %% First check mandatory elements: name and start function
+ Tool = gs:read(Window#tfwindow.toolentry,text),
+ M = gs:read(Window#tfwindow.moduleentry,text),
+ F = gs:read(Window#tfwindow.functionentry,text),
+
+ if
+ Tool/="",M/="",F/="" ->
+ ToolInfo =
+ #toolinfo{tool=Tool,
+ start={list_to_atom(M),list_to_atom(F),[]},
+ icon=gs:read(Window#tfwindow.iconentry,text),
+ message=gs:read(Window#tfwindow.messageentry,text),
+ html=gs:read(Window#tfwindow.htmlentry,text)},
+ {ok,ToolInfo};
+
+ Tool=="" ->
+ {error,noname};
+
+ true ->
+ {error,nostart}
+ end.
+
+
+%=============================================================================
+% Save information to file
+%=============================================================================
+
+%----------------------------------------
+% save_info(Win,File,ToolInfo) => ok | cancel | {error,waccess}
+% Win - GS object
+% File - string()
+% ToolInfo - toolinfo()
+% Saves the information in ToolInfo to File on a predefined format.
+%----------------------------------------
+save_info(Win,File,ToolInfo) ->
+
+ %% First check if file already exists
+ case file:read_file_info(File) of
+ {ok,_FileInfo} ->
+
+ %% Request the user to confirm that the file should
+ %% be overwritten
+ case tool_utils:confirm(Win,[File,
+ "exists, will be overwritten"]) of
+ ok ->
+ save_info2(File,ToolInfo);
+ cancel ->
+ cancel
+ end;
+
+ {error,_Reason} -> % _Reason = "No such file or directory"
+ save_info2(File,ToolInfo)
+ end.
+
+%----------------------------------------
+% save_info2(File,ToolInfo) => ok | {error,waccess}
+% File - string() File name
+% ToolInfo - toolinfo record
+% Called by save_info/3
+%----------------------------------------
+save_info2(File,ToolInfo) ->
+ case file:open(File, [write]) of
+ {ok,Fd} ->
+ io:format(Fd,"{version,\"~s\"}.~n",[toolbar:version()]),
+ io:format(Fd,"{{tool,\"~s\"},~n",[ToolInfo#toolinfo.tool]),
+ io:format(Fd," {start,~w}",[ToolInfo#toolinfo.start]),
+ case ToolInfo#toolinfo.icon of
+ "" -> ignore;
+ Icon -> io:format(Fd,",~n {icon,\"~s\"}",[Icon])
+ end,
+ case ToolInfo#toolinfo.message of
+ "" -> ignore;
+ Message -> io:format(Fd,",~n {message,\"~s\"}",[Message])
+ end,
+ case ToolInfo#toolinfo.html of
+ "" -> ignore;
+ Html -> io:format(Fd,",~n {html,\"~s\"}",[Html])
+ end,
+ io:format(Fd,"}.~n",[]),
+ file:close(Fd),
+ ok;
+ _Error ->
+ {error,waccess}
+ end.
+
+
+%=============================================================================
+% Auxiliary functions
+%=============================================================================
+
+%----------------------------------------
+% tool_file(File) => string()
+% File - string()
+% Return a file name consisting of File with the suffix .tool added,
+% if File does not already have this suffix.
+%----------------------------------------
+tool_file(File) ->
+ case filename:extension(File) of
+ ".tool" -> File;
+ _ -> File ++ ".tool"
+ end.