Advertisement
PaymentOption

Word processor

Sep 22nd, 2012
806
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.11 KB | None | 0 0
  1. -- Word processor written by PaymentOption for ComputerCraft 1.42 --
  2.  
  3. -- VARIABLES --
  4. bPrinted = false -- Whether or not the document has been printed.
  5. tDocument = {}
  6.  
  7. bHasPaper = false
  8. nPaperCount = 0
  9. nPaperWidth, nPaperHeight = 0,0
  10.  
  11. bHasInk = false
  12. nInkCount = 0
  13.  
  14. bHasPrinter = false
  15. sPrinterSide = nil
  16.  
  17. bFirstPage = false -- Whether or not the first page has been started.
  18. -- The wrapped printer.
  19. printer = nil
  20.  
  21. nScreenWidth, nScreenHeight = term.getSize()
  22. nSelection = 1 -- The selection of the print confirmation dialog box.
  23. ---------------
  24.  
  25. -- INITIALIZATION METHODS --
  26. -- Returns true and the side the printer exists on if there a printer is found.
  27. function checkForPrinter()
  28.     local tSides = rs.getSides()
  29.     -- Run through all of the possible sides and check for a printer peripheral.
  30.     for index, side in ipairs( tSides ) do
  31.         -- If a printer is found.
  32.         if peripheral.isPresent( side ) and peripheral.getType( side ) == "printer" then
  33.             return true, side
  34.         end
  35.     end
  36.    
  37.     -- No printer was found.
  38.     return false, nil
  39. end
  40.  
  41. -- Returns the wrapped printer object.
  42. function wrapPrinter( side )
  43.     return peripheral.wrap( side )
  44. end
  45.  
  46. -- Returns true and the amount of paper if there is paper; false and nil if there is none.
  47. function checkForPaper( side, printerWrap )
  48.     if printerWrap.getPaperLevel() > 0 then
  49.         return true, printerWrap.getPaperLevel()
  50.     else
  51.         return false, 0
  52.     end
  53. end
  54.  
  55. -- Returns true and the amount of ink if there is ink; false and nil if there is none.
  56. function checkForInk( side, printerWrap )
  57.     if printerWrap.getInkLevel() > 0 then
  58.         return true, printerWrap.getInkLevel()
  59.     else
  60.         return false, 0
  61.     end
  62. end
  63.  
  64. -- Returns the width and height of the paper stored.
  65. function getPaperDimensions( printerWrap )
  66.     return printerWrap.getPageSize()
  67. end
  68.  
  69. -- Sets up the page to be printed on: clears it and repositions the cursor to (1, 1)
  70. function setCursorToPrint( printerWrap )
  71.     clearPage() -- Clear the page of any previous data.
  72.     printerWrap.setCursorPos( 1, 1 )
  73. end
  74.  
  75. -- Runs all necessary checks, if they pass then true is returned and all variables are setup.
  76. function initializePrinterAndProgram()
  77.     local bPrinterExists, sSide = checkForPrinter()
  78.    
  79.     local bPaper, bInk = false
  80.     local nPaper, nInk = 0
  81.    
  82.     if bPrinterExists then
  83.         -- Assign the global printer wrap to the newly found and wrapped peripheral.
  84.         printer = wrapPrinter( sSide )
  85.         -- Check for paper and ink amounts.
  86.         bPaper, nPaper = checkForPaper( sSide, printer )
  87.         bInk, nInk = checkForInk( sSide, printer )
  88.        
  89.         if bPaper and bInk then
  90.             -- Assign the global variables to their proper values.
  91.             bHasPaper = bPaper
  92.             bHasInk = bInk
  93.            
  94.             nPaperCount = nPaper
  95.             nInkCount = nInk
  96.            
  97.             bFirstPage = printer.newPage() -- Start the first page.
  98.             nPaperWidth, nPaperHeight = getPaperDimensions( printer )
  99.             setCursorToPrint( printer ) -- Setup the page so it is blank and the cursor is in the upper left hand corner (1, 1).
  100.             -- Report a successful printer initialization.
  101.             return true
  102.         -- There was either no paper, or no ink.
  103.         else
  104.             -- There was no paper.
  105.             if not bPaper then
  106.                 return false, true -- bHasPaper = false, bHasInk = true
  107.             -- There was no ink, but there was paper.
  108.             else
  109.                 return true, false -- bHasPaper = true, bHasInk = false
  110.             end
  111.         end
  112.     -- No printer was found.
  113.     else
  114.         return false
  115.     end
  116. end
  117. ----------------------------
  118.  
  119. -- CUSTOM PRINTER METHODS --
  120. -- Clears the current page of all textual data.
  121. function clearPage()
  122.     for nCurrentHeight=1, nPaperHeight do
  123.         printer.setCursorPos( 1, nCurrentHeight )
  124.         printer.write( string.rep( " ", nPaperWidth ) )
  125.     end
  126. end
  127.  
  128. -- Prints the page with the specified title and string.
  129. function printPage( sTitle, tPage )
  130.     printer.setPageTitle( sTitle )
  131.    
  132.     for nHeight=1, #tPage do
  133.         printer.setCursorPos( 1, nHeight )
  134.         printer.write( tPage[nHeight] )
  135.     end
  136.    
  137.     if printer.endPage() then
  138.         return true
  139.     else
  140.         return false
  141.     end
  142. end
  143. ----------------------------
  144.  
  145. -- TERMINAL ROUTINES (COMPUTER SPECIFIC METHODS) --
  146. function clearScreen()
  147.     term.clear()
  148.     term.setCursorPos( 1, 1 )
  149. end
  150.  
  151. -- Prints a string to the very center of the screen on the specified line.
  152. function printCentered( nHeight, sString )
  153.     term.setCursorPos( nScreenWidth/2 - string.len( sString )/2, nHeight )
  154.     write( sString )
  155. end
  156.  
  157. -- Prints a string to the very right of the screen on the specified line.
  158. function printRight( nHeight, sString )
  159.     term.setCursorPos( nScreenWidth - string.len( sString ), nHeight )
  160.     write( sString )
  161. end
  162.  
  163. -- Draws a box with a width of nBoxWidth.
  164. function drawBox( nBoxWidth )
  165.     printCentered( 4, "+" .. string.rep( "-", nBoxWidth ) .. "+" )
  166.     for nHeight = 5, 12 do
  167.         printCentered( nHeight, "|" .. string.rep( " ", nBoxWidth ) .. "|" )
  168.     end
  169.     printCentered( 13, "+" .. string.rep( "-", nBoxWidth ) .. "+" )
  170. end
  171.  
  172. -- Handles the key presses thrown when we're getting print confirmation.
  173. function handleKeyPress( nKey )
  174.     -- If the right key is pressed and the current selection is 'YES'.
  175.     if nKey == 205 and nSelection == 1 then
  176.         nSelection = 2
  177.     -- If the left key is pressed and the current selection is 'NO'.
  178.     elseif nKey == 203 and nSelection == 2 then
  179.         nSelection = 1
  180.     -- If the enter key is pressed.
  181.     elseif nKey == 28 then
  182.         -- If the user wants to print then print the prompt the user for a tile to the document.
  183.         if nSelection == 1 then
  184.             local sPageTitle = getPageTitle()
  185.             if printPage( sPageTitle, tDocument ) then
  186.                 -- End the program.
  187.                 clearScreen()
  188.                 print( os.version() )
  189.                 bPrinted = true
  190.             else
  191.                 clearScreen()
  192.                 print( os.version() )
  193.                 error( "Printing error!" )
  194.             end
  195.         -- If the user does not want to print the re-edit the document.
  196.         elseif nSelection == 2 then
  197.             tDocument = readLines( tDocument )
  198.             getConfirmation()
  199.         end
  200.     end
  201. end
  202.  
  203. -- Reads a fixed amount of characters without ruining a GUI that may be printed on the same line.
  204. function limitRead( nLength, cReplaceChar )
  205.     term.setCursorBlink( true )
  206.    
  207.     nLength = nLength or -1 -- -1 is unlimited
  208.     sReturnString = ""
  209.    
  210.     xPos, yPos = term.getCursorPos()
  211.    
  212.     while true do
  213.         event, char = os.pullEvent()
  214.        
  215.         if nLength ~= -1 and string.len( sReturnString ) >= nLength then term.setCursorBlink( false ); return sReturnString end -- Length check
  216.        
  217.         if event == "char" then sReturnString = sReturnString .. char
  218.         elseif event == "key" and char == 28 then term.setCursorBlink( false ); return sReturnString -- Enter
  219.         elseif event == "key" and char == 14 then -- Backspace
  220.             term.setCursorPos( xPos, yPos )
  221.             term.write( string.rep( " ", string.len( sReturnString ) ) )
  222.             sReturnString = string.sub( sReturnString, 1, string.len( sReturnString )-1 )
  223.             term.setCursorPos( xPos, yPos )
  224.            
  225.             if not cReplaceChar then term.write( sReturnString )
  226.             else term.write( string.rep( cReplaceChar, string.len( sReturnString ) ) ) end
  227.         end
  228.        
  229.         term.setCursorPos( xPos, yPos )
  230.         term.write( string.rep( " ", string.len( sReturnString ) ) )
  231.         term.setCursorPos( xPos, yPos )
  232.         if not cReplaceChar then term.write( sReturnString )
  233.         else term.write( string.rep( cReplaceChar, string.len( sReturnString ) ) ) end
  234.     end
  235. end
  236.  
  237. -- Takes a line and checks if a word has not finished. If it hasn't
  238. -- then it returns the table of lines with the corrected new line.
  239. --[[function fixTruncation( tLines )
  240.     -- Remove the \n chracter.
  241.     sLine = sLine:sub( 1, string.len( sLine ) - 1 )
  242.     -- Check if the line has not finished.
  243.     if tLines[#tLines]:sub( 1, 2 ) ~= " " then
  244.         for  in string.gfind(  )
  245.         tLines[#tLines - 1] = tLines[#tLines - 1]:sub( 1,  )
  246.     end
  247. end--]]
  248.  
  249. -- TODO: Remove the truncation effect when jumping lines.
  250. -- Reads multiple lines as one string.
  251. function readLines( tLines )
  252.     term.setCursorBlink( true )
  253.    
  254.     local bExistingDocument = nil
  255.     if tLines then
  256.         bExistingDocument = true
  257.     else
  258.         bExistingDocument = true
  259.     end
  260.    
  261.     local tLines = tLines or {}
  262.     local nLineWidthCap = nPaperWidth
  263.     local nLineCap = nScreenHeight
  264.    
  265.     -- Initialize the lines.
  266.     if #tLines == 0 then
  267.         for nLine = 1, nLineCap do
  268.             tLines[nLine] = ""
  269.         end
  270.     end
  271.    
  272.     local nReturnKey = 207 -- 'End'
  273.    
  274.     local nCursorPosX = 1
  275.     local nCurrentLine = 1
  276.     local nCurrentLineLength = 0
  277.    
  278.     -- Draws the paper border so people know where the page ends.
  279.     local function drawBorder()
  280.         for nHeight = 1, nScreenHeight do
  281.             term.setCursorPos( 12, nHeight )
  282.             term.write( "|" )
  283.            
  284.             term.setCursorPos( 12 + nPaperWidth + 1, nHeight )
  285.             term.write( "|" )
  286.         end
  287.        
  288.         term.setCursorPos( 1, nScreenHeight )
  289.         term.write( "'END' menu" )
  290.         printRight( nScreenHeight, "Ln " .. nCurrentLine .. " of ".. nScreenHeight )
  291.     end
  292.    
  293.     clearScreen()
  294.     drawBorder()
  295.     if bExistingDocument then
  296.         for nHeight=1, #tLines do
  297.             term.setCursorPos( 13, nHeight )
  298.             term.write( tLines[nHeight] )
  299.         end
  300.     end
  301.     while nCurrentLine < nLineCap do
  302.         term.setCursorPos( 13 + nCursorPosX - 1, nCurrentLine )
  303.         local sEvent, cChar = os.pullEvent()
  304.        
  305.         if sEvent == "char" then
  306.             if tLines[nCurrentLine]:len() + 1 < nLineWidthCap then
  307.                 tLines[nCurrentLine] = tLines[nCurrentLine]:sub( 1, nCursorPosX - 1 ) .. cChar .. tLines[nCurrentLine]:sub( nCursorPosX, tLines[nCurrentLine]:len() )
  308.                 nCursorPosX = nCursorPosX + 1
  309.             else
  310.                 if nCurrentLine + 1 <= nLineCap then
  311.                     tLines[nCurrentLine] = tLines[nCurrentLine] .. cChar
  312.                     nCurrentLine = nCurrentLine+1
  313.                     nCursorPosX = 1
  314.                 else
  315.                     term.setCursorBlink( false )
  316.                     return tLines
  317.                 end
  318.             end
  319.         elseif sEvent == "key" then
  320.             if cChar == 14 then
  321.                 if nCursorPosX - 1 > 0 then
  322.                     tLines[nCurrentLine] = tLines[nCurrentLine]:sub( 1, nCursorPosX - 2 ) .. tLines[nCurrentLine]:sub( nCursorPosX, tLines[nCurrentLine]:len() )
  323.                     nCursorPosX = nCursorPosX - 1
  324.                 else
  325.                     if nCurrentLine > 1 then
  326.                         nCurrentLine = nCurrentLine - 1
  327.                         if tLines[nCurrentLine]:len() == nLineWidthCap then
  328.                             tLines[nCurrentLine] = tLines[nCurrentLine]:sub( 1, tLines[nCurrentLine]:len() - 1 )
  329.                         end
  330.                         nCursorPosX = tLines[nCurrentLine]:len() + 1
  331.                     end
  332.                 end
  333.             elseif cChar == 28 then
  334.                 if nCurrentLine + 1 <= nLineCap then
  335.                     nCurrentLine = nCurrentLine+1
  336.                     nCursorPosX = 1
  337.                 else
  338.                     term.setCursorBlink( false )
  339.                     return tLines
  340.                 end
  341.             elseif cChar == 203 then
  342.                 if nCursorPosX - 1 > 1 then
  343.                     nCursorPosX = nCursorPosX - 1
  344.                 end
  345.             elseif cChar == 205 then
  346.                 if nCursorPosX + 1 < tLines[nCurrentLine]:len() + 2 then
  347.                     nCursorPosX = nCursorPosX + 1
  348.                 end
  349.             elseif cChar == 200 then
  350.                 if nCurrentLine - 1 > 0 then
  351.                     nCurrentLine = nCurrentLine - 1
  352.                     if tLines[nCurrentLine]:len() < nCursorPosX then
  353.                         if tLines[nCurrentLine]:len() > 0 then
  354.                             nCursorPosX = tLines[nCurrentLine]:len()
  355.                         else
  356.                             nCursorPosX = 1
  357.                         end
  358.                     end
  359.                 end
  360.             elseif cChar == 208 then
  361.                 if nCurrentLine + 1 < #tLines then
  362.                     nCurrentLine = nCurrentLine + 1
  363.                     if tLines[nCurrentLine]:len() < nCursorPosX then
  364.                         if tLines[nCurrentLine]:len() > 0 then
  365.                             nCursorPosX = tLines[nCurrentLine]:len()
  366.                         else
  367.                             nCursorPosX = 1
  368.                         end
  369.                     end
  370.                 end
  371.             elseif cChar == 15 then
  372.                 if tLines[nCurrentLine]:len() + 3 > nLineWidthCap then
  373.                     local nSpaceLeft = nLineWidthCap - tLines[nCurrentLine]:len()
  374.                     if nSpaceLeft > 0 then
  375.                         tLines[nCurrentLine] = tLines[nCurrentLine] .. string.rep( " ", nSpaceLeft )
  376.                     end
  377.                    
  378.                     nCurrentLine = nCurrentLine + 1
  379.                     nCursorPosX = 1
  380.                 else
  381.                     tLines[nCurrentLine] = tLines[nCurrentLine] .. "   "
  382.                     nCursorPosX = nCursorPosX + 3
  383.                 end
  384.             elseif cChar == nReturnKey then
  385.                 term.setCursorBlink( false )
  386.                 return tLines
  387.             end
  388.         end
  389.        
  390.         clearScreen()
  391.         drawBorder()
  392.         for nHeight=1, #tLines do
  393.             term.setCursorPos( 13, nHeight )
  394.             term.write( tLines[nHeight] )
  395.         end
  396.     end
  397.    
  398.     term.setCursorBlink( false )
  399.     return tLines
  400. end
  401. ---------------------------------------------------
  402.  
  403. -- SCREENS --
  404. -- This method gets whether or not the user wants to print the document typed. (used in drawAndGetPrintConfirmationScreen)
  405. function getConfirmation()
  406.     local function drawSelections()
  407.         if nSelection == 1 then
  408.             printCentered( 9, "[YES] NO " )
  409.         elseif nSelection == 2 then
  410.             printCentered( 9, " YES [NO]" )
  411.         end
  412.     end
  413.    
  414.     -- Draw the confirmation options.
  415.     drawBox( 20 )
  416.     printCentered( 6, "PRINT?" )
  417.    
  418.     -- Get a 'YES' or 'NO' from the user with a simple menu.
  419.     while not bPrinted do
  420.         drawSelections()
  421.         local sEvent, nKey = os.pullEvent( "key" )
  422.        
  423.         if nKey == 28 or nKey == 205 or nKey == 203 then
  424.             handleKeyPress( nKey )
  425.         end
  426.     end
  427.    
  428.     return true
  429. end
  430.  
  431. -- Gets the title for the page to be printed.
  432. function getPageTitle()
  433.     drawBox( 20 )
  434.     printCentered( 6, "Page Title:" )
  435.     term.setCursorPos( nScreenWidth/2 - 9, 9 )
  436.        
  437.     local sPageTitle = tostring( limitRead( 18 ) )
  438.     if not sPageTitle or string.len( sPageTitle ) == 0 then
  439.         sPageTitle = "Default_PageTitle"
  440.     end
  441.    
  442.     return sPageTitle
  443. end
  444.    
  445. -- This screen will prompt the user for a yes or no answer.
  446. function drawAndGetPrintConfirmationScreen()
  447.     getConfirmation()
  448. end
  449. ------------
  450.  
  451. initializePrinterAndProgram()
  452. tDocument = readLines()
  453. drawAndGetPrintConfirmationScreen()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement