Initial commit.
[pdfium.git] / core / src / fpdfdoc / doc_action.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4  \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../include/fpdfdoc/fpdf_doc.h"\r
8 CPDF_Dest CPDF_Action::GetDest(CPDF_Document* pDoc) const\r
9 {\r
10     if (m_pDict == NULL) {\r
11         return NULL;\r
12     }\r
13     CFX_ByteString type = m_pDict->GetString("S");\r
14     if (type != "GoTo" && type != "GoToR") {\r
15         return NULL;\r
16     }\r
17     CPDF_Object* pDest = m_pDict->GetElementValue("D");\r
18     if (pDest == NULL) {\r
19         return NULL;\r
20     }\r
21     if (pDest->GetType() == PDFOBJ_STRING || pDest->GetType() == PDFOBJ_NAME) {\r
22         CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests"));\r
23         CFX_ByteStringC name = pDest->GetString();\r
24         return name_tree.LookupNamedDest(pDoc, name);\r
25     } else if (pDest->GetType() == PDFOBJ_ARRAY) {\r
26         return (CPDF_Array*)pDest;\r
27     }\r
28     return NULL;\r
29 }\r
30 const FX_CHAR* g_sATypes[] = {"Unknown", "GoTo", "GoToR", "GoToE", "Launch", "Thread", "URI", "Sound", "Movie",\r
31                               "Hide",   "Named", "SubmitForm", "ResetForm", "ImportData", "JavaScript", "SetOCGState",\r
32                               "Rendition", "Trans", "GoTo3DView", ""\r
33                              };\r
34 CPDF_Action::ActionType CPDF_Action::GetType() const\r
35 {\r
36     ActionType eType = Unknown;\r
37     if (m_pDict != NULL) {\r
38         CFX_ByteString csType = m_pDict->GetString("S");\r
39         if (!csType.IsEmpty()) {\r
40             int i = 0;\r
41             while (g_sATypes[i][0] != '\0') {\r
42                 if (csType == g_sATypes[i]) {\r
43                     return (ActionType)i;\r
44                 }\r
45                 i ++;\r
46             }\r
47         }\r
48     }\r
49     return eType;\r
50 }\r
51 CFX_WideString CPDF_Action::GetFilePath() const\r
52 {\r
53     CFX_ByteString type = m_pDict->GetString("S");\r
54     if (type != "GoToR" && type != "Launch" &&\r
55             type != "SubmitForm" && type != "ImportData") {\r
56         return CFX_WideString();\r
57     }\r
58     CPDF_Object* pFile = m_pDict->GetElementValue("F");\r
59     CFX_WideString path;\r
60     if (pFile == NULL) {\r
61         if (type == "Launch") {\r
62             CPDF_Dictionary* pWinDict = m_pDict->GetDict(FX_BSTRC("Win"));\r
63             if (pWinDict) {\r
64                 return CFX_WideString::FromLocal(pWinDict->GetString(FX_BSTRC("F")));\r
65             }\r
66         }\r
67         return path;\r
68     }\r
69     CPDF_FileSpec filespec(pFile);\r
70     filespec.GetFileName(path);\r
71     return path;\r
72 }\r
73 CFX_ByteString CPDF_Action::GetURI(CPDF_Document* pDoc) const\r
74 {\r
75     CFX_ByteString csURI;\r
76     if (m_pDict == NULL) {\r
77         return csURI;\r
78     }\r
79     if (m_pDict->GetString("S") != "URI") {\r
80         return csURI;\r
81     }\r
82     csURI = m_pDict->GetString("URI");\r
83     CPDF_Dictionary* pRoot = pDoc->GetRoot();\r
84     CPDF_Dictionary* pURI = pRoot->GetDict("URI");\r
85     if (pURI != NULL) {\r
86         if (csURI.Find(FX_BSTRC(":"), 0) < 1) {\r
87             csURI = pURI->GetString("Base") + csURI;\r
88         }\r
89     }\r
90     return csURI;\r
91 }\r
92 FX_DWORD CPDF_ActionFields::GetFieldsCount() const\r
93 {\r
94     if (m_pAction == NULL) {\r
95         return 0;\r
96     }\r
97     CPDF_Dictionary* pDict = (CPDF_Dictionary*)(*m_pAction);\r
98     if (pDict == NULL) {\r
99         return 0;\r
100     }\r
101     CFX_ByteString csType = pDict->GetString("S");\r
102     CPDF_Object* pFields = NULL;\r
103     if (csType == "Hide") {\r
104         pFields = pDict->GetElementValue("T");\r
105     } else {\r
106         pFields = pDict->GetArray("Fields");\r
107     }\r
108     if (pFields == NULL) {\r
109         return 0;\r
110     }\r
111     int iType = pFields->GetType();\r
112     if (iType == PDFOBJ_DICTIONARY) {\r
113         return 1;\r
114     } else if (iType == PDFOBJ_STRING) {\r
115         return 1;\r
116     } else if (iType == PDFOBJ_ARRAY) {\r
117         return ((CPDF_Array*)pFields)->GetCount();\r
118     }\r
119     return 0;\r
120 }\r
121 void CPDF_ActionFields::GetAllFields(CFX_PtrArray& fieldObjects) const\r
122 {\r
123     fieldObjects.RemoveAll();\r
124     if (m_pAction == NULL) {\r
125         return;\r
126     }\r
127     CPDF_Dictionary* pDict = (CPDF_Dictionary*)(*m_pAction);\r
128     if (pDict == NULL) {\r
129         return;\r
130     }\r
131     CFX_ByteString csType = pDict->GetString("S");\r
132     CPDF_Object* pFields = NULL;\r
133     if (csType == "Hide") {\r
134         pFields = pDict->GetElementValue("T");\r
135     } else {\r
136         pFields = pDict->GetArray("Fields");\r
137     }\r
138     if (pFields == NULL) {\r
139         return;\r
140     }\r
141     int iType = pFields->GetType();\r
142     if (iType == PDFOBJ_DICTIONARY || iType == PDFOBJ_STRING) {\r
143         fieldObjects.Add(pFields);\r
144     } else if (iType == PDFOBJ_ARRAY) {\r
145         CPDF_Array* pArray = (CPDF_Array*)pFields;\r
146         FX_DWORD iCount = pArray->GetCount();\r
147         for (FX_DWORD i = 0; i < iCount; i ++) {\r
148             CPDF_Object* pObj = pArray->GetElementValue(i);\r
149             if (pObj != NULL) {\r
150                 fieldObjects.Add(pObj);\r
151             }\r
152         }\r
153     }\r
154 }\r
155 CPDF_Object* CPDF_ActionFields::GetField(FX_DWORD iIndex) const\r
156 {\r
157     if (m_pAction == NULL) {\r
158         return NULL;\r
159     }\r
160     CPDF_Dictionary* pDict = (CPDF_Dictionary*)(*m_pAction);\r
161     if (pDict == NULL) {\r
162         return NULL;\r
163     }\r
164     CFX_ByteString csType = pDict->GetString("S");\r
165     CPDF_Object* pFields = NULL;\r
166     if (csType == "Hide") {\r
167         pFields = pDict->GetElementValue("T");\r
168     } else {\r
169         pFields = pDict->GetArray("Fields");\r
170     }\r
171     if (pFields == NULL) {\r
172         return NULL;\r
173     }\r
174     CPDF_Object* pFindObj = NULL;\r
175     int iType = pFields->GetType();\r
176     if (iType == PDFOBJ_DICTIONARY || iType == PDFOBJ_STRING) {\r
177         if (iIndex == 0) {\r
178             pFindObj = pFields;\r
179         }\r
180     } else if (iType == PDFOBJ_ARRAY) {\r
181         pFindObj = ((CPDF_Array*)pFields)->GetElementValue(iIndex);\r
182     }\r
183     return pFindObj;\r
184 }\r
185 CPDF_LWinParam CPDF_Action::GetWinParam() const\r
186 {\r
187     if (m_pDict == NULL) {\r
188         return NULL;\r
189     }\r
190     if (m_pDict->GetString("S") != "Launch") {\r
191         return NULL;\r
192     }\r
193     return m_pDict->GetDict("Win");\r
194 }\r
195 CFX_WideString CPDF_Action::GetJavaScript() const\r
196 {\r
197     CFX_WideString csJS;\r
198     if (m_pDict == NULL) {\r
199         return csJS;\r
200     }\r
201     CPDF_Object* pJS = m_pDict->GetElementValue("JS");\r
202     if (pJS != NULL) {\r
203         return pJS->GetUnicodeText();\r
204     }\r
205     return csJS;\r
206 }\r
207 CPDF_Dictionary* CPDF_Action::GetAnnot() const\r
208 {\r
209     if (m_pDict == NULL) {\r
210         return NULL;\r
211     }\r
212     CFX_ByteString csType = m_pDict->GetString("S");\r
213     if (csType == FX_BSTRC("Rendition")) {\r
214         return m_pDict->GetDict("AN");\r
215     } else if (csType == FX_BSTRC("Movie")) {\r
216         return m_pDict->GetDict("Annotation");\r
217     }\r
218     return NULL;\r
219 }\r
220 FX_INT32 CPDF_Action::GetOperationType() const\r
221 {\r
222     if (m_pDict == NULL) {\r
223         return 0;\r
224     }\r
225     CFX_ByteString csType = m_pDict->GetString("S");\r
226     if (csType == FX_BSTRC("Rendition")) {\r
227         return m_pDict->GetInteger("OP");\r
228     } else if (csType == FX_BSTRC("Movie")) {\r
229         CFX_ByteString csOP = m_pDict->GetString("Operation");\r
230         if (csOP == FX_BSTRC("Play")) {\r
231             return 0;\r
232         } else if (csOP == FX_BSTRC("Stop")) {\r
233             return 1;\r
234         } else if (csOP == FX_BSTRC("Pause")) {\r
235             return 2;\r
236         } else if (csOP == FX_BSTRC("Resume")) {\r
237             return 3;\r
238         }\r
239     }\r
240     return 0;\r
241 }\r
242 FX_DWORD CPDF_Action::GetSubActionsCount() const\r
243 {\r
244     if (m_pDict == NULL || !m_pDict->KeyExist("Next")) {\r
245         return 0;\r
246     }\r
247     CPDF_Object* pNext = m_pDict->GetElementValue("Next");\r
248     if (!pNext) {\r
249         return 0;\r
250     }\r
251     int iObjType = pNext->GetType();\r
252     if (iObjType == PDFOBJ_DICTIONARY) {\r
253         return 1;\r
254     }\r
255     if (iObjType == PDFOBJ_ARRAY) {\r
256         return ((CPDF_Array*)pNext)->GetCount();\r
257     }\r
258     return 0;\r
259 }\r
260 CPDF_Action CPDF_Action::GetSubAction(FX_DWORD iIndex) const\r
261 {\r
262     if (m_pDict == NULL || !m_pDict->KeyExist("Next")) {\r
263         return NULL;\r
264     }\r
265     CPDF_Object* pNext = m_pDict->GetElementValue("Next");\r
266     int iObjType = pNext->GetType();\r
267     if (iObjType == PDFOBJ_DICTIONARY) {\r
268         if (iIndex == 0) {\r
269             return (CPDF_Dictionary*)pNext;\r
270         }\r
271     }\r
272     if (iObjType == PDFOBJ_ARRAY) {\r
273         return ((CPDF_Array*)pNext)->GetDict(iIndex);\r
274     }\r
275     return NULL;\r
276 }\r
277 const FX_CHAR* g_sAATypes[] = {"E", "X", "D", "U", "Fo", "Bl", "PO", "PC", "PV", "PI",\r
278                                "O", "C",\r
279                                "K", "F", "V", "C",\r
280                                "WC", "WS", "DS", "WP", "DP",\r
281                                ""\r
282                               };\r
283 FX_BOOL CPDF_AAction::ActionExist(AActionType eType) const\r
284 {\r
285     if (m_pDict == NULL) {\r
286         return FALSE;\r
287     }\r
288     return m_pDict->KeyExist(g_sAATypes[(int)eType]);\r
289 }\r
290 CPDF_Action CPDF_AAction::GetAction(AActionType eType) const\r
291 {\r
292     if (m_pDict == NULL) {\r
293         return NULL;\r
294     }\r
295     return m_pDict->GetDict(g_sAATypes[(int)eType]);\r
296 }\r
297 FX_POSITION CPDF_AAction::GetStartPos() const\r
298 {\r
299     if (m_pDict == NULL) {\r
300         return NULL;\r
301     }\r
302     return m_pDict->GetStartPos();\r
303 }\r
304 CPDF_Action CPDF_AAction::GetNextAction(FX_POSITION& pos, AActionType& eType) const\r
305 {\r
306     if (m_pDict == NULL) {\r
307         return NULL;\r
308     }\r
309     CFX_ByteString csKey;\r
310     CPDF_Object* pObj = m_pDict->GetNextElement(pos, csKey);\r
311     if (pObj != NULL) {\r
312         CPDF_Object* pDirect = pObj->GetDirect();\r
313         if (pDirect != NULL && pDirect->GetType() == PDFOBJ_DICTIONARY) {\r
314             int i = 0;\r
315             while (g_sAATypes[i][0] != '\0') {\r
316                 if (csKey == g_sAATypes[i]) {\r
317                     break;\r
318                 }\r
319                 i ++;\r
320             }\r
321             eType = (AActionType)i;\r
322             return (CPDF_Dictionary*)pDirect;\r
323         }\r
324     }\r
325     return NULL;\r
326 }\r
327 CPDF_DocJSActions::CPDF_DocJSActions(CPDF_Document* pDoc)\r
328 {\r
329     m_pDocument = pDoc;\r
330 }\r
331 int CPDF_DocJSActions::CountJSActions() const\r
332 {\r
333     ASSERT(m_pDocument != NULL);\r
334     CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));\r
335     return name_tree.GetCount();\r
336 }\r
337 CPDF_Action CPDF_DocJSActions::GetJSAction(int index, CFX_ByteString& csName) const\r
338 {\r
339     ASSERT(m_pDocument != NULL);\r
340     CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));\r
341     CPDF_Object *pAction = name_tree.LookupValue(index, csName);\r
342     if (pAction == NULL || pAction->GetType() != PDFOBJ_DICTIONARY) {\r
343         return NULL;\r
344     }\r
345     return pAction->GetDict();\r
346 }\r
347 CPDF_Action CPDF_DocJSActions::GetJSAction(const CFX_ByteString& csName) const\r
348 {\r
349     ASSERT(m_pDocument != NULL);\r
350     CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));\r
351     CPDF_Object *pAction = name_tree.LookupValue(csName);\r
352     if (pAction == NULL || pAction->GetType() != PDFOBJ_DICTIONARY) {\r
353         return NULL;\r
354     }\r
355     return pAction->GetDict();\r
356 }\r
357 int CPDF_DocJSActions::FindJSAction(const CFX_ByteString& csName) const\r
358 {\r
359     ASSERT(m_pDocument != NULL);\r
360     CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));\r
361     return name_tree.GetIndex(csName);\r
362 }\r