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 "../../public/fpdf_ext.h"
8#include "../include/fsdk_define.h"
9#include "../include/fsdk_mgr.h"
10#include "../include/formfiller/FFL_FormFiller.h"
11#include "../include/javascript/IJavaScript.h"
12
13#if _FX_OS_ == _FX_ANDROID_
14#include "time.h"
15#else
16#include <ctime>
17#endif
18
19//extern CPDFDoc_Environment* g_pFormFillApp;
20class CFX_SystemHandler:public IFX_SystemHandler
21{
22public:
23	CFX_SystemHandler(CPDFDoc_Environment* pEnv):m_pEnv(pEnv),m_nCharSet(-1) {}
24public:
25	virtual void				InvalidateRect(FX_HWND hWnd, FX_RECT rect) ;
26	virtual void				OutputSelectedRect(void* pFormFiller, CPDF_Rect& rect);
27
28	virtual FX_BOOL				IsSelectionImplemented();
29
30	virtual CFX_WideString		GetClipboardText(FX_HWND hWnd){return L"";}
31	virtual FX_BOOL				SetClipboardText(FX_HWND hWnd, CFX_WideString string) {return FALSE;}
32
33	virtual void				ClientToScreen(FX_HWND hWnd, FX_INT32& x, FX_INT32& y) {}
34	virtual void				ScreenToClient(FX_HWND hWnd, FX_INT32& x, FX_INT32& y) {}
35
36	/*cursor style
37	FXCT_ARROW
38	FXCT_NESW
39	FXCT_NWSE
40	FXCT_VBEAM
41	FXCT_HBEAM
42	FXCT_HAND
43	*/
44	virtual void				SetCursor(FX_INT32 nCursorType);
45
46	virtual FX_HMENU			CreatePopupMenu() {return NULL;}
47	virtual FX_BOOL				AppendMenuItem(FX_HMENU hMenu, FX_INT32 nIDNewItem, CFX_WideString string) {return FALSE;}
48	virtual FX_BOOL				EnableMenuItem(FX_HMENU hMenu, FX_INT32 nIDItem, FX_BOOL bEnabled) {return FALSE;}
49	virtual FX_INT32			TrackPopupMenu(FX_HMENU hMenu, FX_INT32 x, FX_INT32 y, FX_HWND hParent) {return -1;}
50	virtual void				DestroyMenu(FX_HMENU hMenu) {}
51
52	virtual CFX_ByteString		GetNativeTrueTypeFont(FX_INT32 nCharset);
53	virtual FX_BOOL				FindNativeTrueTypeFont(FX_INT32 nCharset, CFX_ByteString sFontFaceName);
54	virtual CPDF_Font*			AddNativeTrueTypeFontToPDF(CPDF_Document* pDoc, CFX_ByteString sFontFaceName, FX_BYTE nCharset);
55
56	virtual FX_INT32			SetTimer(FX_INT32 uElapse, TimerCallback lpTimerFunc) ;
57	virtual void				KillTimer(FX_INT32 nID) ;
58
59
60	virtual FX_BOOL				IsSHIFTKeyDown(FX_DWORD nFlag) {return m_pEnv->FFI_IsSHIFTKeyDown(nFlag);}
61	virtual FX_BOOL				IsCTRLKeyDown(FX_DWORD nFlag) {return m_pEnv->FFI_IsCTRLKeyDown(nFlag);}
62	virtual FX_BOOL				IsALTKeyDown(FX_DWORD nFlag) {return m_pEnv->FFI_IsALTKeyDown(nFlag);}
63	virtual FX_BOOL				IsINSERTKeyDown(FX_DWORD nFlag) {return m_pEnv->FFI_IsINSERTKeyDown(nFlag);}
64
65	virtual	FX_SYSTEMTIME		GetLocalTime();
66
67	virtual FX_INT32			GetCharSet() {return m_nCharSet;}
68	virtual void 				SetCharSet(FX_INT32 nCharSet) {m_nCharSet = nCharSet;}
69private:
70	CPDFDoc_Environment* m_pEnv;
71	int		m_nCharSet;
72};
73
74void CFX_SystemHandler::SetCursor(FX_INT32 nCursorType)
75{
76
77	m_pEnv->FFI_SetCursor(nCursorType);
78}
79
80void CFX_SystemHandler::InvalidateRect(FX_HWND hWnd, FX_RECT rect)
81{
82	//g_pFormFillApp->FFI_Invalidate();
83	CPDFSDK_Annot* pSDKAnnot = (CPDFSDK_Annot*)hWnd;
84	CPDF_Page* pPage = NULL;
85	CPDFSDK_PageView* pPageView = NULL;
86	pPageView = pSDKAnnot->GetPageView();
87	pPage = pSDKAnnot->GetPDFPage();
88	if(!pPage || !pPageView)
89		return;
90	CPDF_Matrix page2device;
91	pPageView->GetCurrentMatrix(page2device);
92	CPDF_Matrix device2page;
93	device2page.SetReverse(page2device);
94	FX_FLOAT left, top, right,bottom;
95	device2page.Transform((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, left, top);
96	device2page.Transform((FX_FLOAT)rect.right, (FX_FLOAT)rect.bottom, right, bottom);
97// 	m_pEnv->FFI_DeviceToPage(pPage, rect.left, rect.top, (double*)&left, (double*)&top);
98// 	m_pEnv->FFI_DeviceToPage(pPage, rect.right, rect.bottom, (double*)&right, (double*)&bottom);
99	CPDF_Rect rcPDF(left, bottom, right, top);
100	rcPDF.Normalize();
101
102	m_pEnv->FFI_Invalidate(pPage, rcPDF.left, rcPDF.top, rcPDF.right, rcPDF.bottom);
103}
104void CFX_SystemHandler::OutputSelectedRect(void* pFormFiller, CPDF_Rect& rect)
105{
106	CFFL_FormFiller* pFFL = (CFFL_FormFiller*)pFormFiller;
107	if(pFFL)
108	{
109		CPDF_Point leftbottom = CPDF_Point(rect.left, rect.bottom);
110		CPDF_Point righttop = CPDF_Point(rect.right, rect.top);
111		CPDF_Point ptA = pFFL->PWLtoFFL(leftbottom);
112		CPDF_Point ptB = pFFL->PWLtoFFL(righttop);
113
114
115		CPDFSDK_Annot* pAnnot  = pFFL->GetSDKAnnot();
116		ASSERT(pAnnot);
117		CPDF_Page* pPage = pAnnot->GetPDFPage();
118		ASSERT(pPage);
119		m_pEnv->FFI_OutputSelectedRect(pPage, ptA.x, ptB.y, ptB.x, ptA.y);
120	}
121
122}
123
124FX_BOOL CFX_SystemHandler::IsSelectionImplemented()
125{
126	if(m_pEnv)
127	{
128		FPDF_FORMFILLINFO* pInfo = m_pEnv->GetFormFillInfo();
129		if(pInfo && pInfo->FFI_OutputSelectedRect)
130			return TRUE;
131	}
132	return FALSE;
133}
134
135CFX_ByteString CFX_SystemHandler::GetNativeTrueTypeFont(FX_INT32 nCharset)
136{
137	return "";
138}
139
140FX_BOOL	CFX_SystemHandler::FindNativeTrueTypeFont(FX_INT32 nCharset, CFX_ByteString sFontFaceName)
141{
142	CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
143//	FXFT_Face nFace = pFontMgr->FindSubstFont(sFontFaceName,TRUE,0,0,0,0,NULL);
144//	FXFT_Face nFace  = pFontMgr->m_pBuiltinMapper->FindSubstFont(sFontFaceName,TRUE,0,0,0,0,NULL);
145
146	if(pFontMgr)
147	{
148		CFX_FontMapper*	pFontMapper = pFontMgr->m_pBuiltinMapper;
149		if(pFontMapper)
150		{
151			int nSize = pFontMapper->m_InstalledTTFonts.GetSize();
152			if(nSize ==0)
153			{
154				pFontMapper->LoadInstalledFonts();
155				nSize = pFontMapper->m_InstalledTTFonts.GetSize();
156			}
157
158			for(int i=0; i<nSize; i++)
159			{
160				if(pFontMapper->m_InstalledTTFonts[i].Compare(sFontFaceName))
161					return TRUE;
162			}
163		}
164
165	}
166
167	return FALSE;
168// 	pFontMgr->m_FaceMap.Lookup(sFontFaceName,pFont);
169// 	return (pFont!=NULL);
170}
171
172static int CharSet2CP(int charset)
173{
174	if(charset == 128)
175		return 932;
176	else if(charset == 134)
177		return 936;
178	else if(charset == 129)
179		return 949;
180	else if(charset == 136)
181		return 950;
182	return 0;
183}
184CPDF_Font* CFX_SystemHandler::AddNativeTrueTypeFontToPDF(CPDF_Document* pDoc, CFX_ByteString sFontFaceName,
185														 FX_BYTE nCharset)
186{
187	if(pDoc)
188	{
189		CFX_Font* pFXFont = new CFX_Font();
190		pFXFont->LoadSubst(sFontFaceName,TRUE,0,0,0,CharSet2CP(nCharset),FALSE);
191		CPDF_Font* pFont = pDoc->AddFont(pFXFont,nCharset,FALSE);
192		delete pFXFont;
193		return pFont;
194	}
195
196	return NULL;
197}
198
199
200FX_INT32 CFX_SystemHandler::SetTimer(FX_INT32 uElapse, TimerCallback lpTimerFunc)
201{
202	return m_pEnv->FFI_SetTimer(uElapse, lpTimerFunc);
203}
204void CFX_SystemHandler::KillTimer(FX_INT32 nID)
205{
206	m_pEnv->FFI_KillTimer(nID);
207}
208
209FX_SYSTEMTIME CFX_SystemHandler::GetLocalTime()
210{
211	return m_pEnv->FFI_GetLocalTime();
212}
213
214
215CJS_RuntimeFactory* GetJSRuntimeFactory()
216{
217	static CJS_RuntimeFactory s_JSRuntimeFactory;
218	return &s_JSRuntimeFactory;
219}
220
221CPDFDoc_Environment::CPDFDoc_Environment(CPDF_Document* pDoc) :
222	m_pAnnotHandlerMgr(NULL),
223	m_pActionHandler(NULL),
224	m_pJSRuntime(NULL),
225	m_pInfo(NULL),
226	m_pSDKDoc(NULL),
227	m_pPDFDoc(pDoc),
228	m_pIFormFiller(NULL)
229{
230
231	m_pSysHandler = NULL;
232	m_pSysHandler = new CFX_SystemHandler(this);
233
234
235	m_pJSRuntimeFactory = NULL;
236	m_pJSRuntimeFactory = GetJSRuntimeFactory();
237	m_pJSRuntimeFactory->AddRef();
238}
239
240CPDFDoc_Environment::~CPDFDoc_Environment()
241{
242
243	if ( m_pIFormFiller )
244	{
245		delete m_pIFormFiller;
246		m_pIFormFiller = NULL;
247	}
248	if(m_pJSRuntime && m_pJSRuntimeFactory)
249		m_pJSRuntimeFactory->DeleteJSRuntime(m_pJSRuntime);
250	m_pJSRuntimeFactory->Release();
251
252	if(m_pSysHandler)
253	{
254		delete m_pSysHandler;
255		m_pSysHandler = NULL;
256	}
257
258	if(m_pAnnotHandlerMgr)
259	{
260		delete m_pAnnotHandlerMgr;
261		m_pAnnotHandlerMgr = NULL;
262	}
263	if(m_pActionHandler)
264	{
265		delete m_pActionHandler;
266		m_pActionHandler = NULL;
267	}
268
269
270}
271
272
273IFXJS_Runtime* CPDFDoc_Environment::GetJSRuntime()
274{
275	if(!IsJSInitiated())
276		return NULL;
277	assert(m_pJSRuntimeFactory);
278	if(!m_pJSRuntime)
279		m_pJSRuntime = m_pJSRuntimeFactory->NewJSRuntime(this);
280	return m_pJSRuntime;
281}
282
283CPDFSDK_AnnotHandlerMgr* CPDFDoc_Environment::GetAnnotHandlerMgr()
284{
285	if(!m_pAnnotHandlerMgr)
286		m_pAnnotHandlerMgr = new CPDFSDK_AnnotHandlerMgr(this);
287	return m_pAnnotHandlerMgr;
288}
289
290CPDFSDK_ActionHandler* CPDFDoc_Environment::GetActionHander()
291{
292	if(!m_pActionHandler)
293		m_pActionHandler = new CPDFSDK_ActionHandler(this);
294	return m_pActionHandler;
295}
296
297int CPDFDoc_Environment::RegAppHandle(FPDF_FORMFILLINFO* pFFinfo)
298{
299	m_pInfo  = pFFinfo;
300	return TRUE;
301}
302
303CPDFSDK_Document* CPDFDoc_Environment::GetCurrentDoc()
304{
305	return m_pSDKDoc;
306}
307
308CFFL_IFormFiller* CPDFDoc_Environment::GetIFormFiller()
309{
310	if(!m_pIFormFiller)
311		m_pIFormFiller = new CFFL_IFormFiller(this);
312	return m_pIFormFiller;
313}
314
315FX_BOOL	CPDFDoc_Environment::IsJSInitiated()
316{
317	if(m_pInfo)
318	{
319		if(m_pInfo->m_pJsPlatform)
320			return TRUE;
321		else
322			return FALSE;
323	}
324	return FALSE;
325}
326
327CPDFSDK_Document::CPDFSDK_Document(CPDF_Document* pDoc,CPDFDoc_Environment* pEnv):m_pDoc(pDoc),
328						m_pInterForm(NULL),m_pEnv(pEnv),m_pOccontent(NULL),m_bChangeMask(FALSE)
329{
330	m_pFocusAnnot = NULL;
331}
332
333CPDFSDK_Document::~CPDFSDK_Document()
334{
335	FX_POSITION pos = m_pageMap.GetStartPosition();
336	while (pos) {
337            CPDF_Page* pPage = NULL;
338            CPDFSDK_PageView* pPageView = NULL;
339            m_pageMap.GetNextAssoc(pos, pPage, pPageView);
340            delete pPageView;
341        }
342        m_pageMap.RemoveAll();
343	if(m_pInterForm)
344	{
345		m_pInterForm->Destroy();
346		m_pInterForm = NULL;
347	}
348	if(m_pOccontent)
349	{
350		delete m_pOccontent;
351		m_pOccontent = NULL;
352	}
353}
354
355void CPDFSDK_Document::InitPageView()
356{
357	int nCount = m_pDoc->GetPageCount();
358	for(int i=0; i<nCount; i++)
359	{
360	// To do
361//		CPDF_Dictionary* pDic = m_pDoc->GetPage(i);
362//		m_pageMap.SetAt(pDic, pPageView);
363	}
364}
365
366void CPDFSDK_Document::AddPageView(CPDF_Page* pPDFPage, CPDFSDK_PageView* pPageView)
367{
368	m_pageMap.SetAt(pPDFPage, pPageView);
369}
370
371CPDFSDK_PageView* CPDFSDK_Document::GetPageView(CPDF_Page* pPDFPage, FX_BOOL ReNew)
372{
373	CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)m_pageMap.GetValueAt(pPDFPage);
374	if(pPageView != NULL)
375		return pPageView;
376	if(ReNew)
377	{
378		pPageView = new CPDFSDK_PageView(this,pPDFPage);
379		m_pageMap.SetAt(pPDFPage, pPageView);
380		//Delay to load all the annotations, to avoid endless loop.
381		pPageView->LoadFXAnnots();
382	}
383	return pPageView;
384
385}
386
387CPDFSDK_PageView* CPDFSDK_Document::GetCurrentView()
388{
389	CPDF_Page * pPage = (CPDF_Page *)m_pEnv->FFI_GetCurrentPage(m_pDoc);
390	if(pPage)
391		return this->GetPageView(pPage, TRUE);
392	return NULL;
393}
394
395CPDFSDK_PageView* CPDFSDK_Document::GetPageView(int nIndex)
396{
397	CPDFSDK_PageView * pTempPageView = NULL;
398	CPDF_Page * pTempPage = (CPDF_Page*)m_pEnv->FFI_GetPage(m_pDoc,nIndex);
399	if(!pTempPage)
400		return NULL;
401
402	m_pageMap.Lookup(pTempPage, pTempPageView);
403
404	ASSERT(pTempPageView != NULL);
405
406	return pTempPageView;
407}
408
409void CPDFSDK_Document:: ProcJavascriptFun()
410{
411	CPDF_Document* pPDFDoc = this->GetDocument();
412	CPDF_DocJSActions docJS(pPDFDoc);
413	int iCount = docJS.CountJSActions();
414	if (iCount < 1) return;
415	for (int i = 0; i < iCount; i ++)
416	{
417		CFX_ByteString csJSName;
418		CPDF_Action jsAction = docJS.GetJSAction(i, csJSName);
419		if(m_pEnv->GetActionHander())
420			m_pEnv->GetActionHander()->DoAction_JavaScript(jsAction,CFX_WideString::FromLocal(csJSName),this);
421	}
422
423}
424
425FX_BOOL CPDFSDK_Document::ProcOpenAction()
426{
427	if(!m_pDoc)
428		return FALSE;
429
430	CPDF_Dictionary* pRoot = m_pDoc->GetRoot();
431	if (!pRoot)
432		return FALSE;
433
434	CPDF_Object* pOpenAction = pRoot->GetDict("OpenAction");
435	if(!pOpenAction)
436		pOpenAction = pRoot->GetArray("OpenAction");
437
438	if(!pOpenAction)
439		return FALSE;
440
441	if(pOpenAction->GetType()==PDFOBJ_ARRAY)
442		return TRUE;
443
444	if(pOpenAction->GetType()==PDFOBJ_DICTIONARY)
445	{
446		CPDF_Dictionary * pDict=(CPDF_Dictionary*)pOpenAction;
447		CPDF_Action action(pDict);
448		if(m_pEnv->GetActionHander())
449			m_pEnv->GetActionHander()->DoAction_DocOpen(action, this);
450		return TRUE;
451	}
452	return FALSE;
453}
454
455CPDF_OCContext*	CPDFSDK_Document::GetOCContext()
456{
457	if(!m_pOccontent)
458		m_pOccontent = new CPDF_OCContext(m_pDoc);
459	return m_pOccontent;
460}
461
462void CPDFSDK_Document::ReMovePageView(CPDF_Page* pPDFPage)
463{
464	CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)m_pageMap.GetValueAt(pPDFPage);
465	if(pPageView && !pPageView->IsLocked())
466	{
467		delete pPageView;
468		m_pageMap.RemoveKey(pPDFPage);
469	}
470}
471
472CPDF_Page * CPDFSDK_Document::GetPage(int nIndex)
473{
474	CPDF_Page * pTempPage = (CPDF_Page*)m_pEnv->FFI_GetPage(m_pDoc,nIndex);
475	if(!pTempPage)
476		return NULL;
477	return pTempPage;
478}
479
480CPDFSDK_InterForm* CPDFSDK_Document::GetInterForm()
481{
482	if(!m_pInterForm)
483		m_pInterForm = new CPDFSDK_InterForm(this);
484	return m_pInterForm;
485}
486
487void CPDFSDK_Document::UpdateAllViews(CPDFSDK_PageView* pSender, CPDFSDK_Annot* pAnnot)
488{
489
490	FX_POSITION pos = m_pageMap.GetStartPosition();
491	CPDF_Page * pPage = NULL;
492	CPDFSDK_PageView * pPageView = NULL;
493	while(pos)
494	{
495		m_pageMap.GetNextAssoc(pos, pPage, pPageView);
496
497		if(pPageView != pSender)
498		{
499			pPageView->UpdateView(pAnnot);
500		}
501	}
502}
503
504CPDFSDK_Annot* CPDFSDK_Document::GetFocusAnnot()
505{
506	return this->m_pFocusAnnot;
507}
508
509FX_BOOL CPDFSDK_Document::SetFocusAnnot(CPDFSDK_Annot* pAnnot,FX_UINT nFlag)
510{
511
512	if(m_pFocusAnnot==pAnnot) return TRUE;
513
514	if(m_pFocusAnnot)
515	{
516		if(!this->KillFocusAnnot(nFlag) ) return FALSE;
517	}
518	CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
519	if(pAnnot && pPageView->IsValid())
520	{
521		CPDFSDK_AnnotHandlerMgr *pAnnotHandler=m_pEnv->GetAnnotHandlerMgr();
522
523		if(pAnnotHandler&&!m_pFocusAnnot)
524		{
525			if (!pAnnotHandler->Annot_OnSetFocus(pAnnot,nFlag))
526				return FALSE;
527			if(!m_pFocusAnnot)
528			{
529				this->m_pFocusAnnot=pAnnot;
530				return TRUE;
531			}
532		}
533	}
534	return FALSE;
535}
536
537FX_BOOL CPDFSDK_Document::KillFocusAnnot(FX_UINT nFlag)
538{
539	if(m_pFocusAnnot)
540	{
541		CPDFSDK_AnnotHandlerMgr *pAnnotHandler=m_pEnv->GetAnnotHandlerMgr();
542		if(pAnnotHandler)
543		{
544			CPDFSDK_Annot* pFocusAnnot = m_pFocusAnnot;
545			m_pFocusAnnot = NULL;
546			if(pAnnotHandler->Annot_OnKillFocus(pFocusAnnot, nFlag))
547			{
548
549				if(pFocusAnnot->GetType() == FX_BSTRC("Widget"))
550				{
551					CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pFocusAnnot;
552					int nFieldType = pWidget->GetFieldType();
553					if(FIELDTYPE_TEXTFIELD == nFieldType || FIELDTYPE_COMBOBOX == nFieldType)
554						m_pEnv->FFI_OnSetFieldInputFocus(NULL, NULL, 0, FALSE);
555				}
556
557				if(!m_pFocusAnnot)
558					return TRUE;
559			}
560			else
561			{
562				m_pFocusAnnot = pFocusAnnot;
563			}
564		}
565	}
566	return FALSE;
567}
568
569FX_BOOL	CPDFSDK_Document::DeletePages(int nStart, int  nCount)
570{
571	if ( nStart < 0 || nStart >= GetPageCount() || nCount <= 0 )
572	{
573		return FALSE;
574	}
575
576	CPDF_Page * pTempPage = NULL;
577	for ( int i = nCount-1; i >= 0; i-- )
578	{
579		pTempPage = GetPage(nStart+i);
580		if ( pTempPage != NULL )
581		{
582			ReMovePageView(pTempPage);
583		}
584	}
585	return TRUE;
586}
587
588void CPDFSDK_Document::OnCloseDocument()
589{
590	KillFocusAnnot();
591}
592
593FX_BOOL CPDFSDK_Document::GetPermissions(int nFlag)
594{
595	FX_DWORD dwPermissions = m_pDoc->GetUserPermissions();
596	return dwPermissions&nFlag;
597}
598
599IFXJS_Runtime * CPDFSDK_Document::GetJsRuntime()
600{
601	ASSERT(m_pEnv!=NULL);
602	return m_pEnv->GetJSRuntime();
603}
604
605CFX_WideString	CPDFSDK_Document::GetPath()
606{
607	ASSERT(m_pEnv != NULL);
608	return m_pEnv->JS_docGetFilePath();
609}
610
611
612CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,CPDF_Page* page):m_page(page),m_pSDKDoc(pSDKDoc)
613{
614	CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm();
615	if(pInterForm)
616	{
617		CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
618		pPDFInterForm->FixPageFields(page);
619	}
620        m_page->SetPrivateData((FX_LPVOID)m_page, (FX_LPVOID)this, NULL);
621	m_fxAnnotArray.RemoveAll();
622
623	m_bEnterWidget = FALSE;
624	m_bExitWidget = FALSE;
625	m_bOnWidget = FALSE;
626	m_CaptureWidget = NULL;
627	m_bValid = FALSE;
628        m_bLocked = FALSE;
629        m_bTakeOverPage = FALSE;
630}
631
632CPDFSDK_PageView::~CPDFSDK_PageView()
633{
634	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
635	int nAnnotCount = m_fxAnnotArray.GetSize();
636
637	for (int i=0; i<nAnnotCount; i++)
638	{
639		CPDFSDK_Annot* pAnnot = (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(i);
640		//if there is a focused annot on the page, we should kill the focus first.
641		if(pAnnot == m_pSDKDoc->GetFocusAnnot())
642			KillFocusAnnot();
643		CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
644		ASSERT(pAnnotHandlerMgr);
645		pAnnotHandlerMgr->ReleaseAnnot(pAnnot);
646	}
647	m_fxAnnotArray.RemoveAll();
648	if(m_pAnnotList)
649	{
650		delete m_pAnnotList;
651		m_pAnnotList = NULL;
652	}
653        m_page->RemovePrivateData((FX_LPVOID)m_page);
654        if(m_bTakeOverPage) {
655            delete m_page;
656        }
657}
658
659void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions)
660{
661	m_curMatrix = *pUser2Device;
662
663	//	m_pAnnotList->DisplayAnnots(m_page, pDevice, pUser2Device, FALSE, pOptions);
664	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
665	CPDFSDK_AnnotIterator annotIterator(this, TRUE);
666	CPDFSDK_Annot * pSDKAnnot=NULL;
667	int index=-1;
668	while((pSDKAnnot = annotIterator.Next(index)))
669	{
670		CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
671		ASSERT(pAnnotHandlerMgr);
672		pAnnotHandlerMgr->Annot_OnDraw(this, pSDKAnnot, pDevice, pUser2Device, 0);
673	}
674
675}
676
677CPDF_Annot* CPDFSDK_PageView::GetPDFAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY)
678{
679
680	int nCount = m_pAnnotList->Count();
681	for(int i = 0 ; i<nCount; i++)
682	{
683		CPDF_Annot* pAnnot = m_pAnnotList->GetAt(i);
684		CFX_FloatRect annotRect;
685		pAnnot->GetRect(annotRect);
686		if(annotRect.Contains(pageX, pageY))
687			return pAnnot;
688	}
689	return NULL;
690}
691
692CPDF_Annot* CPDFSDK_PageView::GetPDFWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY)
693{
694
695	int nCount = m_pAnnotList->Count();
696	for(int i = 0 ; i<nCount; i++)
697	{
698		CPDF_Annot* pAnnot = m_pAnnotList->GetAt(i);
699		if(pAnnot->GetSubType() == "Widget")
700		{
701			CFX_FloatRect annotRect;
702			pAnnot->GetRect(annotRect);
703			if(annotRect.Contains(pageX, pageY))
704				return pAnnot;
705		}
706	}
707	return NULL;
708}
709
710CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY)
711{
712
713	CPDFSDK_AnnotIterator annotIterator(this, FALSE);
714	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
715	CPDFSDK_AnnotHandlerMgr* pAnnotMgr = pEnv->GetAnnotHandlerMgr();
716	CPDFSDK_Annot* pSDKAnnot = NULL;
717	int index = -1;
718	while((pSDKAnnot = annotIterator.Next(index)))
719	{
720		CPDF_Rect rc = pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot);
721		if(rc.Contains(pageX, pageY))
722			return pSDKAnnot;
723	}
724
725	return NULL;
726}
727
728CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY)
729{
730
731	CPDFSDK_AnnotIterator annotIterator(this, FALSE);
732	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
733	CPDFSDK_AnnotHandlerMgr* pAnnotMgr = pEnv->GetAnnotHandlerMgr();
734	CPDFSDK_Annot* pSDKAnnot = NULL;
735	int index = -1;
736	while((pSDKAnnot = annotIterator.Next(index)))
737	{
738		if(pSDKAnnot->GetType() == "Widget")
739		{
740			pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot);
741			CPDF_Point point(pageX, pageY);
742			if (pAnnotMgr->Annot_OnHitTest(this, pSDKAnnot, point))
743//			if(rc.Contains(pageX, pageY))
744				return pSDKAnnot;
745		}
746	}
747
748	return NULL;
749}
750
751
752FX_BOOL CPDFSDK_PageView::Annot_HasAppearance(CPDF_Annot* pAnnot)
753{
754	CPDF_Dictionary* pAnnotDic = pAnnot->m_pAnnotDict;
755	if(pAnnotDic)
756		return	pAnnotDic->KeyExist("AS");
757	return FALSE;
758}
759
760CPDFSDK_Annot*	CPDFSDK_PageView::AddAnnot(CPDF_Annot * pPDFAnnot)
761{
762	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
763	ASSERT(pEnv);
764	CPDFSDK_AnnotHandlerMgr * pAnnotHandler= pEnv->GetAnnotHandlerMgr();
765
766	CPDFSDK_Annot* pSDKAnnot =NULL;
767
768	if(pAnnotHandler)
769	{
770		pSDKAnnot = pAnnotHandler->NewAnnot(pPDFAnnot, this);
771	}
772	if(!pSDKAnnot)
773		return NULL;
774
775	m_fxAnnotArray.Add(pSDKAnnot);
776
777	if(pAnnotHandler)
778	{
779		pAnnotHandler->Annot_OnCreate(pSDKAnnot);
780
781	}
782
783	 return pSDKAnnot;
784}
785
786CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CPDF_Dictionary * pDict)
787{
788	if(pDict)
789		return this->AddAnnot(pDict->GetString("Subtype"),pDict);
790	 return NULL;
791}
792
793CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(FX_LPCSTR lpSubType,CPDF_Dictionary * pDict)
794{
795	return NULL;
796}
797
798FX_BOOL  CPDFSDK_PageView::DeleteAnnot(CPDFSDK_Annot* pAnnot)
799{
800	return FALSE;
801}
802
803CPDF_Document* CPDFSDK_PageView::GetPDFDocument()
804{
805	if(m_page)
806	{
807		return m_page->m_pDocument;
808	}
809	return NULL;
810}
811
812int	CPDFSDK_PageView::CountAnnots()
813{
814	return m_pAnnotList->Count();
815}
816
817CPDFSDK_Annot*	CPDFSDK_PageView::GetAnnot(int nIndex)
818{
819	int nCount = m_fxAnnotArray.GetSize();
820	if ( nIndex < 0 || nIndex >= nCount )
821	{
822		return NULL;
823	}
824
825	return (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(nIndex);
826}
827
828CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByDict(CPDF_Dictionary * pDict)
829{
830	int nCount = m_fxAnnotArray.GetSize();
831 	for(int i=0; i<nCount; i++)
832 	{
833		CPDFSDK_Annot* pAnnot = (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(i);
834 		if(pDict==pAnnot->GetPDFAnnot()->m_pAnnotDict)
835 			return pAnnot;
836 	}
837	return NULL;
838}
839
840FX_BOOL CPDFSDK_PageView::OnLButtonDown(const CPDF_Point & point, FX_UINT nFlag)
841{
842	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
843	ASSERT(pEnv);
844	CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y);
845	if(!pFXAnnot)
846	{
847		KillFocusAnnot(nFlag);
848	}
849	else
850	{
851		CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
852		ASSERT(pAnnotHandlerMgr);
853
854		FX_BOOL bRet = pAnnotHandlerMgr->Annot_OnLButtonDown(this, pFXAnnot, nFlag,point);
855 		if(bRet)
856 		{
857 			SetFocusAnnot(pFXAnnot);
858 		}
859		return bRet;
860	}
861	return FALSE;
862}
863
864
865FX_BOOL CPDFSDK_PageView::OnLButtonUp(const CPDF_Point & point, FX_UINT nFlag)
866{
867	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
868	ASSERT(pEnv);
869	CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
870	ASSERT(pAnnotHandlerMgr);
871	CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y);
872	CPDFSDK_Annot* pFocusAnnot = GetFocusAnnot();
873	FX_BOOL bRet  = FALSE;
874	if(pFocusAnnot && pFocusAnnot != pFXAnnot)
875	{
876		//Last focus Annot gets a chance to handle the event.
877		bRet = pAnnotHandlerMgr->Annot_OnLButtonUp(this, pFocusAnnot, nFlag,point);
878	}
879	if(pFXAnnot && !bRet)
880	{
881		bRet = pAnnotHandlerMgr->Annot_OnLButtonUp(this, pFXAnnot, nFlag,point);
882		return bRet;
883	}
884	return bRet;
885}
886
887FX_BOOL CPDFSDK_PageView::OnMouseMove(const CPDF_Point & point, int nFlag)
888{
889
890	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
891	CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
892	ASSERT(pAnnotHandlerMgr);
893	if(CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y))
894	{
895		if(m_CaptureWidget && m_CaptureWidget != pFXAnnot)
896		{
897			m_bExitWidget = TRUE;
898			m_bEnterWidget = FALSE;
899			pAnnotHandlerMgr->Annot_OnMouseExit(this, m_CaptureWidget, nFlag);
900		}
901		m_CaptureWidget = (CPDFSDK_Widget*)pFXAnnot;
902		m_bOnWidget = TRUE;
903		if(!m_bEnterWidget)
904		{
905			m_bEnterWidget = TRUE;
906			m_bExitWidget = FALSE;
907			pAnnotHandlerMgr->Annot_OnMouseEnter(this, pFXAnnot,nFlag);
908		}
909		pAnnotHandlerMgr->Annot_OnMouseMove(this, pFXAnnot, nFlag, point);
910		return TRUE;
911	}
912	else
913	{
914		if(m_bOnWidget)
915		{
916			m_bOnWidget = FALSE;
917			m_bExitWidget = TRUE;
918			m_bEnterWidget = FALSE;
919			if(m_CaptureWidget)
920			{
921				pAnnotHandlerMgr->Annot_OnMouseExit(this, m_CaptureWidget, nFlag);
922				m_CaptureWidget = NULL;
923			}
924		}
925		return FALSE;
926	}
927
928	return FALSE;;
929}
930
931FX_BOOL CPDFSDK_PageView::OnMouseWheel(double deltaX, double deltaY,const CPDF_Point& point, int nFlag)
932{
933	if(CPDFSDK_Annot* pAnnot = GetFXWidgetAtPoint(point.x, point.y))
934	{
935		CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
936		CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
937		ASSERT(pAnnotHandlerMgr);
938		return pAnnotHandlerMgr->Annot_OnMouseWheel(this, pAnnot, nFlag, (int)deltaY, point);
939	}
940	return FALSE;
941
942}
943
944FX_BOOL CPDFSDK_PageView::OnChar(int nChar, FX_UINT nFlag)
945{
946	if(CPDFSDK_Annot* pAnnot = GetFocusAnnot())
947	{
948		CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
949		CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
950		ASSERT(pAnnotHandlerMgr);
951		return pAnnotHandlerMgr->Annot_OnChar(pAnnot, nChar, nFlag);
952	}
953
954	return FALSE;
955}
956
957FX_BOOL CPDFSDK_PageView::OnKeyDown(int nKeyCode, int nFlag)
958{
959	if(CPDFSDK_Annot* pAnnot = GetFocusAnnot())
960	{
961		CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
962		CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
963		ASSERT(pAnnotHandlerMgr);
964		return pAnnotHandlerMgr->Annot_OnKeyDown(pAnnot, nKeyCode, nFlag);
965	}
966	return FALSE;
967}
968
969FX_BOOL CPDFSDK_PageView::OnKeyUp(int nKeyCode, int nFlag)
970{
971// 	if(CPDFSDK_Annot* pAnnot = GetFocusAnnot())
972// 	{
973// 		CFFL_IFormFiller* pIFormFiller = g_pFormFillApp->GetIFormFiller();
974// 		return pIFormFiller->OnKeyUp(pAnnot, nKeyCode, nFlag);
975// 	}
976	return FALSE;
977}
978
979extern void CheckUnSupportAnnot(CPDF_Document * pDoc, CPDF_Annot* pPDFAnnot);
980
981void CPDFSDK_PageView::LoadFXAnnots()
982{
983	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
984
985	FX_BOOL enableAPUpdate = CPDF_InterForm::UpdatingAPEnabled();
986	//Disable the default AP construction.
987	CPDF_InterForm::EnableUpdateAP(FALSE);
988	m_pAnnotList = new CPDF_AnnotList(m_page);
989	CPDF_InterForm::EnableUpdateAP(enableAPUpdate);
990	int nCount = m_pAnnotList->Count();
991        SetLock(TRUE);
992	for(int i=0; i<nCount; i++)
993	{
994		CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
995		CPDF_Document * pDoc = this->GetPDFDocument();
996
997		CheckUnSupportAnnot(pDoc, pPDFAnnot);
998
999		CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
1000		ASSERT(pAnnotHandlerMgr != NULL);
1001
1002		if(pAnnotHandlerMgr)
1003		{
1004			CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pPDFAnnot, this);
1005			if(!pAnnot)
1006				continue;
1007			m_fxAnnotArray.Add(pAnnot);
1008
1009			pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
1010		}
1011
1012	}
1013        SetLock(FALSE);
1014}
1015
1016void	CPDFSDK_PageView::UpdateRects(CFX_RectArray& rects)
1017{
1018	for(int i=0; i<rects.GetSize(); i++)
1019	{
1020		CPDF_Rect rc = rects.GetAt(i);
1021		CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
1022		pEnv->FFI_Invalidate(m_page, rc.left, rc.top, rc.right, rc.bottom);
1023	}
1024}
1025
1026void CPDFSDK_PageView::UpdateView(CPDFSDK_Annot* pAnnot)
1027{
1028	CPDF_Rect rcWindow;
1029
1030 	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
1031// 	CPDFSDK_AnnotHandlerMgr* pAnnotHandler = pEnv->GetAnnotHandlerMgr();
1032
1033	rcWindow = pAnnot->GetRect();//pAnnotHandler->Annot_OnGetViewBBox(this,pAnnot);
1034	pEnv->FFI_Invalidate(m_page, rcWindow.left, rcWindow.top, rcWindow.right, rcWindow.bottom);
1035
1036}
1037
1038int CPDFSDK_PageView::GetPageIndex()
1039{
1040	if(m_page)
1041	{
1042		CPDF_Dictionary* pDic = m_page->m_pFormDict;
1043		CPDF_Document* pDoc = m_pSDKDoc->GetDocument();
1044		if(pDoc && pDic)
1045		{
1046			return pDoc->GetPageIndex(pDic->GetObjNum());
1047		}
1048	}
1049	return -1;
1050}
1051
1052FX_BOOL	CPDFSDK_PageView::IsValidAnnot(FX_LPVOID p)
1053{
1054	if (p == NULL) return FALSE;
1055	int iCount = m_pAnnotList->Count();
1056	for (int i = 0; i < iCount; i++)
1057	{
1058		if (m_pAnnotList->GetAt(i) == p)
1059			return TRUE;
1060	}
1061	return FALSE;
1062}
1063
1064
1065CPDFSDK_Annot* CPDFSDK_PageView::GetFocusAnnot()
1066{
1067	CPDFSDK_Annot* pFocusAnnot = m_pSDKDoc->GetFocusAnnot();
1068	if(!pFocusAnnot)
1069		return NULL;
1070
1071	for(int i=0; i<m_fxAnnotArray.GetSize(); i++)
1072	{
1073		CPDFSDK_Annot* pAnnot = (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(i);
1074		if(pAnnot == pFocusAnnot)
1075			return pAnnot;
1076	}
1077	return NULL;
1078}
1079
1080