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