/v3.2/nimbits-tds/src/com/nimbits/client/panels/PointGridPanel.java
Java | 567 lines | 416 code | 128 blank | 23 comment | 18 complexity | d4b720d2e92dbb2674de9453fa89e9de MD5 | raw file
1/* 2 * Copyright (c) 2010 Tonic Solutions LLC. 3 * 4 * http://www.nimbits.com 5 * 6 * 7 * Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 8 * 9 * http://www.gnu.org/licenses/gpl.html 10 * 11 * Unless required by applicable law or agreed to in writing, software distributed under the license is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 12 */ 13 14package com.nimbits.client.panels; 15 16import com.extjs.gxt.ui.client.Style; 17import com.extjs.gxt.ui.client.Style.HorizontalAlignment; 18import com.extjs.gxt.ui.client.data.ModelData; 19import com.extjs.gxt.ui.client.event.*; 20import com.extjs.gxt.ui.client.store.ListStore; 21import com.extjs.gxt.ui.client.widget.ContentPanel; 22import com.extjs.gxt.ui.client.widget.Info; 23import com.extjs.gxt.ui.client.widget.button.Button; 24import com.extjs.gxt.ui.client.widget.form.CheckBox; 25import com.extjs.gxt.ui.client.widget.form.DateField; 26import com.extjs.gxt.ui.client.widget.form.NumberField; 27import com.extjs.gxt.ui.client.widget.form.TextField; 28import com.extjs.gxt.ui.client.widget.grid.*; 29import com.extjs.gxt.ui.client.widget.layout.FillLayout; 30import com.extjs.gxt.ui.client.widget.layout.FitLayout; 31import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem; 32import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; 33import com.google.gwt.core.client.GWT; 34import com.google.gwt.i18n.client.DateTimeFormat; 35import com.google.gwt.i18n.client.NumberFormat; 36import com.google.gwt.user.client.Element; 37import com.google.gwt.user.client.Timer; 38import com.google.gwt.user.client.rpc.AsyncCallback; 39import com.google.gwt.user.client.ui.AbstractImagePrototype; 40import com.nimbits.client.exception.NimbitsException; 41import com.nimbits.client.icons.Icons; 42import com.nimbits.client.model.Const; 43import com.nimbits.client.model.GxtPointModel; 44import com.nimbits.client.model.point.Point; 45import com.nimbits.client.model.point.PointName; 46import com.nimbits.client.model.value.Value; 47import com.nimbits.client.model.value.ValueModelFactory; 48import com.nimbits.client.service.recordedvalues.RecordedValueService; 49import com.nimbits.client.service.recordedvalues.RecordedValueServiceAsync; 50 51import java.util.*; 52 53class PointGridPanel extends NavigationEventProvider { 54 55 56 private final ListStore<GxtPointModel> store = new ListStore<GxtPointModel>(); 57 private final EditorGrid<GxtPointModel> grid; 58 private final Map<PointName, Point> points = new HashMap<PointName, Point>(); 59 private final CheckBox saveToNowCheckBox = new CheckBox(); 60 private final CheckBox autoSaveCheckBox = new CheckBox(); 61 private final CheckBoxSelectionModel<GxtPointModel> sm = new CheckBoxSelectionModel<GxtPointModel>(); 62 private Timer updater; 63 private final static int valueColumnIndex = 4; 64 65 66 @Override 67 protected void onRender(final Element parent, final int index) { 68 super.onRender(parent, index); 69 70 setLayout(new FillLayout()); 71 getAriaSupport().setPresentation(true); 72 73 74 grid.addListener(Events.AfterEdit, new Listener<GridEvent>() { 75 76 @Override 77 public void handleEvent(final GridEvent be) { 78 updater.cancel(); 79 final GxtPointModel model = (GxtPointModel) be.getModel(); 80 if (!model.isReadOnly()) { 81 model.setDirty(true); 82 83 84 if (be.getColIndex() == valueColumnIndex && autoSaveCheckBox.getValue()) { //only save when the value is updated 85 86 final Point point = points.get(model.getName()); 87 final Date timestamp = saveToNowCheckBox.getValue() ? new Date() : (Date) model.get(Const.PARAM_TIMESTAMP); 88 final Double v = model.get(Const.PARAM_VALUE); 89 final String note = model.get(Const.PARAM_NOTE); 90 final Value value = ValueModelFactory.createValueModel(0.0, 0.0, v, timestamp, model.getId(), note); 91 92 GWT.log(value.getNote()); 93 GWT.log(String.valueOf(value.getValue())); 94 RecordedValueServiceAsync service = GWT.create(RecordedValueService.class); 95 try { 96 service.recordValue(point, value, new AsyncCallback<Value>() { 97 @Override 98 public void onFailure(final Throwable throwable) { 99 be.getRecord().reject(false); 100 } 101 102 @Override 103 public void onSuccess(final Value value) { 104 be.getRecord().commit(false); 105 model.setDirty(false); 106 notifyValueEnteredListener(point, value); 107 } 108 }); 109 } catch (NimbitsException e) { 110 GWT.log(e.getMessage(), e); 111 } 112 } 113 114 115 } 116 updater.scheduleRepeating(Const.DEFAULT_TIMER_UPDATE_SPEED); 117 updater.run(); 118 119 } 120 }); 121 122 final ContentPanel mainPanel = new ContentPanel(); 123 mainPanel.setTopComponent(gridToolBar()); 124 mainPanel.setHeaderVisible(false); 125 mainPanel.setBorders(false); 126 mainPanel.setBodyBorder(false); 127 mainPanel.setLayout(new FitLayout()); 128 mainPanel.setScrollMode(Style.Scroll.AUTO); 129 // grid.setHeight(400); 130 mainPanel.add(grid); 131 132 add(mainPanel); 133 134 135 } 136 137 public PointGridPanel() { 138 grid = new EditorGrid<GxtPointModel>(store, new ColumnModel(gridConfig())); 139 140 grid.setHeight("100%"); 141 grid.setBorders(true); 142 grid.setSelectionModel(sm); 143 grid.addPlugin(sm); 144 145 } 146 147 public List<Point> getSelectedPoints() { 148 final List<GxtPointModel> models = grid.getSelectionModel().getSelectedItems(); 149 final List<Point> retObj = new ArrayList<Point>(); 150 151 for (GxtPointModel model : models) { 152 retObj.add(points.get(model.getName())); 153 } 154 return retObj; 155 156 } 157 158 private List<ColumnConfig> gridConfig() { 159 final List<ColumnConfig> configs = new ArrayList<ColumnConfig>(); 160 sm.setSelectionMode(Style.SelectionMode.SIMPLE); 161 162 configs.add(sm.getColumn()); 163 addPropertyColumn(configs); 164 addAlertColumn(configs); 165 addPointNameColumn(configs); 166 addCurrentValueColumn(configs); 167 addNoteColumn(configs); 168 addTimestampColumn(configs); 169 170 return configs; 171 } 172 173 private void addTimestampColumn(final List<ColumnConfig> configs) { 174 final DateField dateField = new DateField(); 175 dateField.getPropertyEditor().setFormat( 176 DateTimeFormat.getFormat(Const.FORMAT_DATE_TIME)); 177 178 final ColumnConfig columnTime = new ColumnConfig(); 179 columnTime.setId(Const.PARAM_TIMESTAMP); 180 columnTime.setHeader(Const.WORD_TIMESTAMP); 181 columnTime.setAlignment(HorizontalAlignment.LEFT); 182 columnTime.setWidth(200); 183 columnTime.setDateTimeFormat(DateTimeFormat 184 .getFormat(Const.FORMAT_DATE_TIME)); 185 columnTime.setEditor(new CellEditor(dateField)); 186 // column.setDateTimeFormat(DateTimeFormat.getShortDateTimeFormat()); 187 configs.add(columnTime); 188 } 189 190 private void addNoteColumn(final List<ColumnConfig> configs) { 191 final ColumnConfig columnNote = new ColumnConfig(); 192 columnNote.setId(Const.PARAM_NOTE); 193 columnNote.setHeader(Const.WORD_ANNOTATION); 194 columnNote.setWidth(250); 195 196 final TextField<String> noteText = new TextField<String>(); 197 noteText.setAllowBlank(true); 198 columnNote.setEditor(new CellEditor(noteText)); 199 columnNote.setAlignment(HorizontalAlignment.LEFT); 200 configs.add(columnNote); 201 } 202 203 private void addCurrentValueColumn(final List<ColumnConfig> configs) { 204 final NumberField n = new NumberField(); 205 n.getPropertyEditor().setFormat(NumberFormat.getDecimalFormat()); 206 n.setSelectOnFocus(true); 207 n.setEditable(true); 208 209 final ColumnConfig columnValue = new ColumnConfig(); 210 columnValue.setId(Const.PARAM_VALUE); 211 columnValue.setHeader(Const.WORD_VALUE); 212 columnValue.setAlignment(HorizontalAlignment.CENTER); 213 columnValue.setWidth(50); 214 columnValue.setNumberFormat(NumberFormat.getDecimalFormat()); 215 CellEditor ce = new CellEditor(n); 216 columnValue.setEditor(ce); 217 218 configs.add(columnValue); 219 } 220 221 private void addPointNameColumn(final List<ColumnConfig> configs) { 222 final ColumnConfig nameColumn = new ColumnConfig(); 223 nameColumn.setId(Const.PARAM_NAME); 224 nameColumn.setHeader(Const.MESSAGE_DATA_POINT); 225 nameColumn.setAlignment(HorizontalAlignment.LEFT); 226 227 nameColumn.setWidth(250); 228 229 TextField<String> nameText = new TextField<String>(); 230 nameText.setAllowBlank(false); 231 nameText.setSelectOnFocus(true); 232 configs.add(nameColumn); 233 } 234 235 private void addPropertyColumn(final List<ColumnConfig> configs) { 236 final GridCellRenderer<GxtPointModel> propertyButtonRenderer = new GridCellRenderer<GxtPointModel>() { 237 238 239 public Object render(final GxtPointModel model, final String property, final ColumnData config, final int rowIndex, 240 final int colIndex, final ListStore<GxtPointModel> store, final Grid<GxtPointModel> grid) { 241 242 243 final Button b = new Button((String) model.get(property), new SelectionListener<ButtonEvent>() { 244 @Override 245 public void componentSelected(ButtonEvent ce) { 246 Point p = points.get(model.getName()); 247 // notifyPointClickedListener(p); 248 try { 249 createPointPropertyWindow(p); 250 } catch (NimbitsException e) { 251 GWT.log(e.getMessage()); 252 } 253 254 } 255 }); 256 257 b.setWidth(20); 258 b.setToolTip(Const.MESSAGE_CONFIGURE_POINT); 259 b.setEnabled(!model.isReadOnly()); 260 b.setBorders(false); 261 // b.setStyleName("gwt-button"); 262 b.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.edit())); 263 return b; 264 } 265 }; 266 267 268 final ColumnConfig propertyColumn = new ColumnConfig(); 269 propertyColumn.setId(Const.PARAM_PROPERTY); 270 propertyColumn.setHeader("edit"); 271 propertyColumn.setWidth(35); 272 propertyColumn.setAlignment(HorizontalAlignment.LEFT); 273 propertyColumn.setRenderer(propertyButtonRenderer); 274 configs.add(propertyColumn); 275 } 276 277 private void addAlertColumn(final List<ColumnConfig> configs) { 278 final GridCellRenderer<GxtPointModel> propertyButtonRenderer = new GridCellRenderer<GxtPointModel>() { 279 280 public Object render(final GxtPointModel model, final String property, final ColumnData config, final int rowIndex, 281 final int colIndex, final ListStore<GxtPointModel> store, final Grid<GxtPointModel> grid) { 282 283 final Button b = new Button((String) model.get(property), new SelectionListener<ButtonEvent>() { 284 @Override 285 public void componentSelected(final ButtonEvent ce) { 286 final Point p = points.get(model.getName()); 287 notifyPointClickedListener(p); 288 /// createPointPropertyWindow(p); 289 290 } 291 }); 292 293 b.setWidth(25); 294 b.setToolTip(Const.MESSAGE_CLICK_TO_TREND); 295 b.setEnabled(!model.isReadOnly()); 296 297 b.setBorders(false); 298 switch (model.getAlertState()) { 299 case IdleAlert: 300 b.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.point_idle())); 301 break; 302 case HighAlert: 303 b.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.point_high())); 304 break; 305 case LowAlert: 306 b.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.point_low())); 307 break; 308 default: 309 b.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.point_ok())); 310 311 } 312 313 return b; 314 } 315 }; 316 317 318 final ColumnConfig propertyColumn = new ColumnConfig(); 319 propertyColumn.setId(Const.PARAM_STATE); 320 propertyColumn.setHeader("state"); 321 propertyColumn.setWidth(35); 322 propertyColumn.setAlignment(HorizontalAlignment.LEFT); 323 propertyColumn.setRenderer(propertyButtonRenderer); 324 configs.add(propertyColumn); 325 } 326 327 328 @Override 329 protected void onAttach() { 330 updater = new Timer() { 331 @Override 332 public void run() { 333 try { 334 updateValues(); 335 } catch (NimbitsException e) { 336 GWT.log(e.getMessage(), e); 337 } 338 } 339 }; 340 updater.scheduleRepeating(Const.DEFAULT_TIMER_UPDATE_SPEED); 341 updater.run(); 342 super.onAttach(); 343 } 344 345 @Override 346 protected void onDetach() { 347 348 updater.cancel(); 349 350 // updater.cancel(); 351 super.onDetach(); 352 } 353 354 public void addPoint(final Point point) { 355 if (!points.containsKey(point.getName())) { 356 points.put(point.getName(), point); 357 store.add(new GxtPointModel(point)); 358 } 359 360 } 361 362 private void createPointPropertyWindow(final Point p) throws NimbitsException { 363 final com.extjs.gxt.ui.client.widget.Window window = new com.extjs.gxt.ui.client.widget.Window(); 364 final PointPanel pp = new PointPanel(p); 365 366 pp.addPointUpdatedListeners(new PointPanel.PointUpdatedListener() { 367 @Override 368 public void onPointUpdated(final Point p) { 369 370 points.remove(p.getName()); 371 points.put(p.getName(), p); 372 373 // mp.setTopComponent(mainToolBar( points)); 374 } 375 }); 376 377 pp.addPointDeletedListeners(new PointPanel.PointDeletedListener() { 378 @Override 379 public void onPointDeleted(Point p) { 380 points.remove(p.getName()); 381 382 383 } 384 }); 385 386 window.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.connect())); 387 window.setSize(466, 520); 388 window.setPlain(false); 389 window.setModal(true); 390 window.setBlinkModal(true); 391 window.setHeading(p.getName().getValue() + " Properties"); 392 window.setHeaderVisible(true); 393 window.setBodyBorder(true); 394// window.setLayout(new FitLayout()); 395 window.add(pp); 396 window.show(); 397 } 398 399 400 private void updateValues() throws NimbitsException { 401 store.commitChanges(); 402 final RecordedValueServiceAsync dataService = GWT.create(RecordedValueService.class); 403 if (!grid.isEditing()) { 404 for (final GxtPointModel gxtPointModel : store.getModels()) { 405 if (!gxtPointModel.isDirty()) { 406 final Point point = points.get(gxtPointModel.getName()); 407 408 dataService.getCurrentValue(point, 409 new AsyncCallback<Value>() { 410 411 @Override 412 public void onFailure(final Throwable caught) { 413 GWT.log(caught.getMessage(), caught); 414 } 415 416 @Override 417 public void onSuccess(final Value result) { 418 419 420 if (!(result == null)) { 421 422 gxtPointModel.set(Const.PARAM_VALUE, result.getValue()); 423 gxtPointModel.set(Const.PARAM_TIMESTAMP, result.getTimestamp()); 424 gxtPointModel.set(Const.PARAM_NOTE, result.getNote()); 425 gxtPointModel.setAlertState(result.getAlertState()); 426 store.update(gxtPointModel); 427 428 } else { 429 gxtPointModel.set(Const.PARAM_VALUE, 0); 430 431 gxtPointModel.set(Const.PARAM_TIMESTAMP, new Date()); 432 gxtPointModel.set(Const.PARAM_NOTE, ""); 433 store.update(gxtPointModel); 434 } 435 } 436 437 }); 438 439 } 440 441 442 } 443 } 444 445 } 446 447 private ToolBar gridToolBar() { 448 final ToolBar t = new ToolBar(); 449 450 final Button refresh = new Button(); 451 refresh.setText(""); 452 453 refresh.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.refresh2())); 454 refresh.addSelectionListener(new SelectionListener<ButtonEvent>() { 455 456 @Override 457 public void componentSelected(ButtonEvent ce) { 458 459 460 try { 461 updateValues(); 462 } catch (NimbitsException ignored) { 463 464 } 465 } 466 467 }); 468 469 470 final Button pause = new Button(); 471 pause.setText(""); 472 473 pause.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.Pause())); 474 pause.addSelectionListener(new SelectionListener<ButtonEvent>() { 475 476 @Override 477 public void componentSelected(ButtonEvent ce) { 478 479 updater.cancel(); 480 } 481 482 }); 483 Button play = new Button(); 484 play.setText(""); 485 486 play.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.Play())); 487 play.addSelectionListener(new SelectionListener<ButtonEvent>() { 488 489 @Override 490 public void componentSelected(ButtonEvent ce) { 491 492 updater.scheduleRepeating(Const.DEFAULT_TIMER_UPDATE_SPEED); 493 updater.run(); 494 } 495 }); 496 497 saveToNowCheckBox.setBoxLabel("Save with Current Time"); 498 saveToNowCheckBox.setValue(true); 499 500 autoSaveCheckBox.setBoxLabel("Auto-Save on new value entry"); 501 autoSaveCheckBox.setValue(true); 502 503 // t.add(save); 504 t.add(refresh); 505 506 t.add(pause); 507 t.add(play); 508 509 t.add(new SeparatorToolItem()); 510 511 t.add(saveToNowCheckBox); 512 t.add(autoSaveCheckBox); 513 514 return t; 515 516 } 517 518 public void removePoint(Point p) { 519 520 for (final ModelData m : store.getModels()) { 521 522 final GxtPointModel model = (GxtPointModel) m; 523 points.remove(((GxtPointModel) m).getName()); 524 if (model.getName().getValue().equals(p.getName().getValue())) { 525 store.remove(model); 526 break; 527 } 528 } 529 530 531 //To change body of created methods use File | Settings | File Templates. 532 } 533 534 535 public List<Point> saveSelectedPoints() throws NimbitsException { 536 final List<GxtPointModel> models = grid.getSelectionModel().getSelectedItems(); 537 final List<Point> retObj = new ArrayList<Point>(); 538 RecordedValueServiceAsync service = GWT.create(RecordedValueService.class); 539 for (final GxtPointModel model : models) { 540 if (model.isDirty()) { 541 542 final Date timestamp = saveToNowCheckBox.getValue() ? new Date() : (Date) model.get(Const.PARAM_TIMESTAMP); 543 final double v = model.get(Const.PARAM_VALUE) == null ? 0.0 : Double.valueOf(model.get(Const.PARAM_VALUE).toString()); 544 final String note = model.get(Const.PARAM_NOTE); 545 final Value value = ValueModelFactory.createValueModel(0.0, 0.0, v, timestamp, model.getId(), note); 546 service.recordValue(points.get(model.getName()), value, new AsyncCallback<Value>() { 547 @Override 548 public void onFailure(final Throwable throwable) { 549 Info.display("Error Saving", throwable.getMessage()); 550 } 551 552 @Override 553 public void onSuccess(final Value value) { 554 555 //be.getRecord().commit(false); 556 model.setDirty(false); 557 notifyValueEnteredListener(points.get(model.getName()), value); 558 } 559 }); 560 model.setDirty(false); 561 } 562 retObj.add(points.get(model.getName())); 563 } 564 return retObj; 565 566 } 567}