]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/textctrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ----------------------------------------------------------------------------
14 // ----------------------------------------------------------------------------
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
20 #include "wx/textctrl.h"
21 #include "wx/settings.h"
29 #include "wx/clipbrd.h"
32 #include "wx/textfile.h"
34 #include "wx/os2/private.h"
38 #include <sys/types.h>
46 #if !USE_SHARED_LIBRARY
48 // ----------------------------------------------------------------------------
49 // event tables and other macros
50 // ----------------------------------------------------------------------------
52 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
54 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
55 EVT_CHAR(wxTextCtrl::OnChar
)
56 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
58 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
59 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
60 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
61 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
62 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
64 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
65 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
66 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
67 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
68 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
71 #endif // USE_SHARED_LIBRARY
73 // ============================================================================
75 // ============================================================================
77 // ----------------------------------------------------------------------------
79 // ----------------------------------------------------------------------------
81 wxTextCtrl::wxTextCtrl()
85 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
86 const wxString
& value
,
91 # if defined(__VISAGECPP__)
92 const wxValidator
* validator
,
94 const wxValidator
& validator
,
99 // base initialization
100 if ( !CreateBase(parent
, id
, pos
, size
, style
, validator
, name
) )
103 // Validator was set in CreateBase
104 //SetValidator(validator);
106 parent
->AddChild(this);
111 // translate wxWin style flags to MSW ones, checking for consistency while
115 long msStyle = ES_LEFT | WS_VISIBLE | WS_CHILD | WS_TABSTOP;
116 if ( m_windowStyle & wxTE_MULTILINE )
118 wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER),
119 wxT("wxTE_PROCESS_ENTER style is ignored for multiline "
120 "text controls (they always process it)") );
122 msStyle |= ES_MULTILINE | ES_WANTRETURN;
123 if ((m_windowStyle & wxTE_NO_VSCROLL) == 0)
124 msStyle |= WS_VSCROLL;
125 m_windowStyle |= wxTE_PROCESS_ENTER;
128 msStyle |= ES_AUTOHSCROLL;
130 if (m_windowStyle & wxHSCROLL)
131 msStyle |= (WS_HSCROLL | ES_AUTOHSCROLL);
133 if (m_windowStyle & wxTE_READONLY)
134 msStyle |= ES_READONLY;
136 if (m_windowStyle & wxHSCROLL)
137 msStyle |= (WS_HSCROLL | ES_AUTOHSCROLL);
138 if (m_windowStyle & wxTE_PASSWORD) // hidden input
139 msStyle |= ES_PASSWORD;
141 // we always want the characters and the arrows
142 m_lDlgCode = DLGC_WANTCHARS | DLGC_WANTARROWS;
144 // we may have several different cases:
145 // 1. normal case: both TAB and ENTER are used for dialog navigation
146 // 2. ctrl which wants TAB for itself: ENTER is used to pass to the next
147 // control in the dialog
148 // 3. ctrl which wants ENTER for itself: TAB is used for dialog navigation
149 // 4. ctrl which wants both TAB and ENTER: Ctrl-ENTER is used to pass to
151 if ( m_windowStyle & wxTE_PROCESS_ENTER )
152 m_lDlgCode |= DLGC_WANTMESSAGE;
153 if ( m_windowStyle & wxTE_PROCESS_TAB )
154 m_lDlgCode |= DLGC_WANTTAB;
156 // do create the control - either an EDIT or RICHEDIT
157 const wxChar *windowClass = wxT("EDIT");
160 WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
162 // Even with extended styles, need to combine with WS_BORDER for them to
164 if ( want3D || wxStyleHasBorder(m_windowStyle) )
165 msStyle |= WS_BORDER;
167 // NB: don't use pos and size as CreateWindowEx arguments because they
168 // might be -1 in which case we should use the default values (and
169 // SetSize called below takes care of it)
170 m_hWnd = (WXHWND)::CreateWindowEx(exStyle,
180 wxCHECK_MSG( m_hWnd, FALSE, wxT("Failed to create text ctrl") );
182 SubclassWin(GetHWND());
184 // set font, position, size and initial value
185 wxFont
& fontParent
= parent
->GetFont();
186 if ( fontParent
.Ok() )
192 SetFont(wxSystemSettings::GetSystemFont(wxSYS_SYSTEM_FONT
));
195 SetSize(pos
.x
, pos
.y
, size
.x
, size
.y
);
200 // Make sure the window style (etc.) reflects the HWND style (roughly)
201 void wxTextCtrl::AdoptAttributesFromHWND()
203 wxWindow::AdoptAttributesFromHWND();
205 HWND hWnd
= GetHwnd();
208 long style = GetWindowLong(hWnd, GWL_STYLE);
210 if (style & ES_MULTILINE)
211 m_windowStyle |= wxTE_MULTILINE;
212 if (style & ES_PASSWORD)
213 m_windowStyle |= wxTE_PASSWORD;
214 if (style & ES_READONLY)
215 m_windowStyle |= wxTE_READONLY;
216 if (style & ES_WANTRETURN)
217 m_windowStyle |= wxTE_PROCESS_ENTER;
221 void wxTextCtrl::SetupColours()
223 // FIXME why is bg colour not inherited from parent?
224 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW
));
225 SetForegroundColour(GetParent()->GetForegroundColour());
228 // ----------------------------------------------------------------------------
229 // set/get the controls text
230 // ----------------------------------------------------------------------------
232 wxString
wxTextCtrl::GetValue() const
234 return wxGetWindowText(GetHWND());
237 void wxTextCtrl::SetValue(const wxString
& value
)
241 wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos);
243 SetWindowText(GetHwnd(), valueDos);
249 void wxTextCtrl::WriteText(const wxString
& value
)
253 wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos);
255 SendMessage(GetHwnd(), EM_REPLACESEL, 0, (LPARAM)valueDos.c_str());
261 void wxTextCtrl::AppendText(const wxString
& text
)
265 SetInsertionPointEnd();
270 void wxTextCtrl::Clear()
272 // SetWindowText(GetHwnd(), wxT(""));
275 // ----------------------------------------------------------------------------
276 // Clipboard operations
277 // ----------------------------------------------------------------------------
279 void wxTextCtrl::Copy()
283 HWND hWnd
= GetHwnd();
284 // SendMessage(hWnd, WM_COPY, 0, 0L);
288 void wxTextCtrl::Cut()
292 HWND hWnd
= GetHwnd();
293 // SendMessage(hWnd, WM_CUT, 0, 0L);
297 void wxTextCtrl::Paste()
301 HWND hWnd
= GetHwnd();
302 // SendMessage(hWnd, WM_PASTE, 0, 0L);
306 bool wxTextCtrl::CanCopy() const
308 // Can copy if there's a selection
310 // GetSelection(& from, & to);
314 bool wxTextCtrl::CanCut() const
316 // Can cut if there's a selection
318 // GetSelection(& from, & to);
322 bool wxTextCtrl::CanPaste() const
327 // Standard edit control: check for straight text on clipboard
328 bool isTextAvailable
= FALSE
;
331 if ( ::OpenClipboard(GetHwndOf(wxTheApp->GetTopWindow())) )
333 isTextAvailable = (::IsClipboardFormatAvailable(CF_TEXT) != 0);
337 return isTextAvailable
;
340 // ----------------------------------------------------------------------------
342 // ----------------------------------------------------------------------------
344 void wxTextCtrl::SetEditable(bool editable
)
346 HWND hWnd
= GetHwnd();
347 // SendMessage(hWnd, EM_SETREADONLY, (WPARAM)!editable, (LPARAM)0L);
350 void wxTextCtrl::SetInsertionPoint(long pos
)
354 HWND hWnd = GetHwnd();
356 SendMessage(hWnd, EM_SETSEL, pos, pos);
357 SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);
359 static const char *nothing = "";
360 SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)nothing);
364 void wxTextCtrl::SetInsertionPointEnd()
368 long pos = GetLastPosition();
369 SetInsertionPoint(pos);
373 long wxTextCtrl::GetInsertionPoint() const
377 DWORD Pos = (DWORD)SendMessage(GetHwnd(), EM_GETSEL, 0, 0L);
383 long wxTextCtrl::GetLastPosition() const
385 HWND hWnd
= GetHwnd();
389 // Will always return a number > 0 (according to docs)
390 int noLines = (int)SendMessage(hWnd, EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0L);
392 // This gets the char index for the _beginning_ of the last line
393 int charIndex = (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)(noLines-1), (LPARAM)0L);
395 // Get number of characters in the last line. We'll add this to the character
396 // index for the last line, 1st position.
397 int lineLength = (int)SendMessage(hWnd, EM_LINELENGTH, (WPARAM)charIndex, (LPARAM)0L);
399 return (long)(charIndex + lineLength);
404 // If the return values from and to are the same, there is no
406 void wxTextCtrl::GetSelection(long* from
, long* to
) const
408 DWORD dwStart
, dwEnd
;
409 MPARAM wParam
= (MPARAM
) (DWORD
*) & dwStart
; // receives starting position
410 MPARAM lParam
= (MPARAM
) (DWORD
*) & dwEnd
; // receives ending position
412 // ::SendMessage(GetHwnd(), EM_GETSEL, wParam, lParam);
418 bool wxTextCtrl::IsEditable() const
422 long style = ::GetWindowLong(GetHwnd(), GWL_STYLE);
424 return ((style & ES_READONLY) == 0);
429 // ----------------------------------------------------------------------------
431 // ----------------------------------------------------------------------------
433 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
436 HWND hWnd
= GetHwnd();
437 long fromChar
= from
;
440 // Set selection and remove it
441 // SendMessage(hWnd, EM_SETSEL, fromChar, toChar);
442 // SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0);
444 // Now replace with 'value', by pasting.
445 wxSetClipboardData(wxDF_TEXT
, (wxObject
*) (const wxChar
*)value
, 0, 0);
447 // Paste into edit control
448 // SendMessage(hWnd, WM_PASTE, (WPARAM)0, (LPARAM)0L);
450 wxFAIL_MSG("wxTextCtrl::Replace not implemented if wxUSE_CLIPBOARD is 0.");
454 void wxTextCtrl::Remove(long from
, long to
)
456 HWND hWnd
= GetHwnd();
457 long fromChar
= from
;
460 // Cut all selected text
461 // SendMessage(hWnd, EM_SETSEL, fromChar, toChar);
462 // SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0);
465 void wxTextCtrl::SetSelection(long from
, long to
)
467 HWND hWnd
= GetHwnd();
468 long fromChar
= from
;
471 // if from and to are both -1, it means (in wxWindows) that all text should
472 // be selected. Translate into Windows convention
473 if ((from
== -1) && (to
== -1))
479 // SendMessage(hWnd, EM_SETSEL, (WPARAM)fromChar, (LPARAM)toChar);
480 // SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);
483 bool wxTextCtrl::LoadFile(const wxString
& file
)
487 if ( wxTextCtrlBase::LoadFile(file) )
489 // update the size limit if needed
498 bool wxTextCtrl::IsModified() const
500 // return (SendMessage(GetHwnd(), EM_GETMODIFY, 0, 0) != 0);
504 // Makes 'unmodified'
505 void wxTextCtrl::DiscardEdits()
507 // SendMessage(GetHwnd(), EM_SETMODIFY, FALSE, 0L);
510 int wxTextCtrl::GetNumberOfLines() const
512 // return (int)SendMessage(GetHwnd(), EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0);
516 long wxTextCtrl::XYToPosition(long x
, long y
) const
518 HWND hWnd
= GetHwnd();
520 // This gets the char index for the _beginning_ of this line
523 int charIndex = (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)y, (LPARAM)0);
524 return (long)(x + charIndex);
529 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
531 HWND hWnd
= GetHwnd();
533 // This gets the line number containing the character
535 // lineNo = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)pos, 0);
543 // This gets the char index for the _beginning_ of this line
544 int charIndex
= 0; // TODO: (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)lineNo, (LPARAM)0);
545 if ( charIndex
== -1 )
550 // The X position must therefore be the different between pos and charIndex
552 *x
= (long)(pos
- charIndex
);
559 void wxTextCtrl::ShowPosition(long pos
)
561 HWND hWnd
= GetHwnd();
563 // To scroll to a position, we pass the number of lines and characters
564 // to scroll *by*. This means that we need to:
565 // (1) Find the line position of the current line.
566 // (2) Find the line position of pos.
567 // (3) Scroll by (pos - current).
568 // For now, ignore the horizontal scrolling.
570 // Is this where scrolling is relative to - the line containing the caret?
571 // Or is the first visible line??? Try first visible line.
572 // int currentLineLineNo1 = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)-1, (LPARAM)0L);
576 int currentLineLineNo = (int)SendMessage(hWnd, EM_GETFIRSTVISIBLELINE, (WPARAM)0, (LPARAM)0L);
578 int specifiedLineLineNo = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)pos, (LPARAM)0L);
580 int linesToScroll = specifiedLineLineNo - currentLineLineNo;
582 if (linesToScroll != 0)
583 (void)SendMessage(hWnd, EM_LINESCROLL, (WPARAM)0, (LPARAM)linesToScroll);
587 int wxTextCtrl::GetLineLength(long lineNo
) const
592 long charIndex = XYToPosition(0, lineNo);
593 int len = (int)SendMessage(GetHwnd(), EM_LINELENGTH, charIndex, 0);
599 wxString
wxTextCtrl::GetLineText(long lineNo
) const
601 size_t len
= (size_t)GetLineLength(lineNo
) + 1;
602 char *buf
= (char *)malloc(len
);
604 int noChars
= 0; // TODO:(int)SendMessage(GetHwnd(), EM_GETLINE, lineNo, (LPARAM)buf);
614 // ----------------------------------------------------------------------------
616 // ----------------------------------------------------------------------------
618 void wxTextCtrl::Undo()
622 // ::SendMessage(GetHwnd(), EM_UNDO, 0, 0);
626 void wxTextCtrl::Redo()
630 // Same as Undo, since Undo undoes the undo, i.e. a redo.
631 // ::SendMessage(GetHwnd(), EM_UNDO, 0, 0);
635 bool wxTextCtrl::CanUndo() const
637 // return (::SendMessage(GetHwnd(), EM_CANUNDO, 0, 0) != 0);
641 bool wxTextCtrl::CanRedo() const
643 // return (::SendMessage(GetHwnd(), EM_CANUNDO, 0, 0) != 0);
647 // ----------------------------------------------------------------------------
648 // implemenation details
649 // ----------------------------------------------------------------------------
651 void wxTextCtrl::Command(wxCommandEvent
& event
)
653 SetValue(event
.GetString());
654 ProcessCommand (event
);
657 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
659 // By default, load the first file into the text window.
660 if (event
.GetNumberOfFiles() > 0)
662 LoadFile(event
.GetFiles()[0]);
666 WXHBRUSH
wxTextCtrl::OnCtlColor(WXHDC pDC
, WXHWND pWnd
, WXUINT nCtlColor
,
667 WXUINT message
, WXWPARAM wParam
,
673 SetBkMode(hdc, GetParent()->GetTransparentBackground() ? TRANSPARENT
676 ::SetBkColor(hdc, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
677 ::SetTextColor(hdc, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
679 wxBrush
*backgroundBrush
= wxTheBrushList
->FindOrCreateBrush(GetBackgroundColour(), wxSOLID
);
681 return (WXHBRUSH
) backgroundBrush
->GetResourceHandle();
684 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
686 switch ( event
.KeyCode() )
691 if ( !(m_windowStyle & wxTE_MULTILINE) )
693 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
694 event.SetEventObject( this );
695 if ( GetEventHandler()->ProcessEvent(event) )
698 //else: multiline controls need Enter for themselves
703 // always produce navigation event - even if we process TAB
704 // ourselves the fact that we got here means that the user code
705 // decided to skip processing of this TAB - probably to let it
706 // do its default job.
708 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
709 // handled by Windows
711 wxNavigationKeyEvent eventNav;
712 eventNav.SetDirection(!event.ShiftDown());
713 eventNav.SetWindowChange(FALSE);
714 eventNav.SetEventObject(this);
716 if ( GetEventHandler()->ProcessEvent(eventNav) )
726 // don't just call event.Skip() because this will cause TABs and ENTERs
727 // be passed upwards and we don't always want this - instead process it
734 bool wxTextCtrl::OS2Command(WXUINT param
, WXWORD
WXUNUSED(id
))
743 wxFocusEvent event(param == EN_KILLFOCUS ? wxEVT_KILL_FOCUS
746 event.SetEventObject( this );
747 GetEventHandler()->ProcessEvent(event);
753 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
754 wxString val(GetValue());
756 event.m_commandString = WXSTRINGCAST val;
757 event.SetEventObject( this );
758 ProcessCommand(event);
763 // the text size limit has been hit - increase it
767 // the other notification messages are not processed
781 void wxTextCtrl::AdjustSpaceLimit()
785 unsigned int len = ::GetWindowTextLength(GetHwnd()),
786 limit = ::SendMessage(GetHwnd(), EM_GETLIMITTEXT, 0, 0);
789 limit = len + 0x8000; // 32Kb
791 if ( limit > 0xffff )
792 ::SendMessage(GetHwnd(), EM_LIMITTEXT, 0, limit);
794 ::SendMessage(GetHwnd(), EM_LIMITTEXT, limit, 0);
799 bool wxTextCtrl::AcceptsFocus() const
801 // we don't want focus if we can't be edited
802 return IsEditable() && wxControl::AcceptsFocus();
805 wxSize
wxTextCtrl::DoGetBestSize()
808 wxGetCharSize(GetHWND(), &cx
, &cy
, &GetFont());
810 int wText
= DEFAULT_ITEM_WIDTH
;
812 int hText
= EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy
);
813 if ( m_windowStyle
& wxTE_MULTILINE
)
815 hText
*= wxMin(GetNumberOfLines(), 5);
817 //else: for single line control everything is ok
819 return wxSize(wText
, hText
);
822 // ----------------------------------------------------------------------------
823 // standard handlers for standard edit menu events
824 // ----------------------------------------------------------------------------
826 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
831 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
836 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
841 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
846 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
851 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
853 event
.Enable( CanCut() );
856 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
858 event
.Enable( CanCopy() );
861 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
863 event
.Enable( CanPaste() );
866 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
868 event
.Enable( CanUndo() );
871 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
873 event
.Enable( CanRedo() );