mirror of https://github.com/JakubMelka/PDF4QT.git
Update actions accordin to PDF 2.0 specification
This commit is contained in:
parent
784525d4cd
commit
3ac4a1d445
|
@ -76,13 +76,15 @@ PDFActionPtr PDFAction::parseImpl(const PDFObjectStorage* storage, PDFObject obj
|
|||
if (name == "GoTo") // Goto action
|
||||
{
|
||||
PDFDestination destination = PDFDestination::parse(storage, dictionary->get("D"));
|
||||
return PDFActionPtr(new PDFActionGoTo(qMove(destination)));
|
||||
PDFDestination structureDestination = PDFDestination::parse(storage, dictionary->get("SD"));
|
||||
return PDFActionPtr(new PDFActionGoTo(qMove(destination), qMove(structureDestination)));
|
||||
}
|
||||
else if (name == "GoToR")
|
||||
{
|
||||
PDFDestination destination = PDFDestination::parse(storage, dictionary->get("D"));
|
||||
PDFDestination structureDestination = PDFDestination::parse(storage, dictionary->get("SD"));
|
||||
PDFFileSpecification fileSpecification = PDFFileSpecification::parse(storage, dictionary->get("F"));
|
||||
return PDFActionPtr(new PDFActionGoToR(qMove(destination), qMove(fileSpecification), loader.readBooleanFromDictionary(dictionary, "NewWindow", false)));
|
||||
return PDFActionPtr(new PDFActionGoToR(qMove(destination), qMove(structureDestination), qMove(fileSpecification), loader.readBooleanFromDictionary(dictionary, "NewWindow", false)));
|
||||
}
|
||||
else if (name == "GoToE")
|
||||
{
|
||||
|
@ -90,6 +92,11 @@ PDFActionPtr PDFAction::parseImpl(const PDFObjectStorage* storage, PDFObject obj
|
|||
PDFFileSpecification fileSpecification = PDFFileSpecification::parse(storage, dictionary->get("F"));
|
||||
return PDFActionPtr(new PDFActionGoToE(qMove(destination), qMove(fileSpecification), loader.readBooleanFromDictionary(dictionary, "NewWindow", false), storage->getObject(dictionary->get("T"))));
|
||||
}
|
||||
else if (name == "GoToDp")
|
||||
{
|
||||
PDFObjectReference documentPart = loader.readReferenceFromDictionary(dictionary, "Dp");
|
||||
return PDFActionPtr(new PDFActionGoToDp(documentPart));
|
||||
}
|
||||
else if (name == "Launch")
|
||||
{
|
||||
PDFFileSpecification fileSpecification = PDFFileSpecification::parse(storage, dictionary->get("F"));
|
||||
|
@ -294,6 +301,22 @@ PDFActionPtr PDFAction::parseImpl(const PDFObjectStorage* storage, PDFObject obj
|
|||
}
|
||||
return PDFActionPtr(new PDFActionJavaScript(PDFEncoding::convertTextString(textJavaScript)));
|
||||
}
|
||||
else if (name == "RichMediaExecute")
|
||||
{
|
||||
PDFObjectReference richMediaAnnotation = loader.readReferenceFromDictionary(dictionary, "TA");
|
||||
PDFObjectReference richMediaInstance = loader.readReferenceFromDictionary(dictionary, "TI");
|
||||
|
||||
QString command;
|
||||
PDFObject arguments;
|
||||
|
||||
if (const PDFDictionary* commandDictionary = storage->getDictionaryFromObject(dictionary->get("CMD")))
|
||||
{
|
||||
command = loader.readTextStringFromDictionary(commandDictionary, "C", QString());
|
||||
arguments = commandDictionary->get("A");
|
||||
}
|
||||
|
||||
return PDFActionPtr(new PDFActionRichMediaExecute(richMediaAnnotation, richMediaInstance, qMove(command), qMove(arguments)));
|
||||
}
|
||||
else if (name == "SubmitForm")
|
||||
{
|
||||
PDFFormAction::FieldScope fieldScope = PDFFormAction::FieldScope::All;
|
||||
|
@ -478,4 +501,9 @@ PDFFormAction::FieldList PDFFormAction::parseFieldList(const PDFObjectStorage* s
|
|||
return result;
|
||||
}
|
||||
|
||||
QString PDFActionURI::getURIString() const
|
||||
{
|
||||
return QString::fromUtf8(m_URI);
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -41,6 +41,7 @@ enum class ActionType
|
|||
GoTo,
|
||||
GoToR,
|
||||
GoToE,
|
||||
GoToDp,
|
||||
Launch,
|
||||
Thread,
|
||||
URI,
|
||||
|
@ -55,7 +56,8 @@ enum class ActionType
|
|||
JavaScript,
|
||||
SubmitForm,
|
||||
ResetForm,
|
||||
ImportDataForm
|
||||
ImportDataForm,
|
||||
RichMediaExecute
|
||||
};
|
||||
|
||||
enum class DestinationType
|
||||
|
@ -146,24 +148,31 @@ private:
|
|||
std::vector<PDFActionPtr> m_nextActions;
|
||||
};
|
||||
|
||||
/// Regular go-to action. Can contain also structure destinations, both regular page destination
|
||||
/// and structure destination are present, because if structure destination fails, then
|
||||
/// page destination can be used as fallback resolution.
|
||||
class PDFActionGoTo : public PDFAction
|
||||
{
|
||||
public:
|
||||
explicit inline PDFActionGoTo(PDFDestination destination) : m_destination(qMove(destination)) { }
|
||||
explicit inline PDFActionGoTo(PDFDestination destination, PDFDestination structureDestination) :
|
||||
m_destination(qMove(destination)), m_structureDestination(qMove(structureDestination)) { }
|
||||
|
||||
virtual ActionType getType() const override { return ActionType::GoTo; }
|
||||
|
||||
const PDFDestination& getDestination() const { return m_destination; }
|
||||
const PDFDestination& getStructureDestination() const { return m_structureDestination; }
|
||||
|
||||
private:
|
||||
PDFDestination m_destination;
|
||||
PDFDestination m_structureDestination;
|
||||
};
|
||||
|
||||
class PDFActionGoToR : public PDFAction
|
||||
{
|
||||
public:
|
||||
explicit inline PDFActionGoToR(PDFDestination destination, PDFFileSpecification fileSpecification, bool newWindow) :
|
||||
explicit inline PDFActionGoToR(PDFDestination destination, PDFDestination structureDestination, PDFFileSpecification fileSpecification, bool newWindow) :
|
||||
m_destination(qMove(destination)),
|
||||
m_structureDestination(qMove(structureDestination)),
|
||||
m_fileSpecification(qMove(fileSpecification)),
|
||||
m_newWindow(newWindow)
|
||||
{
|
||||
|
@ -173,11 +182,13 @@ public:
|
|||
virtual ActionType getType() const override { return ActionType::GoToR; }
|
||||
|
||||
const PDFDestination& getDestination() const { return m_destination; }
|
||||
const PDFDestination& getStructureDestination() const { return m_structureDestination; }
|
||||
const PDFFileSpecification& getFileSpecification() const { return m_fileSpecification; }
|
||||
bool isNewWindow() const { return m_newWindow; }
|
||||
|
||||
private:
|
||||
PDFDestination m_destination;
|
||||
PDFDestination m_structureDestination;
|
||||
PDFFileSpecification m_fileSpecification;
|
||||
bool m_newWindow = false;
|
||||
};
|
||||
|
@ -208,6 +219,21 @@ private:
|
|||
PDFObject m_target;
|
||||
};
|
||||
|
||||
/// Go to document part
|
||||
class PDFActionGoToDp : public PDFAction
|
||||
{
|
||||
public:
|
||||
explicit inline PDFActionGoToDp(PDFObjectReference documentPart) :
|
||||
m_documentPart(documentPart) { }
|
||||
|
||||
virtual ActionType getType() const override { return ActionType::GoToDp; }
|
||||
|
||||
PDFObjectReference getDocumentPart() const { return m_documentPart; }
|
||||
|
||||
private:
|
||||
PDFObjectReference m_documentPart;
|
||||
};
|
||||
|
||||
class PDFActionLaunch : public PDFAction
|
||||
{
|
||||
public:
|
||||
|
@ -282,6 +308,10 @@ public:
|
|||
const QByteArray& getURI() const { return m_URI; }
|
||||
bool isMap() const { return m_isMap; }
|
||||
|
||||
/// Returns URI as string in unicode. If pdf document conforms
|
||||
/// to PDF specification, URI is UTF-8 encoded string.
|
||||
QString getURIString() const;
|
||||
|
||||
private:
|
||||
QByteArray m_URI;
|
||||
bool m_isMap;
|
||||
|
@ -520,6 +550,36 @@ private:
|
|||
QString m_javaScript;
|
||||
};
|
||||
|
||||
class PDFActionRichMediaExecute : public PDFAction
|
||||
{
|
||||
public:
|
||||
explicit PDFActionRichMediaExecute(PDFObjectReference richMediaAnnotation,
|
||||
PDFObjectReference richMediaInstance,
|
||||
QString command,
|
||||
PDFObject arguments) :
|
||||
m_richMediaAnnotation(richMediaAnnotation),
|
||||
m_richMediaInstance(richMediaInstance),
|
||||
m_command(qMove(command)),
|
||||
m_arguments(qMove(arguments))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual ActionType getType() const override { return ActionType::RichMediaExecute; }
|
||||
|
||||
PDFObjectReference getRichMediaAnnotation() const { return m_richMediaAnnotation; }
|
||||
PDFObjectReference getRichMediaInstance() const { return m_richMediaInstance; }
|
||||
QString getCommand() const { return m_command; }
|
||||
PDFObject getArguments() const { return m_arguments; }
|
||||
|
||||
private:
|
||||
PDFObjectReference m_richMediaAnnotation;
|
||||
PDFObjectReference m_richMediaInstance;
|
||||
QString m_command;
|
||||
PDFObject m_arguments;
|
||||
};
|
||||
|
||||
|
||||
class PDFFormAction : public PDFAction
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -319,7 +319,7 @@ PDFAnnotationPtr PDFAnnotation::parse(const PDFObjectStorage* storage, PDFObject
|
|||
if (!linkAnnotation->m_action)
|
||||
{
|
||||
PDFDestination destination = PDFDestination::parse(storage, dictionary->get("Dest"));
|
||||
linkAnnotation->m_action.reset(new PDFActionGoTo(destination));
|
||||
linkAnnotation->m_action.reset(new PDFActionGoTo(destination, PDFDestination()));
|
||||
}
|
||||
linkAnnotation->m_previousAction = PDFAction::parse(storage, dictionary->get("PA"));
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ PDFCatalog PDFCatalog::parse(const PDFObject& catalog, const PDFDocument* docume
|
|||
PDFObject openAction = document->getObject(catalogDictionary->get("OpenAction"));
|
||||
if (openAction.isArray())
|
||||
{
|
||||
catalogObject.m_openAction.reset(new PDFActionGoTo(PDFDestination::parse(&document->getStorage(), openAction)));
|
||||
catalogObject.m_openAction.reset(new PDFActionGoTo(PDFDestination::parse(&document->getStorage(), openAction), PDFDestination()));
|
||||
}
|
||||
if (openAction.isDictionary())
|
||||
{
|
||||
|
|
|
@ -73,7 +73,7 @@ void PDFOutlineItem::parseImpl(const PDFDocument* document,
|
|||
currentOutlineItem->setAction(PDFAction::parse(&document->getStorage(), dictionary->get("A")));
|
||||
if (!currentOutlineItem->getAction() && dictionary->hasKey("Dest"))
|
||||
{
|
||||
currentOutlineItem->setAction(PDFActionPtr(new PDFActionGoTo(PDFDestination::parse(&document->getStorage(), dictionary->get("Dest")))));
|
||||
currentOutlineItem->setAction(PDFActionPtr(new PDFActionGoTo(PDFDestination::parse(&document->getStorage(), dictionary->get("Dest")), PDFDestination())));
|
||||
}
|
||||
|
||||
PDFDocumentDataLoaderDecorator loader(document);
|
||||
|
|
|
@ -516,7 +516,7 @@ void PDFViewerMainWindow::onActionTriggered(const pdf::PDFAction* action)
|
|||
|
||||
const pdf::PDFActionURI* typedAction = dynamic_cast<const pdf::PDFActionURI*>(currentAction);
|
||||
QByteArray URI = m_pdfDocument->getCatalog()->getBaseURI() + typedAction->getURI();
|
||||
QString urlString = QString::fromLatin1(URI);
|
||||
QString urlString = QString::fromUtf8(URI);
|
||||
QString message = tr("Would you like to open URL '%1'?").arg(urlString);
|
||||
if (QMessageBox::question(this, tr("Open URL"), message) == QMessageBox::Yes)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue