Cleanup: Remove CFFL_IFormFiller::GetCommitKey() that always returns 0.
[pdfium.git] / fpdfsdk / src / fsdk_baseform.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4  
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../third_party/base/nonstd_unique_ptr.h"
8 #include "../include/fsdk_define.h"
9 #include "../include/fsdk_mgr.h"
10 #include "../include/fsdk_baseannot.h"
11 #include "../include/fsdk_baseform.h"
12 #include "../include/formfiller/FFL_FormFiller.h"
13 #include "../include/fsdk_actionhandler.h"
14
15 #include "../include/javascript/IJavaScript.h"
16
17 //------------------------------------------------------------------------------------
18 //*                                                                             CPDFSDK_Widget 
19 //------------------------------------------------------------------------------------
20
21 #define IsFloatZero(f)                                          ((f) < 0.01 && (f) > -0.01)
22 #define IsFloatBigger(fa,fb)                            ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
23 #define IsFloatSmaller(fa,fb)                           ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
24 #define IsFloatEqual(fa,fb)                                     IsFloatZero((fa)-(fb))
25
26 CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView, CPDFSDK_InterForm* pInterForm) :
27                                         CPDFSDK_Annot(pAnnot, pPageView),
28                                         m_pInterForm(pInterForm),
29                                         m_nAppAge(0),
30                                         m_nValueAge(0)
31 {
32         ASSERT(m_pInterForm != NULL);
33 }
34
35 CPDFSDK_Widget::~CPDFSDK_Widget()
36 {
37
38 }
39
40 FX_BOOL         CPDFSDK_Widget::IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode)
41 {
42         CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDict("AP");
43         if (pAP == NULL) return FALSE;
44         
45         // Choose the right sub-ap
46         const FX_CHAR* ap_entry = "N";
47         if (mode == CPDF_Annot::Down)
48                 ap_entry = "D";
49         else if (mode == CPDF_Annot::Rollover)
50                 ap_entry = "R";
51         if (!pAP->KeyExist(ap_entry))
52                 ap_entry = "N";
53         
54         // Get the AP stream or subdirectory
55         CPDF_Object* psub = pAP->GetElementValue(ap_entry);
56         if (psub == NULL) return FALSE;
57         
58         int nFieldType = GetFieldType();
59         switch (nFieldType)
60         {
61         case FIELDTYPE_PUSHBUTTON:
62         case FIELDTYPE_COMBOBOX:
63         case FIELDTYPE_LISTBOX:
64         case FIELDTYPE_TEXTFIELD:
65         case FIELDTYPE_SIGNATURE:
66                 return psub->GetType() == PDFOBJ_STREAM;
67         case FIELDTYPE_CHECKBOX:
68         case FIELDTYPE_RADIOBUTTON:
69                 if (psub->GetType() == PDFOBJ_DICTIONARY) 
70                 {
71                         CPDF_Dictionary* pSubDict = (CPDF_Dictionary*)psub;
72                         
73                         return pSubDict->GetStream(this->GetAppState()) != NULL;
74                 }
75                 else
76                         return FALSE;
77                 break;
78         }
79         
80         return TRUE;
81 }
82
83 int     CPDFSDK_Widget::GetFieldType() const
84 {
85         CPDF_FormField* pField = GetFormField();
86         ASSERT(pField != NULL);
87         
88         return pField->GetFieldType();
89 }
90
91 int CPDFSDK_Widget::GetFieldFlags() const
92 {
93         CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
94         ASSERT(pPDFInterForm != NULL);
95
96         CPDF_FormControl* pFormControl = pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict());
97         CPDF_FormField* pFormField = pFormControl->GetField();
98         return pFormField->GetFieldFlags();
99 }
100
101 CFX_ByteString CPDFSDK_Widget::GetSubType() const
102 {
103         int nType = GetFieldType();
104         
105         if (nType == FIELDTYPE_SIGNATURE)
106                 return BFFT_SIGNATURE;
107         return CPDFSDK_Annot::GetSubType();
108 }
109
110 CPDF_FormField* CPDFSDK_Widget::GetFormField() const
111 {
112         ASSERT(m_pInterForm != NULL);
113         
114         CPDF_FormControl* pCtrl = GetFormControl();     
115         ASSERT(pCtrl != NULL);
116         
117         return pCtrl->GetField();
118 }
119
120 CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const
121 {
122         ASSERT(m_pInterForm != NULL);
123         
124         CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
125         ASSERT(pPDFInterForm != NULL);
126         
127         return pPDFInterForm->GetControlByDict(GetAnnotDict());
128 }
129 static CPDF_Dictionary* BF_GetField(CPDF_Dictionary* pFieldDict, const FX_CHAR* name)
130 {
131         if (pFieldDict == NULL) return NULL;
132         // First check the dictionary itself
133         CPDF_Object* pAttr = pFieldDict->GetElementValue(name);
134         if (pAttr) return pFieldDict;
135         
136         // Now we need to search from parents
137         CPDF_Dictionary* pParent = pFieldDict->GetDict("Parent");
138         if (pParent == NULL) return NULL;
139         
140         return BF_GetField(pParent, name);
141 }
142
143 CPDF_FormControl* CPDFSDK_Widget::GetFormControl(CPDF_InterForm* pInterForm, CPDF_Dictionary* pAnnotDict)
144 {
145         ASSERT(pInterForm != NULL);
146         ASSERT(pAnnotDict != NULL);
147         
148         CPDF_FormControl* pControl = pInterForm->GetControlByDict(pAnnotDict);
149         
150         return pControl;
151 }
152
153 int CPDFSDK_Widget::GetRotate() const
154 {
155         CPDF_FormControl* pCtrl = this->GetFormControl();
156         ASSERT(pCtrl != NULL);
157         
158         return pCtrl->GetRotation() % 360;
159 }
160
161 FX_BOOL CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const
162 {
163         CPDF_FormControl* pFormCtrl = GetFormControl();
164         ASSERT(pFormCtrl != NULL);
165         
166         int iColorType = 0;     
167         color = FX_ARGBTOCOLORREF(pFormCtrl->GetBackgroundColor(iColorType));
168         
169         return iColorType != COLORTYPE_TRANSPARENT;
170 }
171
172 FX_BOOL CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const
173 {
174         CPDF_FormControl* pFormCtrl = GetFormControl();
175         ASSERT(pFormCtrl != NULL);
176         
177         int iColorType = 0;     
178         color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType));
179         
180         return iColorType != COLORTYPE_TRANSPARENT;
181 }
182
183 FX_BOOL CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const
184 {
185         CPDF_FormControl* pFormCtrl = GetFormControl();
186         ASSERT(pFormCtrl != NULL);
187         
188         CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
189         if (da.HasColor())
190         {
191                 FX_ARGB argb;
192                 int iColorType = COLORTYPE_TRANSPARENT; 
193                 da.GetColor(argb, iColorType);
194                 color = FX_ARGBTOCOLORREF(argb);
195                 
196                 return iColorType != COLORTYPE_TRANSPARENT;
197         }
198         
199         return FALSE;
200 }
201
202 FX_FLOAT CPDFSDK_Widget::GetFontSize() const
203 {
204         CPDF_FormControl* pFormCtrl = GetFormControl();
205         ASSERT(pFormCtrl != NULL);
206         
207         CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
208         CFX_ByteString csFont = "";
209         FX_FLOAT fFontSize = 0.0f;
210         pDa.GetFont(csFont, fFontSize);
211         
212         return fFontSize;
213 }
214
215 int     CPDFSDK_Widget::GetSelectedIndex(int nIndex) const
216 {
217         CPDF_FormField* pFormField = GetFormField();
218         ASSERT(pFormField != NULL);
219         
220         return pFormField->GetSelectedIndex(nIndex);
221 }
222
223 CFX_WideString CPDFSDK_Widget::GetValue() const
224 {
225         CPDF_FormField* pFormField = GetFormField();
226         ASSERT(pFormField != NULL);
227         
228         return pFormField->GetValue();
229 }
230
231 CFX_WideString CPDFSDK_Widget::GetDefaultValue() const
232 {
233         CPDF_FormField* pFormField = GetFormField();
234         ASSERT(pFormField != NULL);
235         
236         return pFormField->GetDefaultValue();
237 }
238
239 CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const
240 {
241         CPDF_FormField* pFormField = GetFormField();
242         ASSERT(pFormField != NULL);
243         
244         return pFormField->GetOptionLabel(nIndex);
245 }
246
247 int     CPDFSDK_Widget::CountOptions() const
248 {
249         CPDF_FormField* pFormField = GetFormField();
250         ASSERT(pFormField != NULL);
251         
252         return pFormField->CountOptions();
253 }
254
255 FX_BOOL CPDFSDK_Widget::IsOptionSelected(int nIndex) const
256 {
257         CPDF_FormField* pFormField = GetFormField();
258         ASSERT(pFormField != NULL);
259         
260         return pFormField->IsItemSelected(nIndex);
261 }
262
263 int     CPDFSDK_Widget::GetTopVisibleIndex() const
264 {
265         CPDF_FormField* pFormField = GetFormField();
266         ASSERT(pFormField != NULL);
267         
268         return pFormField->GetTopVisibleIndex();
269 }
270
271 FX_BOOL CPDFSDK_Widget::IsChecked() const
272 {
273         CPDF_FormControl* pFormCtrl = GetFormControl();
274         ASSERT(pFormCtrl != NULL);
275         
276         return pFormCtrl->IsChecked();
277 }
278
279 int     CPDFSDK_Widget::GetAlignment() const
280 {
281         CPDF_FormControl* pFormCtrl = GetFormControl();
282         ASSERT(pFormCtrl != NULL);
283         
284         return pFormCtrl->GetControlAlignment();
285 }
286
287 int     CPDFSDK_Widget::GetMaxLen() const
288 {
289         CPDF_FormField* pFormField = GetFormField();
290         ASSERT(pFormField != NULL);
291         
292         return pFormField->GetMaxLen();
293 }
294
295 void CPDFSDK_Widget::SetCheck(FX_BOOL bChecked, FX_BOOL bNotify)
296 {
297         CPDF_FormControl* pFormCtrl = GetFormControl();
298         ASSERT(pFormCtrl != NULL);
299         
300         CPDF_FormField* pFormField = pFormCtrl->GetField();
301         ASSERT(pFormField != NULL);
302         
303         pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked, bNotify);
304 }
305
306 void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify)
307 {
308         CPDF_FormField* pFormField = GetFormField();
309         ASSERT(pFormField != NULL);
310         
311         pFormField->SetValue(sValue, bNotify);
312 }
313
314 void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue)
315 {
316 }
317 void CPDFSDK_Widget::SetOptionSelection(int index, FX_BOOL bSelected, FX_BOOL bNotify)
318 {
319         CPDF_FormField* pFormField = GetFormField();
320         ASSERT(pFormField != NULL);
321         
322         pFormField->SetItemSelection(index, bSelected, bNotify);
323 }
324
325 void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify)
326 {
327         CPDF_FormField* pFormField = GetFormField();
328         ASSERT(pFormField != NULL);
329         
330         pFormField->ClearSelection(bNotify);
331 }
332
333 void CPDFSDK_Widget::SetTopVisibleIndex(int index)
334 {
335 }
336
337 void CPDFSDK_Widget::SetAppModified()
338 {
339         m_bAppModified = TRUE;
340 }
341
342 void CPDFSDK_Widget::ClearAppModified()
343 {
344         m_bAppModified = FALSE;
345 }
346
347 FX_BOOL CPDFSDK_Widget::IsAppModified() const
348 {
349         return m_bAppModified;
350 }
351
352 void CPDFSDK_Widget::ResetAppearance(const FX_WCHAR* sValue, FX_BOOL bValueChanged)
353 {
354         SetAppModified();
355
356         m_nAppAge++;
357         if (m_nAppAge > 999999)
358                 m_nAppAge = 0;
359         if (bValueChanged)
360                 m_nValueAge++;
361
362         int nFieldType = GetFieldType();
363         
364         switch (nFieldType)
365         {
366         case FIELDTYPE_PUSHBUTTON:
367                 ResetAppearance_PushButton();
368                 break;
369         case FIELDTYPE_CHECKBOX:
370                 ResetAppearance_CheckBox();
371                 break;
372         case FIELDTYPE_RADIOBUTTON:
373                 ResetAppearance_RadioButton();
374                 break;
375         case FIELDTYPE_COMBOBOX:
376                 ResetAppearance_ComboBox(sValue);
377                 break;
378         case FIELDTYPE_LISTBOX:
379                 ResetAppearance_ListBox();
380                 break;
381         case FIELDTYPE_TEXTFIELD:
382                 ResetAppearance_TextField(sValue);
383                 break;
384         }
385         
386         ASSERT(m_pAnnot != NULL);
387         m_pAnnot->ClearCachedAP();
388 }
389
390 CFX_WideString CPDFSDK_Widget::OnFormat(FX_BOOL& bFormated)
391 {
392     CPDF_FormField* pFormField = GetFormField();
393     ASSERT(pFormField != NULL);
394     return m_pInterForm->OnFormat(pFormField, bFormated);
395 }
396
397 void CPDFSDK_Widget::ResetFieldAppearance(FX_BOOL bValueChanged)
398 {
399         CPDF_FormField* pFormField = GetFormField();
400         ASSERT(pFormField != NULL);
401         
402         ASSERT(m_pInterForm != NULL);
403
404         m_pInterForm->ResetFieldAppearance(pFormField, NULL, bValueChanged);
405 }
406
407 void    CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
408                 CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions)
409 {
410         int nFieldType = GetFieldType();
411         
412         if ((nFieldType == FIELDTYPE_CHECKBOX || nFieldType == FIELDTYPE_RADIOBUTTON) &&
413                 mode == CPDF_Annot::Normal && 
414                 !this->IsWidgetAppearanceValid(CPDF_Annot::Normal))
415         {
416                 CFX_PathData pathData;
417                 
418                 CPDF_Rect rcAnnot = this->GetRect();
419                 
420                 pathData.AppendRect(rcAnnot.left, rcAnnot.bottom,
421                         rcAnnot.right, rcAnnot.top);
422                 
423                 CFX_GraphStateData gsd;
424                 gsd.m_LineWidth = 0.0f;
425                 
426                 pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA, FXFILL_ALTERNATE);
427         }
428         else
429         {
430                 CPDFSDK_Annot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
431         }
432 }
433
434 void CPDFSDK_Widget::UpdateField()
435 {
436         CPDF_FormField* pFormField = GetFormField();
437         ASSERT(pFormField != NULL);
438         
439         ASSERT(m_pInterForm != NULL);
440         m_pInterForm->UpdateField(pFormField);
441 }
442
443 void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice, CPDFSDK_PageView* pPageView)
444 {
445         ASSERT(m_pInterForm != NULL);
446  
447         int nFieldType = GetFieldType();
448         if (m_pInterForm->IsNeedHighLight(nFieldType))
449         {
450  
451 //              if (nFieldType != FIELDTYPE_PUSHBUTTON)
452 //              {
453                         CPDF_Rect rc  = GetRect();
454                         FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
455                         uint8_t alpha = m_pInterForm->GetHighlightAlpha();
456
457                         CFX_FloatRect rcDevice;
458                         ASSERT(m_pInterForm->GetDocument());
459                         CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv();
460                         if(!pEnv)
461                                 return;
462                         CFX_AffineMatrix page2device;
463                         pPageView->GetCurrentMatrix(page2device);
464                         page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom), rcDevice.left, rcDevice.bottom);
465 //                      pEnv->FFI_PageToDevice(m_pPageView->GetPDFPage(), rc.left, rc.bottom, &rcDevice.left, &rcDevice.bottom);
466 //                      pEnv->FFI_PageToDevice(m_pPageView->GetPDFPage(), rc.right, rc.top, &rcDevice.right, &rcDevice.top);
467                         page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top), rcDevice.right, rcDevice.top);
468
469                         rcDevice.Normalize();
470
471                         FX_ARGB argb = ArgbEncode((int)alpha, color);
472                         FX_RECT rcDev((int)rcDevice.left,(int)rcDevice.top,(int)rcDevice.right,(int)rcDevice.bottom);
473                         pDevice->FillRect(&rcDev, argb);        
474                         /*              }*/
475         }
476 }
477
478 void CPDFSDK_Widget::ResetAppearance_PushButton()
479 {
480         CPDF_FormControl* pControl = GetFormControl();
481         ASSERT(pControl != NULL);
482
483
484         
485         CPDF_Rect rcWindow = GetRotatedRect();  
486
487         int32_t nLayout = 0;
488
489         switch (pControl->GetTextPosition())
490         {
491         case TEXTPOS_ICON:
492                 nLayout = PPBL_ICON;
493                 break;
494         case TEXTPOS_BELOW:
495                 nLayout = PPBL_ICONTOPLABELBOTTOM;
496                 break;
497         case TEXTPOS_ABOVE:
498                 nLayout = PPBL_LABELTOPICONBOTTOM;
499                 break;
500         case TEXTPOS_RIGHT:
501                 nLayout = PPBL_ICONLEFTLABELRIGHT;
502                 break;
503         case TEXTPOS_LEFT:
504                 nLayout = PPBL_LABELLEFTICONRIGHT;
505                 break;
506         case TEXTPOS_OVERLAID:
507                 nLayout = PPBL_LABELOVERICON;
508                 break;
509         default:
510                 nLayout = PPBL_LABEL;
511                 break;
512         }
513
514         CPWL_Color crBackground, crBorder;
515
516         int iColorType;
517         FX_FLOAT fc[4];
518
519         pControl->GetOriginalBackgroundColor(iColorType, fc);
520         if (iColorType > 0)
521                 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
522
523         pControl->GetOriginalBorderColor(iColorType, fc);
524         if (iColorType > 0)
525                 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
526
527         FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
528         int32_t nBorderStyle = 0;
529         CPWL_Dash dsBorder(3,0,0);
530         CPWL_Color crLeftTop,crRightBottom;
531
532         switch (GetBorderStyle())
533         {
534         case BBS_DASH:
535                 nBorderStyle = PBS_DASH;
536                 dsBorder = CPWL_Dash(3, 3, 0);
537                 break;
538         case BBS_BEVELED:
539                 nBorderStyle = PBS_BEVELED;
540                 fBorderWidth *= 2;
541                 crLeftTop = CPWL_Color(COLORTYPE_GRAY,1);
542                 crRightBottom = CPWL_Utils::DevideColor(crBackground,2);
543                 break;
544         case BBS_INSET:
545                 nBorderStyle = PBS_INSET;
546                 fBorderWidth *= 2;
547                 crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5);
548                 crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75);
549                 break;
550         case BBS_UNDERLINE:
551                 nBorderStyle = PBS_UNDERLINED;
552                 break;
553         default: 
554                 nBorderStyle = PBS_SOLID;
555                 break;
556         }
557
558         CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow,fBorderWidth);    
559
560         CPWL_Color crText(COLORTYPE_GRAY,0);
561
562         FX_FLOAT fFontSize = 12.0f;
563         CFX_ByteString csNameTag;
564
565         CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
566         if (da.HasColor())
567         {
568                 da.GetColor(iColorType, fc);
569                 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
570         }
571
572         if (da.HasFont()) 
573                 da.GetFont(csNameTag, fFontSize);
574
575         CFX_WideString csWCaption;
576         CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;
577
578         if (pControl->HasMKEntry("CA"))
579         {
580                 csNormalCaption = pControl->GetNormalCaption();
581         }
582         if (pControl->HasMKEntry("RC"))
583         {
584                 csRolloverCaption = pControl->GetRolloverCaption();
585         }
586         if (pControl->HasMKEntry("AC"))
587         {
588                 csDownCaption = pControl->GetDownCaption();
589         }
590
591         CPDF_Stream* pNormalIcon = NULL;
592         CPDF_Stream* pRolloverIcon = NULL;
593         CPDF_Stream* pDownIcon = NULL;
594
595         if (pControl->HasMKEntry("I"))
596         {
597                 pNormalIcon = pControl->GetNormalIcon();
598         }
599         if (pControl->HasMKEntry("RI"))
600         {
601                 pRolloverIcon = pControl->GetRolloverIcon();
602         }
603         if (pControl->HasMKEntry("IX"))
604         {
605                 pDownIcon = pControl->GetDownIcon();
606         }
607
608         if (pNormalIcon)
609         {
610                 if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict())
611                 {
612                         if (pImageDict->GetString("Name").IsEmpty())
613                                 pImageDict->SetAtString("Name", "ImgA");
614                 }
615         }
616
617         if (pRolloverIcon)
618         {
619                 if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict())
620                 {
621                         if (pImageDict->GetString("Name").IsEmpty())
622                                 pImageDict->SetAtString("Name", "ImgB");
623                 }
624         }
625
626         if (pDownIcon)
627         {
628                 if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict())
629                 {
630                         if (pImageDict->GetString("Name").IsEmpty())
631                                 pImageDict->SetAtString("Name", "ImgC");
632                 }
633         }
634
635         CPDF_IconFit iconFit = pControl->GetIconFit();
636
637 //      ASSERT(this->m_pBaseForm != NULL);
638         ASSERT(this->m_pInterForm != NULL);
639         CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
640         ASSERT(pDoc != NULL);
641         CPDFDoc_Environment* pEnv = pDoc->GetEnv();
642
643         CBA_FontMap FontMap(this,pEnv->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pBaseForm->GetEnv()));
644         FontMap.Initial();
645
646         FontMap.SetAPType("N");
647
648         CFX_ByteString csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) + 
649                 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder) +
650                 CPWL_Utils::GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap, pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);
651
652         WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
653         if (pNormalIcon)
654                 AddImageToAppearance("N", pNormalIcon);
655
656         CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
657         if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle)
658         {
659                 if (csRolloverCaption.IsEmpty() && !pRolloverIcon)                      
660                 {
661                         csRolloverCaption = csNormalCaption;
662                         pRolloverIcon = pNormalIcon;
663                 }
664
665                 FontMap.SetAPType("R");
666
667                 csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) + 
668                                 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder) +
669                                 CPWL_Utils::GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap, pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize, nLayout);
670
671                 WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
672                 if (pRolloverIcon)
673                         AddImageToAppearance("R", pRolloverIcon);
674
675                 if (csDownCaption.IsEmpty() && !pDownIcon)
676                 {
677                         csDownCaption = csNormalCaption;
678                         pDownIcon = pNormalIcon;
679                 }
680
681                 switch (nBorderStyle)
682                 {
683                 case PBS_BEVELED:
684                         {
685                                 CPWL_Color crTemp = crLeftTop;
686                                 crLeftTop = crRightBottom;
687                                 crRightBottom = crTemp;
688                         }
689                         break;
690                 case PBS_INSET:
691                         crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
692                         crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
693                         break;
694                 }
695                 
696                 FontMap.SetAPType("D");
697
698                 csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, CPWL_Utils::SubstractColor(crBackground,0.25f)) + 
699                         CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder) + 
700                         CPWL_Utils::GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap, pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
701
702                 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
703                 if (pDownIcon)
704                         AddImageToAppearance("D", pDownIcon);
705         }
706         else
707         {
708                 RemoveAppearance("D");
709                 RemoveAppearance("R");
710         }
711 }
712
713 void CPDFSDK_Widget::ResetAppearance_CheckBox()
714 {
715         CPDF_FormControl* pControl = GetFormControl();
716         ASSERT(pControl != NULL);
717
718
719
720         CPWL_Color crBackground, crBorder, crText;
721         
722         int iColorType;
723         FX_FLOAT fc[4];
724
725         pControl->GetOriginalBackgroundColor(iColorType, fc);
726         if (iColorType > 0)
727                 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
728
729         pControl->GetOriginalBorderColor(iColorType, fc);
730         if (iColorType > 0)
731                 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
732
733         FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
734         int32_t nBorderStyle = 0;
735         CPWL_Dash dsBorder(3,0,0);
736         CPWL_Color crLeftTop,crRightBottom;
737
738         switch (GetBorderStyle())
739         {
740         case BBS_DASH:
741                 nBorderStyle = PBS_DASH;
742                 dsBorder = CPWL_Dash(3, 3, 0);
743                 break;
744         case BBS_BEVELED:
745                 nBorderStyle = PBS_BEVELED;
746                 fBorderWidth *= 2;
747                 crLeftTop = CPWL_Color(COLORTYPE_GRAY,1);
748                 crRightBottom = CPWL_Utils::DevideColor(crBackground,2);
749                 break;
750         case BBS_INSET:
751                 nBorderStyle = PBS_INSET;
752                 fBorderWidth *= 2;
753                 crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5);
754                 crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75);
755                 break;
756         case BBS_UNDERLINE:
757                 nBorderStyle = PBS_UNDERLINED;
758                 break;
759         default: 
760                 nBorderStyle = PBS_SOLID;
761                 break;
762         }
763
764         CPDF_Rect rcWindow = GetRotatedRect();
765         CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow,fBorderWidth);
766
767         CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
768         if (da.HasColor())
769         {
770                 da.GetColor(iColorType, fc);
771                 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
772         }
773
774         int32_t nStyle = 0;
775
776         CFX_WideString csWCaption = pControl->GetNormalCaption();
777         if (csWCaption.GetLength() > 0)
778         {
779                 switch (csWCaption[0])
780                 {
781                 case L'l':
782                         nStyle = PCS_CIRCLE;                    
783                         break;
784                 case L'8':
785                         nStyle = PCS_CROSS;
786                         break;
787                 case L'u':
788                         nStyle = PCS_DIAMOND;
789                         break;
790                 case L'n':
791                         nStyle = PCS_SQUARE;
792                         break;
793                 case L'H':
794                         nStyle = PCS_STAR;
795                         break;
796                 default: //L'4'
797                         nStyle = PCS_CHECK;
798                         break;
799                 }
800         }
801         else
802         {
803                 nStyle = PCS_CHECK;
804         }
805
806         CFX_ByteString csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,crBackground) +
807                 CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
808
809         CFX_ByteString csAP_N_OFF = csAP_N_ON;
810
811         switch (nBorderStyle)
812         {
813         case PBS_BEVELED:
814                 {
815                         CPWL_Color crTemp = crLeftTop;
816                         crLeftTop = crRightBottom;
817                         crRightBottom = crTemp;
818                 }
819                 break;
820         case PBS_INSET:
821                 crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
822                 crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
823                 break;
824         }
825
826         CFX_ByteString csAP_D_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,CPWL_Utils::SubstractColor(crBackground,0.25f)) + 
827                 CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
828
829         CFX_ByteString csAP_D_OFF = csAP_D_ON;
830
831         csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient,nStyle,crText);
832         csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient,nStyle,crText);
833
834         WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON, pControl->GetCheckedAPState());
835         WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
836
837         WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON, pControl->GetCheckedAPState());
838         WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
839
840         CFX_ByteString csAS = GetAppState();
841         if (csAS.IsEmpty())
842                 SetAppState("Off");
843 }
844
845 void CPDFSDK_Widget::ResetAppearance_RadioButton()
846 {
847         CPDF_FormControl* pControl = GetFormControl();
848         ASSERT(pControl != NULL);
849         
850
851
852         CPWL_Color crBackground, crBorder, crText;
853         
854         int iColorType;
855         FX_FLOAT fc[4];
856
857         pControl->GetOriginalBackgroundColor(iColorType, fc);
858         if (iColorType > 0)
859                 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
860
861         pControl->GetOriginalBorderColor(iColorType, fc);
862         if (iColorType > 0)
863                 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
864
865         FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
866         int32_t nBorderStyle = 0;
867         CPWL_Dash dsBorder(3,0,0);
868         CPWL_Color crLeftTop,crRightBottom;
869
870         switch (GetBorderStyle())
871         {
872         case BBS_DASH:
873                 nBorderStyle = PBS_DASH;
874                 dsBorder = CPWL_Dash(3, 3, 0);
875                 break;
876         case BBS_BEVELED:
877                 nBorderStyle = PBS_BEVELED;
878                 fBorderWidth *= 2;
879                 crLeftTop = CPWL_Color(COLORTYPE_GRAY,1);
880                 crRightBottom = CPWL_Utils::DevideColor(crBackground,2);
881                 break;
882         case BBS_INSET:
883                 nBorderStyle = PBS_INSET;
884                 fBorderWidth *= 2;
885                 crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5);
886                 crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75);
887                 break;
888         case BBS_UNDERLINE:
889                 nBorderStyle = PBS_UNDERLINED;
890                 break;
891         default: 
892                 nBorderStyle = PBS_SOLID;
893                 break;
894         }
895
896         CPDF_Rect rcWindow = GetRotatedRect();
897         CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
898
899         CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
900         if (da.HasColor())
901         {
902                 da.GetColor(iColorType, fc);
903                 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
904         }
905
906         int32_t nStyle = 0;
907
908         CFX_WideString csWCaption = pControl->GetNormalCaption();
909         if (csWCaption.GetLength() > 0)
910         {
911                 switch (csWCaption[0])
912                 {
913                 default: //L'l':
914                         nStyle = PCS_CIRCLE;                    
915                         break;
916                 case L'8':
917                         nStyle = PCS_CROSS;
918                         break;
919                 case L'u':
920                         nStyle = PCS_DIAMOND;
921                         break;
922                 case L'n':
923                         nStyle = PCS_SQUARE;
924                         break;
925                 case L'H':
926                         nStyle = PCS_STAR;
927                         break;
928                 case L'4':
929                         nStyle = PCS_CHECK;
930                         break;
931                 }
932         }
933         else
934         {
935                 nStyle = PCS_CIRCLE;
936         }
937
938         CFX_ByteString csAP_N_ON;
939
940         CPDF_Rect rcCenter = CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f);
941         
942         if (nStyle == PCS_CIRCLE)
943         {
944                 if (nBorderStyle == PBS_BEVELED)
945                 {
946                         crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
947                         crRightBottom = CPWL_Utils::SubstractColor(crBackground,0.25f);
948                 }
949                 else if (nBorderStyle == PBS_INSET)
950                 {
951                         crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5f);
952                         crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75f);
953                 }
954
955                 csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter,crBackground) + 
956                         CPWL_Utils::GetCircleBorderAppStream(rcCenter,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
957         }
958         else
959         {
960                 csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,crBackground) + 
961                         CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
962         }
963
964         CFX_ByteString csAP_N_OFF = csAP_N_ON;
965
966         switch (nBorderStyle)
967         {
968         case PBS_BEVELED:
969                 {
970                         CPWL_Color crTemp = crLeftTop;
971                         crLeftTop = crRightBottom;
972                         crRightBottom = crTemp;
973                 }
974                 break;
975         case PBS_INSET:
976                 crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
977                 crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
978                 break;
979         }
980
981         CFX_ByteString csAP_D_ON;
982
983         if (nStyle == PCS_CIRCLE)
984         {
985                 CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground,0.25f);
986                 if (nBorderStyle == PBS_BEVELED)
987                 {
988                         crLeftTop = CPWL_Utils::SubstractColor(crBackground,0.25f);
989                         crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
990                         crBK = crBackground;
991                 }
992                 else if (nBorderStyle == PBS_INSET)
993                 {
994                         crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
995                         crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
996                 }
997
998                 csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter,crBK)
999                         + CPWL_Utils::GetCircleBorderAppStream(rcCenter,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
1000         }
1001         else
1002         {
1003                 csAP_D_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,CPWL_Utils::SubstractColor(crBackground,0.25f)) + 
1004                         CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);           
1005         }
1006
1007         CFX_ByteString csAP_D_OFF = csAP_D_ON;
1008
1009         csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient,nStyle,crText);
1010         csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient,nStyle,crText);
1011
1012         WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON, pControl->GetCheckedAPState());
1013         WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
1014
1015         WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON, pControl->GetCheckedAPState());
1016         WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
1017
1018         CFX_ByteString csAS = GetAppState();
1019         if (csAS.IsEmpty())
1020                 SetAppState("Off");
1021 }
1022
1023 void CPDFSDK_Widget::ResetAppearance_ComboBox(const FX_WCHAR* sValue)
1024 {
1025         CPDF_FormControl* pControl = GetFormControl();
1026         ASSERT(pControl != NULL);
1027         CPDF_FormField* pField = pControl->GetField();
1028         ASSERT(pField != NULL);
1029
1030         CFX_ByteTextBuf sBody, sLines;
1031
1032         CPDF_Rect rcClient = GetClientRect();
1033         CPDF_Rect rcButton = rcClient;
1034         rcButton.left = rcButton.right - 13;
1035         rcButton.Normalize();
1036
1037         if (IFX_Edit * pEdit = IFX_Edit::NewEdit())
1038         {
1039                 pEdit->EnableRefresh(FALSE);
1040
1041                 ASSERT(this->m_pInterForm != NULL);
1042                 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
1043                 ASSERT(pDoc != NULL);
1044                 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
1045                 CBA_FontMap FontMap(this,pEnv->GetSysHandler());
1046                 FontMap.Initial();
1047                 pEdit->SetFontMap(&FontMap);
1048
1049                 CPDF_Rect rcEdit = rcClient;
1050                 rcEdit.right = rcButton.left;
1051                 rcEdit.Normalize();
1052                 
1053                 pEdit->SetPlateRect(rcEdit);
1054                 pEdit->SetAlignmentV(1);
1055
1056                 FX_FLOAT fFontSize = this->GetFontSize();
1057                 if (IsFloatZero(fFontSize))
1058                         pEdit->SetAutoFontSize(TRUE);
1059                 else
1060                         pEdit->SetFontSize(fFontSize);
1061                 
1062                 pEdit->Initialize();
1063                 
1064                 if (sValue)
1065                         pEdit->SetText(sValue);
1066                 else
1067                 {
1068                         int32_t nCurSel = pField->GetSelectedIndex(0);
1069
1070                         if (nCurSel < 0)
1071                                 pEdit->SetText(pField->GetValue().c_str());
1072                         else
1073                                 pEdit->SetText(pField->GetOptionLabel(nCurSel).c_str());
1074                 }
1075
1076                 CPDF_Rect rcContent = pEdit->GetContentRect();
1077
1078                 CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,0.0f));
1079                 if (sEdit.GetLength() > 0)
1080                 {
1081                         sBody << "/Tx BMC\n" << "q\n";
1082                         if (rcContent.Width() > rcEdit.Width() ||
1083                                 rcContent.Height() > rcEdit.Height())
1084                         {
1085                                 sBody << rcEdit.left << " " << rcEdit.bottom << " " 
1086                                         << rcEdit.Width() << " " << rcEdit.Height() << " re\nW\nn\n";
1087                         }
1088
1089                         CPWL_Color crText = GetTextPWLColor();  
1090                         sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n" << "Q\nEMC\n";
1091                 }
1092
1093                 IFX_Edit::DelEdit(pEdit);
1094         }
1095
1096         sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
1097
1098         CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + sLines.GetByteString() + sBody.GetByteString();
1099
1100         WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1101 }
1102
1103 void CPDFSDK_Widget::ResetAppearance_ListBox()
1104 {
1105         CPDF_FormControl* pControl = GetFormControl();
1106         ASSERT(pControl != NULL);
1107         CPDF_FormField* pField = pControl->GetField();
1108         ASSERT(pField != NULL);
1109
1110         CPDF_Rect rcClient = GetClientRect();
1111
1112         CFX_ByteTextBuf sBody, sLines;
1113
1114         if (IFX_Edit * pEdit = IFX_Edit::NewEdit())
1115         {
1116                 pEdit->EnableRefresh(FALSE);
1117
1118 //              ASSERT(this->m_pBaseForm != NULL);
1119                 ASSERT(this->m_pInterForm != NULL);
1120                 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
1121                 ASSERT(pDoc != NULL);
1122                 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
1123
1124                 CBA_FontMap FontMap(this,pEnv->GetSysHandler());
1125                 FontMap.Initial();
1126                 pEdit->SetFontMap(&FontMap);
1127
1128                 pEdit->SetPlateRect(CPDF_Rect(rcClient.left,0.0f,rcClient.right,0.0f)); 
1129                 
1130                 FX_FLOAT fFontSize = GetFontSize();
1131
1132                 if (IsFloatZero(fFontSize))
1133                         pEdit->SetFontSize(12.0f);
1134                 else
1135                         pEdit->SetFontSize(fFontSize);
1136                 
1137                 pEdit->Initialize();
1138
1139                 CFX_ByteTextBuf sList;
1140                 FX_FLOAT fy = rcClient.top;
1141
1142                 int32_t nTop = pField->GetTopVisibleIndex();
1143                 int32_t nCount = pField->CountOptions();
1144                 int32_t nSelCount = pField->CountSelectedItems();
1145
1146                 for (int32_t i=nTop; i<nCount; i++)
1147                 {
1148                         FX_BOOL bSelected = FALSE;                              
1149                         for (int32_t j=0; j<nSelCount; j++)
1150                         {
1151                                 if (pField->GetSelectedIndex(j) == i)
1152                                 {
1153                                         bSelected = TRUE;
1154                                         break;
1155                                 }
1156                         }
1157
1158                         pEdit->SetText(pField->GetOptionLabel(i).c_str());
1159
1160                         CPDF_Rect rcContent = pEdit->GetContentRect();
1161                         FX_FLOAT fItemHeight = rcContent.Height();
1162
1163                         if (bSelected)
1164                         {
1165                                 CPDF_Rect rcItem = CPDF_Rect(rcClient.left,fy-fItemHeight,rcClient.right,fy);
1166                                 sList << "q\n" << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_RGB,0,51.0f/255.0f,113.0f/255.0f),TRUE)
1167                                         << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width() << " " << rcItem.Height() << " re f\n" << "Q\n";
1168
1169                                 sList << "BT\n" << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY,1),TRUE) << 
1170                                         CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,fy)) << "ET\n";
1171                         }
1172                         else
1173                         {
1174                                 CPWL_Color crText = GetTextPWLColor();
1175                                 sList << "BT\n" << CPWL_Utils::GetColorAppStream(crText,TRUE) << 
1176                                 CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,fy)) << "ET\n";
1177                         }
1178
1179                         fy -= fItemHeight;
1180                 }
1181                                         
1182                 if (sList.GetSize() > 0)
1183                 {
1184                         sBody << "/Tx BMC\n" << "q\n" << rcClient.left << " " << rcClient.bottom << " " 
1185                                         << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
1186                         sBody << sList << "Q\nEMC\n";
1187                 }
1188
1189                 IFX_Edit::DelEdit(pEdit);
1190         }
1191
1192         CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + sLines.GetByteString() + sBody.GetByteString();
1193
1194         WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1195 }
1196
1197 void CPDFSDK_Widget::ResetAppearance_TextField(const FX_WCHAR* sValue)
1198 {
1199         CPDF_FormControl* pControl = GetFormControl();
1200         ASSERT(pControl != NULL);
1201         CPDF_FormField* pField = pControl->GetField();
1202         ASSERT(pField != NULL);
1203
1204         CFX_ByteTextBuf sBody, sLines;
1205         
1206         if (IFX_Edit * pEdit = IFX_Edit::NewEdit())
1207         {
1208                 pEdit->EnableRefresh(FALSE);
1209
1210 //              ASSERT(this->m_pBaseForm != NULL);
1211                 ASSERT(this->m_pInterForm != NULL);
1212                 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
1213                 ASSERT(pDoc != NULL);
1214                 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
1215
1216                 CBA_FontMap FontMap(this,pEnv->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pBaseForm->GetEnv()));
1217                 FontMap.Initial();
1218                 pEdit->SetFontMap(&FontMap);
1219
1220                 CPDF_Rect rcClient = GetClientRect();
1221                 pEdit->SetPlateRect(rcClient);
1222                 pEdit->SetAlignmentH(pControl->GetControlAlignment());
1223                 
1224                 FX_DWORD dwFieldFlags = pField->GetFieldFlags();
1225                 FX_BOOL bMultiLine = (dwFieldFlags >> 12) & 1;
1226
1227                 if (bMultiLine)
1228                 {
1229                         pEdit->SetMultiLine(TRUE);
1230                         pEdit->SetAutoReturn(TRUE);
1231                 }
1232                 else
1233                 {
1234                         pEdit->SetAlignmentV(1);
1235                 }
1236
1237                 FX_WORD subWord = 0;
1238                 if ((dwFieldFlags >> 13) & 1)
1239                 {
1240                         subWord = '*';
1241                         pEdit->SetPasswordChar(subWord);
1242                 }
1243
1244                 int nMaxLen = pField->GetMaxLen();
1245                 FX_BOOL bCharArray = (dwFieldFlags >> 24) & 1;
1246                 FX_FLOAT fFontSize = GetFontSize();     
1247
1248                 if (nMaxLen > 0)
1249                 {
1250                         if (bCharArray)
1251                         {
1252                                 pEdit->SetCharArray(nMaxLen);
1253
1254                                 if (IsFloatZero(fFontSize))
1255                                 {
1256                                         fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(FontMap.GetPDFFont(0),rcClient,nMaxLen);
1257                                 }
1258                         }
1259                         else
1260                         {
1261                                 if (sValue)
1262                                         nMaxLen = wcslen((const wchar_t*)sValue); 
1263                                 pEdit->SetLimitChar(nMaxLen);
1264                         }
1265                 }
1266
1267                 if (IsFloatZero(fFontSize))
1268                         pEdit->SetAutoFontSize(TRUE);
1269                 else
1270                         pEdit->SetFontSize(fFontSize);
1271
1272                 pEdit->Initialize();
1273                 
1274                 if (sValue)
1275                         pEdit->SetText(sValue);
1276                 else
1277                         pEdit->SetText(pField->GetValue().c_str());
1278
1279                 CPDF_Rect rcContent = pEdit->GetContentRect();
1280
1281                 CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,0.0f),
1282                                                                                                                                         NULL,!bCharArray,subWord);
1283
1284                 if (sEdit.GetLength() > 0)
1285                 {
1286                         sBody << "/Tx BMC\n" << "q\n";
1287                         if (rcContent.Width() > rcClient.Width() ||
1288                                 rcContent.Height() > rcClient.Height())
1289                         {
1290                                 sBody << rcClient.left << " " << rcClient.bottom << " " 
1291                                         << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
1292                         }
1293                         CPWL_Color crText = GetTextPWLColor();  
1294                         sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n" << "Q\nEMC\n";
1295                 }
1296
1297                 if (bCharArray)
1298                 {
1299                         switch (GetBorderStyle())
1300                         {
1301                         case BBS_SOLID:
1302                                 {
1303                                         CFX_ByteString sColor = CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE);
1304                                         if (sColor.GetLength() > 0)
1305                                         {
1306                                                 sLines << "q\n" << GetBorderWidth() << " w\n" 
1307                                                         << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE) << " 2 J 0 j\n";                                    
1308
1309                                                 for (int32_t i=1;i<nMaxLen;i++)
1310                                                 {
1311                                                         sLines << rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
1312                                                                 << rcClient.bottom << " m\n"
1313                                                                 << rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
1314                                                                 << rcClient.top << " l S\n";                                            
1315                                                 }
1316
1317                                                 sLines << "Q\n";                
1318                                         }
1319                                 }
1320                                 break;
1321                         case BBS_DASH:
1322                                 {
1323                                         CFX_ByteString sColor = CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE);
1324                                         if (sColor.GetLength() > 0)
1325                                         {
1326                                                 CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
1327
1328                                                 sLines << "q\n" << GetBorderWidth() << " w\n" 
1329                                                         << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE)
1330                                                         << "[" << dsBorder.nDash << " " 
1331                                                         << dsBorder.nGap << "] " 
1332                                                         << dsBorder.nPhase << " d\n";
1333
1334                                                 for (int32_t i=1;i<nMaxLen;i++)                                 
1335                                                 {
1336                                                         sLines << rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
1337                                                                 << rcClient.bottom << " m\n"
1338                                                                 << rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
1339                                                                 << rcClient.top << " l S\n";    
1340                                                 }
1341
1342                                                 sLines << "Q\n";
1343                                         }
1344                                 }
1345                                 break;
1346                         }
1347                 }
1348
1349                 IFX_Edit::DelEdit(pEdit);
1350         }
1351
1352         CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + sLines.GetByteString() + sBody.GetByteString();
1353         WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1354 }
1355
1356 CPDF_Rect CPDFSDK_Widget::GetClientRect() const
1357 {
1358         CPDF_Rect rcWindow = GetRotatedRect();
1359         FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1360         switch (GetBorderStyle())
1361         {
1362         case BBS_BEVELED:
1363         case BBS_INSET:
1364                 fBorderWidth *= 2.0f;
1365                 break;
1366         }
1367
1368         return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
1369 }
1370
1371 CPDF_Rect CPDFSDK_Widget::GetRotatedRect() const
1372 {
1373         CPDF_Rect rectAnnot = GetRect();
1374         FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
1375         FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
1376
1377         CPDF_FormControl* pControl = GetFormControl();
1378         ASSERT(pControl != NULL);
1379
1380         CPDF_Rect rcPDFWindow;
1381         switch(abs(pControl->GetRotation() % 360))
1382         {
1383                 case 0:
1384                 case 180:
1385                 default:
1386                         rcPDFWindow = CPDF_Rect(0, 0, fWidth, fHeight); 
1387                         break;
1388                 case 90:
1389                 case 270:
1390                         rcPDFWindow = CPDF_Rect(0, 0, fHeight, fWidth);
1391                         break;
1392         }
1393
1394         return rcPDFWindow;
1395 }
1396
1397 CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const
1398 {
1399         CPWL_Color crBackground = GetFillPWLColor();
1400         if (crBackground.nColorType != COLORTYPE_TRANSPARENT)
1401                 return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
1402         else
1403                 return "";
1404 }
1405
1406 CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const
1407 {
1408         CPDF_Rect rcWindow = GetRotatedRect();
1409         CPWL_Color crBorder = GetBorderPWLColor();
1410         CPWL_Color crBackground = GetFillPWLColor();
1411         CPWL_Color crLeftTop, crRightBottom;
1412
1413         FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1414         int32_t nBorderStyle = 0;
1415         CPWL_Dash dsBorder(3,0,0);
1416
1417         switch (GetBorderStyle())
1418         {
1419         case BBS_DASH:
1420                 nBorderStyle = PBS_DASH;
1421                 dsBorder = CPWL_Dash(3, 3, 0);
1422                 break;
1423         case BBS_BEVELED:
1424                 nBorderStyle = PBS_BEVELED;
1425                 fBorderWidth *= 2;
1426                 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1427                 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
1428                 break;
1429         case BBS_INSET:
1430                 nBorderStyle = PBS_INSET;
1431                 fBorderWidth *= 2;
1432                 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1433                 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1434                 break;
1435         case BBS_UNDERLINE:
1436                 nBorderStyle = PBS_UNDERLINED;
1437                 break;
1438         default: 
1439                 nBorderStyle = PBS_SOLID;
1440                 break;
1441         }
1442
1443         return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, 
1444                 crRightBottom, nBorderStyle, dsBorder);
1445 }
1446
1447 CPDF_Matrix CPDFSDK_Widget::GetMatrix() const
1448 {
1449         CPDF_Matrix mt;
1450         CPDF_FormControl* pControl = GetFormControl();
1451         ASSERT(pControl != NULL);
1452
1453         CPDF_Rect rcAnnot = GetRect();
1454         FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left;
1455         FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom;
1456         
1457
1458
1459         switch (abs(pControl->GetRotation() % 360))
1460         {
1461                 case 0:
1462                 default:
1463                         mt = CPDF_Matrix(1, 0, 0, 1, 0, 0);
1464                         break;
1465                 case 90:
1466                         mt = CPDF_Matrix(0, 1, -1, 0, fWidth, 0);
1467                         break;
1468                 case 180:
1469                         mt = CPDF_Matrix(-1, 0, 0, -1, fWidth, fHeight);
1470                         break;
1471                 case 270:
1472                         mt = CPDF_Matrix(0, -1, 1, 0, 0, fHeight);
1473                         break;
1474         }
1475
1476         return mt;
1477 }
1478
1479 CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const
1480 {
1481         CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0);
1482
1483         CPDF_FormControl* pFormCtrl = GetFormControl();
1484         ASSERT(pFormCtrl != NULL);
1485
1486         CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
1487         if (da.HasColor())
1488         {
1489                 int32_t iColorType;
1490                 FX_FLOAT fc[4];
1491                 da.GetColor(iColorType, fc);
1492                 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1493         }
1494
1495         return crText;
1496 }
1497
1498 CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const
1499 {
1500         CPWL_Color crBorder;
1501
1502         CPDF_FormControl* pFormCtrl = GetFormControl();
1503         ASSERT(pFormCtrl != NULL);
1504
1505         int32_t iColorType;
1506         FX_FLOAT fc[4];
1507         pFormCtrl->GetOriginalBorderColor(iColorType, fc);
1508         if (iColorType > 0)
1509                 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1510
1511         return crBorder;
1512 }
1513
1514 CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const
1515 {
1516         CPWL_Color crFill;
1517
1518         CPDF_FormControl* pFormCtrl = GetFormControl();
1519         ASSERT(pFormCtrl != NULL);
1520
1521         int32_t iColorType;
1522         FX_FLOAT fc[4];
1523         pFormCtrl->GetOriginalBackgroundColor(iColorType, fc);
1524         if (iColorType > 0)
1525                 crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1526
1527         return crFill;
1528 }
1529
1530 void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType, CPDF_Stream* pImage)
1531 {
1532         ASSERT(pImage != NULL);
1533
1534         CPDF_Document* pDoc = m_pPageView->GetPDFDocument();//pDocument->GetDocument();
1535         ASSERT(pDoc != NULL);
1536
1537         CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP");
1538         ASSERT(pAPDict != NULL);
1539
1540         CPDF_Stream* pStream = pAPDict->GetStream(sAPType);
1541         ASSERT(pStream != NULL);
1542
1543         CPDF_Dictionary* pStreamDict = pStream->GetDict();
1544         ASSERT(pStreamDict != NULL);
1545
1546         CFX_ByteString sImageAlias = "IMG";
1547
1548         if (CPDF_Dictionary* pImageDict = pImage->GetDict())
1549         {
1550                 sImageAlias = pImageDict->GetString("Name");
1551                 if (sImageAlias.IsEmpty())
1552                         sImageAlias = "IMG";
1553         }       
1554
1555         CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
1556         if (!pStreamResList)
1557         {
1558                 pStreamResList = new CPDF_Dictionary();
1559                 pStreamDict->SetAt("Resources", pStreamResList);
1560         }
1561
1562         if (pStreamResList)
1563         {
1564                 CPDF_Dictionary* pXObject = new CPDF_Dictionary;
1565                 pXObject->SetAtReference(sImageAlias, pDoc, pImage);
1566                 pStreamResList->SetAt("XObject", pXObject);
1567         }
1568 }
1569
1570 void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType)
1571 {
1572         if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP"))
1573         {
1574                 pAPDict->RemoveAt(sAPType);
1575         }
1576 }
1577
1578 FX_BOOL CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type, PDFSDK_FieldAction& data, CPDFSDK_PageView* pPageView)
1579 {
1580         CPDF_Action action = GetAAction(type);
1581
1582         if (action && action.GetType() != CPDF_Action::Unknown)
1583         {
1584                 CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
1585                 ASSERT(pDocument != NULL);
1586  
1587                 CPDFDoc_Environment* pEnv = pDocument->GetEnv();
1588                 ASSERT(pEnv != NULL);
1589
1590                 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();/*(CPDFSDK_ActionHandler*)pApp->GetActionHandler();*/
1591                 ASSERT(pActionHandler != NULL);
1592  
1593                 return pActionHandler->DoAction_Field(action, type, pDocument, GetFormField(), data);
1594         }
1595
1596         return FALSE;
1597 }
1598
1599 CPDF_Action     CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT)
1600 {
1601         switch (eAAT)
1602         {
1603         case CPDF_AAction::CursorEnter:
1604         case CPDF_AAction::CursorExit:
1605         case CPDF_AAction::ButtonDown:
1606         case CPDF_AAction::ButtonUp:
1607         case CPDF_AAction::GetFocus:
1608         case CPDF_AAction::LoseFocus:
1609         case CPDF_AAction::PageOpen:
1610         case CPDF_AAction::PageClose:
1611         case CPDF_AAction::PageVisible:
1612         case CPDF_AAction::PageInvisible:
1613                 return CPDFSDK_Annot::GetAAction(eAAT);
1614
1615         case CPDF_AAction::KeyStroke:
1616         case CPDF_AAction::Format:
1617         case CPDF_AAction::Validate:
1618         case CPDF_AAction::Calculate:
1619                 {
1620                         CPDF_FormField* pField = this->GetFormField();
1621                         if (CPDF_AAction aa = pField->GetAdditionalAction())
1622                                 return aa.GetAction(eAAT);
1623
1624                         return CPDFSDK_Annot::GetAAction(eAAT);
1625                 }
1626         default:
1627                 break;
1628         }
1629
1630         return CPDF_Action();
1631 }
1632
1633
1634 CFX_WideString CPDFSDK_Widget::GetAlternateName() const
1635 {
1636         CPDF_FormField* pFormField = GetFormField();
1637         ASSERT(pFormField != NULL);
1638
1639         return pFormField->GetAlternateName();
1640 }
1641
1642 int32_t CPDFSDK_Widget::GetAppearanceAge() const
1643 {
1644         return m_nAppAge;
1645 }
1646
1647 int32_t CPDFSDK_Widget::GetValueAge() const
1648 {
1649         return m_nValueAge;
1650 }
1651
1652
1653 FX_BOOL CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY)
1654 {
1655         CPDF_Annot* pAnnot = GetPDFAnnot();
1656         CFX_FloatRect annotRect;
1657         pAnnot->GetRect(annotRect);
1658         if(annotRect.Contains(pageX, pageY))
1659         {
1660                 if (!IsVisible()) return FALSE;
1661                 
1662                 int nFieldFlags = GetFieldFlags();
1663                 if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY) 
1664                         return FALSE;
1665                 
1666                 return TRUE;
1667         }
1668         return FALSE;
1669 }
1670
1671 CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
1672         :m_pDocument(pDocument),
1673         m_pInterForm(NULL),
1674         m_bCalculate(TRUE),
1675         m_bBusy(FALSE)
1676 {
1677         ASSERT(m_pDocument != NULL);
1678         m_pInterForm = new CPDF_InterForm(m_pDocument->GetDocument(), FALSE);
1679         ASSERT(m_pInterForm != NULL);
1680         m_pInterForm->SetFormNotify(this);
1681
1682         for(int i=0; i<6; i++)
1683                 m_bNeedHightlight[i] = FALSE;
1684         m_iHighlightAlpha = 0;
1685 }
1686
1687 CPDFSDK_InterForm::~CPDFSDK_InterForm()
1688 {
1689         ASSERT(m_pInterForm != NULL);
1690         delete m_pInterForm;
1691         m_pInterForm = NULL;
1692
1693         m_Map.RemoveAll();
1694 }
1695
1696 void CPDFSDK_InterForm::Destroy()
1697 {
1698         delete this;
1699 }
1700
1701 CPDF_InterForm* CPDFSDK_InterForm::GetInterForm()
1702 {
1703         return m_pInterForm;
1704 }
1705
1706 CPDFSDK_Document* CPDFSDK_InterForm::GetDocument()
1707 {
1708         return m_pDocument;
1709 }
1710
1711 FX_BOOL CPDFSDK_InterForm::HighlightWidgets()
1712 {
1713         return FALSE;
1714 }
1715
1716 CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget, FX_BOOL bNext) const
1717 {
1718     nonstd::unique_ptr<CBA_AnnotIterator> pIterator(
1719         new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", ""));
1720
1721     if (bNext) {
1722         return (CPDFSDK_Widget*)pIterator->GetNextAnnot(pWidget);
1723     }
1724     return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget);
1725 }
1726
1727 CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl) const
1728 {
1729         if(!pControl || !m_pInterForm) return NULL;
1730         
1731         CPDFSDK_Widget* pWidget = NULL;
1732         m_Map.Lookup(pControl, pWidget);
1733
1734         if (pWidget) return pWidget;
1735
1736         CPDF_Dictionary* pControlDict = pControl->GetWidget();
1737         ASSERT(pControlDict != NULL);
1738
1739         ASSERT(m_pDocument != NULL);
1740         CPDF_Document* pDocument = m_pDocument->GetDocument();
1741
1742         CPDFSDK_PageView* pPage = NULL;
1743
1744         if (CPDF_Dictionary* pPageDict = pControlDict->GetDict("P"))
1745         {
1746                 int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
1747                 if (nPageIndex >= 0)
1748                 {
1749                         pPage = m_pDocument->GetPageView(nPageIndex);
1750                 }
1751         }
1752
1753         if (!pPage) 
1754         {
1755                 int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
1756                 if (nPageIndex >= 0)
1757                 {
1758                         pPage = m_pDocument->GetPageView(nPageIndex);
1759                 }
1760         }
1761
1762         if (pPage)
1763                 return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict);
1764
1765         return NULL;
1766 }
1767
1768 void CPDFSDK_InterForm::GetWidgets(const CFX_WideString& sFieldName, CFX_PtrArray& widgets)
1769 {
1770         ASSERT(m_pInterForm != NULL);
1771
1772         for (int i=0,sz=m_pInterForm->CountFields(sFieldName); i<sz; i++)
1773         {
1774                 CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName);
1775                 ASSERT(pFormField != NULL);
1776
1777                 GetWidgets(pFormField, widgets);        
1778         }
1779 }
1780
1781 void CPDFSDK_InterForm::GetWidgets(CPDF_FormField* pField, CFX_PtrArray& widgets)
1782 {
1783         ASSERT(pField != NULL);
1784
1785         for (int i=0,isz=pField->CountControls(); i<isz; i++)
1786         {
1787                 CPDF_FormControl* pFormCtrl = pField->GetControl(i);
1788                 ASSERT(pFormCtrl != NULL);
1789
1790                 CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl);
1791
1792                 if (pWidget)
1793                         widgets.Add(pWidget);
1794         }
1795 }
1796
1797 int CPDFSDK_InterForm::GetPageIndexByAnnotDict(CPDF_Document* pDocument, CPDF_Dictionary* pAnnotDict) const
1798 {
1799         ASSERT(pDocument != NULL);
1800         ASSERT(pAnnotDict != NULL);
1801
1802         for (int i=0,sz=pDocument->GetPageCount(); i<sz; i++)
1803         {
1804                 if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i))
1805                 {                       
1806                         if (CPDF_Array* pAnnots = pPageDict->GetArray("Annots"))
1807                         {
1808                                 for (int j=0,jsz=pAnnots->GetCount(); j<jsz; j++)
1809                                 {
1810                                         CPDF_Object* pDict = pAnnots->GetElementValue(j);
1811                                         if (pAnnotDict == pDict)
1812                                         {
1813                                                 return i;
1814                                         }
1815                                 }
1816                         }
1817                 }
1818         }
1819
1820         return -1;
1821 }
1822
1823 void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl, CPDFSDK_Widget* pWidget)
1824 {
1825         m_Map.SetAt(pControl, pWidget);
1826 }
1827
1828 void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl)
1829 {
1830         m_Map.RemoveKey(pControl);
1831 }
1832
1833 void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled)
1834 {
1835         m_bCalculate = bEnabled;
1836 }
1837
1838 FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const
1839 {
1840         return m_bCalculate;
1841 }
1842
1843 #ifdef _WIN32
1844 CPDF_Stream* CPDFSDK_InterForm::LoadImageFromFile(const CFX_WideString& sFile)
1845 {
1846         ASSERT(m_pDocument != NULL);
1847         CPDF_Document* pDocument = m_pDocument->GetDocument();
1848         ASSERT(pDocument != NULL);
1849
1850         CPDF_Stream* pRetStream = NULL;
1851
1852         if (CFX_DIBitmap* pBmp = CFX_WindowsDIB::LoadFromFile(sFile.c_str()))
1853         {
1854                 int nWidth = pBmp->GetWidth();
1855                 int nHeight = pBmp->GetHeight();
1856
1857                 CPDF_Image Image(pDocument);
1858                 Image.SetImage(pBmp, FALSE);
1859                 CPDF_Stream* pImageStream = Image.GetStream();
1860                 if (pImageStream)
1861                 {
1862                         if (pImageStream->GetObjNum() == 0)
1863                                 pDocument->AddIndirectObject(pImageStream);
1864
1865                         CPDF_Dictionary* pStreamDict = new CPDF_Dictionary();
1866                         pStreamDict->SetAtName("Subtype", "Form");
1867                         pStreamDict->SetAtName("Name", "IMG");
1868                         CPDF_Array* pMatrix = new CPDF_Array();
1869                         pStreamDict->SetAt("Matrix", pMatrix);
1870                         pMatrix->AddInteger(1);
1871                         pMatrix->AddInteger(0);
1872                         pMatrix->AddInteger(0);
1873                         pMatrix->AddInteger(1);
1874                         pMatrix->AddInteger(-nWidth / 2);
1875                         pMatrix->AddInteger(-nHeight / 2);
1876                         CPDF_Dictionary* pResource = new CPDF_Dictionary();
1877                         pStreamDict->SetAt("Resources", pResource);
1878                         CPDF_Dictionary* pXObject = new CPDF_Dictionary();
1879                         pResource->SetAt("XObject", pXObject);
1880                         pXObject->SetAtReference("Img", pDocument, pImageStream);
1881                         CPDF_Array* pProcSet = new CPDF_Array();
1882                         pResource->SetAt("ProcSet", pProcSet);
1883                         pProcSet->AddName("PDF");
1884                         pProcSet->AddName("ImageC");
1885                         pStreamDict->SetAtName("Type", "XObject");
1886                         CPDF_Array* pBBox = new CPDF_Array();
1887                         pStreamDict->SetAt("BBox", pBBox);
1888                         pBBox->AddInteger(0);
1889                         pBBox->AddInteger(0);
1890                         pBBox->AddInteger(nWidth);
1891                         pBBox->AddInteger(nHeight);
1892                         pStreamDict->SetAtInteger("FormType", 1);
1893
1894                         pRetStream = new CPDF_Stream(NULL, 0, NULL);
1895                         CFX_ByteString csStream;
1896                         csStream.Format("q\n%d 0 0 %d 0 0 cm\n/Img Do\nQ", nWidth, nHeight);
1897                         pRetStream->InitStream((uint8_t*)csStream.c_str(), csStream.GetLength(), pStreamDict);
1898                         pDocument->AddIndirectObject(pRetStream);
1899                 }
1900
1901                 delete pBmp;
1902         }
1903
1904         return pRetStream;
1905 }
1906 #endif
1907
1908 void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField)
1909 {
1910         ASSERT(m_pDocument != NULL);
1911         CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
1912         ASSERT(pEnv);
1913         if(!pEnv->IsJSInitiated())
1914                 return;
1915
1916         if (m_bBusy) return;
1917
1918         m_bBusy = TRUE;
1919
1920         if (this->IsCalculateEnabled())
1921         {
1922                 IFXJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
1923                 ASSERT(pRuntime != NULL);
1924
1925                 pRuntime->SetReaderDocument(m_pDocument);
1926
1927                 int nSize = m_pInterForm->CountFieldsInCalculationOrder();
1928                 for (int i=0; i<nSize; i++)
1929                 {
1930                         if(CPDF_FormField* pField = m_pInterForm->GetFieldInCalculationOrder(i))
1931                         {
1932 //                      ASSERT(pField != NULL);
1933                                 int nType = pField->GetFieldType();
1934                                 if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD)
1935                                 {
1936                                         CPDF_AAction aAction = pField->GetAdditionalAction();
1937                                         if (aAction && aAction.ActionExist(CPDF_AAction::Calculate))
1938                                         {
1939                                                 CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
1940                                                 if (action)
1941                                                 {
1942                                                         CFX_WideString csJS = action.GetJavaScript();
1943                                                         if (!csJS.IsEmpty())
1944                                                         {
1945                                                                 IFXJS_Context* pContext = pRuntime->NewContext();
1946                                                                 ASSERT(pContext != NULL);
1947                                                                 
1948                                                                 CFX_WideString sOldValue = pField->GetValue();
1949                                                                 CFX_WideString sValue = sOldValue;
1950                                                                 FX_BOOL bRC = TRUE;
1951                                                                 pContext->OnField_Calculate(pFormField, pField, sValue, bRC);
1952                                                                 
1953                                                                 CFX_WideString sInfo;
1954                                                                 FX_BOOL bRet = pContext->RunScript(csJS, sInfo);
1955                                                                 pRuntime->ReleaseContext(pContext);
1956                                                                 
1957                                                                 if (bRet)
1958                                                                 {
1959                                                                         if (bRC)
1960                                                                         {
1961                                                                                 if (sValue.Compare(sOldValue) != 0)
1962                                                                                         pField->SetValue(sValue, TRUE);
1963                                                                         }
1964                                                                 }
1965                                                         }
1966                                                 }
1967                                         }
1968                                 }
1969                         }
1970                 }
1971
1972                 
1973         }
1974
1975         m_bBusy = FALSE;
1976 }
1977
1978 CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField, FX_BOOL& bFormated)
1979 {
1980         ASSERT(m_pDocument != NULL);
1981         ASSERT(pFormField != NULL);
1982
1983         CFX_WideString sValue = pFormField->GetValue();
1984         CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
1985         ASSERT(pEnv);
1986         if(!pEnv->IsJSInitiated())
1987         {
1988                 bFormated = FALSE;
1989                 return sValue;
1990         } 
1991
1992         IFXJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
1993         ASSERT(pRuntime != NULL);
1994         
1995         pRuntime->SetReaderDocument(m_pDocument);
1996
1997         if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX)
1998         {
1999                 if (pFormField->CountSelectedItems() > 0)
2000                 {
2001                         int index = pFormField->GetSelectedIndex(0);
2002                         if (index >= 0)
2003                                 sValue = pFormField->GetOptionLabel(index);
2004                 }
2005         }
2006
2007         bFormated = FALSE;
2008
2009         CPDF_AAction aAction = pFormField->GetAdditionalAction();
2010         if (aAction != NULL && aAction.ActionExist(CPDF_AAction::Format)) 
2011         {
2012                 CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
2013                 if (action)
2014                 {                       
2015                         CFX_WideString script = action.GetJavaScript();
2016                         if (!script.IsEmpty())
2017                         {
2018                                 CFX_WideString Value = sValue;
2019
2020                                 IFXJS_Context* pContext = pRuntime->NewContext();
2021                                 ASSERT(pContext != NULL);
2022
2023                                 pContext->OnField_Format(pFormField, Value, TRUE);
2024                         
2025                                 CFX_WideString sInfo;
2026                                 FX_BOOL bRet = pContext->RunScript(script, sInfo);
2027                                 pRuntime->ReleaseContext(pContext);
2028
2029                                 if (bRet)
2030                                 {
2031                                         sValue = Value;
2032                                         bFormated = TRUE;
2033                                 }
2034                         }
2035                 }
2036         }
2037
2038         return sValue;
2039 }
2040
2041 void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField, const FX_WCHAR* sValue, FX_BOOL bValueChanged)
2042 {
2043         ASSERT(pFormField != NULL);
2044
2045         for (int i=0,sz=pFormField->CountControls(); i<sz; i++)
2046         {
2047                 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
2048                 ASSERT(pFormCtrl != NULL);
2049
2050                 ASSERT(m_pInterForm != NULL);
2051                 if(CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
2052                         pWidget->ResetAppearance(sValue, bValueChanged);
2053         }
2054 }
2055
2056 void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField)
2057 {
2058         ASSERT(pFormField != NULL);
2059
2060         for (int i=0,sz=pFormField->CountControls(); i<sz; i++)
2061         {
2062                 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
2063                 ASSERT(pFormCtrl != NULL);
2064
2065                 if(CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
2066                 {
2067                         CPDFDoc_Environment * pEnv = m_pDocument->GetEnv();
2068                         CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
2069                         
2070                         CPDF_Page * pPage = pWidget->GetPDFPage();
2071                         CPDFSDK_PageView * pPageView = m_pDocument->GetPageView(pPage,FALSE);
2072
2073                         FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget);
2074
2075                         pEnv->FFI_Invalidate(pPage,rcBBox.left, rcBBox.top, rcBBox.right, rcBBox.bottom);
2076                 }
2077         }
2078 }
2079
2080 void CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField, CFX_WideString& csValue, FX_BOOL& bRC)
2081 {
2082         ASSERT(pFormField != NULL);
2083
2084         CPDF_AAction aAction = pFormField->GetAdditionalAction();
2085         if (aAction != NULL && aAction.ActionExist(CPDF_AAction::KeyStroke)) 
2086         {
2087                 CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
2088                 if (action)
2089                 {                        
2090                         ASSERT(m_pDocument != NULL);
2091                         CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2092                         ASSERT(pEnv != NULL);
2093
2094                         CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
2095                         ASSERT(pActionHandler != NULL);
2096         
2097                         PDFSDK_FieldAction fa;
2098                         fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
2099                         fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
2100                         fa.sValue = csValue;
2101
2102                         pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke, 
2103                                 m_pDocument, pFormField, fa);
2104                         bRC = fa.bRC;
2105                 }
2106         }
2107 }
2108
2109 void CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField, CFX_WideString& csValue, FX_BOOL& bRC)
2110 {
2111         ASSERT(pFormField != NULL);
2112
2113         CPDF_AAction aAction = pFormField->GetAdditionalAction();
2114         if (aAction != NULL && aAction.ActionExist(CPDF_AAction::Validate)) 
2115         {
2116                 CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
2117                 if (action)
2118                 {               
2119                         ASSERT(m_pDocument != NULL);
2120                         CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2121                         ASSERT(pEnv != NULL);
2122                         
2123                         CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
2124                         ASSERT(pActionHandler != NULL);
2125
2126                         PDFSDK_FieldAction fa;
2127                         fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
2128                         fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
2129                         fa.sValue = csValue;
2130
2131                         pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate, m_pDocument, pFormField, fa);
2132                         bRC = fa.bRC;
2133          
2134                 }
2135         }
2136 }
2137
2138 /* ----------------------------- action ----------------------------- */
2139
2140 FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action)
2141 {
2142         ASSERT(action);
2143
2144         CPDF_ActionFields af = action.GetWidgets();
2145         CFX_PtrArray fieldObjects;
2146         af.GetAllFields(fieldObjects);
2147         CFX_PtrArray widgetArray;
2148         CFX_PtrArray fields;
2149         GetFieldFromObjects(fieldObjects, fields);
2150
2151         FX_BOOL bHide = action.GetHideStatus();
2152
2153         FX_BOOL bChanged = FALSE;
2154         
2155         for (int i=0, sz=fields.GetSize(); i<sz; i++)
2156         {
2157                 CPDF_FormField* pField = (CPDF_FormField*)fields[i];
2158                 ASSERT(pField != NULL);
2159
2160         
2161                 for (int j=0,jsz=pField->CountControls(); j<jsz; j++)
2162                 {
2163                         CPDF_FormControl* pControl = pField->GetControl(j);
2164                         ASSERT(pControl != NULL);
2165
2166                         if (CPDFSDK_Widget* pWidget = GetWidget(pControl))
2167                         {
2168                                 int nFlags = pWidget->GetFlags();
2169                                 if (bHide)
2170                                 {
2171                                         nFlags &= (~ANNOTFLAG_INVISIBLE);
2172                                         nFlags &= (~ANNOTFLAG_NOVIEW);
2173                                         nFlags |= (ANNOTFLAG_HIDDEN);
2174                                 }
2175                                 else
2176                                 {
2177                                         nFlags &= (~ANNOTFLAG_INVISIBLE);
2178                                         nFlags &= (~ANNOTFLAG_HIDDEN);
2179                                         nFlags &= (~ANNOTFLAG_NOVIEW);
2180                                 }
2181                                 pWidget->SetFlags(nFlags);
2182
2183                                 CPDFSDK_PageView* pPageView = pWidget->GetPageView();
2184                                 ASSERT(pPageView != NULL);
2185  
2186                                 pPageView->UpdateView(pWidget);
2187
2188                                 bChanged = TRUE;
2189                         }
2190                 }
2191         }
2192
2193         return bChanged;
2194 }
2195
2196 FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action)
2197 {
2198         ASSERT(action);
2199         ASSERT(m_pInterForm != NULL);
2200
2201         CFX_WideString sDestination = action.GetFilePath();
2202         if (sDestination.IsEmpty()) return FALSE;
2203
2204         CPDF_Dictionary* pActionDict = action.GetDict();
2205         if (pActionDict->KeyExist("Fields"))
2206         {
2207                 CPDF_ActionFields af = action.GetWidgets();
2208                 FX_DWORD dwFlags = action.GetFlags();
2209                 
2210                 CFX_PtrArray fieldObjects;
2211                 af.GetAllFields(fieldObjects);
2212                 CFX_PtrArray fields;
2213                 GetFieldFromObjects(fieldObjects, fields);
2214                 
2215                 if (fields.GetSize() != 0)
2216                 {
2217                         FX_BOOL bIncludeOrExclude = !(dwFlags & 0x01);
2218                         if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude))
2219                         {
2220                                 return FALSE;
2221                         }
2222                         return SubmitFields(sDestination, fields, bIncludeOrExclude, FALSE);
2223                 }
2224                 else
2225                 {
2226                         if ( m_pInterForm->CheckRequiredFields())
2227                         {
2228                                 return FALSE;
2229                         }
2230
2231                         return SubmitForm(sDestination, FALSE);
2232                 }
2233         }
2234         else
2235         {
2236                 if ( m_pInterForm->CheckRequiredFields())
2237                 {
2238                         return FALSE;
2239                 }
2240
2241                 return SubmitForm(sDestination, FALSE);
2242         }
2243 }
2244
2245 FX_BOOL CPDFSDK_InterForm::SubmitFields(const CFX_WideString& csDestination, const CFX_PtrArray& fields,
2246                                                                         FX_BOOL bIncludeOrExclude, FX_BOOL bUrlEncoded)
2247 {
2248         CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2249         ASSERT(pEnv != NULL);
2250
2251         CFX_ByteTextBuf textBuf;
2252         ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);
2253
2254         uint8_t* pBuffer = textBuf.GetBuffer();
2255         FX_STRSIZE nBufSize = textBuf.GetLength();
2256         
2257         if (bUrlEncoded)
2258         {
2259                 if(!FDFToURLEncodedData(pBuffer, nBufSize))
2260                         return FALSE;
2261         }
2262
2263         pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
2264         
2265         return TRUE;
2266 }
2267
2268 void CPDFSDK_InterForm::DoFDFBuffer(CFX_ByteString sBuffer)
2269 {
2270         ASSERT(m_pDocument != NULL);
2271
2272         if (CFDF_Document *pFDFDocument = CFDF_Document::ParseMemory((const unsigned char *)sBuffer.GetBuffer(sBuffer.GetLength()), sBuffer.GetLength()))
2273         {                                               
2274                 CPDF_Dictionary* pRootDic = pFDFDocument->GetRoot();
2275                 if(pRootDic)
2276                 {
2277                         CPDF_Dictionary * pFDFDict=pRootDic->GetDict("FDF");
2278                         if(pFDFDict)
2279                         {               
2280                                 CPDF_Dictionary * pJSDict = pFDFDict->GetDict("JavaScript");
2281                                 if(pJSDict)
2282                                 {
2283                                         CFX_WideString csJS;
2284                                 
2285                                         CPDF_Object* pJS = pJSDict->GetElementValue("Before");
2286                                         if (pJS != NULL)
2287                                         {
2288                                                 int iType = pJS->GetType();
2289                                                 if (iType == PDFOBJ_STRING)
2290                                                         csJS = pJSDict->GetUnicodeText("Before");
2291                                                 else if (iType == PDFOBJ_STREAM)
2292                                                         csJS = pJS->GetUnicodeText();
2293                                         }
2294                                         
2295                                 }
2296                         }
2297                 }
2298                 delete pFDFDocument;
2299         }
2300
2301         sBuffer.ReleaseBuffer();
2302 }
2303
2304 FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile, CFX_WideString csTxtFile)
2305 {
2306         return TRUE;
2307 }
2308
2309 FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf, FX_STRSIZE& nBufSize)
2310 {
2311         CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize);
2312         if (pFDF)
2313         {
2314                 CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF");
2315                 if (pMainDict == NULL) return FALSE;
2316                 
2317                 // Get fields
2318                 CPDF_Array* pFields = pMainDict->GetArray("Fields");
2319                 if (pFields == NULL) return FALSE;
2320                 
2321                 CFX_ByteTextBuf fdfEncodedData;
2322
2323                 for (FX_DWORD i = 0; i < pFields->GetCount(); i ++) 
2324                 {
2325                         CPDF_Dictionary* pField = pFields->GetDict(i);
2326                         if (pField == NULL) continue;
2327                         CFX_WideString name;
2328                         name = pField->GetUnicodeText("T");
2329                         CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
2330                         CFX_ByteString csBValue = pField->GetString("V");
2331                         CFX_WideString csWValue = PDF_DecodeText(csBValue);
2332                         CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);
2333
2334                         fdfEncodedData = fdfEncodedData<<name_b.GetBuffer(name_b.GetLength());
2335                         name_b.ReleaseBuffer();
2336                         fdfEncodedData = fdfEncodedData<<"=";
2337                         fdfEncodedData = fdfEncodedData<<csValue_b.GetBuffer(csValue_b.GetLength());
2338                         csValue_b.ReleaseBuffer();
2339                         if(i != pFields->GetCount()-1)
2340                                 fdfEncodedData = fdfEncodedData<<"&";
2341                 }
2342
2343                 nBufSize = fdfEncodedData.GetLength();
2344                 pBuf = FX_Alloc(uint8_t, nBufSize);
2345                 FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize);
2346         }
2347         return TRUE;
2348 }
2349
2350 FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(const CFX_PtrArray& fields,FX_BOOL bIncludeOrExclude, CFX_ByteTextBuf& textBuf)
2351 {
2352         ASSERT(m_pDocument != NULL);
2353         ASSERT(m_pInterForm != NULL);
2354         
2355         CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath(),(CFX_PtrArray&)fields, bIncludeOrExclude);
2356         if (!pFDF) return FALSE;
2357         FX_BOOL bRet = pFDF->WriteBuf(textBuf); // = FALSE;//
2358         delete pFDF;
2359         
2360         return bRet;
2361 }
2362
2363 CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(const CFX_WideString& sFileExt)
2364 {
2365         CFX_WideString sFileName;
2366         return L"";
2367 }
2368
2369 FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination, FX_BOOL bUrlEncoded)
2370 {
2371         if (sDestination.IsEmpty()) return FALSE;
2372
2373         CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2374         ASSERT(pEnv != NULL);
2375
2376         if(NULL == m_pDocument) return FALSE;
2377         CFX_WideString wsPDFFilePath = m_pDocument->GetPath();
2378         
2379         if(NULL == m_pInterForm) return FALSE;
2380         CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath);
2381         if (NULL == pFDFDoc) return FALSE;
2382
2383         CFX_ByteTextBuf FdfBuffer;
2384         FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer);
2385         delete pFDFDoc;
2386         if (!bRet) return FALSE;
2387
2388         uint8_t* pBuffer = FdfBuffer.GetBuffer();
2389         FX_STRSIZE nBufSize = FdfBuffer.GetLength();
2390         
2391         if (bUrlEncoded)
2392         {
2393                 if(!FDFToURLEncodedData(pBuffer, nBufSize))
2394                         return FALSE;
2395         }
2396
2397         pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());
2398         
2399         if (bUrlEncoded && pBuffer)
2400         {
2401                 FX_Free(pBuffer);
2402                 pBuffer = NULL; 
2403         }
2404
2405         return TRUE;
2406 }
2407
2408 FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf)
2409 {
2410
2411         ASSERT(m_pInterForm != NULL);
2412         ASSERT(m_pDocument != NULL);
2413         
2414         CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath());
2415         if (!pFDF) return FALSE;
2416         
2417         FX_BOOL bRet = pFDF->WriteBuf(textBuf);
2418         delete pFDF;
2419         
2420         return bRet;
2421 }
2422
2423
2424 FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action)
2425 {
2426         ASSERT(action);
2427
2428         CPDF_Dictionary* pActionDict = action.GetDict();
2429         if (pActionDict->KeyExist("Fields"))
2430         {
2431                 CPDF_ActionFields af = action.GetWidgets();
2432                 FX_DWORD dwFlags = action.GetFlags();
2433
2434                 CFX_PtrArray fieldObjects;
2435                 af.GetAllFields(fieldObjects);
2436                 CFX_PtrArray fields;
2437                 GetFieldFromObjects(fieldObjects, fields);
2438                 return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), TRUE);
2439         }
2440
2441         return m_pInterForm->ResetForm(TRUE);
2442 }
2443
2444 FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action)
2445 {
2446         return FALSE;
2447 }
2448
2449 void CPDFSDK_InterForm::GetFieldFromObjects(const CFX_PtrArray& objects, CFX_PtrArray& fields)
2450 {
2451         ASSERT(m_pInterForm != NULL);
2452
2453         int iCount = objects.GetSize();
2454         for (int i = 0; i < iCount; i ++)
2455         {
2456                 CPDF_Object* pObject = (CPDF_Object*)objects[i];
2457                 if (pObject == NULL) continue;
2458                 
2459                 int iType = pObject->GetType();
2460                 if (iType == PDFOBJ_STRING)
2461                 {
2462                         CFX_WideString csName = pObject->GetUnicodeText();
2463                         CPDF_FormField* pField = m_pInterForm->GetField(0, csName);
2464                         if (pField != NULL)
2465                                 fields.Add(pField);
2466                 }
2467                 else if (iType == PDFOBJ_DICTIONARY)
2468                 {
2469                         if (m_pInterForm->IsValidFormField(pObject))
2470                                 fields.Add(pObject);
2471                 }
2472         }
2473 }
2474
2475 /* ----------------------------- CPDF_FormNotify ----------------------------- */
2476
2477 int     CPDFSDK_InterForm::BeforeValueChange(const CPDF_FormField* pField, CFX_WideString& csValue)
2478 {
2479         ASSERT(pField != NULL);
2480
2481         CPDF_FormField* pFormField = (CPDF_FormField*)pField;
2482
2483         int nType = pFormField->GetFieldType();
2484         if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD)
2485         {
2486                 FX_BOOL bRC = TRUE;
2487                 OnKeyStrokeCommit(pFormField, csValue, bRC);
2488                 if (bRC) 
2489                 {
2490                         OnValidate(pFormField, csValue, bRC);
2491                         if (bRC)
2492                                 return 1;
2493                         else
2494                                 return -1;
2495                 }
2496                 else
2497                         return -1;
2498         }
2499         else
2500                 return 0;
2501 }
2502
2503 int     CPDFSDK_InterForm::AfterValueChange(const CPDF_FormField* pField)
2504 {
2505         ASSERT(pField != NULL);
2506
2507         CPDF_FormField* pFormField = (CPDF_FormField*)pField;
2508         int nType = pFormField->GetFieldType();
2509
2510         if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD)
2511         {
2512                 this->OnCalculate(pFormField);
2513                 FX_BOOL bFormated = FALSE;
2514                 CFX_WideString sValue = this->OnFormat(pFormField, bFormated);
2515                 if (bFormated)
2516                         this->ResetFieldAppearance(pFormField, sValue.c_str(), TRUE);
2517                 else
2518                         this->ResetFieldAppearance(pFormField, NULL, TRUE);
2519                 this->UpdateField(pFormField);
2520         }
2521
2522         return 0;
2523 }
2524
2525 int     CPDFSDK_InterForm::BeforeSelectionChange(const CPDF_FormField* pField, CFX_WideString& csValue)
2526 {
2527         ASSERT(pField != NULL);
2528
2529         CPDF_FormField* pFormField = (CPDF_FormField*)pField;
2530
2531         int nType = pFormField->GetFieldType();
2532         if (nType == FIELDTYPE_LISTBOX)
2533         {
2534                 FX_BOOL bRC = TRUE;
2535                 OnKeyStrokeCommit(pFormField, csValue, bRC);
2536                 if (bRC) 
2537                 {
2538                         OnValidate(pFormField, csValue, bRC);
2539                         if (bRC)
2540                                 return 1;
2541                         else
2542                                 return -1;
2543                 }
2544                 else
2545                         return -1;
2546         }
2547         else
2548                 return 0;
2549 }
2550
2551 int     CPDFSDK_InterForm::AfterSelectionChange(const CPDF_FormField* pField)
2552 {
2553         ASSERT(pField != NULL);
2554
2555         CPDF_FormField* pFormField = (CPDF_FormField*)pField;
2556         int nType = pFormField->GetFieldType();
2557
2558         if (nType == FIELDTYPE_LISTBOX)
2559         {
2560                 this->OnCalculate(pFormField);
2561                 this->ResetFieldAppearance(pFormField, NULL, TRUE);
2562                 this->UpdateField(pFormField);
2563         }
2564
2565         return 0;
2566 }
2567
2568 int     CPDFSDK_InterForm::AfterCheckedStatusChange(const CPDF_FormField* pField, const CFX_ByteArray& statusArray)
2569 {
2570         ASSERT(pField != NULL);
2571
2572         CPDF_FormField* pFormField = (CPDF_FormField*)pField;
2573         int nType = pFormField->GetFieldType();
2574
2575         if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON)
2576         {
2577                 this->OnCalculate(pFormField);
2578                 //this->ResetFieldAppearance(pFormField, NULL);
2579                 this->UpdateField(pFormField);
2580         }
2581
2582         return 0;
2583 }
2584
2585 int     CPDFSDK_InterForm::BeforeFormReset(const CPDF_InterForm* pForm)
2586 {
2587         return 0;
2588 }
2589
2590 int     CPDFSDK_InterForm::AfterFormReset(const CPDF_InterForm* pForm)
2591 {
2592         this->OnCalculate(NULL);
2593
2594         return 0;
2595 }
2596
2597 int     CPDFSDK_InterForm::BeforeFormImportData(const CPDF_InterForm* pForm)
2598 {
2599         return 0;
2600 }
2601
2602 int     CPDFSDK_InterForm::AfterFormImportData(const CPDF_InterForm* pForm)
2603 {
2604         this->OnCalculate(NULL);
2605
2606         return 0;
2607 }
2608
2609 FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType)
2610 {
2611         if(nFieldType <1 || nFieldType > 6)
2612                 return FALSE;
2613         return m_bNeedHightlight[nFieldType-1];
2614 }
2615
2616 void CPDFSDK_InterForm::RemoveAllHighLight()
2617 {
2618         memset((void*)m_bNeedHightlight, 0, 6*sizeof(FX_BOOL));
2619 }
2620 void   CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType)
2621 {
2622         if(nFieldType <0 || nFieldType > 6) return;
2623         switch(nFieldType)
2624         {
2625         case 0:
2626                 {
2627                         for(int i=0; i<6; i++)
2628                         {
2629                                 m_aHighlightColor[i] = clr;
2630                                 m_bNeedHightlight[i] = TRUE;
2631                         }
2632                         break;
2633                 }
2634         default:
2635                 {
2636                         m_aHighlightColor[nFieldType-1] = clr;
2637                         m_bNeedHightlight[nFieldType-1] = TRUE;
2638                         break;
2639                 }
2640         }
2641         
2642 }
2643
2644 FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType)
2645 {
2646         if(nFieldType <0 || nFieldType >6) return FXSYS_RGB(255,255,255);
2647         if(nFieldType == 0)
2648                 return m_aHighlightColor[0];
2649         else
2650                 return m_aHighlightColor[nFieldType-1];
2651 }
2652
2653 /* ------------------------- CBA_AnnotIterator ------------------------- */
2654
2655 CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, const CFX_ByteString& sType, const CFX_ByteString& sSubType)
2656         :m_pPageView(pPageView),
2657         m_sType(sType),
2658         m_sSubType(sSubType),
2659         m_nTabs(BAI_STRUCTURE)
2660 {
2661         ASSERT(m_pPageView != NULL);
2662
2663         CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
2664         ASSERT(pPDFPage != NULL);
2665         ASSERT(pPDFPage->m_pFormDict != NULL);
2666
2667         CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetString("Tabs");
2668
2669         if (sTabs == "R")
2670         {
2671                 m_nTabs = BAI_ROW;
2672         }
2673         else if (sTabs == "C")
2674         {
2675                 m_nTabs = BAI_COLUMN;
2676         }
2677         else
2678         {
2679                 m_nTabs = BAI_STRUCTURE;
2680         }
2681
2682         GenerateResults();
2683 }
2684
2685 CBA_AnnotIterator::~CBA_AnnotIterator()
2686 {
2687         m_Annots.RemoveAll();
2688 }
2689
2690 CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot()
2691 {
2692         if (m_Annots.GetSize() > 0)
2693                 return m_Annots[0];
2694         
2695         return NULL;
2696 }
2697
2698 CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot()
2699 {
2700         if (m_Annots.GetSize() > 0)
2701                 return m_Annots[m_Annots.GetSize() - 1];
2702
2703         return NULL;
2704 }
2705
2706 CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot)
2707 {
2708         for (int i=0,sz=m_Annots.GetSize(); i<sz; i++)
2709         {
2710                 if (m_Annots[i] == pAnnot)
2711                 {
2712                         if (i+1 < sz)
2713                                 return m_Annots[i+1];
2714                         else
2715                                 return m_Annots[0];
2716                 }
2717         }
2718
2719         return NULL;
2720 }
2721
2722 CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot)
2723 {
2724         for (int i=0,sz=m_Annots.GetSize(); i<sz; i++)
2725         {
2726                 if (m_Annots[i] == pAnnot)
2727                 {
2728                         if (i-1 >= 0)
2729                                 return m_Annots[i-1];
2730                         else
2731                                 return m_Annots[sz-1];
2732                 }
2733         }
2734
2735         return NULL;
2736 }
2737
2738 int CBA_AnnotIterator::CompareByLeft(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2)
2739 {
2740         ASSERT(p1 != NULL);
2741         ASSERT(p2 != NULL);
2742
2743         CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
2744         CPDF_Rect rcAnnot2 = GetAnnotRect(p2);
2745
2746         if (rcAnnot1.left < rcAnnot2.left)
2747                 return -1;
2748         if (rcAnnot1.left > rcAnnot2.left)
2749                 return 1;
2750         return 0;
2751 }
2752
2753
2754 int CBA_AnnotIterator::CompareByTop(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2)
2755 {
2756         ASSERT(p1 != NULL);
2757         ASSERT(p2 != NULL);
2758
2759         CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
2760         CPDF_Rect rcAnnot2 = GetAnnotRect(p2);
2761
2762         if (rcAnnot1.top < rcAnnot2.top)
2763                 return -1;
2764         if (rcAnnot1.top > rcAnnot2.top)
2765                 return 1;
2766         return 0;
2767 }
2768
2769 void CBA_AnnotIterator::GenerateResults()
2770 {
2771         ASSERT(m_pPageView != NULL);
2772
2773         switch (m_nTabs)
2774         {
2775         case BAI_STRUCTURE:
2776                 {
2777                         for (int i=0,sz=m_pPageView->CountAnnots(); i<sz; i++)
2778                         {
2779                                 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
2780                                 ASSERT(pAnnot != NULL);
2781
2782                                 if (pAnnot->GetType() == m_sType 
2783                                         && pAnnot->GetSubType() == m_sSubType)
2784                                         m_Annots.Add(pAnnot);
2785                         }
2786                 }
2787                 break;
2788         case BAI_ROW:
2789                 {
2790                         CPDFSDK_SortAnnots sa;
2791
2792                         {
2793                                 
2794                                 for (int i=0,sz=m_pPageView->CountAnnots(); i<sz; i++)
2795                                 {
2796                                         CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
2797                                         ASSERT(pAnnot != NULL);
2798
2799                                         if (pAnnot->GetType() == m_sType 
2800                                                 && pAnnot->GetSubType() == m_sSubType)
2801                                                 sa.Add(pAnnot);
2802                                 }
2803                         }
2804
2805                         if (sa.GetSize() > 0)
2806                         {
2807                                 sa.Sort(CBA_AnnotIterator::CompareByLeft);
2808                         }
2809
2810                         while (sa.GetSize() > 0)
2811                         {
2812                                 int nLeftTopIndex = -1;
2813
2814                                 {
2815                                         FX_FLOAT fTop = 0.0f;
2816
2817                                         for (int i=sa.GetSize()-1; i>=0; i--)
2818                                         {
2819                                                 CPDFSDK_Annot* pAnnot = sa.GetAt(i);
2820                                                 ASSERT(pAnnot != NULL);
2821
2822                                                 CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
2823
2824                                                 if (rcAnnot.top > fTop)
2825                                                 {
2826                                                         nLeftTopIndex = i;
2827                                                         fTop = rcAnnot.top;
2828                                                 }
2829                                         }
2830                                 }
2831
2832                                 if (nLeftTopIndex >= 0)
2833                                 {
2834                                         CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
2835                                         ASSERT(pLeftTopAnnot != NULL);
2836
2837                                         CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
2838                                         
2839                                         m_Annots.Add(pLeftTopAnnot);
2840                                         sa.RemoveAt(nLeftTopIndex);
2841
2842                                         CFX_ArrayTemplate<int> aSelect;
2843
2844                                         {
2845                                                 for (int i=0,sz=sa.GetSize(); i<sz; i++)
2846                                                 {
2847                                                         CPDFSDK_Annot* pAnnot = sa.GetAt(i);
2848                                                         ASSERT(pAnnot != NULL);
2849
2850                                                         CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
2851
2852                                                         FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f;
2853
2854                                                         if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top)
2855                                                                 aSelect.Add(i);
2856                                                 }
2857                                         }
2858
2859                                         {
2860                                                 for (int i=0,sz=aSelect.GetSize(); i<sz; i++)
2861                                                 {
2862                                                         m_Annots.Add(sa[aSelect[i]]);
2863                                                 }
2864                                         }
2865
2866                                         {
2867                                                 for (int i=aSelect.GetSize()-1; i>=0; i--)
2868                                                 {
2869                                                         sa.RemoveAt(aSelect[i]);
2870                                                 }
2871                                         }
2872
2873                                         aSelect.RemoveAll();
2874                                 }
2875                         }
2876                         sa.RemoveAll();
2877                 }
2878                 break;
2879         case BAI_COLUMN:
2880                 {
2881                         CPDFSDK_SortAnnots sa;
2882
2883                         {
2884                                 for (int i=0,sz=m_pPageView->CountAnnots(); i<sz; i++)
2885                                 {
2886                                         CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
2887                                         ASSERT(pAnnot != NULL);
2888
2889                                         if (pAnnot->GetType() == m_sType 
2890                                                 && pAnnot->GetSubType() == m_sSubType)
2891                                                 sa.Add(pAnnot);
2892                                 }
2893                         }
2894
2895                         if (sa.GetSize() > 0)
2896                         {
2897                                 sa.Sort(CBA_AnnotIterator::CompareByTop, FALSE);
2898                         }
2899
2900                         while (sa.GetSize() > 0)
2901                         {
2902                                 int nLeftTopIndex = -1;
2903
2904                                 {
2905                                         FX_FLOAT fLeft = -1.0f;
2906
2907                                         for (int i=sa.GetSize()-1; i>=0; i--)
2908                                         {
2909                                                 CPDFSDK_Annot* pAnnot = sa.GetAt(i);
2910                                                 ASSERT(pAnnot != NULL);
2911
2912                                                 CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
2913
2914                                                 if (fLeft < 0)
2915                                                 {
2916                                                         nLeftTopIndex = 0;
2917                                                         fLeft = rcAnnot.left;
2918                                                 }
2919                                                 else if (rcAnnot.left < fLeft)
2920                                                 {
2921                                                         nLeftTopIndex = i;
2922                                                         fLeft = rcAnnot.left;
2923                                                 }
2924                                         }
2925                                 }
2926
2927                                 if (nLeftTopIndex >= 0)
2928                                 {
2929                                         CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
2930                                         ASSERT(pLeftTopAnnot != NULL);
2931
2932                                         CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
2933                                         
2934                                         m_Annots.Add(pLeftTopAnnot);
2935                                         sa.RemoveAt(nLeftTopIndex);
2936
2937                                         CFX_ArrayTemplate<int> aSelect;
2938
2939                                         {
2940                                                 for (int i=0,sz=sa.GetSize(); i<sz; i++)
2941                                                 {
2942                                                         CPDFSDK_Annot* pAnnot = sa.GetAt(i);
2943                                                         ASSERT(pAnnot != NULL);
2944
2945                                                         CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
2946
2947                                                         FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f;
2948
2949                                                         if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right)
2950                                                                 aSelect.Add(i);
2951                                                 }
2952                                         }
2953
2954                                         {
2955                                                 for (int i=0,sz=aSelect.GetSize(); i<sz; i++)
2956                                                 {
2957                                                         m_Annots.Add(sa[aSelect[i]]);
2958                                                 }
2959                                         }
2960
2961                                         {
2962                                                 for (int i=aSelect.GetSize()-1; i>=0; i--)
2963                                                 {
2964                                                         sa.RemoveAt(aSelect[i]);
2965                                                 }
2966                                         }
2967
2968                                         aSelect.RemoveAll();
2969                                 }
2970                         }
2971                         sa.RemoveAll();
2972                 }
2973                 break;
2974         }
2975 }
2976
2977 CPDF_Rect CBA_AnnotIterator::GetAnnotRect(CPDFSDK_Annot* pAnnot)
2978 {
2979         ASSERT(pAnnot != NULL);
2980
2981         CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
2982         ASSERT(pPDFAnnot != NULL);
2983
2984         CPDF_Rect rcAnnot;
2985         pPDFAnnot->GetRect(rcAnnot);
2986
2987         return rcAnnot;
2988 }
2989