Skip to content

Commit

Permalink
Improve page reference lookup by attempting to highlight the
Browse files Browse the repository at this point in the history
corresponding text.

This won't work 100% of the time due to the way PDF embeds text, but it
appears to be reliable enough in my limited testing.
  • Loading branch information
richardwilkes committed Jan 21, 2016
1 parent 9106834 commit 5652f20
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 47 deletions.
5 changes: 5 additions & 0 deletions src/com/trollworks/gcs/advantage/Advantage.java
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,11 @@ public boolean setReference(String reference) {
return false;
}

@Override
public String getReferenceHighlight() {
return getName();
}

/**
* @return Whether the point cost should be rounded down rather than up, as is normal for most
* GURPS rules.
Expand Down
3 changes: 3 additions & 0 deletions src/com/trollworks/gcs/common/HasSourceReference.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
package com.trollworks.gcs.common;

public interface HasSourceReference {
/** @return The text to highlight. */
String getReferenceHighlight();

/** @return The page reference. */
String getReference();

Expand Down
5 changes: 5 additions & 0 deletions src/com/trollworks/gcs/equipment/Equipment.java
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,11 @@ public String getReference() {
return mReference;
}

@Override
public String getReferenceHighlight() {
return getDescription();
}

@Override
public boolean setReference(String reference) {
if (!mReference.equals(reference)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ public FileProxy open(Path path) {
proxy = dockTemplate(new TemplateDockable(new Template(path.toFile())));
break;
case FileType.PDF_EXTENSION:
proxy = dockPdf(new PdfDockable(new PdfRef(null, path.toFile(), 0), 1));
proxy = dockPdf(new PdfDockable(new PdfRef(null, path.toFile(), 0), 1, null));
break;
default:
break;
Expand Down
56 changes: 34 additions & 22 deletions src/com/trollworks/gcs/menu/item/OpenPageReferenceCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,28 @@ private OpenPageReferenceCommand(String title, String cmd, int key, int modifier

@Override
public void adjust() {
setEnabled(!getReferences().isEmpty());
setEnabled(!getReferences(getTarget()).isEmpty());
}

@Override
public void actionPerformed(ActionEvent event) {
List<String> references = getReferences();
if (!references.isEmpty()) {
if (this == OPEN_ONE_INSTANCE) {
openReference(references.get(0));
} else {
for (String one : new ReverseListIterator<>(references)) {
openReference(one);
HasSourceReference target = getTarget();
if (target != null) {
List<String> references = getReferences(target);
if (!references.isEmpty()) {
String highlight = target.getReferenceHighlight();
if (this == OPEN_ONE_INSTANCE) {
openReference(references.get(0), highlight);
} else {
for (String one : new ReverseListIterator<>(references)) {
openReference(one, highlight);
}
}
}
}
}

public static void openReference(String reference) {
public static void openReference(String reference, String highlight) {
int i = reference.length() - 1;
while (i >= 0) {
char ch = reference.charAt(i);
Expand Down Expand Up @@ -107,10 +111,10 @@ public static void openReference(String reference) {
LibraryExplorerDockable library = LibraryExplorerDockable.get();
PdfDockable dockable = (PdfDockable) library.getDockableFor(path);
if (dockable != null) {
dockable.goToPage(ref, page);
dockable.goToPage(ref, page, highlight);
dockable.getDockContainer().setCurrentDockable(dockable);
} else {
dockable = new PdfDockable(ref, page);
dockable = new PdfDockable(ref, page, highlight);
library.dockPdf(dockable);
library.open(path);
}
Expand All @@ -121,8 +125,8 @@ public static void openReference(String reference) {
}
}

private static List<String> getReferences() {
List<String> list = new ArrayList<>();
private static HasSourceReference getTarget() {
HasSourceReference ref = null;
Component comp = getFocusOwner();
if (comp instanceof Outline) {
OutlineModel model = ((Outline) comp).getModel();
Expand All @@ -131,15 +135,23 @@ private static List<String> getReferences() {
if (selection.getCount() == 1) {
Row row = model.getFirstSelectedRow();
if (row instanceof HasSourceReference) {
String[] refs = ((HasSourceReference) row).getReference().split("[,;]"); //$NON-NLS-1$
if (refs.length > 0) {
for (String one : refs) {
String trimmed = one.trim();
if (!trimmed.isEmpty()) {
list.add(trimmed);
}
}
}
ref = (HasSourceReference) row;
}
}
}
}
return ref;
}

private static List<String> getReferences(HasSourceReference ref) {
List<String> list = new ArrayList<>();
if (ref != null) {
String[] refs = ref.getReference().split("[,;]"); //$NON-NLS-1$
if (refs.length > 0) {
for (String one : refs) {
String trimmed = one.trim();
if (!trimmed.isEmpty()) {
list.add(trimmed);
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/com/trollworks/gcs/pdfview/PdfDockable.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class PdfDockable extends Dockable implements FileProxy, CloseHandler {
private IconButton mPreviousPageButton;
private IconButton mNextPageButton;

public PdfDockable(PdfRef pdfRef, int page) {
public PdfDockable(PdfRef pdfRef, int page, String highlight) {
super(new BorderLayout());
mFile = pdfRef.getFile();
int pageCount = 9999;
Expand All @@ -99,7 +99,7 @@ public PdfDockable(PdfRef pdfRef, int page) {
mPageField = new EditorField(new DefaultFormatterFactory(new IntegerFormatter(1, pageCount, false)), event -> {
if (mPanel != null) {
int pageIndex = ((Integer) mPageField.getValue()).intValue() - 1;
int newPageIndex = mPanel.goToPageIndex(pageIndex);
int newPageIndex = mPanel.goToPageIndex(pageIndex, null);
if (pageIndex != newPageIndex) {
mPageField.setValue(Integer.valueOf(newPageIndex + 1));
} else {
Expand All @@ -116,7 +116,7 @@ public PdfDockable(PdfRef pdfRef, int page) {
mToolbar.add(mNextPageButton);

add(mToolbar, BorderLayout.NORTH);
mPanel = new PdfPanel(this, mPdf, pdfRef, page);
mPanel = new PdfPanel(this, mPdf, pdfRef, page, highlight);
add(new JScrollPane(mPanel), BorderLayout.CENTER);

setFocusCycleRoot(true);
Expand Down Expand Up @@ -160,8 +160,8 @@ private boolean updatePageInfo(int page, int pageCount) {
return false;
}

public void goToPage(PdfRef pdfRef, int page) {
mPanel.goToPage(pdfRef, page);
public void goToPage(PdfRef pdfRef, int page, String highlight) {
mPanel.goToPage(pdfRef, page, highlight);
}

@Override
Expand Down
44 changes: 25 additions & 19 deletions src/com/trollworks/gcs/pdfview/PdfPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

package com.trollworks.gcs.pdfview;

import com.trollworks.toolkit.io.Log;
import com.trollworks.toolkit.ui.GraphicsUtilities;
import com.trollworks.toolkit.ui.UIUtilities;

Expand All @@ -31,9 +30,9 @@
import javax.swing.SwingConstants;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDPageLabels;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.rendering.PDFRenderer;

/** A panel that will display a single page of a PDF. */
public class PdfPanel extends JPanel implements KeyListener, MouseListener, Scrollable {
Expand All @@ -42,22 +41,24 @@ public class PdfPanel extends JPanel implements KeyListener, MouseListener, Scro
private PDDocument mPdf;
private int mPageIndex;
private int mScaleIndex = Arrays.binarySearch(SCALES, 1f);
private String mHighlight;
private BufferedImage mImg;
private int mWidth;
private int mHeight;
private boolean mNeedLoad;
private boolean mIgnorePageChange;

public PdfPanel(PdfDockable owner, PDDocument pdf, PdfRef pdfRef, int page) {
public PdfPanel(PdfDockable owner, PDDocument pdf, PdfRef pdfRef, int page, String highlight) {
mOwner = owner;
mPdf = pdf;
setFocusable(true);
addMouseListener(this);
addKeyListener(this);
goToPage(pdfRef, page);
goToPage(pdfRef, page, highlight);
}

public void goToPage(PdfRef pdfRef, int page) {
if (mPdf != null) {
public void goToPage(PdfRef pdfRef, int page, String highlight) {
if (!mIgnorePageChange && mPdf != null) {
int lastPageIndex = mPageIndex;
mPageIndex = page;
try {
Expand All @@ -72,30 +73,38 @@ public void goToPage(PdfRef pdfRef, int page) {
// Had no catalog... we will just use the original page number
}
mPageIndex += pdfRef.getPageToIndexOffset();
if (mPageIndex != lastPageIndex) {
if (mPageIndex != lastPageIndex || isHighlightNew(highlight)) {
mHighlight = highlight;
markPageForLoading();
}
}
}

public int goToPageIndex(int pageIndex) {
if (mPdf != null && mPageIndex != pageIndex && pageIndex >= 0 && pageIndex < mPdf.getNumberOfPages()) {
private boolean isHighlightNew(String highlight) {
return mHighlight == null ? highlight != null : !mHighlight.equals(highlight);
}

public int goToPageIndex(int pageIndex, String highlight) {
if (!mIgnorePageChange && mPdf != null && (mPageIndex != pageIndex || isHighlightNew(highlight)) && pageIndex >= 0 && pageIndex < mPdf.getNumberOfPages()) {
mPageIndex = pageIndex;
mHighlight = highlight;
markPageForLoading();
}
return mPageIndex;
}

public void previousPage() {
if (mPdf != null && mPageIndex > 0) {
if (!mIgnorePageChange && mPdf != null && mPageIndex > 0) {
mPageIndex--;
mHighlight = null;
markPageForLoading();
}
}

public void nextPage() {
if (mPdf != null && mPageIndex < mPdf.getNumberOfPages()) {
if (!mIgnorePageChange && mPdf != null && mPageIndex < mPdf.getNumberOfPages()) {
mPageIndex++;
mHighlight = null;
markPageForLoading();
}
}
Expand Down Expand Up @@ -130,7 +139,8 @@ private void markPageForLoading() {
mPageIndex = numberOfPages - 1;
}
if (mPageIndex >= 0 && mPageIndex < numberOfPages) {
PDRectangle cropBox = mPdf.getPage(mPageIndex).getCropBox();
PDPage page = mPdf.getPage(mPageIndex);
PDRectangle cropBox = page.getCropBox();
float scale = SCALES[mScaleIndex] * Toolkit.getDefaultToolkit().getScreenResolution();
mWidth = (int) Math.ceil(cropBox.getWidth() / 72 * scale);
mHeight = (int) Math.ceil(cropBox.getHeight() / 72 * scale);
Expand All @@ -140,21 +150,17 @@ private void markPageForLoading() {
UIUtilities.setOnlySize(this, size);
setSize(size);
repaint();
mIgnorePageChange = true;
mOwner.updateStatus(mPageIndex, numberOfPages, SCALES[mScaleIndex]);
mIgnorePageChange = false;
}
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (mNeedLoad && mPdf != null) {
PDFRenderer renderer = new PDFRenderer(mPdf);
try {
mImg = renderer.renderImageWithDPI(mPageIndex, SCALES[mScaleIndex] * Toolkit.getDefaultToolkit().getScreenResolution() * (GraphicsUtilities.isRetinaDisplay(g) ? 2 : 1));
} catch (Throwable throwable) {
mImg = null;
Log.error(throwable);
}
mImg = PdfRenderer.create(mPdf, mPageIndex, SCALES[mScaleIndex] * (GraphicsUtilities.isRetinaDisplay(g) ? 2 : 1), mHighlight);
mNeedLoad = false;
}
if (mImg != null) {
Expand Down
Loading

0 comments on commit 5652f20

Please sign in to comment.