Go to most recent revision | Details | Last modification | View Log | SVN | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 15 | arune | 1 | /* |
| 2 | * File created by arune |
||
| 3 | * at 2005-jan-09 16:54:44 |
||
| 4 | */ |
||
| 5 | package Macbeth.Modules.modMenuSystem; |
||
| 6 | |||
| 7 | import Macbeth.System.*; |
||
| 8 | import Macbeth.Utilities.*; |
||
| 9 | import Macbeth.XML.XMLDataHandler; |
||
| 10 | import Macbeth.XML.XMLParser; |
||
| 11 | import Macbeth.Utilities.*; |
||
| 12 | import Macbeth.Modules.modGenRoomControl.GenRoomObject; |
||
| 13 | import Macbeth.Net.*; |
||
| 14 | |||
| 15 | import java.util.*; |
||
| 16 | |||
| 17 | import javax.swing.*; |
||
| 18 | import javax.swing.Timer; |
||
| 19 | |||
| 20 | import org.xml.sax.SAXException; |
||
| 21 | |||
| 22 | import java.awt.event.*; |
||
| 23 | import java.io.IOException; |
||
| 24 | |||
| 25 | /** |
||
| 26 | * This is the core of the menusystem, this module should register |
||
| 27 | * the Pad-, Ok- and Cancel/back/menu-buttons from remotecontrol. |
||
| 28 | * Other submenumodules can register to this module. |
||
| 29 | * Submenumodules get (if they need) a row in the root menu. |
||
| 30 | * The user navigates the rootmenu with the pad-buttons, when selecting one |
||
| 31 | * row with pad-right or ok then this choosen submenu should send its root-menu |
||
| 32 | * to menusystem and it sends it to be displayed, menusystem should also |
||
| 33 | * send the pad-buttons to this submenu. |
||
| 34 | * |
||
| 35 | * for now... |
||
| 36 | * |
||
| 37 | * @author arune |
||
| 38 | */ |
||
| 39 | public class modMenuSystem extends MbModule implements ServerDataHandler{ |
||
| 40 | |||
| 41 | private XMLDataHandler flinshDataHandler; |
||
| 42 | //private XMLParser packetXMLParser; |
||
| 43 | |||
| 44 | private TcpServer flinshServer; |
||
| 45 | //private Timer requestDataTimer = null; |
||
| 46 | //private int timerInterval = 0; |
||
| 47 | private final char EOF = (char) 0x00; |
||
| 48 | //A table containing all registered modules (submenus and vlc) |
||
| 49 | private ArrayList subMenus = new ArrayList(); |
||
| 50 | //what module that should receive all remotebutton changes |
||
| 51 | private String curButtonReceiver; |
||
| 52 | //what module that is visible on all flashclients |
||
| 53 | //often same as curButtonReceiver, but not when curButtonReceiver is vlc-module |
||
| 54 | private String curSubMenu; |
||
| 55 | |||
| 56 | private String currentAddress = ""; |
||
| 57 | private int currentLevel = 0; |
||
| 58 | |||
| 59 | private ArrayList userLogin = new ArrayList(); |
||
| 60 | private ArrayList clientsConnected = new ArrayList(); |
||
| 61 | |||
| 62 | //holds track of what item is marked in the root_menu (menu system) |
||
| 63 | private String rootMenuMiddleId; |
||
| 64 | |||
| 65 | private boolean guestCanView; |
||
| 66 | |||
| 67 | String padUp; |
||
| 68 | String padDown; |
||
| 69 | String padLeft; |
||
| 70 | String padRight; |
||
| 71 | String padOk; |
||
| 72 | |||
| 73 | |||
| 74 | /** |
||
| 75 | * Creates a new instance of . |
||
| 76 | */ |
||
| 77 | public modMenuSystem() { |
||
| 78 | //construct MbModule |
||
| 79 | super(); |
||
| 80 | //initial values |
||
| 81 | |||
| 82 | addDependency("RemoteControl"); |
||
| 83 | |||
| 84 | //from start the root-menu should be visible |
||
| 85 | curButtonReceiver = name(); |
||
| 86 | curSubMenu = name(); |
||
| 87 | rootMenuMiddleId = "0"; |
||
| 88 | |||
| 89 | //subMenuLastMenu = ""; |
||
| 90 | //register our packet data handler |
||
| 91 | setPacketDataHandler(new PacketDataHandler()); |
||
| 92 | //packetXMLParser = new XMLParser(new PacketDataHandler()); |
||
| 93 | flinshDataHandler = new FlinshDataHandler(); |
||
| 94 | } |
||
| 95 | |||
| 96 | public String name() { |
||
| 97 | return "MenuSystem"; |
||
| 98 | } |
||
| 99 | |||
| 100 | public String description() { |
||
| 101 | return "bla"; |
||
| 102 | } |
||
| 103 | |||
| 104 | /** |
||
| 105 | * This method sets default values on all _required_ data |
||
| 106 | * fields in the data repository. |
||
| 107 | */ |
||
| 108 | public void initDataFields() { |
||
| 109 | //set default values on all REQUIRED option fields before starting up subsystems |
||
| 110 | //options.putField("mode", "simple"); |
||
| 111 | //options.putField("checkinterval", "5"); |
||
| 112 | //options.putField("displaytext", "New mail"); |
||
| 113 | // options.putField("port", "2050"); |
||
| 114 | } |
||
| 115 | |||
| 116 | public void handleServerData(String data, String address) { |
||
| 117 | |||
| 118 | //nulltecken finns, tar bort |
||
| 119 | data = data.replaceAll("" + EOF, ""); |
||
| 120 | |||
| 121 | if (data.length() > 0) { |
||
| 122 | if (data.equals("<ping />")) { |
||
| 123 | //gör inget om det är ping |
||
| 124 | } else { |
||
| 125 | //_debug.println("got data: " + data); |
||
| 126 | |||
| 127 | //kan vara en säkerhetsrisk att skicka med det såhär, klienten kan ju |
||
| 128 | //konstruera en sån här sträng och skicka till oss |
||
| 129 | //data = "<clientaddress value=\"" + address + "\">" + data; |
||
| 130 | //fet säkerhetsrisk ja |
||
| 131 | //private String currentAddress = ""; |
||
| 132 | currentLevel = 0; |
||
| 133 | //check user level |
||
| 134 | currentAddress = address; |
||
| 135 | for (int i=0; i<clientsConnected.size(); i++) { |
||
| 136 | String adr = ((ClientObj)clientsConnected.get(i)).address; |
||
| 137 | if (adr.equals(address)) { |
||
| 138 | currentLevel = ((ClientObj)clientsConnected.get(i)).level; |
||
| 139 | break; |
||
| 140 | } |
||
| 141 | } |
||
| 142 | |||
| 143 | |||
| 144 | //<flinshpacket id="MainMenu" middleitem="1" /> |
||
| 145 | if (flinshDataHandler!=null) { |
||
| 146 | //create XML parser and try to parse configuration file |
||
| 147 | XMLParser xmlParser = new XMLParser(flinshDataHandler); |
||
| 148 | try { |
||
| 149 | xmlParser.parseString(data); |
||
| 150 | } catch (SAXException e) { |
||
| 151 | _errors.println("The data send from flinsh contains errors:"); |
||
| 152 | _errors.println(e); |
||
| 153 | e.printStackTrace(); |
||
| 154 | } catch (IOException e) { |
||
| 155 | //I/O-exception. that's worse, so lets warn |
||
| 156 | _errors.println("I/O-error while trying to read data from flinsh:"); |
||
| 157 | _errors.println(e); |
||
| 158 | e.printStackTrace(); |
||
| 159 | } |
||
| 160 | } |
||
| 161 | //allt parsas nu av xml-parsern |
||
| 162 | } |
||
| 163 | } |
||
| 164 | |||
| 165 | |||
| 166 | } |
||
| 167 | |||
| 168 | /** |
||
| 169 | * When a client dropps out, delete it from the client list |
||
| 170 | * |
||
| 171 | */ |
||
| 172 | public void clientDropped(String address) { |
||
| 173 | for (int i=0; i<clientsConnected.size(); i++) { |
||
| 174 | String adr = ((ClientObj)clientsConnected.get(i)).address; |
||
| 175 | if (adr.equals(address)) { |
||
| 176 | clientsConnected.remove(i); |
||
| 177 | _debug.println("client dropped: " + address); |
||
| 178 | break; |
||
| 179 | |||
| 180 | } |
||
| 181 | } |
||
| 182 | } |
||
| 183 | |||
| 184 | /** |
||
| 185 | * When flins client connects it should get the latest menu. If its the root menu |
||
| 186 | * sendRootMenu get called. If its a submenu a refresh is sent to that submenu |
||
| 187 | * and the submenu should send out the latest menu to menusystem. |
||
| 188 | */ |
||
| 189 | public void setRemoteAddress(String address) { |
||
| 190 | //_debug.println("got connection: " + address); |
||
| 191 | |||
| 192 | /* |
||
| 193 | * check if the newly connected client has a level specified in config |
||
| 194 | */ |
||
| 195 | int level = 0; |
||
| 196 | _debug.println("client connected: " + address); |
||
| 197 | //rota igenom listan över de möjliga logins som finns |
||
| 198 | for (int i=0; i<userLogin.size(); i++) { |
||
| 199 | if (((UserLoginObj)userLogin.get(i)).user.equals("ip")) { |
||
| 200 | String userLoginIp = ((UserLoginObj)userLogin.get(i)).password; |
||
| 201 | String[] ipPort = address.split(":"); |
||
| 202 | |||
| 203 | if (ipPort[0].equals("/" + userLoginIp)) { |
||
| 204 | if (((UserLoginObj)userLogin.get(i)).level > level) { |
||
| 205 | level = ((UserLoginObj)userLogin.get(i)).level; |
||
| 206 | _debug.println("client got level by ip: " + level); |
||
| 207 | } |
||
| 208 | } |
||
| 209 | } |
||
| 210 | } |
||
| 211 | //lägg till klienten i listan över klienter: |
||
| 212 | clientsConnected.add(new ClientObj(address, level)); |
||
| 213 | |||
| 214 | if (curSubMenu.equals(name())) { |
||
| 215 | sendRootMenu(address); |
||
| 216 | } else { |
||
| 217 | sendMacbeth(curSubMenu, "<refresh />"); |
||
| 218 | } |
||
| 219 | } |
||
| 220 | |||
| 221 | |||
| 222 | /** |
||
| 223 | * |
||
| 224 | * @param address Specifies flinsh-client to send data to, send to all clients if null |
||
| 225 | */ |
||
| 226 | private void sendRootMenu(String address) { |
||
| 227 | //nu ska vi visa rootmenyn (lista alla submodulers displayname) |
||
| 228 | String dataToSend = "<?xml version=\"1.0\"?><packet menuid=\"MainMenu\"><data>"; |
||
| 229 | |||
| 230 | dataToSend = dataToSend + "<middleid>" + rootMenuMiddleId + "</middleid><list id=\"menudata\">"; |
||
| 231 | for (int i = 0; i < subMenus.size(); i++) { |
||
| 232 | //generera e |
||
| 233 | dataToSend = dataToSend + "<item id=\"" + i + "\" title=\"" + ((SubMenu)subMenus.get(i)).getDisplayName() + "\" desc=\"" + ((SubMenu)subMenus.get(i)).getDisplayDesc() + "\" />"; |
||
| 234 | /* |
||
| 235 | dataToSend = dataToSend + "<item>"; |
||
| 236 | dataToSend = dataToSend + "<id>" + i + "</id>"; |
||
| 237 | dataToSend = dataToSend + "<title>" + ((SubMenu)subMenus.get(i)).getDisplayName() + "</title>"; |
||
| 238 | dataToSend = dataToSend + "<description>" + ((SubMenu)subMenus.get(i)).getDisplayDesc() + "</description>"; |
||
| 239 | dataToSend = dataToSend + "</item>"; |
||
| 240 | */ |
||
| 241 | } |
||
| 242 | dataToSend = dataToSend + "</list></data></packet>" + EOF; |
||
| 243 | |||
| 244 | if (address != null) { |
||
| 245 | //skicka till en klient |
||
| 246 | if (guestCanView) { |
||
| 247 | flinshServer.sendToClient(dataToSend, address); |
||
| 248 | } else { |
||
| 249 | //skicka till alla inloggade med adressen address (level > 0) |
||
| 250 | for (int i=0; i<clientsConnected.size(); i++) { |
||
| 251 | String adr = ((ClientObj)clientsConnected.get(i)).address; |
||
| 252 | int level = ((ClientObj)clientsConnected.get(i)).level; |
||
| 253 | if (adr.equals(address) && level > 0) { |
||
| 254 | flinshServer.sendToClient(dataToSend, adr); |
||
| 255 | } |
||
| 256 | } |
||
| 257 | } |
||
| 258 | |||
| 259 | } else { |
||
| 260 | //skicka till alla |
||
| 261 | if (guestCanView) { |
||
| 262 | flinshServer.sendToAll(dataToSend); |
||
| 263 | } else { |
||
| 264 | //skicka till alla inloggade (level > 0) |
||
| 265 | for (int i=0; i<clientsConnected.size(); i++) { |
||
| 266 | String adr = ((ClientObj)clientsConnected.get(i)).address; |
||
| 267 | int level = ((ClientObj)clientsConnected.get(i)).level; |
||
| 268 | if (level > 0) { |
||
| 269 | flinshServer.sendToClient(dataToSend, adr); |
||
| 270 | } |
||
| 271 | } |
||
| 272 | } |
||
| 273 | } |
||
| 274 | } |
||
| 275 | |||
| 276 | private void sendData(String address, String data) { |
||
| 277 | String dataToSend = "<?xml version=\"1.0\"?>"; |
||
| 278 | dataToSend = dataToSend + data; |
||
| 279 | dataToSend = dataToSend + EOF; |
||
| 280 | if (address != null) { |
||
| 281 | //skicka till en klient |
||
| 282 | flinshServer.sendToClient(dataToSend, address); |
||
| 283 | } else { |
||
| 284 | //skicka till alla |
||
| 285 | if (guestCanView) { |
||
| 286 | flinshServer.sendToAll(dataToSend); |
||
| 287 | } else { |
||
| 288 | //skicka till alla inloggade (level > 0) |
||
| 289 | for (int i=0; i<clientsConnected.size(); i++) { |
||
| 290 | String adr = ((ClientObj)clientsConnected.get(i)).address; |
||
| 291 | int level = ((ClientObj)clientsConnected.get(i)).level; |
||
| 292 | if (level > 0) { |
||
| 293 | flinshServer.sendToClient(dataToSend, adr); |
||
| 294 | } |
||
| 295 | } |
||
| 296 | } |
||
| 297 | } |
||
| 298 | } |
||
| 299 | |||
| 300 | private void sendCommand(String address, String command) { |
||
| 301 | String dataToSend = "<?xml version=\"1.0\"?><packet menuid=\"MainMenu\"><command>"; |
||
| 302 | dataToSend = dataToSend + command; |
||
| 303 | dataToSend = dataToSend + "</command></packet>" + EOF; |
||
| 304 | //_debug.println("skickar " + dataToSend); |
||
| 305 | if (address != null) { |
||
| 306 | //skicka till en klient |
||
| 307 | flinshServer.sendToClient(dataToSend, address); |
||
| 308 | } else { |
||
| 309 | //skicka till alla |
||
| 310 | if (guestCanView) { |
||
| 311 | flinshServer.sendToAll(dataToSend); |
||
| 312 | } else { |
||
| 313 | //skicka till alla inloggade (level > 0) |
||
| 314 | for (int i=0; i<clientsConnected.size(); i++) { |
||
| 315 | String adr = ((ClientObj)clientsConnected.get(i)).address; |
||
| 316 | int level = ((ClientObj)clientsConnected.get(i)).level; |
||
| 317 | if (level > 0) { |
||
| 318 | flinshServer.sendToClient(dataToSend, adr); |
||
| 319 | } |
||
| 320 | } |
||
| 321 | } |
||
| 322 | } |
||
| 323 | } |
||
| 324 | |||
| 325 | public void startup() throws MbStartupException { |
||
| 326 | //startup MbModule |
||
| 327 | super.startup(); |
||
| 328 | |||
| 329 | //get all login users/ip objects from the data repository |
||
| 330 | DataRepository.DataList list = dataRepository.getList("login"); |
||
| 331 | if (list!=null) { |
||
| 332 | Iterator it = list.items(); |
||
| 333 | while (it.hasNext()) { |
||
| 334 | DataRepository.DataListItem item = (DataRepository.DataListItem)it.next(); |
||
| 335 | String name = (String)item.getField("user"); |
||
| 336 | String passIp = (String)item.getField("pass"); |
||
| 337 | int level = 0; |
||
| 338 | try { |
||
| 339 | level = Integer.parseInt((String)item.getField("level")); |
||
| 340 | } catch (NumberFormatException ex) { |
||
| 341 | _errors.println("Config error: level not a number: " + (String)item.getField("level")); |
||
| 342 | } |
||
| 343 | |||
| 344 | userLogin.add(new UserLoginObj(name, passIp, level)); |
||
| 345 | } |
||
| 346 | } |
||
| 347 | |||
| 348 | guestCanView = ((String)options.getField("guestcanview")).equals("true"); |
||
| 349 | |||
| 350 | int flinshServerPort = Integer.parseInt(options.getField("port")); |
||
| 351 | //konfigurerbar port via vanlig config |
||
| 352 | if (flinshServerPort >= 1024) { |
||
| 353 | flinshServer = new TcpServer(flinshServerPort, this); |
||
| 354 | flinshServer.startServer(); |
||
| 355 | flinshServer.setTcpNoDelay(true); |
||
| 356 | } else { |
||
| 357 | _errors.println("Config error: Port number must be greater than or equal to 1024"); |
||
| 358 | } |
||
| 359 | |||
| 360 | padUp = options.getField("padup"); |
||
| 361 | padDown = options.getField("paddown"); |
||
| 362 | padLeft = options.getField("padleft"); |
||
| 363 | padRight = options.getField("padright"); |
||
| 364 | padOk = options.getField("padok"); |
||
| 365 | //lets send requests for their remote control buttons |
||
| 366 | MbPacket p = new MbPacket(); |
||
| 367 | p.setDestination(new MbLocation("self", "RemoteControl")); |
||
| 368 | p.appendContents(" <buttonrequest button=\"" + padUp + "\" module=\"" + name() + "\" />"); |
||
| 369 | p.appendContents(" <buttonrequest button=\"" + padDown + "\" module=\"" + name() + "\" />"); |
||
| 370 | p.appendContents(" <buttonrequest button=\"" + padLeft + "\" module=\"" + name() + "\" />"); |
||
| 371 | p.appendContents(" <buttonrequest button=\"" + padRight + "\" module=\"" + name() + "\" />"); |
||
| 372 | p.appendContents(" <buttonrequest button=\"" + padOk + "\" module=\"" + name() + "\" />"); |
||
| 373 | |||
| 374 | sendPacket(p); |
||
| 375 | |||
| 376 | } |
||
| 377 | |||
| 378 | /** |
||
| 379 | * Shuts down this module. |
||
| 380 | */ |
||
| 381 | public void shutdown() { |
||
| 382 | //stop timer if it's running |
||
| 383 | /*if (requestDataTimer!=null) { |
||
| 384 | if (requestDataTimer.isRunning()) { |
||
| 385 | requestDataTimer.stop(); |
||
| 386 | } |
||
| 387 | }*/ |
||
| 388 | //shut down MbModule |
||
| 389 | flinshServer.stopServer(); |
||
| 390 | super.shutdown(); |
||
| 391 | } |
||
| 392 | |||
| 393 | private void sendMacbeth(String receiver, String data) { |
||
| 394 | MbPacket p = new MbPacket(); |
||
| 395 | p.setDestination(new MbLocation("self", receiver)); |
||
| 396 | p.appendContents(data); |
||
| 397 | sendPacket(p); |
||
| 398 | |||
| 399 | } |
||
| 400 | |||
| 401 | private void parseKeys(String button, String state, int level) { |
||
| 402 | //_debug.println("knapp " + button + " i state " + state); |
||
| 403 | if (state.equals("DOWN")) { |
||
| 404 | if (padUp.equals(button)) { |
||
| 405 | //if current button-receiver is the menu system module |
||
| 406 | if (curButtonReceiver.equals(name())) { |
||
| 407 | if (level >= 1) { |
||
| 408 | sendCommand(null, "<scroll>1</scroll>"); |
||
| 409 | } |
||
| 410 | } else { |
||
| 411 | sendMacbeth(curButtonReceiver, "<padUp state=\"DOWN\" level=\"" + level + "\" />"); |
||
| 412 | } |
||
| 413 | } |
||
| 414 | else if (padDown.equals(button)) { |
||
| 415 | //if current button-receiver is the menu system module |
||
| 416 | if (curButtonReceiver.equals(name())) { |
||
| 417 | if (level >= 1) { |
||
| 418 | sendCommand(null, "<scroll>-1</scroll>"); |
||
| 419 | } |
||
| 420 | } else { |
||
| 421 | sendMacbeth(curButtonReceiver, "<padDown state=\"DOWN\" level=\"" + level + "\" />"); |
||
| 422 | } |
||
| 423 | } |
||
| 424 | else if (padRight.equals(button)) { |
||
| 425 | //if current button-receiver is the menu system module |
||
| 426 | if (curButtonReceiver.equals(name())) { |
||
| 427 | if (level >= 2) { |
||
| 428 | curButtonReceiver = ((SubMenu)subMenus.get(Integer.parseInt(rootMenuMiddleId))).getModuleName(); |
||
| 429 | curSubMenu = curButtonReceiver; |
||
| 430 | sendMacbeth(curSubMenu, "<activate />"); |
||
| 431 | } |
||
| 432 | } else { |
||
| 433 | sendMacbeth(curButtonReceiver, "<padRight state=\"DOWN\" level=\"" + level + "\" />"); |
||
| 434 | } |
||
| 435 | } else if (padLeft.equals(button)) { |
||
| 436 | //if current button-receiver is the menu system module |
||
| 437 | if (curButtonReceiver.equals(name())) { |
||
| 438 | //do nothing |
||
| 439 | } else { |
||
| 440 | sendMacbeth(curButtonReceiver, "<padLeft state=\"DOWN\" level=\"" + level + "\" />"); |
||
| 441 | } |
||
| 442 | } |
||
| 443 | |||
| 444 | else if (padOk.equals(button)) { |
||
| 445 | //if current button-receiver is the menu system module |
||
| 446 | if (curButtonReceiver.equals(name())) { |
||
| 447 | |||
| 448 | } else { |
||
| 449 | sendMacbeth(curButtonReceiver, "<padOk state=\"DOWN\" level=\"" + level + "\" />"); |
||
| 450 | } |
||
| 451 | } |
||
| 452 | } |
||
| 453 | else if (state.equals("UP")) { |
||
| 454 | if (padUp.equals(button)) { |
||
| 455 | //if current button-receiver is the menu system module |
||
| 456 | if (curButtonReceiver.equals(name())) { |
||
| 457 | if (level >= 1) { |
||
| 458 | sendCommand(null, "<scroll>0</scroll>"); |
||
| 459 | } |
||
| 460 | } else { |
||
| 461 | sendMacbeth(curButtonReceiver, "<padUp state=\"UP\" level=\"" + level + "\" />"); |
||
| 462 | } |
||
| 463 | } |
||
| 464 | else if (padDown.equals(button)) { |
||
| 465 | //if current button-receiver is the menu system module |
||
| 466 | if (curButtonReceiver.equals(name())) { |
||
| 467 | if (level >= 1) { |
||
| 468 | sendCommand(null, "<scroll>0</scroll>"); |
||
| 469 | } |
||
| 470 | } else { |
||
| 471 | sendMacbeth(curButtonReceiver, "<padDown state=\"UP\" level=\"" + level + "\" />"); |
||
| 472 | } |
||
| 473 | } |
||
| 474 | else if (padOk.equals(button)) { |
||
| 475 | //if current button-receiver is the menu system module |
||
| 476 | if (curButtonReceiver.equals(name())) { |
||
| 477 | |||
| 478 | } else { |
||
| 479 | sendMacbeth(curButtonReceiver, "<padOk state=\"UP\" level=\"" + level + "\" />"); |
||
| 480 | } |
||
| 481 | } |
||
| 482 | else if (padLeft.equals(button)) { |
||
| 483 | //if current button-receiver is the menu system module |
||
| 484 | if (curButtonReceiver.equals(name())) { |
||
| 485 | |||
| 486 | } else { |
||
| 487 | sendMacbeth(curButtonReceiver, "<padLeft state=\"UP\" level=\"" + level + "\" />"); |
||
| 488 | } |
||
| 489 | } |
||
| 490 | else if (padRight.equals(button)) { |
||
| 491 | //if current button-receiver is the menu system module |
||
| 492 | if (curButtonReceiver.equals(name())) { |
||
| 493 | |||
| 494 | } else { |
||
| 495 | sendMacbeth(curButtonReceiver, "<padRight state=\"UP\" level=\"" + level + "\" />"); |
||
| 496 | } |
||
| 497 | } |
||
| 498 | |||
| 499 | } |
||
| 500 | } |
||
| 501 | |||
| 502 | |||
| 503 | /** |
||
| 504 | * Takes care of XML-data found in incoming macbeth-packets. |
||
| 505 | */ |
||
| 506 | private class PacketDataHandler implements XMLDataHandler { |
||
| 507 | public void XMLstartElement(String element, HashMap attributes) { |
||
| 508 | if (element.equals("packet")) { |
||
| 509 | if (currentPacket.getSource().getModule().equals(curSubMenu)) { |
||
| 510 | //data arrive from active submenu |
||
| 511 | sendData(null, currentPacket.getContents()); |
||
| 512 | |||
| 513 | } else { |
||
| 514 | //data arrives from submenu that is not active |
||
| 515 | //what happens then? |
||
| 516 | } |
||
| 517 | |||
| 518 | } else if (element.equals("deactivates") ) { |
||
| 519 | String module = currentPacket.getSource().getModule(); |
||
| 520 | if (curSubMenu.equals(module)) { |
||
| 521 | curSubMenu = name(); |
||
| 522 | sendRootMenu(null); |
||
| 523 | sendMacbeth(curSubMenu, "<deactivate />"); |
||
| 524 | } |
||
| 525 | if (curButtonReceiver.equals(module)) { |
||
| 526 | curButtonReceiver = name(); |
||
| 527 | sendMacbeth(curButtonReceiver, "<deactivate />"); |
||
| 528 | } |
||
| 529 | |||
| 530 | } else if (element.equals("request") ) { |
||
| 531 | //om en undermeny vill ha uppmärksamhet skickar den "request" |
||
| 532 | //vad är kraven på att en undermeny ska få visas på begäran? |
||
| 533 | //en timeout när vald meny inte skickat något? |
||
| 534 | //eller att en krävd visning kan klickas bort med cancel/back på fjärren |
||
| 535 | // och att man då återgår till den meny som visades innan |
||
| 536 | |||
| 537 | String module = currentPacket.getSource().getModule(); |
||
| 538 | if (!curSubMenu.equals(module)) { |
||
| 539 | //kontroller här? |
||
| 540 | curSubMenu = module; |
||
| 541 | sendMacbeth(curSubMenu, "<activate />"); |
||
| 542 | } |
||
| 543 | if (!curButtonReceiver.equals(module)) { |
||
| 544 | //kontroller här? |
||
| 545 | curButtonReceiver = module; |
||
| 546 | } |
||
| 547 | |||
| 548 | /* |
||
| 549 | * a submenu should be able to register itself to the menu system |
||
| 550 | * it provides a name and description to display, but also a true/false value |
||
| 551 | * indicating if the submenu should be displayed in the root_menu list at all |
||
| 552 | */ |
||
| 553 | } else if (element.equals("registersubmod") && attributes.containsKey("displayname") && attributes.containsKey("visible") && attributes.containsKey("displaydesc")) { |
||
| 554 | String displayname = (String)attributes.get("displayname"); |
||
| 555 | String displaydesc = (String)attributes.get("displaydesc"); |
||
| 556 | _debug.println(displayname + " registrerar sig"); |
||
| 557 | //_debug.println(displaydesc); |
||
| 558 | String module = currentPacket.getSource().getModule(); |
||
| 559 | boolean visible = false; |
||
| 560 | if (attributes.get("visible").toString().equals("true")) { |
||
| 561 | visible = true; |
||
| 562 | } |
||
| 563 | |||
| 564 | //has this module been reged before? |
||
| 565 | boolean exists = false; |
||
| 566 | for (int i = 0; i < subMenus.size(); i++) { |
||
| 567 | if (((SubMenu)subMenus.get(i)).getModuleName().equals(module)) { |
||
| 568 | exists = true; |
||
| 569 | break; |
||
| 570 | } |
||
| 571 | } |
||
| 572 | if (!exists) { |
||
| 573 | //so create a new submenu object |
||
| 574 | SubMenu sm = new SubMenu(module, displayname, displaydesc, visible); |
||
| 575 | subMenus.add(sm); |
||
| 576 | //refresh flinsh-client menu (if it is root menu) |
||
| 577 | if (curSubMenu.equals(name())) { |
||
| 578 | sendRootMenu(null); |
||
| 579 | } |
||
| 580 | } |
||
| 581 | |||
| 582 | //en submeny ska kunna avregistrera sig också, om den avslutas |
||
| 583 | } else if (element.equals("unregistersubmod") ) { |
||
| 584 | String module = currentPacket.getSource().getModule(); |
||
| 585 | |||
| 586 | //has this module been registered? |
||
| 587 | for (int i = 0; i < subMenus.size(); i++) { |
||
| 588 | if (((SubMenu)subMenus.get(i)).getModuleName().equals(module)) { |
||
| 589 | subMenus.remove(i); |
||
| 590 | |||
| 591 | // TODO: avskaffa parseint på data som kommer utifrån |
||
| 592 | if (Integer.parseInt(rootMenuMiddleId) >= subMenus.size() & Integer.parseInt(rootMenuMiddleId) > 0) { |
||
| 593 | rootMenuMiddleId = "" + (Integer.parseInt(rootMenuMiddleId) - 1); |
||
| 594 | } |
||
| 595 | |||
| 596 | if (curSubMenu.equals(module)) { |
||
| 597 | curSubMenu = name(); |
||
| 598 | //refresha klientens meny (om den är root) |
||
| 599 | sendRootMenu(null); |
||
| 600 | } |
||
| 601 | if (curButtonReceiver.equals(module)) { |
||
| 602 | curButtonReceiver = name(); |
||
| 603 | } |
||
| 604 | |||
| 605 | break; |
||
| 606 | } |
||
| 607 | } |
||
| 608 | } |
||
| 609 | |||
| 610 | /* Ex: <remotecontrol button="NUMERIC4" state="DOWN" /> |
||
| 611 | * This is a notification from the remote control module |
||
| 612 | * about one of our requested remote control buttons have |
||
| 613 | * been pressed. */ |
||
| 614 | else if (element.equals("remotecontrol") && attributes.containsKey("button") && attributes.containsKey("state")) { |
||
| 615 | String state = (String)attributes.get("state"); |
||
| 616 | String button = (String)attributes.get("button"); |
||
| 617 | parseKeys(button, state, 3); |
||
| 618 | } |
||
| 619 | |||
| 620 | } |
||
| 621 | public void XMLendElement(String element) {} |
||
| 622 | public void XMLelementData(String data) {} |
||
| 623 | public void XMLdocumentStart() {} |
||
| 624 | public void XMLdocumentEnd() {} |
||
| 625 | } |
||
| 626 | |||
| 627 | /** |
||
| 628 | * Takes care of XML-data found in incoming flinsh-packets. |
||
| 629 | */ |
||
| 630 | private class FlinshDataHandler implements XMLDataHandler { |
||
| 631 | public void XMLstartElement(String element, HashMap attributes) { |
||
| 632 | if (element.equals("flinshpacket") && attributes.containsKey("button") && attributes.containsKey("state")) { |
||
| 633 | String button = (String)attributes.get("button"); |
||
| 634 | String state = (String)attributes.get("state"); |
||
| 635 | String newButton = ""; |
||
| 636 | |||
| 637 | if (button.equals("padUp")) { |
||
| 638 | newButton = padUp; |
||
| 639 | } else if (button.equals("padDown")) { |
||
| 640 | newButton = padDown; |
||
| 641 | } else if (button.equals("padLeft")) { |
||
| 642 | newButton = padLeft; |
||
| 643 | } else if (button.equals("padRight")) { |
||
| 644 | newButton = padRight; |
||
| 645 | } else if (button.equals("padOk")) { |
||
| 646 | newButton = padOk; |
||
| 647 | } |
||
| 648 | |||
| 649 | if (!newButton.equals("") && (state.equals("UP") || state.equals("DOWN"))) { |
||
| 650 | parseKeys(newButton, state, currentLevel); |
||
| 651 | } |
||
| 652 | } |
||
| 653 | else if (element.equals("flinshpacket") && attributes.containsKey("menuid") && attributes.containsKey("middleid")) { |
||
| 654 | String id = (String)attributes.get("middleid"); |
||
| 655 | String menuid = (String)attributes.get("menuid"); |
||
| 656 | //int flinshMiddleItem = Integer.parseInt(id); |
||
| 657 | |||
| 658 | //om root: |
||
| 659 | if (curButtonReceiver.equals(name())) { |
||
| 660 | if (currentLevel >= 2) { |
||
| 661 | rootMenuMiddleId = id; |
||
| 662 | } |
||
| 663 | } else { |
||
| 664 | sendMacbeth(curSubMenu, "<middleid value=\"" + id + "\" menuid=\"" + menuid + "\" userlevel=\"" + currentLevel + "\" />"); |
||
| 665 | } |
||
| 666 | //_debug.println("data parsad, id: " + menuid + " middleitem: " + id); |
||
| 667 | } |
||
| 668 | else if (element.equals("flinshpacket") && attributes.containsKey("login") && attributes.containsKey("pass")) { |
||
| 669 | String user = (String)attributes.get("login"); |
||
| 670 | String pass = (String)attributes.get("pass"); |
||
| 671 | login(currentAddress, user, pass); |
||
| 672 | |||
| 673 | } |
||
| 674 | |||
| 675 | } |
||
| 676 | public void XMLendElement(String element) {} |
||
| 677 | public void XMLelementData(String data) {} |
||
| 678 | public void XMLdocumentStart() {} |
||
| 679 | public void XMLdocumentEnd() {} |
||
| 680 | } |
||
| 681 | |||
| 682 | /** |
||
| 683 | * |
||
| 684 | * @param address |
||
| 685 | * @param user |
||
| 686 | * @param pass |
||
| 687 | */ |
||
| 688 | private void login(String address, String user, String pass) { |
||
| 689 | //ip är inte ett giltigt användarnamn |
||
| 690 | //eftersom ip används för att få autologin för ipadresser |
||
| 691 | if (!user.equals("ip")) { |
||
| 692 | int level = 0; |
||
| 693 | //rota igenom listan över de möjliga logins som finns |
||
| 694 | for (int i=0; i<userLogin.size(); i++) { |
||
| 695 | String username = ((UserLoginObj)userLogin.get(i)).user; |
||
| 696 | String userLoginIp = ((UserLoginObj)userLogin.get(i)).password; |
||
| 697 | if (username.equals(user) && userLoginIp.equals(pass)) { |
||
| 698 | level = ((UserLoginObj)userLogin.get(i)).level; |
||
| 699 | //rota igenom alla inloggade klienter |
||
| 700 | for (int j=0; j<clientsConnected.size(); j++) { |
||
| 701 | String adr = ((ClientObj)clientsConnected.get(j)).address; |
||
| 702 | if (adr.equals(address)) { |
||
| 703 | int oldlevel = ((ClientObj)clientsConnected.get(j)).level; |
||
| 704 | if (oldlevel < level) { |
||
| 705 | _debug.println("client logged in with new level: " + level); |
||
| 706 | ((ClientObj)clientsConnected.get(j)).level = level; |
||
| 707 | if (oldlevel == 0 && !guestCanView) { |
||
| 708 | //skicka meny till klienten |
||
| 709 | if (curSubMenu.equals(name())) { |
||
| 710 | sendRootMenu(address); |
||
| 711 | } else { |
||
| 712 | sendMacbeth(curSubMenu, "<refresh />"); |
||
| 713 | } |
||
| 714 | } |
||
| 715 | } |
||
| 716 | break; |
||
| 717 | } |
||
| 718 | } |
||
| 719 | break; |
||
| 720 | } |
||
| 721 | } |
||
| 722 | } |
||
| 723 | } |
||
| 724 | /*private class TimerListener implements ActionListener { |
||
| 725 | |||
| 726 | public void actionPerformed(ActionEvent e) { |
||
| 727 | _debug.println("timer ping"); |
||
| 728 | //först skicka testdata här bara |
||
| 729 | //börja med <scrollup /> |
||
| 730 | testserver.sendToAll("<?xml version=\"1.0\"?><contentdata><middleitem>0</middleitem><contentname>MainMenu</contentname><list><item><title>08:00 Clifford, den lilla röda valpen</title><description>Tecknad serie. Del 13 av 17.</description></item><item><title>08:35 Lantmusen och stadsmusen</title><description>Animerad serie. Mössen Alexander och Emily reser jorden runt. Del 9 av 13.</description></item><item><title>15:00 Perkele</title><description>Test bla bla</description></item></list></contentdata>" + EOF); |
||
| 731 | |||
| 732 | //koppla upp sig mot http://www.arune.se/tv/tv_rss_now.php?id0=21&id1=22&id2=26&id3=27&id4=10&id5=42&id6=14&id7=89 |
||
| 733 | //forma om den xml till det format flinsh vill ha skiten |
||
| 734 | //skicka till flinsh |
||
| 735 | } |
||
| 736 | }*/ |
||
| 737 | |||
| 738 | /** |
||
| 739 | * Objekt som håller reda på vilka möjliga inloggningar klienten kan göra |
||
| 740 | */ |
||
| 741 | private class UserLoginObj { |
||
| 742 | public String user; |
||
| 743 | public String password; |
||
| 744 | public int level; |
||
| 745 | /** |
||
| 746 | * Creates a new instance of UserLoginObj. |
||
| 747 | */ |
||
| 748 | public UserLoginObj(String user, String password, int level) { |
||
| 749 | this.user = user; |
||
| 750 | this.password = password; |
||
| 751 | this.level = level; |
||
| 752 | } |
||
| 753 | } |
||
| 754 | |||
| 755 | /** |
||
| 756 | * Objekt som håller reda på alla inloggade klienter |
||
| 757 | * @author arune |
||
| 758 | */ |
||
| 759 | private class ClientObj { |
||
| 760 | public String address; |
||
| 761 | public int level; |
||
| 762 | /** |
||
| 763 | * Creates a new instance of ClientObj. |
||
| 764 | */ |
||
| 765 | public ClientObj(String address, int level) { |
||
| 766 | this.address = address; |
||
| 767 | this.level = level; |
||
| 768 | } |
||
| 769 | } |
||
| 770 | } |