<?xml version="1.0" encoding="windows-1252"?>
<node id="479213" title="Utility to capture parameters and perform a task" created="2005-07-28 22:24:10" updated="2005-08-15 16:15:46">
<type id="1042">
CUFP</type>
<author id="461912">
GrandFather</author>
<data>
<field name="doctext">
&lt;p&gt;This code is a part way point in the development of a tool to perform some directory and file management. At this stage it captures information required for the management from the user. The information gathered to controlled by a configuration file. This seems a generally usefull task so the code is offered here for other monks to make what use they wish of it.&lt;/p&gt;
&lt;p&gt;The configuration files is comprised of lines containing a parameter name, and optional default value, and a label. For example:&lt;/p&gt;
&lt;c&gt;_version_ "1_0" Version as it should appear in the project path (e.g. 1_0)&lt;/c&gt;
&lt;p&gt;If the default string contains names of other parameters, the default value for the parameter will be generated at run time as the other parameters are updated.&lt;/p&gt;
&lt;p&gt;The work of the task goes in &lt;c&gt;sub CreateProject&lt;/c&gt; (which is an appropriate name for my initial task :).&lt;/p&gt;
&lt;readmore title="the code"&gt;
&lt;c&gt;
use warnings;
use strict;
use Tk;

=head

Parse a configuration text file (TemplateValues.txt) to gather configuration
parameters, defaults and labels required to perform some task then present a
user interface built from the information in the configuration file to capture
user values for the parameters.

=cut

my $main = MainWindow-&gt;new ();

if (! open configIn, "&lt; TemplateValues.txt")
  {
  my $text = $main-&gt;Text ();
  $text-&gt;Insert ("Unable to open configuration file: $!");
  $text-&gt;pack ();
  $main-&gt;Button (-text =&gt; "Quit", -command =&gt; sub {$main-&gt;destroy ()})-&gt;pack ();
  MainLoop ();
  exit (-1);
  }

my %Parameters;

while (&lt;configIn&gt;)
  {
  next if /^#/; #Skip comment lines
  chomp;
  next if ! length $_;
  my ($key, $default, $comment) = /^(\w+)\s(?:"(.*?)")?(.*)/;
  my $label = $main-&gt;Label (-text =&gt; $comment)-&gt;pack ();
  $Parameters {$key} =
    [
    $main-&gt;Entry
      (
      -validate =&gt; 'focusout',
      -validatecommand =&gt; sub {touch ($key);}
      )-&gt;pack (),
    $default
    ];
  }
touch ("");

$main-&gt;Button (-text =&gt; "Cancel", -command =&gt; sub {$main-&gt;destroy ()})-&gt;pack ();
$main-&gt;Button
  (
  -text =&gt; "Create Project",
  -command =&gt; sub {tidyParams (); CreateProject (); $main-&gt;destroy ();}
  )-&gt;pack ();
MainLoop;


sub CreateProject
{
#Note that %Parameters's values are now the user supplied strings

print join "\n", map {$_ . " =&gt; " . $Parameters{$_}} keys %Parameters;
}


sub touch
{
my $key = shift;

Entry: for (keys %Parameters)
  {
  next if defined $key and $key eq $_;

  my $repKey = $_;
  my $default = ${$Parameters {$repKey}}[1];
  next if ! defined $default or ! length $default; #Don't edit

  while ($default =~ /(_[a-zA-Z0-9]+_)/)
    {
    next Entry if ! defined $Parameters {$1};

    my $subStr = ${$Parameters {$1}}[0]-&gt;get ();
    $default =~ s/$1/$subStr/eg;
    }

  ${$Parameters{$repKey}}[0]-&gt;delete (0, 'end');
  ${$Parameters{$repKey}}[0]-&gt;insert (0, $default) if length $default;
  }
  
${$Parameters{$key}}[1] = undef if defined $key and length $key; #Prevent auto default updates
return 1;
}


sub tidyParams
{
touch ();
for my $key (keys %Parameters)
  {
  next if ! length $key;
  next if ! defined $Parameters{$key};
  $Parameters{$key} = ${$Parameters {$key}}[0]-&gt;get ();
  }
}
&lt;/c&gt;
&lt;/readmore&gt;
&lt;readmore title="sample template file and output"&gt;
&lt;c&gt;
_ExtensionFile_ File name for extension (excluding file extension)
_ExtensionNameUI_ "_ExtensionFile_" Extension name as shown in UI
_ExtensionPath_ "Extensions/_ExtensionFile_" Path from PCDevelop\Main to folder containing project
_MinVersion_ Minimum version required
_ExtensionSlnFile_ "_ExtensionFile_" Name of solution file (excluding file extension)
_ExtensionType_ "Extension" Extension or Module
_author_ Email name of primary extension author
_version_ "1_0" Version as it should appear in the project path (e.g. 1_0)

_ExtensionPath_ =&gt; Extensions/Telegraph
_author_ =&gt; GrandFather@erewhon
_ExtensionSlnFile_ =&gt; Telegraph
_ExtensionType_ =&gt; Extension
_version_ =&gt; 1_0
_ExtensionFile_ =&gt; Telegraph
_MinVersion_ =&gt; 2.7
_ExtensionNameUI_ =&gt; Telegraph
&lt;/c&gt;
&lt;/readmore&gt;
&lt;div class="pmsig"&gt;&lt;div class="pmsig-461912"&gt;
&lt;hr&gt;Perl is Huffman encoded by design.
&lt;/div&gt;&lt;/div&gt;</field>
</data>
</node>
