package de.urszeidler.shr5.ecp.editor.actions; import java.io.File; import java.io.IOException; import java.util.Collection; import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSObject; import org.apache.pdfbox.exceptions.CryptographyException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.common.COSArrayList; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.ItemPropertyDescriptor; import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.swt.widgets.Shell; import org.eclipse.wb.swt.ResourceManager; import de.urszeidler.eclipse.shr5.Shr5Factory; import de.urszeidler.eclipse.shr5.Shr5Package; import de.urszeidler.eclipse.shr5.SourceBook; import de.urszeidler.eclipse.shr5.SourceLink; import de.urszeidler.shr5.ecp.Activator; import de.urszeidler.shr5.ecp.preferences.PreferenceConstants; import de.urszeidler.shr5.ecp.util.DefaultLabelProvider; import de.urszeidler.shr5.ecp.util.ShadowrunEditingTools; import de.urszeidler.shr5.ecp.views.SourceBookView; public class CreateTOCFromSourcebook extends Action { private Shell shell; private SourceLink theObject; private LabelProvider labelProvider= new DefaultLabelProvider(); public CreateTOCFromSourcebook(Shell shell, SourceLink object) { this.shell = shell; this.theObject = object; setToolTipText("Create source links from "+ labelProvider.getText(theObject.getSrcBook())); setImageDescriptor(ResourceManager.getPluginImageDescriptor("de.urszeidler.shr5.ecp", "images/collection.png")); } @Override public void run() { final SourceBook srcBook = theObject.getSrcBook(); if(srcBook==null && (theObject.getPage()==null || theObject.getPage().isEmpty()) ){ importAllSources(); return; } final File docFile = SourceBookView.getFileFromPreferences(srcBook); final IPreferenceStore store = Activator.getDefault().getPreferenceStore(); final String id2 = ShadowrunEditingTools.getId(srcBook); if (srcBook == null || docFile == null || id2 == null) { MessageDialog.openError(shell, "Sourcebook not configured.", String.format("%s is not configured propertly, you need to set the pdf in the preferences", labelProvider.getText(theObject))); return; } Job job = new Job(String.format("importing outline from %s" , labelProvider.getText(theObject))) { @Override protected IStatus run(IProgressMonitor monitor) { return doAction(monitor,docFile,store,id2,srcBook,theObject); } }; job.setUser(true); job.schedule(); } private void importAllSources() { final Collection<EObject> collection = ItemPropertyDescriptor.getReachableObjectsOfType(theObject, Shr5Package.Literals.SOURCE_BOOK); Job job = new Job(String.format("Importing outline from all confifured sources." , labelProvider.getText(theObject))) { @Override protected IStatus run(IProgressMonitor monitor) { for (EObject eObject : collection) { SourceBook srcBook = (SourceBook)eObject; final File docFile = SourceBookView.getFileFromPreferences(srcBook); final IPreferenceStore store = Activator.getDefault().getPreferenceStore(); final String id2 = ShadowrunEditingTools.getId(srcBook); if (srcBook == null || docFile == null || id2 == null) { continue; } SourceLink link = Shr5Factory.eINSTANCE.createSourceLink(); link.setSrcBook(srcBook); link.setName(srcBook.getName()); theObject.getSubLinks().add(link); doAction(monitor,docFile,store,id2,srcBook,link); } return Status.OK_STATUS; } }; job.setUser(true); job.schedule(); } protected IStatus doAction(IProgressMonitor monitor, File docFile, IPreferenceStore store, String id2, SourceBook srcBook, SourceLink orgLink) { int offset = store.getInt(PreferenceConstants.LINKED_SOURCEBOOKS_OFFSET + id2); monitor.setTaskName("load document "+labelProvider.getText(srcBook)); SourceLink link = Shr5Factory.eINSTANCE.createSourceLink(); link.setSrcBook(srcBook); try { PDDocument pdDocument = PDDocument.load(docFile); if (pdDocument.isEncrypted()) { pdDocument.decrypt(""); pdDocument.setAllSecurityToBeRemoved(true); } PDDocumentOutline root = pdDocument.getDocumentCatalog().getDocumentOutline(); monitor.setTaskName("process document"); PDOutlineItem item = root.getFirstChild(); processItem(item, link, pdDocument, offset); pdDocument.close(); EList<SourceLink> subLinks = link.getSubLinks(); EditingDomain editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(orgLink); if(editingDomain!=null){ Command command = AddCommand.create(editingDomain, orgLink, Shr5Package.Literals.SOURCE_LINK__SUB_LINKS, subLinks); editingDomain.getCommandStack().execute(command); } } catch (IOException e) { Activator.logError(e); } catch (CryptographyException e) { Activator.logError(e); } return Status.OK_STATUS; } private void processItem(PDOutlineItem item, SourceLink sl, PDDocument doc, int offset) { while (item != null) { SourceLink link = Shr5Factory.eINSTANCE.createSourceLink(); link.setName(item.getTitle()); link.setSrcBook(sl.getSrcBook()); try { PDPage page = item.findDestinationPage(doc); if (page != null) { COSArray pageArray = ((COSArrayList<?>)page.getParent().getKids()).toList(); int indexOfObject = pageArray.indexOfObject(page.getCOSObject()); COSObject cosBase = (COSObject)pageArray.get(indexOfObject); cosBase.getGenerationNumber(); String objStr = String.valueOf(cosBase.getObjectNumber().intValue()); String genStr = String.valueOf(cosBase.getGenerationNumber().intValue()); Integer integer = doc.getPageMap().get(objStr + "," + genStr); if (integer != null) { integer = integer - offset; link.setPage(integer.toString()); } } } catch (IOException e) { e.printStackTrace(); } sl.getSubLinks().add(link); PDOutlineItem child = item.getFirstChild(); if (child != null) { processItem(child, link, doc, offset); } item = item.getNextSibling(); } } }