]> Pileus Git - ~andy/spades/blob - src/org/pileus/spades/Main.java
Initial text formatting
[~andy/spades] / src / org / pileus / spades / Main.java
1 package org.pileus.spades;
2
3 import android.app.Activity;
4 import android.content.Intent;
5 import android.os.Bundle;
6 import android.os.Handler;
7 import android.os.Messenger;
8 import android.text.Html;
9 import android.text.method.ScrollingMovementMethod;
10 import android.text.format.DateFormat;
11 import android.view.Menu;
12 import android.view.MenuInflater;
13 import android.view.MenuItem;
14 import android.view.View;
15 import android.widget.Button;
16 import android.widget.EditText;
17 import android.widget.LinearLayout;
18 import android.widget.ScrollView;
19 import android.widget.TabHost;
20 import android.widget.TabWidget;
21 import android.widget.TextView;
22 import android.widget.Toast;
23
24 public class Main extends Activity
25 {
26         /* Private data */
27         private Handler      handler;
28         private Messenger    messenger;
29         private Task         task;
30         private Toast        toast;
31         private boolean      ready;
32         private String       topic;
33         private String       names;
34
35         /* Widgets */
36         private TabHost      window;
37         private TabWidget    tabs;
38         private LinearLayout chat;
39         private TextView     log;
40         private EditText     input;
41         private Button       send;
42         private TextView     spades;
43         private TextView     debug;
44
45         private ScrollView   lscroll;
46         private ScrollView   dscroll;
47
48         /* Private helper methods */
49         private void notice(String text)
50         {
51                 this.log.append(Html.fromHtml("<b>*** " + text + "</b><br />"));
52         }
53
54         private void display(Message msg)
55         {
56                 String when = DateFormat.format("hh:mm:ss", msg.time).toString();
57                 String from = String.format("<font color=\"#ff88ff\">%s</font>", msg.from);
58                 String text = msg.msg;
59                 String fmt  = null;
60                 Os.debug("msg: " + Os.base64(msg.msg));
61
62                 // Do IRC Colors
63                 //   - This doesn't actually work
64                 String fg   = "<font color=\"<$1>\">";
65                 String bg   = "<font bgcolor=\"<$2>\">";
66                 text = text
67                         .replaceAll("&", "&amp;")
68                         .replaceAll("<", "&lt;")
69                         .replaceAll(">", "&gt;");
70                 text = text
71                         .replaceAll("\\002", "<b>")  // bold
72                         .replaceAll("\\011", "<i>")  // italic
73                         .replaceAll("\\025", "<u>")  // underline
74                         .replaceAll("\\022", "<b>"); // reverse
75                 text = text
76                         .replaceAll("\\003(\\d+),(\\d+)", fg + bg) // color
77                         .replaceAll("\\013(\\d+),(\\d+)", fg + bg) // color
78                         .replaceAll("\\003(\\d+)", fg)             // color
79                         .replaceAll("\\013(\\d+)", fg);            // color
80                 text = text
81                         .replaceAll("<0?0>", "#000000")  // White
82                         .replaceAll("<0?1>", "#000000")  // Black
83                         .replaceAll("<0?2>", "#000080")  // Navy Blue
84                         .replaceAll("<0?3>", "#008000")  // Green
85                         .replaceAll("<0?4>", "#FF0000")  // Red
86                         .replaceAll("<0?5>", "#804040")  // Brown
87                         .replaceAll("<0?6>", "#8000FF")  // Purple
88                         .replaceAll("<0?7>", "#808000")  // Olive
89                         .replaceAll("<0?8>", "#FFFF00")  // Yellow
90                         .replaceAll("<0?9>", "#00FF00")  // Lime Green
91                         .replaceAll("<10>",  "#008080")  // Teal
92                         .replaceAll("<11>",  "#00FFFF")  // Aqua Light
93                         .replaceAll("<12>",  "#0000FF")  // Royal Blue
94                         .replaceAll("<13>",  "#FF00FF")  // Hot Pink
95                         .replaceAll("<14>",  "#808080")  // Dark Gray
96                         .replaceAll("<15>",  "#C0C0C0"); // Light Gray
97
98                 // Message formatting
99                 switch (msg.how) {
100                         case DIRECT:
101                         case MENTION:
102                         case PRIVMSG:
103                                 fmt  = "<b>(%s) %s: %s</b>";
104                                 break;
105                         default:
106                                 fmt  = "(%s) %s: %s";
107                                 break;
108                 }
109
110                 String html = String.format(fmt, when, from, text);
111                 this.log.append(Html.fromHtml(html + "<br />"));
112         }
113
114         /* Private handler methods */
115         private void onRegister(Object obj)
116         {
117                 Os.debug("Main: onRegister");
118                 this.task = (Task)obj;
119         }
120
121         private void onMessage(Object obj)
122         {
123                 Message msg = (Message)obj;
124
125                 // Debug
126                 this.debug.append("> " + msg.line + "\n");
127                 this.dscroll.smoothScrollTo(0, this.debug.getBottom());
128
129                 // Chat
130                 switch (msg.type) {
131                         case PRIVMSG:
132                                 this.display(msg);
133                                 break;
134                         case TOPIC:
135                                 if (!msg.txt.equals(this.topic))
136                                         this.notice("Topic for " + msg.arg + ": " + msg.txt);
137                                 this.topic = msg.txt;
138                                 break;
139                         case NAMES:
140                                 if (!msg.txt.equals(this.names))
141                                         this.notice("Users in " + msg.arg + ": " + msg.txt);
142                                 this.names = msg.txt;
143                                 break;
144                         case ERROR:
145                                 this.notice("Error: " + msg.txt);
146                                 break;
147                         case AUTHOK:
148                                 this.notice("Authentication succeeded: " + msg.txt);
149                                 break;
150                         case AUTHFAIL:
151                                 this.notice("Authentication failed: " + msg.txt);
152                                 break;
153                 }
154                 this.lscroll.smoothScrollTo(0, this.log.getBottom());
155         }
156
157         private void onNotify(String text)
158         {
159                 Os.debug("Main: onNotify - " + text);
160                 this.notice(text);
161                 this.toast.setText(text);
162                 this.toast.show();
163         }
164
165         /* Private service methods */
166         private void startService()
167         {
168                 Os.debug("Main: startService");
169                 startService(new Intent(this, Task.class)
170                                 .putExtra("Messenger", this.messenger));
171         }
172
173         private void stopService()
174         {
175                 Os.debug("Main: stopService");
176                 stopService(new Intent(this, Task.class));
177         }
178
179         /* Widget callback functions */
180         public void onSend(View btn)
181         {
182                 if (this.task == null)
183                         return;
184                 String  txt = this.input.getText().toString();
185                 Message msg = this.task.send(txt);
186                 if (msg == null)
187                         return;
188                 this.input.setText("");
189         }
190
191         /* Activity Methods */
192         @Override
193         public void onCreate(Bundle savedInstanceState)
194         {
195                 try {
196                         super.onCreate(savedInstanceState);
197                         Os.debug("Main: onCreate");
198
199                         // Setup main layout
200                         this.setContentView(R.layout.main);
201
202                         // Setup toast
203                         this.toast     = Toast.makeText(this, "", Toast.LENGTH_SHORT);
204
205                         // Setup communication
206                         this.handler   = new MainHandler();
207                         this.messenger = new Messenger(this.handler);
208
209                         // Find widgets
210                         this.window    = (TabHost)      findViewById(android.R.id.tabhost);
211                         this.tabs      = (TabWidget)    findViewById(android.R.id.tabs);
212                         this.chat      = (LinearLayout) findViewById(R.id.chat);
213                         this.log       = (TextView)     findViewById(R.id.log);
214                         this.input     = (EditText)     findViewById(R.id.input);
215                         this.send      = (Button)       findViewById(R.id.send);
216                         this.spades    = (TextView)     findViewById(R.id.spades);
217                         this.debug     = (TextView)     findViewById(R.id.debug);
218
219                         this.lscroll   = (ScrollView)   findViewById(R.id.log_scroll);
220                         this.dscroll   = (ScrollView)   findViewById(R.id.debug_scroll);
221
222                         // Add window tabs
223                         this.window.setup();
224
225                         this.window.addTab(this.window
226                                         .newTabSpec("chat")
227                                         .setIndicator("Chat")
228                                         .setContent(R.id.chat));
229                         this.window.addTab(this.window
230                                         .newTabSpec("spades")
231                                         .setIndicator("Spades")
232                                         .setContent(R.id.spades));
233                         this.window.addTab(this.window
234                                         .newTabSpec("debug")
235                                         .setIndicator("Debug")
236                                         .setContent(R.id.debug));
237                 } catch (Exception e) {
238                         Os.debug("Error setting content view", e);
239                         return;
240                 }
241         }
242
243         @Override
244         public void onStart()
245         {
246                 super.onStart();
247                 Os.debug("Main: onStart");
248         }
249
250         @Override
251         public void onResume()
252         {
253                 super.onResume();
254                 Os.debug("Main: onResume");
255         }
256
257         @Override
258         public void onPause()
259         {
260                 super.onPause();
261                 Os.debug("Main: onPause");
262         }
263
264         @Override
265         public void onStop()
266         {
267                 super.onStop();
268                 Os.debug("Main: onStop");
269         }
270
271         @Override
272         public void onRestart()
273         {
274                 super.onRestart();
275                 Os.debug("Main: onRestart");
276         }
277
278         @Override
279         public void onDestroy()
280         {
281                 super.onDestroy();
282                 Os.debug("Main: onDestroy");
283         }
284
285         @Override
286         public boolean onCreateOptionsMenu(Menu menu)
287         {
288                 MenuInflater inflater = getMenuInflater();
289                 inflater.inflate(R.menu.main, menu);
290                 return true;
291         }
292
293         @Override
294         public boolean onPrepareOptionsMenu(Menu menu)
295         {
296                 menu.findItem(R.id.connect).setVisible(!this.ready);
297                 menu.findItem(R.id.disconnect).setVisible(this.ready);
298                 return true;
299         }
300
301         @Override
302         public boolean onOptionsItemSelected(MenuItem item)
303         {
304                 switch (item.getItemId()) {
305                         case R.id.connect:
306                                 this.startService();
307                                 return true;
308                         case R.id.disconnect:
309                                 this.stopService();
310                                 return true;
311                         case R.id.settings:
312                                 this.startActivity(new Intent(this, Prefs.class));
313                                 return true;
314                         case R.id.exit:
315                                 this.stopService();
316                                 this.finish();
317                                 return true;
318                         default:
319                                 return false;
320                 }
321         }
322
323         /* Handler class */
324         class MainHandler extends Handler
325         {
326                 public void handleMessage(android.os.Message msg)
327                 {
328                         switch (msg.what) {
329                                 case Task.REGISTER:
330                                         Main.this.onRegister(msg.obj);
331                                         break;
332                                 case Task.MESSAGE:
333                                         Main.this.onMessage(msg.obj);
334                                         break;
335                                 case Task.CONNECT:
336                                         Main.this.ready = true;
337                                         break;
338                                 case Task.DISCONNECT:
339                                         Main.this.ready = false;
340                                         break;
341                                 case Task.NOTIFY:
342                                         Main.this.onNotify((String)msg.obj);
343                                         break;
344                                 default:
345                                         Os.debug("Main: unknown message - " + msg.what);
346                                         break;
347                         }
348                 }
349         }
350 }