#!/usr/bin/perl ######################################################################### #************************************************************** # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #************************************************************** #################################################################### # File Name: converterlib.pm # Version : 1.0 # Project : XMerge # Author : Brian Cameron # Date : 5th Sept. 2001 # # This script enters text at position x,y on screen. # # Parameter # x-coordinate # y-coordinate # Text to enter # ########################################################################## use EmRPC; # EmRPC::OpenConnection, CloseConnection use EmFunctions; use EmUtils; # Set global_debug flag # $global_debug = $ENV{'ZENDEBUG'}; #$em_script_home = "/export/home/test/qadir/bin"; $em_script_home = $ENV{'EM_SCRIPT_HOME'}; #$qa_script_home = "/export/home/test/qadir/qa-new/bin"; $qa_script_home = $ENV{'QA_SCRIPT_HOME'}; # # CONVERT FUNCTIONS # # convert_to_pdb # directory - directory containing the xml-orig and pdb-orig # subdirectories. # file - file to convert # extension - extension of file to convert (sxw or sxc) # convert_to - what PDB format to convert into. # # Returns 0 if success, -1 otherwise. # # Converts file from XML to PDB # sub convert_to_pdb { my $directory = $_[0]; my $file = $_[1]; my $extension = $_[2]; my $convert_to = $_[3]; my $pdb_directory = $_[4]; my $rc = 0; my $xmlfile = "$directory/$file.$extension"; my $pdbdir = "$pdb_directory"; &enter_func("convert_to_pdb"); if (! -f "$xmlfile") { print "\nERROR, file $xmlfile does not exist\n"; $rc = -1; } if (! -d "$pdbdir") { print "\nERROR, directory $directory/pdb-orig does not exist\n"; $rc = -1; } if ($rc != -1) { if ("$convert_to" eq "application/x-minicalc") { # Move all files over. # my $i = 1; while (-f "$pdbdir/$file-Sheet$i.pdb") { my $pdbfile = "$pdbdir/$file-Sheet$i.pdb"; print "\n"; if (-f "$pdbfile.old") { print "Removing $pdbfile.old\n"; `/bin/rm -f $pdbfile.old`; } print "Moving $pdbfile file to $pdbfile.old\n"; `mv "$pdbfile" "$pdbfile.old"`; $i++; } } else { if (-f "$pdbdir/$file.pdb") { print "\n"; if (-f "$pdbdir/$file.pdb.old") { print "Removing $pdbdir/$file.pdb.old\n"; `/bin/rm -f $pdbdir/$file.pdb.old`; } print "Moving $pdbdir/$file.pdb file to $pdbdir/$file.pdb.old\n"; `mv "$pdbdir/$file.pdb" "$pdbdir/$file.pdb.old"` } } &start_rd($extension, $convert_to, $xmlfile, ""); if ("$convert_to" eq "application/x-minicalc") { # Must handle minicalc separately since it can # convert to multiple files with this file name # convention. # print "Moving $file-Sheet*.pdb files to $pdbdir\n"; `mv $file-Sheet*.pdb $pdbdir`; `chmod 666 $pdbdir/$file-*.pdb`; } else { print "Moving $file.pdb file to $pdbdir\n"; `mv $file.pdb $pdbdir`; `chmod 666 $pdbdir/$file.pdb`; } } &leave_func("convert_to_pdb"); return $rc; } # convert_to_xml # xmldir - directory to contain the xml output. # xmlorigdir - directory to contain the xml input (used for merge) # pdbfile - file to convert # convert_from - what PDB format to convert from. # extension - extension of file to convert (sxw or sxc) # output - output filename to create # merge_opt - 1 if convert and merge, 0 if convert only # # Returns 0 if success, -1 otherwise. # # Converts file from PDB to XML # sub convert_to_xml { my $xmldir = $_[0]; my $xmlorigdir = $_[1]; my $pdbfile = $_[2]; my $convert_from = $_[3]; my $extension = $_[4]; my $output = $_[5]; my $merge_opt = $_[6]; my $rc = 0; &enter_func("convert_to_xml"); my @args = split(/ /,$pdbfile); for ($i=0;$i <= $#args; $i++) { if (! -f "@args[$i]") { print "\nERROR, file $pdbfile does not exist\n"; $rc = -1; } } if (! -f "$xmlorigdir/$output.$extension") { print "\nERROR, file $xmlorigdir/$output.$extension does not exist\n"; $rc = -1; } if (! -d "$xmldir") { print "\nERROR, directory $xmlorigdir does not exist\n"; $rc = -1; } if (! -d "$xmlorigdir") { print "\nERROR, directory $xmldir does not exist\n"; $rc = -1; } if ($rc != -1) { if ($merge_opt == 1) { print "Copying <$xmlorigdir/$output.$extension> to <$xmldir>\n"; `cp $xmlorigdir/$output.$extension $xmldir/`; my $check_stamp = (stat("$xmldir/$output.$extension"))[9]; &start_rd($convert_from, $extension, $pdbfile, "$xmldir/$output.$extension"); # No need to move the file to the $xmldir since the merge # argument specifies the output file. my $check_stamp_update = (stat("$xmldir/$output.$extension"))[9]; if ($check_stamp eq $check_stamp_update) { print "\nERROR, Problem while merging <$xmldir/$output.$extension>\n"; `mv $xmldir/$output.$extension $xmldir/$output.$extension.err`; } } else { &start_rd($convert_from, $extension, $pdbfile, ""); print "Moving $output.$extension to $xmldir\n"; `mv $output.$extension $xmldir`; `chmod 666 $xmldir/$output.$extension`; } } &leave_func("convert_to_xml"); return $rc; } # start_rd # from - format to convert from # to - format to convert to # file - file to convert # merge - merge filename ("" indicates convert-only with no merge) # # converts file from/to the specified formats. # sub start_rd { my $from = $_[0]; my $to = $_[1]; my $file = $_[2]; my $merge = $_[3]; print "\nConverting from $from to $to.\n"; if ($global_debug) { &print_debug ("rd command is:\n"); } if ($merge eq "") { &print_debug (" $em_script_home/rd -from $from -to $to $file\n"); print "\nConverting from $from to $to with no merge.\n"; `$em_script_home/rd -from $from -to $to $file`; } else { &print_debug (" $em_script_home/rd -from $from -to $to -merge $merge $file\n"); print "\nConverting from $from to $to with merge.\n"; `$em_script_home/rd -from $from -to $to -merge $merge $file`; } print "Done converting.\n\n"; } # # POSE INTERACTION FUNCTIONS # # open_connection # display_debug - debug will be displayed if not 0 # # Opens the connection to pose. # sub open_connection { my $display_debug = $_[0]; my $rc; EmRPC::OpenConnection(6415, "localhost"); if ($display_debug && $global_debug) { print "\nPose Connection Opened\n"; } } # close_connection # display_debug - debug will be displayed if not 0 # # Closes the connection to pose. # sub close_connection { my $display_debug = $_[0]; EmRPC::CloseConnection(); if ($display_debug && $global_debug) { print "\nPose Connection Closed\n"; } } # start_pose # pose_exe - name of pose executable. # apps_load - The PRC files to load into pose, can be a comma # separated list. # run_prog - Program to run at startup. # timeout - Timeout value to use when starting pose. # # Starts the Palm OS Emulator, loads PRC files, and starts # a program. # sub start_pose { my $pose_exe = $_[0]; my $sessionfile = $ENV{'EM_SESSION_FILE'}; my $romfile = $ENV{'EM_ROM_FILE'}; my $apps_load = $_[1]; my $run_prog = $_[2]; my $timeout = $_[3]; my $stay_in_loop = 1; my $address; my $title; my $form; my $label_id; my $num_objects; my $i; my $ii; my $rc = 1; my $pose_cmd = "$pose_exe "; $pose_cmd .= " -psf $sessionfile "; $pose_cmd .= "-load_apps $apps_load "; $pose_cmd .= "-run_app $run_prog"; # It is more effective to use the -psf argument to # set these values. # # $pose_cmd .= -rom $romfile "; # $pose_cmd .= "-ram_size 8192 "; # $pose_cmd .= "-device PalmVx "; &enter_func("start_pose"); if ($global_debug) { &print_debug("\n"); &print_debug("pose command is:\n"); &print_debug(" $pose_cmd\n"); } print "\nLaunching pose...\n"; system ("$pose_cmd &"); # Give time for pose to get started... # for ($i=0; $i < $timeout; $i++) { $tmp = $i + 1; print "$tmp\n"; # Do not use pose_sleep here # sleep(1); } # Verify pose started successfully, and fail otherwise... # $rc = &verify_pose(5); if ($rc != 0) { $stay_in_loop = 0; } else { # Sleep before opening the connection again, after testing in # the verify_pose function. # pose_sleep(2); &open_connection(1); print "\nChecking if the appropriate window is on screen...\n"; } # Stop looping when the specified window has started. # for ($i=0; $i < $timeout && $stay_in_loop == 1; $i++) { $form = FrmGetActiveForm(); $num_objects = FrmGetNumberOfObjects($form); for $ii (0..$num_objects - 1) { my ($object_type) = FrmGetObjectType($form, $ii); if ("$run_prog" eq "Quickword") { if ($object_type == frmTitleObj) { ($address, $title) = FrmGetTitle($form,); # Display count and title. # $tmp = $i + 1; print "$tmp - title is $title\n"; if ("$title" eq "Quickword") { $stay_in_loop = 0; $rc = 0; last; } } } elsif ("$run_prog" eq "MiniCalc") { if ($object_type == frmLabelObj) { $label_id = FrmGetObjectId ($form, $ii); ($address, $label) = FrmGetLabel($form, $label_id); # Display count and label. # $tmp = $i + 1; print "$tmp - label is $label\n"; if ("$label" =~ "Solutions In Hand") { $stay_in_loop = 0; $rc = 0; last; } } } } # Do not use pose_sleep here # sleep(1); } # Do not use pose_sleep here # sleep(1); &leave_func("start_pose"); return($rc); } # kill_pose # # Kills all pose processes # sub kill_pose { if ($global_debug) { print "Stopping pose process...\n"; } `pkill pose`; } # verify_pose # timeout - timeout to wait for pose # # Tries to do a connect/close to Pose to see if # it is working okay. # sub verify_pose { my $timeout = $_[0]; my $rc = 0; $rc = system("$em_script_home/verify_sane.pl $timeout"); return $rc; } # db_export # dbname - Name of database to export # # Exports a palmdb file to /tmp # sub db_export { my $dbname = $_[0]; &enter_func("db_export"); print "\nExporting PDB file <$dbname> from pose\n"; &pose_tap_pen(22, 20, 2); &pose_tap_pen (15, 85, 2); &enter_string($dbname, 1); &pose_tap_pen (15, 126, 1); &enter_string("/tmp/", 1); &pose_tap_button("OK", 4); &tap_applications(3); print "Export of PDB file <$dbname> completed.\n"; &leave_func("db_export"); } # # QUICKWORD SPECIFIC # # start_quickword # # Assuming pose was launched with the -run_app flag to launch # QuickWord on startup, this starts up QuickWord with the first # file in the list and turns off write-protect. # sub start_quickword { &enter_func("start_quickword"); # This will open the first file in the list. # Assuming this will always be the case. # &pose_tap_pen(20, 18, 1); &quickword_press_write_protect(); &leave_func("start_quickword"); } # quickword_press_write_protect # # Useful function for pressing the write protect button # to allow changes to be made. # sub quickword_press_write_protect { &enter_func("quickword_press_write_protect"); my ($form) = FrmGetActiveForm(); my ($num_objects) = FrmGetNumberOfObjects($form); for $ii (0..$num_objects - 1) { my ($object_type) = FrmGetObjectType($form, $ii); # The write protect button is the only frmGadgetObj # on the QuickWord screen. # if ($object_type == frmGadgetObj) { my (%bounds) = FrmGetObjectBounds($form, $ii); if ($global_debug) { &print_debug(" Found QuickWord WriteProtect button\n"); &print_debug(" left = $bounds{left}\n"); &print_debug(" right = $bounds{right}\n"); &print_debug(" top = $bounds{top}\n"); &print_debug(" bottom = $bounds{bottom}\n"); } # For some reason, the tapping of the write-protect button # doesn't work unless you tap somewhere else first. # &pose_sleep(1); &pose_tap_pen($bounds{left} + 2, $bounds{top} + 2, 1); last; } } &leave_func("quickword_press_write_protect"); } # quickword_find_replace # from_string - string to replace # to_string - string to replace with # # Uses QuickWord's find/replace utility to replace # one string with another. # sub quickword_find_replace { my $from_string = $_[0]; my $to_string = $_[1]; &enter_func("quickword_find_replace"); # Move cursor to beginning... # &quickword_tap_at_top(1); # Move to "Find" field: # Triple-click to highlight all the text in the field, # so it is removed when the string is entered... # &pose_tap_button("Find", 2); &pose_tap_pen(50, 100, 0); &pose_tap_pen(50, 100, 0); &pose_tap_pen(50, 100, 1); # sleep for 2 seconds to avoid double click after moving # to replace field # &enter_string("$from_string", 2); # Move to "Replace" field: # Triple-click to highlight all the text in the field, # so it is removed when the string is entered... # &pose_tap_pen(50, 120, 0); &pose_tap_pen(50, 120, 0); &pose_tap_pen(50, 120, 1); &enter_string("$to_string", 1); # Do find, then replace... # &pose_tap_button("Find", 1); &pose_tap_button("Replace", 1); &pose_tap_button("Cancel", 1); &leave_func("quickword_find_replace"); } # quickword_tap_at_top # secs - seconds to sleep after the tap # # Tap's at the top of the QuickWord document. # sub quickword_tap_at_top { my $secs = $_[0]; &enter_func("quickword_tap_at_top"); # Sleep for a second to avoid any double-clicks # from happening. # &pose_sleep(1); &pose_tap_pen(0, 15, $secs); &leave_func("quickword_tap_at_top"); } # Saves file and returns to the Application list. # sub close_quickword { &enter_func("close_quickword"); &pose_tap_button("Done", 2); &tap_applications(2); &leave_func("close_quickword"); } # # MINICALC SPECIFIC # # start_minicalc # # Assuming pose was launched with the -run_app flag to launch # Minicalc on startup, this starts up Minicalc with the first # file in the list. # sub start_minicalc { &enter_func("start_minicalc"); &pose_tap_button("OK", 1); # For now just tap on the first spreadsheet. Add support # for multiple sheets later. # &pose_tap_pen(10, 40, 5); &leave_func("start_minicalc"); } # close_minicalc # # Returns to the Application list (no need to save). # sub close_minicalc { &enter_func("close_minicalc"); &tap_applications(3); &leave_func("close_minicalc"); } # minicalc_enter_cell # row - row to enter value, starting with 1 # col - column to enter value, starting with 1 # val - value to enter # # Only valid for minicalc. # # This only works if the val passed in has a '\n' at the # end. # sub minicalc_enter_cell { my $row = $_[0]; my $col = $_[1]; my $val = $_[2]; my $i; my $j; &enter_func("minicalc_enter_cell"); if ($global_debug) { &print_debug (" tapping to cell row=<$row> col=<$col>\n"); } # Tap pen on home button to start with row=1, col=A # at top left. # pose_tap_pen(1, 1, 3); # Now the cell should be in the top-left corner, # so click there. However we must first click # in another cell or pose doesn't acknowledge the # click. # # pose_tap_pen(120, 95, 1); # pose_tap_pen(21, 9, 1); # Click the down button once for each row. # Must pause 3 seconds each time, otherwise MiniCalc # will not keep up. # for ($i=0; $i < $row; $i++) { if ($global_debug) { &print_debug (" Typing carrage return to go down\n"); } enter_string("\n", 1); } # Click the right button once for each col. # Must pause 3 seconds each time, otherwise MiniCalc # will not keep up. # for ($i=0; $i < $col; $i++) { if ($global_debug) { &print_debug (" Typing tab to go right\n"); } enter_string("\t", 1); } # enter string # &enter_string($val, 1); &leave_func("minicalc_enter_cell"); } # # GENERIC UTILIIES (pose) # # tap_applications # secs - seconds to sleep after the tap # # taps pen on the Applications button. # sub tap_applications { my $secs = $_[0]; &enter_func("tap_applications"); &pose_tap_pen(15, 170, 1); &pose_tap_pen(155, 10, 1); &pose_tap_pen(155, 10, $secs); &leave_func("tap_applications"); } # enter_string_at_location # x - x-location to enter string # y - y-location to enter string # in_string - string to enter # application - appliation (QUICKWORD or MINICALC) # # Enters a string at the specified x,y position. # sub enter_string_at_location { my $x_val = $_[0]; my $y_val = $_[1]; my $in_string = $_[2]; my $application = $_[3]; my $x; my $y; &enter_func("enter_string_at_location"); $x = $x_val; $y = $y_val; if ($application eq "QUICKWORD") { # Allow users to specify TOP/BOTTOM/LEFT/RIGHT # for QuickWord. # if ($y_val eq "TOP") { if ($global_debug) { &print_debug(" Converting TOP to 15\n"); } $y = 15; } if ($y_val eq "BOTTOM") { if ($global_debug) { &print_debug(" Converting BOTTOM to 144\n"); } $y = 144; } if ($x_val eq "LEFT") { if ($global_debug) { &print_debug(" Converting LEFT to 0\n"); } $x = 0; } if ($x_val eq "RIGHT") { if ($global_debug) { &print_debug(" Converting RIGHT to 152\n"); } $x = 152; } } # Just to make sure the offset isn't outside the # proper area. # if ($x >= 100) { $offset = -2; } else { $offset = 2; } &off_tap_pen($x, $y, $offset); &enter_string($in_string, 1); &leave_func("enter_string_at_location"); } # off_tap_pen # x - x-location to tap # y - y-location to tap # offset - x-offset to use for first tap. # # For some reason, pose does not register a single # pen tap if the last single pen tap was also # at the same x,y coordinate (even if the last tap # was a while ago). So this function does two # slightly different pen taps to ensure then pen # tap happens. # sub off_tap_pen { my $x = $_[0]; my $y = $_[1]; my $offset = $_[2]; &enter_func("off_tap_pen"); # sleep for 2 seconds to avoid double-click. # &pose_tap_pen_hard($x + $offset, $y, 2); &pose_tap_pen_hard($x, $y, 1); &leave_func("off_tap_pen"); } # enter_string # in_string - string to enter # secs - seconds to sleep after entering the string # # Enters a string # sub enter_string { my $in_string = $_[0]; my $secs = $_[1]; my $j; &enter_func("enter_string"); if ($global_debug) { # Display in_string so \n and \t values # show up as normal ASCII. # if ($in_string eq "\n") { &print_debug(" Entering string : <\\n>\n"); } elsif ($in_string eq "\t") { &print_debug(" Entering string : <\\t>\n"); } else { &print_debug(" Entering string : <$in_string>\n"); } } # Replace "\n" with real carrage returns. # my $string_val = $in_string; $string_val =~ s#\\n#\n#g; # Replace "\t" with a real tab. # $string_val =~ s#\\t#\t#g; # Convert string to ASCII numeric values # my @array = unpack("C*", $string_val); # Enter string one key at a time. # for ($j=0; $j <= $#array; $j++) { $queue_size = EnterKey($array[$j], 0, 0); } if ($secs > 0) { pose_sleep($secs); } &leave_func("enter_string"); } # # GENERIC UTILIIES (non pose) # # get_date_string # # Returns a timestampe string in yyyymmddHHMM format, where: # yyyy = year # mm = month # dd = day # HH = hour # MM = minute # # This sort of datestamp is used to create the output directory # names, so it used in various places. # sub get_date_string { my $cur_secs = time; my @lu = localtime $cur_secs; my $lu_secs = $lu[1]; my $lu_hours = $lu[2]; my $lu_day = $lu[3]; my $lu_mon = $lu[4] + 1; my $lu_year = $lu[5] + 1900; my $lu_str = $lu_year; if ($lu_mon < 10) { $lu_str .= "0"; } $lu_str .= $lu_mon; if ($lu_day < 10) { $lu_str .= "0"; } $lu_str .= $lu_day; if ($lu_hours < 10) { $lu_str .= "0"; } $lu_str .= $lu_hours; if ($lu_secs < 10) { $lu_str .= "0"; } $lu_str .= $lu_secs; return $lu_str; } # # DEBUG FUNCTIONS - Wrapper functions # # pose_tap_pen # x - x-position of pen tap # y - y-position of pen tap # secs - seconds to sleep after the tap # # Taps pen at specified position and displays debug info # sub pose_tap_pen { my $x = $_[0]; my $y = $_[1]; my $secs = $_[2]; if ($global_debug) { &print_debug(" Tapping pen at : $x,$y\n"); } TapPen($x, $y); if ($secs > 0) { pose_sleep($secs); } } # pose_tap_pen_hard # x - x-position of pen tap # y - y-position of pen tap # secs - seconds to sleep after the tap # # Taps pen at specified position and displays debug info # This function works more effectively in situations where # pose_tap_pen is flakey. This function is not good for # double/triple click situations since it is slow. # sub pose_tap_pen_hard { my $x = $_[0]; my $y = $_[1]; my $secs = $_[2]; if ($global_debug) { &print_debug(" Tapping pen hard at : $x,$y\n"); } `$qa_script_home/tappen.pl $x $y`; if ($secs > 0) { pose_sleep($secs); } } # pose_tap_button # button - button to press # secs - seconds to sleep after the button press # # Presses specified button and displays debug info # sub pose_tap_button { my $button = $_[0]; my $secs = $_[1]; if ($global_debug) { &print_debug(" Tapping button : $button\n"); } TapButton($button); if ($secs > 0) { pose_sleep($secs); } } # pose_sleep # secs - seconds to sleep # # Sleeps the specified amount of time and displays debug info # sub pose_sleep { my $secs = $_[0]; if ($global_debug) { &print_debug(" Sleeping : $secs seconds\n"); } sleep($secs); } # enter_func # func - function name # # Displays debug info about entering specified function. # sub enter_func { my $func = $_[0]; if ($global_debug) { &print_debug("Function enter : $func\n"); } } # leave_func # func - function name # # Displays debug info about leaving specified function. # sub leave_func { my $func = $_[0]; if ($global_debug) { &print_debug("Function exit : $func\n"); } } # print_debug # string - string to print # # Displays debug message with a # at the beginning of the line. # sub print_debug { my $string = $_[0]; print "# $string"; } 1;