home *** CD-ROM | disk | FTP | other *** search
/ Lighthouse Design Suite / LIGHTHOUSE.mdf / TaskMaster_1.8 / Application / FilterServicer.service / tm2diagram < prev    next >
Text File  |  1993-09-02  |  20KB  |  788 lines

  1. #
  2. #  tm2diagram
  3. #
  4. #  This file when used as input to perl will take a TaskMaster file and 
  5. #  generate a PERT diagram in Diagram!2 format.
  6. #
  7. #  Copyright (C) 1993 Lighthouse Design Ltd.
  8. #
  9. #  You may freely copy, distribute, and reuse the code in
  10. #  this example provided this copyright legend and disclaimer
  11. #  are preserved in all copies and derivative work.
  12. #
  13. #  Lighthouse Design disclaims any warranty of any kind,
  14. #  expressed or implied, as to this code's fitness
  15. #  for any particular use.
  16. #
  17.  
  18. #
  19. # NOTE: tweak these to show/hide various parts of the PERT.
  20. # Set to 0 if you don't want to see them, to 1 if you do.
  21. #
  22.  
  23. $showResources = 1;
  24. $showDates = 1;
  25. $showCriticalPath = 1;
  26.  
  27. #
  28. # variables
  29. #
  30. $taskWidth = 125;
  31. $taskHeight = 54;
  32. $taskTongueLength = 20;
  33. $taskHorizOffset = 30 + 2 * $taskTongueLength;
  34. $taskVertOffset = 50;
  35. $groupTaskTopBorder = 43;
  36. $groupTaskBottomBorder = ($showResources?27:20);
  37. $groupTaskBorder = 20;
  38. $resourceFieldHeight = 14;
  39. $rootTaskX = 10;
  40. $rootTaskY = 10;
  41. $taskStroke = 1.00;
  42. #$debug = "YES";
  43. $a = 0;        #hack to prevent compile warnings. used in &numerically
  44. $b = 0;
  45.  
  46. @ARGV;
  47.  
  48. if($ARGV[0] eq "-t"){
  49.     require "writedg.pl";
  50.     shift(@ARGV);
  51.     foreach $file (@ARGV) {
  52.     if (! open(GPBFILE,"< $file/CoreText.tmdata")) {
  53.         printf(STDERR "$file/CoreText not readable. Skipping $file\n");
  54.         next;
  55.     }
  56.         
  57.     $dirName = ".";
  58.     if ($file =~ /\//) {
  59.         $dirName = $file;
  60.         $dirName =~ s/\/[^\/]$//;
  61.     }
  62.     
  63.     $diagramFilename = $file;
  64.     $diagramFilename =~ s/taskmaster/diagram2/;
  65.  
  66.     &doFile();
  67.     #
  68.     #    Cleanup
  69.     #
  70.     
  71.     close(GPBFILE);
  72.     }
  73. }else{
  74.     require "$ARGV[2]/writedg.pl";
  75.     $| = 1;
  76.     if (! open(GPBFILE,"< $ARGV[0]/CoreText.tmdata")) {
  77.     printf(STDERR "$ARGV[0] not readable.\n\n");
  78.     exit 0;
  79.     }
  80.     $diagramFilename = $ARGV[1];
  81.     
  82. #    $silent = "YES";
  83.     &doFile();
  84.     close(GPBFILE);
  85. }
  86.  
  87. sub doFile{  
  88.     
  89.     $inTask = 0;
  90.     $taskNum = 0;
  91.     $title = "";
  92.     $inDependency = 0;
  93.     $depFrom = 0;
  94.     $depTo = 0;
  95.     $inScenario = 0;
  96.     $hasSchedulingInfo = 0;
  97.     $inResource = 0;
  98.     $inAssignment = 0;
  99.     if($silent){
  100.     $printDebugMessages = "";
  101.     }else{
  102.         $printDebugMessages = $debug;
  103.     }
  104.     
  105.     $taskNotified = 0;
  106.     $depNotified = 0;
  107.     $schedNotified = 0;
  108.     $resNotified = 0;
  109.     while (<GPBFILE>){    
  110.     #
  111.     #    TASK STUFF
  112.     #
  113.     $inTask == 0 && /^Task ([0-9]+)/ && do {
  114.         $inTask = 1;
  115.         print "Reading Tasks...\n\n" unless ($silent || $taskNotified);
  116.         $taskNotified = 1;
  117.         $taskNum = $1;
  118.         next;
  119.     };
  120.     
  121.     $inTask == 1 && /Title \"(.*)\"$/ && do {
  122.         $title = $1;
  123.         next;
  124.     };
  125.     
  126.     $inTask == 1 && /Parent (-?[0-9]+)/ && do {
  127.         if($1 <= 0){
  128.         $outlineNumber = "";
  129.         }else{
  130.         if(!$numKids{$1}){
  131.             $numKids{$1} = 1;
  132.         }else{
  133.             $numKids{$1}++;
  134.         }
  135.         if($outlineNumbers{$1}){
  136.             $outlineNumber = $outlineNumbers{$1}.".$numKids{$1}";
  137.         }else{
  138.             $outlineNumber = $numKids{$1};
  139.         }
  140.         if($children{$1}){
  141.             $children{$1} .= "$taskNum,";
  142.         }else{
  143.             $children{$1} = "$taskNum,";
  144.         }
  145.         }
  146.         $parent{$taskNum} = $1;
  147.         next;
  148.     };
  149.     
  150.     $inTask && /^end/ && do {
  151.         $titles{$taskNum} = $title;
  152.         $title = "";
  153.         $outlineNumbers{$taskNum} = $outlineNumber;
  154.         $beginningXValue{$taskNum} = -1.0;
  155.         $endingXValue{$taskNum} = -1.0;
  156.         $beginningYValue{$taskNum} = -1.0;
  157.         $endingYValue{$taskNum} = -1.0;
  158.         if($printDebugMessages){
  159.         print "initialized $taskNum\n";
  160.         }
  161.         $inTask = 0;
  162.     };
  163.     #
  164.     #    Scenario STUFF
  165.     #
  166.     $inScenario == 0 && /\#  DefaultScenario/ && do {
  167.         $inScenario = 1;
  168.         print "Reading Scheduling Info...\n\n" unless ($silent || $schedNotified);
  169.         $schedNotified = 1;
  170.         $hasSchedulingInfo = 1;
  171.     };
  172.     
  173.     $inScenario == 1 && /Task:([0-9]+)/ && do{
  174.         $taskNum = $1;
  175.     };
  176.  
  177.     $inScenario == 1 && /Start: \^(.*)\^/ && do{
  178.         $taskStartDate{$taskNum} = $1;
  179.     };
  180.  
  181.     $inScenario == 1 && /End: \^(.*)\^/ && do{
  182.         $taskEndDate{$taskNum} = $1;
  183.     };
  184.     
  185.     $inScenario == 1 && /IsCritical:(YES|NO)/ && do{
  186.         if($1 =~ /YES/){
  187.         $critical{$taskNum} = 1;
  188.         }else{
  189.         $critical{$taskNum} = 0;
  190.         }
  191.     };
  192.     
  193.     $inScenario == 1 && /^end/ && do{
  194.         $inScenario = 0;
  195.     };
  196.     
  197.     #
  198.     #    Dependency STUFF
  199.     #
  200.     $inDependency == 0 && /^Dependency ([0-9]+) DependsOn ([0-9]+)/ && do {
  201.         $inDependency = 1;
  202.         print "Reading Dependencies...\n\n" unless ($silent || $depNotified);
  203.         $depNotified = 1;
  204.         $depFrom = $2;
  205.         $depTo = $1;
  206.         next;
  207.     };
  208.     
  209.     $inDependency && /^end/ && do {
  210.         push(@fromList,$depFrom);
  211.         push(@toList,$depTo);
  212.         if($predecessors{$depTo}){
  213.         $predecessors{$depTo} .= "$depFrom,";
  214.         }else{
  215.         $predecessors{$depTo} = "$depFrom,";
  216.         }
  217.         if($successors{$depFrom}){
  218.         $successors{$depFrom} .= "$depTo,";
  219.         }else{
  220.         $successors{$depFrom} = "$depTo,";
  221.         }
  222.         $inDependency = 0;
  223.     };
  224.  
  225.     #
  226.     #    Resource STUFF
  227.     #
  228.     $inResource == 0 && /^Resource ([0-9]+)/ && do {
  229.         $inResource = 1;
  230.         print "Reading Resources...\n\n" unless ($silent || $resNotified);
  231.         $resNotified = 1;
  232.         $resNum = $1;
  233.         next;
  234.     };
  235.  
  236.     $inResource == 1 && /Name (.*)$/ && do {
  237.         $1 =~ /^\"(.*)\"$/;
  238.         $resourceName{$resNum} = $1;
  239.         next;
  240.     };
  241.  
  242.     $inResource == 1 && /^end/ && do {
  243.         $inResource = 0;
  244.         next;
  245.     };
  246.  
  247.     #
  248.     #    Assignment STUFF
  249.     #
  250.     $inAssignment == 0 && /^ScheduledEvent (\d+) (\d+) (\d+)/ && do {
  251.         $inAssignment = 1;
  252.         print "Reading Assignments...\n\n" unless ($silent || $assignNotified);
  253.         $assignNotified = 1;
  254.         $currentAssignmentTask = $2;
  255.         next;
  256.     };
  257.  
  258.     $inAssignment == 1 && /Assignment (\d+) (\d+)/ && do {
  259.         if($1 <= 3){
  260.         next;
  261.         }
  262.         if($taskAssignments{$currentAssignmentTask}){
  263.         $taskAssignments{$currentAssignmentTask} .= ", $resourceName{$1}";
  264.         }else{
  265.         $taskAssignments{$currentAssignmentTask} = "$resourceName{$1}";
  266.         }
  267.         next;
  268.     };
  269.  
  270.     $inAssignment == 1 && /^end/ && do {
  271.         $inAssignment = 0;
  272.         next;
  273.     };
  274.     
  275.     next;
  276.     }
  277.  
  278. #
  279. #    Calculate the tasks' X values
  280. #
  281.  
  282.     print "Calculating the X positions...\n\n" unless $silent; 
  283.     &calcAllX(1);            
  284.  
  285.  
  286. #
  287. #    Calculate the tasks' Y values
  288. #
  289.   
  290.     print "Calculating the Y positions...\n\n" unless $silent;
  291.     &calcHeights(1);
  292.     &calcYs(1);
  293.  
  294. #
  295. #    Graphic Stuff
  296. #
  297.     $numGroupLayers = &calcNumGroups(1);
  298.     $numLeafLayers = &calcNumLeaves(1);
  299.     $numLineLayers = &calcNumDependencies(1);
  300.     $numVertexLayers = 2*$numLineLayers;
  301.     
  302.     $currentLeafLayer = 1;
  303.     $currentVertexLayer = $currentLeafLayer + $numLeafLayers;
  304.     $currentLineLayer = $currentVertexLayer + $numVertexLayers;
  305.     $currentGroupLayer = $currentLineLayer+$numLineLayers+$numGroupLayers;
  306.  
  307. #
  308. #    Calc pagesize
  309. #
  310.     $numHorizPages = int(($endingXValue{1} / 756.0) + 1.0);
  311.     $numVertPages = int(($endingYValue{1} / 576.0) + 1.0);
  312.     if((1/$numHorizPages) < (1/$numVertPages)){
  313.     $zoom = (1/$numHorizPages);
  314.     }else{
  315.     $zoom = (1/$numVertPages);
  316.     }
  317.  
  318. #
  319. #      Setup file
  320.     &setDebugging(1) unless !$debug;
  321.     $theDocument = &newDocument(); 
  322.     &setDocumentButtons($theDocument, 1);
  323.     &setDocumentDefaultFont($theDocument, "Helvetica", 10.0);
  324.     &setDocumentCanvasSize($theDocument, $numHorizPages, $numVertPages);
  325.     &setDocumentZoom($theDocument, $zoom);
  326.  
  327. #
  328. # create tasks
  329. #
  330.     print "Drawing Tasks...\n\n" unless $silent;
  331.     &doAllFromRoot();
  332.  
  333. #
  334. # create dependencies
  335. #
  336.     print "Drawing Dependencies...\n\n" unless $silent;
  337.     foreach $ct (0 .. $#fromList){
  338.     $theLine = &newLine($theDocument, $fromPoint{$fromList[$ct]}, $toPoint{$toList[$ct]});
  339.     &setObjectLayer($theLine, $currentLineLayer++);
  340.     if($showCriticalPath && $critical{$fromList[$ct]} && $critical{$toList[$ct]}){
  341.         &setObjectFrameColor($theLine, 1, 0, 0);
  342.     }
  343.     }
  344.     
  345.     print "Writing File...\n\n" unless $silent;
  346.  
  347.     &writeDocument($theDocument, $diagramFilename);
  348.  
  349.     print "Done.\n\n" unless $silent;
  350.     sleep 1;
  351. }
  352.  
  353. #
  354. #    Graphic Setup subroutines
  355. #
  356.  
  357. sub calcNumGroups {
  358.     $tempTask = $_[0];
  359.     local($totalNum, $theTask, $kid);
  360.     $theTask = $tempTask;
  361.     $totalNum = 0;
  362.     if($children{$theTask}){
  363.     foreach $kid (split(/,/ , $children{$theTask})){
  364.         $totalNum += &calcNumGroups($kid);
  365.     }
  366.     $totalNum++;
  367.     }
  368.     return($totalNum);
  369. }
  370.  
  371. sub calcNumLeaves {
  372.     $tempTask = $_[0];
  373.     local($totalLeaves, $theTask, $kid);
  374.     $theTask = $tempTask;
  375.     $totalLeaves = 0;
  376.     if($children{$theTask}){
  377.     foreach $kid (split(/,/ , $children{$theTask})){
  378.         $totalLeaves += &calcNumLeaves($kid);
  379.     }
  380.     }else{
  381.     $totalLeaves = 1;
  382.     }
  383.     return($totalLeaves);
  384. }
  385.  
  386. sub calcNumDependencies {
  387.     $tempTask = $_[0];
  388.     local($totalDependencies, $theTask, $kid, @deps);
  389.     $theTask = $tempTask;
  390.     if($predecessors{$theTask}){
  391.     @deps = (split(/,/ , $predecessors{$theTask}));
  392.     $totalDependencies = $#deps +1;
  393.     }else{
  394.     $totalDependencies = 0;
  395.     }
  396.     if($children{$theTask}){
  397.     foreach $kid (split(/,/ , $children{$theTask})){
  398.         $totalDependencies += &calcNumDependencies($kid);
  399.     }
  400.     }
  401.     return($totalDependencies);
  402. }
  403.  
  404. #
  405. #     XValue subroutines
  406. #
  407.  
  408. sub calcAllX {
  409.     $tempTask = $_[0];
  410.     local($theTask);
  411.     $theTask = $tempTask;
  412.     if($printDebugMessages){
  413.     print "\ncalcAllX $theTask\n";
  414.     }
  415.  
  416.     &calcBeginningX($theTask);
  417.     &calcChildrenX($theTask);
  418.     &calcEndingX($theTask);
  419.     &checkBeginningX($theTask);
  420. }
  421.  
  422. sub calcBeginningX {
  423.     $tempTask = $_[0];
  424.     local($theTask, $pred);
  425.     $theTask = $tempTask;
  426.     
  427.     # root special case
  428.     if(($theTask) == 1){
  429.     &calcBegX($theTask);
  430.     return 1;
  431.     }
  432.     
  433.     if($beginningXValue{$theTask} != -1.0){
  434.     return 1;
  435.     }
  436.     if($beginningXValue{$parent{$theTask}} == -1.0){
  437.     &calcBeginningX($parent{$theTask});
  438.     }
  439.     if($predecessors{$theTask}){
  440.     foreach $pred (split(/,/ , $predecessors{$theTask})){
  441.         if($endingXValue{$pred} < 0){
  442.         &calcAllX($pred);
  443.         }
  444.     }
  445.     }
  446.     &calcBegX($theTask);
  447. }
  448.  
  449. sub calcChildrenX {
  450.     $tempTask = $_[0];
  451.     local($theTask, $kid);
  452.     $theTask = $tempTask;
  453.     if($children{$theTask}){
  454.     foreach $kid (split(/,/ , $children{$theTask})){
  455.         &calcAllX($kid);
  456.     }
  457.     }
  458. }
  459.  
  460. sub calcEndingX {
  461.     &calcEndX($_[0]);
  462. }
  463.  
  464. sub checkBeginningX {
  465.     $tempTask = $_[0];
  466.     local($theTask, $kid, $minChildX);
  467.     $theTask = $tempTask;
  468.     if($children{$theTask}){
  469.     $minChildX = $endingXValue{$theTask};
  470.     foreach $kid (split(/,/ , $children{$theTask})){
  471.         if($beginningXValue{$kid} < $minChildX){
  472.         $minChildX = $beginningXValue{$kid};
  473.         }
  474.     }
  475.     $beginningXValue{$theTask} = $minChildX - $groupTaskBorder;
  476.     }
  477. }
  478.  
  479. sub calcBegX {
  480.     $tempTask = $_[0];
  481.     local($theTask, $maxX, $parentX, $pred, $x);
  482.     $theTask = $tempTask;
  483.     if($printDebugMessages){
  484.     print "calc'ed XBeginning of: $theTask\n";
  485.     }
  486.     if($theTask == 1){
  487.     $beginningXValue{$theTask} = $rootTaskX;
  488.     return 1;
  489.     }
  490.     $parentX = $beginningXValue{$parent{$theTask}};
  491.     $maxX = $parentX;
  492.     if($predecessors{$theTask}){
  493.     foreach $pred (split(/,/ , $predecessors{$theTask})){
  494.         $x = $endingXValue{$pred};
  495.         if ($x > $maxX){
  496.         $maxX = $x;
  497.         }
  498.     }
  499.     }
  500.     if($maxX == $parentX){
  501.     $beginningXValue{$theTask} = $maxX + $groupTaskBorder;
  502.     }else{
  503.     $beginningXValue{$theTask} = $maxX + $taskHorizOffset;
  504.     }
  505. }
  506.     
  507. sub calcEndX {
  508.     $tempTask = $_[0];
  509.     local($theTask, $maxX, $kid, $x);
  510.     $theTask = $tempTask;
  511.     
  512.     if($printDebugMessages){
  513.     print "calc'ed XEnding of: $theTask\n";
  514.     }
  515.     if($children{$theTask}){
  516.     $maxX = 0.0;
  517.     foreach $kid (split(/,/ , $children{$theTask})){
  518.         $x = $endingXValue{$kid};
  519.         if ($x > $maxX){
  520.         $maxX = $x;
  521.         }
  522.     }
  523.     $endingXValue{$theTask} = $maxX + $groupTaskBorder;
  524.     }else{
  525.     $endingXValue{$theTask} = $beginningXValue{$theTask} + $taskWidth;
  526.     }
  527. }
  528.  
  529. #
  530. #     YValue subroutines
  531. #
  532.  
  533. sub calcHeights {
  534.     $tempTask = $_[0];
  535.     local($theTask, $theOffset, @theChains, $temp);
  536.     $theTask = $tempTask;
  537.     if($printDebugMessages){
  538.     print "calcHeight: $outlineNumbers{$theTask}\n";
  539.     }
  540.     if($children{$theTask}){
  541.     foreach $kid (split(/,/ , $children{$theTask})){
  542.         if(&isChainBase($kid)){
  543.         push(@theChains, $kid);
  544.         }
  545.     }
  546.     $theOffset = $groupTaskTopBorder;
  547.     foreach $kid (sort sequentially @theChains){
  548.         $chainOffset{$kid} = $theOffset;
  549.         $temp = &calcChainHeights($kid, 0);
  550.         $theOffset +=  $temp + $taskVertOffset;
  551.     }
  552.     $theOffset += $groupTaskBottomBorder - $taskVertOffset;
  553.     $height{$theTask} = $theOffset;
  554.     }else{
  555.     $height{$theTask} = $taskHeight;
  556.     }
  557. }
  558.  
  559. sub calcChainHeights {
  560.     $tempTask = $_[0];
  561.     $tempHeight = $_[1];
  562.     local($theTask, $succ, $siblings, $succsHeight, $myHeight, $currentHeight, @succs, $passHeight);
  563.     $theTask = $tempTask;
  564.     $currentHeight = $tempHeight;
  565.     
  566.     if($printDebugMessages){
  567.     print "calcChainHeights:$outlineNumbers{$theTask} withHeight:$currentHeight\n";
  568.     }
  569.     $siblings = "";
  570.     foreach $sib (split(/,/, $children{$parent{$theTask}})){
  571.     $siblings .= "($outlineNumbers{$sib})";
  572.     }
  573.     if($height{$theTask}){
  574.     if($printDebugMessages){
  575.         print "Already calculated height for $outlineNumbers{$theTask}\n";
  576.     }         
  577.     return 0;
  578.     }
  579.     $myHeight = &calcHeights($theTask);
  580.     foreach $succ (split(/,/ , $successors{$theTask})){
  581.     $checkString = "($outlineNumbers{$succ})";
  582.     if(index($siblings, $checkString)>=0){
  583.         push(@succs, $succ);
  584.     }
  585.     }
  586.     if ($#succs > 0){
  587.     $passHeight = 0;
  588.     }elsif($myHeight > $currentHeight){
  589.     $passHeight = $myHeight;
  590.     }else{
  591.     $passHeight = $currentHeight;
  592.     }
  593.     $succsHeight = 0.0;
  594.     foreach $succ (sort sequentially @succs){
  595.     if(!$height{$succ}){
  596.         $chainOffset{$succ} = $chainOffset{$theTask} + $succsHeight;
  597.         $succsHeight += &calcChainHeights($succ, $passHeight) + $taskVertOffset;
  598.     }
  599.     }
  600.     $succsHeight -= $taskVertOffset;
  601.     if($succsHeight > $currentHeight && $succsHeight > $myHeight){
  602.     $chainHeight{$theTask} = $succsHeight;
  603.     }elsif($currentHeight > $myHeight){
  604.     $chainHeight{$theTask} = $currentHeight;
  605.     }else{
  606.     $chainHeight{$theTask} = $myHeight;
  607.     }
  608. }
  609.     
  610. sub calcYs {
  611.     $tempTask = $_[0];
  612.     local($theTask, $kid);
  613.     $theTask = $tempTask;
  614.     if($printDebugMessages){
  615.     print "calcYs: $outlineNumbers{$theTask}\n";
  616.     }
  617.     
  618.     if($theTask == 1){
  619.     $beginningYValue{$theTask} = $rootTaskY;
  620.     }else{
  621.     $beginningYValue{$theTask} = $beginningYValue{$parent{$theTask}} + $chainOffset{$theTask} + ($chainHeight{$theTask}-$height{$theTask})/2;
  622.     }
  623.     if($printDebugMessages && $theTask != 1){
  624.     print "calcYs: $outlineNumbers{$theTask} -> $beginningYValue{$theTask} calc $beginningYValue{$parent{$theTask}} offset:$chainOffset{$theTask}  chainHeight:$chainHeight{$theTask}\n";
  625.     }
  626.     $endingYValue{$theTask} = $beginningYValue{$theTask} + $height{$theTask};
  627.     
  628.     if($children{$theTask}){
  629.     foreach $kid (split(/,/ , $children{$theTask})){
  630.         &calcYs($kid);
  631.     }
  632.     }
  633. }
  634.  
  635. sub isChainBase {
  636.     $tempTask = $_[0];
  637.     local($theTask, $pred, $siblings);
  638.     $theTask = $tempTask;
  639.     $siblings = "";
  640.     foreach $sib (split(/,/, $children{$parent{$theTask}})){
  641.     $siblings .= "($outlineNumbers{$sib})";
  642.     }
  643.     foreach $pred (split(/,/ , $predecessors{$theTask})){
  644.     $checkString = "($outlineNumbers{$pred})";
  645.     if(index($siblings, $checkString) >= 0){
  646.         return 0;
  647.     }
  648.     }
  649.     if($printDebugMessages){
  650.     print "found chain base:$outlineNumbers{$theTask}\n";
  651.     }
  652.     return 1;
  653. }
  654.  
  655. sub doAllFromRoot{
  656.     local($kid);
  657.     
  658.     foreach $kid (split(/,/ , $children{1})){
  659.     &doTask($kid);
  660.     }
  661. }
  662.  
  663. sub doTask {
  664.     $tempTask = $_[0];
  665.     local($theTask, $width, $height, $layer, $kid, $startField, $endField);
  666.     $theTask = $tempTask;
  667.  
  668.     if($children{$theTask}){
  669.     $layer = $currentGroupLayer;
  670.     $currentGroupLayer--;
  671.     }else{
  672.     $layer = $currentLeafLayer;
  673.     $currentLeafLayer++;
  674.     }
  675.  
  676.     $width = $endingXValue{$theTask}-$beginningXValue{$theTask};
  677.     $height = $endingYValue{$theTask}-$beginningYValue{$theTask};
  678.     $theTaskSymbol = &newSymbol($theDocument, "Rectangle", $beginningXValue{$theTask}, $beginningYValue{$theTask}, $width, $height);
  679.     &setObjectFramed($theTaskSymbol, 1);
  680.     if($showCriticalPath && $critical{$theTask}){
  681.     &setObjectFrameColor($theTaskSymbol, 1, 0, 0);
  682.     }
  683.     if($titles{$theTask}){
  684.     $taskString = "\{\\rtf0\\ansi\{\\fonttbl\\f0\\fswiss Helvetica;\}\\margl40\\margr40\\pard\\tx440\\tx1320\\tx1760\\tx2220\\tx2660\\tx3100\\tx3540\\tx4000\\tx4440\\f0\\b0\\i0\\ulnone\\fs20\\fc0\\cf0 Task $outlineNumbers{$theTask}\\\n\\b $titles{$theTask}\}";
  685.     }elsif($outlineNumbers{$theTask}){
  686.     $taskString = "\{\\rtf0\\ansi\{\\fonttbl\\f0\\fswiss Helvetica;\}\\margl40\\margr40\\pard\\tx440\\tx1320\\tx1760\\tx2220\\tx2660\\tx3100\\tx3540\\tx4000\\tx4440\\f0\\b0\\i0\\ulnone\\fs20\\fc0\\cf0 Task $outlineNumbers{$theTask}\}";
  687.     }
  688.     &setObjectRtfText($theTaskSymbol, $taskString);
  689.     &setObjectTextPlacement($theTaskSymbol, "top");
  690.     &setObjectFilled($theTaskSymbol, 1);
  691.     &setObjectLineWidth($theTaskSymbol, $taskStroke);
  692.  
  693.     @groupList = ($theTaskSymbol);
  694.  
  695.     #
  696.     #  Start/End dates
  697.     #
  698.     if($showDates && $hasSchedulingInfo){
  699.     $startField = &newSymbol($theDocument, "Rectangle", $beginningXValue{$theTask} - 2.0, $beginningYValue{$theTask} - 12.0, $width, 14);
  700.     &setObjectFramed($startField, 0);
  701.     &setObjectText($startField, $taskStartDate{$theTask});
  702.     &setObjectTextPlacement($startField, "top");
  703.     
  704.     $endField = &newSymbol($theDocument, "Rectangle", $beginningXValue{$theTask} - 2.0, $endingYValue{$theTask} - 2.0, $width, 14);
  705.     &setObjectFramed($endField, 0);
  706.     &setObjectText($endField, $taskEndDate{$theTask});
  707.     &setObjectTextPlacement($endField, "top");
  708.     
  709.     push(@groupList, $startField, $endField);
  710.     }
  711.  
  712.     #
  713.     #  Resources 
  714.     #
  715.     if($showResources && $taskAssignments{$theTask}){
  716.     $yLocation = $endingYValue{$theTask}+ ($showDates && $hasSchedulingInfo?10:-2);
  717.     $resourceField = &newSymbol($theDocument, "Rectangle", $beginningXValue{$theTask} - 2.0, $yLocation, $width, $resourceFieldHeight);
  718.     &setObjectFramed($resourceField, 0);
  719.     &setObjectRtfText($resourceField, "\{\\rtf0\\ansi\{\\fonttbl\\f0\\fswiss Helvetica;\}\\margl40\\margr40\\pard\\tx444\\tx889\\tx1334\\tx1779\\tx2223\\tx2668\\tx3113\\tx3558\\tx4003\\tx4447\\f0\\b0\\i\\ulnone\\fs20\\fc0\\cf0 $taskAssignments{$theTask}\}");
  720.     &setObjectTextPlacement($resourceField, "top");
  721.     push(@groupList, $resourceField);
  722.     }
  723.  
  724.     #
  725.     #  Tongues
  726.     #
  727.     if($successors{$theTask}){
  728.     $tongue = &newLine($theDocument, $theTaskSymbol, $theTaskSymbol);
  729.     @verts = &vertexesForLine($tongue);
  730.     $fromPoint{$theTask} = $verts[1];
  731.     &setObjectLocation($verts[1], $endingXValue{$theTask} + $taskTongueLength, $beginningYValue{$theTask} + $height/2.0);
  732.     &setLineTo($tongue, $verts[1]);
  733.     if($showCriticalPath && $critical{$theTask}){
  734.         &setObjectFrameColor($tongue, 1, 0, 0);
  735.     }
  736.     &setLineTailType($tongue, "circle");
  737.     push(@groupList, $tongue, @verts);
  738.     }
  739.     if($predecessors{$theTask}){
  740.     $tongue = &newLine($theDocument, $theTaskSymbol, $theTaskSymbol);
  741.     @verts = &vertexesForLine($tongue);
  742.     $toPoint{$theTask} = $verts[0];
  743.     &setObjectLocation($verts[0], $beginningXValue{$theTask} - $taskTongueLength, $beginningYValue{$theTask} + $height/2.0);
  744.     &setLineFrom($tongue, $verts[0]);
  745.     if($showCriticalPath && $critical{$theTask}){
  746.         &setObjectFrameColor($tongue, 1, 0, 0);
  747.     }
  748.     &setLineHeadType($tongue, "arrow");
  749.     push(@groupList, $tongue, @verts);
  750.     }
  751.     $theTaskGroup = &newGroup($theDocument, @groupList);
  752.     &setObjectLayer($theTaskGroup, $layer);
  753.     if($children{$theTask}){
  754.     &setObjectLocked($theTaskGroup, 1);
  755.     }
  756.     #
  757.     #    now the kids
  758.     #
  759.    foreach $kid (split(/,/ , $children{$theTask})){
  760.     &doTask($kid, $layer-1);
  761.     }
  762. }
  763.  
  764. sub sequentially { 
  765.     local(@aThing, @bThing, $ct);
  766.     return 0 if !$a;
  767.     return 1 if !$b;
  768.     @aThing = split(/\./,$outlineNumbers{$a});
  769.     @bThing = split(/\./,$outlineNumbers{$b});
  770.     for($ct=0; $ct <= $#aThing; $ct++){
  771.     if(!$bThing[$ct]){
  772.         return 0;
  773.     }
  774.     if($aThing[$ct] < $bThing[$ct]){
  775.         return 0;
  776.     }
  777.     if($aThing[$ct] > $bThing[$ct]){
  778.         return 1;
  779.     }
  780.     }
  781.     return 1;
  782. }
  783.  
  784. # Place Emacs into Perl-mode
  785. # Local Variables:
  786. # mode: perl
  787. # End:
  788.