Nux

Merge lp:~3v1n0/nux/text-entry-virtual-clipboard into lp:nux

Proposed by Marco Trevisan (Treviño) on 2012-07-03
Status: Merged
Approved by: Marco Trevisan (Treviño) on 2012-07-03
Approved revision: 657
Merged at revision: 628
Proposed branch: lp:~3v1n0/nux/text-entry-virtual-clipboard
Merge into: lp:nux
Prerequisite: lp:~3v1n0/nux/text-entry-meta-filters
Diff against target: 705 lines (+400/-78)
6 files modified
Nux/InputMethodIBus.cpp (+11/-11)
Nux/TextEntry.cpp (+53/-29)
Nux/TextEntry.h (+7/-3)
tests/gtest-nux-textentry.cpp (+269/-33)
tests/gtest-nux-utils.h (+58/-0)
tests/xtest-text-entry.cpp (+2/-2)
To merge this branch: bzr merge lp:~3v1n0/nux/text-entry-virtual-clipboard
Reviewer Review Type Date Requested Status
Thomi Richards (community) quality Approve on 2012-07-03
Brandon Schaefer (community) 2012-07-03 Approve on 2012-07-03
Review via email: mp+113145@code.launchpad.net

Commit Message

TextEntry: make the clipboard functions virtual to be implemented by clients

Description of the Change

Added virtual methods for clipboard management, so that clients could override the code.

Added a lot of tests to check the events behavior.

UNBLOCK

To post a comment you must log in.
Brandon Schaefer (brandontschaefer) wrote :

All test pass, and look good. +1

review: Approve
Thomi Richards (thomir) wrote :

Why do we have this in the code?

195 + // TODO

We shouldn't be merging unfinished code. If it's intentionally left empty, please add a comment to that effect. Otherwise, looks great.

review: Needs Fixing (quality)
Thomi Richards (thomir) wrote :

Apparently bschafer and Trevino *promise* me that this will actually get done, and not be left in the code forever, like some unwanted relative that keeps showing up every christmas time but no one can understand them and no one really knows how they're related to the family...

Where was I? Oh yeah, Approved.

review: Approve (quality)
656. By Marco Trevisan (Treviño) on 2012-07-03

InputMethodIBus: fix IsHotkeyEvent for key-up events

657. By Marco Trevisan (Treviño) on 2012-07-03

TextEntry: make IBus to be the first to eat events, also ignore keyup ones

