2
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; version 2 of the
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21
* Implementation of the textbox (multi line edit) wrapper for the mforms library.
25
#include "wf_textbox.h"
27
using namespace MySQL::Forms;
29
using namespace System::Windows::Forms;
30
using namespace System::Text;
32
DEFAULT_LOG_DOMAIN(DOMAIN_MFORMS_WRAPPER)
34
//----------------- TextBoxEx ----------------------------------------------------------------------
36
bool TextBoxEx::ProcessCmdKey(Message% msg, Keys keyData)
38
// In order to be able to determine certain special keys we have to hook into the chain before any
39
// other key handling is performed.
40
if (msg.Msg == WM_KEYDOWN)
42
switch (msg.WParam.ToInt32())
47
mforms::TextBox* backend = ObjectImpl::get_backend_control<mforms::TextBox>(this);
48
if (((msg.LParam.ToInt32() >> 16) & KF_EXTENDED) == KF_EXTENDED)
49
result = backend->key_event(mforms::KeyReturn, getModifiers(keyData), "");
51
result = backend->key_event(mforms::KeyEnter, getModifiers(keyData), "");
54
return TextBox::ProcessCmdKey(msg, keyData);
62
return TextBox::ProcessCmdKey(msg, keyData);
66
return TextBox::ProcessCmdKey(msg, keyData);
69
//--------------------------------------------------------------------------------------------------
71
mforms::ModifierKey TextBoxEx::getModifiers(Keys keyData)
73
mforms::ModifierKey modifiers = mforms::ModifierNoModifier;
74
if ((keyData & Keys::Control) == Keys::Control)
75
modifiers = modifiers | mforms::ModifierControl;
76
if ((keyData & Keys::Alt) == Keys::Alt)
77
modifiers = modifiers | mforms::ModifierAlt;
78
if ((keyData & Keys::Shift) == Keys::Shift)
79
modifiers = modifiers | mforms::ModifierShift;
80
if ((keyData & Keys::LWin) == Keys::LWin)
81
modifiers = modifiers | mforms::ModifierCommand;
86
//----------------- TextBoxImpl --------------------------------------------------------------------
88
bool TextBoxImpl::create(::mforms::TextBox *self, ::mforms::ScrollBars scroll_bars)
90
TextBoxImpl ^text= gcnew TextBoxImpl(self);
94
TextBox ^textbox= ViewImpl::create<TextBoxEx>(self, text);
95
textbox->ForeColor = Color::Black;
96
textbox->Multiline= true;
97
textbox->AcceptsReturn= true;
98
ScrollBars native_scrollbars = ScrollBars::None;
99
if ((scroll_bars & mforms::HorizontalScrollBar) != 0)
101
if ((scroll_bars & mforms::VerticalScrollBar) != 0)
102
native_scrollbars = ScrollBars::Both;
104
native_scrollbars = ScrollBars::Horizontal;
107
if ((scroll_bars & mforms::VerticalScrollBar) != 0)
108
native_scrollbars = ScrollBars::Vertical;
109
textbox->ScrollBars= native_scrollbars;
110
textbox->TextChanged += gcnew EventHandler(text, &TextBoxImpl::OnChange);
111
textbox->KeyDown += gcnew KeyEventHandler(text, &TextBoxImpl::OnKeyDown);
112
textbox->KeyPress += gcnew KeyPressEventHandler(text, &TextBoxImpl::OnKeyPress);
113
textbox->Size= Size(100, textbox->PreferredSize.Height); // DefaultSize is not accessible here.
119
//--------------------------------------------------------------------------------------------------
121
void TextBoxImpl::OnChange(Object^ sender, EventArgs^ args)
123
TextBox^ textbox= (TextBox^) sender;
125
if (textbox->Tag != nullptr)
127
::mforms::TextBox* box= ViewImpl::get_backend_control<::mforms::TextBox>(textbox);
133
//--------------------------------------------------------------------------------------------------
135
void TextBoxImpl::OnKeyDown(Object^ sender, KeyEventArgs^ args)
137
// Don't call the back end for the return key. We have already done that.
138
if (args->KeyCode != Keys::Return)
140
TextBoxEx^ textbox= (TextBoxEx^) sender;
141
if (textbox->Tag != nullptr)
143
::mforms::TextBox* box= ViewImpl::get_backend_control<::mforms::TextBox>(textbox);
145
modifiers = textbox->getModifiers(args->KeyData);
146
mforms::KeyCode code = mforms::KeyNone;
147
switch (args->KeyCode & Keys::KeyCode)
150
code = mforms::KeyHome;
154
code = mforms::KeyEnd;
158
code = mforms::KeyPrevious;
162
code = mforms::KeyNext;
166
case Keys::ControlKey:
167
case Keys::Menu: // Alt key
168
case Keys::LWin: // Command on Mac.
169
code = mforms::KeyModifierOnly;
173
if (code != mforms::KeyNone)
174
if (!box->key_event(code, modifiers, ""))
175
args->Handled = true; // If the backend consumed the key (by returning false) then we stop
176
// further processing of this event.
181
//--------------------------------------------------------------------------------------------------
183
void TextBoxImpl::OnKeyPress(Object^ sender, KeyPressEventArgs^ args)
185
// Don't call the back end for the return key. We have already done that.
186
if (args->KeyChar != '\r')
188
TextBoxEx^ textbox= (TextBoxEx^) sender;
189
if (textbox->Tag != nullptr)
191
::mforms::TextBox* box= ViewImpl::get_backend_control<::mforms::TextBox>(textbox);
192
String^ string = gcnew String(args->KeyChar, 1);
193
if (!box->key_event(mforms::KeyChar, modifiers, NativeToCppString(string)))
194
args->Handled = true;
199
//--------------------------------------------------------------------------------------------------
201
void TextBoxImpl::set_bordered(::mforms::TextBox *self, bool bordered)
203
TextBoxImpl^ textbox= (TextBoxImpl^)ObjectImpl::FromUnmanaged(self);
205
if (textbox != nullptr)
206
textbox->get_control<TextBox>()->BorderStyle= bordered ? BorderStyle::FixedSingle : BorderStyle::None;
209
//--------------------------------------------------------------------------------------------------
211
void TextBoxImpl::set_text(::mforms::TextBox *self, const std::string &text)
213
TextBoxImpl^ textbox= (TextBoxImpl^)ObjectImpl::FromUnmanaged(self);
215
if (textbox != nullptr)
217
// Convert LF only line breaks into Windows line breaks.
218
StringBuilder^ builder= gcnew StringBuilder(CppStringToNative(text));
219
builder->Replace("\n", Environment::NewLine);
221
textbox->get_control<Control>()->Text= builder->ToString();
225
//--------------------------------------------------------------------------------------------------
227
void TextBoxImpl::append_text(::mforms::TextBox *self, const std::string &text, bool scroll_to_end)
229
TextBoxImpl^ textbox= (TextBoxImpl^)ObjectImpl::FromUnmanaged(self);
231
if (textbox != nullptr)
233
// Convert LF only line breaks into Windows line breaks.
234
StringBuilder^ builder= gcnew StringBuilder(CppStringToNative(text));
235
builder->Replace("\n", Environment::NewLine);
237
TextBox^ native_box= textbox->get_control<TextBox>();
238
native_box->AppendText(builder->ToString());
239
if (scroll_to_end && native_box->Text->Length > 0)
241
native_box->Select(native_box->Text->Length - 1, 0);
242
native_box->ScrollToCaret();
247
//--------------------------------------------------------------------------------------------------
249
std::string TextBoxImpl::get_text(::mforms::TextBox *self)
251
TextBoxImpl^ textbox= (TextBoxImpl^)ObjectImpl::FromUnmanaged(self);
253
if (textbox != nullptr)
255
// Convert Windows line breaks to LF.
256
StringBuilder^ builder= gcnew StringBuilder(textbox->get_control<Control>()->Text);
257
builder->Replace(Environment::NewLine, "\n");
258
return NativeToCppString(builder->ToString());
263
//--------------------------------------------------------------------------------------------------
265
void TextBoxImpl::set_read_only(::mforms::TextBox *self, bool flag)
267
TextBoxImpl^ textbox= (TextBoxImpl^)ObjectImpl::FromUnmanaged(self);
269
if (textbox != nullptr)
270
textbox->get_control<TextBox>()->ReadOnly= flag;
273
//--------------------------------------------------------------------------------------------------
275
void TextBoxImpl::set_padding(::mforms::TextBox *self, int pad)
277
TextBoxImpl^ textbox= (TextBoxImpl^)ObjectImpl::FromUnmanaged(self);
279
if (textbox != nullptr)
280
textbox->get_control<TextBox>()->Padding = Padding(pad); // Doesn't have any effect.
283
//--------------------------------------------------------------------------------------------------
285
void TextBoxImpl::clear(::mforms::TextBox *self)
287
TextBoxImpl^ textbox= (TextBoxImpl^)ObjectImpl::FromUnmanaged(self);
289
if (textbox != nullptr)
290
textbox->get_control<TextBox>()->Clear();
293
//--------------------------------------------------------------------------------------------------
295
void TextBoxImpl::set_monospaced(::mforms::TextBox *self, bool flag)
297
TextBoxImpl^ textbox= (TextBoxImpl^)ObjectImpl::FromUnmanaged(self);
299
if (textbox != nullptr)
304
textbox->get_control<TextBox>()->Font = gcnew System::Drawing::Font("Bitstream Vera Sans Mono", textbox->get_control<TextBox>()->Font->Size - 2);
306
catch (System::ArgumentException^ e)
308
// Argument exception pops up when the system cannot find the Regular font style (corrupt font).
309
log_error("TextBoxImpl::set_monospaced failed. %s\n", e->Message);
312
textbox->get_control<TextBox>()->ResetFont();
316
//--------------------------------------------------------------------------------------------------
318
void TextBoxImpl::get_selected_range(::mforms::TextBox *self, int &start, int &end)
320
TextBoxImpl^ textbox= (TextBoxImpl^)ObjectImpl::FromUnmanaged(self);
322
if (textbox != nullptr)
324
start = textbox->get_control<TextBox>()->SelectionStart;
325
end = start + textbox->get_control<TextBox>()->SelectionLength;
329
//--------------------------------------------------------------------------------------------------
331
TextBoxImpl::TextBoxImpl(::mforms::TextBox *text)
336
//--------------------------------------------------------------------------------------------------