#!C:\\perl\\bin\\perl.exe
# proc_files_win.pl
# Processes files on Windows PCs for the Collective.
# Additional processing is required once the files are moved to the Linux
# box (see proc_files_lin.pl). This app only handles the Windows processing.
# The app consists of a GUI (using tk) and processing functions (using perl).
# Various functions use private $statusFlag variables for error tracking; they
# return a positive number on success and 0 on failure.
# Note: Functions have multiple returns. When a significant error is encountered,
# a function displays an error message and then returns at that point. This makes the
# code simpler, but when reading the code keep in mind that errors can cause early
# returns from functions.
# Windows 95/98/ME Note: Perl's rename() function works on Win NT/2000/XP but not on
# Win 95/98/ME. When the script detects a rename() failure, it makes a system call to
# Window's ren command as a workaround.
# WARNING: The system call to ren has not been fully tested!
# Contents
# PART 1: The Premilinaries
# PART 1.1: Modules
# PART 1.2: Global Variables
# PART 2: The GUI
# PART 2.1: Widgets (Windows, Boxes, and their Contents)
# Input Window
# Output Window
# Help Window
# PART 2.2: The Main Loop
# PART 2.3: GUI-Management Functions
# OpenHelpWin()
# OpenOutWin()
# ShowError()
# ShowQuery()
# ScanWkgDir()
# CheckStartDirState()
# CheckExtsState()
# CheckZipState()
# CheckDestDirState()
# PART 3: Input Error Checking Functions
# CheckForErrors()
# CheckDirName()
# CheckStartDir()
# CheckDirContents()
# CheckFixIncludes()
# BuildDestPath()
# CheckZipName()
# CheckExts()
# CheckDestDir()
# PART 4: File Processing Functions
# ProcessFiles()
# EchoInput()
# ClearROA()
# ZipSource()
# FixSpaces()
# FixCase()
# FixIncludes()
# CopyToLinux()
# PART 5: Help Data
# GetHelpContents()
# PART 1: The Premilinaries
# PART 1.1: Modules
use strict; # Catches errors during code.
use File::Find; # For file operations.
use File::Path; # For removal of non-empty directories.
use Tk; # For the GUI.
use Tk::DialogBox; # For the GUI.
# PART 1.2: Global Variables
# Global input variables. These hold the user input and important values
# derived from the input.
my $wkgDir = 'C:\Astell-THQ\wkg'; # Working directory (where dirs to be processed typicall are).
my $initDir = "???"; # Initial directory; i.e., dir to be processed.
my $userDir = ""; # For user to enter a project dir.
my $startDirFlag = 1; # Flags whether (1) a dir from $wkgDir or (2) a user-input dir is to be used.
my $startDirState = 1; # Tracks whether or not to reset input dir items.
my @foundDirs = (); # Dirs found in $wkgDir; possible dirs to be processed.
my $numDirs = 0; # Number of dirs found in $wkgDir.
my $clearROA = 1; # Clear read-only attributes flag.
my $zipSource = 1; # Zip source code flag.
my $zipBase = "XXX"; # Base name for the possible zip file.
my $zipName = ""; # Name and ext for zip file.
my $fixSpaces = 1; # Change spaces to underscores flag.
my $fixCase = 1; # Change upper case to lower.
my $fixIncludes = 1; # Fix #include format in C/C++ source code files.
my $useCpp = 1; # Fix #includes in .cpp files.
my $useC = 1; # Fix #includes in .c files.
my $useH = 1; # Fix #includes in .h files.
my $useHpp = 1; # Fix #includes in .hpp files.
my $moreExts = ""; # More extension to fix #includes.
my $destDirFlag = 1; # Directory (on a Linux box) to copy processed dir to.
# 0 - No copying.
# 1 - Copy to THQ Collective.
# 2 - Copy to THQ DevNet.
my $destDirName = "XXX"; # Name of dest subdir (final subdir of $intiDir).
my $destDir = ""; # Destination directory.
# ($destDir = path . $destDirName.)
my $userDestDir = ""; # For user to enter a destination dir.
my $overOld = 0; # Overwrite dest dir flag.
my $echoInput = 1; # Echo input in output flag.
# Predeclared variables (widget references) so that code can use them before they are defined.
my $inWin;
my $inTitleFr;
my $inBody;
my $inDirFr;
my $dirList;
my $rescanBtn;
my $initDirEn;
my $zipBaseEn;
my $fixCpp;
my $fixC;
my $fixH;
my $fixHpp;
my $moreExtsIntro;
my $moreExtsEn;
my $moreExtsExtro;
my $destDirEn;
my $noOverRbn;
my $yesOverRbn;
my $showOutWinBn;
my $outWin;
my $outTitleFr;
my $outBody;
my $helpWin;
my $helpTitleFr;
my $helpBody;
# Other global variables.
my $temp; # Used to refer to widgets when permanent reference is not needed.
my $tempStr = ""; # Temporary string.
my $width; # Used in sizing windows.
my $height; # Used in sizing windows.
my $widthEntry; # Width of an entry box.
my @msgItem; # Holds text-and-tag entries for error and query messages.
my $text; # Holds the text to insert into a Text widget.
my $tag; # Holds the tag for the text being inserted into a Text widget.
my $scanFlag = 0; # Flags whether or $wkgDir has been scanned for dirs.
# PART 2: The GUI
# App can display these windows:
# Input window (the Main Window) on left; is called up initially.
# Output window (a Top Level) on right; is called up initially.
# Help window (a Top Level) on right; user can call up.
# and these dialog boxes (Tk::DialogBox):
# Error box; pops up when bad input is detected.
# Query box; pops up to check that user actually wants to do some odd set of specifications.
# Canvases are used to create visual spacers (highlightthickness is set to 0
# to turn off "border" outside canvas).
# $_toplevel_->protocol() is used to prevent inadvertent destruction of top level windows
# that are not the main window (e.g., the user clicks the X, which destroys
# the window. The protocol causes the window to be withdrawn instead. Cannot use:
# $_toplevel_->bind( "", sub { $outWin->withdraw; } );
# as bind() detects the event but does not prevent it (so the window is
# destroyed despite your best intentions.
# PART 2.1: Widgets (Windows, Boxes, and their Contents)
# Input Window
# Create the main window (the Input Window).
$inWin = new MainWindow;
$inWin->title( "Windows File Processing: Input" );
$inWin->configure( -background => "#EEEEEE" );
$inWin->focusFollowsMouse();
# When app loads, checks that processing will occur using Windows (Win32).
$inWin->bind( "", sub
{
if ( $^O ne "MSWin32" )
{
@msgItem = ( @msgItem, "ERROR: Wrong operating system!\n12b" );
@msgItem = ( @msgItem,
"Processing must occur on a Windows PC, but your OS says it is $^O.\n\n" .
"The program will shut down.\n10n" );
ShowError();
exit;
}
} );
# Ctrl-W closes the app (defined in main window but affects all windows).
# 'all' forces all widgets to recognize event, else widgets with focus
# would ignore this.
$inWin->bind( 'all', "", sub
{
$temp = $inWin->focusCurrent();
if ( $temp->toplevel() == $inWin->toplevel() )
{
exit; # Ctrl-W was pressed in Input window; exit app.
} elsif ( $temp->toplevel() == $outWin->toplevel() )
{
$outWin->withdraw; # Ctrl-W was pressed in Output window; withdraw that window.
} elsif ( $temp->toplevel() == $helpWin->toplevel() )
{
$helpWin->withdraw; # Ctrl-W was pressed in Help window; withdraw that window.
} else
{
return; # Ctrl-W was pressed elsewhere (dialog box?); ignore.
}
} );
# Adjust window per screen resolution.
$width = int( .5 * .9 * $inWin->screenwidth() );
$height = int( .8 * $inWin->screenheight() );
$inWin->geometry( $width . "x" . $height . "+20+15" );
# Base width of entry widgets on screen size.
if ( $inWin->screenwidth() < 800 )
{
$widthEntry = 30;
} elsif ( $inWin->screenwidth() < 1000 )
{
$widthEntry = 40;
} else
{
$widthEntry = 60;
}
# Overall Title
$inWin->Label(
-anchor => 'w',
-background => "#BBBBBB",
-font => "{Tahoma} 16 {bold}",
-text => "Windows File Processing for the Collective" )
->pack(
-fill => 'x',
-side => 'top' );
# Input Title Frame
$inTitleFr = $inWin->Frame( -background => "#EEEEEE" )
->pack(
-fill => 'x',
-pady => 2,
-side => 'top' );
# Input Title
$inTitleFr->Label(
-anchor => 'w',
-background => "#EEEEEE",
-font => "{Tahoma} 12 {bold}",
-text => "Input" )
->pack( -side => 'left' );
# Help Button
$inTitleFr->Button(
-activebackground => "#F7DF8F",
-background => "#CCBB99",
-command => \&OpenHelpWin,
-font => "{Tahoma} 8 {bold}",
-text => "Help" )
->pack(
-padx => 10,
-side => 'right' );
# Visual Separator
$inWin->Canvas(
-background => "#888888",
-height => 2,
-highlightthickness => 0,
-takefocus => 0 )
->pack(
-fill => 'x',
-pady => 2,
-side => 'top' );
# Input Area
$inBody = $inWin->Scrolled( "Text",
-background => "#EEEEEE",
-cursor => 'arrow',
-font => "{Tahoma} 10 {normal}",
-relief => 'flat',
-scrollbars => 'osoe',
-wrap => 'word' )
->pack(
-expand => 1,
-fill => 'both',
-side => 'top' );
$inBody->tagConfigure( '8n', -font => "{Tahoma} 8 {normal}" );
$inBody->tagConfigure( '8b', -font => "{Tahoma} 8 {bold}" );
$inBody->tagConfigure( '10n', -font => "{Tahoma} 10 {normal}" );
$inBody->tagConfigure( '10b', -font => "{Tahoma} 10 {bold}" );
$inBody->tagConfigure( '10i', -font => "{Tahoma} 10 {italic}" );
$inBody->tagConfigure( '12n', -font => "{Tahoma} 12 {normal}" );
$inBody->tagConfigure( '12b', -font => "{Tahoma} 12 {bold}" );
# Directory to be Processed
$inBody->insert( 'end', "Directory to be Processed:\n", '10b' );
$inDirFr = $inBody->Frame( -background => "#EEEEEE" )
->pack(
-fill => 'x',
-pady => 2,
-side => 'top' );
$inBody->windowCreate( 'end', -window => $inDirFr );
# Use a Dir in $wkgDir Radiobutton
$temp = $inDirFr->Radiobutton(
-activebackground => "#F7DF8F",
-anchor => 'nw',
-background => "#EEEEEE",
-command => sub
{
ScanWkgDir() if ( not $scanFlag );
$rescanBtn->configure( -state => 'normal' ) if ( $rescanBtn->cget( -state ) eq "disabled" );
CheckStartDirState();
},
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => "Click a directory in $wkgDir:",
-variable => \$startDirFlag,
-value => "1" )
->grid(
-column => 0,
-row => 0,
-sticky => 'ne' );
# Directory Listing
$dirList = $inDirFr->Listbox(
-background => "#FFFFFF",
-font => "{Tahoma} 10 {bold}",
-height => 0,
-relief => 'flat',
-selectbackground => "#F7DF8F",
-selectforeground => "#000000",
-selectmode => "single" )
->grid(
-column => 1,
-row => 0,
-sticky => 'ne' );
$dirList->insert( 'end', @foundDirs );
$dirList->bind( "", sub
{
return unless ( $startDirFlag );
if ( $numDirs == 0 )
{
@msgItem = ( @msgItem, "ERROR: No directories!\n12b" );
@msgItem = ( @msgItem,
"No directories were found in $wkgDir.\n10n" );
ShowError();
return;
}
$destDirName = $dirList->get( $dirList->curselection() );
$initDir = $wkgDir . "\\" . $destDirName;
$zipBase = $destDirName;
CheckStartDir( $initDir );
} );
# Rescan Button
$rescanBtn = $inDirFr->Button(
-activebackground => "#F7DF8F",
-anchor => 'nw',
-background => "#CCBB99",
-command => \&ScanWkgDir,
-font => "{Tahoma} 8 {bold}",
-text => "Rescan" )
->grid(
-column => 2,
-row => 0,
-sticky => 'ne' );
$rescanBtn->bind( "", sub
{
if ( not $scanFlag )
{
if ( -d $wkgDir )
{
ScanWkgDir();
} else
{
$startDirFlag = 0;
$rescanBtn->configure( -state => 'disabled' );
$initDirEn->configure( -background => "#FFFFFF", -state => 'normal' );
$dirList->configure( -background => "#EEEEEE", -takefocus => '0' );
}
}
} );
$inBody->insert( 'end', "\n" );
# Use a User-Input Dir Radiobutton
$temp = $inBody->Radiobutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-command => sub
{
$rescanBtn->configure( -state => 'disabled' ) if ( $rescanBtn->cget( -state ) eq "normal" );
CheckStartDirState();
},
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => "Enter the full path to a directory: ",
-variable => \$startDirFlag,
-value => "0" );
$inBody->windowCreate( 'end', -window => $temp );
# User-Input Dir Entry
$initDirEn = $inBody->Entry(
-background => "#EEEEEE",
-font => "{Tahoma} 10 {normal}",
-state => 'disabled',
-textvariable => \$userDir,
-width => 40 );
$inBody->windowCreate( 'end', -window => $initDirEn );
$initDirEn->bind( "", sub
{
return if ( $initDirEn->cget( -state ) eq 'disabled' );
$initDirEn->selectionRange( 0, 'end' );
} );
$initDirEn->bind( "", sub
{
return if ( $initDirEn->cget( -state ) eq 'disabled' );
$userDir =~ s/\//\\/g; # Make sure dir uses Windows \ separators
$userDir = "???" if ( $userDir eq "" );
$initDir = $userDir;
# Get the name for the zip file and the destination subdir.
$tempStr = substr( "$initDir", (rindex( "$initDir", "\\" ) + 1) );
$destDirName = $tempStr;
# Guess the name for the zip file.
$tempStr =~ s/\s//g;
if ( length( $tempStr ) != 0 )
{
$zipBase = $tempStr;
} else
{
$zipBase = "XXX";
}
} );
$inBody->insert( 'end', "\n" );
# Processing Options
$inBody->insert( 'end', "\n", '8n' );
$inBody->insert( 'end', "Processing Options for ", '10b' );
$temp = $inBody->Label(
-anchor => 'w',
-background => "#EEEEEE",
-font => "{Tahoma} 10 {bold}",
-foreground => "#FF0000",
-textvariable => \$destDirName );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', ":\n", '10b' );
# Clear ROA Checkbutton
$temp = $inBody->Checkbutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-font => "{Tahoma} 10 {bold}",
-justify => 'left',
-text => "Clear Read-Only Attributes",
-variable => \$clearROA );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', "for files and directories.", '10n' );
$inBody->insert( 'end', "\n" );
# Zip Source Code Checkbutton
$temp = $inBody->Checkbutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-command => \&CheckZipState,
-font => "{Tahoma} 10 {bold}",
-justify => 'left',
-text => "Zip Source Code",
-variable => \$zipSource );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', "(and include it in the directory).", '10n' );
$inBody->insert( 'end', "\n" );
$inBody->insert( 'end', " Zip file name: ", '10n' );
$zipBaseEn = $inBody->Entry(
-font => "{Tahoma} 10 {normal}",
-textvariable => \$zipBase,
-width => 30 );
$inBody->windowCreate( 'end', -window => $zipBaseEn );
$zipBaseEn->bind( "", sub
{
return if ( $zipBaseEn->cget( -state ) eq 'disabled' );
$zipBaseEn->selectionRange( 0, 'end' );
} );
$zipBaseEn->bind( "", sub
{
return if ( $zipBaseEn->cget( -state ) eq 'disabled' );
$zipBase =~ s/\s//g; # Lose whitespace in name
$zipBase =~ s/(\.zip)+$//; # Lose 1+ trailing .zip (.zip is automatically appended)
} );
$inBody->insert( 'end', ".zip\n" );
# Change Spaces to Underscore Checkbutton
$temp = $inBody->Checkbutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-font => "{Tahoma} 10 {bold}",
-justify => 'left',
-text => "Change Spaces to Underscores",
-variable => \$fixSpaces );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', "in file and directory names.", '10n' );
$inBody->insert( 'end', "\n" );
# Change Upper Case to Lower Checkbutton
$temp = $inBody->Checkbutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-font => "{Tahoma} 10 {bold}",
-justify => 'left',
-text => "Change Upper Case to Lower",
-variable => \$fixCase );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', "in file and directory names.", '10n' );
$inBody->insert( 'end', "\n" );
# Fix #include Formatting Checkbutton
$temp = $inBody->Checkbutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-command => \&CheckExtsState,
-font => "{Tahoma} 10 {bold}",
-justify => 'left',
-text => "Fix \x23include Formatting",
-variable => \$fixIncludes );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', "in C/C++ files. Extensions to fix:", '10n' );
$inBody->insert( 'end', "\n" );
$inBody->insert( 'end', " " ); # Indent line of checkbuttons.
# Fix .cpp Checkbutton
$fixCpp = $inBody->Checkbutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => ".cpp ",
-variable => \$useCpp );
$inBody->windowCreate( 'end', -window => $fixCpp );
# Fix .c Checkbutton
$fixC = $inBody->Checkbutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => ".c ",
-variable => \$useC );
$inBody->windowCreate( 'end', -window => $fixC );
# Fix .h Checkbutton
$fixH = $inBody->Checkbutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => ".h ",
-variable => \$useH );
$inBody->windowCreate( 'end', -window => $fixH );
# Fix .hpp Checkbutton
$fixHpp = $inBody->Checkbutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => ".hpp ",
-variable => \$useHpp );
$inBody->windowCreate( 'end', -window => $fixHpp );
$inBody->insert( 'end', "\n" );
# Fix Other Extensions Entry
$moreExtsIntro = $inBody->insert( 'end', " Other:", '10n' );
$moreExtsEn = $inBody->Entry(
-font => "{Tahoma} 10 {normal}",
-textvariable => \$moreExts,
-width => 40 );
$inBody->windowCreate( 'end', -window => $moreExtsEn );
$moreExtsEn->bind( "", sub
{
return if ( $moreExtsEn->cget( -state ) eq 'disabled' );
$moreExts =~ s/,+|\.+/ /g; # Convert all , and . to spaces.
$moreExts =~ s/\s+/ /g; # Use only single spaces.
$moreExts =~ s/^\s|\s$//; # Lose leading or trailing spaces.
# Clean up moreExts: all exts begin with periods, are separated by one space,
# and any needless repetition is tossed out. (This uses a hash with the exts
# used as the KEYS of the hash, thus avoid duplicate names.)
my %uniqueExts;
foreach ( split( / /, $moreExts ))
{
$uniqueExts{ $_ } = 1; # Value is immaterial; key is what we care about.
}
$moreExts = "";
foreach ( keys( %uniqueExts ))
{
$moreExts .= " ." . $_; # Keys are used to reconsistute $moreExts without duplicates.
}
$moreExts =~ s/^ //; # Lose the initial space.
} );
$inBody->insert( 'end', "\n" );
$moreExtsExtro = $inBody->insert( 'end', " Enter a comma and/or space separated list of extensions.\n", '10n' );
# Copy Processed Directory
$inBody->insert( 'end', "\n", '8n' );
$inBody->insert( 'end', "Copy the Processed Directory, ", '10b' );
$temp = $inBody->Label(
-anchor => 'w',
-background => "#EEEEEE",
-font => "{Tahoma} 10 {bold}",
-foreground => "#FF0000",
-textvariable => \$destDirName );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', ", into:\n", '10b' );
# L: Collective Dir Radiobutton
$temp = $inBody->Radiobutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-command => \&CheckDestDirState,
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => "L:\\inetpub\\www\\wkg (THQ Collective).",
-variable => \$destDirFlag,
-value => "1" );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', "\n" );
# Use a User-Input Dir Radiobutton
$temp = $inBody->Radiobutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-command => \&CheckDestDirState,
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => "Enter the full path to a directory: ",
-variable => \$destDirFlag,
-value => "2" );
$inBody->windowCreate( 'end', -window => $temp );
# User-Input Dest Dir Entry
$destDirEn = $inBody->Entry(
-background => "#EEEEEE",
-font => "{Tahoma} 10 {normal}",
-state => 'disabled',
-textvariable => \$userDestDir,
-width => 40 );
$inBody->windowCreate( 'end', -window => $destDirEn );
$destDirEn->bind( "", sub
{
return if ( $destDirEn->cget( -state ) eq 'disabled' );
$destDirEn->selectionRange( 0, 'end' );
} );
$destDirEn->bind( "", sub
{
return if ( $destDirEn->cget( -state ) eq 'disabled' );
$userDestDir =~ s/\//\\/g; # Make sure dir uses Windows \ separators
# Lose any trailing \ separators.
chop $userDestDir while ( rindex( $userDestDir, "\\" ) == (length( $userDestDir ) - 1) );
$userDestDir = "???" if ( $userDestDir eq "" );
} );
$inBody->insert( 'end', "\n" );
# Don't Copy Radiobutton
$temp = $inBody->Radiobutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-command => \&CheckDestDirState,
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => "Do not copy.",
-variable => \$destDirFlag,
-value => "0" );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', "\n" );
# Overwrite Destination
$inBody->insert( 'end', "\n", '8n' );
$inBody->insert( 'end', "Overwrite ", '10b' );
$temp = $inBody->Label(
-anchor => 'w',
-background => "#EEEEEE",
-font => "{Tahoma} 10 {bold}",
-foreground => "#FF0000",
-textvariable => \$destDirName );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', " if it already Exists in the Destination Directory:\n", '10b' );
# Don't Overwrite Radiobutton
$noOverRbn = $inBody->Radiobutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => "Do not overwrite (safest).",
-variable => \$overOld,
-value => "0" );
$inBody->windowCreate( 'end', -window => $noOverRbn );
# Overwrite Radiobutton
$yesOverRbn = $inBody->Radiobutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-font => "{Tahoma} 10 {normal}",
-justify => 'left',
-text => "Overwrite.",
-variable => \$overOld,
-value => "1" );
$inBody->windowCreate( 'end', -window => $yesOverRbn );
$inBody->insert( 'end', "\n" );
# Echo Input Option
$inBody->insert( 'end', "\n", '8n' );
$inBody->insert( 'end', "Echo Input:\n", '10b' );
# Echo Input Checkbutton
$temp = $inBody->Checkbutton(
-activebackground => "#F7DF8F",
-anchor => 'e',
-background => "#EEEEEE",
-borderwidth => 0,
-font => "{Tahoma} 8 {bold}",
-justify => 'left',
-text => "Echo input values during processing",
-variable => \$echoInput );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', "(you might notice an error).", '8n' );
$inBody->insert( 'end', "\n" );
# Final set of buttons.
$inBody->insert( 'end', "\n" );
# Process Files Button
$temp = $inBody->Button(
-activebackground => "#F7DF8F",
-background => "#CCBB99",
-command => sub
{
my $statusFlag = 1;
$outBody->configure( -state => 'normal' );
$statusFlag = CheckForErrors();
ProcessFiles() if ( $statusFlag );
$outBody->configure( -state => 'disabled' );
},
-font => "{Tahoma} 8 {bold}",
-text => "Process Files" );
$inBody->windowCreate( 'end', -window => $temp );
# Adds space between buttons
$inBody->insert( 'end', " " );
# Reset Button
$temp = $inBody->Button(
-activebackground => "#F7DF8F",
-background => "#CCBB99",
-command => sub
{
$wkgDir = 'C:\Astell-THQ\wkg';
$initDir = '???';
$userDir = "";
$startDirFlag = 1;
$startDirState = 1;
@foundDirs = ();
$numDirs = 0;
$clearROA = 1;
$zipSource = 1;
$zipBase = "XXX";
$zipName = "";
$fixSpaces = 1;
$fixCase = 1;
$fixIncludes = 1;
$useCpp = 1;
$useC = 1;
$useH = 1;
$useHpp = 1;
$moreExts = "";
$destDirFlag = 1;
$destDirName = "XXX";
$userDestDir = "";
$destDir = "";
$overOld = 0;
$echoInput = 1;
$tempStr = "";
ScanWkgDir();
},
-font => "{Tahoma} 8 {bold}",
-text => "Reset Form" );
$inBody->windowCreate( 'end', -window => $temp );
# Adds space between buttons
$inBody->insert( 'end', " " );
# Quit Button
$temp = $inBody->Button(
-activebackground => "#F7DF8F",
-background => "#CCBB99",
-command => sub { exit; },
-font => "{Tahoma} 8 {bold}",
-text => "Quit" );
$inBody->windowCreate( 'end', -window => $temp );
$inBody->insert( 'end', "\n" );
# Output Window Button
$inBody->insert( 'end', "\n", '8n' );
$showOutWinBn = $inBody->Button(
-activebackground => "#F7DF8F",
-background => "#CCBB99",
-disabledforeground => "#EEEEEE",
-command => \&OpenOutWin,
-font => "{Tahoma} 8 {bold}",
-text => "Show Ouput Window" )
->pack(
-padx => 10,
-side => 'top' );
$inBody->windowCreate( 'end', -window => $showOutWinBn );
$inBody->insert( 'end', "\n" );
# Affects static elements but not inserted interactive widgets.
$inBody->configure( -state => 'disabled' ); # Disables user mucking with non-interactive widgets.
# Output Window
$outWin = $inWin->Toplevel();
$outWin->title( "Windows File Processing: Output" );
$outWin->configure( -background => "#DDDDDD" );
# Prevent inadvertent destruction of the window (withdraw it instead).
$outWin->protocol( 'WM_DELETE_WINDOW', sub
{
$outWin->withdraw;
} );
# Adjust window per screen resolution.
$outWin->geometry( $width . "x" . $height . "+" . ( 27 + $width ) . "+15" );
# Output Title Frame
$outTitleFr = $outWin->Frame( -background => "#DDDDDD" )
->pack(
-fill => 'x',
-pady => 2,
-side => 'top' );
# Output Title
$outTitleFr->Label(
-anchor => 'w',
-background => "#DDDDDD",
-font => "{Tahoma} 12 {bold}",
-text => "Output" )
->pack( -side => 'left' );
# Clear Output Button
$outTitleFr->Button(
-activebackground => "#F7DF8F",
-background => "#CCBB99",
-font => "{Tahoma} 8 {bold}",
-command => sub
{
$outBody->configure( -state => 'normal' );
$outBody->delete( "1.0", 'end' );
$outBody->configure( -state => 'disabled' );
},
-text => "Clear" )
->pack(
-padx => 10,
-side => 'right' );
# Visual Separator
$outWin->Canvas(
-background => "#888888",
-height => 2,
-highlightthickness => 0,
-takefocus => 0 )
->pack(
-fill => 'x',
-pady => 2,
-side => 'top' );
# Output Area
$outBody = $outWin->Scrolled( "Text",
-background => "#DDDDDD",
-cursor => 'arrow',
-font => "{Tahoma} 10 {normal}",
-relief => 'flat',
-scrollbars => 'osoe',
-wrap => 'word' )
->pack(
-expand => 1,
-fill => 'both',
-side => 'top' );
$outBody->tagConfigure( '10n', -font => "{Tahoma} 10 {normal}" );
$outBody->tagConfigure( '10b', -font => "{Tahoma} 10 {bold}" );
$outBody->tagConfigure( '12n', -font => "{Tahoma} 12 {normal}" );
$outBody->tagConfigure( '12b', -font => "{Tahoma} 12 {bold}" );
$outBody->tagConfigure( 'c10n', -font => "{Courier New} 10 {normal}" );
$outBody->tagConfigure( 'c10b', -font => "{Courier New} 10 {bold}" );
# Screen size warning
if ( $inWin->screenwidth() < 800 )
{
$outBody->insert( 'end', "Screen Size\n", '12b' );
$outBody->insert( 'end', "WARNING: ", '10b' );
$outBody->insert( 'end', "Screen size is small! " .
"You may have problems using this program at this resolution.\n", '10n' );
}
# Initial Message
$outBody->insert( 'end', "Output messages will appear here.\n" );
# User cannot change output contents.
$outBody->configure( -state => 'disabled' );
# Binding to toggle Show Output Window button (in Input Window) on and off.
# Binding is mapped to a specific widget in $outWin rather than $outWin itself
# (as otherwise the binding is triggered as each child in $outWin is mapped
# and unmapped).
$outBody->bind( "