blob: 6992e5701922544d931d6c48fd39a0202aae9986 [file] [log] [blame]
// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "xfa/fxfa/cxfa_ffwidgethandler.h"
#include "fxjs/xfa/cjx_object.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_fffield.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
#include "xfa/fxfa/layout/cxfa_layoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_calculate.h"
#include "xfa/fxfa/parser/cxfa_checkbutton.h"
#include "xfa/fxfa/parser/cxfa_measurement.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_ui.h"
#include "xfa/fxfa/parser/cxfa_validate.h"
CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
: m_pDocView(pDocView) {}
CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() = default;
void CXFA_FFWidgetHandler::Trace(cppgc::Visitor* visitor) const {
visitor->Trace(m_pDocView);
}
bool CXFA_FFWidgetHandler::OnMouseEnter(CXFA_FFWidget* hWidget) {
CXFA_FFDocView::UpdateScope scope(m_pDocView);
return hWidget->OnMouseEnter();
}
bool CXFA_FFWidgetHandler::OnMouseExit(CXFA_FFWidget* hWidget) {
CXFA_FFDocView::UpdateScope scope(m_pDocView);
return hWidget->OnMouseExit();
}
bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget,
Mask<XFA_FWL_KeyFlag> dwFlags,
const CFX_PointF& point) {
CXFA_FFDocView::UpdateScope scope(m_pDocView);
if (!hWidget->AcceptsFocusOnButtonDown(
dwFlags, hWidget->Rotate2Normal(point),
CFWL_MessageMouse::MouseCommand::kLeftButtonDown)) {
return false;
}
// May re-enter JS.
if (m_pDocView->SetFocus(hWidget))
m_pDocView->GetDoc()->SetFocusWidget(hWidget);
return hWidget->OnLButtonDown(dwFlags, hWidget->Rotate2Normal(point));
}
bool CXFA_FFWidgetHandler::OnLButtonUp(CXFA_FFWidget* hWidget,
Mask<XFA_FWL_KeyFlag> dwFlags,
const CFX_PointF& point) {
CXFA_FFDocView::UpdateScope scope(m_pDocView);
m_pDocView->SetLayoutEvent();
return hWidget->OnLButtonUp(dwFlags, hWidget->Rotate2Normal(point));
}
bool CXFA_FFWidgetHandler::OnLButtonDblClk(CXFA_FFWidget* hWidget,
Mask<XFA_FWL_KeyFlag> dwFlags,
const CFX_PointF& point) {
return hWidget->OnLButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
}
bool CXFA_FFWidgetHandler::OnMouseMove(CXFA_FFWidget* hWidget,
Mask<XFA_FWL_KeyFlag> dwFlags,
const CFX_PointF& point) {
return hWidget->OnMouseMove(dwFlags, hWidget->Rotate2Normal(point));
}
bool CXFA_FFWidgetHandler::OnMouseWheel(CXFA_FFWidget* hWidget,
Mask<XFA_FWL_KeyFlag> dwFlags,
const CFX_PointF& point,
const CFX_Vector& delta) {
return hWidget->OnMouseWheel(dwFlags, hWidget->Rotate2Normal(point), delta);
}
bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget,
Mask<XFA_FWL_KeyFlag> dwFlags,
const CFX_PointF& point) {
if (!hWidget->AcceptsFocusOnButtonDown(
dwFlags, hWidget->Rotate2Normal(point),
CFWL_MessageMouse::MouseCommand::kRightButtonDown)) {
return false;
}
// May re-enter JS.
if (m_pDocView->SetFocus(hWidget)) {
m_pDocView->GetDoc()->SetFocusWidget(hWidget);
}
return hWidget->OnRButtonDown(dwFlags, hWidget->Rotate2Normal(point));
}
bool CXFA_FFWidgetHandler::OnRButtonUp(CXFA_FFWidget* hWidget,
Mask<XFA_FWL_KeyFlag> dwFlags,
const CFX_PointF& point) {
return hWidget->OnRButtonUp(dwFlags, hWidget->Rotate2Normal(point));
}
bool CXFA_FFWidgetHandler::OnRButtonDblClk(CXFA_FFWidget* hWidget,
Mask<XFA_FWL_KeyFlag> dwFlags,
const CFX_PointF& point) {
return hWidget->OnRButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
}
bool CXFA_FFWidgetHandler::OnKeyDown(CXFA_FFWidget* hWidget,
XFA_FWL_VKEYCODE dwKeyCode,
Mask<XFA_FWL_KeyFlag> dwFlags) {
bool bRet = hWidget->OnKeyDown(dwKeyCode, dwFlags);
m_pDocView->UpdateDocView();
return bRet;
}
bool CXFA_FFWidgetHandler::OnChar(CXFA_FFWidget* hWidget,
uint32_t dwChar,
Mask<XFA_FWL_KeyFlag> dwFlags) {
return hWidget->OnChar(dwChar, dwFlags);
}
WideString CXFA_FFWidgetHandler::GetText(CXFA_FFWidget* widget) {
return widget->GetText();
}
WideString CXFA_FFWidgetHandler::GetSelectedText(CXFA_FFWidget* widget) {
if (!widget->CanCopy())
return WideString();
return widget->Copy().value_or(WideString());
}
void CXFA_FFWidgetHandler::PasteText(CXFA_FFWidget* widget,
const WideString& text) {
if (!widget->CanPaste())
return;
widget->Paste(text);
}
bool CXFA_FFWidgetHandler::SelectAllText(CXFA_FFWidget* widget) {
if (!widget->CanSelectAll())
return false;
widget->SelectAll();
return true;
}
bool CXFA_FFWidgetHandler::CanUndo(CXFA_FFWidget* widget) {
return widget->CanUndo();
}
bool CXFA_FFWidgetHandler::CanRedo(CXFA_FFWidget* widget) {
return widget->CanRedo();
}
bool CXFA_FFWidgetHandler::Undo(CXFA_FFWidget* widget) {
return widget->Undo();
}
bool CXFA_FFWidgetHandler::Redo(CXFA_FFWidget* widget) {
return widget->Redo();
}
FWL_WidgetHit CXFA_FFWidgetHandler::HitTest(CXFA_FFWidget* pWidget,
const CFX_PointF& point) {
if (!pWidget->GetLayoutItem()->TestStatusBits(XFA_WidgetStatus::kVisible))
return FWL_WidgetHit::Unknown;
return pWidget->HitTest(pWidget->Rotate2Normal(point));
}
void CXFA_FFWidgetHandler::RenderWidget(CXFA_FFWidget* hWidget,
CFGAS_GEGraphics* pGS,
const CFX_Matrix& matrix,
bool bHighlight) {
hWidget->RenderWidget(
pGS, matrix,
bHighlight ? CXFA_FFWidget::kHighlight : CXFA_FFWidget::kNoHighlight);
}
bool CXFA_FFWidgetHandler::HasEvent(CXFA_Node* pNode,
XFA_EVENTTYPE eEventType) {
if (eEventType == XFA_EVENT_Unknown)
return false;
if (!pNode || pNode->GetElementType() == XFA_Element::Draw)
return false;
switch (eEventType) {
case XFA_EVENT_Calculate: {
CXFA_Calculate* calc = pNode->GetCalculateIfExists();
return calc && calc->GetScriptIfExists();
}
case XFA_EVENT_Validate: {
CXFA_Validate* validate = pNode->GetValidateIfExists();
return validate && validate->GetScriptIfExists();
}
default:
break;
}
return !pNode->GetEventByActivity(kXFAEventActivity[eEventType], false)
.empty();
}
XFA_EventError CXFA_FFWidgetHandler::ProcessEvent(CXFA_Node* pNode,
CXFA_EventParam* pParam) {
if (!pParam || pParam->m_eType == XFA_EVENT_Unknown)
return XFA_EventError::kNotExist;
if (!pNode || pNode->GetElementType() == XFA_Element::Draw)
return XFA_EventError::kNotExist;
switch (pParam->m_eType) {
case XFA_EVENT_Calculate:
return pNode->ProcessCalculate(m_pDocView.Get());
case XFA_EVENT_Validate:
if (m_pDocView->GetDoc()->IsValidationsEnabled())
return pNode->ProcessValidate(m_pDocView.Get(), 0);
return XFA_EventError::kDisabled;
case XFA_EVENT_InitCalculate: {
CXFA_Calculate* calc = pNode->GetCalculateIfExists();
if (!calc)
return XFA_EventError::kNotExist;
if (pNode->IsUserInteractive())
return XFA_EventError::kDisabled;
return pNode->ExecuteScript(m_pDocView.Get(), calc->GetScriptIfExists(),
pParam);
}
default:
break;
}
return pNode->ProcessEvent(m_pDocView.Get(),
kXFAEventActivity[pParam->m_eType], pParam);
}