Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1313)

Side by Side Diff: pdf/pdfium/pdfium_engine.cc

Issue 2963753003: Fix discrepancies in form text selection between PDF and HTML forms. (Closed)
Patch Set: Initialize in_form_text_area_ and mouse_left_button_down_ + change comment in SetFormSelectedText Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pdf/pdfium/pdfium_engine.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "pdf/pdfium/pdfium_engine.h" 5 #include "pdf/pdfium/pdfium_engine.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 current_zoom_(1.0), 675 current_zoom_(1.0),
676 current_rotation_(0), 676 current_rotation_(0),
677 doc_loader_(this), 677 doc_loader_(this),
678 password_tries_remaining_(0), 678 password_tries_remaining_(0),
679 doc_(nullptr), 679 doc_(nullptr),
680 form_(nullptr), 680 form_(nullptr),
681 defer_page_unload_(false), 681 defer_page_unload_(false),
682 selecting_(false), 682 selecting_(false),
683 mouse_down_state_(PDFiumPage::NONSELECTABLE_AREA, 683 mouse_down_state_(PDFiumPage::NONSELECTABLE_AREA,
684 PDFiumPage::LinkTarget()), 684 PDFiumPage::LinkTarget()),
685 in_form_text_area_(false),
686 mouse_left_button_down_(false),
685 next_page_to_search_(-1), 687 next_page_to_search_(-1),
686 last_page_to_search_(-1), 688 last_page_to_search_(-1),
687 last_character_index_to_search_(-1), 689 last_character_index_to_search_(-1),
688 permissions_(0), 690 permissions_(0),
689 permissions_handler_revision_(-1), 691 permissions_handler_revision_(-1),
690 fpdf_availability_(nullptr), 692 fpdf_availability_(nullptr),
691 next_formfill_timer_id_(0), 693 next_formfill_timer_id_(0),
692 next_touch_timer_id_(0), 694 next_touch_timer_id_(0),
693 last_page_mouse_down_(-1), 695 last_page_mouse_down_(-1),
694 most_visible_page_(-1), 696 most_visible_page_(-1),
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 void PDFiumEngine::SaveSelectedFormForPrint() { 1630 void PDFiumEngine::SaveSelectedFormForPrint() {
1629 FORM_ForceToKillFocus(form_); 1631 FORM_ForceToKillFocus(form_);
1630 SetInFormTextArea(false); 1632 SetInFormTextArea(false);
1631 } 1633 }
1632 1634
1633 void PDFiumEngine::SetFormSelectedText(FPDF_FORMHANDLE form_handle, 1635 void PDFiumEngine::SetFormSelectedText(FPDF_FORMHANDLE form_handle,
1634 FPDF_PAGE page) { 1636 FPDF_PAGE page) {
1635 unsigned long form_sel_text_len = 1637 unsigned long form_sel_text_len =
1636 FORM_GetSelectedText(form_handle, page, nullptr, 0); 1638 FORM_GetSelectedText(form_handle, page, nullptr, 0);
1637 1639
1638 // Check to see if there is selected text in the form. When 1640 // If form selected text is empty and there was no previous form text
1639 // |form_sel_text_len| is 2, that represents a wide string with just a 1641 // selection, exit early because nothing has changed. When |form_sel_text_len|
1640 // NUL-terminator. 1642 // is 2, that represents a wide string with just a NUL-terminator.
1641 if (form_sel_text_len <= 2) 1643 if (form_sel_text_len <= 2 && selected_form_text_.empty())
1642 return; 1644 return;
1643 1645
1644 base::string16 selected_form_text16; 1646 base::string16 selected_form_text16;
1645 PDFiumAPIStringBufferSizeInBytesAdapter<base::string16> string_adapter( 1647 PDFiumAPIStringBufferSizeInBytesAdapter<base::string16> string_adapter(
1646 &selected_form_text16, form_sel_text_len, false); 1648 &selected_form_text16, form_sel_text_len, false);
1647 string_adapter.Close(FORM_GetSelectedText( 1649 string_adapter.Close(FORM_GetSelectedText(
1648 form_handle, page, string_adapter.GetData(), form_sel_text_len)); 1650 form_handle, page, string_adapter.GetData(), form_sel_text_len));
1649 1651
1650 std::string selected_form_text = base::UTF16ToUTF8(selected_form_text16); 1652 // Update previous and current selections, then compare them to check if
1651 if (!selected_form_text.empty()) { 1653 // selection has changed. If so, set plugin text selection.
1652 pp::PDF::SetSelectedText(GetPluginInstance(), selected_form_text.c_str()); 1654 std::string selected_form_text = selected_form_text_;
1653 } 1655 selected_form_text_ = base::UTF16ToUTF8(selected_form_text16);
1656 if (selected_form_text != selected_form_text_)
1657 pp::PDF::SetSelectedText(GetPluginInstance(), selected_form_text_.c_str());
1654 } 1658 }
1655 1659
1656 void PDFiumEngine::PrintEnd() { 1660 void PDFiumEngine::PrintEnd() {
1657 FORM_DoDocumentAAction(form_, FPDFDOC_AACTION_DP); 1661 FORM_DoDocumentAAction(form_, FPDFDOC_AACTION_DP);
1658 } 1662 }
1659 1663
1660 PDFiumPage::Area PDFiumEngine::GetCharIndex(const pp::MouseInputEvent& event, 1664 PDFiumPage::Area PDFiumEngine::GetCharIndex(const pp::MouseInputEvent& event,
1661 int* page_index, 1665 int* page_index,
1662 int* char_index, 1666 int* char_index,
1663 int* form_type, 1667 int* form_type,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1712 SelectionChangeInvalidator selection_invalidator(this); 1716 SelectionChangeInvalidator selection_invalidator(this);
1713 selection_.clear(); 1717 selection_.clear();
1714 return true; 1718 return true;
1715 } 1719 }
1716 1720
1717 if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT && 1721 if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT &&
1718 event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) { 1722 event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) {
1719 return false; 1723 return false;
1720 } 1724 }
1721 1725
1726 SetMouseLeftButtonDown(event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT);
1727
1722 SelectionChangeInvalidator selection_invalidator(this); 1728 SelectionChangeInvalidator selection_invalidator(this);
1723 selection_.clear(); 1729 selection_.clear();
1724 1730
1725 int page_index = -1; 1731 int page_index = -1;
1726 int char_index = -1; 1732 int char_index = -1;
1727 int form_type = FPDF_FORMFIELD_UNKNOWN; 1733 int form_type = FPDF_FORMFIELD_UNKNOWN;
1728 PDFiumPage::LinkTarget target; 1734 PDFiumPage::LinkTarget target;
1729 PDFiumPage::Area area = 1735 PDFiumPage::Area area =
1730 GetCharIndex(event, &page_index, &char_index, &form_type, &target); 1736 GetCharIndex(event, &page_index, &char_index, &form_type, &target);
1731 mouse_down_state_.Set(area, target); 1737 mouse_down_state_.Set(area, target);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 selection_.push_back(PDFiumRange(pages_[page_index].get(), start_index, 1813 selection_.push_back(PDFiumRange(pages_[page_index].get(), start_index,
1808 end_index - start_index)); 1814 end_index - start_index));
1809 } 1815 }
1810 1816
1811 bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) { 1817 bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) {
1812 if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT && 1818 if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT &&
1813 event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) { 1819 event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) {
1814 return false; 1820 return false;
1815 } 1821 }
1816 1822
1823 if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT)
1824 SetMouseLeftButtonDown(false);
1825
1817 int page_index = -1; 1826 int page_index = -1;
1818 int char_index = -1; 1827 int char_index = -1;
1819 int form_type = FPDF_FORMFIELD_UNKNOWN; 1828 int form_type = FPDF_FORMFIELD_UNKNOWN;
1820 PDFiumPage::LinkTarget target; 1829 PDFiumPage::LinkTarget target;
1821 PDFiumPage::Area area = 1830 PDFiumPage::Area area =
1822 GetCharIndex(event, &page_index, &char_index, &form_type, &target); 1831 GetCharIndex(event, &page_index, &char_index, &form_type, &target);
1823 1832
1824 // Open link on mouse up for same link for which mouse down happened earlier. 1833 // Open link on mouse up for same link for which mouse down happened earlier.
1825 if (mouse_down_state_.Matches(area, target)) { 1834 if (mouse_down_state_.Matches(area, target)) {
1826 if (area == PDFiumPage::WEBLINK_AREA) { 1835 if (area == PDFiumPage::WEBLINK_AREA) {
(...skipping 23 matching lines...) Expand all
1850 if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) 1859 if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_MIDDLE)
1851 return false; 1860 return false;
1852 1861
1853 if (page_index != -1) { 1862 if (page_index != -1) {
1854 double page_x, page_y; 1863 double page_x, page_y;
1855 pp::Point point = event.GetPosition(); 1864 pp::Point point = event.GetPosition();
1856 DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y); 1865 DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y);
1857 FORM_OnLButtonUp(form_, pages_[page_index]->GetPage(), 0, page_x, page_y); 1866 FORM_OnLButtonUp(form_, pages_[page_index]->GetPage(), 0, page_x, page_y);
1858 } 1867 }
1859 1868
1860 if (area == PDFiumPage::FORM_TEXT_AREA && last_page_mouse_down_ != -1)
1861 SetFormSelectedText(form_, pages_[last_page_mouse_down_]->GetPage());
1862
1863 if (!selecting_) 1869 if (!selecting_)
1864 return false; 1870 return false;
1865 1871
1866 SetSelecting(false); 1872 SetSelecting(false);
1867 return true; 1873 return true;
1868 } 1874 }
1869 1875
1870 bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) { 1876 bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) {
1871 int page_index = -1; 1877 int page_index = -1;
1872 int char_index = -1; 1878 int char_index = -1;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1917 DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y); 1923 DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y);
1918 FORM_OnMouseMove(form_, pages_[page_index]->GetPage(), 0, page_x, page_y); 1924 FORM_OnMouseMove(form_, pages_[page_index]->GetPage(), 0, page_x, page_y);
1919 } 1925 }
1920 1926
1921 client_->UpdateCursor(cursor); 1927 client_->UpdateCursor(cursor);
1922 std::string url = GetLinkAtPosition(event.GetPosition()); 1928 std::string url = GetLinkAtPosition(event.GetPosition());
1923 if (url != link_under_cursor_) { 1929 if (url != link_under_cursor_) {
1924 link_under_cursor_ = url; 1930 link_under_cursor_ = url;
1925 pp::PDF::SetLinkUnderCursor(GetPluginInstance(), url.c_str()); 1931 pp::PDF::SetLinkUnderCursor(GetPluginInstance(), url.c_str());
1926 } 1932 }
1933
1934 // If in form text area while left mouse button is held down, check if form
1935 // text selection needs to be updated.
1936 if (mouse_left_button_down_ && area == PDFiumPage::FORM_TEXT_AREA &&
1937 last_page_mouse_down_ != -1) {
1938 SetFormSelectedText(form_, pages_[last_page_mouse_down_]->GetPage());
1939 }
1940
1927 // No need to swallow the event, since this might interfere with the 1941 // No need to swallow the event, since this might interfere with the
1928 // scrollbars if the user is dragging them. 1942 // scrollbars if the user is dragging them.
1929 return false; 1943 return false;
1930 } 1944 }
1931 1945
1932 // We're selecting but right now we're not over text, so don't change the 1946 // We're selecting but right now we're not over text, so don't change the
1933 // current selection. 1947 // current selection.
1934 if (area != PDFiumPage::TEXT_AREA && area != PDFiumPage::WEBLINK_AREA && 1948 if (area != PDFiumPage::TEXT_AREA && area != PDFiumPage::WEBLINK_AREA &&
1935 area != PDFiumPage::DOCLINK_AREA) { 1949 area != PDFiumPage::DOCLINK_AREA) {
1936 return false; 1950 return false;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2011 // http://chrome-corpsvn.mtv.corp.google.com/viewvc?view=rev&root=chrome&rev ision=31805 2025 // http://chrome-corpsvn.mtv.corp.google.com/viewvc?view=rev&root=chrome&rev ision=31805
2012 // for more information. So just fake one since PDFium uses it. 2026 // for more information. So just fake one since PDFium uses it.
2013 std::string str; 2027 std::string str;
2014 str.push_back(event.GetKeyCode()); 2028 str.push_back(event.GetKeyCode());
2015 pp::KeyboardInputEvent synthesized(pp::KeyboardInputEvent( 2029 pp::KeyboardInputEvent synthesized(pp::KeyboardInputEvent(
2016 client_->GetPluginInstance(), PP_INPUTEVENT_TYPE_CHAR, 2030 client_->GetPluginInstance(), PP_INPUTEVENT_TYPE_CHAR,
2017 event.GetTimeStamp(), event.GetModifiers(), event.GetKeyCode(), str)); 2031 event.GetTimeStamp(), event.GetModifiers(), event.GetKeyCode(), str));
2018 OnChar(synthesized); 2032 OnChar(synthesized);
2019 } 2033 }
2020 2034
2021 // If form selected text is empty and key pressed within form text area,
2022 // plugin text selection should be cleared.
2023 if (in_form_text_area_ &&
2024 FORM_GetSelectedText(form_, pages_[last_page_mouse_down_]->GetPage(),
2025 nullptr, 0) <= 2) {
2026 pp::PDF::SetSelectedText(GetPluginInstance(), "");
2027 }
2028
2029 return rv; 2035 return rv;
2030 } 2036 }
2031 2037
2032 bool PDFiumEngine::OnKeyUp(const pp::KeyboardInputEvent& event) { 2038 bool PDFiumEngine::OnKeyUp(const pp::KeyboardInputEvent& event) {
2033 if (last_page_mouse_down_ == -1) 2039 if (last_page_mouse_down_ == -1)
2034 return false; 2040 return false;
2035 2041
2042 // Check if form text selection needs to be updated.
2036 if (in_form_text_area_) { 2043 if (in_form_text_area_) {
2037 if (event.GetKeyCode() == ui::VKEY_SHIFT) 2044 SetFormSelectedText(form_, pages_[last_page_mouse_down_]->GetPage());
2038 SetFormSelectedText(form_, pages_[last_page_mouse_down_]->GetPage());
2039 } 2045 }
2040 2046
2041 return !!FORM_OnKeyUp(form_, pages_[last_page_mouse_down_]->GetPage(), 2047 return !!FORM_OnKeyUp(form_, pages_[last_page_mouse_down_]->GetPage(),
2042 event.GetKeyCode(), event.GetModifiers()); 2048 event.GetKeyCode(), event.GetModifiers());
2043 } 2049 }
2044 2050
2045 bool PDFiumEngine::OnChar(const pp::KeyboardInputEvent& event) { 2051 bool PDFiumEngine::OnChar(const pp::KeyboardInputEvent& event) {
2046 if (last_page_mouse_down_ == -1) 2052 if (last_page_mouse_down_ == -1)
2047 return false; 2053 return false;
2048 2054
(...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after
3609 selecting_ = selecting; 3615 selecting_ = selecting;
3610 if (selecting_ != was_selecting) 3616 if (selecting_ != was_selecting)
3611 client_->IsSelectingChanged(selecting); 3617 client_->IsSelectingChanged(selecting);
3612 } 3618 }
3613 3619
3614 void PDFiumEngine::SetInFormTextArea(bool in_form_text_area) { 3620 void PDFiumEngine::SetInFormTextArea(bool in_form_text_area) {
3615 client_->FormTextFieldFocusChange(in_form_text_area); 3621 client_->FormTextFieldFocusChange(in_form_text_area);
3616 in_form_text_area_ = in_form_text_area; 3622 in_form_text_area_ = in_form_text_area;
3617 } 3623 }
3618 3624
3625 void PDFiumEngine::SetMouseLeftButtonDown(bool is_mouse_left_button_down) {
3626 mouse_left_button_down_ = is_mouse_left_button_down;
3627 }
3628
3619 void PDFiumEngine::ScheduleTouchTimer(const pp::TouchInputEvent& evt) { 3629 void PDFiumEngine::ScheduleTouchTimer(const pp::TouchInputEvent& evt) {
3620 touch_timers_[++next_touch_timer_id_] = evt; 3630 touch_timers_[++next_touch_timer_id_] = evt;
3621 client_->ScheduleTouchTimerCallback(next_touch_timer_id_, 3631 client_->ScheduleTouchTimerCallback(next_touch_timer_id_,
3622 kTouchLongPressTimeoutMs); 3632 kTouchLongPressTimeoutMs);
3623 } 3633 }
3624 3634
3625 void PDFiumEngine::KillTouchTimer(int timer_id) { 3635 void PDFiumEngine::KillTouchTimer(int timer_id) {
3626 touch_timers_.erase(timer_id); 3636 touch_timers_.erase(timer_id);
3627 } 3637 }
3628 3638
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
4198 FPDF_DOCUMENT doc = 4208 FPDF_DOCUMENT doc =
4199 FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, nullptr); 4209 FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, nullptr);
4200 if (!doc) 4210 if (!doc)
4201 return false; 4211 return false;
4202 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0; 4212 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0;
4203 FPDF_CloseDocument(doc); 4213 FPDF_CloseDocument(doc);
4204 return success; 4214 return success;
4205 } 4215 }
4206 4216
4207 } // namespace chrome_pdf 4217 } // namespace chrome_pdf
OLDNEW
« no previous file with comments | « pdf/pdfium/pdfium_engine.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698