]>
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>
47 // ----------------------------------------------------------------------------
48 // event tables and other macros
49 // ----------------------------------------------------------------------------
51 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
53 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
54 EVT_CHAR(wxTextCtrl::OnChar
)
55 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
57 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
58 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
59 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
60 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
61 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
63 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
64 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
65 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
66 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
67 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
71 // ============================================================================
73 // ============================================================================
75 // ----------------------------------------------------------------------------
77 // ----------------------------------------------------------------------------
79 wxTextCtrl::wxTextCtrl()
83 bool wxTextCtrl::Create(
86 , const wxString
& rsValue
91 , const wxValidator
& rValidator
93 , const wxString
& rsName
97 // Base initialization
99 if ( !CreateBase( pParent
112 pParent
->AddChild(this);
114 m_windowStyle
= lStyle
;
116 long lSstyle
= WS_VISIBLE
| WS_TABSTOP
;
119 // Single and multiline edit fields are two different controls in PM
121 if ( m_windowStyle
& wxTE_MULTILINE
)
124 m_windowStyle
|= wxTE_PROCESS_ENTER
;
126 if ((m_windowStyle
& wxTE_NO_VSCROLL
) == 0)
127 lSstyle
|= MLS_VSCROLL
;
128 if (m_windowStyle
& wxHSCROLL
)
129 lSstyle
|= MLS_HSCROLL
;
130 if (m_windowStyle
& wxTE_READONLY
)
131 lSstyle
|= MLS_READONLY
;
137 if (m_windowStyle
& wxHSCROLL
)
138 lSstyle
|= ES_AUTOSCROLL
;
139 if (m_windowStyle
& wxTE_READONLY
)
140 lSstyle
|= ES_READONLY
;
141 if (m_windowStyle
& wxTE_PASSWORD
) // hidden input
142 lSstyle
|= ES_UNREADABLE
;
146 m_hWnd
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle
147 ,WC_MLE
// Window class
148 ,(PSZ
)rsValue
.c_str() // Initial Text
149 ,(ULONG
)lSstyle
// Style flags
150 ,(LONG
)rPos
.x
// X pos of origin
151 ,(LONG
)rPos
.y
// Y pos of origin
152 ,(LONG
)rSize
.x
// field width
153 ,(LONG
)rSize
.y
// field height
154 ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent
155 ,HWND_TOP
// initial z position
156 ,(ULONG
)vId
// Window identifier
157 ,NULL
// no control data
158 ,NULL
// no Presentation parameters
163 m_hWnd
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle
164 ,WC_ENTRYFIELD
// Window class
165 ,(PSZ
)rsValue
.c_str() // Initial Text
166 ,(ULONG
)lSstyle
// Style flags
167 ,(LONG
)rPos
.x
// X pos of origin
168 ,(LONG
)rPos
.y
// Y pos of origin
169 ,(LONG
)rSize
.x
// field width
170 ,(LONG
)rSize
.y
// field height
171 ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent
172 ,HWND_TOP
// initial z position
173 ,(ULONG
)vId
// Window identifier
174 ,NULL
// no control data
175 ,NULL
// no Presentation parameters
184 SubclassWin(GetHWND());
187 // Set font, position, size and initial value
189 wxFont
& vFontParent
= pParent
->GetFont();
191 if (vFontParent
.Ok())
193 SetFont(vFontParent
);
197 SetFont(wxSystemSettings::GetSystemFont(wxSYS_SYSTEM_FONT
));
199 if (!rsValue
.IsEmpty())
210 } // end of wxTextCtrl::Create
213 // Make sure the window style (etc.) reflects the HWND style (roughly)
215 void wxTextCtrl::AdoptAttributesFromHWND()
217 HWND hWnd
= GetHwnd();
218 LONG lStyle
= ::WinQueryWindowULong(hWnd
, QWL_STYLE
);
220 wxWindow::AdoptAttributesFromHWND();
224 m_windowStyle
|= wxTE_MULTILINE
;
225 if (lStyle
& MLS_READONLY
)
226 m_windowStyle
|= wxTE_READONLY
;
230 if (lStyle
& ES_UNREADABLE
)
231 m_windowStyle
|= wxTE_PASSWORD
;
232 if (lStyle
& ES_READONLY
)
233 m_windowStyle
|= wxTE_READONLY
;
237 void wxTextCtrl::SetupColours()
239 // FIXME why is bg colour not inherited from parent?
240 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW
));
241 SetForegroundColour(GetParent()->GetForegroundColour());
244 // ----------------------------------------------------------------------------
245 // set/get the controls text
246 // ----------------------------------------------------------------------------
248 wxString
wxTextCtrl::GetValue() const
250 return wxGetWindowText(GetHWND());
253 void wxTextCtrl::SetValue(const wxString
& value
)
257 wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos);
259 SetWindowText(GetHwnd(), valueDos);
265 void wxTextCtrl::WriteText(const wxString
& value
)
269 wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos);
271 SendMessage(GetHwnd(), EM_REPLACESEL, 0, (LPARAM)valueDos.c_str());
277 void wxTextCtrl::AppendText(const wxString
& text
)
281 SetInsertionPointEnd();
286 void wxTextCtrl::Clear()
288 // SetWindowText(GetHwnd(), wxT(""));
291 // ----------------------------------------------------------------------------
292 // Clipboard operations
293 // ----------------------------------------------------------------------------
295 void wxTextCtrl::Copy()
299 HWND hWnd
= GetHwnd();
301 ::WinSendMsg(hWnd
, MLM_COPY
, 0, 0);
303 ::WinSendMsg(hWnd
, EM_COPY
, 0, 0);
305 } // end of wxTextCtrl::Copy
307 void wxTextCtrl::Cut()
311 HWND hWnd
= GetHwnd();
314 ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0);
316 ::WinSendMsg(hWnd
, EM_CUT
, 0, 0);
320 void wxTextCtrl::Paste()
324 HWND hWnd
= GetHwnd();
325 // SendMessage(hWnd, WM_PASTE, 0, 0L);
329 bool wxTextCtrl::CanCopy() const
331 // Can copy if there's a selection
334 // GetSelection(& from, & to);
338 bool wxTextCtrl::CanCut() const
340 // Can cut if there's a selection
343 // GetSelection(& from, & to);
347 bool wxTextCtrl::CanPaste() const
349 bool bIsTextAvailable
= FALSE
;
355 // Check for straight text on clipboard
357 if (::WinOpenClipbrd(vHabmain
))
359 bIsTextAvailable
= (::WinQueryClipbrdData(vHabmain
, CF_TEXT
) != 0);
360 ::WinCloseClipbrd(vHabmain
);
362 return bIsTextAvailable
;
363 } // end of wxTextCtrl::CanPaste
365 // ----------------------------------------------------------------------------
367 // ----------------------------------------------------------------------------
369 void wxTextCtrl::SetEditable(bool editable
)
371 HWND hWnd
= GetHwnd();
372 // SendMessage(hWnd, EM_SETREADONLY, (WPARAM)!editable, (LPARAM)0L);
375 void wxTextCtrl::SetInsertionPoint(long pos
)
379 HWND hWnd = GetHwnd();
381 SendMessage(hWnd, EM_SETSEL, pos, pos);
382 SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);
384 static const char *nothing = "";
385 SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)nothing);
389 void wxTextCtrl::SetInsertionPointEnd()
393 long wxTextCtrl::GetInsertionPoint() const
398 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), MLM_QUERYSEL
, (MPARAM
)MLFQS_MINSEL
, 0);
401 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), EM_QUERYSEL
, 0, 0);
402 dwPos
= SHORT1FROMMP((MPARAM
)dwPos
); // the first 16 bit value is the min pos
404 return (dwPos
& 0xFFFF);
405 } // end of wxTextCtrl::GetInsertionPoint
407 long wxTextCtrl::GetLastPosition() const
409 HWND hWnd
= GetHwnd();
418 // This just gets the total text length. The last will be this value
420 lLineLength
= (long)::WinSendMsg(hWnd
, MLM_QUERYTEXTLENGTH
, 0, 0);
427 vParams
.fsStatus
= WPM_CCHTEXT
;
428 if (::WinSendMsg( GetHwnd()
429 ,WM_QUERYWINDOWPARAMS
434 lLineLength
= (long)vParams
.cchText
;
439 return(lCharIndex
+ lLineLength
);
440 } // end of wxTextCtrl::GetLastPosition
442 // If the return values from and to are the same, there is no
444 void wxTextCtrl::GetSelection(long* from
, long* to
) const
446 DWORD dwStart
, dwEnd
;
447 MPARAM wParam
= (MPARAM
) (DWORD
*) & dwStart
; // receives starting position
448 MPARAM lParam
= (MPARAM
) (DWORD
*) & dwEnd
; // receives ending position
450 // ::SendMessage(GetHwnd(), EM_GETSEL, wParam, lParam);
456 bool wxTextCtrl::IsEditable() const
460 long style = ::GetWindowLong(GetHwnd(), GWL_STYLE);
462 return ((style & ES_READONLY) == 0);
467 // ----------------------------------------------------------------------------
469 // ----------------------------------------------------------------------------
471 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
474 HWND hWnd
= GetHwnd();
475 long fromChar
= from
;
478 // Set selection and remove it
479 // SendMessage(hWnd, EM_SETSEL, fromChar, toChar);
480 // SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0);
482 // Now replace with 'value', by pasting.
483 wxSetClipboardData(wxDF_TEXT
, (wxObject
*) (const wxChar
*)value
, 0, 0);
485 // Paste into edit control
486 // SendMessage(hWnd, WM_PASTE, (WPARAM)0, (LPARAM)0L);
488 wxFAIL_MSG("wxTextCtrl::Replace not implemented if wxUSE_CLIPBOARD is 0.");
492 void wxTextCtrl::Remove(long from
, long to
)
494 HWND hWnd
= GetHwnd();
495 long fromChar
= from
;
498 // Cut all selected text
499 // SendMessage(hWnd, EM_SETSEL, fromChar, toChar);
500 // SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0);
503 void wxTextCtrl::SetSelection(long from
, long to
)
505 HWND hWnd
= GetHwnd();
506 long fromChar
= from
;
509 // if from and to are both -1, it means (in wxWindows) that all text should
510 // be selected. Translate into Windows convention
511 if ((from
== -1) && (to
== -1))
517 // SendMessage(hWnd, EM_SETSEL, (WPARAM)fromChar, (LPARAM)toChar);
518 // SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);
521 bool wxTextCtrl::LoadFile(const wxString
& file
)
525 if ( wxTextCtrlBase::LoadFile(file) )
527 // update the size limit if needed
536 bool wxTextCtrl::IsModified() const
538 // return (SendMessage(GetHwnd(), EM_GETMODIFY, 0, 0) != 0);
543 // Makes 'unmodified'
545 void wxTextCtrl::DiscardEdits()
548 ::WinSendMsg(GetHwnd(), MLM_SETCHANGED
, MPFROMLONG(FALSE
), 0);
551 // EM controls do not have a SETCHANGED but issuing a query should reset it
553 ::WinSendMsg(GetHwnd(), EM_QUERYCHANGED
, 0, 0);
554 } // end of wxTextCtrl::DiscardEdits
556 int wxTextCtrl::GetNumberOfLines() const
558 // return (int)SendMessage(GetHwnd(), EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0);
562 long wxTextCtrl::XYToPosition(long x
, long y
) const
564 HWND hWnd
= GetHwnd();
566 // This gets the char index for the _beginning_ of this line
569 int charIndex = (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)y, (LPARAM)0);
570 return (long)(x + charIndex);
575 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
577 HWND hWnd
= GetHwnd();
579 // This gets the line number containing the character
581 // lineNo = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)pos, 0);
589 // This gets the char index for the _beginning_ of this line
590 int charIndex
= 0; // TODO: (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)lineNo, (LPARAM)0);
591 if ( charIndex
== -1 )
596 // The X position must therefore be the different between pos and charIndex
598 *x
= (long)(pos
- charIndex
);
605 void wxTextCtrl::ShowPosition(long pos
)
607 HWND hWnd
= GetHwnd();
609 // To scroll to a position, we pass the number of lines and characters
610 // to scroll *by*. This means that we need to:
611 // (1) Find the line position of the current line.
612 // (2) Find the line position of pos.
613 // (3) Scroll by (pos - current).
614 // For now, ignore the horizontal scrolling.
616 // Is this where scrolling is relative to - the line containing the caret?
617 // Or is the first visible line??? Try first visible line.
618 // int currentLineLineNo1 = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)-1, (LPARAM)0L);
622 int currentLineLineNo = (int)SendMessage(hWnd, EM_GETFIRSTVISIBLELINE, (WPARAM)0, (LPARAM)0L);
624 int specifiedLineLineNo = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)pos, (LPARAM)0L);
626 int linesToScroll = specifiedLineLineNo - currentLineLineNo;
628 if (linesToScroll != 0)
629 (void)SendMessage(hWnd, EM_LINESCROLL, (WPARAM)0, (LPARAM)linesToScroll);
633 int wxTextCtrl::GetLineLength(
640 lLen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0);
645 vParams
.fsStatus
= WPM_CCHTEXT
;
646 if (::WinSendMsg( GetHwnd()
647 ,WM_QUERYWINDOWPARAMS
652 lLen
= vParams
.cchText
;
660 wxString
wxTextCtrl::GetLineText(long lineNo
) const
662 size_t len
= (size_t)GetLineLength(lineNo
) + 1;
663 char *buf
= (char *)malloc(len
);
665 int noChars
= 0; // TODO:(int)SendMessage(GetHwnd(), EM_GETLINE, lineNo, (LPARAM)buf);
675 // ----------------------------------------------------------------------------
677 // ----------------------------------------------------------------------------
679 void wxTextCtrl::Undo()
683 // ::SendMessage(GetHwnd(), EM_UNDO, 0, 0);
687 void wxTextCtrl::Redo()
691 // Same as Undo, since Undo undoes the undo, i.e. a redo.
692 // ::SendMessage(GetHwnd(), EM_UNDO, 0, 0);
696 bool wxTextCtrl::CanUndo() const
701 bOk
= (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO
, 0, 0) != 0);
703 bOk
= FALSE
; // can't undo regular edit fields in PM
705 } // end of wxTextCtrl::CanUndo
707 bool wxTextCtrl::CanRedo() const
712 bOk
= (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO
, 0, 0) != 0);
714 bOk
= FALSE
; // can't undo regular edit fields in PM
716 } // end of wxTextCtrl::CanRedo
718 // ----------------------------------------------------------------------------
719 // implemenation details
720 // ----------------------------------------------------------------------------
722 void wxTextCtrl::Command(wxCommandEvent
& event
)
724 SetValue(event
.GetString());
725 ProcessCommand (event
);
728 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
730 // By default, load the first file into the text window.
731 if (event
.GetNumberOfFiles() > 0)
733 LoadFile(event
.GetFiles()[0]);
737 WXHBRUSH
wxTextCtrl::OnCtlColor(WXHDC pDC
, WXHWND pWnd
, WXUINT nCtlColor
,
738 WXUINT message
, WXWPARAM wParam
,
744 SetBkMode(hdc, GetParent()->GetTransparentBackground() ? TRANSPARENT
747 ::SetBkColor(hdc, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
748 ::SetTextColor(hdc, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
750 wxBrush
*backgroundBrush
= wxTheBrushList
->FindOrCreateBrush(GetBackgroundColour(), wxSOLID
);
752 return (WXHBRUSH
) backgroundBrush
->GetResourceHandle();
755 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
757 switch ( event
.KeyCode() )
762 if ( !(m_windowStyle & wxTE_MULTILINE) )
764 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
765 event.SetEventObject( this );
766 if ( GetEventHandler()->ProcessEvent(event) )
769 //else: multiline controls need Enter for themselves
774 // always produce navigation event - even if we process TAB
775 // ourselves the fact that we got here means that the user code
776 // decided to skip processing of this TAB - probably to let it
777 // do its default job.
779 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
780 // handled by Windows
782 wxNavigationKeyEvent eventNav;
783 eventNav.SetDirection(!event.ShiftDown());
784 eventNav.SetWindowChange(FALSE);
785 eventNav.SetEventObject(this);
787 if ( GetEventHandler()->ProcessEvent(eventNav) )
797 // don't just call event.Skip() because this will cause TABs and ENTERs
798 // be passed upwards and we don't always want this - instead process it
805 bool wxTextCtrl::OS2Command(WXUINT param
, WXWORD
WXUNUSED(id
))
814 wxFocusEvent event(param == EN_KILLFOCUS ? wxEVT_KILL_FOCUS
817 event.SetEventObject( this );
818 GetEventHandler()->ProcessEvent(event);
824 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
825 wxString val(GetValue());
827 event.m_commandString = WXSTRINGCAST val;
828 event.SetEventObject( this );
829 ProcessCommand(event);
834 // the text size limit has been hit - increase it
838 // the other notification messages are not processed
852 void wxTextCtrl::AdjustSpaceLimit()
854 unsigned int uLen
= 0;
855 unsigned int uLimit
= 0;
857 uLen
= ::WinQueryWindowTextLength(GetHwnd());
860 uLimit
= (unsigned int)::WinSendMsg( GetHwnd()
871 vParams
.fsStatus
= WPM_CBCTLDATA
;
872 vParams
.cbCtlData
= sizeof(ENTRYFDATA
);
874 if (::WinSendMsg( GetHwnd()
875 ,WM_QUERYWINDOWPARAMS
880 pEfd
= (ENTRYFDATA
*)vParams
.pCtlData
;
881 uLimit
= (unsigned int)pEfd
->cchEditLimit
;
884 uLimit
= 32; //PM's default
888 uLimit
= uLen
+ 0x8000; // 32Kb
894 ::WinSendMsg(GetHwnd(), MLM_SETTEXTLIMIT
, MPFROMLONG(uLimit
), 0);
896 ::WinSendMsg(GetHwnd(), EM_SETTEXTLIMIT
, MPFROMLONG(uLimit
), 0);
898 } // end of wxTextCtrl::AdjustSpaceLimit
900 bool wxTextCtrl::AcceptsFocus() const
902 // we don't want focus if we can't be edited
903 return IsEditable() && wxControl::AcceptsFocus();
906 wxSize
wxTextCtrl::DoGetBestSize() const
909 wxGetCharSize(GetHWND(), &cx
, &cy
, (wxFont
*)&GetFont());
911 int wText
= DEFAULT_ITEM_WIDTH
;
913 int hText
= EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy
);
914 if ( m_windowStyle
& wxTE_MULTILINE
)
916 hText
*= wxMin(GetNumberOfLines(), 5);
918 //else: for single line control everything is ok
920 return wxSize(wText
, hText
);
923 // ----------------------------------------------------------------------------
924 // standard handlers for standard edit menu events
925 // ----------------------------------------------------------------------------
927 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
932 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
937 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
942 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
947 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
952 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
954 event
.Enable( CanCut() );
957 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
959 event
.Enable( CanCopy() );
962 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
964 event
.Enable( CanPaste() );
967 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
969 event
.Enable( CanUndo() );
972 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
974 event
.Enable( CanRedo() );