Only ibus can need keyup events, so we just send them to it.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Nux/InputMethodIBus.cpp'
2--- Nux/InputMethodIBus.cpp 2012-07-03 13:57:17 +0000
3+++ Nux/InputMethodIBus.cpp 2012-07-03 23:03:18 +0000
4@@ -122,6 +122,7 @@
5 NULL,
6 reinterpret_cast<GAsyncReadyCallback>(ProcessKeyEventDone),
7 new ProcessKeyEventData(this, event));
8+
9 return true;
10 }
11 return false;
12@@ -372,7 +373,8 @@
13 void IBusIMEContext::ProcessKeyEventDone(IBusInputContext *context, GAsyncResult* res, ProcessKeyEventData *data)
14 {
15 //nuxDebugMsg("***IBusIMEContext::ProcessKeyEventDone***");
16- nuxAssert(data->context->context_ == context);
17+ std::unique_ptr<ProcessKeyEventData> key_ev(data);
18+ nuxAssert(key_ev->context->context_ == context);
19
20 GError *error = NULL;
21 gboolean processed = ibus_input_context_process_key_event_async_finish (
22@@ -380,22 +382,20 @@
23 res,
24 &error);
25
26- if (error != NULL)
27+ if (error)
28 {
29 g_warning ("Process Key Event failed: %s.", error->message);
30 g_error_free (error);
31 }
32
33- if (processed == FALSE)
34+ if (!processed)
35 {
36- data->context->text_entry_->ProcessKeyEvent(data->event.type(),
37- data->event.key_sym(),
38- data->event.flags() | IBUS_IGNORED_MASK,
39- data->event.character().c_str(),
40- 0);
41+ key_ev->context->text_entry_->ProcessKeyEvent(key_ev->event.type(),
42+ key_ev->event.key_sym(),
43+ key_ev->event.flags() | IBUS_IGNORED_MASK,
44+ key_ev->event.character().c_str(),
45+ 0);
46 }
47-
48- delete data;
49 }
50
51 std::vector<Event> IBusIMEContext::ParseIBusHotkeys(const gchar** keybindings)
52@@ -506,7 +506,7 @@
53 {
54 if (ev.x11_keysym == keysym && (ev.type == type || type == EVENT_KEY_DOWN))
55 {
56- if (type == EVENT_KEY_UP)
57+ if (ev.type == EVENT_KEY_UP)
58 return (modifiers & ev.key_modifiers);
59 else
60 return (ev.key_modifiers == modifiers);
61
62=== modified file 'Nux/TextEntry.cpp'
63--- Nux/TextEntry.cpp 2012-07-03 19:16:38 +0000
64+++ Nux/TextEntry.cpp 2012-07-03 23:03:18 +0000
65@@ -237,15 +237,26 @@
66
67 void TextEntry::ProcessMouseEvent(int event_type, int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
68 {
69- if (GetEventButton(button_flags) != 1 && event_type != NUX_MOUSE_MOVE)
70- return;
71-
72- //ResetImContext();
73- //Event::Type type = event.GetType();
74-
75 int X = static_cast<int>(x /*round(event.GetX())*/) - kInnerBorderX - scroll_offset_x_;
76 int Y = static_cast<int>(y /*round(event.GetY())*/) - kInnerBorderY - scroll_offset_y_;
77 int index = XYToTextIndex(X, Y);
78+ MouseButton button = GetEventButton(button_flags);
79+
80+ if (event_type == NUX_MOUSE_PRESSED && (button == 2 || button == 3))
81+ {
82+ SetCursor(index);
83+#if defined(NUX_OS_LINUX)
84+ if (button == 2)
85+ PastePrimaryClipboard();
86+#endif
87+ QueueRefresh(false, true);
88+
89+ return;
90+ }
91+
92+ if (button != 1 && event_type != NUX_MOUSE_MOVE)
93+ return;
94+
95 int sel_start, sel_end;
96 GetSelectionBounds(&sel_start, &sel_end);
97
98@@ -253,7 +264,7 @@
99
100 if ((event_type == NUX_MOUSE_PRESSED) && (current_time - last_dblclick_time_ <= kTripleClickTimeout))
101 {
102- SelectLine();
103+ SelectLine();
104 }
105 else if (event_type == NUX_MOUSE_DOUBLECLICK && !ime_active_)
106 {
107@@ -294,7 +305,22 @@
108 const char* character , /*character*/
109 unsigned short keyCount /*key repeat count*/)
110 {
111- bool im_filtered = false;
112+#if defined(NUX_OS_LINUX)
113+ if (im_running())
114+ {
115+ // FIXME Have to get the current event for the x11_keycode for ibus-hangul/korean input
116+ nux::Event const& cur_event = GetGraphicsDisplay()->GetCurrentEvent();
117+ KeyEvent event(static_cast<EventType>(event_type), keysym, cur_event.x11_keycode, state, character);
118+
119+ if (ime_->FilterKeyEvent(event))
120+ return;
121+ }
122+#endif
123+
124+ /* Ignore all the keyup events to make Composition and Dead keys to work,
125+ * as no one (IBus a part) needs them */
126+ if (event_type == NUX_KEYUP)
127+ return;
128
129 #if defined(NUX_OS_LINUX)
130 if (dead_key_mode_ && keysym == XK_space)
131@@ -313,17 +339,10 @@
132 {
133 return;
134 }
135-
136- // FIXME Have to get the current event fot he x11_keycode for ibus-hangul/korean input
137- nux::Event const& cur_event = GetGraphicsDisplay()->GetCurrentEvent();
138- KeyEvent event(static_cast<EventType>(event_type), keysym, cur_event.x11_keycode, state, character);
139- im_filtered = ime_->FilterKeyEvent(event);
140 #endif
141
142 if (event_type == NUX_KEYDOWN)
143 text_input_mode_ = true;
144- else if (event_type == NUX_KEYUP)
145- return;
146
147 cursor_blink_status_ = 4;
148
149@@ -343,7 +362,7 @@
150 if (keysym == NUX_VK_TAB)
151 return;
152
153- if ((keysym == NUX_VK_ENTER || keysym == NUX_KP_ENTER) && !im_filtered)
154+ if ((keysym == NUX_VK_ENTER || keysym == NUX_KP_ENTER))
155 {
156 activated.emit();
157 return;
158@@ -354,7 +373,7 @@
159 bool ctrl = (state & NUX_STATE_CTRL);
160
161 // DLOG("TextEntry::key_down(%d, shift:%d ctrl:%d)", keyval, shift, ctrl);
162- if (event_type == NUX_KEYDOWN && !im_filtered)
163+ if (event_type == NUX_KEYDOWN)
164 {
165 if (keyval == NUX_VK_LEFT)
166 {
167@@ -464,18 +483,15 @@
168 // }
169 }
170
171- if (!im_filtered)
172+ if (character)
173 {
174- if (character)
175- {
176- unsigned int utf_char = g_utf8_get_char(character);
177-
178- if (g_unichar_isprint(utf_char))
179- EnterText(character);
180- }
181-
182- QueueRefresh(false, true);
183+ unsigned int utf_char = g_utf8_get_char(character);
184+
185+ if (g_unichar_isprint(utf_char))
186+ EnterText(character);
187 }
188+
189+ QueueRefresh(false, true);
190 }
191
192 void TextEntry::RecvMouseDoubleClick(int x, int y, unsigned long button_flags, unsigned long key_flags)
193@@ -610,7 +626,7 @@
194 {
195 #if defined(NUX_OS_LINUX)
196 /* Checks if the keysym between the first and last dead key */
197- if ((keysym >= XK_dead_grave) && (keysym <= XK_dead_stroke) && !dead_key_mode_)
198+ if (character && (keysym >= XK_dead_grave) && (keysym <= XK_dead_stroke) && !dead_key_mode_)
199 {
200 int key = keysym - XK_dead_grave;
201 dead_key_mode_ = true;
202@@ -656,7 +672,7 @@
203 return true;
204 }
205
206- if (composition_mode_)
207+ if (composition_mode_ && character)
208 {
209 if (strncmp(character, "", 1) == 0 && keysym != NUX_VK_SHIFT)
210 {
211@@ -1782,6 +1798,7 @@
212 {
213 CopyClipboard();
214 DeleteSelection();
215+ QueueRefresh(true, true);
216 }
217
218 void TextEntry::PasteClipboard()
219@@ -1795,6 +1812,13 @@
220 // }
221 }
222
223+#if defined(NUX_OS_LINUX)
224+ void TextEntry::PastePrimaryClipboard()
225+ {
226+ // TODO
227+ }
228+#endif
229+
230 void TextEntry::BackSpace(MovementStep step)
231 {
232 if (GetSelectionBounds(NULL, NULL))
233
234=== modified file 'Nux/TextEntry.h'
235--- Nux/TextEntry.h 2012-07-03 19:16:38 +0000
236+++ Nux/TextEntry.h 2012-07-03 23:03:18 +0000
237@@ -325,11 +325,15 @@
238 void DeleteSelection();
239
240 /** Cut the current selected text to the clipboard */
241- void CutClipboard();
242+ virtual void CutClipboard();
243 /** Copy the current selected text to the clipboard */
244- void CopyClipboard();
245+ virtual void CopyClipboard();
246 /** Paste the text in the clipboard to current offset */
247- void PasteClipboard();
248+ virtual void PasteClipboard();
249+#if defined(NUX_OS_LINUX)
250+ /** Paste the text in the primary clipboard to current offset */
251+ virtual void PastePrimaryClipboard();
252+#endif
253 /** Delete a character before the offset of the cursor */
254 void BackSpace(MovementStep step);
255 /** Delete a character at the offset of the cursor */
256
257=== modified file 'tests/gtest-nux-textentry.cpp'
258--- tests/gtest-nux-textentry.cpp 2012-07-03 14:55:18 +0000
259+++ tests/gtest-nux-textentry.cpp 2012-07-03 23:03:18 +0000
260@@ -1,26 +1,64 @@
261+/*
262+ * Copyright 2012 Canonical Ltd.
263+ *
264+ * This program is free software: you can redistribute it and/or modify it
265+ * under the terms of the GNU Lesser General Public License version 3, as
266+ * published by the Free Software Foundation.
267+ *
268+ * This program is distributed in the hope that it will be useful, but
269+ * WITHOUT ANY WARRANTY; without even the implied warranties of
270+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
271+ * PURPOSE. See the applicable version of the GNU Lesser General Public
272+ * License for more details.
273+ *
274+ * You should have received a copy of both the GNU Lesser General Public
275+ * License version 3 along with this program. If not, see
276+ * <http://www.gnu.org/licenses/>
277+ *
278+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
279+ *
280+ */
281+
282+#include "gtest-nux-utils.h"
283+
284 #include <gmock/gmock.h>
285
286 #include "Nux/Nux.h"
287 #include "Nux/TextEntry.h"
288+#include "Nux/HLayout.h"
289 #if defined(NUX_OS_LINUX)
290 #include "Nux/InputMethodIBus.h"
291 #endif
292
293-
294 using namespace testing;
295 using namespace nux;
296
297 namespace {
298
299-class MockTextEntry : public nux::TextEntry
300+class MockTextEntry : public TextEntry
301 {
302 public:
303- MockTextEntry(const char* text) : nux::TextEntry(text)
304+ MockTextEntry() : TextEntry("")
305 {}
306
307- bool InspectKeyEvent(nux::Event const& event)
308- {
309- return nux::TextEntry::InspectKeyEvent(event);
310+ bool InspectKeyEvent(Event const& event)
311+ {
312+ return TextEntry::InspectKeyEvent(event);
313+ }
314+
315+ bool GetSelectionBounds(int* start, int* end) const
316+ {
317+ return TextEntry::GetSelectionBounds(start, end);
318+ }
319+
320+ int GetCursor() const
321+ {
322+ return cursor_;
323+ }
324+
325+ void SetCursor(int cursor)
326+ {
327+ TextEntry::SetCursor(cursor);
328 }
329
330 nux::IBusIMEContext* ime() const
331@@ -31,6 +69,44 @@
332 return nullptr;
333 #endif
334 }
335+
336+ void WaitEvent()
337+ {
338+ if (im_running())
339+ Utils::WaitForTimeoutMSec(100);
340+ }
341+
342+ MOCK_METHOD0(CutClipboard, void());
343+ MOCK_METHOD0(CopyClipboard, void());
344+ MOCK_METHOD0(PasteClipboard, void());
345+#if defined(NUX_OS_LINUX)
346+ MOCK_METHOD0(PastePrimaryClipboard, void());
347+#endif
348+};
349+
350+class TestEvent : public Event
351+{
352+public:
353+ TestEvent(KeyModifier keymod, unsigned long keysym)
354+ {
355+ type = NUX_KEYDOWN;
356+ key_modifiers = keymod;
357+#if defined(NUX_OS_LINUX)
358+ x11_keysym = keysym;
359+#elif defined(NUX_OS_WINDOWS)
360+ win32_keysym = keysym;
361+#endif
362+ }
363+
364+ TestEvent(unsigned long keysym)
365+ {
366+ type = NUX_KEYDOWN;
367+#if defined(NUX_OS_LINUX)
368+ x11_keysym = keysym;
369+#elif defined(NUX_OS_WINDOWS)
370+ win32_keysym = keysym;
371+#endif
372+ }
373 };
374
375 class TestTextEntry : public Test
376@@ -38,16 +114,20 @@
377 public:
378 virtual void SetUp()
379 {
380- nux::NuxInitialize(0);
381- wnd_thread.reset(nux::CreateNuxWindow("Nux Window", 300, 200,
382- nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL));
383-
384- text_entry = new MockTextEntry("");
385- nux::GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(text_entry.GetPointer());
386+ NuxInitialize(0);
387+ wnd_thread.reset(CreateNuxWindow("Nux Window", 300, 200, WINDOWSTYLE_NORMAL,
388+ nullptr, false, NULL, NULL));
389+
390+ text_entry = new MockTextEntry();
391+ HLayout* layout = new HLayout();
392+ layout->AddView(text_entry);
393+ wnd_thread->SetLayout(layout);
394+
395+ GetWindowCompositor().SetKeyFocusArea(text_entry);
396 }
397
398- std::unique_ptr<nux::WindowThread> wnd_thread;
399- nux::ObjectPtr<MockTextEntry> text_entry;
400+ std::unique_ptr<WindowThread> wnd_thread;
401+ MockTextEntry* text_entry;
402 };
403
404 TEST_F(TestTextEntry, TestSetText)
405@@ -81,9 +161,9 @@
406
407 EXPECT_EQ(text_entry->IsInTextInputMode(), true);
408
409- nux::GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(NULL);
410+ GetWindowCompositor().SetKeyFocusArea(nullptr);
411
412- nux::GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(text_entry.GetPointer());
413+ GetWindowCompositor().SetKeyFocusArea(text_entry);
414
415 EXPECT_EQ(text_entry->IsInTextInputMode(), false);
416
417@@ -95,23 +175,6 @@
418 }
419
420 #if defined(NUX_OS_LINUX)
421-class TestEvent : public nux::Event
422-{
423-public:
424- TestEvent(nux::KeyModifier keymod, unsigned long keysym)
425- {
426- type = nux::NUX_KEYDOWN;
427- key_modifiers = keymod;
428- x11_keysym = keysym;
429- }
430-
431- TestEvent(unsigned long keysym)
432- {
433- type = nux::NUX_KEYDOWN;
434- x11_keysym = keysym;
435- }
436-};
437-
438 TEST_F(TestTextEntry, AltLinuxKeybindings)
439 {
440 for (unsigned long keysym = 0; keysym < XK_VoidSymbol; ++keysym)
441@@ -149,8 +212,181 @@
442 unsigned int keysym = g_utf8_get_char(c.c_str());
443 text_entry->DeleteText(0, std::numeric_limits<int>::max());
444 text_entry->key_down.emit(NUX_KEYDOWN, keysym, 0, c.c_str(), 1);
445+ text_entry->WaitEvent();
446 EXPECT_EQ(text_entry->GetText(), "");
447 }
448 }
449
450+TEST_F(TestTextEntry, CopyCtrlC)
451+{
452+ EXPECT_CALL(*text_entry, CopyClipboard());
453+ TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_c);
454+ GetWindowCompositor().ProcessEvent(event);
455+ text_entry->WaitEvent();
456+}
457+
458+TEST_F(TestTextEntry, CopyCtrlIns)
459+{
460+ EXPECT_CALL(*text_entry, CopyClipboard());
461+ TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_INSERT);
462+ GetWindowCompositor().ProcessEvent(event);
463+ text_entry->WaitEvent();
464+}
465+
466+TEST_F(TestTextEntry, PasteCtrlV)
467+{
468+ EXPECT_CALL(*text_entry, PasteClipboard());
469+ TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_v);
470+ GetWindowCompositor().ProcessEvent(event);
471+ text_entry->WaitEvent();
472+}
473+
474+TEST_F(TestTextEntry, PasteShiftIns)
475+{
476+ EXPECT_CALL(*text_entry, PasteClipboard());
477+ TestEvent event(KEY_MODIFIER_SHIFT, NUX_VK_INSERT);
478+ GetWindowCompositor().ProcessEvent(event);
479+ text_entry->WaitEvent();
480+}
481+
482+#if defined(NUX_OS_LINUX)
483+TEST_F(TestTextEntry, PastePrimaryClipboard)
484+{
485+ EXPECT_CALL(*text_entry, PastePrimaryClipboard());
486+ text_entry->mouse_down.emit(0, 0, NUX_EVENT_BUTTON2_DOWN, 0);
487+
488+ EXPECT_CALL(*text_entry, PastePrimaryClipboard()).Times(0);
489+ text_entry->mouse_down.emit(0, 0, NUX_EVENT_BUTTON1_DOWN, 0);
490+
491+ EXPECT_CALL(*text_entry, PastePrimaryClipboard()).Times(0);
492+ text_entry->mouse_down.emit(0, 0, NUX_EVENT_BUTTON3_DOWN, 0);
493+}
494+#endif
495+
496+TEST_F(TestTextEntry, CutCtrlX)
497+{
498+ EXPECT_CALL(*text_entry, CutClipboard());
499+ TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_x);
500+ GetWindowCompositor().ProcessEvent(event);
501+ text_entry->WaitEvent();
502+}
503+
504+TEST_F(TestTextEntry, CutShiftDel)
505+{
506+ EXPECT_CALL(*text_entry, CutClipboard());
507+ TestEvent event(KEY_MODIFIER_SHIFT, NUX_VK_DELETE);
508+ GetWindowCompositor().ProcessEvent(event);
509+ text_entry->WaitEvent();
510+}
511+
512+TEST_F(TestTextEntry, CtrlA)
513+{
514+ TestEvent selectall(KEY_MODIFIER_CTRL, NUX_VK_a);
515+ int start, end;
516+ const std::string test_str("Nux");
517+ text_entry->EnterText(test_str.c_str());
518+ EXPECT_FALSE(text_entry->GetSelectionBounds(&start, &end));
519+ ASSERT_EQ(start, end);
520+ ASSERT_EQ(start, test_str.length());
521+
522+ GetWindowCompositor().ProcessEvent(selectall);
523+ text_entry->WaitEvent();
524+ EXPECT_TRUE(text_entry->GetSelectionBounds(&start, &end));
525+ EXPECT_EQ(start, 0);
526+ EXPECT_EQ(end, test_str.length());
527+}
528+
529+TEST_F(TestTextEntry, MoveKeys)
530+{
531+ const std::string test_str("Nux");
532+ text_entry->EnterText(test_str.c_str());
533+ ASSERT_EQ(text_entry->GetCursor(), test_str.length());
534+ text_entry->SetCursor(0);
535+ ASSERT_EQ(text_entry->GetCursor(), 0);
536+
537+ TestEvent right(NUX_VK_RIGHT);
538+ GetWindowCompositor().ProcessEvent(right);
539+ text_entry->WaitEvent();
540+ EXPECT_EQ(text_entry->GetCursor(), 1);
541+
542+ TestEvent end(NUX_VK_END);
543+ GetWindowCompositor().ProcessEvent(end);
544+ text_entry->WaitEvent();
545+ EXPECT_EQ(text_entry->GetCursor(), test_str.length());
546+
547+ TestEvent left(NUX_VK_LEFT);
548+ GetWindowCompositor().ProcessEvent(left);
549+ text_entry->WaitEvent();
550+ EXPECT_EQ(text_entry->GetCursor(), 2);
551+
552+ TestEvent home(NUX_VK_HOME);
553+ GetWindowCompositor().ProcessEvent(home);
554+ text_entry->WaitEvent();
555+ EXPECT_EQ(text_entry->GetCursor(), 0);
556+}
557+
558+TEST_F(TestTextEntry, CtrlMoveKeys)
559+{
560+ const std::string test_str("Nux Text Entry");
561+ text_entry->EnterText(test_str.c_str());
562+ ASSERT_EQ(text_entry->GetCursor(), test_str.length());
563+ text_entry->SetCursor(0);
564+ ASSERT_EQ(text_entry->GetCursor(), 0);
565+
566+ TestEvent right(KEY_MODIFIER_CTRL, NUX_VK_RIGHT);
567+ GetWindowCompositor().ProcessEvent(right);
568+ text_entry->WaitEvent();
569+ EXPECT_EQ(text_entry->GetCursor(), 3);
570+
571+ TestEvent left(KEY_MODIFIER_CTRL, NUX_VK_LEFT);
572+ GetWindowCompositor().ProcessEvent(left);
573+ text_entry->WaitEvent();
574+ EXPECT_EQ(text_entry->GetCursor(), 0);
575+
576+ TestEvent end(KEY_MODIFIER_CTRL, NUX_VK_END);
577+ GetWindowCompositor().ProcessEvent(end);
578+ text_entry->WaitEvent();
579+ EXPECT_EQ(text_entry->GetCursor(), test_str.length());
580+
581+ TestEvent home(KEY_MODIFIER_CTRL, NUX_VK_HOME);
582+ GetWindowCompositor().ProcessEvent(home);
583+ text_entry->WaitEvent();
584+ EXPECT_EQ(text_entry->GetCursor(), 0);
585+}
586+
587+TEST_F(TestTextEntry, DeleteKeys)
588+{
589+ const std::string test_str("Nux");
590+ text_entry->EnterText(test_str.c_str());
591+ text_entry->SetCursor(0);
592+
593+ TestEvent del(NUX_VK_DELETE);
594+ GetWindowCompositor().ProcessEvent(del);
595+ text_entry->WaitEvent();
596+ EXPECT_EQ(text_entry->GetText(), "ux");
597+
598+ text_entry->SetCursor(std::string(text_entry->GetText()).length());
599+ TestEvent backspace(NUX_VK_BACKSPACE);
600+ GetWindowCompositor().ProcessEvent(backspace);
601+ text_entry->WaitEvent();
602+ EXPECT_EQ(text_entry->GetText(), "u");
603+}
604+
605+TEST_F(TestTextEntry, CtrlDeleteKeys)
606+{
607+ const std::string test_str("Nux Text Entry");
608+ text_entry->EnterText(test_str.c_str());
609+ text_entry->SetCursor(0);
610+
611+ TestEvent del(KEY_MODIFIER_CTRL, NUX_VK_DELETE);
612+ GetWindowCompositor().ProcessEvent(del);
613+ text_entry->WaitEvent();
614+ EXPECT_EQ(text_entry->GetText(), " Text Entry");
615+
616+ text_entry->SetCursor(std::string(text_entry->GetText()).length());
617+ TestEvent backspace(KEY_MODIFIER_CTRL, NUX_VK_BACKSPACE);
618+ GetWindowCompositor().ProcessEvent(backspace);
619+ text_entry->WaitEvent();
620+ EXPECT_EQ(text_entry->GetText(), " Text ");
621+}
622 }
623
624=== added file 'tests/gtest-nux-utils.h'
625--- tests/gtest-nux-utils.h 1970-01-01 00:00:00 +0000
626+++ tests/gtest-nux-utils.h 2012-07-03 23:03:18 +0000
627@@ -0,0 +1,58 @@
628+#ifndef TEST_UTILS_H
629+#define TEST_UTILS_H
630+
631+#include <glib.h>
632+#include <gtest/gtest.h>
633+
634+namespace
635+{
636+
637+class Utils
638+{
639+public:
640+ static void WaitUntil(bool& success, unsigned int max_wait = 10)
641+ {
642+ bool timeout_reached = false;
643+ guint32 timeout_id = ScheduleTimeout(&timeout_reached, max_wait * 1000);
644+
645+ while (!success && !timeout_reached)
646+ g_main_context_iteration(g_main_context_get_thread_default(), TRUE);
647+
648+ if (success)
649+ g_source_remove(timeout_id);
650+
651+ EXPECT_TRUE(success);
652+ }
653+
654+ static guint32 ScheduleTimeout(bool* timeout_reached, unsigned int timeout_duration = 10)
655+ {
656+ return g_timeout_add(timeout_duration, TimeoutCallback, timeout_reached);
657+ }
658+
659+ static void WaitForTimeout(unsigned int timeout_duration = 10)
660+ {
661+ WaitForTimeoutMSec(timeout_duration * 1000);
662+ }
663+
664+ static void WaitForTimeoutMSec(unsigned int timeout_duration = 10)
665+ {
666+ bool timeout_reached = false;
667+ guint32 timeout_id = ScheduleTimeout(&timeout_reached, timeout_duration);
668+
669+ while (!timeout_reached)
670+ g_main_context_iteration(g_main_context_get_thread_default(), TRUE);
671+
672+ g_source_remove(timeout_id);
673+ }
674+
675+private:
676+ static gboolean TimeoutCallback(gpointer data)
677+ {
678+ *(bool*)data = true;
679+ return FALSE;
680+ };
681+};
682+
683+}
684+
685+#endif
686
687=== modified file 'tests/xtest-text-entry.cpp'
688--- tests/xtest-text-entry.cpp 2012-07-02 22:56:02 +0000
689+++ tests/xtest-text-entry.cpp 2012-07-03 23:03:18 +0000
690@@ -353,13 +353,13 @@
691 {
692 // Type random stuff
693 {
694- test.ViewSendString("qwerty");
695+ test.ViewSendString("ninhao");
696 nux::SleepForMilliseconds(500);
697 test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "TextEntry is only Preedit");
698
699 test.ViewSendChar('1');
700 nux::SleepForMilliseconds(500);
701- test.TestReportMsg(test_textentry->text_entry_->GetText() == "请问儿童有", "TextEntry is \"请问儿童有\"");
702+ test.TestReportMsg(test_textentry->text_entry_->GetText() == "您好", "TextEntry is \"您好\"");
703
704 test.ViewSendCtrlA();
705 nux::SleepForMilliseconds(500);

Subscribers

People subscribed via source and target branches