text.cpp 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: text.cpp
  3. // Purpose: TextCtrl wxWidgets sample
  4. // Author: Robert Roebling
  5. // Modified by:
  6. // Copyright: (c) Robert Roebling, Julian Smart, Vadim Zeitlin
  7. // Licence: wxWindows licence
  8. /////////////////////////////////////////////////////////////////////////////
  9. // For compilers that support precompilation, includes "wx/wx.h".
  10. #include "wx/wxprec.h"
  11. #ifdef __BORLANDC__
  12. #pragma hdrstop
  13. #endif
  14. #ifndef WX_PRECOMP
  15. #include "wx/wx.h"
  16. #endif
  17. #if wxUSE_CLIPBOARD
  18. #include "wx/dataobj.h"
  19. #include "wx/clipbrd.h"
  20. #endif
  21. #if wxUSE_FILE
  22. #include "wx/file.h"
  23. #endif
  24. #if wxUSE_TOOLTIPS
  25. #include "wx/tooltip.h"
  26. #endif
  27. // We test for wxUSE_DRAG_AND_DROP also, because data objects may not be
  28. // implemented for compilers that can't cope with the OLE parts in
  29. // wxUSE_DRAG_AND_DROP.
  30. #if !wxUSE_DRAG_AND_DROP
  31. #undef wxUSE_CLIPBOARD
  32. #define wxUSE_CLIPBOARD 0
  33. #endif
  34. #include "wx/colordlg.h"
  35. #include "wx/fontdlg.h"
  36. #include "wx/numdlg.h"
  37. #include "wx/tokenzr.h"
  38. #ifndef wxHAS_IMAGES_IN_RESOURCES
  39. #include "../sample.xpm"
  40. #endif
  41. //----------------------------------------------------------------------
  42. // class definitions
  43. //----------------------------------------------------------------------
  44. class MyApp: public wxApp
  45. {
  46. public:
  47. bool OnInit();
  48. };
  49. // a text ctrl which allows to call different wxTextCtrl functions
  50. // interactively by pressing function keys in it
  51. class MyTextCtrl : public wxTextCtrl
  52. {
  53. public:
  54. MyTextCtrl(wxWindow *parent, wxWindowID id, const wxString &value,
  55. const wxPoint &pos, const wxSize &size, int style = 0)
  56. : wxTextCtrl(parent, id, value, pos, size, style)
  57. {
  58. m_hasCapture = false;
  59. }
  60. void OnKeyDown(wxKeyEvent& event);
  61. void OnKeyUp(wxKeyEvent& event);
  62. void OnChar(wxKeyEvent& event);
  63. void OnText(wxCommandEvent& event);
  64. void OnTextEnter(wxCommandEvent& event);
  65. void OnTextURL(wxTextUrlEvent& event);
  66. void OnTextMaxLen(wxCommandEvent& event);
  67. void OnTextCut(wxClipboardTextEvent & event);
  68. void OnTextCopy(wxClipboardTextEvent & event);
  69. void OnTextPaste(wxClipboardTextEvent & event);
  70. void OnMouseEvent(wxMouseEvent& event);
  71. void OnSetFocus(wxFocusEvent& event);
  72. void OnKillFocus(wxFocusEvent& event);
  73. static bool ms_logKey;
  74. static bool ms_logChar;
  75. static bool ms_logMouse;
  76. static bool ms_logText;
  77. static bool ms_logFocus;
  78. static bool ms_logClip;
  79. private:
  80. static inline wxChar GetChar(bool on, wxChar c) { return on ? c : wxT('-'); }
  81. void LogKeyEvent(const wxChar *name, wxKeyEvent& event) const;
  82. void LogClipEvent(const wxChar *what, wxClipboardTextEvent& event);
  83. bool m_hasCapture;
  84. wxDECLARE_EVENT_TABLE();
  85. };
  86. class MyPanel: public wxPanel
  87. {
  88. public:
  89. MyPanel(wxFrame *frame, int x, int y, int w, int h);
  90. virtual ~MyPanel()
  91. {
  92. #if wxUSE_LOG
  93. delete wxLog::SetActiveTarget(m_logOld);
  94. #endif // wxUSE_LOG
  95. }
  96. #if wxUSE_CLIPBOARD
  97. void DoPasteFromClipboard();
  98. void DoCopyToClipboard();
  99. #endif // wxUSE_CLIPBOARD
  100. void DoRemoveText();
  101. void DoReplaceText();
  102. void DoSelectText();
  103. void DoMoveToEndOfText();
  104. void DoMoveToEndOfEntry();
  105. void DoGetWindowCoordinates();
  106. // return true if currently text control has any selection
  107. bool HasSelection() const
  108. {
  109. long from, to;
  110. GetFocusedText()->GetSelection(&from, &to);
  111. return from != to;
  112. }
  113. MyTextCtrl *m_text;
  114. MyTextCtrl *m_password;
  115. MyTextCtrl *m_enter;
  116. MyTextCtrl *m_tab;
  117. MyTextCtrl *m_readonly;
  118. MyTextCtrl *m_limited;
  119. MyTextCtrl *m_multitext;
  120. MyTextCtrl *m_horizontal;
  121. MyTextCtrl *m_textrich;
  122. #if wxUSE_LOG
  123. wxTextCtrl *m_log;
  124. wxLog *m_logOld;
  125. #endif // wxUSE_LOG
  126. private:
  127. // get the currently focused text control or return the default one
  128. // (m_multitext) is no text ctrl has focus -- in any case, returns
  129. // something non NULL
  130. wxTextCtrl *GetFocusedText() const;
  131. };
  132. class MyFrame: public wxFrame
  133. {
  134. public:
  135. MyFrame(wxFrame *frame, const wxChar *title, int x, int y, int w, int h);
  136. void OnQuit(wxCommandEvent& event);
  137. void OnAbout(wxCommandEvent& event);
  138. #if wxUSE_TOOLTIPS
  139. void OnSetTooltipDelay(wxCommandEvent& event);
  140. void OnToggleTooltips(wxCommandEvent& event);
  141. #endif // wxUSE_TOOLTIPS
  142. #if wxUSE_CLIPBOARD
  143. void OnPasteFromClipboard( wxCommandEvent& WXUNUSED(event) )
  144. {
  145. wxLogMessage(wxT("Pasting text from clipboard."));
  146. m_panel->DoPasteFromClipboard();
  147. }
  148. void OnCopyToClipboard( wxCommandEvent& WXUNUSED(event) )
  149. {
  150. wxLogMessage(wxT("Copying text to clipboard."));
  151. m_panel->DoCopyToClipboard();
  152. }
  153. void OnUpdatePasteFromClipboard(wxUpdateUIEvent& event)
  154. {
  155. wxClipboardLocker lockClip;
  156. event.Enable( wxTheClipboard->IsSupported(wxDF_TEXT) );
  157. }
  158. void OnUpdateCopyToClipboard(wxUpdateUIEvent& event)
  159. {
  160. event.Enable( m_panel->HasSelection() );
  161. }
  162. #endif // wxUSE_CLIPBOARD
  163. void OnAddTextLine(wxCommandEvent& WXUNUSED(event))
  164. {
  165. static int s_n = 0;
  166. m_panel->m_textrich->AppendText(wxString::Format("Line %d\n", ++s_n));
  167. }
  168. void OnAddTextFreeze( wxCommandEvent& WXUNUSED(event) )
  169. { DoAddText(true); }
  170. void OnAddText( wxCommandEvent& WXUNUSED(event) )
  171. { DoAddText(false); }
  172. void OnRemoveText( wxCommandEvent& WXUNUSED(event) )
  173. { m_panel->DoRemoveText(); }
  174. void OnReplaceText( wxCommandEvent& WXUNUSED(event) )
  175. { m_panel->DoReplaceText(); }
  176. void OnSelectText( wxCommandEvent& WXUNUSED(event) )
  177. { m_panel->DoSelectText(); }
  178. void OnMoveToEndOfText( wxCommandEvent& WXUNUSED(event) )
  179. { m_panel->DoMoveToEndOfText(); }
  180. void OnGetWindowCoordinates( wxCommandEvent& WXUNUSED(event) )
  181. { m_panel->DoGetWindowCoordinates(); }
  182. void OnMoveToEndOfEntry( wxCommandEvent& WXUNUSED(event) )
  183. { m_panel->DoMoveToEndOfEntry(); }
  184. void OnScrollLineDown(wxCommandEvent& WXUNUSED(event))
  185. {
  186. if ( !m_panel->m_textrich->LineDown() )
  187. {
  188. wxLogMessage(wxT("Already at the bottom"));
  189. }
  190. }
  191. void OnScrollLineUp(wxCommandEvent& WXUNUSED(event))
  192. {
  193. if ( !m_panel->m_textrich->LineUp() )
  194. {
  195. wxLogMessage(wxT("Already at the top"));
  196. }
  197. }
  198. void OnScrollPageDown(wxCommandEvent& WXUNUSED(event))
  199. {
  200. if ( !m_panel->m_textrich->PageDown() )
  201. {
  202. wxLogMessage(wxT("Already at the bottom"));
  203. }
  204. }
  205. void OnScrollPageUp(wxCommandEvent& WXUNUSED(event))
  206. {
  207. if ( !m_panel->m_textrich->PageUp() )
  208. {
  209. wxLogMessage(wxT("Already at the top"));
  210. }
  211. }
  212. void OnGetLine(wxCommandEvent& WXUNUSED(event))
  213. {
  214. long nLine = wxGetNumberFromUser(wxT("Which line would you like to get?"),
  215. wxT("Enter which line you would like to get"),
  216. wxT("Get a line from the tabbed multiline text control") );
  217. wxMessageBox(m_panel->m_tab->GetLineText(nLine));
  218. }
  219. void OnGetLineLength(wxCommandEvent& WXUNUSED(event))
  220. {
  221. long nLine = wxGetNumberFromUser(wxT("Which line would you like to get?"),
  222. wxT("Enter which line you would like to get"),
  223. wxT("Get length of a line from the tabbed multiline text control") );
  224. wxMessageBox(wxString::Format(wxT("Length of line %i is:%i"),
  225. (int) nLine,
  226. m_panel->m_tab->GetLineLength(nLine))
  227. );
  228. }
  229. #if wxUSE_LOG
  230. void OnLogClear(wxCommandEvent& event);
  231. #endif // wxUSE_LOG
  232. void OnFileSave(wxCommandEvent& event);
  233. void OnFileLoad(wxCommandEvent& event);
  234. void OnRichTextTest(wxCommandEvent& event);
  235. void OnSetEditable(wxCommandEvent& event);
  236. void OnSetEnabled(wxCommandEvent& event);
  237. void OnLogKey(wxCommandEvent& event)
  238. {
  239. MyTextCtrl::ms_logKey = event.IsChecked();
  240. }
  241. void OnLogChar(wxCommandEvent& event)
  242. {
  243. MyTextCtrl::ms_logChar = event.IsChecked();
  244. }
  245. void OnLogMouse(wxCommandEvent& event)
  246. {
  247. MyTextCtrl::ms_logMouse = event.IsChecked();
  248. }
  249. void OnLogText(wxCommandEvent& event)
  250. {
  251. MyTextCtrl::ms_logText = event.IsChecked();
  252. }
  253. void OnLogFocus(wxCommandEvent& event)
  254. {
  255. MyTextCtrl::ms_logFocus = event.IsChecked();
  256. }
  257. void OnLogClip(wxCommandEvent& event)
  258. {
  259. MyTextCtrl::ms_logClip = event.IsChecked();
  260. }
  261. void OnSetText(wxCommandEvent& WXUNUSED(event))
  262. {
  263. m_panel->m_text->SetValue(wxT("Hello, world! (what else did you expect?)"));
  264. }
  265. void OnChangeText(wxCommandEvent& WXUNUSED(event))
  266. {
  267. m_panel->m_text->ChangeValue(wxT("Changed, not set: no event"));
  268. }
  269. void OnIdle( wxIdleEvent& event );
  270. private:
  271. void DoAddText(bool freeze)
  272. {
  273. wxTextCtrl * const text = m_panel->m_textrich;
  274. if ( freeze )
  275. text->Freeze();
  276. text->Clear();
  277. for ( int i = 0; i < 100; i++ )
  278. {
  279. text->AppendText(wxString::Format(wxT("Line %i\n"), i));
  280. }
  281. text->SetInsertionPoint(0);
  282. if ( freeze )
  283. text->Thaw();
  284. }
  285. MyPanel *m_panel;
  286. wxDECLARE_EVENT_TABLE();
  287. };
  288. /*
  289. * RichTextFrame is used to demonstrate rich text behaviour
  290. */
  291. class RichTextFrame: public wxFrame
  292. {
  293. public:
  294. RichTextFrame(wxWindow* parent, const wxString& title);
  295. // Event handlers
  296. void OnClose(wxCommandEvent& event);
  297. void OnIdle(wxIdleEvent& event);
  298. void OnLeftAlign(wxCommandEvent& event);
  299. void OnRightAlign(wxCommandEvent& event);
  300. void OnJustify(wxCommandEvent& event);
  301. void OnCentre(wxCommandEvent& event);
  302. void OnChangeFont(wxCommandEvent& event);
  303. void OnChangeTextColour(wxCommandEvent& event);
  304. void OnChangeBackgroundColour(wxCommandEvent& event);
  305. void OnLeftIndent(wxCommandEvent& event);
  306. void OnRightIndent(wxCommandEvent& event);
  307. void OnTabStops(wxCommandEvent& event);
  308. private:
  309. wxTextCtrl *m_textCtrl;
  310. long m_currentPosition;
  311. wxDECLARE_EVENT_TABLE();
  312. };
  313. //----------------------------------------------------------------------
  314. // main()
  315. //----------------------------------------------------------------------
  316. IMPLEMENT_APP(MyApp)
  317. //----------------------------------------------------------------------
  318. // MyApp
  319. //----------------------------------------------------------------------
  320. enum
  321. {
  322. TEXT_QUIT = wxID_EXIT,
  323. TEXT_ABOUT = wxID_ABOUT,
  324. TEXT_LOAD = 101,
  325. TEXT_SAVE,
  326. TEXT_CLEAR,
  327. TEXT_RICH_TEXT_TEST,
  328. // clipboard menu
  329. TEXT_CLIPBOARD_COPY = 200,
  330. TEXT_CLIPBOARD_PASTE,
  331. TEXT_CLIPBOARD_VETO,
  332. // tooltip menu
  333. TEXT_TOOLTIPS_SETDELAY = 300,
  334. TEXT_TOOLTIPS_ENABLE,
  335. // text menu
  336. TEXT_ADD_SOME = 400,
  337. TEXT_ADD_FREEZE,
  338. TEXT_ADD_LINE,
  339. TEXT_MOVE_ENDTEXT,
  340. TEXT_GET_WINDOW_COORD,
  341. TEXT_MOVE_ENDENTRY,
  342. TEXT_SET_EDITABLE,
  343. TEXT_SET_ENABLED,
  344. TEXT_LINE_DOWN,
  345. TEXT_LINE_UP,
  346. TEXT_PAGE_DOWN,
  347. TEXT_PAGE_UP,
  348. TEXT_GET_LINE,
  349. TEXT_GET_LINELENGTH,
  350. TEXT_REMOVE,
  351. TEXT_REPLACE,
  352. TEXT_SELECT,
  353. TEXT_SET,
  354. TEXT_CHANGE,
  355. // log menu
  356. TEXT_LOG_KEY,
  357. TEXT_LOG_CHAR,
  358. TEXT_LOG_MOUSE,
  359. TEXT_LOG_TEXT,
  360. TEXT_LOG_FOCUS,
  361. TEXT_LOG_CLIP,
  362. TEXT_END
  363. };
  364. bool MyApp::OnInit()
  365. {
  366. if ( !wxApp::OnInit() )
  367. return false;
  368. // Create the main frame window
  369. MyFrame *frame = new MyFrame((wxFrame *) NULL,
  370. wxT("Text wxWidgets sample"), 50, 50, 700, 550);
  371. frame->SetSizeHints( 500, 400 );
  372. wxMenu *file_menu = new wxMenu;
  373. file_menu->Append(TEXT_SAVE, wxT("&Save file\tCtrl-S"),
  374. wxT("Save the text control contents to file"));
  375. file_menu->Append(TEXT_LOAD, wxT("&Load file\tCtrl-O"),
  376. wxT("Load the sample file into text control"));
  377. file_menu->AppendSeparator();
  378. file_menu->Append(TEXT_RICH_TEXT_TEST, wxT("Show Rich Text Editor"));
  379. file_menu->AppendSeparator();
  380. file_menu->Append(TEXT_ABOUT, wxT("&About\tAlt-A"));
  381. file_menu->AppendSeparator();
  382. file_menu->Append(TEXT_QUIT, wxT("E&xit\tAlt-X"), wxT("Quit this sample"));
  383. wxMenuBar *menu_bar = new wxMenuBar( wxMB_DOCKABLE );
  384. menu_bar->Append(file_menu, wxT("&File"));
  385. #if wxUSE_TOOLTIPS
  386. wxMenu *tooltip_menu = new wxMenu;
  387. tooltip_menu->Append(TEXT_TOOLTIPS_SETDELAY, wxT("Set &delay\tCtrl-D"));
  388. tooltip_menu->AppendSeparator();
  389. tooltip_menu->Append(TEXT_TOOLTIPS_ENABLE, wxT("&Toggle tooltips\tCtrl-T"),
  390. wxT("enable/disable tooltips"), true);
  391. tooltip_menu->Check(TEXT_TOOLTIPS_ENABLE, true);
  392. menu_bar->Append(tooltip_menu, wxT("&Tooltips"));
  393. #endif // wxUSE_TOOLTIPS
  394. #if wxUSE_CLIPBOARD
  395. // notice that we use non default accelerators on purpose here to compare
  396. // their behaviour with the built in handling of standard Ctrl/Cmd-C/V
  397. wxMenu *menuClipboard = new wxMenu;
  398. menuClipboard->Append(TEXT_CLIPBOARD_COPY, wxT("&Copy\tCtrl-Shift-C"),
  399. wxT("Copy the selection to the clipboard"));
  400. menuClipboard->Append(TEXT_CLIPBOARD_PASTE, wxT("&Paste\tCtrl-Shift-V"),
  401. wxT("Paste from clipboard to the text control"));
  402. menuClipboard->AppendSeparator();
  403. menuClipboard->AppendCheckItem(TEXT_CLIPBOARD_VETO, wxT("Vet&o\tCtrl-Shift-O"),
  404. wxT("Veto all clipboard operations"));
  405. menu_bar->Append(menuClipboard, wxT("&Clipboard"));
  406. #endif // wxUSE_CLIPBOARD
  407. wxMenu *menuText = new wxMenu;
  408. menuText->Append(TEXT_ADD_SOME, wxT("&Append some text\tCtrl-A"));
  409. menuText->Append(TEXT_ADD_FREEZE, wxT("&Append text with freeze/thaw\tShift-Ctrl-A"));
  410. menuText->Append(TEXT_ADD_LINE, wxT("Append a new &line\tAlt-Shift-A"));
  411. menuText->Append(TEXT_REMOVE, wxT("&Remove first 10 characters\tCtrl-Y"));
  412. menuText->Append(TEXT_REPLACE, wxT("&Replace characters 4 to 8 with ABC\tCtrl-R"));
  413. menuText->Append(TEXT_SELECT, wxT("&Select characters 4 to 8\tCtrl-I"));
  414. menuText->Append(TEXT_SET, wxT("&Set the first text zone value\tCtrl-E"));
  415. menuText->Append(TEXT_CHANGE, wxT("&Change the first text zone value\tShift-Ctrl-E"));
  416. menuText->AppendSeparator();
  417. menuText->Append(TEXT_MOVE_ENDTEXT, wxT("Move cursor to the end of &text"));
  418. menuText->Append(TEXT_MOVE_ENDENTRY, wxT("Move cursor to the end of &entry"));
  419. menuText->AppendCheckItem(TEXT_SET_EDITABLE, wxT("Toggle &editable state"));
  420. menuText->AppendCheckItem(TEXT_SET_ENABLED, wxT("Toggle e&nabled state"));
  421. menuText->Check(TEXT_SET_EDITABLE, true);
  422. menuText->Check(TEXT_SET_ENABLED, true);
  423. menuText->AppendSeparator();
  424. menuText->Append(TEXT_LINE_DOWN, wxT("Scroll text one line down"));
  425. menuText->Append(TEXT_LINE_UP, wxT("Scroll text one line up"));
  426. menuText->Append(TEXT_PAGE_DOWN, wxT("Scroll text one page down"));
  427. menuText->Append(TEXT_PAGE_UP, wxT("Scroll text one page up"));
  428. menuText->Append(TEXT_GET_WINDOW_COORD, wxT("Get window coordinates"));
  429. menuText->AppendSeparator();
  430. menuText->Append(TEXT_GET_LINE, wxT("Get the text of a line of the tabbed multiline"));
  431. menuText->Append(TEXT_GET_LINELENGTH, wxT("Get the length of a line of the tabbed multiline"));
  432. menu_bar->Append(menuText, wxT("Te&xt"));
  433. #if wxUSE_LOG
  434. wxMenu *menuLog = new wxMenu;
  435. menuLog->AppendCheckItem(TEXT_LOG_KEY, wxT("Log &key events"));
  436. menuLog->AppendCheckItem(TEXT_LOG_CHAR, wxT("Log &char events"));
  437. menuLog->AppendCheckItem(TEXT_LOG_MOUSE, wxT("Log &mouse events"));
  438. menuLog->AppendCheckItem(TEXT_LOG_TEXT, wxT("Log &text events"));
  439. menuLog->AppendCheckItem(TEXT_LOG_FOCUS, wxT("Log &focus events"));
  440. menuLog->AppendCheckItem(TEXT_LOG_CLIP, wxT("Log clip&board events"));
  441. menuLog->AppendSeparator();
  442. menuLog->Append(TEXT_CLEAR, wxT("&Clear the log\tCtrl-L"),
  443. wxT("Clear the log window contents"));
  444. // select only the interesting events by default
  445. MyTextCtrl::ms_logClip =
  446. MyTextCtrl::ms_logText = true;
  447. menuLog->Check(TEXT_LOG_KEY, MyTextCtrl::ms_logKey);
  448. menuLog->Check(TEXT_LOG_CHAR, MyTextCtrl::ms_logChar);
  449. menuLog->Check(TEXT_LOG_TEXT, MyTextCtrl::ms_logText);
  450. menu_bar->Append(menuLog, wxT("&Log"));
  451. #endif // wxUSE_LOG
  452. frame->SetMenuBar(menu_bar);
  453. frame->Show(true);
  454. // report success
  455. return true;
  456. }
  457. //----------------------------------------------------------------------
  458. // MyTextCtrl
  459. //----------------------------------------------------------------------
  460. wxBEGIN_EVENT_TABLE(MyTextCtrl, wxTextCtrl)
  461. EVT_KEY_DOWN(MyTextCtrl::OnKeyDown)
  462. EVT_KEY_UP(MyTextCtrl::OnKeyUp)
  463. EVT_CHAR(MyTextCtrl::OnChar)
  464. EVT_TEXT(wxID_ANY, MyTextCtrl::OnText)
  465. EVT_TEXT_ENTER(wxID_ANY, MyTextCtrl::OnTextEnter)
  466. EVT_TEXT_URL(wxID_ANY, MyTextCtrl::OnTextURL)
  467. EVT_TEXT_MAXLEN(wxID_ANY, MyTextCtrl::OnTextMaxLen)
  468. EVT_TEXT_CUT(wxID_ANY, MyTextCtrl::OnTextCut)
  469. EVT_TEXT_COPY(wxID_ANY, MyTextCtrl::OnTextCopy)
  470. EVT_TEXT_PASTE(wxID_ANY, MyTextCtrl::OnTextPaste)
  471. EVT_MOUSE_EVENTS(MyTextCtrl::OnMouseEvent)
  472. EVT_SET_FOCUS(MyTextCtrl::OnSetFocus)
  473. EVT_KILL_FOCUS(MyTextCtrl::OnKillFocus)
  474. wxEND_EVENT_TABLE()
  475. bool MyTextCtrl::ms_logKey = false;
  476. bool MyTextCtrl::ms_logChar = false;
  477. bool MyTextCtrl::ms_logMouse = false;
  478. bool MyTextCtrl::ms_logText = false;
  479. bool MyTextCtrl::ms_logFocus = false;
  480. bool MyTextCtrl::ms_logClip = false;
  481. void MyTextCtrl::LogKeyEvent(const wxChar *name, wxKeyEvent& event) const
  482. {
  483. wxString key;
  484. long keycode = event.GetKeyCode();
  485. {
  486. switch ( keycode )
  487. {
  488. case WXK_BACK: key = wxT("BACK"); break;
  489. case WXK_TAB: key = wxT("TAB"); break;
  490. case WXK_RETURN: key = wxT("RETURN"); break;
  491. case WXK_ESCAPE: key = wxT("ESCAPE"); break;
  492. case WXK_SPACE: key = wxT("SPACE"); break;
  493. case WXK_DELETE: key = wxT("DELETE"); break;
  494. case WXK_START: key = wxT("START"); break;
  495. case WXK_LBUTTON: key = wxT("LBUTTON"); break;
  496. case WXK_RBUTTON: key = wxT("RBUTTON"); break;
  497. case WXK_CANCEL: key = wxT("CANCEL"); break;
  498. case WXK_MBUTTON: key = wxT("MBUTTON"); break;
  499. case WXK_CLEAR: key = wxT("CLEAR"); break;
  500. case WXK_SHIFT: key = wxT("SHIFT"); break;
  501. case WXK_ALT: key = wxT("ALT"); break;
  502. case WXK_CONTROL: key = wxT("CONTROL"); break;
  503. case WXK_MENU: key = wxT("MENU"); break;
  504. case WXK_PAUSE: key = wxT("PAUSE"); break;
  505. case WXK_CAPITAL: key = wxT("CAPITAL"); break;
  506. case WXK_END: key = wxT("END"); break;
  507. case WXK_HOME: key = wxT("HOME"); break;
  508. case WXK_LEFT: key = wxT("LEFT"); break;
  509. case WXK_UP: key = wxT("UP"); break;
  510. case WXK_RIGHT: key = wxT("RIGHT"); break;
  511. case WXK_DOWN: key = wxT("DOWN"); break;
  512. case WXK_SELECT: key = wxT("SELECT"); break;
  513. case WXK_PRINT: key = wxT("PRINT"); break;
  514. case WXK_EXECUTE: key = wxT("EXECUTE"); break;
  515. case WXK_SNAPSHOT: key = wxT("SNAPSHOT"); break;
  516. case WXK_INSERT: key = wxT("INSERT"); break;
  517. case WXK_HELP: key = wxT("HELP"); break;
  518. case WXK_NUMPAD0: key = wxT("NUMPAD0"); break;
  519. case WXK_NUMPAD1: key = wxT("NUMPAD1"); break;
  520. case WXK_NUMPAD2: key = wxT("NUMPAD2"); break;
  521. case WXK_NUMPAD3: key = wxT("NUMPAD3"); break;
  522. case WXK_NUMPAD4: key = wxT("NUMPAD4"); break;
  523. case WXK_NUMPAD5: key = wxT("NUMPAD5"); break;
  524. case WXK_NUMPAD6: key = wxT("NUMPAD6"); break;
  525. case WXK_NUMPAD7: key = wxT("NUMPAD7"); break;
  526. case WXK_NUMPAD8: key = wxT("NUMPAD8"); break;
  527. case WXK_NUMPAD9: key = wxT("NUMPAD9"); break;
  528. case WXK_MULTIPLY: key = wxT("MULTIPLY"); break;
  529. case WXK_ADD: key = wxT("ADD"); break;
  530. case WXK_SEPARATOR: key = wxT("SEPARATOR"); break;
  531. case WXK_SUBTRACT: key = wxT("SUBTRACT"); break;
  532. case WXK_DECIMAL: key = wxT("DECIMAL"); break;
  533. case WXK_DIVIDE: key = wxT("DIVIDE"); break;
  534. case WXK_F1: key = wxT("F1"); break;
  535. case WXK_F2: key = wxT("F2"); break;
  536. case WXK_F3: key = wxT("F3"); break;
  537. case WXK_F4: key = wxT("F4"); break;
  538. case WXK_F5: key = wxT("F5"); break;
  539. case WXK_F6: key = wxT("F6"); break;
  540. case WXK_F7: key = wxT("F7"); break;
  541. case WXK_F8: key = wxT("F8"); break;
  542. case WXK_F9: key = wxT("F9"); break;
  543. case WXK_F10: key = wxT("F10"); break;
  544. case WXK_F11: key = wxT("F11"); break;
  545. case WXK_F12: key = wxT("F12"); break;
  546. case WXK_F13: key = wxT("F13"); break;
  547. case WXK_F14: key = wxT("F14"); break;
  548. case WXK_F15: key = wxT("F15"); break;
  549. case WXK_F16: key = wxT("F16"); break;
  550. case WXK_F17: key = wxT("F17"); break;
  551. case WXK_F18: key = wxT("F18"); break;
  552. case WXK_F19: key = wxT("F19"); break;
  553. case WXK_F20: key = wxT("F20"); break;
  554. case WXK_F21: key = wxT("F21"); break;
  555. case WXK_F22: key = wxT("F22"); break;
  556. case WXK_F23: key = wxT("F23"); break;
  557. case WXK_F24: key = wxT("F24"); break;
  558. case WXK_NUMLOCK: key = wxT("NUMLOCK"); break;
  559. case WXK_SCROLL: key = wxT("SCROLL"); break;
  560. case WXK_PAGEUP: key = wxT("PAGEUP"); break;
  561. case WXK_PAGEDOWN: key = wxT("PAGEDOWN"); break;
  562. case WXK_NUMPAD_SPACE: key = wxT("NUMPAD_SPACE"); break;
  563. case WXK_NUMPAD_TAB: key = wxT("NUMPAD_TAB"); break;
  564. case WXK_NUMPAD_ENTER: key = wxT("NUMPAD_ENTER"); break;
  565. case WXK_NUMPAD_F1: key = wxT("NUMPAD_F1"); break;
  566. case WXK_NUMPAD_F2: key = wxT("NUMPAD_F2"); break;
  567. case WXK_NUMPAD_F3: key = wxT("NUMPAD_F3"); break;
  568. case WXK_NUMPAD_F4: key = wxT("NUMPAD_F4"); break;
  569. case WXK_NUMPAD_HOME: key = wxT("NUMPAD_HOME"); break;
  570. case WXK_NUMPAD_LEFT: key = wxT("NUMPAD_LEFT"); break;
  571. case WXK_NUMPAD_UP: key = wxT("NUMPAD_UP"); break;
  572. case WXK_NUMPAD_RIGHT: key = wxT("NUMPAD_RIGHT"); break;
  573. case WXK_NUMPAD_DOWN: key = wxT("NUMPAD_DOWN"); break;
  574. case WXK_NUMPAD_PAGEUP: key = wxT("NUMPAD_PAGEUP"); break;
  575. case WXK_NUMPAD_PAGEDOWN: key = wxT("NUMPAD_PAGEDOWN"); break;
  576. case WXK_NUMPAD_END: key = wxT("NUMPAD_END"); break;
  577. case WXK_NUMPAD_BEGIN: key = wxT("NUMPAD_BEGIN"); break;
  578. case WXK_NUMPAD_INSERT: key = wxT("NUMPAD_INSERT"); break;
  579. case WXK_NUMPAD_DELETE: key = wxT("NUMPAD_DELETE"); break;
  580. case WXK_NUMPAD_EQUAL: key = wxT("NUMPAD_EQUAL"); break;
  581. case WXK_NUMPAD_MULTIPLY: key = wxT("NUMPAD_MULTIPLY"); break;
  582. case WXK_NUMPAD_ADD: key = wxT("NUMPAD_ADD"); break;
  583. case WXK_NUMPAD_SEPARATOR: key = wxT("NUMPAD_SEPARATOR"); break;
  584. case WXK_NUMPAD_SUBTRACT: key = wxT("NUMPAD_SUBTRACT"); break;
  585. case WXK_NUMPAD_DECIMAL: key = wxT("NUMPAD_DECIMAL"); break;
  586. default:
  587. {
  588. if ( wxIsprint((int)keycode) )
  589. key.Printf(wxT("'%c'"), (char)keycode);
  590. else if ( keycode > 0 && keycode < 27 )
  591. key.Printf(_("Ctrl-%c"), wxT('A') + keycode - 1);
  592. else
  593. key.Printf(wxT("unknown (%ld)"), keycode);
  594. }
  595. }
  596. }
  597. #if wxUSE_UNICODE
  598. key += wxString::Format(wxT(" (Unicode: %#04x)"), event.GetUnicodeKey());
  599. #endif // wxUSE_UNICODE
  600. wxLogMessage( wxT("%s event: %s (flags = %c%c%c%c)"),
  601. name,
  602. key.c_str(),
  603. GetChar( event.ControlDown(), wxT('C') ),
  604. GetChar( event.AltDown(), wxT('A') ),
  605. GetChar( event.ShiftDown(), wxT('S') ),
  606. GetChar( event.MetaDown(), wxT('M') ) );
  607. }
  608. static wxString GetMouseEventDesc(const wxMouseEvent& ev)
  609. {
  610. // click event
  611. wxString button;
  612. bool dbl, up;
  613. if ( ev.LeftDown() || ev.LeftUp() || ev.LeftDClick() )
  614. {
  615. button = wxT("Left");
  616. dbl = ev.LeftDClick();
  617. up = ev.LeftUp();
  618. }
  619. else if ( ev.MiddleDown() || ev.MiddleUp() || ev.MiddleDClick() )
  620. {
  621. button = wxT("Middle");
  622. dbl = ev.MiddleDClick();
  623. up = ev.MiddleUp();
  624. }
  625. else if ( ev.RightDown() || ev.RightUp() || ev.RightDClick() )
  626. {
  627. button = wxT("Right");
  628. dbl = ev.RightDClick();
  629. up = ev.RightUp();
  630. }
  631. else if ( ev.Aux1Down() || ev.Aux1Up() || ev.Aux1DClick() )
  632. {
  633. button = wxT("Aux1");
  634. dbl = ev.Aux1DClick();
  635. up = ev.Aux1Up();
  636. }
  637. else if ( ev.Aux2Down() || ev.Aux2Up() || ev.Aux2DClick() )
  638. {
  639. button = wxT("Aux2");
  640. dbl = ev.Aux2DClick();
  641. up = ev.Aux2Up();
  642. }
  643. else if ( ev.GetWheelRotation() )
  644. {
  645. return wxString::Format("Wheel rotation %+d", ev.GetWheelRotation());
  646. }
  647. else
  648. {
  649. return wxT("Unknown mouse event");
  650. }
  651. wxASSERT(!(dbl && up));
  652. return wxString::Format(wxT("%s mouse button %s"),
  653. button.c_str(),
  654. dbl ? wxT("double clicked")
  655. : up ? wxT("released") : wxT("clicked"));
  656. }
  657. void MyTextCtrl::OnMouseEvent(wxMouseEvent& ev)
  658. {
  659. ev.Skip();
  660. if ( !ms_logMouse )
  661. return;
  662. if ( !ev.Moving() )
  663. {
  664. wxString msg;
  665. if ( ev.Entering() )
  666. {
  667. msg = wxT("Mouse entered the window");
  668. }
  669. else if ( ev.Leaving() )
  670. {
  671. msg = wxT("Mouse left the window");
  672. }
  673. else
  674. {
  675. msg = GetMouseEventDesc(ev);
  676. }
  677. msg << wxT(" at (") << ev.GetX() << wxT(", ") << ev.GetY() << wxT(") ");
  678. long pos;
  679. wxTextCtrlHitTestResult rc = HitTest(ev.GetPosition(), &pos);
  680. if ( rc != wxTE_HT_UNKNOWN )
  681. {
  682. msg << wxT("at position ") << pos << wxT(' ');
  683. }
  684. msg << wxT("[Flags: ")
  685. << GetChar( ev.LeftIsDown(), wxT('1') )
  686. << GetChar( ev.MiddleIsDown(), wxT('2') )
  687. << GetChar( ev.RightIsDown(), wxT('3') )
  688. << GetChar( ev.Aux1IsDown(), wxT('x') )
  689. << GetChar( ev.Aux2IsDown(), wxT('X') )
  690. << GetChar( ev.ControlDown(), wxT('C') )
  691. << GetChar( ev.AltDown(), wxT('A') )
  692. << GetChar( ev.ShiftDown(), wxT('S') )
  693. << GetChar( ev.MetaDown(), wxT('M') )
  694. << wxT(']');
  695. wxLogMessage(msg);
  696. }
  697. //else: we're not interested in mouse move events
  698. }
  699. void MyTextCtrl::OnSetFocus(wxFocusEvent& event)
  700. {
  701. if ( ms_logFocus )
  702. {
  703. wxLogMessage( wxT("%p got focus."), this);
  704. }
  705. event.Skip();
  706. }
  707. void MyTextCtrl::OnKillFocus(wxFocusEvent& event)
  708. {
  709. if ( ms_logFocus )
  710. {
  711. wxLogMessage( wxT("%p lost focus"), this);
  712. }
  713. event.Skip();
  714. }
  715. void MyTextCtrl::OnText(wxCommandEvent& event)
  716. {
  717. if ( !ms_logText )
  718. return;
  719. MyTextCtrl *win = (MyTextCtrl *)event.GetEventObject();
  720. const wxChar *changeVerb = win->IsModified() ? wxT("changed")
  721. : wxT("set by program");
  722. const wxChar *data = (const wxChar *)(win->GetClientData());
  723. if ( data )
  724. {
  725. wxLogMessage(wxT("Text %s in control \"%s\""), changeVerb, data);
  726. }
  727. else
  728. {
  729. wxLogMessage(wxT("Text %s in some control"), changeVerb);
  730. }
  731. }
  732. void MyTextCtrl::OnTextEnter(wxCommandEvent& event)
  733. {
  734. if ( !ms_logText )
  735. return;
  736. MyTextCtrl *win = (MyTextCtrl *)event.GetEventObject();
  737. const wxChar *data = (const wxChar *)(win->GetClientData());
  738. if ( data )
  739. {
  740. wxLogMessage(wxT("Enter pressed in control '%s'"), data);
  741. }
  742. else
  743. {
  744. wxLogMessage(wxT("Enter pressed in some control"));
  745. }
  746. }
  747. void MyTextCtrl::OnTextMaxLen(wxCommandEvent& WXUNUSED(event))
  748. {
  749. wxLogMessage(wxT("You can't enter more characters into this control."));
  750. }
  751. void MyTextCtrl::OnTextCut(wxClipboardTextEvent& event)
  752. {
  753. LogClipEvent(wxT("cut to"), event);
  754. }
  755. void MyTextCtrl::OnTextCopy(wxClipboardTextEvent& event)
  756. {
  757. LogClipEvent(wxT("copied to"), event);
  758. }
  759. void MyTextCtrl::OnTextPaste(wxClipboardTextEvent& event)
  760. {
  761. LogClipEvent(wxT("pasted from"), event);
  762. }
  763. void MyTextCtrl::LogClipEvent(const wxChar *what, wxClipboardTextEvent& event)
  764. {
  765. wxFrame *frame = wxDynamicCast(wxGetTopLevelParent(this), wxFrame);
  766. wxCHECK_RET( frame, wxT("no parent frame?") );
  767. const bool veto = frame->GetMenuBar()->IsChecked(TEXT_CLIPBOARD_VETO);
  768. if ( !veto )
  769. event.Skip();
  770. if ( ms_logClip )
  771. {
  772. wxLogMessage(wxT("Text %s%s the clipboard."),
  773. veto ? wxT("not ") : wxT(""), what);
  774. }
  775. }
  776. void MyTextCtrl::OnTextURL(wxTextUrlEvent& event)
  777. {
  778. const wxMouseEvent& ev = event.GetMouseEvent();
  779. // filter out mouse moves, too many of them
  780. if ( ev.Moving() )
  781. return;
  782. long start = event.GetURLStart(),
  783. end = event.GetURLEnd();
  784. wxLogMessage(wxT("Mouse event over URL '%s': %s"),
  785. GetValue().Mid(start, end - start).c_str(),
  786. GetMouseEventDesc(ev).c_str());
  787. }
  788. void MyTextCtrl::OnChar(wxKeyEvent& event)
  789. {
  790. if ( ms_logChar )
  791. LogKeyEvent( wxT("Char"), event);
  792. event.Skip();
  793. }
  794. void MyTextCtrl::OnKeyUp(wxKeyEvent& event)
  795. {
  796. if ( ms_logKey )
  797. LogKeyEvent( wxT("Key up"), event);
  798. event.Skip();
  799. }
  800. void MyTextCtrl::OnKeyDown(wxKeyEvent& event)
  801. {
  802. switch ( event.GetKeyCode() )
  803. {
  804. case WXK_F1:
  805. // show current position and text length
  806. {
  807. long line, column, pos = GetInsertionPoint();
  808. PositionToXY(pos, &column, &line);
  809. wxLogMessage(wxT("Current position: %ld\nCurrent line, column: (%ld, %ld)\nNumber of lines: %ld\nCurrent line length: %ld\nTotal text length: %u (%ld)"),
  810. pos,
  811. line, column,
  812. (long) GetNumberOfLines(),
  813. (long) GetLineLength(line),
  814. (unsigned int) GetValue().length(),
  815. GetLastPosition());
  816. long from, to;
  817. GetSelection(&from, &to);
  818. wxString sel = GetStringSelection();
  819. wxLogMessage(wxT("Selection: from %ld to %ld."), from, to);
  820. wxLogMessage(wxT("Selection = '%s' (len = %u)"),
  821. sel.c_str(),
  822. (unsigned int) sel.length());
  823. const wxString text = GetLineText(line);
  824. wxLogMessage(wxT("Current line: \"%s\"; length = %lu"),
  825. text.c_str(), text.length());
  826. }
  827. break;
  828. case WXK_F2:
  829. // go to the end
  830. SetInsertionPointEnd();
  831. break;
  832. case WXK_F3:
  833. // go to position 10
  834. SetInsertionPoint(10);
  835. break;
  836. case WXK_F4:
  837. if (!m_hasCapture)
  838. {
  839. wxLogDebug( wxT("Now capturing mouse and events.") );
  840. m_hasCapture = true;
  841. CaptureMouse();
  842. }
  843. else
  844. {
  845. wxLogDebug( wxT("Stopped capturing mouse and events.") );
  846. m_hasCapture = false;
  847. ReleaseMouse();
  848. }
  849. break;
  850. case WXK_F5:
  851. // insert a blank line
  852. WriteText(wxT("\n"));
  853. break;
  854. case WXK_F6:
  855. wxLogMessage(wxT("IsModified() before SetValue(): %d"),
  856. IsModified());
  857. ChangeValue(wxT("ChangeValue() has been called"));
  858. wxLogMessage(wxT("IsModified() after SetValue(): %d"),
  859. IsModified());
  860. break;
  861. case WXK_F7:
  862. wxLogMessage(wxT("Position 10 should be now visible."));
  863. ShowPosition(10);
  864. break;
  865. case WXK_F8:
  866. wxLogMessage(wxT("Control has been cleared"));
  867. Clear();
  868. break;
  869. case WXK_F9:
  870. WriteText(wxT("WriteText() has been called"));
  871. break;
  872. case WXK_F10:
  873. AppendText(wxT("AppendText() has been called"));
  874. break;
  875. case WXK_F11:
  876. DiscardEdits();
  877. wxLogMessage(wxT("Control marked as non modified"));
  878. break;
  879. }
  880. if ( ms_logKey )
  881. LogKeyEvent( wxT("Key down"), event);
  882. event.Skip();
  883. }
  884. //----------------------------------------------------------------------
  885. // MyPanel
  886. //----------------------------------------------------------------------
  887. MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
  888. : wxPanel( frame, wxID_ANY, wxPoint(x, y), wxSize(w, h) )
  889. {
  890. #if wxUSE_LOG
  891. m_log = new wxTextCtrl( this, wxID_ANY, wxT("This is the log window.\n"),
  892. wxPoint(5,260), wxSize(630,100),
  893. wxTE_MULTILINE | wxTE_READONLY);
  894. m_logOld = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
  895. #endif // wxUSE_LOG
  896. // single line text controls
  897. m_text = new MyTextCtrl( this, wxID_ANY, wxT("Single line."),
  898. wxDefaultPosition, wxDefaultSize,
  899. wxTE_PROCESS_ENTER);
  900. m_text->SetForegroundColour(*wxBLUE);
  901. m_text->SetBackgroundColour(*wxLIGHT_GREY);
  902. (*m_text) << wxT(" Appended.");
  903. m_text->SetInsertionPoint(0);
  904. m_text->WriteText( wxT("Prepended. ") );
  905. m_password = new MyTextCtrl( this, wxID_ANY, wxT(""),
  906. wxPoint(10,50), wxSize(140,wxDefaultCoord), wxTE_PASSWORD );
  907. m_limited = new MyTextCtrl(this, wxID_ANY, "",
  908. wxPoint(10, 90), wxDefaultSize);
  909. m_limited->SetHint("Max 8 ch");
  910. m_limited->SetMaxLength(8);
  911. wxSize size2 = m_limited->GetSizeFromTextSize(m_limited->GetTextExtent("WWWWWWWW"));
  912. m_limited->SetSizeHints(size2, size2);
  913. // multi line text controls
  914. wxString string3L("Read only\nMultiline\nFitted size");
  915. m_readonly = new MyTextCtrl( this, wxID_ANY, string3L,
  916. wxPoint(10, 120), wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY );
  917. wxWindowDC dc(m_readonly);
  918. size2 = m_readonly->GetSizeFromTextSize(dc.GetMultiLineTextExtent(string3L));
  919. m_readonly->SetMinSize(size2);
  920. m_horizontal = new MyTextCtrl( this, wxID_ANY, wxT("Multiline text control with a horizontal scrollbar.\n"),
  921. wxPoint(10,170), wxSize(140,70), wxTE_MULTILINE | wxHSCROLL);
  922. // a little hack to use the command line argument for encoding testing
  923. if ( wxTheApp->argc == 2 )
  924. {
  925. switch ( (wxChar)wxTheApp->argv[1][0] )
  926. {
  927. case '2':
  928. m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
  929. false, wxT(""),
  930. wxFONTENCODING_ISO8859_2));
  931. m_horizontal->AppendText(wxT("\256lu\273ou\350k\375 k\371\362 zb\354sile \350e\271tina \253\273"));
  932. break;
  933. case '1':
  934. m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
  935. false, wxT(""),
  936. wxFONTENCODING_CP1251));
  937. m_horizontal->AppendText(wxT("\317\360\350\342\345\362!"));
  938. break;
  939. case '8':
  940. m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
  941. false, wxT(""),
  942. wxFONTENCODING_CP1251));
  943. #if wxUSE_UNICODE
  944. m_horizontal->AppendText(L"\x0412\x0430\x0434\x0438\x043c \x0426");
  945. #else
  946. m_horizontal->AppendText("\313\301\326\305\324\323\321 \325\304\301\336\316\331\315");
  947. #endif
  948. }
  949. }
  950. else
  951. {
  952. m_horizontal->AppendText(wxT("Text in default encoding"));
  953. }
  954. m_multitext = new MyTextCtrl( this, wxID_ANY,
  955. wxT("Multi line without vertical scrollbar."),
  956. wxPoint(180,10), wxSize(200,70), wxTE_MULTILINE | wxTE_NO_VSCROLL );
  957. m_multitext->SetFont(*wxITALIC_FONT);
  958. (*m_multitext) << wxT(" Appended.");
  959. m_multitext->SetInsertionPoint(0);
  960. m_multitext->WriteText( wxT("Prepended. ") );
  961. m_multitext->SetForegroundColour(*wxYELLOW);
  962. m_multitext->SetBackgroundColour(*wxLIGHT_GREY);
  963. #if wxUSE_TOOLTIPS
  964. m_multitext->SetToolTip(wxT("Press Fn function keys here"));
  965. #endif
  966. m_tab = new MyTextCtrl( this, 100, wxT("Multiline, allow <TAB> processing."),
  967. wxPoint(180,90), wxDefaultSize, wxTE_MULTILINE | wxTE_PROCESS_TAB );
  968. m_tab->SetClientData((void *)wxT("tab"));
  969. m_enter = new MyTextCtrl( this, 100, wxT("Multiline, allow <ENTER> processing."),
  970. wxPoint(180,170), wxSize(200,70), wxTE_MULTILINE);
  971. m_enter->SetClientData((void *)wxT("enter"));
  972. m_textrich = new MyTextCtrl(this, wxID_ANY, wxT("Allows more than 30Kb of text\n")
  973. wxT("(even under broken Win9x)\n")
  974. wxT("and a very very very very very ")
  975. wxT("very very very long line to test ")
  976. wxT("wxHSCROLL style\n")
  977. wxT("\nAnd here is a link in quotation marks to ")
  978. wxT("test wxTE_AUTO_URL: \"http://www.wxwidgets.org\""),
  979. wxPoint(450, 10), wxSize(200, 230),
  980. wxTE_RICH | wxTE_MULTILINE | wxTE_AUTO_URL);
  981. m_textrich->SetStyle(0, 10, *wxRED);
  982. m_textrich->SetStyle(10, 20, *wxBLUE);
  983. m_textrich->SetStyle(30, 40,
  984. wxTextAttr(*wxGREEN, wxNullColour, *wxITALIC_FONT));
  985. m_textrich->SetDefaultStyle(wxTextAttr());
  986. m_textrich->AppendText(wxT("\n\nFirst 10 characters should be in red\n"));
  987. m_textrich->AppendText(wxT("Next 10 characters should be in blue\n"));
  988. m_textrich->AppendText(wxT("Next 10 characters should be normal\n"));
  989. m_textrich->AppendText(wxT("And the next 10 characters should be green and italic\n"));
  990. m_textrich->SetDefaultStyle(wxTextAttr(*wxCYAN, *wxBLUE));
  991. m_textrich->AppendText(wxT("This text should be cyan on blue\n"));
  992. m_textrich->SetDefaultStyle(wxTextAttr(*wxBLUE, *wxWHITE));
  993. m_textrich->AppendText(wxT("And this should be in blue and the text you ")
  994. wxT("type should be in blue as well"));
  995. // lay out the controls
  996. wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL);
  997. column1->Add( m_text, 0, wxALL | wxEXPAND, 10 );
  998. column1->Add( m_password, 0, wxALL | wxEXPAND, 10 );
  999. column1->Add( m_readonly, 0, wxALL, 10 );
  1000. column1->Add( m_limited, 0, wxALL, 10 );
  1001. column1->Add( m_horizontal, 1, wxALL | wxEXPAND, 10 );
  1002. wxBoxSizer *column2 = new wxBoxSizer(wxVERTICAL);
  1003. column2->Add( m_multitext, 1, wxALL | wxEXPAND, 10 );
  1004. column2->Add( m_tab, 0, wxALL | wxEXPAND, 10 );
  1005. column2->Add( m_enter, 1, wxALL | wxEXPAND, 10 );
  1006. wxBoxSizer *row1 = new wxBoxSizer(wxHORIZONTAL);
  1007. row1->Add( column1, 0, wxALL | wxEXPAND, 10 );
  1008. row1->Add( column2, 1, wxALL | wxEXPAND, 10 );
  1009. row1->Add( m_textrich, 1, wxALL | wxEXPAND, 10 );
  1010. wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
  1011. topSizer->Add( row1, 2, wxALL | wxEXPAND, 10 );
  1012. #if wxUSE_LOG
  1013. topSizer->Add( m_log, 1, wxALL | wxEXPAND, 10 );
  1014. #endif
  1015. SetSizer(topSizer);
  1016. }
  1017. wxTextCtrl *MyPanel::GetFocusedText() const
  1018. {
  1019. wxWindow *win = FindFocus();
  1020. wxTextCtrl *text = win ? wxDynamicCast(win, wxTextCtrl) : NULL;
  1021. return text ? text : m_multitext;
  1022. }
  1023. #if wxUSE_CLIPBOARD
  1024. void MyPanel::DoPasteFromClipboard()
  1025. {
  1026. // On X11, we want to get the data from the primary selection instead
  1027. // of the normal clipboard (which isn't normal under X11 at all). This
  1028. // call has no effect under MSW.
  1029. wxTheClipboard->UsePrimarySelection();
  1030. if (!wxTheClipboard->Open())
  1031. {
  1032. #if wxUSE_LOG
  1033. *m_log << wxT("Error opening the clipboard.\n");
  1034. #endif // wxUSE_LOG
  1035. return;
  1036. }
  1037. else
  1038. {
  1039. #if wxUSE_LOG
  1040. *m_log << wxT("Successfully opened the clipboard.\n");
  1041. #endif // wxUSE_LOG
  1042. }
  1043. wxTextDataObject data;
  1044. if (wxTheClipboard->IsSupported( data.GetFormat() ))
  1045. {
  1046. #if wxUSE_LOG
  1047. *m_log << wxT("Clipboard supports requested format.\n");
  1048. #endif // wxUSE_LOG
  1049. if (wxTheClipboard->GetData( data ))
  1050. {
  1051. #if wxUSE_LOG
  1052. *m_log << wxT("Successfully retrieved data from the clipboard.\n");
  1053. #endif // wxUSE_LOG
  1054. GetFocusedText()->AppendText(data.GetText());
  1055. }
  1056. else
  1057. {
  1058. #if wxUSE_LOG
  1059. *m_log << wxT("Error getting data from the clipboard.\n");
  1060. #endif // wxUSE_LOG
  1061. }
  1062. }
  1063. else
  1064. {
  1065. #if wxUSE_LOG
  1066. *m_log << wxT("Clipboard doesn't support requested format.\n");
  1067. #endif // wxUSE_LOG
  1068. }
  1069. wxTheClipboard->Close();
  1070. #if wxUSE_LOG
  1071. *m_log << wxT("Closed the clipboard.\n");
  1072. #endif // wxUSE_LOG
  1073. }
  1074. void MyPanel::DoCopyToClipboard()
  1075. {
  1076. // On X11, we want to get the data from the primary selection instead
  1077. // of the normal clipboard (which isn't normal under X11 at all). This
  1078. // call has no effect under MSW.
  1079. wxTheClipboard->UsePrimarySelection();
  1080. wxString text( GetFocusedText()->GetStringSelection() );
  1081. if (text.IsEmpty())
  1082. {
  1083. #if wxUSE_LOG
  1084. *m_log << wxT("No text to copy.\n");
  1085. #endif // wxUSE_LOG
  1086. return;
  1087. }
  1088. if (!wxTheClipboard->Open())
  1089. {
  1090. #if wxUSE_LOG
  1091. *m_log << wxT("Error opening the clipboard.\n");
  1092. #endif // wxUSE_LOG
  1093. return;
  1094. }
  1095. else
  1096. {
  1097. #if wxUSE_LOG
  1098. *m_log << wxT("Successfully opened the clipboard.\n");
  1099. #endif // wxUSE_LOG
  1100. }
  1101. wxTextDataObject *data = new wxTextDataObject( text );
  1102. if (!wxTheClipboard->SetData( data ))
  1103. {
  1104. #if wxUSE_LOG
  1105. *m_log << wxT("Error while copying to the clipboard.\n");
  1106. #endif // wxUSE_LOG
  1107. }
  1108. else
  1109. {
  1110. #if wxUSE_LOG
  1111. *m_log << wxT("Successfully copied data to the clipboard.\n");
  1112. #endif // wxUSE_LOG
  1113. }
  1114. wxTheClipboard->Close();
  1115. #if wxUSE_LOG
  1116. *m_log << wxT("Closed the clipboard.\n");
  1117. #endif // wxUSE_LOG
  1118. }
  1119. #endif // wxUSE_CLIPBOARD
  1120. void MyPanel::DoMoveToEndOfText()
  1121. {
  1122. m_multitext->SetInsertionPointEnd();
  1123. m_multitext->SetFocus();
  1124. }
  1125. void MyPanel::DoGetWindowCoordinates()
  1126. {
  1127. wxTextCtrl * const text = GetFocusedText();
  1128. const wxPoint pt0 = text->PositionToCoords(0);
  1129. const wxPoint ptCur = text->PositionToCoords(text->GetInsertionPoint());
  1130. *m_log << "Current position coordinates: "
  1131. "(" << ptCur.x << ", " << ptCur.y << "), "
  1132. "first position coordinates: "
  1133. "(" << pt0.x << ", " << pt0.y << ")\n";
  1134. }
  1135. void MyPanel::DoMoveToEndOfEntry()
  1136. {
  1137. m_text->SetInsertionPointEnd();
  1138. m_text->SetFocus();
  1139. }
  1140. void MyPanel::DoRemoveText()
  1141. {
  1142. GetFocusedText()->Remove(0, 10);
  1143. }
  1144. void MyPanel::DoReplaceText()
  1145. {
  1146. GetFocusedText()->Replace(3, 8, wxT("ABC"));
  1147. }
  1148. void MyPanel::DoSelectText()
  1149. {
  1150. GetFocusedText()->SetSelection(3, 8);
  1151. }
  1152. //----------------------------------------------------------------------
  1153. // MyFrame
  1154. //----------------------------------------------------------------------
  1155. wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
  1156. EVT_MENU(TEXT_QUIT, MyFrame::OnQuit)
  1157. EVT_MENU(TEXT_ABOUT, MyFrame::OnAbout)
  1158. EVT_MENU(TEXT_SAVE, MyFrame::OnFileSave)
  1159. EVT_MENU(TEXT_LOAD, MyFrame::OnFileLoad)
  1160. EVT_MENU(TEXT_RICH_TEXT_TEST, MyFrame::OnRichTextTest)
  1161. EVT_MENU(TEXT_LOG_KEY, MyFrame::OnLogKey)
  1162. EVT_MENU(TEXT_LOG_CHAR, MyFrame::OnLogChar)
  1163. EVT_MENU(TEXT_LOG_MOUSE,MyFrame::OnLogMouse)
  1164. EVT_MENU(TEXT_LOG_TEXT, MyFrame::OnLogText)
  1165. EVT_MENU(TEXT_LOG_FOCUS,MyFrame::OnLogFocus)
  1166. EVT_MENU(TEXT_LOG_CLIP, MyFrame::OnLogClip)
  1167. #if wxUSE_LOG
  1168. EVT_MENU(TEXT_CLEAR, MyFrame::OnLogClear)
  1169. #endif // wxUSE_LOG
  1170. #if wxUSE_TOOLTIPS
  1171. EVT_MENU(TEXT_TOOLTIPS_SETDELAY, MyFrame::OnSetTooltipDelay)
  1172. EVT_MENU(TEXT_TOOLTIPS_ENABLE, MyFrame::OnToggleTooltips)
  1173. #endif // wxUSE_TOOLTIPS
  1174. #if wxUSE_CLIPBOARD
  1175. EVT_MENU(TEXT_CLIPBOARD_PASTE, MyFrame::OnPasteFromClipboard)
  1176. EVT_MENU(TEXT_CLIPBOARD_COPY, MyFrame::OnCopyToClipboard)
  1177. EVT_UPDATE_UI(TEXT_CLIPBOARD_PASTE, MyFrame::OnUpdatePasteFromClipboard)
  1178. EVT_UPDATE_UI(TEXT_CLIPBOARD_COPY, MyFrame::OnUpdateCopyToClipboard)
  1179. #endif // wxUSE_CLIPBOARD
  1180. EVT_MENU(TEXT_REMOVE, MyFrame::OnRemoveText)
  1181. EVT_MENU(TEXT_REPLACE, MyFrame::OnReplaceText)
  1182. EVT_MENU(TEXT_SELECT, MyFrame::OnSelectText)
  1183. EVT_MENU(TEXT_ADD_SOME, MyFrame::OnAddText)
  1184. EVT_MENU(TEXT_ADD_FREEZE, MyFrame::OnAddTextFreeze)
  1185. EVT_MENU(TEXT_ADD_LINE, MyFrame::OnAddTextLine)
  1186. EVT_MENU(TEXT_MOVE_ENDTEXT, MyFrame::OnMoveToEndOfText)
  1187. EVT_MENU(TEXT_GET_WINDOW_COORD, MyFrame::OnGetWindowCoordinates)
  1188. EVT_MENU(TEXT_MOVE_ENDENTRY, MyFrame::OnMoveToEndOfEntry)
  1189. EVT_MENU(TEXT_SET_EDITABLE, MyFrame::OnSetEditable)
  1190. EVT_MENU(TEXT_SET_ENABLED, MyFrame::OnSetEnabled)
  1191. EVT_MENU(TEXT_LINE_DOWN, MyFrame::OnScrollLineDown)
  1192. EVT_MENU(TEXT_LINE_UP, MyFrame::OnScrollLineUp)
  1193. EVT_MENU(TEXT_PAGE_DOWN, MyFrame::OnScrollPageDown)
  1194. EVT_MENU(TEXT_PAGE_UP, MyFrame::OnScrollPageUp)
  1195. EVT_MENU(TEXT_GET_LINE, MyFrame::OnGetLine)
  1196. EVT_MENU(TEXT_GET_LINELENGTH, MyFrame::OnGetLineLength)
  1197. EVT_MENU(TEXT_SET, MyFrame::OnSetText)
  1198. EVT_MENU(TEXT_CHANGE, MyFrame::OnChangeText)
  1199. EVT_IDLE(MyFrame::OnIdle)
  1200. wxEND_EVENT_TABLE()
  1201. MyFrame::MyFrame(wxFrame *frame, const wxChar *title, int x, int y, int w, int h)
  1202. : wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h) )
  1203. {
  1204. SetIcon(wxICON(sample));
  1205. #if wxUSE_STATUSBAR
  1206. CreateStatusBar(2);
  1207. #endif // wxUSE_STATUSBAR
  1208. m_panel = new MyPanel( this, 10, 10, 300, 100 );
  1209. }
  1210. void MyFrame::OnQuit (wxCommandEvent& WXUNUSED(event) )
  1211. {
  1212. Close(true);
  1213. }
  1214. void MyFrame::OnAbout( wxCommandEvent& WXUNUSED(event) )
  1215. {
  1216. wxBeginBusyCursor();
  1217. wxMessageDialog dialog(this,
  1218. wxT("This is a text control sample. It demonstrates the many different\n")
  1219. wxT("text control styles, the use of the clipboard, setting and handling\n")
  1220. wxT("tooltips and intercepting key and char events.\n")
  1221. wxT("\n")
  1222. wxT("Copyright (c) 1999, Robert Roebling, Julian Smart, Vadim Zeitlin"),
  1223. wxT("About wxTextCtrl Sample"),
  1224. wxOK | wxICON_INFORMATION);
  1225. dialog.ShowModal();
  1226. wxEndBusyCursor();
  1227. }
  1228. #if wxUSE_TOOLTIPS
  1229. void MyFrame::OnSetTooltipDelay(wxCommandEvent& WXUNUSED(event))
  1230. {
  1231. static long s_delay = 5000;
  1232. wxString delay;
  1233. delay.Printf( wxT("%ld"), s_delay);
  1234. delay = wxGetTextFromUser(wxT("Enter delay (in milliseconds)"),
  1235. wxT("Set tooltip delay"),
  1236. delay,
  1237. this);
  1238. if ( !delay )
  1239. return; // cancelled
  1240. wxSscanf(delay, wxT("%ld"), &s_delay);
  1241. wxToolTip::SetDelay(s_delay);
  1242. wxLogStatus(this, wxT("Tooltip delay set to %ld milliseconds"), s_delay);
  1243. }
  1244. void MyFrame::OnToggleTooltips(wxCommandEvent& WXUNUSED(event))
  1245. {
  1246. static bool s_enabled = true;
  1247. s_enabled = !s_enabled;
  1248. wxToolTip::Enable(s_enabled);
  1249. wxLogStatus(this, wxT("Tooltips %sabled"), s_enabled ? wxT("en") : wxT("dis") );
  1250. }
  1251. #endif // tooltips
  1252. #if wxUSE_LOG
  1253. void MyFrame::OnLogClear(wxCommandEvent& WXUNUSED(event))
  1254. {
  1255. m_panel->m_log->Clear();
  1256. }
  1257. #endif // wxUSE_LOG
  1258. void MyFrame::OnSetEditable(wxCommandEvent& WXUNUSED(event))
  1259. {
  1260. static bool s_editable = true;
  1261. s_editable = !s_editable;
  1262. m_panel->m_text->SetEditable(s_editable);
  1263. m_panel->m_password->SetEditable(s_editable);
  1264. m_panel->m_multitext->SetEditable(s_editable);
  1265. m_panel->m_textrich->SetEditable(s_editable);
  1266. }
  1267. void MyFrame::OnSetEnabled(wxCommandEvent& WXUNUSED(event))
  1268. {
  1269. bool enabled = m_panel->m_text->IsEnabled();
  1270. enabled = !enabled;
  1271. m_panel->m_text->Enable(enabled);
  1272. m_panel->m_password->Enable(enabled);
  1273. m_panel->m_multitext->Enable(enabled);
  1274. m_panel->m_readonly->Enable(enabled);
  1275. m_panel->m_limited->Enable(enabled);
  1276. m_panel->m_textrich->Enable(enabled);
  1277. }
  1278. void MyFrame::OnFileSave(wxCommandEvent& WXUNUSED(event))
  1279. {
  1280. if ( m_panel->m_textrich->SaveFile(wxT("dummy.txt")) )
  1281. {
  1282. #if wxUSE_FILE
  1283. // verify that the fil length is correct (it wasn't under Win95)
  1284. wxFile file(wxT("dummy.txt"));
  1285. wxLogStatus(this,
  1286. wxT("Successfully saved file (text len = %lu, file size = %ld)"),
  1287. (unsigned long)m_panel->m_textrich->GetValue().length(),
  1288. (long) file.Length());
  1289. #endif
  1290. }
  1291. else
  1292. wxLogStatus(this, wxT("Couldn't save the file"));
  1293. }
  1294. void MyFrame::OnFileLoad(wxCommandEvent& WXUNUSED(event))
  1295. {
  1296. if ( m_panel->m_textrich->LoadFile(wxT("dummy.txt")) )
  1297. {
  1298. wxLogStatus(this, wxT("Successfully loaded file"));
  1299. }
  1300. else
  1301. {
  1302. wxLogStatus(this, wxT("Couldn't load the file"));
  1303. }
  1304. }
  1305. void MyFrame::OnRichTextTest(wxCommandEvent& WXUNUSED(event))
  1306. {
  1307. RichTextFrame* frame = new RichTextFrame(this, wxT("Rich Text Editor"));
  1308. frame->Show(true);
  1309. }
  1310. void MyFrame::OnIdle( wxIdleEvent& event )
  1311. {
  1312. // track the window which has the focus in the status bar
  1313. static wxWindow *s_windowFocus = (wxWindow *)NULL;
  1314. wxWindow *focus = wxWindow::FindFocus();
  1315. if ( focus && (focus != s_windowFocus) )
  1316. {
  1317. s_windowFocus = focus;
  1318. wxString msg;
  1319. msg.Printf(
  1320. #ifdef __WXMSW__
  1321. wxT("Focus: wxWindow = %p, HWND = %p"),
  1322. #else
  1323. wxT("Focus: wxWindow = %p"),
  1324. #endif
  1325. s_windowFocus
  1326. #ifdef __WXMSW__
  1327. , s_windowFocus->GetHWND()
  1328. #endif
  1329. );
  1330. #if wxUSE_STATUSBAR
  1331. SetStatusText(msg);
  1332. #endif // wxUSE_STATUSBAR
  1333. }
  1334. event.Skip();
  1335. }
  1336. /*
  1337. * RichTextFrame is used to demonstrate rich text behaviour
  1338. */
  1339. enum
  1340. {
  1341. RICHTEXT_CLOSE = 1000,
  1342. RICHTEXT_LEFT_ALIGN,
  1343. RICHTEXT_RIGHT_ALIGN,
  1344. RICHTEXT_CENTRE,
  1345. RICHTEXT_JUSTIFY,
  1346. RICHTEXT_CHANGE_FONT,
  1347. RICHTEXT_CHANGE_TEXT_COLOUR,
  1348. RICHTEXT_CHANGE_BACKGROUND_COLOUR,
  1349. RICHTEXT_LEFT_INDENT,
  1350. RICHTEXT_RIGHT_INDENT,
  1351. RICHTEXT_TAB_STOPS
  1352. };
  1353. wxBEGIN_EVENT_TABLE(RichTextFrame, wxFrame)
  1354. EVT_IDLE(RichTextFrame::OnIdle)
  1355. EVT_MENU(RICHTEXT_CLOSE, RichTextFrame::OnClose)
  1356. EVT_MENU(RICHTEXT_LEFT_ALIGN, RichTextFrame::OnLeftAlign)
  1357. EVT_MENU(RICHTEXT_RIGHT_ALIGN, RichTextFrame::OnRightAlign)
  1358. EVT_MENU(RICHTEXT_CENTRE, RichTextFrame::OnCentre)
  1359. EVT_MENU(RICHTEXT_JUSTIFY, RichTextFrame::OnJustify)
  1360. EVT_MENU(RICHTEXT_CHANGE_FONT, RichTextFrame::OnChangeFont)
  1361. EVT_MENU(RICHTEXT_CHANGE_TEXT_COLOUR, RichTextFrame::OnChangeTextColour)
  1362. EVT_MENU(RICHTEXT_CHANGE_BACKGROUND_COLOUR, RichTextFrame::OnChangeBackgroundColour)
  1363. EVT_MENU(RICHTEXT_LEFT_INDENT, RichTextFrame::OnLeftIndent)
  1364. EVT_MENU(RICHTEXT_RIGHT_INDENT, RichTextFrame::OnRightIndent)
  1365. EVT_MENU(RICHTEXT_TAB_STOPS, RichTextFrame::OnTabStops)
  1366. wxEND_EVENT_TABLE()
  1367. RichTextFrame::RichTextFrame(wxWindow* parent, const wxString& title):
  1368. wxFrame(parent, wxID_ANY, title, wxDefaultPosition, wxSize(300, 400))
  1369. {
  1370. m_currentPosition = -1;
  1371. m_textCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
  1372. wxDefaultSize, wxTE_MULTILINE|wxTE_RICH2);
  1373. wxString value;
  1374. int i;
  1375. for (i = 0; i < 10; i++)
  1376. {
  1377. int j;
  1378. for (j = 0; j < 10; j++)
  1379. {
  1380. value << wxT("Hello, welcome to a very simple rich text editor. You can set some character and paragraph styles from the Edit menu. ");
  1381. }
  1382. value << wxT("\n\n");
  1383. }
  1384. m_textCtrl->SetValue(value);
  1385. wxMenuBar* menuBar = new wxMenuBar;
  1386. wxMenu* fileMenu = new wxMenu;
  1387. fileMenu->Append(RICHTEXT_CLOSE, _("Close\tCtrl+W"));
  1388. menuBar->Append(fileMenu, _("File"));
  1389. wxMenu* editMenu = new wxMenu;
  1390. editMenu->Append(RICHTEXT_LEFT_ALIGN, _("Left Align"));
  1391. editMenu->Append(RICHTEXT_RIGHT_ALIGN, _("Right Align"));
  1392. editMenu->Append(RICHTEXT_CENTRE, _("Centre"));
  1393. editMenu->Append(RICHTEXT_JUSTIFY, _("Justify"));
  1394. editMenu->AppendSeparator();
  1395. editMenu->Append(RICHTEXT_CHANGE_FONT, _("Change Font"));
  1396. editMenu->Append(RICHTEXT_CHANGE_TEXT_COLOUR, _("Change Text Colour"));
  1397. editMenu->Append(RICHTEXT_CHANGE_BACKGROUND_COLOUR, _("Change Background Colour"));
  1398. editMenu->AppendSeparator();
  1399. editMenu->Append(RICHTEXT_LEFT_INDENT, _("Left Indent"));
  1400. editMenu->Append(RICHTEXT_RIGHT_INDENT, _("Right Indent"));
  1401. editMenu->Append(RICHTEXT_TAB_STOPS, _("Tab Stops"));
  1402. menuBar->Append(editMenu, _("Edit"));
  1403. SetMenuBar(menuBar);
  1404. #if wxUSE_STATUSBAR
  1405. CreateStatusBar();
  1406. #endif // wxUSE_STATUSBAR
  1407. }
  1408. // Event handlers
  1409. void RichTextFrame::OnClose(wxCommandEvent& WXUNUSED(event))
  1410. {
  1411. Close(true);
  1412. }
  1413. void RichTextFrame::OnLeftAlign(wxCommandEvent& WXUNUSED(event))
  1414. {
  1415. wxTextAttr attr;
  1416. attr.SetAlignment(wxTEXT_ALIGNMENT_LEFT);
  1417. long start, end;
  1418. m_textCtrl->GetSelection(& start, & end);
  1419. m_textCtrl->SetStyle(start, end, attr);
  1420. m_currentPosition = -1;
  1421. }
  1422. void RichTextFrame::OnRightAlign(wxCommandEvent& WXUNUSED(event))
  1423. {
  1424. wxTextAttr attr;
  1425. attr.SetAlignment(wxTEXT_ALIGNMENT_RIGHT);
  1426. long start, end;
  1427. m_textCtrl->GetSelection(& start, & end);
  1428. m_textCtrl->SetStyle(start, end, attr);
  1429. m_currentPosition = -1;
  1430. }
  1431. void RichTextFrame::OnJustify(wxCommandEvent& WXUNUSED(event))
  1432. {
  1433. wxTextAttr attr;
  1434. attr.SetAlignment(wxTEXT_ALIGNMENT_JUSTIFIED);
  1435. long start, end;
  1436. m_textCtrl->GetSelection(& start, & end);
  1437. m_textCtrl->SetStyle(start, end, attr);
  1438. m_currentPosition = -1;
  1439. }
  1440. void RichTextFrame::OnCentre(wxCommandEvent& WXUNUSED(event))
  1441. {
  1442. wxTextAttr attr;
  1443. attr.SetAlignment(wxTEXT_ALIGNMENT_CENTRE);
  1444. long start, end;
  1445. m_textCtrl->GetSelection(& start, & end);
  1446. m_textCtrl->SetStyle(start, end, attr);
  1447. m_currentPosition = -1;
  1448. }
  1449. void RichTextFrame::OnChangeFont(wxCommandEvent& WXUNUSED(event))
  1450. {
  1451. wxFontData data;
  1452. wxFontDialog dialog(this, data);
  1453. if (dialog.ShowModal() == wxID_OK)
  1454. {
  1455. wxFontData retData = dialog.GetFontData();
  1456. wxFont font = retData.GetChosenFont();
  1457. wxTextAttr attr;
  1458. attr.SetFont(font);
  1459. long start, end;
  1460. m_textCtrl->GetSelection(& start, & end);
  1461. m_textCtrl->SetStyle(start, end, attr);
  1462. m_currentPosition = -1;
  1463. }
  1464. }
  1465. void RichTextFrame::OnChangeTextColour(wxCommandEvent& WXUNUSED(event))
  1466. {
  1467. wxColourData data;
  1468. data.SetColour(* wxBLACK);
  1469. data.SetChooseFull(true);
  1470. for (int i = 0; i < 16; i++)
  1471. {
  1472. wxColour colour((unsigned char)(i*16), (unsigned char)(i*16), (unsigned char)(i*16));
  1473. data.SetCustomColour(i, colour);
  1474. }
  1475. wxColourDialog dialog(this, &data);
  1476. dialog.SetTitle(wxT("Choose the text colour"));
  1477. if (dialog.ShowModal() == wxID_OK)
  1478. {
  1479. wxColourData retData = dialog.GetColourData();
  1480. wxColour col = retData.GetColour();
  1481. wxTextAttr attr;
  1482. attr.SetTextColour(col);
  1483. long start, end;
  1484. m_textCtrl->GetSelection(& start, & end);
  1485. m_textCtrl->SetStyle(start, end, attr);
  1486. m_currentPosition = -1;
  1487. }
  1488. }
  1489. void RichTextFrame::OnChangeBackgroundColour(wxCommandEvent& WXUNUSED(event))
  1490. {
  1491. wxColourData data;
  1492. data.SetColour(* wxWHITE);
  1493. data.SetChooseFull(true);
  1494. for (int i = 0; i < 16; i++)
  1495. {
  1496. wxColour colour((unsigned char)(i*16), (unsigned char)(i*16), (unsigned char)(i*16));
  1497. data.SetCustomColour(i, colour);
  1498. }
  1499. wxColourDialog dialog(this, &data);
  1500. dialog.SetTitle(wxT("Choose the text background colour"));
  1501. if (dialog.ShowModal() == wxID_OK)
  1502. {
  1503. wxColourData retData = dialog.GetColourData();
  1504. wxColour col = retData.GetColour();
  1505. wxTextAttr attr;
  1506. attr.SetBackgroundColour(col);
  1507. long start, end;
  1508. m_textCtrl->GetSelection(& start, & end);
  1509. m_textCtrl->SetStyle(start, end, attr);
  1510. m_currentPosition = -1;
  1511. }
  1512. }
  1513. void RichTextFrame::OnLeftIndent(wxCommandEvent& WXUNUSED(event))
  1514. {
  1515. wxString indentStr = wxGetTextFromUser
  1516. (
  1517. _("Please enter the left indent in tenths of a millimetre."),
  1518. _("Left Indent"),
  1519. wxEmptyString,
  1520. this
  1521. );
  1522. if (!indentStr.IsEmpty())
  1523. {
  1524. int indent = wxAtoi(indentStr);
  1525. wxTextAttr attr;
  1526. attr.SetLeftIndent(indent);
  1527. long start, end;
  1528. m_textCtrl->GetSelection(& start, & end);
  1529. m_textCtrl->SetStyle(start, end, attr);
  1530. m_currentPosition = -1;
  1531. }
  1532. }
  1533. void RichTextFrame::OnRightIndent(wxCommandEvent& WXUNUSED(event))
  1534. {
  1535. wxString indentStr = wxGetTextFromUser
  1536. (
  1537. _("Please enter the right indent in tenths of a millimetre."),
  1538. _("Right Indent"),
  1539. wxEmptyString,
  1540. this
  1541. );
  1542. if (!indentStr.IsEmpty())
  1543. {
  1544. int indent = wxAtoi(indentStr);
  1545. wxTextAttr attr;
  1546. attr.SetRightIndent(indent);
  1547. long start, end;
  1548. m_textCtrl->GetSelection(& start, & end);
  1549. m_textCtrl->SetStyle(start, end, attr);
  1550. m_currentPosition = -1;
  1551. }
  1552. }
  1553. void RichTextFrame::OnTabStops(wxCommandEvent& WXUNUSED(event))
  1554. {
  1555. wxString tabsStr = wxGetTextFromUser
  1556. (
  1557. _("Please enter the tab stop positions in tenths of a millimetre, separated by spaces.\nLeave empty to reset tab stops."),
  1558. _("Tab Stops"),
  1559. wxEmptyString,
  1560. this
  1561. );
  1562. wxArrayInt tabs;
  1563. wxStringTokenizer tokens(tabsStr, wxT(" "));
  1564. while (tokens.HasMoreTokens())
  1565. {
  1566. wxString token = tokens.GetNextToken();
  1567. tabs.Add(wxAtoi(token));
  1568. }
  1569. wxTextAttr attr;
  1570. attr.SetTabs(tabs);
  1571. long start, end;
  1572. m_textCtrl->GetSelection(& start, & end);
  1573. m_textCtrl->SetStyle(start, end, attr);
  1574. m_currentPosition = -1;
  1575. }
  1576. void RichTextFrame::OnIdle(wxIdleEvent& WXUNUSED(event))
  1577. {
  1578. long insertionPoint = m_textCtrl->GetInsertionPoint();
  1579. if (insertionPoint != m_currentPosition)
  1580. {
  1581. #if wxUSE_STATUSBAR
  1582. wxTextAttr attr;
  1583. if (m_textCtrl->GetStyle(insertionPoint, attr))
  1584. {
  1585. wxString msg;
  1586. wxString facename(wxT("unknown"));
  1587. if (attr.GetFont().IsOk())
  1588. {
  1589. facename = attr.GetFont().GetFaceName();
  1590. }
  1591. wxString alignment(wxT("unknown alignment"));
  1592. if (attr.GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
  1593. alignment = wxT("centred");
  1594. else if (attr.GetAlignment() == wxTEXT_ALIGNMENT_RIGHT)
  1595. alignment = wxT("right-aligned");
  1596. else if (attr.GetAlignment() == wxTEXT_ALIGNMENT_LEFT)
  1597. alignment = wxT("left-aligned");
  1598. else if (attr.GetAlignment() == wxTEXT_ALIGNMENT_JUSTIFIED)
  1599. alignment = wxT("justified");
  1600. msg.Printf("Facename: %s", facename);
  1601. if (attr.HasTextColour())
  1602. {
  1603. msg += wxString::Format(", colour: %s",
  1604. attr.GetTextColour().GetAsString());
  1605. }
  1606. else
  1607. {
  1608. msg += ", no colour";
  1609. }
  1610. msg << ", " << alignment;
  1611. if (attr.HasFont())
  1612. {
  1613. if (attr.GetFont().GetWeight() == wxBOLD)
  1614. msg += wxT(" BOLD");
  1615. else if (attr.GetFont().GetWeight() == wxNORMAL)
  1616. msg += wxT(" NORMAL");
  1617. if (attr.GetFont().GetStyle() == wxITALIC)
  1618. msg += wxT(" ITALIC");
  1619. if (attr.GetFont().GetUnderlined())
  1620. msg += wxT(" UNDERLINED");
  1621. }
  1622. SetStatusText(msg);
  1623. }
  1624. #endif // wxUSE_STATUSBAR
  1625. m_currentPosition = insertionPoint;
  1626. }
  1627. }