Update from the upstream.
* Increased the build number to 4180 (2.25.4180).
* Code refactoring.
Hiroyuki Komatsu
3 years ago
53 | 53 | ClockImpl() : timezone_offset_sec_(0) {} |
54 | 54 | #endif // OS_NACL |
55 | 55 | |
56 | virtual ~ClockImpl() {} | |
56 | ~ClockImpl() override {} | |
57 | 57 | |
58 | virtual void GetTimeOfDay(uint64 *sec, uint32 *usec) { | |
58 | void GetTimeOfDay(uint64 *sec, uint32 *usec) override { | |
59 | 59 | #ifdef OS_WIN |
60 | 60 | FILETIME file_time; |
61 | 61 | GetSystemTimeAsFileTime(&file_time); |
82 | 82 | #endif // OS_WIN |
83 | 83 | } |
84 | 84 | |
85 | virtual uint64 GetTime() { | |
85 | uint64 GetTime() override { | |
86 | 86 | #ifdef OS_WIN |
87 | 87 | return static_cast<uint64>(_time64(nullptr)); |
88 | 88 | #else |
90 | 90 | #endif // OS_WIN |
91 | 91 | } |
92 | 92 | |
93 | virtual bool GetTmWithOffsetSecond(time_t offset_sec, tm *output) { | |
93 | bool GetTmWithOffsetSecond(time_t offset_sec, tm *output) override { | |
94 | 94 | const time_t current_sec = static_cast<time_t>(this->GetTime()); |
95 | 95 | const time_t modified_sec = current_sec + offset_sec; |
96 | 96 | |
111 | 111 | return true; |
112 | 112 | } |
113 | 113 | |
114 | virtual uint64 GetFrequency() { | |
114 | uint64 GetFrequency() override { | |
115 | 115 | #if defined(OS_WIN) |
116 | 116 | LARGE_INTEGER timestamp; |
117 | 117 | // TODO(yukawa): Consider the case where QueryPerformanceCounter is not |
131 | 131 | #endif // platforms (OS_WIN, __APPLE__, OS_LINUX, ...) |
132 | 132 | } |
133 | 133 | |
134 | virtual uint64 GetTicks() { | |
134 | uint64 GetTicks() override { | |
135 | 135 | // TODO(team): Use functions in <chrono> once the use of it is approved. |
136 | 136 | #if defined(OS_WIN) |
137 | 137 | LARGE_INTEGER timestamp; |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | 29 | #include "base/clock_mock.h" |
30 | ||
30 | 31 | #include "base/util.h" |
31 | 32 | #include "testing/base/public/googletest.h" |
32 | 33 | #include "testing/base/public/gunit.h" |
46 | 46 | |
47 | 47 | class CodeGenByteArrayStreamTest : public testing::Test { |
48 | 48 | protected: |
49 | virtual void SetUp() { | |
49 | void SetUp() override { | |
50 | 50 | result_stream_.reset(new std::ostringstream()); |
51 | 51 | codegen_stream_.reset(new mozc::CodeGenByteArrayOutputStream( |
52 | 52 | result_stream_.get(), mozc::codegenstream::NOT_OWN_STREAM)); |
53 | 53 | } |
54 | 54 | |
55 | virtual void TearDown() { | |
55 | void TearDown() override { | |
56 | 56 | codegen_stream_.reset(); |
57 | 57 | result_stream_.reset(); |
58 | 58 | } |
35 | 35 | #include <cstring> |
36 | 36 | #include <map> |
37 | 37 | #include <sstream> |
38 | ||
38 | 39 | #include "base/file_stream.h" |
39 | 40 | #include "base/file_util.h" |
40 | 41 | #include "base/logging.h" |
26 | 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | #include "base/config_file_stream.h" | |
30 | ||
29 | 31 | #include <cstddef> |
30 | 32 | #include <ios> |
31 | 33 | #include <istream> |
32 | 34 | #include <memory> |
33 | 35 | |
34 | #include "base/config_file_stream.h" | |
35 | 36 | #include "base/file_util.h" |
36 | 37 | #include "base/system_util.h" |
37 | 38 | #include "testing/base/public/googletest.h" |
69 | 70 | |
70 | 71 | class ConfigFileStreamTest : public testing::Test { |
71 | 72 | protected: |
72 | virtual void SetUp() { | |
73 | void SetUp() override { | |
73 | 74 | default_profile_directory_ = SystemUtil::GetUserProfileDirectory(); |
74 | 75 | SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir); |
75 | 76 | } |
76 | 77 | |
77 | virtual void TearDown() { | |
78 | void TearDown() override { | |
78 | 79 | SystemUtil::SetUserProfileDirectory(default_profile_directory_); |
79 | 80 | } |
80 | 81 | |
206 | 207 | ASSERT_NE(nullptr, ifs.get()); |
207 | 208 | std::string line; |
208 | 209 | int line_number = 0; // note that this is 1-origin. |
209 | while (!getline(*ifs.get(), line).fail()) { | |
210 | while (!std::getline(*ifs, line).fail()) { | |
210 | 211 | ++line_number; |
211 | 212 | ASSERT_LE(line_number, arraysize(kExpectedLines)); |
212 | 213 | EXPECT_EQ(line, kExpectedLines[line_number - 1]) |
59 | 59 | class CPUStats : public CPUStatsInterface { |
60 | 60 | public: |
61 | 61 | CPUStats(); |
62 | virtual ~CPUStats(); | |
62 | ~CPUStats() override; | |
63 | 63 | |
64 | 64 | // return 0.0 if CPU load is unknown |
65 | float GetSystemCPULoad(); | |
65 | float GetSystemCPULoad() override; | |
66 | 66 | |
67 | 67 | // return 0.0 if CPU load is unknown |
68 | float GetCurrentProcessCPULoad(); | |
68 | float GetCurrentProcessCPULoad() override; | |
69 | 69 | |
70 | 70 | // return the number of processors |
71 | size_t GetNumberOfProcessors() const; | |
71 | size_t GetNumberOfProcessors() const override; | |
72 | 72 | |
73 | 73 | private: |
74 | 74 | uint64 prev_system_total_times_; |
45 | 45 | class DummyThread : public mozc::Thread { |
46 | 46 | public: |
47 | 47 | DummyThread() {} |
48 | void Run() { | |
48 | void Run() override { | |
49 | 49 | volatile uint64 n = 0; |
50 | 50 | while (true) { |
51 | 51 | ++n; |
26 | 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | #include "base/encryptor.h" | |
30 | ||
29 | 31 | #include <memory> |
30 | 32 | |
31 | #include "base/encryptor.h" | |
32 | 33 | #include "base/password_manager.h" |
33 | 34 | #include "base/system_util.h" |
34 | 35 | #include "base/util.h" |
304 | 304 | InputFileStream ifs(to.c_str()); |
305 | 305 | EXPECT_TRUE(ifs.good()); |
306 | 306 | std::string line; |
307 | getline(ifs, line); | |
307 | std::getline(ifs, line); | |
308 | 308 | EXPECT_EQ("test", line); |
309 | 309 | } |
310 | 310 |
50 | 50 | |
51 | 51 | class FlagsTest : public testing::Test { |
52 | 52 | protected: |
53 | void SetUp() { | |
53 | void SetUp() override { | |
54 | 54 | FLAGS_test_string = "hogehoge"; |
55 | 55 | FLAGS_test_int32 = 20; |
56 | 56 | FLAGS_test_int64 = 29051773239673121LL; |
255 | 255 | prot |= PROT_WRITE; |
256 | 256 | } |
257 | 257 | |
258 | void *ptr = mmap(0, st.st_size, prot, MAP_SHARED, fd, 0); | |
258 | void *ptr = mmap(nullptr, st.st_size, prot, MAP_SHARED, fd, 0); | |
259 | 259 | if (ptr == MAP_FAILED) { |
260 | 260 | LOG(WARNING) << "mmap() failed: " << filename; |
261 | 261 | return false; |
48 | 48 | #endif // OS_NACL |
49 | 49 | |
50 | 50 | Mmap(); |
51 | virtual ~Mmap() { Close(); } | |
51 | ~Mmap() override { Close(); } | |
52 | 52 | |
53 | 53 | bool Open(const char *filename, const char *mode = "r"); |
54 | 54 | void Close(); |
48 | 48 | InputMultiFile::~InputMultiFile() { ifs_.reset(); } |
49 | 49 | |
50 | 50 | bool InputMultiFile::ReadLine(std::string *line) { |
51 | if (ifs_.get() == nullptr) { | |
51 | if (ifs_ == nullptr) { | |
52 | 52 | return false; |
53 | 53 | } |
54 | 54 | do { |
55 | if (!getline(*ifs_, *line).fail()) { | |
55 | if (!std::getline(*ifs_, *line).fail()) { | |
56 | 56 | return true; |
57 | 57 | } |
58 | 58 | } while (OpenNext()); |
159 | 159 | // PlainPasswordManager |
160 | 160 | class PlainPasswordManager : public PasswordManagerInterface { |
161 | 161 | public: |
162 | virtual bool SetPassword(const std::string &password) const; | |
163 | virtual bool GetPassword(std::string *password) const; | |
164 | virtual bool RemovePassword() const; | |
162 | bool SetPassword(const std::string &password) const override; | |
163 | bool GetPassword(std::string *password) const override; | |
164 | bool RemovePassword() const override; | |
165 | 165 | }; |
166 | 166 | |
167 | 167 | bool PlainPasswordManager::SetPassword(const std::string &password) const { |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | 29 | #include "base/password_manager.h" |
30 | ||
30 | 31 | #include "base/system_util.h" |
31 | 32 | #include "testing/base/public/googletest.h" |
32 | 33 | #include "testing/base/public/gunit.h" |
33 | 33 | #else |
34 | 34 | #include <string.h> |
35 | 35 | #include <sys/stat.h> |
36 | ||
36 | 37 | #include <cerrno> |
37 | 38 | #endif // OS_WIN |
38 | 39 | |
40 | 41 | #include <fcntl.h> |
41 | 42 | #include <signal.h> |
42 | 43 | #include <spawn.h> // for posix_spawn(). |
44 | ||
43 | 45 | #include "base/mac_process.h" |
44 | 46 | #endif // __APPLE__ |
45 | 47 |
30 | 30 | |
31 | 31 | #ifndef OS_WIN |
32 | 32 | #include <unistd.h> |
33 | ||
33 | 34 | #include <cstdlib> |
34 | 35 | #endif // OS_WIN |
35 | 36 | |
46 | 47 | |
47 | 48 | class ProcessMutexTest : public testing::Test { |
48 | 49 | protected: |
49 | virtual void SetUp() { | |
50 | void SetUp() override { | |
50 | 51 | original_user_profile_dir_ = SystemUtil::GetUserProfileDirectory(); |
51 | 52 | SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir); |
52 | 53 | } |
53 | 54 | |
54 | virtual void TearDown() { | |
55 | void TearDown() override { | |
55 | 56 | ProcessMutex mutex(kName); |
56 | 57 | if (FileUtil::FileExists(mutex.lock_filename())) { |
57 | 58 | LOG(FATAL) << "Lock file unexpectedly remains: " << mutex.lock_filename(); |
171 | 171 | Util::SetRandomSeed(static_cast<uint32>(Clock::GetTime())); |
172 | 172 | } |
173 | 173 | |
174 | virtual ~SchedulerImpl() { RemoveAllJobs(); } | |
175 | ||
176 | virtual void RemoveAllJobs() { | |
174 | ~SchedulerImpl() override { RemoveAllJobs(); } | |
175 | ||
176 | void RemoveAllJobs() override { | |
177 | 177 | scoped_lock l(&mutex_); |
178 | 178 | jobs_.clear(); |
179 | 179 | } |
186 | 186 | DCHECK(job_setting.callback() != nullptr); |
187 | 187 | } |
188 | 188 | |
189 | virtual bool AddJob(const Scheduler::JobSetting &job_setting) { | |
189 | bool AddJob(const Scheduler::JobSetting &job_setting) override { | |
190 | 190 | scoped_lock l(&mutex_); |
191 | 191 | |
192 | 192 | ValidateSetting(job_setting); |
217 | 217 | return true; |
218 | 218 | } |
219 | 219 | |
220 | virtual bool RemoveJob(const std::string &name) { | |
220 | bool RemoveJob(const std::string &name) override { | |
221 | 221 | scoped_lock l(&mutex_); |
222 | 222 | if (!HasJob(name)) { |
223 | 223 | LOG(WARNING) << "Job " << name << " is not registered"; |
226 | 226 | return (jobs_.erase(name) != 0); |
227 | 227 | } |
228 | 228 | |
229 | virtual bool HasJob(const std::string &name) const { | |
229 | bool HasJob(const std::string &name) const override { | |
230 | 230 | return (jobs_.find(name) != jobs_.end()); |
231 | 231 | } |
232 | 232 |
52 | 52 | class SchedulerStub : public Scheduler::SchedulerInterface { |
53 | 53 | public: |
54 | 54 | SchedulerStub(); |
55 | virtual ~SchedulerStub(); | |
55 | ~SchedulerStub() override; | |
56 | 56 | |
57 | 57 | // |random_delay| will be ignored. |
58 | virtual bool AddJob(const Scheduler::JobSetting &job_setting); | |
59 | virtual bool RemoveJob(const std::string &name); | |
60 | virtual void RemoveAllJobs(); | |
61 | virtual bool HasJob(const std::string &name) const; | |
58 | bool AddJob(const Scheduler::JobSetting &job_setting) override; | |
59 | bool RemoveJob(const std::string &name) override; | |
60 | void RemoveAllJobs() override; | |
61 | bool HasJob(const std::string &name) const override; | |
62 | 62 | |
63 | 63 | // Puts stub internal clock forward. |
64 | 64 | // Jobs will be executed according to forwarded time. |
43 | 43 | |
44 | 44 | class SchedulerStubTest : public ::testing::Test { |
45 | 45 | protected: |
46 | virtual void SetUp() { | |
46 | void SetUp() override { | |
47 | 47 | g_counter = 0; |
48 | 48 | g_result = true; |
49 | 49 | } |
50 | 50 | |
51 | virtual void TearDown() { | |
51 | void TearDown() override { | |
52 | 52 | g_counter = 0; |
53 | 53 | g_result = true; |
54 | 54 | } |
61 | 61 | }; |
62 | 62 | |
63 | 63 | protected: |
64 | virtual void TearDown() { Scheduler::RemoveAllJobs(); } | |
64 | void TearDown() override { Scheduler::RemoveAllJobs(); } | |
65 | 65 | }; |
66 | 66 | |
67 | 67 | TEST_F(SchedulerTest, SimpleJob) { |
255 | 255 | explicit NameCheckScheduler(const std::string &expected_name) |
256 | 256 | : expected_name_(expected_name) {} |
257 | 257 | |
258 | void RemoveAllJobs() {} | |
259 | bool RemoveJob(const std::string &name) { return true; } | |
260 | bool AddJob(const Scheduler::JobSetting &job_setting) { | |
258 | void RemoveAllJobs() override {} | |
259 | bool RemoveJob(const std::string &name) override { return true; } | |
260 | bool AddJob(const Scheduler::JobSetting &job_setting) override { | |
261 | 261 | return (expected_name_ == job_setting.name()); |
262 | 262 | } |
263 | bool HasJob(const std::string &name) const { return expected_name_ == name; } | |
263 | bool HasJob(const std::string &name) const override { | |
264 | return expected_name_ == name; | |
265 | } | |
264 | 266 | |
265 | 267 | private: |
266 | 268 | const std::string expected_name_; |
34 | 34 | #include <string> |
35 | 35 | |
36 | 36 | #include "base/port.h" |
37 | #include "testing/base/public/gunit.h" | |
37 | 38 | #include "absl/strings/string_view.h" |
38 | #include "testing/base/public/gunit.h" | |
39 | 39 | |
40 | 40 | namespace mozc { |
41 | 41 | namespace { |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | 29 | #include "base/singleton.h" |
30 | ||
30 | 31 | #include <stdlib.h> |
32 | ||
31 | 33 | #include "base/thread.h" |
32 | 34 | #include "base/util.h" |
33 | 35 | #include "testing/base/public/gunit.h" |
54 | 56 | |
55 | 57 | class ThreadTest : public Thread { |
56 | 58 | public: |
57 | void Run() { instance_ = Singleton<ThreadInstance>::get(); } | |
59 | void Run() override { instance_ = Singleton<ThreadInstance>::get(); } | |
58 | 60 | |
59 | 61 | ThreadInstance *get() { return instance_; } |
60 | 62 |
39 | 39 | |
40 | 40 | class StopwatchTest : public testing::Test { |
41 | 41 | protected: |
42 | void SetUp() { | |
42 | void SetUp() override { | |
43 | 43 | clock_mock_.reset(new ClockMock(0, 0)); |
44 | 44 | // 1GHz (Accuracy = 1ns) |
45 | 45 | clock_mock_->SetFrequency(uint64{1000000000}); |
46 | 46 | Clock::SetClockForUnitTest(clock_mock_.get()); |
47 | 47 | } |
48 | 48 | |
49 | void TearDown() { Clock::SetClockForUnitTest(nullptr); } | |
49 | void TearDown() override { Clock::SetClockForUnitTest(nullptr); } | |
50 | 50 | |
51 | 51 | void PutForwardNanoseconds(uint64 nano_sec) { |
52 | 52 | clock_mock_->PutClockForwardByTicks(nano_sec); |
395 | 395 | # else |
396 | 396 | return "/usr/lib/mozc"; |
397 | 397 | # endif // MOZC_SERVER_DIRECTORY |
398 | ||
399 | #else // OS_LINUX || OS_ANDROID || OS_NACL || OS_WASM | |
400 | # error "unknown platform" | |
401 | ||
402 | 398 | #endif // OS_LINUX || OS_ANDROID || OS_NACL || OS_WASM |
399 | ||
400 | // If none of the above platforms is specified, the compiler raises an error | |
401 | // because of no return value. | |
403 | 402 | } |
404 | 403 | |
405 | 404 | std::string SystemUtil::GetServerPath() { |
472 | 471 | return ppw->pw_name; |
473 | 472 | #endif // OS_ANDROID |
474 | 473 | |
475 | // __APPLE__, OS_LINUX or OS_NACL | |
474 | #if defined(__APPLE__) || defined(OS_LINUX) || defined(OS_WASM) | |
476 | 475 | struct passwd pw, *ppw; |
477 | 476 | char buf[1024]; |
478 | 477 | CHECK_EQ(0, getpwuid_r(geteuid(), &pw, buf, sizeof(buf), &ppw)); |
479 | 478 | return pw.pw_name; |
479 | #endif // __APPLE__ || OS_LINUX || OS_WASM | |
480 | ||
481 | // If none of the above platforms is specified, the compiler raises an error | |
482 | // because of no return value. | |
480 | 483 | } |
481 | 484 | |
482 | 485 | #ifdef OS_WIN |
885 | 888 | # else // defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES) |
886 | 889 | return 0; |
887 | 890 | # endif // defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES) |
888 | ||
889 | #else // OS_LINUX || OS_ANDROID || OS_NACL || OS_WASM | |
890 | # error "unknown platform" | |
891 | ||
892 | 891 | #endif // OS_LINUX || OS_ANDROID || OS_NACL || OS_WASM |
892 | ||
893 | // If none of the above platforms is specified, the compiler raises an error | |
894 | // because of no return value. | |
893 | 895 | } |
894 | 896 | |
895 | 897 | } // namespace mozc |
37 | 37 | class TestThread : public Thread { |
38 | 38 | public: |
39 | 39 | explicit TestThread(int time) : time_(time), invoked_(false) {} |
40 | virtual ~TestThread() {} | |
40 | ~TestThread() override {} | |
41 | 41 | |
42 | virtual void Run() { | |
42 | void Run() override { | |
43 | 43 | invoked_ = true; |
44 | 44 | Util::Sleep(time_); |
45 | 45 | } |
36 | 36 | #include <vector> |
37 | 37 | |
38 | 38 | #include "base/logging.h" |
39 | #include "base/util.h" | |
39 | 40 | #include "absl/strings/string_view.h" |
40 | #include "base/util.h" | |
41 | 41 | |
42 | 42 | namespace mozc { |
43 | 43 | |
93 | 93 | delete sub_trie; |
94 | 94 | trie_.erase(std::string(GetKeyHead(key))); |
95 | 95 | // If the size of trie_ is 0, This trie should be deleted. |
96 | return trie_.size() == 0; | |
96 | return trie_.empty(); | |
97 | 97 | } else { |
98 | 98 | return false; |
99 | 99 | } |
43 | 43 | : event_(event), timeout_(timeout) {} |
44 | 44 | |
45 | 45 | public: |
46 | virtual void Run() { | |
46 | void Run() override { | |
47 | 47 | Util::Sleep(timeout_); |
48 | 48 | LOG(INFO) << "Notify event"; |
49 | 49 | event_->Notify(); |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | 29 | #include "base/unverified_aes256.h" |
30 | ||
30 | 31 | #include "testing/base/public/googletest.h" |
31 | 32 | #include "testing/base/public/gunit.h" |
32 | 33 |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | 29 | #include "base/unverified_sha1.h" |
30 | ||
30 | 31 | #include "testing/base/public/googletest.h" |
31 | 32 | #include "testing/base/public/gunit.h" |
32 | 33 |
1281 | 1281 | void Util::AppendCGIParams( |
1282 | 1282 | const std::vector<std::pair<std::string, std::string> > ¶ms, |
1283 | 1283 | std::string *base) { |
1284 | if (params.size() == 0 || base == nullptr) { | |
1284 | if (params.empty() || base == nullptr) { | |
1285 | 1285 | return; |
1286 | 1286 | } |
1287 | 1287 |
67 | 67 | |
68 | 68 | // Read tsv file. |
69 | 69 | std::string line; |
70 | while (!getline(finput, line).fail()) { | |
70 | while (!std::getline(finput, line).fail()) { | |
71 | 71 | if (Util::StartsWith(line, "#")) { |
72 | 72 | // Skip comment line. |
73 | 73 | continue; |
30 | 30 | #define MOZC_BASE_VERSION_H_ |
31 | 31 | |
32 | 32 | #include <string> |
33 | ||
33 | 34 | #include "base/port.h" |
34 | 35 | |
35 | 36 | namespace mozc { |
57 | 57 | std::string command; |
58 | 58 | std::string left, focused, right; |
59 | 59 | |
60 | while (getline(std::cin, command)) { | |
60 | while (std::getline(std::cin, command)) { | |
61 | 61 | if (command == "<") { |
62 | 62 | composer->MoveCursorLeft(); |
63 | 63 | } else if (command == "<<") { |
93 | 93 | void TypingCorrector::InsertCharacter( |
94 | 94 | const absl::string_view key, const ProbableKeyEvents &probable_key_events) { |
95 | 95 | raw_key_.append(key.data(), key.size()); |
96 | if (!IsAvailable() || probable_key_events.size() == 0) { | |
96 | if (!IsAvailable() || probable_key_events.empty()) { | |
97 | 97 | // If this corrector is not available or no ProbableKeyEvent is available, |
98 | 98 | // just append |key| to each corrections. |
99 | 99 | for (size_t i = 0; i < top_n_.size(); ++i) { |
492 | 492 | mozc::Segments segments; |
493 | 493 | std::string line; |
494 | 494 | |
495 | while (!getline(std::cin, line).fail()) { | |
495 | while (!std::getline(std::cin, line).fail()) { | |
496 | 496 | if (mozc::ExecCommand(*converter, &segments, line, request)) { |
497 | 497 | if (FLAGS_output_debug_string) { |
498 | 498 | mozc::PrintSegments(segments, &std::cout); |
431 | 431 | |
432 | 432 | std::string converted; |
433 | 433 | int segment_num = 0; |
434 | while (1) { | |
434 | while (true) { | |
435 | 435 | int position = -1; |
436 | 436 | for (size_t i = 0; i < segments.segment(segment_num).candidates_size(); |
437 | 437 | ++i) { |
409 | 409 | return false; |
410 | 410 | } |
411 | 411 | |
412 | if (key.size() == 0 || key.size() >= kMaxSize) { | |
412 | if (key.empty() || key.size() >= kMaxSize) { | |
413 | 413 | VLOG(1) << "invalid key length"; |
414 | 414 | return false; |
415 | 415 | } |
49 | 49 | |
50 | 50 | std::string line; |
51 | 51 | std::vector<std::string> columns; |
52 | while (getline(*id_def, line)) { | |
52 | while (std::getline(*id_def, line)) { | |
53 | 53 | columns.clear(); |
54 | 54 | Util::SplitStringUsing(line, " ", &columns); |
55 | 55 | CHECK_EQ(2, columns.size()); |
165 | 165 | return false; |
166 | 166 | } |
167 | 167 | std::string line; |
168 | while (!getline(ifs, line).fail()) { | |
168 | while (!std::getline(ifs, line).fail()) { | |
169 | 169 | if (line.empty() || line.c_str()[0] == '#') { |
170 | 170 | continue; |
171 | 171 | } |
32 | 32 | MINOR = 25 |
33 | 33 | |
34 | 34 | # Number to be increased. This value may be replaced by other tools. |
35 | BUILD = 4150 | |
35 | BUILD = 4180 | |
36 | 36 | |
37 | 37 | # Represent the platform and release channel. |
38 | 38 | REVISION = 100 |
242 | 242 | |
243 | 243 | // Step 2. |
244 | 244 | key_info_list->clear(); |
245 | if (reduce_buffer.size() == 0) { | |
245 | if (reduce_buffer.empty()) { | |
246 | 246 | return; |
247 | 247 | } |
248 | 248 | KeyInfo last_key_info; |
253 | 253 | // Move instances to backup vector. |
254 | 254 | std::vector<UserDictionary::Entry *> backup(entries->pointer_begin(), |
255 | 255 | entries->pointer_end()); |
256 | while (entries->size() > 0) { | |
256 | while (!entries->empty()) { | |
257 | 257 | entries->ReleaseLast(); |
258 | 258 | } |
259 | 259 |
49 | 49 | Process::OpenBrowser(std::string(utf8.data(), utf8.length())); |
50 | 50 | } |
51 | 51 | |
52 | inline void Replace(QString &str, const char pattern[], const char repl[]) { | |
53 | str.replace(QLatin1String(pattern), QLatin1String(repl)); | |
54 | } | |
55 | ||
56 | inline void Replace(QString &str, const char pattern[], const QString &repl) { | |
57 | str.replace(QLatin1String(pattern), repl); | |
58 | } | |
59 | ||
52 | 60 | QString ReplaceString(const QString &str) { |
53 | 61 | QString replaced(str); |
54 | replaced.replace("[ProductName]", GuiUtil::ProductName()); | |
62 | Replace(replaced, "[ProductName]", GuiUtil::ProductName()); | |
55 | 63 | |
56 | 64 | #ifdef GOOGLE_JAPANESE_INPUT_BUILD |
57 | replaced.replace("[ProductUrl]", "https://www.google.co.jp/ime/"); | |
58 | replaced.replace("[ForumUrl]", | |
59 | "https://support.google.com/gboard/community?hl=ja"); | |
60 | replaced.replace("[ForumName]", QObject::tr("issues")); | |
65 | Replace(replaced, "[ProductUrl]", "https://www.google.co.jp/ime/"); | |
66 | Replace(replaced, "[ForumUrl]", | |
67 | "https://support.google.com/gboard/community?hl=ja"); | |
68 | Replace(replaced, "[ForumName]", QObject::tr("issues")); | |
61 | 69 | #else |
62 | replaced.replace("[ProductUrl]", "https://github.com/google/mozc"); | |
63 | replaced.replace("[ForumUrl]", "https://github.com/google/mozc/issues"); | |
64 | replaced.replace("[ForumName]", QObject::tr("issues")); | |
70 | Replace(replaced, "[ProductUrl]", "https://github.com/google/mozc"); | |
71 | Replace(replaced, "[ForumUrl]", "https://github.com/google/mozc/issues"); | |
72 | Replace(replaced, "[ForumName]", QObject::tr("issues")); | |
65 | 73 | #endif // GOOGLE_JAPANESE_INPUT_BUILD |
66 | 74 | |
67 | 75 | const std::string credit_filepath = |
68 | 76 | FileUtil::JoinPath(SystemUtil::GetDocumentDirectory(), "credits_en.html"); |
69 | replaced.replace("credits_en.html", credit_filepath.c_str()); | |
77 | Replace(replaced, "credits_en.html", credit_filepath.c_str()); | |
70 | 78 | |
71 | 79 | return replaced; |
72 | 80 | } |
85 | 93 | window_palette.setColor(QPalette::Window, QColor(255, 255, 255)); |
86 | 94 | setPalette(window_palette); |
87 | 95 | setAutoFillBackground(true); |
88 | QString version_info("("); | |
89 | version_info += Version::GetMozcVersion().c_str(); | |
90 | version_info += ")"; | |
91 | version_label->setText(version_info); | |
96 | std::string version_info = "(" + Version::GetMozcVersion() + ")"; | |
97 | version_label->setText(QLatin1String(version_info.c_str())); | |
92 | 98 | GuiUtil::ReplaceWidgetLabels(this); |
93 | 99 | |
94 | 100 | QPalette palette; |
111 | 117 | SetLabelText(label_terms); |
112 | 118 | SetLabelText(label_credits); |
113 | 119 | |
114 | product_image_ = absl::make_unique<QImage>(":/product_logo.png"); | |
120 | product_image_ = | |
121 | absl::make_unique<QImage>(QLatin1String(":/product_logo.png")); | |
115 | 122 | } |
116 | 123 | |
117 | 124 | void AboutDialog::paintEvent(QPaintEvent *event) { |
122 | 129 | const QRect draw_rect(std::max(5, width() - image_rect.width() - 15), |
123 | 130 | std::max(0, color_frame->y() - image_rect.height()), |
124 | 131 | image_rect.width(), image_rect.height()); |
125 | painter.drawImage(draw_rect, *product_image_.get()); | |
132 | painter.drawImage(draw_rect, *product_image_); | |
126 | 133 | } |
127 | 134 | |
128 | 135 | void AboutDialog::SetLinkCallback(LinkCallbackInterface *callback) { |
40 | 40 | namespace mozc { |
41 | 41 | namespace gui { |
42 | 42 | |
43 | #ifdef OS_WIN | |
43 | 44 | using mozc::config::StatsConfigUtil; |
45 | #endif // OS_WIN | |
44 | 46 | |
45 | 47 | AdministrationDialog::AdministrationDialog() |
46 | 48 | : dialog_title_( |
64 | 66 | |
65 | 67 | #ifdef CHANNEL_DEV |
66 | 68 | usageStatsCheckBox->setEnabled(false); |
67 | #endif | |
69 | #endif // CHANNEL_DEV | |
68 | 70 | |
69 | 71 | usageStatsCheckBox->setChecked(StatsConfigUtil::IsEnabled()); |
70 | 72 | |
132 | 134 | ElevatedProcessDisabledcheckBox->isChecked()) { |
133 | 135 | if (!RunLevel::SetElevatedProcessDisabled( |
134 | 136 | ElevatedProcessDisabledcheckBox->isChecked())) { |
135 | QMessageBox::critical( | |
136 | this, dialog_title_, | |
137 | tr("Failed to save the UAC policy setting. " | |
138 | "Administrator privilege is required to " | |
139 | "change UAC settings.")); | |
137 | QMessageBox::critical(this, dialog_title_, | |
138 | tr("Failed to save the UAC policy setting. " | |
139 | "Administrator privilege is required to " | |
140 | "change UAC settings.")); | |
140 | 141 | } |
141 | 142 | } |
142 | 143 | QWidget::close(); |
71 | 71 | |
72 | 72 | // Load "<translation_path>/qt_<lang>.qm" from a qrc file. |
73 | 73 | bool loaded = translator->load( |
74 | QLocale::system(), "qt", "_", | |
75 | QLibraryInfo::location(QLibraryInfo::TranslationsPath), ".qm"); | |
74 | QLocale::system(), QLatin1String("qt"), QLatin1String("_"), | |
75 | QLibraryInfo::location(QLibraryInfo::TranslationsPath), | |
76 | QLatin1String(".qm")); | |
76 | 77 | if (loaded) { |
77 | 78 | qApp->installTranslator(translator); |
78 | 79 | } else { |
87 | 88 | |
88 | 89 | // static |
89 | 90 | std::unique_ptr<QApplication> GuiUtil::InitQt(int &argc, char *argv[]) { |
90 | QApplication::setStyle(QStyleFactory::create("fusion")); | |
91 | QApplication::setStyle(QStyleFactory::create(QLatin1String("fusion"))); | |
91 | 92 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) |
92 | 93 | QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); |
93 | 94 | #endif |
114 | 115 | std::unique_ptr<QTranslator> translator(new QTranslator); |
115 | 116 | |
116 | 117 | // Load ":/<resource_name>_<lang>.qm" from a qrc file. |
117 | if (translator->load(QLocale::system(), resource_name, "_", ":/", ".qm")) { | |
118 | if (translator->load(QLocale::system(), QLatin1String(resource_name), | |
119 | QLatin1String("_"), QLatin1String(":/"), | |
120 | QLatin1String(".qm"))) { | |
118 | 121 | qApp->installTranslator(translator.get()); |
119 | 122 | translators->emplace(resource_name, std::move(translator)); |
120 | 123 | } |
155 | 158 | // static |
156 | 159 | QString GuiUtil::ReplaceString(const QString &str) { |
157 | 160 | QString replaced(str); |
158 | return replaced.replace("[ProductName]", GuiUtil::ProductName()); | |
161 | return replaced.replace(QLatin1String("[ProductName]"), | |
162 | GuiUtil::ProductName()); | |
159 | 163 | } |
160 | 164 | |
161 | 165 | } // namespace gui |
44 | 44 | return QObject::eventFilter(obj, event); |
45 | 45 | } |
46 | 46 | |
47 | const QString prefix = " (Dev "; | |
47 | const QString prefix = QLatin1String(" (Dev "); | |
48 | 48 | const QString& title = w->windowTitle(); |
49 | 49 | // The window title can be empty, even if it is specified. |
50 | 50 | // See: https://doc.qt.io/qt-5/qmessagebox.html#setWindowTitle |
152 | 152 | // Preedit Katakan is always FULLWIDTH |
153 | 153 | // This item should not be editable |
154 | 154 | if (group == QObject::tr("Katakana")) { |
155 | item_preedit->setFlags(0); // disable flag | |
155 | item_preedit->setFlags(nullptr); // disable flag | |
156 | 156 | } |
157 | 157 | |
158 | 158 | setItem(row, 0, item_group); |
37 | 37 | #include <algorithm> // for unique |
38 | 38 | #include <cctype> |
39 | 39 | #include <sstream> |
40 | #include <set> | |
40 | 41 | #include <string> |
41 | #include <vector> | |
42 | 42 | |
43 | 43 | #include "base/file_stream.h" |
44 | 44 | #include "base/logging.h" |
54 | 54 | int GetTableHeight(QTableWidget *widget) { |
55 | 55 | // Dragon Hack: |
56 | 56 | // Here we use "龍" to calc font size, as it looks almost square |
57 | const QRect rect = QFontMetrics(widget->font()).boundingRect("龍"); | |
57 | const QRect rect = | |
58 | QFontMetrics(widget->font()).boundingRect(QString::fromUtf8("龍")); | |
58 | 59 | #ifdef OS_WIN |
59 | 60 | return static_cast<int>(rect.height() * 1.3); |
60 | 61 | #else |
131 | 132 | } |
132 | 133 | |
133 | 134 | void GenericTableEditorDialog::DeleteSelectedItems() { |
134 | std::vector<int> rows; | |
135 | std::set<int> rows; | |
135 | 136 | QList<QTableWidgetItem *> selected = editorTableWidget->selectedItems(); |
136 | 137 | |
137 | // remember the last column as user chooses the | |
138 | // last rows from top to bottom in general. | |
139 | const int column = selected.isEmpty() ? 0 : selected.back()->column(); | |
140 | ||
141 | for (int i = 0; i < selected.size(); ++i) { | |
142 | rows.push_back(selected[i]->row()); | |
143 | } | |
144 | ||
145 | std::vector<int>::iterator last = std::unique(rows.begin(), rows.end()); | |
146 | rows.erase(last, rows.end()); | |
138 | for (auto item : selected) { | |
139 | rows.insert(item->row()); | |
140 | } | |
147 | 141 | |
148 | 142 | if (rows.empty()) { |
149 | 143 | QMessageBox::warning(this, windowTitle(), tr("No entry is selected")); |
150 | 144 | return; |
151 | 145 | } |
152 | 146 | |
153 | // Choose next or prev item. | |
154 | QTableWidgetItem *item = editorTableWidget->item(rows.back() + 1, column); | |
155 | if (item == nullptr) { | |
156 | item = editorTableWidget->item(rows.back() - 1, column); | |
157 | } | |
158 | ||
159 | // select item | |
160 | if (item != nullptr) { | |
161 | editorTableWidget->setCurrentItem(item); | |
162 | } | |
163 | ||
164 | // remove from the buttom | |
165 | for (int i = rows.size() - 1; i >= 0; --i) { | |
166 | editorTableWidget->removeRow(rows[i]); | |
147 | // Keep the current cursor position after the deletion. | |
148 | { | |
149 | // remember the last column as user chooses the | |
150 | // last rows from top to bottom in general. | |
151 | const int cur_col = selected.back()->column(); | |
152 | const int cur_row = selected.back()->row(); | |
153 | QTableWidgetItem *cur_item = editorTableWidget->item(cur_row + 1, cur_col); | |
154 | if (cur_item == nullptr) { | |
155 | cur_item = editorTableWidget->item(cur_row - 1, cur_col); | |
156 | } | |
157 | ||
158 | // select item | |
159 | if (cur_item != nullptr) { | |
160 | editorTableWidget->setCurrentItem(cur_item); | |
161 | } | |
162 | } | |
163 | ||
164 | // remove from the bottom | |
165 | for (auto rit = rows.rbegin(); rit != rows.rend(); ++rit) { | |
166 | editorTableWidget->removeRow(*rit); | |
167 | 167 | } |
168 | 168 | |
169 | 169 | UpdateMenuStatus(); |
184 | 184 | |
185 | 185 | editorTableWidget->insertRow(row); |
186 | 186 | for (size_t i = 0; i < column_size_; ++i) { |
187 | editorTableWidget->setItem(row, i, new QTableWidgetItem("")); | |
187 | editorTableWidget->setItem(row, i, new QTableWidgetItem(QLatin1String(""))); | |
188 | 188 | } |
189 | 189 | QTableWidgetItem *item = editorTableWidget->item(row, 0); |
190 | 190 | if (item != nullptr) { |
258 | 258 | return; |
259 | 259 | } |
260 | 260 | |
261 | const QString filename = | |
262 | QFileDialog::getSaveFileName(this, tr("export to file"), | |
263 | QDir::homePath() + QDir::separator() + | |
264 | QString(GetDefaultFilename().c_str())); | |
261 | const QString filename = QFileDialog::getSaveFileName( | |
262 | this, tr("export to file"), | |
263 | QDir::homePath() + QDir::separator() + | |
264 | QString::fromUtf8(GetDefaultFilename().c_str())); | |
265 | 265 | if (filename.isEmpty()) { |
266 | 266 | return; |
267 | 267 | } |
47 | 47 | explicit GenericTableEditorDialog(QWidget *parent, size_t column_size); |
48 | 48 | ~GenericTableEditorDialog() override; |
49 | 49 | |
50 | bool LoadFromString(const std::string &table); | |
50 | bool LoadFromString(const std::string &str); | |
51 | 51 | const std::string &table() const; |
52 | 52 | |
53 | 53 | protected slots: |
219 | 219 | // are pressed. If Hiragana/Eisu key is pressed, we assume that |
220 | 220 | // the key is already released at the same time. |
221 | 221 | // Hankaku/Zenkaku key is preserved key and modifier keys are ignored. |
222 | if (modifier_non_required_key_ == "Hiragana" || | |
223 | modifier_non_required_key_ == "Katakana" || | |
224 | modifier_non_required_key_ == "Eisu" || | |
225 | modifier_non_required_key_ == "Hankaku/Zenkaku") { | |
222 | if (modifier_non_required_key_ == QLatin1String("Hiragana") || | |
223 | modifier_non_required_key_ == QLatin1String("Katakana") || | |
224 | modifier_non_required_key_ == QLatin1String("Eisu") || | |
225 | modifier_non_required_key_ == QLatin1String("Hankaku/Zenkaku")) { | |
226 | 226 | *result = modifier_non_required_key_; |
227 | 227 | return KeyBindingFilter::SUBMIT_KEY; |
228 | 228 | } |
230 | 230 | QStringList results; |
231 | 231 | |
232 | 232 | if (ctrl_pressed_) { |
233 | results << "Ctrl"; | |
233 | results << QLatin1String("Ctrl"); | |
234 | 234 | } |
235 | 235 | |
236 | 236 | if (shift_pressed_) { |
237 | results << "Shift"; | |
237 | results << QLatin1String("Shift"); | |
238 | 238 | } |
239 | 239 | |
240 | 240 | if (alt_pressed_) { |
241 | 241 | #ifdef __APPLE__ |
242 | results << "Option"; | |
242 | results << QLatin1String("Option"); | |
243 | 243 | #else |
244 | 244 | // Do not support and show keybindings with alt for Windows |
245 | 245 | // results << "Alt"; |
364 | 364 | for (size_t i = 0; i < arraysize(kQtKeyModifierNonRequiredTable); ++i) { |
365 | 365 | if (kQtKeyModifierNonRequiredTable[i].qt_key == qt_key) { |
366 | 366 | modifier_non_required_key_ = |
367 | kQtKeyModifierNonRequiredTable[i].mozc_key_name; | |
367 | QLatin1String(kQtKeyModifierNonRequiredTable[i].mozc_key_name); | |
368 | 368 | return Encode(result); |
369 | 369 | } |
370 | 370 | } |
375 | 375 | for (size_t i = 0; i < arraysize(kWinVirtualKeyModifierNonRequiredTable); |
376 | 376 | ++i) { |
377 | 377 | if (kWinVirtualKeyModifierNonRequiredTable[i].virtual_key == virtual_key) { |
378 | modifier_non_required_key_ = | |
379 | kWinVirtualKeyModifierNonRequiredTable[i].mozc_key_name; | |
378 | modifier_non_required_key_ = QLatin1String( | |
379 | kWinVirtualKeyModifierNonRequiredTable[i].mozc_key_name); | |
380 | 380 | return Encode(result); |
381 | 381 | } |
382 | 382 | } |
401 | 401 | // 3. Press "Hiragana/Katakana" (shift_pressed_ == false) |
402 | 402 | const bool with_shift = (key_event.modifiers() & Qt::ShiftModifier) != 0; |
403 | 403 | if (with_shift && (qt_key == Qt::Key_Hiragana_Katakana)) { |
404 | modifier_non_required_key_ = "Katakana"; | |
404 | modifier_non_required_key_ = QLatin1String("Katakana"); | |
405 | 405 | return Encode(result); |
406 | 406 | } |
407 | 407 | #endif |
408 | 408 | |
409 | 409 | if (qt_key == Qt::Key_yen) { |
410 | 410 | // Japanese Yen mark, treat it as backslash for compatibility |
411 | modifier_non_required_key_ = "\\"; | |
411 | modifier_non_required_key_ = QLatin1String("\\"); | |
412 | 412 | return Encode(result); |
413 | 413 | } |
414 | 414 | |
415 | 415 | // printable command, which requires modifier keys |
416 | 416 | if ((qt_key >= 0x21 && qt_key <= 0x60) || |
417 | 417 | (qt_key >= 0x7B && qt_key <= 0x7E)) { |
418 | const char key_char = static_cast<char>(qt_key); | |
418 | 419 | if (qt_key >= 0x41 && qt_key <= 0x5A) { |
419 | modifier_required_key_ = static_cast<char>(qt_key - 'A' + 'a'); | |
420 | modifier_required_key_ = QLatin1Char(key_char - 'A' + 'a'); | |
420 | 421 | } else { |
421 | modifier_required_key_ = static_cast<char>(qt_key); | |
422 | modifier_required_key_ = QLatin1Char(key_char); | |
422 | 423 | } |
423 | 424 | return Encode(result); |
424 | 425 | } |
440 | 441 | } |
441 | 442 | |
442 | 443 | // TODO(taku): the following sequence doesn't work as once |
443 | // user relase any of keys, the statues goes to "submitted" | |
444 | // user release any of keys, the statues goes to "submitted" | |
444 | 445 | // 1. Press Ctrl + a |
445 | 446 | // 2. Release a, but keep pressing Ctrl |
446 | 447 | // 3. Press b (the result should be "Ctrl + b"). |
40 | 40 | |
41 | 41 | class KeyBindingEditorTriggerButton : public QPushButton { |
42 | 42 | public: |
43 | KeyBindingEditorTriggerButton(QWidget *parent) | |
43 | explicit KeyBindingEditorTriggerButton(QWidget *parent) | |
44 | 44 | : QPushButton(parent), editor_(new KeyBindingEditor(parent, this)) { |
45 | 45 | editor_->setModal(true); // create a modal dialog |
46 | 46 | setFocusProxy(editor_.get()); |
506 | 506 | } else if (action == actions_[EXPORT_TO_FILE_INDEX]) { |
507 | 507 | Export(); |
508 | 508 | } |
509 | ||
510 | return; | |
511 | 509 | } |
512 | 510 | |
513 | 511 | // static |
96 | 96 | CHECK(ifs.get() != nullptr); // should never happen |
97 | 97 | std::string line, result; |
98 | 98 | std::vector<std::string> fields; |
99 | while (std::getline(*ifs.get(), line)) { | |
99 | while (std::getline(*ifs, line)) { | |
100 | 100 | if (line.empty()) { |
101 | 101 | continue; |
102 | 102 | } |
258 | 258 | } else if (action == actions_[EXPORT_TO_FILE_INDEX]) { |
259 | 259 | Export(); |
260 | 260 | } |
261 | ||
262 | return; | |
263 | 261 | } |
264 | 262 | |
265 | 263 | // static |
49 | 49 | ~RomanTableEditorDialog() override; |
50 | 50 | |
51 | 51 | // show a modal dialog |
52 | static bool Show(QWidget *parent, const std::string ¤t_keymap, | |
53 | std::string *new_keymap); | |
52 | static bool Show(QWidget *parent, const std::string ¤t_roman_table, | |
53 | std::string *new_roman_table); | |
54 | 54 | |
55 | 55 | protected slots: |
56 | 56 | void UpdateMenuStatus() override; |
84 | 84 | } |
85 | 85 | |
86 | 86 | void DictionaryContentTableWidget::focusInEvent(QFocusEvent *event) { |
87 | setStyleSheet(""); | |
87 | setStyleSheet(QLatin1String("")); | |
88 | 88 | } |
83 | 83 | using ::mozc::user_dictionary::UserDictionarySession; |
84 | 84 | using ::mozc::user_dictionary::UserDictionaryStorage; |
85 | 85 | |
86 | inline QString QUtf8(const char str[]) { | |
87 | return QString::fromUtf8(str); | |
88 | } | |
89 | ||
90 | inline QString QUtf8(const string &str) { | |
91 | return QString::fromUtf8(str.c_str()); | |
92 | } | |
93 | ||
86 | 94 | // set longer timeout because it takes longer time |
87 | 95 | // to reload all user dictionary. |
88 | 96 | const int kSessionTimeout = 100000; |
90 | 98 | int GetTableHeight(QTableWidget *widget) { |
91 | 99 | // Dragon Hack: |
92 | 100 | // Here we use "龍" to calc font size, as it looks almsot square |
93 | const QRect rect = QFontMetrics(widget->font()).boundingRect("龍"); | |
101 | const QRect rect = QFontMetrics(widget->font()).boundingRect(QUtf8("龍")); | |
94 | 102 | return static_cast<int>(rect.height() * 1.4); |
95 | 103 | } |
96 | 104 | |
97 | 105 | QProgressDialog *CreateProgressDialog(QString message, QWidget *parent, |
98 | 106 | int size) { |
99 | QProgressDialog *progress = new QProgressDialog(message, "", 0, size, parent); | |
107 | QProgressDialog *progress = | |
108 | new QProgressDialog(message, QLatin1String(""), 0, size, parent); | |
100 | 109 | CHECK(progress); |
101 | 110 | progress->setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | |
102 | 111 | Qt::WindowCloseButtonHint); |
397 | 406 | pos_list_provider_->GetPOSList(&tmp_pos_vec); |
398 | 407 | QStringList pos_list; |
399 | 408 | for (size_t i = 0; i < tmp_pos_vec.size(); ++i) { |
400 | pos_list.append(tmp_pos_vec[i].c_str()); | |
409 | pos_list.append(QUtf8(tmp_pos_vec[i])); | |
401 | 410 | } |
402 | 411 | ComboBoxDelegate *delegate = new ComboBoxDelegate; |
403 | 412 | delegate->SetItemList(pos_list); |
513 | 522 | sort_state_.sorted = false; |
514 | 523 | |
515 | 524 | // If this is the first time for the user dictionary is used, create |
516 | // a defautl dictionary. | |
525 | // a default dictionary. | |
517 | 526 | if (!session_->mutable_storage()->Exists()) { |
518 | 527 | CreateDictionaryHelper(tr("User Dictionary 1")); |
519 | 528 | } |
629 | 638 | tr("Updating the current view data..."), this, dic->entries_size())); |
630 | 639 | |
631 | 640 | for (size_t i = 0; i < dic->entries_size(); ++i) { |
632 | dic_content_->setItem( | |
633 | i, 0, new QTableWidgetItem(dic->entries(i).key().c_str())); | |
634 | dic_content_->setItem( | |
635 | i, 1, new QTableWidgetItem(dic->entries(i).value().c_str())); | |
641 | const UserDictionary::Entry &entry = dic->entries(i); | |
642 | dic_content_->setItem(i, 0, new QTableWidgetItem(QUtf8(entry.key()))); | |
643 | dic_content_->setItem(i, 1, new QTableWidgetItem(QUtf8(entry.value()))); | |
636 | 644 | dic_content_->setItem( |
637 | 645 | i, 2, |
638 | 646 | new QTableWidgetItem( |
639 | UserDictionaryUtil::GetStringPosType(dic->entries(i).pos()))); | |
640 | dic_content_->setItem( | |
641 | i, 3, new QTableWidgetItem(dic->entries(i).comment().c_str())); | |
647 | QUtf8(UserDictionaryUtil::GetStringPosType(entry.pos())))); | |
648 | dic_content_->setItem(i, 3, new QTableWidgetItem(QUtf8(entry.comment()))); | |
642 | 649 | progress->setValue(i); |
643 | 650 | } |
644 | 651 | } |
668 | 675 | return; |
669 | 676 | } |
670 | 677 | |
671 | const QString dic_name = | |
672 | PromptForDictionaryName("", tr("Name of the new dictionary")); | |
678 | const QString dic_name = PromptForDictionaryName( | |
679 | QLatin1String(""), tr("Name of the new dictionary")); | |
673 | 680 | if (dic_name.isEmpty()) { |
674 | 681 | return; // canceld by user |
675 | 682 | } |
791 | 798 | QMessageBox::information(this, window_title_, |
792 | 799 | tr("%1 entries are imported to %2.") |
793 | 800 | .arg(added_entries_size) |
794 | .arg(dic_name.c_str())); | |
801 | .arg(QUtf8(dic_name))); | |
795 | 802 | break; |
796 | 803 | case UserDictionaryImporter::IMPORT_NOT_SUPPORTED: |
797 | 804 | QMessageBox::information(this, window_title_, |
807 | 814 | tr("%1 doesn't have enough space to import all words in " |
808 | 815 | "the file. First %2 entries " |
809 | 816 | "are imported.") |
810 | .arg(dic_name.c_str()) | |
817 | .arg(QUtf8(dic_name)) | |
811 | 818 | .arg(added_entries_size)); |
812 | 819 | break; |
813 | 820 | case UserDictionaryImporter::IMPORT_INVALID_ENTRIES: |
817 | 824 | "words were not recognized by %3. " |
818 | 825 | "Please check the original import file.") |
819 | 826 | .arg(added_entries_size) |
820 | .arg(dic_name.c_str()) | |
827 | .arg(QUtf8(dic_name)) | |
821 | 828 | .arg(window_title_)); |
822 | 829 | break; |
823 | 830 | case UserDictionaryImporter::IMPORT_FATAL: |
836 | 843 | if (!IsReadableToImport(file_name)) { |
837 | 844 | LOG(ERROR) << "File is not readable to import."; |
838 | 845 | QMessageBox::critical(this, window_title_, |
839 | tr("Can't open %1.").arg(file_name.c_str())); | |
846 | tr("Can't open %1.").arg(QUtf8(file_name))); | |
840 | 847 | return; |
841 | 848 | } |
842 | 849 | |
974 | 981 | if (!IsWritableToExport(file_name)) { |
975 | 982 | LOG(ERROR) << "File is not writable to export."; |
976 | 983 | QMessageBox::critical(this, window_title_, |
977 | tr("Can't open %1.").arg(file_name.c_str())); | |
984 | tr("Can't open %1.").arg(QUtf8(file_name))); | |
978 | 985 | return; |
979 | 986 | } |
980 | 987 | |
1001 | 1008 | } |
1002 | 1009 | |
1003 | 1010 | dic_content_->insertRow(row); |
1004 | dic_content_->setItem(row, 0, new QTableWidgetItem("")); | |
1005 | dic_content_->setItem(row, 1, new QTableWidgetItem("")); | |
1011 | dic_content_->setItem(row, 0, new QTableWidgetItem(QLatin1String(""))); | |
1012 | dic_content_->setItem(row, 1, new QTableWidgetItem(QLatin1String(""))); | |
1006 | 1013 | dic_content_->setItem(row, 2, new QTableWidgetItem(default_pos_)); |
1007 | dic_content_->setItem(row, 3, new QTableWidgetItem("")); | |
1014 | dic_content_->setItem(row, 3, new QTableWidgetItem(QLatin1String(""))); | |
1008 | 1015 | |
1009 | 1016 | if (row + 1 >= max_entry_size_) { |
1010 | 1017 | new_word_button_->setEnabled(false); |
1052 | 1059 | void DictionaryTool::DeleteWord() { |
1053 | 1060 | std::vector<int> rows; |
1054 | 1061 | GetSortedSelectedRows(&rows); |
1055 | if (rows.size() == 0) { | |
1062 | if (rows.empty()) { | |
1056 | 1063 | return; |
1057 | 1064 | } |
1058 | 1065 | |
1131 | 1138 | |
1132 | 1139 | std::vector<int> rows; |
1133 | 1140 | GetSortedSelectedRows(&rows); |
1134 | if (rows.size() == 0) { | |
1141 | if (rows.empty()) { | |
1135 | 1142 | return; |
1136 | 1143 | } |
1137 | 1144 | |
1194 | 1201 | |
1195 | 1202 | bool ok = false; |
1196 | 1203 | const QString new_comment = QInputDialog::getText( |
1197 | this, window_title_, tr("New comment"), QLineEdit::Normal, "", &ok, | |
1198 | Qt::WindowTitleHint | Qt::WindowSystemMenuHint); | |
1204 | this, window_title_, tr("New comment"), QLineEdit::Normal, | |
1205 | QLatin1String(""), &ok, Qt::WindowTitleHint | Qt::WindowSystemMenuHint); | |
1199 | 1206 | |
1200 | 1207 | if (!ok) { |
1201 | 1208 | return; |
1263 | 1270 | const QList<QTableWidgetItem *> items = dic_content_->selectedItems(); |
1264 | 1271 | QString delete_menu_text = tr("Delete this word"); |
1265 | 1272 | QString move_to_menu_text = tr("Move this word to"); |
1266 | if (items.size() > 0) { | |
1273 | if (!items.empty()) { | |
1267 | 1274 | const int first_row = items[0]->row(); |
1268 | 1275 | for (int i = 1; i < items.size(); ++i) { |
1269 | 1276 | if (items[i]->row() != first_row) { |
1537 | 1544 | } |
1538 | 1545 | |
1539 | 1546 | bool DictionaryTool::IsReadableToImport(const std::string &file_name) { |
1540 | QFileInfo file_info(file_name.c_str()); | |
1547 | QFileInfo file_info(QUtf8(file_name)); | |
1541 | 1548 | return file_info.isFile() && file_info.isReadable(); |
1542 | 1549 | } |
1543 | 1550 | |
1544 | 1551 | bool DictionaryTool::IsWritableToExport(const std::string &file_name) { |
1545 | QFileInfo file_info(file_name.c_str()); | |
1552 | QFileInfo file_info(QUtf8(file_name)); | |
1546 | 1553 | if (file_info.exists()) { |
1547 | 1554 | return file_info.isFile() && file_info.isWritable(); |
1548 | 1555 | } else { |
62 | 62 | Q_OBJECT |
63 | 63 | |
64 | 64 | public: |
65 | explicit DictionaryTool(QWidget *parent = 0); | |
65 | explicit DictionaryTool(QWidget *parent = nullptr); | |
66 | 66 | ~DictionaryTool() override; |
67 | 67 | |
68 | 68 | // return true DictionaryTool is available. |
73 | 73 | } |
74 | 74 | |
75 | 75 | void FindDialog::closeEvent(QCloseEvent *event) { |
76 | table_->setStyleSheet(""); | |
76 | table_->setStyleSheet(QLatin1String("")); | |
77 | 77 | last_item_ = nullptr; |
78 | 78 | } |
79 | 79 | |
143 | 143 | QTableWidgetItem *item = table_->item(matched_row, matched_column); |
144 | 144 | DCHECK(item); |
145 | 145 | last_item_ = item; |
146 | table_->setStyleSheet(kYellowSelectionStyleSheet); | |
146 | table_->setStyleSheet(QLatin1String(kYellowSelectionStyleSheet)); | |
147 | 147 | table_->setCurrentItem(item); |
148 | 148 | table_->scrollToItem(item); |
149 | 149 | } else { |
49 | 49 | Q_OBJECT |
50 | 50 | |
51 | 51 | public: |
52 | ImportDialog(QWidget *parent = 0); | |
52 | explicit ImportDialog(QWidget *parent = nullptr); | |
53 | 53 | ~ImportDialog() override; |
54 | 54 | |
55 | 55 | // Accessor methods to get form values. |
47 | 47 | |
48 | 48 | class ZeroWidthSplitter : public QSplitter { |
49 | 49 | public: |
50 | ZeroWidthSplitter(QWidget *parent); | |
50 | explicit ZeroWidthSplitter(QWidget *parent); | |
51 | 51 | QSplitterHandle *createHandle() override; |
52 | 52 | }; |
53 | 53 |
50 | 50 | Q_OBJECT |
51 | 51 | |
52 | 52 | public: |
53 | DeleyedMessageDialogHandler(QMessageBox *message_box); | |
53 | explicit DeleyedMessageDialogHandler(QMessageBox *message_box); | |
54 | 54 | ~DeleyedMessageDialogHandler() override; |
55 | 55 | |
56 | 56 | void Exec(); |
79 | 79 | const DWORD buffer_size = |
80 | 80 | ::GetEnvironmentVariable(wenvname.c_str(), nullptr, 0); |
81 | 81 | if (buffer_size == 0) { |
82 | return ""; | |
82 | return QLatin1String(""); | |
83 | 83 | } |
84 | 84 | std::unique_ptr<wchar_t[]> buffer(new wchar_t[buffer_size]); |
85 | 85 | const DWORD num_copied = |
94 | 94 | return QString::fromUcs4(reinterpret_cast<const uint *>(buffer.get())); |
95 | 95 | } |
96 | 96 | } |
97 | return ""; | |
97 | return QLatin1String(""); | |
98 | 98 | #endif // OS_WIN |
99 | 99 | #if defined(__APPLE__) || defined(OS_LINUX) |
100 | return ::getenv(envname); | |
100 | return QString::fromUtf8(::getenv(envname)); | |
101 | 101 | #endif // __APPLE__ or OS_LINUX |
102 | 102 | // TODO(team): Support other platforms. |
103 | return ""; | |
103 | return QLatin1String(""); | |
104 | 104 | } |
105 | 105 | } // namespace |
106 | 106 | |
154 | 154 | pos_list_provider_->GetPOSList(&pos_set); |
155 | 155 | CHECK(!pos_set.empty()); |
156 | 156 | |
157 | for (size_t i = 0; i < pos_set.size(); ++i) { | |
158 | CHECK(!pos_set[i].empty()); | |
159 | PartOfSpeechcomboBox->addItem(pos_set[i].c_str()); | |
157 | for (const string &pos : pos_set) { | |
158 | CHECK(!pos.empty()); | |
159 | PartOfSpeechcomboBox->addItem(QString::fromUtf8(pos.c_str())); | |
160 | 160 | } |
161 | 161 | |
162 | 162 | // Create new dictionary if empty |
176 | 176 | { |
177 | 177 | const UserDictionaryStorage &storage = session_->storage(); |
178 | 178 | CHECK_GT(storage.dictionaries_size(), 0); |
179 | for (size_t i = 0; i < storage.dictionaries_size(); ++i) { | |
180 | DictionarycomboBox->addItem(storage.dictionaries(i).name().c_str()); | |
179 | for (const auto &dictionary : storage.dictionaries()) { | |
180 | DictionarycomboBox->addItem(QString::fromUtf8(dictionary.name().c_str())); | |
181 | 181 | } |
182 | 182 | } |
183 | 183 | |
304 | 304 | CHECK(dic); |
305 | 305 | |
306 | 306 | if (dic->name() != DictionarycomboBox->currentText().toStdString().c_str()) { |
307 | LOG(ERROR) << "Inconsitent dictionary name"; | |
307 | LOG(ERROR) << "Inconsistent dictionary name"; | |
308 | 308 | return FATAL_ERROR; |
309 | 309 | } |
310 | 310 | |
351 | 351 | const QString WordRegisterDialog::GetReading(const QString &str) { |
352 | 352 | if (str.isEmpty()) { |
353 | 353 | LOG(ERROR) << "given string is empty"; |
354 | return ""; | |
354 | return QLatin1String(""); | |
355 | 355 | } |
356 | 356 | |
357 | 357 | if (str.count() >= kMaxReverseConversionLength) { |
358 | 358 | LOG(ERROR) << "too long input"; |
359 | return ""; | |
359 | return QLatin1String(""); | |
360 | 360 | } |
361 | 361 | |
362 | 362 | commands::Output output; |
365 | 365 | key.set_special_key(commands::KeyEvent::ON); |
366 | 366 | if (!client_->SendKey(key, &output)) { |
367 | 367 | LOG(ERROR) << "SendKey failed"; |
368 | return ""; | |
368 | return QLatin1String(""); | |
369 | 369 | } |
370 | 370 | |
371 | 371 | commands::SessionCommand command; |
374 | 374 | |
375 | 375 | if (!client_->SendCommand(command, &output)) { |
376 | 376 | LOG(ERROR) << "SendCommand failed"; |
377 | return ""; | |
377 | return QLatin1String(""); | |
378 | 378 | } |
379 | 379 | |
380 | 380 | commands::Output dummy_output; |
384 | 384 | |
385 | 385 | if (!output.has_preedit()) { |
386 | 386 | LOG(ERROR) << "No preedit"; |
387 | return ""; | |
387 | return QLatin1String(""); | |
388 | 388 | } |
389 | 389 | |
390 | 390 | std::string key; |
394 | 394 | output.preedit().segment(segment_index); |
395 | 395 | if (!segment.has_key()) { |
396 | 396 | LOG(ERROR) << "No segment"; |
397 | return ""; | |
397 | return QLatin1String(""); | |
398 | 398 | } |
399 | 399 | key.append(segment.key()); |
400 | 400 | } |
401 | 401 | |
402 | 402 | if (key.empty() || !UserDictionaryUtil::IsValidReading(key)) { |
403 | 403 | LOG(WARNING) << "containing invalid characters"; |
404 | return ""; | |
405 | } | |
406 | ||
407 | return QString(key.c_str()); | |
404 | return QLatin1String(""); | |
405 | } | |
406 | ||
407 | return QString::fromUtf8(key.c_str()); | |
408 | 408 | } |
409 | 409 | |
410 | 410 | // Get default value from Clipboard |
452 | 452 | LOG(ERROR) << "SendMessageTimeout() failed: " << ::GetLastError(); |
453 | 453 | } |
454 | 454 | #endif // OS_WIN |
455 | ||
456 | return; | |
457 | 455 | } |
458 | 456 | |
459 | 457 | bool WordRegisterDialog::SetDefaultEntryFromEnvironmentVariable() { |
474 | 472 | } |
475 | 473 | |
476 | 474 | const QString WordRegisterDialog::TrimValue(const QString &str) const { |
477 | return str.trimmed().replace('\r', "").replace('\n', ""); | |
475 | return str.trimmed() | |
476 | .replace(QLatin1Char('\r'), QLatin1String("")) | |
477 | .replace(QLatin1Char('\n'), QLatin1String("")); | |
478 | 478 | } |
479 | 479 | |
480 | 480 | void WordRegisterDialog::EnableIME() { |
99 | 99 | bool SetDefaultEntryFromEnvironmentVariable(); |
100 | 100 | |
101 | 101 | // Return reading of value with reverse conversion feature. |
102 | const QString GetReading(const QString &value); | |
102 | const QString GetReading(const QString &str); | |
103 | 103 | |
104 | 104 | // remove "\n" "\r" from |value|. |
105 | 105 | // remove whitespace from the start and the end. |
106 | const QString TrimValue(const QString &value) const; | |
106 | const QString TrimValue(const QString &str) const; | |
107 | 107 | |
108 | 108 | // turn on IME. |
109 | 109 | // When the dialog is shown, it is better to turn on IME. |
1343 | 1343 | request.composer().GetStringForPreedit(input_key); |
1344 | 1344 | std::set<std::string> expanded_set; |
1345 | 1345 | request.composer().GetQueriesForPrediction(base, &expanded_set); |
1346 | if (expanded_set.size() > 0) { | |
1346 | if (!expanded_set.empty()) { | |
1347 | 1347 | expanded->reset(new Trie<std::string>); |
1348 | 1348 | for (std::set<std::string>::const_iterator itr = expanded_set.begin(); |
1349 | 1349 | itr != expanded_set.end(); ++itr) { |
1761 | 1761 | } |
1762 | 1762 | |
1763 | 1763 | InsertHistory(request_type, is_suggestion, last_access_time, segments); |
1764 | return; | |
1765 | 1764 | } |
1766 | 1765 | |
1767 | 1766 | void UserHistoryPredictor::MakeLearningSegments( |
1916 | 1915 | } |
1917 | 1916 | } |
1918 | 1917 | } |
1919 | ||
1920 | return; | |
1921 | 1918 | } |
1922 | 1919 | |
1923 | 1920 | void UserHistoryPredictor::Revert(Segments *segments) { |
180 | 180 | ['(_toolset=="target" and (compiler_target=="clang" or compiler_target=="gcc")) or ' |
181 | 181 | '(_toolset=="host" and (compiler_host=="clang" or compiler_host=="gcc"))', { |
182 | 182 | 'cflags': [ |
183 | '-Wno-tautological-constant-out-of-range-compare', | |
183 | 184 | '-Wno-unused-function', |
184 | 185 | ], |
185 | 186 | }], |
220 | 221 | ['(_toolset=="target" and (compiler_target=="clang" or compiler_target=="gcc")) or ' |
221 | 222 | '(_toolset=="host" and (compiler_host=="clang" or compiler_host=="gcc"))', { |
222 | 223 | 'cflags': [ |
224 | '-Wno-tautological-constant-out-of-range-compare', | |
223 | 225 | '-Wno-unused-const-variable', |
224 | 226 | '-Wno-unused-function', |
225 | 227 | '-Wno-unused-private-field', |
139 | 139 | std::ifstream finput(filename.c_str()); |
140 | 140 | std::string line; |
141 | 141 | int lineno = 0; |
142 | while (getline(finput, line)) { | |
142 | while (std::getline(finput, line)) { | |
143 | 143 | ++lineno; |
144 | 144 | |
145 | 145 | // |line| is of format "expression=answer". |
63 | 63 | |
64 | 64 | // Make a segments which has some dummy candidates. |
65 | 65 | void MakeSegments(Segments *segments, const std::string &key, |
66 | const int &num_segment, const int &num_dummy_candidate) { | |
66 | const int num_segment, const int num_dummy_candidate) { | |
67 | 67 | segments->Clear(); |
68 | 68 | |
69 | 69 | AddSegment(key, segments); |
240 | 240 | |
241 | 241 | { |
242 | 242 | if (IsNumberCandidate(seg.candidate(candidate_index))) { |
243 | bool modified = 0; | |
243 | bool modified = false; | |
244 | 244 | int distance = 0; |
245 | 245 | for (size_t i = segment_index + 1; i < segments->segments_size(); ++i) { |
246 | 246 | Segment *target_right_seg = segments->mutable_segment(i); |
354 | 354 | return; |
355 | 355 | } |
356 | 356 | } |
357 | return; | |
358 | 357 | } |
359 | 358 | |
360 | 359 | // NormalizeCandidate using config |
1507 | 1507 | // "[半] アルファベット" |
1508 | 1508 | std::string expectation = VariantsRewriter::kHalfWidth; |
1509 | 1509 | const std::string alphabet = VariantsRewriter::kAlphabet; |
1510 | if (alphabet.size() != 0) { | |
1510 | if (!alphabet.empty()) { | |
1511 | 1511 | expectation += ' ' + alphabet; |
1512 | 1512 | } |
1513 | 1513 | EXPECT_EQ(expectation, segments.segment(0).candidate(0).description); |
91 | 91 | VLOG(1) << "Mozc server starts with timeout mode"; |
92 | 92 | FLAGS_restricted = true; |
93 | 93 | } |
94 | ||
95 | return; | |
96 | 94 | } |
97 | 95 | |
98 | 96 | int MozcServer::Run() { |
49 | 49 | GenericStorageInterface *emoticon = GenericStorageManagerFactory::GetStorage( |
50 | 50 | commands::GenericStorageEntry::EMOTICON_HISTORY); |
51 | 51 | GenericStorageInterface *invalid = GenericStorageManagerFactory::GetStorage( |
52 | (commands::GenericStorageEntry::StorageType)(100)); | |
52 | static_cast<commands::GenericStorageEntry::StorageType>(100)); | |
53 | 53 | |
54 | 54 | EXPECT_NE(nullptr, symbol); |
55 | 55 | EXPECT_NE(nullptr, emoticon); |
376 | 376 | const commands::GenericStorageEntry &storage_entry = |
377 | 377 | command->input().storage_entry(); |
378 | 378 | if (!storage_entry.has_type() || !storage_entry.has_key() || |
379 | storage_entry.value().size() == 0) { | |
379 | storage_entry.value().empty()) { | |
380 | 380 | LOG(WARNING) << "storage_entry lacks some fields."; |
381 | 381 | return false; |
382 | 382 | } |
99 | 99 | |
100 | 100 | // Insert key and bool value |
101 | 101 | // It is not guaranteed that the data is synced to the disk |
102 | static bool Insert(const std::string &key, const bool &value) { | |
102 | static bool Insert(const std::string &key, const bool value) { | |
103 | 103 | const uint8 tmp = static_cast<uint8>(value); |
104 | 104 | return Insert<uint8>(key, tmp); |
105 | 105 | } |