From: <dal...@us...> - 2017-06-06 18:23:20
|
Revision: 24697 http://sourceforge.net/p/jedit/svn/24697 Author: daleanson Date: 2017-06-06 18:23:17 +0000 (Tue, 06 Jun 2017) Log Message: ----------- Fix bug #4037, print selection not working correctly, plus some refactoring and code clean up. Modified Paths: -------------- jEdit/trunk/org/gjt/sp/jedit/print/BufferPrintable1_7.java jEdit/trunk/org/gjt/sp/jedit/print/BufferPrinter1_7.java jEdit/trunk/org/gjt/sp/jedit/print/PageBreakExtension.java jEdit/trunk/org/gjt/sp/jedit/print/PrintPreviewModel.java jEdit/trunk/org/gjt/sp/jedit/print/PrinterDialog.java Added Paths: ----------- jEdit/trunk/org/gjt/sp/jedit/print/PrintRangeType.java jEdit/trunk/org/gjt/sp/jedit/print/Reverse.java Modified: jEdit/trunk/org/gjt/sp/jedit/print/BufferPrintable1_7.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/print/BufferPrintable1_7.java 2017-06-05 17:36:46 UTC (rev 24696) +++ jEdit/trunk/org/gjt/sp/jedit/print/BufferPrintable1_7.java 2017-06-06 18:23:17 UTC (rev 24697) @@ -60,10 +60,8 @@ private View view; private Buffer buffer; - private boolean selection; - private int[] selectedLines; private boolean reverse; - private int printRangeType = PrinterDialog.ALL; + private PrintRangeType printRangeType = PrintRangeType.ALL; private Font font; private SyntaxStyle[] styles; private boolean header; @@ -86,6 +84,11 @@ this.view = view; this.buffer = buffer; firstCall = true; // pages and page ranges are calculated only once + reverse = attributes.containsKey(Reverse.class); + if (attributes.containsKey(PrintRangeType.class)) + { + printRangeType = (PrintRangeType)attributes.get(PrintRangeType.class); + } header = jEdit.getBooleanProperty("print.header"); footer = jEdit.getBooleanProperty("print.footer"); @@ -121,36 +124,6 @@ } } - /** - * Set the line numbers that are selected in the text area. - * @param lines An array of lines that are selected in the text area. - */ - public void setSelectedLines(int[] lines) - { - selectedLines = Arrays.copyOf(lines, lines.length); - Arrays.sort(selectedLines); - } - - /** - * Set to <code>true</code> to print the pages in reverse order, that is, print - * the last page first and the first page last. - * @param b Whether to print in reverse or not. - */ - public void setReverse(boolean b) - { - reverse = b; - } - - /** - * Set the print range type. - * @param printRangeType One of PrinterDialog.ALL, RANGE, CURRENT_PAGE, or SELECTION. - */ - public void setPrintRangeType(int printRangeType) - { - this.printRangeType = printRangeType; - selection = PrinterDialog.SELECTION == printRangeType; - } - // useful to avoid having to recalculate the page ranges if they are already known public void setPages(HashMap<Integer, Range> pages) { @@ -173,26 +146,8 @@ firstCall = false; } - // figure out the current page if that is what is requested. I'm using - // the page that contains the caret as the current page. - // QUESTION: use the text area first physical line instead? - if (printRangeType == PrinterDialog.CURRENT_PAGE) - { - int caretLine = view.getTextArea().getCaretLine(); - for (Integer i : pages.keySet()) - { - Range range = pages.get(i); - if (range.contains(caretLine)) - { - pageIndex = i; - break; - } - } - } - - // adjust the page index for reverse printing - if (reverse && printRangeType != PrinterDialog.CURRENT_PAGE) + if (reverse && !PrintRangeType.CURRENT_PAGE.equals(printRangeType)) { pageIndex = pages.size() - 1 - pageIndex; //Log.log(Log.DEBUG, this, "Reverse is on, changing page index to " + pageIndex); @@ -201,7 +156,7 @@ // go ahead and print the page Range range = pages.get(pageIndex); //Log.log(Log.DEBUG, this, "range = " + range); - if ( (range == null || !inRange(pageIndex)) && printRangeType != PrinterDialog.CURRENT_PAGE ) + if ( (range == null || !inRange(pageIndex)) && !PrintRangeType.CURRENT_PAGE.equals(printRangeType) ) { //Log.log(Log.DEBUG, this, "Returning NO_SUCH_PAGE for page " + pageIndex); return NO_SUCH_PAGE; @@ -508,14 +463,6 @@ continue; } - // print only selected lines if printing selection - if (selection && Arrays.binarySearch(selectedLines, currentPhysicalLine) < 0) - { - //Log.log(Log.DEBUG, this, "Skipping non-selected line: " + currentPhysicalLine); - continue; - } - - // fill the line list lineList.clear(); tokenHandler.init(styles, frc, tabExpander, lineList, (float)(pageWidth - lineNumberWidth), -1); Modified: jEdit/trunk/org/gjt/sp/jedit/print/BufferPrinter1_7.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/print/BufferPrinter1_7.java 2017-06-05 17:36:46 UTC (rev 24696) +++ jEdit/trunk/org/gjt/sp/jedit/print/BufferPrinter1_7.java 2017-06-06 18:23:17 UTC (rev 24697) @@ -61,10 +61,10 @@ } } - + // print to a printer public static void print( final View view, final Buffer buffer ) { - //Log.log(Log.DEBUG, BufferPrinter1_7.class, "print buffer " + buffer.getPath()); + Log.log(Log.DEBUG, BufferPrinter1_7.class, "print buffer " + buffer.getPath()); // load any saved printing attributes, these are put into 'format' loadPrintSpec(); @@ -75,7 +75,7 @@ PrinterDialog printerDialog = new PrinterDialog( view, format, false ); if ( printerDialog.isCanceled() ) { - //Log.log(Log.DEBUG, BufferPrinter1_7.class, "print dialog canceled"); + Log.log(Log.DEBUG, BufferPrinter1_7.class, "print dialog canceled"); return; } @@ -106,61 +106,17 @@ } - // set up the printable. Some values need to be set directly from the print - // dialog since they don't have attributes, like reverse page printing and printRangeType - BufferPrintable1_7 printable = new BufferPrintable1_7( format, view, buffer ); - printable.setReverse( printerDialog.getReverse() ); - int printRangeType = printerDialog.getPrintRangeType(); - printable.setPrintRangeType( printRangeType ); - - // check if printing a selection, if so, recalculate the page ranges. + // check if printing a selection, if so, create a new temporary buffer + // containing just the selection // TODO: I'm not taking even/odd page setting into account here, nor am // I considering any page values that may have been set in the page range. // I don't think this is important for printing a selection, which is // generally just a few lines rather than pages. I could be wrong... - if ( printRangeType == PrinterDialog.SELECTION ) + Buffer tempBuffer = buffer; + PrintRangeType printRangeType = (PrintRangeType)format.get(PrintRangeType.class); + if ( PrintRangeType.SELECTION.equals(printRangeType) ) { - - // calculate the actual pages with a selection or bail if there is no selection - int selectionCount = view.getTextArea().getSelectionCount(); - if ( selectionCount == 0 ) - { - JOptionPane.showMessageDialog( view, jEdit.getProperty( "print-error.message", new String[] {"No text is selected to print."} ), jEdit.getProperty( "print-error.title" ), JOptionPane.ERROR_MESSAGE ); - return; - } - - - // get the page ranges from the printable - HashMap<Integer, Range> pageRanges = getPageRanges( printable, format ); - if ( pageRanges == null || pageRanges.isEmpty() ) - { - JOptionPane.showMessageDialog( view, jEdit.getProperty( "print-error.message", new String[] {"Unable to calculate page ranges."} ), jEdit.getProperty( "print-error.title" ), JOptionPane.ERROR_MESSAGE ); - return; - } - - - // find the pages that contain the selection(s) and construct a new - // page range for the format - int[] selectedLines = view.getTextArea().getSelectedLines(); - StringBuilder pageRange = new StringBuilder(); - for ( Integer i : pageRanges.keySet() ) - { - Range range = pageRanges.get( i ); - for ( int line : selectedLines ) - { - if ( range.contains( line ) ) - { - pageRange.append( i ).append( ',' ); - break; - } - } - } - pageRange.deleteCharAt( pageRange.length() - 1 ); - format.add( new PageRanges( pageRange.toString() ) ); - - // also tell the printable exactly which lines are selected so it - // doesn't have to fetch them itself - printable.setSelectedLines( selectedLines ); + tempBuffer = getSelectionBuffer(view, buffer); } // copy the doc attributes from the print format attributes @@ -177,6 +133,10 @@ } } //Log.log(Log.DEBUG, BufferPrinter1_7.class, "--- end print request attributes ---"); + + // set up the printable + BufferPrintable1_7 printable = new BufferPrintable1_7( format, view, tempBuffer ); + final Doc doc = new SimpleDoc( printable, DocFlavor.SERVICE_FORMATTED.PRINTABLE, docAttributes ); // ready to print @@ -201,6 +161,22 @@ ThreadUtilities.runInBackground( runner ); } //}}} + // returns a temporary buffer containing only the lines in the current selection + private static Buffer getSelectionBuffer(View view, Buffer buffer) + { + int[] selectedLines = view.getTextArea().getSelectedLines(); + String path = buffer.getPath(); + String parent = path.substring(0, path.lastIndexOf(System.getProperty("file.separator"))); + Buffer temp = jEdit.openTemporary(view, parent, path + ".prn", true); + temp.setMode(buffer.getMode()); + for (int i : selectedLines) + { + String line = buffer.getLineText(i) + '\n'; + temp.insert(temp.getLength(), line); + } + return temp; + } + /** * This is intended for use by the PrintPreview dialog. */ @@ -234,8 +210,14 @@ } - // set up the printable to print just the requested page - BufferPrintable1_7 printable = new BufferPrintable1_7( model.getAttributes(), model.getView(), model.getBuffer() ); + // set up the printable to print just the requested pages + Buffer buffer = model.getBuffer(); + PrintRangeType printRangeType = (PrintRangeType)model.getAttributes().get(PrintRangeType.class); + if ( PrintRangeType.SELECTION.equals(printRangeType) ) + { + buffer = getSelectionBuffer(model.getView(), buffer); + } + BufferPrintable1_7 printable = new BufferPrintable1_7( model.getAttributes(), model.getView(), buffer ); printable.setPages(model.getPageRanges()); int pageNumber = model.getPageNumber(); try @@ -255,14 +237,10 @@ */ public static HashMap<Integer, Range> getPageRanges( View view, Buffer buffer, PrintRequestAttributeSet attributes ) { - if (attributes == null) - { - loadPrintSpec(); - attributes = format; - } - - BufferPrintable1_7 printable = new BufferPrintable1_7( attributes, view, buffer ); - return BufferPrinter1_7.getPageRanges( printable, attributes ); + loadPrintSpec(); + format.addAll(attributes); + BufferPrintable1_7 printable = new BufferPrintable1_7( format, view, buffer ); + return BufferPrinter1_7.getPageRanges( printable, format ); } @@ -299,10 +277,62 @@ } catch(Exception e) { + e.printStackTrace(); return null; } } + public static HashMap<Integer, Range> getCurrentPageRange( View view, Buffer buffer, PrintRequestAttributeSet attributes ) + { + if (attributes == null) + { + loadPrintSpec(); + attributes = format; + } + + BufferPrintable1_7 printable = new BufferPrintable1_7( attributes, view, buffer ); + HashMap<Integer, Range> pages = BufferPrinter1_7.getPageRanges( printable, attributes ); + HashMap<Integer, Range> answer = new HashMap<Integer, Range>(); + int caretLine = view.getTextArea().getCaretLine(); + for (Integer i : pages.keySet()) + { + Range range = pages.get(i); + if (range.contains(caretLine)) + { + answer.put(i, range); + break; + } + } + return answer; + } + + public static HashMap<Integer, Range> getSelectionPageRange( View view, Buffer buffer, PrintRequestAttributeSet attributes ) + { + if (attributes == null) + { + loadPrintSpec(); + attributes = format; + } + + BufferPrintable1_7 printable = new BufferPrintable1_7( attributes, view, buffer ); + HashMap<Integer, Range> pages = BufferPrinter1_7.getPageRanges( printable, attributes ); + HashMap<Integer, Range> answer = new HashMap<Integer, Range>(); + int[] selectedLines = view.getTextArea().getSelectedLines(); + for ( int line : selectedLines ) + { + for ( Integer page : pages.keySet() ) + { + Range range = pages.get(page); + if ( range.contains( line ) ) + { + answer.put(page, range); + continue; + } + } + } + return answer; + } + public static PageFormat getDefaultPageFormat(PrintRequestAttributeSet attributes) { return BufferPrinter1_7.createPageFormat(attributes); Modified: jEdit/trunk/org/gjt/sp/jedit/print/PageBreakExtension.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/print/PageBreakExtension.java 2017-06-05 17:36:46 UTC (rev 24696) +++ jEdit/trunk/org/gjt/sp/jedit/print/PageBreakExtension.java 2017-06-06 18:23:17 UTC (rev 24697) @@ -26,6 +26,10 @@ import java.awt.Graphics2D; import java.util.HashMap; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.standard.PageRanges; + import org.gjt.sp.jedit.Buffer; import org.gjt.sp.jedit.EBComponent; import org.gjt.sp.jedit.EBMessage; @@ -69,7 +73,9 @@ { View view = textArea.getView(); Buffer buffer = ( Buffer )textArea.getBuffer(); - pages = BufferPrinter1_7.getPageRanges( view, buffer, null ); + PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); + attributes.add(new PageRanges("1-1000")); + pages = BufferPrinter1_7.getPageRanges( view, buffer, attributes ); } else { @@ -162,7 +168,7 @@ // 2nd part of 'if' handles soft wrap so if the last line of the page // is wrapped, only the last screen line of the wrapped line will get // the page break line drawn on it. - if ( range.getEnd() == physicalLine && textArea.getLineEndOffset( physicalLine ) == end ) + if ( range != null && range.getEnd() == physicalLine && textArea.getLineEndOffset( physicalLine ) == end ) { y += gfx.getFontMetrics().getHeight(); gfx.drawLine( 0, y, textArea.getPainter().getWidth(), y ); Modified: jEdit/trunk/org/gjt/sp/jedit/print/PrintPreviewModel.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/print/PrintPreviewModel.java 2017-06-05 17:36:46 UTC (rev 24696) +++ jEdit/trunk/org/gjt/sp/jedit/print/PrintPreviewModel.java 2017-06-06 18:23:17 UTC (rev 24697) @@ -47,7 +47,7 @@ private PrintRequestAttributeSet attributes; private HashMap<Integer, Range> pageRanges; private int pageNumber = 1; - private int printRangeType = PrinterDialog.ALL; + private PrintRangeType printRangeType = PrintRangeType.ALL; private Graphics gfx; public static enum Zoom { NONE, IN, OUT, WIDTH, PAGE }; private Zoom zoom = Zoom.NONE; @@ -110,12 +110,12 @@ this.pageRanges = pageRanges; } - public void setPrintRangeType(int type) + public void setPrintRangeType(PrintRangeType type) { printRangeType = type; } - public int getPrintRangeType() + public PrintRangeType getPrintRangeType() { return printRangeType; } Added: jEdit/trunk/org/gjt/sp/jedit/print/PrintRangeType.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/print/PrintRangeType.java (rev 0) +++ jEdit/trunk/org/gjt/sp/jedit/print/PrintRangeType.java 2017-06-06 18:23:17 UTC (rev 24697) @@ -0,0 +1,69 @@ + +package org.gjt.sp.jedit.print; + + +import javax.print.attribute.Attribute; +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintJobAttribute; +import javax.print.attribute.PrintRequestAttribute; + + +public class PrintRangeType extends IntegerSyntax implements PrintRequestAttribute, PrintJobAttribute +{ + + private static final long serialVersionUID = -6426631421680023833L; + public static PrintRangeType ALL = new PrintRangeType( 0 ); + public static PrintRangeType ODD = new PrintRangeType( 1 ); + public static PrintRangeType EVEN = new PrintRangeType( 2 ); + public static PrintRangeType RANGE = new PrintRangeType( 3 ); + public static PrintRangeType CURRENT_PAGE = new PrintRangeType( 4 ); + public static PrintRangeType SELECTION = new PrintRangeType( 5 ); + + public PrintRangeType( int value ) + { + super( value, 0, 5 ); + } + + public boolean equals( Object object ) + { + return super.equals( object ) && object instanceof PrintRangeType; + } + + public final Class< ? extends Attribute> getCategory() + { + return PrintRangeType.class; + } + + public final String getName() + { + return "printRangeType"; + } + + public String toString() + { + StringBuilder sb = new StringBuilder( "PageRangeType: " ); + switch ( getValue() ) + { + case 0: + sb.append( "0 ALL" ); + break; + case 1: + sb.append( "1 ODD" ); + break; + case 2: + sb.append( "2 EVEN" ); + break; + case 3: + sb.append( "3 RANGE" ); + break; + case 4: + sb.append( "4 CURRENT_PAGE" ); + break; + case 6: + sb.append( "5 SELECTION" ); + break; + } + + return sb.toString(); + } +} Modified: jEdit/trunk/org/gjt/sp/jedit/print/PrinterDialog.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/print/PrinterDialog.java 2017-06-05 17:36:46 UTC (rev 24696) +++ jEdit/trunk/org/gjt/sp/jedit/print/PrinterDialog.java 2017-06-06 18:23:17 UTC (rev 24697) @@ -74,16 +74,8 @@ private boolean canceled = false; private Map<String, String> messageMap; private PageSetupPanel pageSetupPanel; - public static int ALL = 0; - public static int ODD = 1; - public static int EVEN = 2; - public static int RANGE = 3; - public static int CURRENT_PAGE = 4; - public static int SELECTION = 5; - public static int onlyPrintPages = ALL; - private int printRangeType = ALL; + public static int onlyPrintPages = PrintRangeType.ALL.getValue(); private DocFlavor DOC_FLAVOR = DocFlavor.SERVICE_FORMATTED.PRINTABLE; - private boolean reversePrinting = false; public PrinterDialog( View owner, PrintRequestAttributeSet attributes, boolean pageSetupOnly ) @@ -90,8 +82,6 @@ { super( owner, Dialog.ModalityType.APPLICATION_MODAL ); try - - { view = owner; this.pageSetupOnly = pageSetupOnly; @@ -115,10 +105,10 @@ this.attributes.remove( Destination.class ); - Attribute[] attrs = attributes.toArray(); + // for debugging - /* + /* Attribute[] attrs = attributes.toArray(); * for ( Attribute a : attrs ) * { * Log.log( Log.DEBUG, this, "+++++ before: " + a.getName() + " = " + a ); @@ -381,27 +371,6 @@ } - /** - * @return <code>true</code> if the pages should be printed in reverse order, - * that is, the last page is printed first and the first page is printed last. - */ - public boolean getReverse() - { - return reversePrinting; - } - - - /** - * @return one of ALL, RANGE, CURRENT, or SELECTION, depending on whether the - * user has elected to print all pages, a range of pages, just the current page - * or just the selected text. - */ - public int getPrintRangeType() - { - return printRangeType; - } - - private PrintService[] getPrintServices() { PrintService[] printServices = PrintServiceLookup.lookupPrintServices( DOC_FLAVOR, null ); @@ -456,7 +425,7 @@ // setting in the Page Setup tab. private PageRanges mergeRanges( PageRanges pr ) throws PrintException { - if ( pr == null || onlyPrintPages == ALL ) + if ( pr == null || onlyPrintPages == PrintRangeType.ALL.getValue() ) { return pr; } @@ -476,12 +445,12 @@ int end = range.length == 1 ? range[0] : Math.min( range[0] + 500, range[1] ); for ( int pageIndex = start; pageIndex <= end; pageIndex++ ) { - if ( pageIndex % 2 == 0 && onlyPrintPages == EVEN ) + if ( pageIndex % 2 == 0 && onlyPrintPages == PrintRangeType.EVEN.getValue() ) { pages.add( pageIndex ); } else - if ( pageIndex % 2 == 1 && onlyPrintPages == ODD ) + if ( pageIndex % 2 == 1 && onlyPrintPages == PrintRangeType.ODD.getValue() ) { pages.add( pageIndex ); } @@ -858,7 +827,7 @@ if ( allPages.isSelected() ) { as.add( new PageRanges( 1, 1000 ) ); - printRangeType = ALL; + as.add( PrintRangeType.ALL ); } else if ( pages.isSelected() ) @@ -867,8 +836,6 @@ if ( pageRange != null ) { try - - { as.add( new PageRanges( pageRange ) ); } @@ -877,21 +844,27 @@ e.printStackTrace(); } } - - - printRangeType = RANGE; + as.add( PrintRangeType.RANGE ); } else if ( currentPage.isSelected() ) { - as.add( new PageRanges( 1 ) ); - printRangeType = CURRENT_PAGE; + PrinterDialog.this.attributes.add(new PageRanges( 1, 1000 ) ); + HashMap<Integer, Range> currentPageRange = BufferPrinter1_7.getCurrentPageRange(view, view.getBuffer(), PrinterDialog.this.attributes); + int page = 1; + if (currentPageRange != null && !currentPageRange.isEmpty()) + { + page = currentPageRange.keySet().iterator().next(); + } + + as.add( new PageRanges( page ) ); + as.add( PrintRangeType.CURRENT_PAGE ); } else if ( selection.isSelected() ) { - as.add( new PageRanges( 1, 1000 ) ); - printRangeType = SELECTION; + PrinterDialog.this.attributes.add(new PageRanges( 1, 1000 ) ); + as.add( PrintRangeType.SELECTION ); } @@ -902,9 +875,12 @@ as.add( new Copies( ( Integer )copies.getValue() ) ); + + if (reverse.isSelected()) + { + as.add(new Reverse()); + } - reversePrinting = reverse.isSelected(); - return as; } Added: jEdit/trunk/org/gjt/sp/jedit/print/Reverse.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/print/Reverse.java (rev 0) +++ jEdit/trunk/org/gjt/sp/jedit/print/Reverse.java 2017-06-06 18:23:17 UTC (rev 24697) @@ -0,0 +1,52 @@ +/* + * Reverse.java - Print attribute indicating reverse print order + * :tabSize=4:indentSize=4:noTabs=false: + * :folding=explicit:collapseFolds=1: + * + * Copyright (C) Dale Anson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.gjt.sp.jedit.print; + + +import javax.print.attribute.Attribute; + + +// Custom print attribute indicating the pages should be printed in reverse +// order. This is just a marker attribute, if present, pages should be printed +// in reverse order, if not present, then print pages in forward order. +public class Reverse implements Attribute +{ + + private static final long serialVersionUID = -2823970704630722439L; + + public boolean equals( Object object ) + { + return object != null && object instanceof Reverse && object.getClass() == this.getClass(); + } + + public final Class< ? extends Attribute> getCategory() + { + return Reverse.class; + } + + public final String getName() + { + return "reverse"; + } +} + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |