Initial commit.
[pdfium.git] / fpdfsdk / src / javascript / PublicMethods.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/javascript/JavaScript.h"\r
8 #include "../../include/javascript/IJavaScript.h"\r
9 #include "../../include/javascript/JS_Define.h"\r
10 #include "../../include/javascript/JS_Object.h"\r
11 #include "../../include/javascript/JS_Value.h"\r
12 #include "../../include/javascript/PublicMethods.h"\r
13 #include "../../include/javascript/JS_EventHandler.h"\r
14 #include "../../include/javascript/resource.h"\r
15 #include "../../include/javascript/JS_Context.h"\r
16 #include "../../include/javascript/JS_Value.h"\r
17 #include "../../include/javascript/util.h"\r
18 #include "../../include/javascript/Field.h"\r
19 #include "../../include/javascript/color.h"\r
20 #include "../../include/javascript/JS_Runtime.h"\r
21 \r
22 static v8::Isolate* GetIsolate(IFXJS_Context* cc)\r
23 {\r
24         CJS_Context* pContext = (CJS_Context *)cc;\r
25         ASSERT(pContext != NULL);\r
26 \r
27         CJS_Runtime* pRuntime = pContext->GetJSRuntime();\r
28         ASSERT(pRuntime != NULL);\r
29 \r
30         return pRuntime->GetIsolate();\r
31 }\r
32 \r
33 \r
34 /* -------------------------------- CJS_PublicMethods -------------------------------- */\r
35 \r
36 #define DOUBLE_CORRECT  0.000000000000001\r
37 \r
38 BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)\r
39         JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format,6)\r
40         JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke,6)\r
41         JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format,2)\r
42         JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke,2)\r
43         JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx,1)\r
44         JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx,1)\r
45         JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format,1)\r
46         JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke,1)\r
47         JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx,1)\r
48         JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx,1)\r
49         JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format,1)\r
50         JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke,1)\r
51         JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format,1)\r
52         JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke,1)\r
53         JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx,1)\r
54         JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple,3)\r
55         JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber,1)\r
56         JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate,2)\r
57         JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate,4)\r
58         JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange,1)\r
59         JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx,2)\r
60         JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums,1)\r
61 END_JS_STATIC_GLOBAL_FUN()\r
62 \r
63 IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)\r
64 \r
65 struct stru_TbConvert\r
66 {\r
67         FX_LPCSTR lpszJSMark;\r
68         FX_LPCSTR lpszCppMark;\r
69 };\r
70 \r
71 static const stru_TbConvert fcTable[] = {"mmmm","%B",\r
72         "mmm", "%b",\r
73         "mm",  "%m",\r
74         //"m"\r
75         "dddd","%A",\r
76         "ddd", "%a",\r
77         "dd",  "%d",\r
78         //"d",   "%w",\r
79         "yyyy","%Y",\r
80         "yy",  "%y",\r
81         "HH",  "%H",\r
82         //"H"\r
83         "hh",  "%I",\r
84         //"h"\r
85         "MM",  "%M",\r
86         //"M"\r
87         "ss",  "%S",\r
88         //"s\r
89         "tt",  "%p"\r
90         //"t"\r
91 };\r
92 \r
93 static FX_LPCWSTR months[] =\r
94 {\r
95         (FX_LPCWSTR)L"Jan", (FX_LPCWSTR)L"Feb", (FX_LPCWSTR)L"Mar", (FX_LPCWSTR)L"Apr", (FX_LPCWSTR)L"May", (FX_LPCWSTR)L"Jun", (FX_LPCWSTR)L"Jul", (FX_LPCWSTR)L"Aug", (FX_LPCWSTR)L"Sep", (FX_LPCWSTR)L"Oct", (FX_LPCWSTR)L"Nov", (FX_LPCWSTR)L"Dec"\r
96 };\r
97 \r
98 static FX_LPCWSTR fullmonths[] = \r
99\r
100         (FX_LPCWSTR)L"January", (FX_LPCWSTR)L"February", (FX_LPCWSTR)L"March", (FX_LPCWSTR)L"April", (FX_LPCWSTR)L"May", (FX_LPCWSTR)L"June", (FX_LPCWSTR)L"July", (FX_LPCWSTR)L"August", (FX_LPCWSTR)L"September", (FX_LPCWSTR)L"October", (FX_LPCWSTR)L"November", (FX_LPCWSTR)L"December" \r
101 };\r
102 \r
103 FX_BOOL CJS_PublicMethods::IsNumber(FX_LPCWSTR string)\r
104 {\r
105         CFX_WideString sTrim = StrTrim(string);\r
106         FX_LPCWSTR pTrim = sTrim;\r
107         FX_LPCWSTR p = pTrim;\r
108 \r
109 \r
110         FX_BOOL bDot = FALSE;\r
111         FX_BOOL bKXJS = FALSE;\r
112 \r
113         wchar_t c;\r
114         while ((c = *p))\r
115         {\r
116                 if (c == '.' || c == ',')\r
117                 {\r
118                         if (bDot) return FALSE;\r
119                         bDot = TRUE;\r
120                 }\r
121                 else if (c == '-' || c == '+')\r
122                 {\r
123                         if (p != pTrim)\r
124                                 return FALSE;\r
125                 }\r
126                 else if (c == 'e' || c == 'E')\r
127                 {\r
128                         if (bKXJS) return FALSE;\r
129 \r
130                         p++;\r
131                         c = *p;\r
132                         if (c == '+' || c == '-')\r
133                         {\r
134                                 bKXJS = TRUE;\r
135                         }\r
136                         else\r
137                         {\r
138                                 return FALSE;\r
139                         }\r
140                 }\r
141                 else if (!IsDigit(c))\r
142                 {\r
143                         return FALSE;\r
144                 }\r
145                 p++;\r
146         }\r
147 \r
148         return TRUE;\r
149 }\r
150 \r
151 FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch)\r
152 {\r
153         return (ch >= L'0' && ch <= L'9');\r
154 }\r
155 \r
156 FX_BOOL CJS_PublicMethods::IsDigit(char ch)\r
157 {\r
158         return (ch >= '0' && ch <= '9');\r
159 }\r
160 \r
161 FX_BOOL CJS_PublicMethods::IsAlphabetic(wchar_t ch)\r
162 {\r
163         return ((ch >= L'a' && ch <= L'z') || (ch >= L'A' && ch <= L'Z'));\r
164 }\r
165 \r
166 FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch)\r
167 {\r
168         return (IsDigit(ch) || IsAlphabetic(ch));\r
169 }\r
170 \r
171 FX_BOOL CJS_PublicMethods::maskSatisfied(wchar_t c_Change,wchar_t c_Mask)\r
172 {\r
173         switch (c_Mask)\r
174         {\r
175         case L'9':\r
176         return IsDigit(c_Change);               \r
177     case L'A':\r
178         return IsAlphabetic(c_Change);          \r
179     case L'O':\r
180         return IsAlphaNumeric(c_Change);                \r
181     case L'X':\r
182         return TRUE;            \r
183         default:\r
184         return (c_Change == c_Mask);\r
185         }\r
186 }\r
187 \r
188 FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch)\r
189 {\r
190         return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';\r
191 }\r
192 \r
193 double CJS_PublicMethods::AF_Simple(FX_LPCWSTR sFuction, double dValue1, double dValue2)\r
194 {\r
195         if (FXSYS_wcsicmp(sFuction,(FX_LPCWSTR)L"AVG") == 0 || FXSYS_wcsicmp(sFuction,(FX_LPCWSTR)L"SUM") == 0)\r
196         {\r
197                 return dValue1 + dValue2;\r
198         }\r
199         else if (FXSYS_wcsicmp(sFuction, (FX_LPCWSTR)L"PRD") == 0)\r
200         {\r
201                 return dValue1 * dValue2;\r
202         }\r
203         else if (FXSYS_wcsicmp(sFuction,(FX_LPCWSTR)L"MIN") == 0)\r
204         {\r
205                 return FX_MIN(dValue1, dValue2);\r
206         }\r
207         else if (FXSYS_wcsicmp(sFuction,(FX_LPCWSTR)L"MAX") == 0)\r
208         {\r
209                 return FX_MAX(dValue1, dValue2);\r
210         }\r
211 \r
212         return dValue1;\r
213 }\r
214 \r
215 CFX_WideString CJS_PublicMethods::StrLTrim(FX_LPCWSTR pStr)\r
216 {\r
217         while (*pStr && *pStr == L' ') pStr++;\r
218 \r
219         return pStr;\r
220 }\r
221 \r
222 CFX_WideString CJS_PublicMethods::StrRTrim(FX_LPCWSTR pStr)\r
223 {\r
224         FX_LPCWSTR p = pStr;\r
225 \r
226         while (*p) p++;\r
227         p--;\r
228         if (p >= pStr)\r
229         {               \r
230                 while (*p && *p == L' ') p--;\r
231                 p++;\r
232                 return CFX_WideString(pStr,p-pStr);\r
233         }\r
234         return L"";\r
235 }\r
236 \r
237 CFX_WideString CJS_PublicMethods::StrTrim(FX_LPCWSTR pStr)\r
238 {\r
239         return StrRTrim(StrLTrim(pStr));\r
240 }\r
241 \r
242 CFX_ByteString CJS_PublicMethods::StrLTrim(FX_LPCSTR pStr)\r
243 {\r
244         while (*pStr && *pStr == ' ') pStr++;\r
245 \r
246     return pStr;\r
247 }\r
248 \r
249 CFX_ByteString CJS_PublicMethods::StrRTrim(FX_LPCSTR pStr)\r
250 {\r
251         FX_LPCSTR p = pStr;\r
252 \r
253         while (*p) p++;\r
254         p--;\r
255         if (p >= pStr)\r
256         {               \r
257                 while (*p && *p == ' ') p--;\r
258                 p++;\r
259                 return CFX_ByteString(pStr,p-pStr);\r
260         }\r
261         return "";\r
262 }\r
263 \r
264 CFX_ByteString CJS_PublicMethods::StrTrim(FX_LPCSTR pStr)\r
265 {\r
266         return StrRTrim(StrLTrim(pStr));\r
267 }\r
268 \r
269 double CJS_PublicMethods::ParseNumber(FX_LPCWSTR swSource, FX_BOOL& bAllDigits, FX_BOOL& bDot, FX_BOOL& bSign, FX_BOOL& bKXJS)\r
270 {\r
271         bDot = FALSE;\r
272         bSign = FALSE;\r
273         bKXJS = FALSE;\r
274 \r
275         FX_BOOL bDigitExist = FALSE;\r
276 \r
277         FX_LPCWSTR p = swSource;\r
278         wchar_t c;\r
279 \r
280         FX_LPCWSTR pStart = NULL;\r
281         FX_LPCWSTR pEnd = NULL;\r
282 \r
283         while ((c = *p))\r
284         {\r
285                 if (!pStart && c != L' ')\r
286                 {\r
287                         pStart = p;\r
288                 }\r
289 \r
290                 pEnd = p;\r
291                 p++;\r
292         }\r
293 \r
294         if (!pStart)\r
295         {\r
296                 bAllDigits = FALSE;\r
297                 return 0;\r
298         }\r
299 \r
300         while (pEnd != pStart)\r
301         {\r
302                 if (*pEnd == L' ')\r
303                         pEnd --;\r
304                 else\r
305                         break;\r
306         }\r
307 \r
308         double dRet = 0;\r
309         p = pStart;\r
310         bAllDigits = TRUE;\r
311         CFX_WideString swDigits;\r
312 \r
313         while (p <= pEnd)\r
314         {       \r
315                 c = *p;\r
316 \r
317                 if (IsDigit(c))\r
318                 {\r
319                         swDigits += c;\r
320                         bDigitExist = TRUE;\r
321                 }\r
322                 else \r
323                 {\r
324                         switch (c)\r
325                         {\r
326                         case L' ':\r
327                                 bAllDigits = FALSE;\r
328                                 break;\r
329                         case L'.':\r
330                         case L',':\r
331                                 if (!bDot)\r
332                                 {\r
333                                         if (bDigitExist)\r
334                                         {\r
335                                                 swDigits += L'.';\r
336                                         }\r
337                                         else\r
338                                         {\r
339                                                 swDigits += L'0';\r
340                                                 swDigits += L'.';\r
341                                                 bDigitExist = TRUE;\r
342                                         }\r
343 \r
344                                         bDot = TRUE;\r
345                                         break;\r
346                                 }\r
347                         case 'e':\r
348                         case 'E':\r
349                                 if (!bKXJS)\r
350                                 {\r
351                                         p++;\r
352                                         c = *p;\r
353                                         if (c == '+' || c == '-')\r
354                                         {\r
355                                                 bKXJS = TRUE;\r
356                                                 swDigits += 'e';\r
357                                                 swDigits += c;\r
358                                         }\r
359                                         break;\r
360                                 }\r
361                         case L'-':\r
362                                 if (!bDigitExist && !bSign)\r
363                                 {\r
364                                         swDigits += c;\r
365                                         bSign = TRUE;\r
366                                         break;\r
367                                 }\r
368                         default:\r
369                                 bAllDigits = FALSE;\r
370 \r
371                                 if (p != pStart && !bDot && bDigitExist)\r
372                                 {\r
373                                         swDigits += L'.';\r
374                                         bDot = TRUE;\r
375                                 }\r
376                                 else\r
377                                 {\r
378                                         bDot = FALSE;\r
379                                         bDigitExist = FALSE;\r
380                                         swDigits = L"";\r
381                                 }\r
382                                 break;\r
383                         }\r
384                 }\r
385 \r
386                 p++;\r
387         }\r
388 \r
389         if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17)\r
390         {\r
391                 CFX_ByteString sDigits = swDigits.UTF8Encode();\r
392 \r
393                 if (bKXJS)\r
394                 {\r
395                         dRet = atof(sDigits);\r
396                 }\r
397                 else\r
398                 {\r
399                         if (bDot)\r
400                         {\r
401                                 char* pStopString;\r
402                                 dRet = ::strtod(sDigits, &pStopString);\r
403                         }\r
404                         else\r
405                         {\r
406                                 dRet = atol(sDigits);\r
407                         }\r
408                 }\r
409 \r
410         }\r
411 \r
412         return dRet;\r
413 }\r
414 \r
415 double CJS_PublicMethods::ParseStringToNumber(FX_LPCWSTR swSource)\r
416 {\r
417         FX_BOOL bAllDigits = FALSE;\r
418         FX_BOOL bDot = FALSE;\r
419         FX_BOOL bSign = FALSE;\r
420         FX_BOOL bKXJS = FALSE;\r
421 \r
422         return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);\r
423 }\r
424 \r
425 FX_BOOL CJS_PublicMethods::ConvertStringToNumber(FX_LPCWSTR swSource, double & dRet, FX_BOOL & bDot)\r
426 {\r
427         FX_BOOL bAllDigits = FALSE;\r
428         FX_BOOL bSign = FALSE;\r
429         FX_BOOL bKXJS = FALSE;\r
430 \r
431         dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);\r
432 \r
433         return bAllDigits;\r
434 }\r
435 \r
436 CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(v8::Isolate* isolate, CJS_Value val)\r
437 {\r
438         CJS_Array StrArray(isolate);\r
439         if(val.IsArrayObject())\r
440         {\r
441                 val.ConvertToArray(StrArray);\r
442                 return StrArray;\r
443         }\r
444         CFX_WideString wsStr = val.operator CFX_WideString();\r
445         CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);\r
446         const char * p = (const char *)t;\r
447 \r
448 \r
449         int ch = ',' ;\r
450         int nIndex = 0;\r
451 \r
452         while (*p)\r
453         {\r
454                 const char * pTemp = strchr(p, ch);\r
455                 if (pTemp == NULL)\r
456                 {\r
457                         StrArray.SetElement(nIndex, CJS_Value(isolate,(FX_LPCSTR)StrTrim(p)));\r
458                         break;\r
459                 }\r
460                 else\r
461                 {\r
462                         char * pSub = new char[pTemp - p + 1];\r
463                         strncpy(pSub, p, pTemp - p);\r
464                         *(pSub + (pTemp - p)) = '\0';\r
465 \r
466                         StrArray.SetElement(nIndex, CJS_Value(isolate,(FX_LPCSTR)StrTrim(pSub)));\r
467                         delete []pSub;\r
468                         \r
469                         nIndex ++;\r
470                         p = ++pTemp;\r
471                 }\r
472                 \r
473         }\r
474         return StrArray;\r
475 }\r
476 \r
477 int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& string,int nStart,int& nSkip, int nMaxStep)\r
478 {\r
479         int nRet = 0;\r
480         nSkip = 0;\r
481         for (int i=nStart, sz=string.GetLength(); i < sz; i++)\r
482         {\r
483                 if (i-nStart > 10)\r
484                         break;\r
485 \r
486                 FX_WCHAR c = string.GetAt(i);\r
487                 if (IsDigit((wchar_t)c))\r
488                 {\r
489                         nRet = nRet * 10 + (c - '0');\r
490                         nSkip = i - nStart + 1;\r
491                         if (nSkip >= nMaxStep) \r
492                                 break;\r
493                 }\r
494                 else\r
495                         break;\r
496         }\r
497 \r
498         return nRet;\r
499 }\r
500 \r
501 CFX_WideString CJS_PublicMethods::ParseStringString(const CFX_WideString& string, int nStart, int& nSkip)\r
502 {\r
503         CFX_WideString swRet;\r
504         nSkip = 0;\r
505         for (int i=nStart, sz=string.GetLength(); i < sz; i++)\r
506         {\r
507                 FX_WCHAR c = string.GetAt(i);\r
508                 if ((c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z'))\r
509                 {\r
510                         swRet += c;\r
511                         nSkip = i - nStart + 1;\r
512                 }\r
513                 else\r
514                         break;\r
515         }\r
516 \r
517         return swRet;\r
518 }\r
519 \r
520 double CJS_PublicMethods::ParseNormalDate(const CFX_WideString & value, FX_BOOL& bWrongFormat)\r
521 {\r
522         double dt = JS_GetDateTime();\r
523 \r
524         int nYear = JS_GetYearFromTime(dt);\r
525         int nMonth = JS_GetMonthFromTime(dt) + 1;\r
526         int nDay = JS_GetDayFromTime(dt);\r
527         int nHour = JS_GetHourFromTime(dt);\r
528         int nMin = JS_GetMinFromTime(dt);\r
529         int nSec = JS_GetSecFromTime(dt);\r
530 \r
531         int number[3];\r
532 \r
533         int nSkip = 0;\r
534         int nLen = value.GetLength();\r
535         int nIndex = 0;\r
536         int i = 0;\r
537         while (i < nLen)\r
538         {\r
539                 if (nIndex > 2) break;\r
540 \r
541                 FX_WCHAR c = value.GetAt(i);\r
542                 if (IsDigit((wchar_t)c))\r
543                 {\r
544                         number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);\r
545                         i += nSkip;                     \r
546                 }\r
547                 else\r
548                 {\r
549                         i ++;\r
550                 }\r
551         }\r
552 \r
553         if (nIndex == 2)\r
554         {\r
555                 // case2: month/day\r
556                 // case3: day/month\r
557                 if ((number[0] >= 1 && number[0] <= 12) && (number[1] >= 1 && number[1] <= 31))\r
558                 {\r
559                         nMonth = number[0];\r
560                         nDay = number[1];\r
561                 }\r
562                 else if ((number[0] >= 1 && number[0] <= 31) && (number[1] >= 1 && number[1] <= 12))\r
563                 {\r
564                         nDay = number[0];\r
565                         nMonth = number[1];\r
566                 }\r
567 \r
568                 bWrongFormat = FALSE;\r
569         }\r
570         else if (nIndex == 3)\r
571         {\r
572                 // case1: year/month/day\r
573                 // case2: month/day/year\r
574                 // case3: day/month/year\r
575 \r
576                 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) && (number[2] >= 1 && number[2] <= 31))\r
577                 {\r
578                         nYear = number[0];\r
579                         nMonth = number[1];\r
580                         nDay = number[2];\r
581                 }\r
582                 else if ((number[0] >= 1 && number[0] <= 12) && (number[1] >= 1 && number[1] <= 31) && number[2] > 31)\r
583                 {\r
584                         nMonth = number[0];\r
585                         nDay = number[1];\r
586                         nYear = number[2];\r
587                 }\r
588                 else if ((number[0] >= 1 && number[0] <= 31) && (number[1] >= 1 && number[1] <= 12) && number[2] > 31)\r
589                 {\r
590                         nDay = number[0];\r
591                         nMonth = number[1];\r
592                         nYear = number[2];\r
593                 }\r
594 \r
595                 bWrongFormat = FALSE;\r
596         }\r
597         else\r
598         {\r
599                 bWrongFormat = TRUE;\r
600                 return dt;\r
601         }\r
602 \r
603         CFX_WideString swTemp;\r
604         swTemp.Format((FX_LPCWSTR)L"%d/%d/%d %d:%d:%d",nMonth,nDay,nYear,nHour,nMin,nSec);\r
605         return JS_DateParse(swTemp);\r
606 }\r
607 \r
608 double CJS_PublicMethods::MakeRegularDate(const CFX_WideString & value, const CFX_WideString & format, FX_BOOL& bWrongFormat)\r
609 {\r
610         double dt = JS_GetDateTime();\r
611 \r
612         if (format.IsEmpty() || value.IsEmpty())\r
613                 return dt;\r
614 \r
615         int nYear = JS_GetYearFromTime(dt);\r
616         int nMonth = JS_GetMonthFromTime(dt) + 1;\r
617         int nDay = JS_GetDayFromTime(dt);\r
618         int nHour = JS_GetHourFromTime(dt);\r
619         int nMin = JS_GetMinFromTime(dt);\r
620         int nSec = JS_GetSecFromTime(dt);\r
621 \r
622         int nYearSub = 99; //nYear - 2000;\r
623 \r
624         FX_BOOL bPm = FALSE;\r
625         FX_BOOL bExit = FALSE;\r
626         bWrongFormat = FALSE;\r
627         \r
628         int i=0;\r
629         int j=0;\r
630 \r
631         while (i < format.GetLength())\r
632         {\r
633                 if (bExit) break;\r
634 \r
635                 FX_WCHAR c = format.GetAt(i);           \r
636                 switch (c)\r
637                 {\r
638                         case ':':\r
639                         case '.':\r
640                         case '-':\r
641                         case '\\':\r
642                         case '/':\r
643                                 i++;\r
644                                 j++;\r
645                                 break;\r
646                                 \r
647                         case 'y':\r
648                         case 'm':\r
649                         case 'd':\r
650                         case 'H':\r
651                         case 'h':\r
652                         case 'M':\r
653                         case 's':\r
654                         case 't':\r
655                                 {\r
656                                         int oldj = j;\r
657                                         int nSkip = 0;\r
658 \r
659                                         if (format.GetAt(i+1) != c)\r
660                                         {\r
661                                                 switch (c)\r
662                                                 {\r
663                                                         case 'y':\r
664                                                                 i++;\r
665                                                                 j++;\r
666                                                                 break;\r
667                                                         case 'm':\r
668                                                                 nMonth = ParseStringInteger(value, j, nSkip, 2);\r
669                                                                 i++;\r
670                                                                 j += nSkip;\r
671                                                                 break;\r
672                                                         case 'd':\r
673                                                                 nDay = ParseStringInteger(value, j, nSkip, 2);\r
674                                                                 i++;\r
675                                                                 j += nSkip;\r
676                                                                 break;\r
677                                                         case 'H':\r
678                                                                 nHour = ParseStringInteger(value, j, nSkip, 2);\r
679                                                                 i++;\r
680                                                                 j += nSkip;\r
681                                                                 break;\r
682                                                         case 'h':\r
683                                                                 nHour = ParseStringInteger(value, j, nSkip, 2);\r
684                                                                 i++;\r
685                                                                 j += nSkip;\r
686                                                                 break;\r
687                                                         case 'M':\r
688                                                                 nMin = ParseStringInteger(value, j, nSkip, 2);\r
689                                                                 i++;\r
690                                                                 j += nSkip;\r
691                                                                 break;\r
692                                                         case 's':\r
693                                                                 nSec = ParseStringInteger(value, j, nSkip, 2);\r
694                                                                 i++;\r
695                                                                 j += nSkip;\r
696                                                                 break;\r
697                                                         case 't':\r
698                                                                 bPm = value.GetAt(i) == 'p';\r
699                                                                 i++;\r
700                                                                 j++;\r
701                                                                 break;\r
702                                                 }                                       \r
703                                         }\r
704                                         else if (format.GetAt(i+1) == c && format.GetAt(i+2) != c)\r
705                                         {\r
706                                                 switch (c)\r
707                                                 {\r
708                                                         case 'y':\r
709                                                                 nYear = ParseStringInteger(value, j, nSkip, 4);\r
710                                                                 i += 2;\r
711                                                                 j += nSkip;\r
712                                                                 break;\r
713                                                         case 'm':\r
714                                                                 nMonth = ParseStringInteger(value, j, nSkip, 2);\r
715                                                                 i += 2;\r
716                                                                 j += nSkip;\r
717                                                                 break;\r
718                                                         case 'd':\r
719                                                                 nDay = ParseStringInteger(value, j, nSkip, 2);\r
720                                                                 i += 2;\r
721                                                                 j += nSkip;\r
722                                                                 break;\r
723                                                         case 'H':\r
724                                                                 nHour = ParseStringInteger(value, j, nSkip, 2);\r
725                                                                 i += 2;\r
726                                                                 j += nSkip;\r
727                                                                 break;\r
728                                                         case 'h':\r
729                                                                 nHour = ParseStringInteger(value, j, nSkip, 2);\r
730                                                                 i += 2;\r
731                                                                 j += nSkip;\r
732                                                                 break;\r
733                                                         case 'M':\r
734                                                                 nMin = ParseStringInteger(value, j, nSkip, 2);\r
735                                                                 i += 2;\r
736                                                                 j += nSkip;\r
737                                                                 break;\r
738                                                         case 's':\r
739                                                                 nSec = ParseStringInteger(value, j, nSkip, 2);\r
740                                                                 i += 2;\r
741                                                                 j += nSkip;\r
742                                                                 break;\r
743                                                         case 't':\r
744                                                                 bPm = (value.GetAt(j) == 'p' && value.GetAt(j+1) == 'm');\r
745                                                                 i += 2;\r
746                                                                 j += 2;\r
747                                                                 break;\r
748                                                 }\r
749                                         }\r
750                                         else if (format.GetAt(i+1) == c && format.GetAt(i+2) == c && format.GetAt(i+3) != c)\r
751                                         {\r
752                                                 switch (c)\r
753                                                 {\r
754                                                         case 'm':\r
755                                                                 {\r
756                                                                         CFX_WideString sMonth = ParseStringString(value, j, nSkip);\r
757                                                                         FX_BOOL bFind = FALSE;\r
758                                                                         for (int m = 0; m < 12; m++)\r
759                                                                         {\r
760                                                                                 if (sMonth.CompareNoCase(months[m]) == 0)\r
761                                                                                 {\r
762                                                                                         nMonth = m + 1;\r
763                                                                                         i+=3;\r
764                                                                                         j+=nSkip;\r
765                                                                                         bFind = TRUE;\r
766                                                                                         break;\r
767                                                                                 }\r
768                                                                         }\r
769                                                                         \r
770                                                                         if (!bFind)\r
771                                                                         {\r
772                                                                                 nMonth = ParseStringInteger(value, j, nSkip, 3);\r
773                                                                                 i+=3;\r
774                                                                                 j += nSkip;\r
775                                                                         }\r
776                                                                 }\r
777                                                                 break;\r
778                                                         case 'y':\r
779                                                                 break;\r
780                                                         default:\r
781                                                                 i+=3;\r
782                                                                 j+=3;\r
783                                                                 break;\r
784                                                 }\r
785                                         }\r
786                                         else if (format.GetAt(i+1) == c && format.GetAt(i+2) == c && format.GetAt(i+3) == c && format.GetAt(i+4) != c)\r
787                                         {\r
788                                                 switch (c)\r
789                                                 {\r
790 \r
791 \r
792                                                         case 'y':\r
793                                                                 nYear = ParseStringInteger(value, j, nSkip, 4);\r
794                                                                 j += nSkip;\r
795                                                                 i += 4;\r
796                                                                 break;\r
797                                                         case 'm':\r
798                                                                 {\r
799                                                                         FX_BOOL bFind = FALSE;\r
800 \r
801                                                                         CFX_WideString sMonth = ParseStringString(value, j, nSkip);\r
802                                                                         sMonth.MakeLower();\r
803 \r
804                                                                         for (int m = 0; m < 12; m++)\r
805                                                                         {\r
806                                                                                 CFX_WideString sFullMonths = fullmonths[m];\r
807                                                                                 sFullMonths.MakeLower();\r
808 \r
809                                                                                 if (sFullMonths.Find(sMonth, 0) != -1)\r
810                                                                                 {\r
811                                                                                         nMonth = m + 1;\r
812                                                                                         i += 4;\r
813                                                                                         j += nSkip;\r
814                                                                                         bFind = TRUE;\r
815                                                                                         break;\r
816                                                                                 }\r
817                                                                         }\r
818                                                                         \r
819                                                                         if (!bFind)\r
820                                                                         {\r
821                                                                                 nMonth = ParseStringInteger(value, j, nSkip, 4);\r
822                                                                                 i+=4;\r
823                                                                                 j += nSkip;\r
824                                                                         }\r
825                                                                 }\r
826                                                                 break;\r
827                                                         default:\r
828                                                                 i += 4;\r
829                                                                 j += 4;\r
830                                                                 break;\r
831                                                 }                                       \r
832                                         }\r
833                                         else\r
834                                         {\r
835                                                 if (format.GetAt(i) != value.GetAt(j))\r
836                                                 {\r
837                                                         bWrongFormat = TRUE;\r
838                                                         bExit = TRUE;\r
839                                                 }\r
840                                                 i++;\r
841                                                 j++;\r
842                                         }\r
843                                         \r
844                                         if (oldj == j)\r
845                                         {\r
846                                                 bWrongFormat = TRUE;\r
847                                                 bExit = TRUE;\r
848                                         }\r
849                                 }\r
850 \r
851                                 break;                  \r
852                         default:\r
853                                 if (value.GetLength() <= j)\r
854                                 {\r
855                                         bExit = TRUE;\r
856                                 }\r
857                                 else if (format.GetAt(i) != value.GetAt(j))\r
858                                 {\r
859                                         bWrongFormat = TRUE;\r
860                                         bExit = TRUE;\r
861                                 }\r
862 \r
863                                 i++;\r
864                                 j++;\r
865                                 break;\r
866                 }               \r
867         }\r
868 \r
869         if (bPm) nHour += 12;\r
870 \r
871         if (nYear >= 0 && nYear <= nYearSub)\r
872                 nYear += 2000;\r
873 \r
874         if (nMonth < 1 || nMonth > 12)\r
875                 bWrongFormat = TRUE;\r
876 \r
877         if (nDay < 1 || nDay > 31)\r
878                 bWrongFormat = TRUE;\r
879 \r
880         if (nHour < 0 || nHour > 24)\r
881                 bWrongFormat = TRUE;\r
882 \r
883         if (nMin < 0 || nMin > 60)\r
884                 bWrongFormat = TRUE;\r
885 \r
886         if (nSec < 0 || nSec > 60)\r
887                 bWrongFormat = TRUE;\r
888 \r
889         double dRet = 0;\r
890 \r
891         if (bWrongFormat)\r
892         {\r
893                 dRet = ParseNormalDate(value, bWrongFormat);\r
894         }\r
895         else\r
896         {\r
897                 dRet = JS_MakeDate(JS_MakeDay(nYear,nMonth - 1,nDay),JS_MakeTime(nHour, nMin, nSec, 0));\r
898 \r
899                 if (JS_PortIsNan(dRet))\r
900                 {\r
901                         dRet = JS_DateParse(value);\r
902                 }\r
903         }\r
904 \r
905         if (JS_PortIsNan(dRet))\r
906         {\r
907                 dRet = ParseNormalDate(value, bWrongFormat);\r
908         }\r
909 \r
910         return dRet;\r
911 \r
912 }\r
913 \r
914 CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate, const CFX_WideString & format)\r
915 {\r
916         CFX_WideString sRet = L"",sPart = L"";\r
917 \r
918         int nYear = JS_GetYearFromTime(dDate);\r
919         int nMonth = JS_GetMonthFromTime(dDate) + 1;\r
920         int nDay = JS_GetDayFromTime(dDate);\r
921         int nHour = JS_GetHourFromTime(dDate);\r
922         int nMin = JS_GetMinFromTime(dDate);\r
923         int nSec = JS_GetSecFromTime(dDate);\r
924 \r
925         int i = 0;\r
926         FX_WCHAR c;\r
927         while (i < format.GetLength())\r
928         {\r
929                 c = format.GetAt(i);\r
930                 sPart = L"";\r
931                 switch (c)\r
932                 {\r
933                         case 'y':\r
934                         case 'm':\r
935                         case 'd':\r
936                         case 'H':\r
937                         case 'h':\r
938                         case 'M':\r
939                         case 's':\r
940                         case 't':\r
941                                 if (format.GetAt(i+1) != c)\r
942                                 {\r
943                                         switch (c)\r
944                                         {\r
945                                                 case 'y':\r
946                                                         sPart += c;\r
947                                                         break;\r
948                                                 case 'm':\r
949                                                         sPart.Format((FX_LPCWSTR)L"%d",nMonth);\r
950                                                         break;\r
951                                                 case 'd':\r
952                                                         sPart.Format((FX_LPCWSTR)L"%d",nDay);\r
953                                                         break;\r
954                                                 case 'H':\r
955                                                         sPart.Format((FX_LPCWSTR)L"%d",nHour);\r
956                                                         break;\r
957                                                 case 'h':\r
958                                                         sPart.Format((FX_LPCWSTR)L"%d",nHour>12?nHour - 12:nHour);\r
959                                                         break;\r
960                                                 case 'M':\r
961                                                         sPart.Format((FX_LPCWSTR)L"%d",nMin);\r
962                                                         break;\r
963                                                 case 's':\r
964                                                         sPart.Format((FX_LPCWSTR)L"%d",nSec);\r
965                                                         break;\r
966                                                 case 't':                               \r
967                                                         sPart += nHour>12?'p':'a';\r
968                                                         break;\r
969                                         }                                       \r
970                                         i++;\r
971                                 }\r
972                                 else if (format.GetAt(i+1) == c && format.GetAt(i+2) != c)\r
973                                 {\r
974                                         switch (c)\r
975                                         {\r
976                                                 case 'y':\r
977                                                         sPart.Format((FX_LPCWSTR)L"%02d",nYear - (nYear / 100) * 100);\r
978                                                         break;\r
979                                                 case 'm':\r
980                                                         sPart.Format((FX_LPCWSTR)L"%02d",nMonth);\r
981                                                         break;\r
982                                                 case 'd':\r
983                                                         sPart.Format((FX_LPCWSTR)L"%02d",nDay);\r
984                                                         break;\r
985                                                 case 'H':\r
986                                                         sPart.Format((FX_LPCWSTR)L"%02d",nHour);\r
987                                                         break;\r
988                                                 case 'h':\r
989                                                         sPart.Format((FX_LPCWSTR)L"%02d",nHour>12?nHour - 12:nHour);\r
990                                                         break;\r
991                                                 case 'M':\r
992                                                         sPart.Format((FX_LPCWSTR)L"%02d",nMin);\r
993                                                         break;\r
994                                                 case 's':\r
995                                                         sPart.Format((FX_LPCWSTR)L"%02d",nSec);\r
996                                                         break;\r
997                                                 case 't':                                                       \r
998                                                         sPart = nHour>12? (FX_LPCWSTR)L"pm": (FX_LPCWSTR)L"am";\r
999                                                         break;\r
1000                                         }                       \r
1001                                         i+=2;\r
1002                                 }\r
1003                                 else if (format.GetAt(i+1) == c && format.GetAt(i+2) == c && format.GetAt(i+3) != c)\r
1004                                 {               \r
1005                                         switch (c)\r
1006                                         {\r
1007                                                 case 'm':\r
1008                                                         i+=3;\r
1009                                                         if (nMonth > 0&&nMonth <= 12)\r
1010                                                                 sPart += months[nMonth - 1];\r
1011                                                         break;\r
1012                                                 default:\r
1013                                                         i+=3;\r
1014                                                         sPart += c;\r
1015                                                         sPart += c;\r
1016                                                         sPart += c;\r
1017                                                         break;\r
1018                                         }                                       \r
1019                                 }\r
1020                                 else if (format.GetAt(i+1) == c && format.GetAt(i+2) == c && format.GetAt(i+3) == c && format.GetAt(i+4) != c)\r
1021                                 {\r
1022                                         switch (c)\r
1023                                         {\r
1024                                                 case 'y':\r
1025                                                         sPart.Format((FX_LPCWSTR)L"%04d",nYear);\r
1026                                                         i += 4;\r
1027                                                         break;  \r
1028                                                 case 'm':\r
1029                                                         i+=4;\r
1030                                                         if (nMonth > 0&&nMonth <= 12)\r
1031                                                                 sPart += fullmonths[nMonth - 1];\r
1032                                                         break;\r
1033                                                 default:\r
1034                                                         i += 4;\r
1035                                                         sPart += c;\r
1036                                                         sPart += c;\r
1037                                                         sPart += c;\r
1038                                                         sPart += c;\r
1039                                                         break;\r
1040                                         }                                       \r
1041                                 }\r
1042                                 else\r
1043                                 {\r
1044                                         i++;\r
1045                                         sPart += c;\r
1046                                 }\r
1047                                 break;                  \r
1048                         default:\r
1049                                 i++;\r
1050                                 sPart += c;\r
1051                                 break;\r
1052                 }\r
1053                 \r
1054                 sRet += sPart;\r
1055         }\r
1056 \r
1057         return sRet;\r
1058 }\r
1059 \r
1060 /* -------------------------------------------------------------------------- */\r
1061 \r
1062 //function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend)\r
1063 FX_BOOL CJS_PublicMethods::AFNumber_Format(OBJ_METHOD_PARAMS)\r
1064 {\r
1065 #if _FX_OS_ != _FX_ANDROID_\r
1066         v8::Isolate* isolate = ::GetIsolate(cc);\r
1067         CJS_Context* pContext = (CJS_Context *)cc;\r
1068         ASSERT(pContext != NULL);\r
1069         CJS_EventHandler* pEvent = pContext->GetEventHandler();\r
1070         ASSERT(pEvent != NULL);\r
1071 \r
1072         if (params.size() != 6)\r
1073         {\r
1074                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
1075                 return FALSE;\r
1076         }\r
1077         if(!pEvent->m_pValue)\r
1078                 return FALSE;\r
1079         CFX_WideString& Value = pEvent->Value();        \r
1080         CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));\r
1081         \r
1082         if (strValue.IsEmpty()) return TRUE;\r
1083         \r
1084         int iDec = params[0];\r
1085         int iSepStyle = params[1];\r
1086         int iNegStyle = params[2];\r
1087         int icurrStyle = params[3]; //it's no use!\r
1088         std::wstring wstrCurrency(params[4].operator CFX_WideString());\r
1089         FX_BOOL bCurrencyPrepend = params[5];\r
1090         \r
1091         if (iDec < 0) iDec = -iDec;\r
1092         \r
1093         if (iSepStyle < 0 || iSepStyle > 3)\r
1094                 iSepStyle = 0;\r
1095         \r
1096         if (iNegStyle < 0 || iNegStyle > 3)\r
1097                 iNegStyle = 0;\r
1098         \r
1099         \r
1100         //////////////////////////////////////////////////////\r
1101         //for processing decimal places\r
1102         strValue.Replace(",", ".");\r
1103         double dValue = atof(strValue);\r
1104         if (iDec > 0)\r
1105                 dValue += DOUBLE_CORRECT;//\r
1106                     \r
1107         int iDec2;\r
1108         FX_BOOL bNagative = FALSE;\r
1109 \r
1110         strValue = fcvt(dValue,iDec,&iDec2,&bNagative);\r
1111         if (strValue.IsEmpty())\r
1112         {\r
1113                 dValue = 0;\r
1114                 strValue = fcvt(dValue,iDec,&iDec2,&bNagative);\r
1115                 if (strValue.IsEmpty())\r
1116                 {\r
1117                         strValue = "0";\r
1118                         iDec2 = 1;\r
1119                 }\r
1120 \r
1121         }\r
1122 \r
1123         if (iDec2 < 0)\r
1124         {\r
1125                 for (int iNum = 0;iNum < abs(iDec2);iNum++)\r
1126                 {\r
1127                         strValue = "0" + strValue;\r
1128                 }\r
1129                 iDec2 = 0;\r
1130                 \r
1131         }\r
1132         int iMax = strValue.GetLength();\r
1133         if (iDec2 > iMax)\r
1134         {\r
1135                 for (int iNum = 0;iNum <= iDec2 - iMax ;iNum++)\r
1136                 {\r
1137                         strValue += "0";\r
1138                 }\r
1139                 iMax = iDec2+1;                 \r
1140         }\r
1141         ///////////////////////////////////////////////////////\r
1142     //for processing seperator style\r
1143         if (iDec2 < iMax)\r
1144         {\r
1145                 if (iSepStyle == 0 || iSepStyle == 1)\r
1146                 {\r
1147                         strValue.Insert(iDec2, '.');\r
1148                         iMax++;\r
1149                 }\r
1150                 else if (iSepStyle == 2 || iSepStyle == 3)\r
1151                 {\r
1152                         strValue.Insert(iDec2, ',');\r
1153                         iMax++;\r
1154                 }\r
1155                 \r
1156                 if (iDec2 == 0)\r
1157                         strValue.Insert(iDec2, '0');\r
1158         }\r
1159         if (iSepStyle == 0 || iSepStyle == 2)\r
1160         {\r
1161                 char cSeperator;\r
1162                 if (iSepStyle == 0)\r
1163                         cSeperator = ',';\r
1164                 else\r
1165                         cSeperator = '.';\r
1166                 \r
1167                 int iDecPositive,iDecNagative;\r
1168                 iDecPositive = iDec2;\r
1169                 iDecNagative = iDec2;           \r
1170                 \r
1171                 for (iDecPositive = iDec2 -3; iDecPositive > 0;iDecPositive -= 3)\r
1172                 {\r
1173                         strValue.Insert(iDecPositive, cSeperator);\r
1174                         iMax++;\r
1175                 }\r
1176         }\r
1177         \r
1178         //////////////////////////////////////////////////////////////////////\r
1179     //for processing currency string\r
1180 \r
1181         Value = CFX_WideString::FromLocal(strValue);\r
1182         \r
1183         std::wstring strValue2(Value);\r
1184 \r
1185         if (bCurrencyPrepend)\r
1186                 strValue2 = wstrCurrency + strValue2;\r
1187         else\r
1188                 strValue2 = strValue2 + wstrCurrency;\r
1189         \r
1190         \r
1191         \r
1192         /////////////////////////////////////////////////////////////////////////\r
1193         //for processing negative style\r
1194         if (bNagative)\r
1195         {\r
1196                 if (iNegStyle == 0)\r
1197                 {\r
1198                         strValue2.insert(0,L"-");\r
1199                 }\r
1200                 if (iNegStyle == 2 || iNegStyle == 3)\r
1201                 {\r
1202                         strValue2.insert(0,L"(");\r
1203                         strValue2.insert(strValue2.length(),L")");\r
1204                 }\r
1205                 if (iNegStyle == 1 || iNegStyle == 3)\r
1206                 {\r
1207                         if (Field * fTarget = pEvent->Target_Field())\r
1208                         {\r
1209                                 CJS_Array arColor(isolate);\r
1210                                 CJS_Value vColElm(isolate);\r
1211                                 vColElm = L"RGB";\r
1212                                 arColor.SetElement(0,vColElm);\r
1213                                 vColElm = 1;\r
1214                                 arColor.SetElement(1,vColElm);\r
1215                                 vColElm = 0;\r
1216                                 arColor.SetElement(2,vColElm);\r
1217                                 \r
1218                                 arColor.SetElement(3,vColElm);\r
1219                                 \r
1220                                 CJS_PropValue vProp(isolate);\r
1221                                 vProp.StartGetting();\r
1222                                 vProp<<arColor;\r
1223                                 vProp.StartSetting();\r
1224                                 fTarget->textColor(cc,vProp,sError);// red\r
1225                         }\r
1226                 }\r
1227         }\r
1228         else\r
1229         {\r
1230                 if (iNegStyle == 1 || iNegStyle == 3)\r
1231                 {\r
1232                         if (Field *fTarget = pEvent->Target_Field())\r
1233                         {\r
1234                                 CJS_Array arColor(isolate);\r
1235                                 CJS_Value vColElm(isolate);\r
1236                                 vColElm = L"RGB";\r
1237                                 arColor.SetElement(0,vColElm);\r
1238                                 vColElm = 0;\r
1239                                 arColor.SetElement(1,vColElm);\r
1240                                 arColor.SetElement(2,vColElm);\r
1241                                 arColor.SetElement(3,vColElm);\r
1242                                 \r
1243                                 CJS_PropValue vProp(isolate);\r
1244                                 vProp.StartGetting();\r
1245                                 fTarget->textColor(cc,vProp,sError);\r
1246                                 \r
1247                                 CJS_Array aProp(isolate);\r
1248                                 vProp.ConvertToArray(aProp);\r
1249 \r
1250                                 CPWL_Color crProp;\r
1251                                 CPWL_Color crColor;\r
1252                                 color::ConvertArrayToPWLColor(aProp, crProp);\r
1253                                 color::ConvertArrayToPWLColor(arColor, crColor);\r
1254 \r
1255                                 if (crColor != crProp)\r
1256                                 {\r
1257                                         CJS_PropValue vProp2(isolate);\r
1258                                         vProp2.StartGetting();\r
1259                                         vProp2<<arColor;\r
1260                                         vProp2.StartSetting();\r
1261                                 fTarget->textColor(cc,vProp2,sError);\r
1262                                 }\r
1263                         }\r
1264                 }\r
1265         }\r
1266         Value = strValue2.c_str();\r
1267 #endif\r
1268         return TRUE;\r
1269 }\r
1270 \r
1271 //function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend)\r
1272 FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(OBJ_METHOD_PARAMS)\r
1273 {\r
1274         CJS_Context* pContext = (CJS_Context *)cc;\r
1275         ASSERT(pContext != NULL);\r
1276         CJS_EventHandler* pEvent = pContext->GetEventHandler();\r
1277         ASSERT(pEvent != NULL);\r
1278         \r
1279         if(params.size() < 2)\r
1280                 return FALSE;\r
1281         int iSepStyle = params[1];\r
1282         \r
1283         if (iSepStyle < 0 || iSepStyle > 3)\r
1284                 iSepStyle = 0;\r
1285         if(!pEvent->m_pValue)\r
1286                 return FALSE;\r
1287         CFX_WideString & val = pEvent->Value(); \r
1288         CFX_WideString & w_strChange = pEvent->Change();\r
1289     CFX_WideString w_strValue = val;\r
1290 \r
1291         if (pEvent->WillCommit())\r
1292         {\r
1293                 CFX_WideString wstrChange = w_strChange;\r
1294                 CFX_WideString wstrValue = StrLTrim(w_strValue);\r
1295                 if (wstrValue.IsEmpty())\r
1296                         return TRUE;\r
1297                 \r
1298                 CFX_WideString swTemp = wstrValue;\r
1299                 swTemp.Replace((FX_LPCWSTR)L",", (FX_LPCWSTR)L".");\r
1300                 if (!IsNumber(swTemp)) //!(IsNumber(wstrChange) && \r
1301                 {\r
1302                         pEvent->Rc() = FALSE;\r
1303                         sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);\r
1304                         Alert(pContext, sError);\r
1305                         return TRUE;\r
1306                 }\r
1307                 return TRUE; // it happens after the last keystroke and before validating,\r
1308         }\r
1309         \r
1310         std::wstring w_strValue2 (w_strValue);\r
1311         std::wstring w_strChange2(w_strChange);\r
1312         \r
1313         std::wstring w_strSelected;\r
1314         if(-1 != pEvent->SelStart())\r
1315                 w_strSelected = w_strValue2.substr(pEvent->SelStart(),(pEvent->SelEnd() - pEvent->SelStart()));\r
1316         FX_BOOL bHasSign = (w_strValue2.find('-') != -1) && (w_strSelected.find('-') == -1);\r
1317         if (bHasSign)\r
1318         {\r
1319                 //can't insert "change" in front to sign postion.\r
1320                 if (pEvent->SelStart() == 0)\r
1321                 {\r
1322             FX_BOOL &bRc = pEvent->Rc();\r
1323                         bRc = FALSE;\r
1324                         return TRUE;\r
1325                 }\r
1326         }\r
1327 \r
1328         char cSep = L'.';\r
1329 \r
1330         switch (iSepStyle)\r
1331         {\r
1332         case 0:\r
1333         case 1:\r
1334                 cSep = L'.';\r
1335                 break;\r
1336         case 2:\r
1337         case 3:\r
1338                 cSep = L',';\r
1339                 break;\r
1340         }\r
1341         \r
1342         FX_BOOL bHasSep = (w_strValue2.find(cSep) != -1);\r
1343         for (std::wstring::iterator it = w_strChange2.begin(); it != w_strChange2.end(); it++)\r
1344         {\r
1345                 if (*it == cSep)\r
1346                 {\r
1347                         if (bHasSep)\r
1348                         {\r
1349                                 FX_BOOL &bRc = pEvent->Rc();\r
1350                                 bRc = FALSE;\r
1351                                 return TRUE;\r
1352                         }\r
1353                         else\r
1354                         {\r
1355                                 bHasSep = TRUE;\r
1356                                 continue;\r
1357                         }\r
1358                 }\r
1359                 if (*it == L'-')\r
1360                 {\r
1361                         if (bHasSign)\r
1362                         {\r
1363                                 FX_BOOL &bRc = pEvent->Rc();\r
1364                                 bRc = FALSE;\r
1365                                 return TRUE;\r
1366                         }\r
1367                         else if (it != w_strChange2.begin()) //sign's position is not correct\r
1368                         {\r
1369                                 FX_BOOL &bRc = pEvent->Rc();\r
1370                                 bRc = FALSE;\r
1371                                 return TRUE;\r
1372                         }\r
1373                         else if (pEvent->SelStart() != 0)\r
1374                         {\r
1375                                 FX_BOOL &bRc = pEvent->Rc();\r
1376                                 bRc = FALSE;\r
1377                                 return TRUE;\r
1378                         }\r
1379                         bHasSign = TRUE;\r
1380                         continue;\r
1381                 }\r
1382                 \r
1383                 if (!IsDigit(*it))\r
1384                 {                       \r
1385                         FX_BOOL &bRc = pEvent->Rc();\r
1386                         bRc = FALSE;\r
1387                         return TRUE;\r
1388                 }\r
1389         }\r
1390         \r
1391         \r
1392         std::wstring w_prefix = w_strValue2.substr(0,pEvent->SelStart());\r
1393         std::wstring w_postfix;\r
1394         if (pEvent->SelEnd()<(int)w_strValue2.length())\r
1395                 w_postfix  = w_strValue2.substr(pEvent->SelEnd());\r
1396         w_strValue2 = w_prefix + w_strChange2 + w_postfix;\r
1397         w_strValue = w_strValue2.c_str();\r
1398         val = w_strValue;\r
1399         return TRUE;            \r
1400         \r
1401 }\r
1402 \r
1403 //function AFPercent_Format(nDec, sepStyle)\r
1404 FX_BOOL CJS_PublicMethods::AFPercent_Format(OBJ_METHOD_PARAMS)\r
1405 {\r
1406 #if _FX_OS_ != _FX_ANDROID_\r
1407         CJS_Context* pContext = (CJS_Context *)cc;\r
1408         ASSERT(pContext != NULL);\r
1409         CJS_EventHandler* pEvent = pContext->GetEventHandler();\r
1410         ASSERT(pEvent != NULL);\r
1411 \r
1412     if (params.size() != 2)\r
1413         {\r
1414                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
1415                 return FALSE;\r
1416         }\r
1417         if(!pEvent->m_pValue)\r
1418                 return FALSE;\r
1419         CFX_WideString& Value = pEvent->Value();\r
1420         \r
1421 //     HWND hMainFrame = NULL;\r
1422 //      \r
1423 //      CPDFSDK_FormFillApp *pApp = pContext->GetReaderApp();\r
1424 //      ASSERT(pApp);\r
1425 //      hMainFrame = pApp->GetMainFrameWnd();\r
1426                 \r
1427         CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));\r
1428         \r
1429         if (strValue.IsEmpty())\r
1430                 return TRUE;\r
1431         \r
1432         int iDec = params[0];\r
1433         int iSepStyle = params[1];\r
1434         \r
1435         //ASSERT(iDec > 0);\r
1436         if (iDec < 0)\r
1437                 iDec = -iDec;\r
1438         \r
1439         if (iSepStyle < 0 || iSepStyle > 3)\r
1440                 iSepStyle = 0;\r
1441         \r
1442         \r
1443         //////////////////////////////////////////////////////\r
1444         //for processing decimal places\r
1445         double dValue = atof(strValue);\r
1446         dValue *= 100;\r
1447         if (iDec > 0)\r
1448                 dValue += DOUBLE_CORRECT;//УÕý\r
1449 \r
1450         int iDec2;\r
1451         FX_BOOL bNagative = FALSE;\r
1452         strValue = fcvt(dValue,iDec,&iDec2,&bNagative);\r
1453     if (strValue.IsEmpty())\r
1454         {\r
1455                 dValue = 0;\r
1456                 strValue = fcvt(dValue,iDec,&iDec2,&bNagative);\r
1457         }\r
1458 \r
1459         if (iDec2 < 0)\r
1460         {\r
1461                 for (int iNum = 0; iNum < abs(iDec2); iNum++)\r
1462                 {\r
1463                         strValue = "0" + strValue;\r
1464                 }\r
1465                 iDec2 = 0;\r
1466                 \r
1467         }\r
1468         int iMax = strValue.GetLength();\r
1469         if (iDec2 > iMax)\r
1470         {\r
1471                 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++)\r
1472                 {\r
1473                         strValue += "0";\r
1474                 }\r
1475                 iMax = iDec2+1;                 \r
1476         }\r
1477         ///////////////////////////////////////////////////////\r
1478     //for processing seperator style\r
1479         if (iDec2 < iMax)\r
1480         {\r
1481                 if (iSepStyle == 0 || iSepStyle == 1)\r
1482                 {\r
1483                         strValue.Insert(iDec2, '.');\r
1484                         iMax++;\r
1485                 }\r
1486                 else if (iSepStyle == 2 || iSepStyle == 3)\r
1487                 {\r
1488                         strValue.Insert(iDec2, ',');\r
1489                         iMax++;\r
1490                 }\r
1491                 \r
1492                 if (iDec2 == 0)\r
1493                         strValue.Insert(iDec2, '0');\r
1494         }\r
1495         if (iSepStyle == 0 || iSepStyle == 2)\r
1496         {\r
1497                 char cSeperator;\r
1498                 if (iSepStyle == 0)\r
1499                         cSeperator = ',';\r
1500                 else\r
1501                         cSeperator = '.';\r
1502                 \r
1503                 int iDecPositive,iDecNagative;\r
1504                 iDecPositive = iDec2;\r
1505                 iDecNagative = iDec2;\r
1506                         \r
1507                 for (iDecPositive = iDec2 -3; iDecPositive > 0; iDecPositive -= 3)\r
1508                 {\r
1509                         strValue.Insert(iDecPositive,cSeperator);\r
1510                         iMax++;\r
1511                 }\r
1512         }\r
1513         ////////////////////////////////////////////////////////////////////\r
1514         //nagative mark\r
1515         if(bNagative)\r
1516                 strValue = "-" + strValue;\r
1517         strValue += "%";\r
1518         Value = CFX_WideString::FromLocal(strValue);\r
1519 #endif\r
1520         return TRUE;\r
1521 }\r
1522 //AFPercent_Keystroke(nDec, sepStyle)\r
1523 FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(OBJ_METHOD_PARAMS)\r
1524 {\r
1525         return AFNumber_Keystroke(cc,params,vRet,sError);\r
1526 }\r
1527 \r
1528 //function AFDate_FormatEx(cFormat)\r
1529 FX_BOOL CJS_PublicMethods::AFDate_FormatEx(OBJ_METHOD_PARAMS)\r
1530 {\r
1531         CJS_Context* pContext = (CJS_Context *)cc;\r
1532         ASSERT(pContext != NULL);\r
1533         CJS_EventHandler* pEvent = pContext->GetEventHandler();\r
1534         ASSERT(pEvent != NULL);\r
1535 \r
1536         if (params.size() != 1)\r
1537         {\r
1538                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
1539                 return FALSE;\r
1540         }       \r
1541         if(!pEvent->m_pValue)\r
1542                 return FALSE;\r
1543         CFX_WideString& val = pEvent->Value();\r
1544         \r
1545         CFX_WideString strValue = val;  \r
1546         if (strValue.IsEmpty()) return TRUE;            \r
1547 \r
1548         CFX_WideString sFormat = params[0].operator CFX_WideString();\r
1549 \r
1550         FX_BOOL bWrongFormat = FALSE;\r
1551         double dDate = 0.0f;\r
1552 \r
1553         if(strValue.Find(L"GMT") != -1)\r
1554         {\r
1555                 //for GMT format time\r
1556                 //such as "Tue Aug 11 14:24:16 GMT+08002009"\r
1557                 dDate = MakeInterDate(strValue);\r
1558         }\r
1559         else\r
1560         {\r
1561                 dDate = MakeRegularDate(strValue,sFormat,bWrongFormat);\r
1562         }\r
1563 \r
1564         if (JS_PortIsNan(dDate))\r
1565         {\r
1566                 CFX_WideString swMsg;\r
1567                 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE), (FX_LPCWSTR)sFormat);\r
1568                 Alert(pContext, swMsg);\r
1569                 return FALSE;\r
1570         }\r
1571         \r
1572         val =  MakeFormatDate(dDate,sFormat);\r
1573 \r
1574         return TRUE;\r
1575 }\r
1576 \r
1577 double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue)\r
1578 {\r
1579         int nHour;\r
1580         int nMin;\r
1581         int nSec;\r
1582         int nYear;\r
1583         int nMonth;\r
1584         int nDay;\r
1585 \r
1586         CFX_WideStringArray wsArray;\r
1587         CFX_WideString sMonth = L"";\r
1588         CFX_WideString sTemp = L"";\r
1589         int nSize = strValue.GetLength();\r
1590 \r
1591         for(int i = 0; i < nSize; i++)\r
1592         {\r
1593                 FX_WCHAR c = strValue.GetAt(i);\r
1594                 if(c == L' ' || c == L':')\r
1595                 {       \r
1596                         wsArray.Add(sTemp);\r
1597                         sTemp = L"";\r
1598                         continue;\r
1599                 }\r
1600 \r
1601                 sTemp += c;\r
1602         }\r
1603         \r
1604         wsArray.Add(sTemp);\r
1605         if(wsArray.GetSize() != 8)return 0;\r
1606 \r
1607         sTemp = wsArray[1];\r
1608         if(sTemp.Compare(L"Jan") == 0) nMonth = 1;\r
1609         if(sTemp.Compare(L"Feb") == 0) nMonth = 2;\r
1610         if(sTemp.Compare(L"Mar") == 0) nMonth = 3;\r
1611         if(sTemp.Compare(L"Apr") == 0) nMonth = 4;\r
1612         if(sTemp.Compare(L"May") == 0) nMonth = 5;\r
1613         if(sTemp.Compare(L"Jun") == 0) nMonth = 6;\r
1614         if(sTemp.Compare(L"Jul") == 0) nMonth = 7;\r
1615         if(sTemp.Compare(L"Aug") == 0) nMonth = 8;\r
1616         if(sTemp.Compare(L"Sep") == 0) nMonth = 9;\r
1617         if(sTemp.Compare(L"Oct") == 0) nMonth = 10;\r
1618         if(sTemp.Compare(L"Nov") == 0) nMonth = 11;\r
1619         if(sTemp.Compare(L"Dec") == 0) nMonth = 12;\r
1620 \r
1621         nDay = (int)ParseStringToNumber(wsArray[2]);\r
1622         nHour = (int)ParseStringToNumber(wsArray[3]);\r
1623         nMin = (int)ParseStringToNumber(wsArray[4]);\r
1624         nSec = (int)ParseStringToNumber(wsArray[5]);\r
1625         nYear = (int)ParseStringToNumber(wsArray[7]);\r
1626 \r
1627         double dRet = JS_MakeDate(JS_MakeDay(nYear,nMonth - 1,nDay),JS_MakeTime(nHour, nMin, nSec, 0));\r
1628 \r
1629         if (JS_PortIsNan(dRet))\r
1630         {\r
1631                 dRet = JS_DateParse(strValue);\r
1632         }\r
1633         \r
1634         return dRet;\r
1635 }\r
1636 \r
1637 //AFDate_KeystrokeEx(cFormat)\r
1638 FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(OBJ_METHOD_PARAMS)\r
1639 {\r
1640         CJS_Context* pContext = (CJS_Context *)cc;\r
1641         ASSERT(pContext != NULL);\r
1642         CJS_EventHandler* pEvent = pContext->GetEventHandler();\r
1643         ASSERT(pEvent != NULL);\r
1644 \r
1645         if (params.size() != 1)\r
1646         {\r
1647                 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";\r
1648                 return FALSE;\r
1649         }       \r
1650         \r
1651         if (pEvent->WillCommit())\r
1652         {\r
1653                 if(!pEvent->m_pValue)\r
1654                         return FALSE;\r
1655                 CFX_WideString strValue = pEvent->Value();\r
1656                 if (strValue.IsEmpty()) return TRUE;\r
1657 \r
1658                 CFX_WideString sFormat = params[0].operator CFX_WideString();\r
1659 \r
1660                 FX_BOOL bWrongFormat = FALSE;\r
1661                 double dRet = MakeRegularDate(strValue,sFormat,bWrongFormat);\r
1662                 if (bWrongFormat || JS_PortIsNan(dRet))\r
1663                 {\r
1664                         CFX_WideString swMsg;\r
1665                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE), (FX_LPCWSTR)sFormat);\r
1666                         Alert(pContext, swMsg);\r
1667                         pEvent->Rc() = FALSE;\r
1668                         return TRUE;\r
1669                 }\r
1670         }\r
1671         return TRUE;\r
1672 }\r
1673 \r
1674 FX_BOOL CJS_PublicMethods::AFDate_Format(OBJ_METHOD_PARAMS)\r
1675 {\r
1676         v8::Isolate* isolate = ::GetIsolate(cc);\r
1677 \r
1678         if (params.size() != 1)\r
1679         {\r
1680                 CJS_Context* pContext = (CJS_Context*)cc;\r
1681                 ASSERT(pContext != NULL);\r
1682 \r
1683                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
1684                 return FALSE;\r
1685         }\r
1686 \r
1687         int iIndex = params[0];\r
1688         FX_LPCWSTR cFormats[] =  {(FX_LPCWSTR)L"m/d", (FX_LPCWSTR)L"m/d/yy", (FX_LPCWSTR)L"mm/dd/yy", (FX_LPCWSTR)L"mm/yy", (FX_LPCWSTR)L"d-mmm", (FX_LPCWSTR)L"d-mmm-yy", (FX_LPCWSTR)L"dd-mmm-yy",\r
1689                 (FX_LPCWSTR)L"yy-mm-dd", (FX_LPCWSTR)L"mmm-yy", (FX_LPCWSTR)L"mmmm-yy", (FX_LPCWSTR)L"mmm d, yyyy", (FX_LPCWSTR)L"mmmm d, yyyy",\r
1690                 (FX_LPCWSTR)L"m/d/yy h:MM tt", (FX_LPCWSTR)L"m/d/yy HH:MM" };\r
1691 \r
1692         ASSERT(iIndex < sizeof(cFormats)/sizeof(FX_LPCWSTR));\r
1693 \r
1694         if (iIndex < 0)\r
1695                 iIndex = 0;\r
1696         if (iIndex >= sizeof(cFormats)/sizeof(FX_LPCWSTR))\r
1697                 iIndex = 0;\r
1698         CJS_Parameters newParams;\r
1699         CJS_Value val(isolate,cFormats[iIndex]);\r
1700         newParams.push_back(val);\r
1701         return AFDate_FormatEx(cc,newParams,vRet,sError);\r
1702 }\r
1703 \r
1704 //AFDate_KeystrokeEx(cFormat)\r
1705 FX_BOOL CJS_PublicMethods::AFDate_Keystroke(OBJ_METHOD_PARAMS)\r
1706 {\r
1707         v8::Isolate* isolate = ::GetIsolate(cc);\r
1708 \r
1709         if (params.size() != 1)\r
1710         {\r
1711                 CJS_Context* pContext = (CJS_Context*)cc;\r
1712                 ASSERT(pContext != NULL);\r
1713 \r
1714                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
1715                 return FALSE;\r
1716         }\r
1717 \r
1718         int iIndex = params[0];\r
1719         FX_LPCWSTR cFormats[] =  {(FX_LPCWSTR)L"m/d", (FX_LPCWSTR)L"m/d/yy", (FX_LPCWSTR)L"mm/dd/yy", (FX_LPCWSTR)L"mm/yy", (FX_LPCWSTR)L"d-mmm", (FX_LPCWSTR)L"d-mmm-yy", (FX_LPCWSTR)L"dd-mmm-yy",\r
1720                 (FX_LPCWSTR)L"yy-mm-dd", (FX_LPCWSTR)L"mmm-yy", (FX_LPCWSTR)L"mmmm-yy", (FX_LPCWSTR)L"mmm d, yyyy", (FX_LPCWSTR)L"mmmm d, yyyy",\r
1721                 (FX_LPCWSTR)L"m/d/yy h:MM tt", (FX_LPCWSTR)L"m/d/yy HH:MM" };\r
1722 \r
1723         ASSERT(iIndex<sizeof(cFormats)/sizeof(FX_LPCWSTR));\r
1724 \r
1725         if (iIndex < 0)\r
1726                 iIndex = 0;\r
1727         if (iIndex >= sizeof(cFormats)/sizeof(FX_LPCWSTR))\r
1728                 iIndex = 0;\r
1729         CJS_Parameters newParams;\r
1730         CJS_Value val(isolate,cFormats[iIndex]);\r
1731         newParams.push_back(val);\r
1732         return AFDate_KeystrokeEx(cc,newParams,vRet,sError);\r
1733 }\r
1734 \r
1735 //function AFTime_Format(ptf)\r
1736 FX_BOOL CJS_PublicMethods::AFTime_Format(OBJ_METHOD_PARAMS)\r
1737 {\r
1738         v8::Isolate* isolate = ::GetIsolate(cc);\r
1739 \r
1740         if (params.size() != 1)\r
1741         {\r
1742                 CJS_Context* pContext = (CJS_Context*)cc;\r
1743                 ASSERT(pContext != NULL);\r
1744                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
1745                 return FALSE;\r
1746         }\r
1747 \r
1748         int iIndex = params[0];\r
1749         FX_LPCWSTR cFormats[] = {(FX_LPCWSTR)L"HH:MM", (FX_LPCWSTR)L"h:MM tt", (FX_LPCWSTR)L"HH:MM:ss", (FX_LPCWSTR)L"h:MM:ss tt"};\r
1750 \r
1751         ASSERT(iIndex<sizeof(cFormats)/sizeof(FX_LPCWSTR));\r
1752 \r
1753         if (iIndex < 0)\r
1754                 iIndex = 0;\r
1755         if (iIndex >= sizeof(cFormats)/sizeof(FX_LPCWSTR))\r
1756                 iIndex = 0;\r
1757         CJS_Parameters newParams;\r
1758         CJS_Value val(isolate,cFormats[iIndex]);\r
1759         newParams.push_back(val);\r
1760         return AFDate_FormatEx(cc,newParams,vRet,sError);\r
1761 }\r
1762 \r
1763 FX_BOOL CJS_PublicMethods::AFTime_Keystroke(OBJ_METHOD_PARAMS)\r
1764 {\r
1765         v8::Isolate* isolate = ::GetIsolate(cc);\r
1766         if (params.size() != 1)\r
1767         {\r
1768                 CJS_Context* pContext = (CJS_Context*)cc;\r
1769                 ASSERT(pContext != NULL);\r
1770                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
1771                 return FALSE;\r
1772         }\r
1773 \r
1774         int iIndex = params[0];\r
1775         FX_LPCWSTR cFormats[] = {(FX_LPCWSTR)L"HH:MM", (FX_LPCWSTR)L"h:MM tt", (FX_LPCWSTR)L"HH:MM:ss", (FX_LPCWSTR)L"h:MM:ss tt"};\r
1776 \r
1777         ASSERT(iIndex<sizeof(cFormats)/sizeof(FX_LPCWSTR));\r
1778 \r
1779         if (iIndex < 0)\r
1780                 iIndex = 0;\r
1781         if (iIndex >= sizeof(cFormats)/sizeof(FX_LPCWSTR))\r
1782                 iIndex = 0;\r
1783         CJS_Parameters newParams;\r
1784         CJS_Value val(isolate,cFormats[iIndex]);\r
1785         newParams.push_back(val);\r
1786         return AFDate_KeystrokeEx(cc,newParams,vRet,sError);\r
1787 }\r
1788 \r
1789 FX_BOOL CJS_PublicMethods::AFTime_FormatEx(OBJ_METHOD_PARAMS)\r
1790 {\r
1791         return AFDate_FormatEx(cc,params,vRet,sError);\r
1792 }\r
1793 \r
1794 FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(OBJ_METHOD_PARAMS)\r
1795 {\r
1796         return AFDate_KeystrokeEx(cc,params,vRet,sError);\r
1797 }\r
1798 \r
1799 //function AFSpecial_Format(psf)\r
1800 FX_BOOL CJS_PublicMethods::AFSpecial_Format(OBJ_METHOD_PARAMS)\r
1801 {\r
1802         CJS_Context* pContext = (CJS_Context *)cc;\r
1803         ASSERT(pContext != NULL);\r
1804 \r
1805         if (params.size() != 1)\r
1806         {\r
1807                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
1808                 return FALSE;\r
1809         }\r
1810 \r
1811         std::string cFormat;\r
1812         int iIndex = params[0];\r
1813 \r
1814         CJS_EventHandler* pEvent = pContext->GetEventHandler();\r
1815         ASSERT(pEvent != NULL);\r
1816 \r
1817         if(!pEvent->m_pValue)\r
1818                 return FALSE;\r
1819         CFX_WideString& Value = pEvent->Value();        \r
1820         std::string strSrc = (FX_LPCSTR)CFX_ByteString::FromUnicode(Value);\r
1821         \r
1822         switch (iIndex) \r
1823         {\r
1824         case 0:                         \r
1825                 cFormat = "99999";\r
1826                 break;\r
1827         case 1:                         \r
1828                 cFormat = "99999-9999";\r
1829                 break;\r
1830         case 2:                         \r
1831                 {\r
1832                         std::string NumberStr;\r
1833                         util::printx("9999999999", strSrc,NumberStr); \r
1834                         if (NumberStr.length() >= 10 )\r
1835                                 cFormat = "(999) 999-9999";\r
1836                         else \r
1837                                 cFormat = "999-9999";\r
1838                         break;\r
1839                 }\r
1840         case 3:\r
1841                 cFormat = "999-99-9999";\r
1842                 break;\r
1843         }\r
1844         \r
1845         std::string strDes;\r
1846         util::printx(cFormat,strSrc,strDes);\r
1847         Value = CFX_WideString::FromLocal(strDes.c_str());\r
1848         return TRUE;\r
1849 }\r
1850 \r
1851 \r
1852 //function AFSpecial_KeystrokeEx(mask)\r
1853 FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(OBJ_METHOD_PARAMS)\r
1854 {\r
1855         CJS_Context* pContext = (CJS_Context *)cc;\r
1856         ASSERT(pContext != NULL);\r
1857         CJS_EventHandler* pEvent = pContext->GetEventHandler();\r
1858 \r
1859         ASSERT(pEvent != NULL);\r
1860 \r
1861         if (params.size() < 1)\r
1862         {\r
1863                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
1864                 return FALSE;\r
1865         }\r
1866 \r
1867         if(!pEvent->m_pValue)\r
1868                 return FALSE;\r
1869         CFX_WideString& valEvent = pEvent->Value();\r
1870 \r
1871         CFX_WideString wstrMask = params[0].operator CFX_WideString();\r
1872         if (wstrMask.IsEmpty()) return TRUE;\r
1873         \r
1874         std::wstring wstrValue(valEvent);\r
1875         \r
1876         if (pEvent->WillCommit())\r
1877         {\r
1878                 if (wstrValue.empty())\r
1879                         return TRUE;\r
1880                 int iIndexMask = 0;\r
1881                 for (std::wstring::iterator it = wstrValue.begin(); it != wstrValue.end(); it++)\r
1882                 {\r
1883                         wchar_t w_Value = *it;\r
1884             if (!maskSatisfied(w_Value,wstrMask[iIndexMask]))\r
1885                                 break;\r
1886                         iIndexMask++;\r
1887                 }\r
1888 \r
1889                 if (iIndexMask != wstrMask.GetLength() || (iIndexMask != wstrValue.size() && wstrMask.GetLength() != 0))\r
1890                 {\r
1891                         Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE));\r
1892                         pEvent->Rc() = FALSE;\r
1893                 }\r
1894                 return TRUE;\r
1895         }\r
1896 \r
1897         \r
1898         CFX_WideString &wideChange = pEvent->Change();\r
1899         std::wstring wChange(wideChange);\r
1900         \r
1901         if (wChange.empty())\r
1902                 return TRUE;\r
1903     int iIndexMask = pEvent->SelStart();\r
1904         //iIndexMask++;\r
1905         \r
1906         \r
1907         if (wstrValue.length() - (pEvent->SelEnd()-pEvent->SelStart()) + wChange.length() > (FX_DWORD)wstrMask.GetLength())\r
1908         {\r
1909                 Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG));\r
1910                 pEvent->Rc() = FALSE;\r
1911                 return TRUE;\r
1912         }\r
1913         \r
1914         \r
1915         if (iIndexMask >= wstrMask.GetLength() && (!wChange.empty()))\r
1916         {\r
1917                 Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG));\r
1918                 pEvent->Rc() = FALSE;\r
1919                 return TRUE;\r
1920         }\r
1921         \r
1922         for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++)\r
1923         {\r
1924                 if (iIndexMask >= wstrMask.GetLength())\r
1925                 {\r
1926                         Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG));\r
1927                         pEvent->Rc() = FALSE;\r
1928                         return TRUE;\r
1929                 }\r
1930                 wchar_t w_Mask = wstrMask[iIndexMask];\r
1931                 if (!isReservedMaskChar(w_Mask))\r
1932                 {\r
1933                         //wChange.insert(it,w_Mask);                            \r
1934                         *it = w_Mask;\r
1935                 }\r
1936                 wchar_t w_Change = *it;\r
1937                 \r
1938         if (!maskSatisfied(w_Change,w_Mask))\r
1939                 {\r
1940                         pEvent->Rc() = FALSE;\r
1941                         return TRUE;\r
1942                 }\r
1943                 iIndexMask++;\r
1944         }\r
1945         \r
1946         wideChange = wChange.c_str();   \r
1947         \r
1948         return TRUE;\r
1949 }\r
1950 \r
1951 \r
1952 //function AFSpecial_Keystroke(psf)\r
1953 FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(OBJ_METHOD_PARAMS)\r
1954 {\r
1955         v8::Isolate* isolate = ::GetIsolate(cc);\r
1956 \r
1957         CJS_Context* pContext = (CJS_Context *)cc;\r
1958         ASSERT(pContext != NULL);\r
1959         CJS_EventHandler* pEvent = pContext->GetEventHandler();\r
1960         ASSERT(pEvent != NULL);\r
1961 \r
1962         if (params.size() != 1)\r
1963         {\r
1964                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
1965                 return FALSE;\r
1966         }\r
1967 \r
1968         std::string cFormat;\r
1969         int iIndex = (int)params[0];    \r
1970 \r
1971         if(!pEvent->m_pValue)\r
1972                 return FALSE;\r
1973         //CJS_Value val = pEvent->Value();\r
1974         CFX_WideString& val = pEvent->Value();\r
1975         std::string strSrc = (FX_LPCSTR)CFX_ByteString::FromUnicode(val);\r
1976         std::wstring wstrChange(pEvent->Change());\r
1977         \r
1978         switch (iIndex) \r
1979         {\r
1980         case 0:                         \r
1981                 cFormat = "99999";\r
1982                 break;\r
1983         case 1:                         \r
1984                 //cFormat = "99999-9999";\r
1985                 cFormat = "999999999";\r
1986                 break;\r
1987         case 2:                         \r
1988                 {\r
1989                         std::string NumberStr;\r
1990                         util::printx("9999999999", strSrc,NumberStr); \r
1991                         if (strSrc.length() + wstrChange.length() > 7 )\r
1992                                 //cFormat = "(999) 999-9999";\r
1993                                 cFormat = "9999999999";\r
1994                         else \r
1995                                 //cFormat = "999-9999";\r
1996                                 cFormat = "9999999";\r
1997                         break;\r
1998                 }\r
1999         case 3:\r
2000                 //cFormat = "999-99-9999";\r
2001                 cFormat = "999999999";\r
2002                 break;\r
2003         }\r
2004     \r
2005         CJS_Parameters params2;\r
2006         CJS_Value vMask(isolate, cFormat.c_str());\r
2007         params2.push_back(vMask);\r
2008         \r
2009     return AFSpecial_KeystrokeEx(cc,params2,vRet,sError);\r
2010 }\r
2011 \r
2012 FX_BOOL CJS_PublicMethods::AFMergeChange(OBJ_METHOD_PARAMS)\r
2013 {\r
2014         CJS_Context* pContext = (CJS_Context *)cc;\r
2015         ASSERT(pContext != NULL);\r
2016         CJS_EventHandler* pEventHandler = pContext->GetEventHandler();\r
2017         ASSERT(pEventHandler != NULL);\r
2018 \r
2019         if (params.size() != 1)\r
2020         {\r
2021                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
2022                 return FALSE;\r
2023         }\r
2024 \r
2025         CFX_WideString swValue;\r
2026         if (pEventHandler->m_pValue != NULL)\r
2027                 swValue = pEventHandler->Value();\r
2028 \r
2029         if (pEventHandler->WillCommit())\r
2030         {\r
2031                 vRet = swValue;\r
2032                 return TRUE;\r
2033         }\r
2034 \r
2035         CFX_WideString prefix,postfix;\r
2036 \r
2037         if (pEventHandler->SelStart() >= 0)\r
2038                 prefix = swValue.Mid(0,pEventHandler->SelStart());\r
2039         else\r
2040                 prefix = L"";\r
2041 \r
2042 \r
2043         if (pEventHandler->SelEnd() >= 0 && pEventHandler->SelEnd() <= swValue.GetLength())\r
2044                 postfix = swValue.Mid(pEventHandler->SelEnd(), swValue.GetLength() - pEventHandler->SelEnd());\r
2045         else postfix = L"";\r
2046 \r
2047         vRet = prefix + pEventHandler->Change() + postfix;\r
2048 \r
2049         return TRUE;\r
2050 }\r
2051 \r
2052 FX_BOOL CJS_PublicMethods::AFParseDateEx(OBJ_METHOD_PARAMS)\r
2053 {\r
2054         CJS_Context* pContext = (CJS_Context *)cc;\r
2055         ASSERT(pContext != NULL);\r
2056 \r
2057         if (params.size() != 2)\r
2058         {\r
2059                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
2060                 return FALSE;\r
2061         }\r
2062 \r
2063         CFX_WideString sValue = params[0].operator CFX_WideString();\r
2064         CFX_WideString sFormat = params[1].operator CFX_WideString();\r
2065 \r
2066         FX_BOOL bWrongFormat = FALSE;\r
2067         double dDate = MakeRegularDate(sValue,sFormat,bWrongFormat);\r
2068 \r
2069         if (JS_PortIsNan(dDate))\r
2070         {\r
2071                 CFX_WideString swMsg;\r
2072                 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE), (FX_LPCWSTR)sFormat);\r
2073                 Alert((CJS_Context *)cc, swMsg);\r
2074                 return FALSE;\r
2075         }\r
2076         \r
2077         vRet = dDate;\r
2078 \r
2079         return TRUE;\r
2080 }\r
2081 \r
2082 FX_BOOL CJS_PublicMethods::AFSimple(OBJ_METHOD_PARAMS)\r
2083 {\r
2084         if (params.size() != 3)\r
2085         {\r
2086                 CJS_Context* pContext = (CJS_Context *)cc;\r
2087                 ASSERT(pContext != NULL);\r
2088 \r
2089                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
2090                 return FALSE;\r
2091         }\r
2092 \r
2093         vRet = (double)AF_Simple(params[0].operator CFX_WideString(), (double)params[1], (double)params[2]);\r
2094         return TRUE;\r
2095 }\r
2096 \r
2097 FX_BOOL CJS_PublicMethods::AFMakeNumber(OBJ_METHOD_PARAMS)\r
2098 {\r
2099         if (params.size() != 1)\r
2100         {\r
2101                 CJS_Context* pContext = (CJS_Context *)cc;\r
2102                 ASSERT(pContext != NULL);\r
2103 \r
2104                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
2105                 return FALSE;\r
2106         }\r
2107     vRet = ParseStringToNumber(params[0].operator CFX_WideString());\r
2108         return TRUE;\r
2109 }\r
2110 \r
2111 FX_BOOL CJS_PublicMethods::AFSimple_Calculate(OBJ_METHOD_PARAMS)\r
2112 {\r
2113         v8::Isolate* isolate = ::GetIsolate(cc);\r
2114 \r
2115         CJS_Context* pContext = (CJS_Context *)cc;\r
2116         ASSERT(pContext != NULL);\r
2117 \r
2118         if (params.size() != 2)\r
2119         {\r
2120                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
2121                 return FALSE;\r
2122         }\r
2123 \r
2124         CJS_Value params1 = params[1];\r
2125 \r
2126         if (!params1.IsArrayObject() && params1.GetType() != VT_string)\r
2127         {\r
2128                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
2129                 return FALSE;\r
2130         }\r
2131         \r
2132         CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();\r
2133     ASSERT(pReaderDoc != NULL);\r
2134 \r
2135         CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();\r
2136         ASSERT(pReaderInterForm != NULL);\r
2137 \r
2138         CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();\r
2139         ASSERT(pInterForm != NULL);\r
2140 \r
2141         double dValue;\r
2142         CFX_WideString sFunction = params[0].operator CFX_WideString();\r
2143         if (wcscmp(sFunction, L"PRD") == 0)\r
2144         dValue = 1.0;\r
2145         else\r
2146                 dValue = 0.0;\r
2147 \r
2148         CJS_Array FieldNameArray = AF_MakeArrayFromList(isolate,params1);\r
2149 \r
2150         int nFieldsCount = 0;\r
2151 \r
2152         for (int i=0,isz=FieldNameArray.GetLength(); i<isz; i++)\r
2153         {\r
2154                 CJS_Value jsValue(isolate);\r
2155                 FieldNameArray.GetElement(i,jsValue);\r
2156         CFX_WideString wsFieldName = jsValue.operator CFX_WideString();\r
2157 \r
2158         for (int j=0,jsz=pInterForm->CountFields(wsFieldName); j<jsz; j++)\r
2159                 {\r
2160                         if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName))\r
2161                         {\r
2162                                 double dTemp = 0.0;\r
2163 \r
2164                                 switch (pFormField->GetFieldType())\r
2165                                 {\r
2166                                 case FIELDTYPE_TEXTFIELD:\r
2167                                 case FIELDTYPE_COMBOBOX:\r
2168                                         {\r
2169                                                 dTemp = ParseStringToNumber(pFormField->GetValue());\r
2170                                                 break;\r
2171                                         }\r
2172                                 case FIELDTYPE_PUSHBUTTON:\r
2173                                         {\r
2174                                                 dTemp = 0.0;\r
2175                                                 break;\r
2176                                         }\r
2177                                 case FIELDTYPE_CHECKBOX:\r
2178                                 case FIELDTYPE_RADIOBUTTON:\r
2179                                         {\r
2180                                                 dTemp = 0.0;\r
2181                                                 for (int c=0,csz=pFormField->CountControls(); c<csz; c++)\r
2182                                                 {\r
2183                                                         if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c))\r
2184                                                         {\r
2185                                                                 if (pFormCtrl->IsChecked())\r
2186                                                                 {\r
2187                                                                         dTemp += ParseStringToNumber(pFormCtrl->GetExportValue());\r
2188                                                                         break;\r
2189                                                                 }\r
2190                                                                 else\r
2191                                                                         continue;\r
2192                                                         }\r
2193                                                 }\r
2194                                                 break;\r
2195                                         }\r
2196                                 case FIELDTYPE_LISTBOX:\r
2197                                         {\r
2198                                                 dTemp = 0.0;\r
2199                                                 if (pFormField->CountSelectedItems() > 1)\r
2200                                                         break;\r
2201                                                 else\r
2202                                                 {\r
2203                                                         dTemp = ParseStringToNumber(pFormField->GetValue());\r
2204                                                         break;\r
2205                                                 }\r
2206                                         }\r
2207                                 default:\r
2208                                         break;\r
2209                                 }\r
2210 \r
2211                                 if (i == 0 && j == 0 && (wcscmp(sFunction,L"MIN") == 0 || wcscmp(sFunction, L"MAX") == 0))\r
2212                                         dValue = dTemp;\r
2213 \r
2214                                 dValue = AF_Simple(sFunction, dValue, dTemp);\r
2215 \r
2216                                 nFieldsCount++;\r
2217                         }\r
2218                 }\r
2219         }\r
2220 \r
2221         if (wcscmp(sFunction, L"AVG") == 0 && nFieldsCount > 0)\r
2222                 dValue /= nFieldsCount;\r
2223 \r
2224         dValue = (double)floor(dValue * FXSYS_pow((double)10,(double)6) + 0.49) / FXSYS_pow((double)10,(double)6);\r
2225         CJS_Value jsValue(isolate,dValue);\r
2226         if((CJS_EventHandler*)pContext->GetEventHandler()->m_pValue)\r
2227                 ((CJS_EventHandler*)pContext->GetEventHandler())->Value() = jsValue;\r
2228 \r
2229         return TRUE;\r
2230 }\r
2231 \r
2232 /* This function validates the current event to ensure that its value is \r
2233 ** within the specified range. */\r
2234 \r
2235 FX_BOOL CJS_PublicMethods::AFRange_Validate(OBJ_METHOD_PARAMS)\r
2236 {\r
2237         CJS_Context* pContext = (CJS_Context *)cc;\r
2238         ASSERT(pContext != NULL);\r
2239         CJS_EventHandler* pEvent = pContext->GetEventHandler();\r
2240         ASSERT(pEvent != NULL);\r
2241 \r
2242         if (params.size() != 4) \r
2243         {\r
2244                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
2245                 return FALSE;\r
2246         }\r
2247 \r
2248         if(!pEvent->m_pValue)\r
2249                 return FALSE;\r
2250         if (pEvent->Value().IsEmpty() )\r
2251                 return TRUE;\r
2252         double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));\r
2253         FX_BOOL bGreaterThan, bLessThan;\r
2254         double  dGreaterThan, dLessThan;\r
2255     bGreaterThan = (FX_BOOL)params[0];\r
2256         CFX_WideString swMsg;\r
2257         dGreaterThan = (double)params[1];\r
2258         bLessThan = (FX_BOOL)params[2];\r
2259         dLessThan = (double)params[3];\r
2260 \r
2261         if (bGreaterThan && bLessThan)\r
2262         {\r
2263                 if (dEentValue < dGreaterThan || dEentValue > dLessThan)\r
2264                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1),(FX_LPCWSTR)params[1].operator CFX_WideString(), (FX_LPCWSTR)params[3].operator CFX_WideString());\r
2265         }\r
2266         else if (bGreaterThan)\r
2267         {\r
2268                 if (dEentValue < dGreaterThan)\r
2269                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2), (FX_LPCWSTR)params[1].operator CFX_WideString());\r
2270         }\r
2271         else if (bLessThan)\r
2272         {\r
2273                 if (dEentValue > dLessThan)\r
2274                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3), (FX_LPCWSTR)params[3].operator CFX_WideString());\r
2275         }\r
2276 \r
2277         if (!swMsg.IsEmpty())\r
2278         {\r
2279                 Alert(pContext, swMsg);\r
2280                 pEvent->Rc() = FALSE;\r
2281         }\r
2282         return TRUE;\r
2283 }\r
2284 \r
2285 FX_BOOL CJS_PublicMethods::AFExtractNums(OBJ_METHOD_PARAMS)\r
2286 {\r
2287         v8::Isolate* isolate = ::GetIsolate(cc);\r
2288         CJS_Context* pContext = (CJS_Context*)cc;\r
2289         ASSERT(pContext != NULL);\r
2290 \r
2291         if (params.size() != 1) \r
2292         {\r
2293                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);\r
2294                 return FALSE;\r
2295         }\r
2296 \r
2297         CJS_Array nums(isolate);\r
2298 \r
2299         CFX_WideString str = params[0].operator CFX_WideString();\r
2300         CFX_WideString sPart;\r
2301 \r
2302         if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')\r
2303                 str = L"0" + str;\r
2304 \r
2305         int nIndex = 0;\r
2306         for (int i=0, sz=str.GetLength(); i<sz; i++)\r
2307         {\r
2308                 FX_WCHAR wc = str.GetAt(i);\r
2309                 if (IsDigit((wchar_t)wc))\r
2310                 {\r
2311                         sPart += wc;\r
2312                 }\r
2313                 else\r
2314                 {\r
2315                         if (sPart.GetLength() > 0)\r
2316                         {\r
2317                                 nums.SetElement(nIndex,CJS_Value(isolate,(FX_LPCWSTR)sPart));\r
2318                                 sPart = L"";\r
2319                                 nIndex ++;\r
2320                         }\r
2321                 }\r
2322         }\r
2323 \r
2324         if (sPart.GetLength() > 0)\r
2325         {\r
2326                 nums.SetElement(nIndex,CJS_Value(isolate,(FX_LPCWSTR)sPart));   \r
2327         }\r
2328 \r
2329         if (nums.GetLength() > 0)\r
2330                 vRet = nums;\r
2331         else\r
2332                 vRet.SetNull();\r
2333 \r
2334         return TRUE;\r
2335 }\r