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