Fcitx
surroundingtext.cpp
1 /*
2  * SPDX-FileCopyrightText: 2016-2016 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 
8 #include "surroundingtext.h"
9 #include "fcitx-utils/macros.h"
10 #include "fcitx-utils/utf8.h"
11 
12 namespace fcitx {
13 
15 public:
17 
18  unsigned int anchor_ = 0, cursor_ = 0;
19  std::string text_;
20  size_t utf8Length_ = 0;
21 
22  bool valid_ = false;
23 };
24 
25 SurroundingText::SurroundingText()
26  : d_ptr(std::make_unique<SurroundingTextPrivate>()) {}
27 
28 FCITX_DEFINE_DPTR_COPY_AND_DEFAULT_DTOR_AND_MOVE(SurroundingText)
29 
30 bool SurroundingText::isValid() const {
31  FCITX_D();
32  return d->valid_;
33 }
34 
36  FCITX_D();
37  d->valid_ = false;
38  d->anchor_ = 0;
39  d->cursor_ = 0;
40  d->text_ = std::string();
41  d->utf8Length_ = 0;
42 }
43 
44 const std::string &SurroundingText::text() const {
45  FCITX_D();
46  return d->text_;
47 }
48 
49 unsigned int SurroundingText::anchor() const {
50  FCITX_D();
51  return d->anchor_;
52 }
53 
54 unsigned int SurroundingText::cursor() const {
55  FCITX_D();
56  return d->cursor_;
57 }
58 
59 std::string SurroundingText::selectedText() const {
60  FCITX_D();
61  auto start = std::min(anchor(), cursor());
62  auto end = std::max(anchor(), cursor());
63  auto len = end - start;
64  if (len == 0) {
65  return {};
66  }
67 
68  auto startIter = utf8::nextNChar(d->text_.begin(), start);
69  auto endIter = utf8::nextNChar(startIter, len);
70  return std::string(startIter, endIter);
71 }
72 
73 void SurroundingText::setText(const std::string &text, unsigned int cursor,
74  unsigned int anchor) {
75  FCITX_D();
76  auto length = utf8::lengthValidated(text);
77  if (length == utf8::INVALID_LENGTH || length < cursor || length < anchor) {
78  invalidate();
79  return;
80  }
81 
82  d->valid_ = true;
83  d->text_ = text;
84  d->cursor_ = cursor;
85  d->anchor_ = anchor;
86  d->utf8Length_ = length;
87 }
88 
89 void SurroundingText::setCursor(unsigned int cursor, unsigned int anchor) {
90  FCITX_D();
91  if (d->utf8Length_ < cursor || d->utf8Length_ < anchor) {
92  invalidate();
93  return;
94  }
95  d->cursor_ = cursor;
96  d->anchor_ = anchor;
97 }
98 
99 void SurroundingText::deleteText(int offset, unsigned int size) {
100  FCITX_D();
101  if (!d->valid_) {
102  return;
103  }
104 
105  /*
106  * do the real deletion here, and client might update it, but input method
107  * itself
108  * would expect a up to date value after this call.
109  *
110  * Make their life easier.
111  */
112  int cursor_pos = d->cursor_ + offset;
113  size_t len = utf8::length(d->text_);
114  if (cursor_pos >= 0 && len >= size + cursor_pos) {
115  auto start = utf8::nextNChar(d->text_.begin(), cursor_pos);
116  auto end = utf8::nextNChar(start, size);
117  d->text_.erase(start, end);
118  d->cursor_ = cursor_pos;
119  d->utf8Length_ = utf8::lengthValidated(d->text_);
120  if (d->utf8Length_ == utf8::INVALID_LENGTH) {
121  invalidate();
122  }
123  } else {
124  d->text_.clear();
125  d->cursor_ = 0;
126  d->utf8Length_ = 0;
127  }
128  d->anchor_ = d->cursor_;
129 }
130 
131 LogMessageBuilder &operator<<(LogMessageBuilder &log,
132  const SurroundingText &surroundingText) {
133  log << "SurroundingText(text=";
134  log << surroundingText.text();
135  log << ",anchor=" << surroundingText.anchor();
136  log << ",cursor=" << surroundingText.cursor();
137  log << ")";
138  return log;
139 }
140 
141 } // namespace fcitx
void setText(const std::string &text, unsigned int cursor, unsigned int anchor)
Set current of surrounding text.
unsigned int anchor() const
offset of anchor in character.
size_t length(Iter start, Iter end)
Return the number UTF-8 characters in the string iterator range.
Definition: utf8.h:33
Definition: action.cpp:17
C++ Utility functions for handling utf8 strings.
unsigned int cursor() const
offset of anchor in character.
Local cache for surrounding text.
Iter nextNChar(Iter iter, size_t n)
Move iter over next n character.
Definition: utf8.h:135
void setCursor(unsigned int cursor, unsigned int anchor)
Set current cursor and anchor of surrounding text.
Class represents the current state of surrounding text of an input context.
size_t lengthValidated(Iter start, Iter end)
Validate and return the number UTF-8 characters in the string iterator range.
Definition: utf8.h:60
constexpr size_t INVALID_LENGTH
Possible return value of lengthValidated if the string is not valid.
Definition: utf8.h:53
void invalidate()
Reset surrounding text to invalid state.
void deleteText(int offset, unsigned int size)
Delete surrounding text with offset and size.