Intro

So you want to help programming segusoLand, and you need an intro to the code? This is the place.

First of all:

If you don't know Prolog, don't worry, because the main part that needs help is C++ coding. Read the TODO document for additional informations.

Adding a new verb

This section requires prolog knowledge.

Suppose you want to add to segusoLand a new verb called "view picture", which requires:

You need to

Specifying the requirements for the verb

You need to add the following prolog facts to the file segusoLand.pl:

verbRequiresAtLeastOneObjectSatisfying('View picture', program, supports('View picture')).
verbRequiresAtLeastOneObjectSatisfying('View picture', file, pictureFile). 
 

Let us now comment this code.

verbRequiresAtLeastOneObjectSatisfying('View picture', program, supports('View picture')).
means that segusoLand will check, for each program P, whether the following holds:
  supports('View picture', P).
if true, then he will show the verb when P is selected.
 verbRequiresAtLeastOneObjectSatisfying('View picture',  file, pictureFile).
This means that segusoLand will check, for each file F, whether the following is true:
  pictureFile(F).
This info is used for narrowing.

Telling segusoLand which program supports that verb

If the verb does not requier programs, this is not necessary. You have to tell segusoLand which program supports that verb. you can do that by adding the following "facts":
supports( 'View picture', 'Kuickshow').
supports( 'View picture', 'Eye of Gnome').

Writing the semantics for the new verb

Now you have to define the semantics of the verb, i.e. what happens when you execute that verb. A very simple implementation of the verb could be:
onVerbExecuted('View picture', N, N):-        %please don't mind  N, N for now :-)
        selected(program, P),
        shellName(P, P2),
        findall(F, selected(file, F), Files),
        sort(Files, Sorted),
        fromListOfFilesToQuotedString(Sorted, String),
        concat_atom([P2, ' ', String, '  &'], Command),
        writeln(Command),
        shell(Command, Status),
        displayProgramNotInstalledIfNecessary(P, Status).
Let's comment the code above:
 onVerbExecuted('View picture', N, N):-        %please don't mind  N, N for now :-)
This is called when the user presses the "Go" button.

N is the current list of tasks. We leave it unchanged in this simple example, so we output the same N.

       selected(program, P), 
Pick on selected program at random and call it P.

In general, the user can select more than one program, then click GO. It would be nice to display an error message here if there is more than one program selected.

It is also possible to prevent the Go button from appearing if there is more than one program/file/device selected, or less than 523 files selected :-) . For such things you need to add a clause to the predicate selectionIncompatibleWithVerb/1, but I won't describe it in this basic example.

 shellName(P, P2), 
Puts in P2 the shell name of P. (e.g. if P='Kuickshow' then P2='kuickshow').
  findall(F, selected(file, F), Files),
find the set of all selected files and put it into Files. Files will be a list of atoms, such as
Files = ['file.pdf'  , 'file2.pdf' ]
Now to the next line:
    sort(Files, Sorted), 
This sets Sorted to be equal to Files, but sorted, and with duplicates removed (actually duplicates shouldn't be unless there is a bug in my code).
      fromListOfFilesToQuotedString(Sorted, String), 
String is a prolog atom obtained concatenating the elements of Sorted. For example
String='file.pdf file2.pdf'
A prolog atom can be thought of as a C++ string :-)
       concat_atom([P2, ' ', String, '  &'], Command),
Command is the atom obtained concatenating P2, '', String, ' &'. In other words, Command will be something like
Command='kuickshow file1.gif file2.gif &'
now to the next line:
      writeln(Command),
this outputs the command for debug purposes.
       shell(Command, Status), 
This executes Command as a CLI command, and sets Status = 0 (success) or 1 (failure)
       displayProgramNotInstalledIfNecessary(P, Status). 
gives an error message if Status = 0 and the program is not installed.

Adding a new verb, part II

The previous implementation of 'View picture' was not very good: It didn't take the selected time into account: it always executed the action immediately, as soon as the go button is pressed. But segusoLand has different times: you can choose to postpone the action. (This may not be very useful for 'View picture', but think of 'Play audio' or 'Shutdown computer').

Let us implement the verb "Mail to...", which requires:

This time we will take the time into account. The current implementation is the following:

verbRequiresAtLeastOneObjectSatisfying('Mail to...', file, anyFile).
verbRequiresAtLeastOneObjectSatisfying('Mail to...', program, supports('Mail to...')).
supports( 'Mail to...', 'Kmail').
onVerbExecuted('Mail to...', Tasks, NewTasks):-
	selected(program, 'Kmail'), 
	createActionFromSelection('Mail to...', A),
	% REGION choose one time at random. @@ we should process all selected times!
	selected(time, T),
	convertTimeToNumber(T, N),
	% END
	NewTasks2 = [(N, A) | Tasks],
	onTimer(NewTasks2, NewTasks).
executeActionNow(['Mail to...', Files, Programs, _]):-
	(Programs\=['Kmail'] -> writeln(error-program-should-be-kmail); true),
	sort(Files, SortedFiles),
	fromListOfFilesToQuotedString(SortedFiles, String),
	concat_atom(['kmail --attach ', String, '  &'], Command),
	writeln(Command),
	shell(Command, _),
	addStringToLog('Sent file by mail').
Let us comment this code.
verbRequiresAtLeastOneObjectSatisfying('Mail to...', file, anyFile).
This should be familiar. segusoLand will check, for each file F, whether
anyFile(F)
holds. And this always holds, since anyFile/1 is defined as
anyFile(_).
:-) Now to the next line: [TO BE CONTINUED]

Introduction to the C++ code

[to be written.]