xref: /haiku/src/add-ons/input_server/methods/t9/T9InputServerMethod.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
1 /*
2 	Copyright 2005, Francois Revol.   All Rights Reserved.
3 	This file may be used under the terms of the Be Sample Code License.
4 */
5 
6 #include <stdlib.h>
7 #include <string.h>
8 #include <ctype.h>
9 
10 #include <Debug.h>
11 #include <List.h>
12 #include <Message.h>
13 #include <OS.h>
14 
15 #include <Alert.h>
16 #include <Application.h>
17 #include <Autolock.h>
18 #include <Handler.h>
19 #include <Locker.h>
20 #include <Menu.h>
21 #include <MenuItem.h>
22 #include <String.h>
23 
24 
25 #include <add-ons/input_server/InputServerMethod.h>
26 
27 #ifndef _T
28 #define _T(s) s
29 #endif
30 
31 #include "T9Icon.h"
32 
33 extern "C" _EXPORT BInputServerMethod* instantiate_input_method();
34 
35 enum T9Mode {
36   WordMode,
37   CharMode,
38   NumMode
39 };
40 
41 
42 // modes: =Abc / Abc / 123
43 // flags:  Abc / ABC / abc
44 
45 class T9InputServerMethod : public BInputServerMethod, public BHandler
46 {
47 public:
48   T9InputServerMethod();
49   virtual ~T9InputServerMethod();
50   virtual filter_result Filter(BMessage *message, BList *outList);
51   virtual status_t MethodActivated(bool active);
52   virtual void MessageReceived(BMessage *message);
53 
54   bool IsEnabled() const { return fEnabled; };
55   T9Mode Mode() const { return fMode; };
56   void SetMode(T9Mode mode);
57 private:
58   bool fEnabled;
59   T9Mode fMode;
60   BMenu *fDeskbarMenu;
61   BLocker fLocker;
62   BString fTyped; /* what has been typed so far for the current word */
63 };
64 
65 
66 
67 
68 BInputServerMethod* instantiate_input_method()
69 {
70 	PRINT(("%s\n", __FUNCTION__));
71 	return (new T9InputServerMethod());
72 }
73 
74 
75 T9InputServerMethod::T9InputServerMethod()
76   : BInputServerMethod("T9", T9IconData),
77     BHandler("T9IMHandler"),
78     fEnabled(false),
79     fMode(WordMode),
80     fDeskbarMenu(NULL),
81     fLocker("T9IM")
82 {
83 	PRINT(("%s\n", __FUNCTION__));
84 
85 	if (be_app) {
86 	  be_app->Lock();
87 	  be_app->AddHandler(this);
88 	  be_app->Unlock();
89 	}
90 
91 	//
92 	fDeskbarMenu = new BMenu(_T("Mode"));
93 
94 
95 	BMessage *msg = new BMessage('SetM');
96 	msg->AddInt32("t9mode", WordMode);
97 	BMenuItem *item;
98 	item = new BMenuItem(_T("Word mode"), msg);
99 	item->SetMarked(true);
100 	fDeskbarMenu->AddItem(item);
101 	msg = new BMessage('SetM');
102 	msg->AddInt32("t9mode", CharMode);
103 	item = new BMenuItem(_T("Character mode"), msg);
104 	fDeskbarMenu->AddItem(item);
105 	msg = new BMessage('SetM');
106 	msg->AddInt32("t9mode", NumMode);
107 	item = new BMenuItem(_T("Numeric mode"), msg);
108 	fDeskbarMenu->AddItem(item);
109 	fDeskbarMenu->SetFont(be_plain_font);
110 	// doesn't seem to work here
111 	//fDeskbarMenu->SetRadioMode(true);
112 	//fDeskbarMenu->SetLabelFromMarked(true);
113 
114 	SetMenu(fDeskbarMenu, BMessenger(this));
115 }
116 
117 T9InputServerMethod::~T9InputServerMethod()
118 {
119 	PRINT(("%s\n", __FUNCTION__));
120 	SetMenu(NULL, BMessenger());
121 	delete fDeskbarMenu;
122 	if (be_app) {
123 	  be_app->Lock();
124 	  be_app->RemoveHandler(this);
125 	  be_app->Unlock();
126 	}
127 }
128 
129 filter_result T9InputServerMethod::Filter(BMessage *message, BList *outList)
130 {
131 	//status_t err;
132 	filter_result res = B_DISPATCH_MESSAGE;
133 	bool keyUp = false;
134 	BString bytes;
135 
136 	if (!IsEnabled())
137 		return B_DISPATCH_MESSAGE;
138 
139 	switch (message->what) {
140 	case B_KEY_UP:
141 	  keyUp = true;
142 	case B_KEY_DOWN:
143 	  if (message->FindString("bytes", &bytes) < B_OK)
144 	    break;
145 	  if (bytes.Length() == 1) {
146 	    BAutolock l(fLocker);
147 
148 	    if (fMode == NumMode)
149 	      break;
150 	  }
151 	  break;
152 	default:
153 	  break;
154 	}
155 
156 	return (res);
157 }
158 
159 status_t T9InputServerMethod::MethodActivated(bool active)
160 {
161   fEnabled = active;
162   return BInputServerMethod::MethodActivated(active);
163 }
164 
165 void T9InputServerMethod::MessageReceived(BMessage *message)
166 {
167   int32 v;
168   switch (message->what) {
169   case 'SetM':
170     if (message->FindInt32("t9mode", &v) < B_OK)
171       break;
172     SetMode((T9Mode)v);
173 
174     /*{
175       BString s;
176       s << v;
177       s << " - ";
178       s << (long) fDeskbarMenu->FindMarked();
179       s << " - ";
180       s << (long) fDeskbarMenu->ItemAt(v);
181       BAlert *a = new BAlert("Plop", s.String(), "OK");
182       a->SetFlags(a->Flags() | B_CLOSE_ON_ESCAPE);
183       a->Go(NULL);
184       }*/
185     break;
186   default:
187     BHandler::MessageReceived(message);
188     break;
189   }
190 }
191 
192 void T9InputServerMethod::SetMode(T9Mode mode)
193 {
194   BAutolock l(fLocker);
195   BMenuItem *item;
196   // XXX: check
197   fMode = mode;
198   item = fDeskbarMenu->FindMarked();
199   if (item)
200     item->SetMarked(false);
201   item = fDeskbarMenu->ItemAt((int32)mode);
202   if (item)
203     item->SetMarked(true);
204   // necessary to update the copy used by the Deskbar icon.
205   SetMenu(fDeskbarMenu, BMessenger(this));
206 }
207