blob: 022e9947464f061eb09bc0400aa8ea9bc7e6580a [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)
: doc_view_(pDocView) {}
CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() = default;
void CXFA_FFWidgetHandler::Trace(cppgc::Visitor* visitor) const {
visitor->Trace(doc_view_);
}
bool CXFA_FFWidgetHandler::OnMouseEnter(CXFA_FFWidget* hWidget) {
CXFA_FFDocView::UpdateScope scope(doc_view_);
return hWidget->OnMouseEnter();
}
bool CXFA_FFWidgetHandler::OnMouseExit(CXFA_FFWidget* hWidget) {
CXFA_FFDocView::UpdateScope scope(doc_view_);
return hWidget->OnMouseExit();
}
bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget,
Mask<XFA_FWL_KeyFlag> dwFlags,
const CFX_PointF& point) {
CXFA_FFDocView::UpdateScope scope(doc_view_);
if (!hWidget->AcceptsFocusOnButtonDown(
dwFlags, hWidget->Rotate2Normal(point),
CFWL_MessageMouse::MouseCommand::kLeftButtonDown)) {
return false;
}
// May re-enter JS.
if (doc_view_->SetFocus(hWidget)) {
doc_view_->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(doc_view_);
doc_view_->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 (doc_view_->SetFocus(hWidget)) {
doc_view_->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);
doc_view_->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->type_ == XFA_EVENT_Unknown) {
return XFA_EventError::kNotExist;
}
if (!pNode || pNode->GetElementType() == XFA_Element::Draw)
return XFA_EventError::kNotExist;
switch (pParam->type_) {
case XFA_EVENT_Calculate:
return pNode->ProcessCalculate(doc_view_.Get());
case XFA_EVENT_Validate:
if (doc_view_->GetDoc()->IsValidationsEnabled()) {
return pNode->ProcessValidate(doc_view_.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(doc_view_.Get(), calc->GetScriptIfExists(),
pParam);
}
default:
break;
}
return pNode->ProcessEvent(doc_view_.Get(), kXFAEventActivity[pParam->type_],
pParam);
}