Skip to content

Commit

Permalink
For #118 #205 #382 - implemented dynamic visibility calculation based…
Browse files Browse the repository at this point in the history
… on the status of device, handle the 'forced' visibility and 'hidden' flags
  • Loading branch information
vitalidze committed Dec 10, 2015
1 parent ede3043 commit c039f94
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public class VisibilityController implements ContentController, DeviceVisibility

private static class DeviceState {
boolean visible;
boolean idle;
boolean offline;
boolean idle = true;
boolean offline = true;
Group group;
}

Expand Down Expand Up @@ -77,7 +77,7 @@ private DeviceState getState(Long deviceId) {
DeviceState state = deviceState.get(deviceId);
if (state == null) {
state = new DeviceState();
state.visible = calculateVisibility(deviceId);
state.visible = calculateVisibility(deviceId, state);
deviceState.put(deviceId, state);
}
return state;
Expand All @@ -94,22 +94,28 @@ private void loadedDeviceVisibility(DeviceVisibilityState deviceVisibility) {
if (deviceVisibility.getHiddenGroups() == null) {
deviceVisibility.setHiddenGroups(new HashSet<Long>());
}
for (Long deviceId : new HashSet<>(deviceState.keySet())) {
updateVisibility(deviceId);
}
updateVisibilityOfAllDevices();
}

@Override
public boolean isVisible(Device device) {
return getState(device).visible;
}

private boolean calculateVisibility(Long deviceId) {
DeviceState state = deviceState.get(deviceId);
return deviceVisibility != null
&& state != null
&& (deviceVisibility.getVisibleForced().contains(deviceId)
|| !deviceVisibility.getHiddenForced().contains(deviceId))
private boolean calculateVisibility(Long deviceId, DeviceState state) {
if (deviceVisibility == null) {
return false;
}

if (deviceVisibility.getVisibleForced().contains(deviceId)) {
return true;
}

if (deviceVisibility.getHiddenForced().contains(deviceId)) {
return false;
}

return state != null
&& (!state.idle || !deviceVisibility.getHideIdle())
&& (state.idle || !deviceVisibility.getHideMoving())
&& (!state.offline || !deviceVisibility.getHideOffline())
Expand All @@ -121,16 +127,20 @@ private boolean calculateVisibility(Long deviceId) {
public void setVisible(Device device, boolean b) {
(b ? deviceVisibility.getHiddenForced() : deviceVisibility.getVisibleForced()).remove(device.getId());
(b ? deviceVisibility.getVisibleForced() : deviceVisibility.getHiddenForced()).add(device.getId());
service.setValue(STATE_KEY_DEVICE_VISIBILITY,
AutoBeanCodex.encode(AutoBeanUtils.getAutoBean(deviceVisibility)).getPayload(),
new BaseAsyncCallback<Void>(i18n));
saveDeviceVisibility();
DeviceState state = getState(device);
if (state.visible != b) {
state.visible = b;
fireChange(device.getId(), b);
}
}

private void saveDeviceVisibility() {
service.setValue(STATE_KEY_DEVICE_VISIBILITY,
AutoBeanCodex.encode(AutoBeanUtils.getAutoBean(deviceVisibility)).getPayload(),
new BaseAsyncCallback<Void>(i18n));
}

@Override
public void addVisibilityChangeHandler(DeviceVisibilityChangeHandler visibilityChangeHandler) {
visibilityChangeHandlers.add(visibilityChangeHandler);
Expand Down Expand Up @@ -180,10 +190,94 @@ private void updateVisibility(Device device) {

private void updateVisibility(Long deviceId) {
DeviceState state = getState(deviceId);
boolean calculated = calculateVisibility(deviceId);
boolean calculated = calculateVisibility(deviceId, state);
if (state.visible != calculated) {
state.visible = calculated;
fireChange(deviceId, calculated);
}
}

private void updateVisibilityOfAllDevices() {
for (Long deviceId : deviceState.keySet()) {
updateVisibility(deviceId);
}
}

@Override
public boolean getHideOnline() {
return deviceVisibility.getHideOnline();
}

@Override
public void setHideOnline(boolean hideOnline) {
deviceVisibility.setHideOnline(hideOnline);
clearForcedVisibility();
saveDeviceVisibility();
updateVisibilityOfAllDevices();
}

@Override
public boolean getHideOffline() {
return deviceVisibility.getHideOffline();
}

@Override
public void setHideOffline(boolean hideOffline) {
deviceVisibility.setHideOffline(hideOffline);
clearForcedVisibility();
saveDeviceVisibility();
updateVisibilityOfAllDevices();
}

@Override
public boolean getHideIdle() {
return deviceVisibility.getHideIdle();
}

@Override
public void setHideIdle(boolean hideIdle) {
deviceVisibility.setHideIdle(hideIdle);
clearForcedVisibility();
saveDeviceVisibility();
updateVisibilityOfAllDevices();
}

@Override
public boolean getHideMoving() {
return deviceVisibility.getHideMoving();
}

@Override
public void setHideMoving(boolean hideMoving) {
deviceVisibility.setHideMoving(hideMoving);
clearForcedVisibility();
saveDeviceVisibility();
updateVisibilityOfAllDevices();
}

@Override
public boolean isHiddenGroup(Long groupId) {
return deviceVisibility.getHiddenGroups().contains(groupId);
}

@Override
public void addHiddenGroup(Long groupId) {
deviceVisibility.getHiddenGroups().add(groupId);
clearForcedVisibility();
saveDeviceVisibility();
updateVisibilityOfAllDevices();
}

@Override
public void removeHiddenGroup(Long groupId) {
deviceVisibility.getHiddenGroups().remove(groupId);
clearForcedVisibility();
saveDeviceVisibility();
updateVisibilityOfAllDevices();
}

private void clearForcedVisibility() {
deviceVisibility.getVisibleForced().clear();
deviceVisibility.getHiddenForced().clear();
}
}
2 changes: 2 additions & 0 deletions src/main/java/org/traccar/web/client/i18n/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -512,4 +512,6 @@ String defaultNotificationTemplate(@Select DeviceEventType type,
String group();

String noGroup();

String online();
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,20 @@ public interface DeviceVisibilityHandler extends DeviceVisibilityProvider {
void offlineStatusChanged(Device device, boolean offline);
void updated(Device device);
void addVisibilityChangeHandler(DeviceVisibilityChangeHandler visibilityChangeHandler);

boolean getHideOnline();
void setHideOnline(boolean hideOnline);

boolean getHideOffline();
void setHideOffline(boolean hideOffline);

boolean getHideIdle();
void setHideIdle(boolean hideIdle);

boolean getHideMoving();
void setHideMoving(boolean hideMoving);

boolean isHiddenGroup(Long groupId);
void addHiddenGroup(Long groupId);
void removeHiddenGroup(Long groupId);
}
103 changes: 102 additions & 1 deletion src/main/java/org/traccar/web/client/view/DeviceView.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.safehtml.shared.SafeHtml;
Expand Down Expand Up @@ -52,12 +53,17 @@
import com.sencha.gxt.widget.core.client.grid.*;
import com.sencha.gxt.widget.core.client.grid.editing.GridEditing;
import com.sencha.gxt.widget.core.client.grid.editing.GridInlineEditing;
import com.sencha.gxt.widget.core.client.menu.CheckMenuItem;
import com.sencha.gxt.widget.core.client.menu.Item;
import com.sencha.gxt.widget.core.client.menu.Menu;
import com.sencha.gxt.widget.core.client.menu.MenuItem;
import com.sencha.gxt.widget.core.client.toolbar.ToolBar;
import org.traccar.web.client.ApplicationContext;
import org.traccar.web.client.i18n.Messages;
import org.traccar.web.client.model.BaseStoreHandlers;
import org.traccar.web.client.model.DeviceProperties;
import org.traccar.web.client.model.GeoFenceProperties;
import org.traccar.web.client.state.DeviceVisibilityChangeHandler;
import org.traccar.web.client.state.DeviceVisibilityHandler;
import org.traccar.web.client.state.GridStateHandler;
import org.traccar.web.shared.model.Device;
Expand Down Expand Up @@ -219,6 +225,92 @@ void refreshView() {
}
}

private static class DeviceGridView extends GroupingView<Device> {
Messages i18n = GWT.create(Messages.class);

final DeviceVisibilityHandler deviceVisibilityHandler;
final ListStore<Group> groupStore;

private DeviceGridView(DeviceVisibilityHandler deviceVisibilityHandler, ListStore<Group> groupStore) {
this.deviceVisibilityHandler = deviceVisibilityHandler;
this.groupStore = groupStore;
}

@Override
protected Menu createContextMenu(int colIndex) {
Menu menu = super.createContextMenu(colIndex);
if (colIndex == 0) {
CheckMenuItem idle = new CheckMenuItem(capitalize(i18n.idle()));
idle.setChecked(!deviceVisibilityHandler.getHideIdle());
idle.addSelectionHandler(new SelectionHandler<Item>() {
@Override
public void onSelection(SelectionEvent<Item> event) {
deviceVisibilityHandler.setHideIdle(!deviceVisibilityHandler.getHideIdle());
}
});
menu.add(idle);

CheckMenuItem moving = new CheckMenuItem(capitalize(i18n.moving()));
moving.setChecked(!deviceVisibilityHandler.getHideMoving());
moving.addSelectionHandler(new SelectionHandler<Item>() {
@Override
public void onSelection(SelectionEvent<Item> event) {
deviceVisibilityHandler.setHideMoving(!deviceVisibilityHandler.getHideMoving());
}
});
menu.add(moving);

CheckMenuItem offline = new CheckMenuItem(capitalize(i18n.offline()));
offline.setChecked(!deviceVisibilityHandler.getHideOffline());
offline.addSelectionHandler(new SelectionHandler<Item>() {
@Override
public void onSelection(SelectionEvent<Item> event) {
deviceVisibilityHandler.setHideOffline(!deviceVisibilityHandler.getHideOffline());
}
});
menu.add(offline);

CheckMenuItem online = new CheckMenuItem(capitalize(i18n.online()));
online.setChecked(!deviceVisibilityHandler.getHideOnline());
online.addSelectionHandler(new SelectionHandler<Item>() {
@Override
public void onSelection(SelectionEvent<Item> event) {
deviceVisibilityHandler.setHideOnline(!deviceVisibilityHandler.getHideOnline());
}
});
menu.add(online);

if (groupStore.size() > 0) {
MenuItem groups = new MenuItem(i18n.groups());
groups.setSubMenu(new Menu());
for (final Group group : groupStore.getAll()) {
CheckMenuItem groupItem = new CheckMenuItem(group.getName());
groupItem.setChecked(!deviceVisibilityHandler.isHiddenGroup(group.getId()));
groupItem.addSelectionHandler(new SelectionHandler<Item>() {
@Override
public void onSelection(SelectionEvent<Item> event) {
if (deviceVisibilityHandler.isHiddenGroup(group.getId())) {
deviceVisibilityHandler.removeHiddenGroup(group.getId());
} else {
deviceVisibilityHandler.addHiddenGroup(group.getId());
}
}
});
groups.getSubMenu().add(groupItem);
}
menu.add(groups);
}
}
return menu;
}

private String capitalize(String s) {
return Character.isUpperCase(s.charAt(0))
? s
: (Character.toUpperCase(s.charAt(0)) + s.substring(1, s.length()));
}
}

private final DeviceHandler deviceHandler;

private final GeoFenceHandler geoFenceHandler;
Expand Down Expand Up @@ -357,6 +449,15 @@ public String getPath() {
colVisible.setToolTip(new SafeHtmlBuilder().appendEscaped(i18n.visible()).toSafeHtml());
columnConfigList.add(colVisible);

// handle visibility change events
deviceVisibilityHandler.addVisibilityChangeHandler(new DeviceVisibilityChangeHandler() {
@Override
public void visibilityChanged(Long deviceId, boolean visible) {
Device device = deviceStore.findModelWithKey(deviceId.toString());
deviceStore.update(device);
}
});

// Name column
ColumnConfig<Device, String> colName = new ColumnConfig<>(deviceProperties.name(), 0, i18n.name());
colName.setCell(new AbstractCell<String>(BrowserEvents.MOUSEOVER, BrowserEvents.MOUSEOUT) {
Expand Down Expand Up @@ -449,7 +550,7 @@ public String getValue(Device device) {
colGroup.setHidden(true);
columnConfigList.add(colGroup);

view = new GroupingView<>();
view = new DeviceGridView(deviceVisibilityHandler, groupStore);
view.setStripeRows(true);
view.setShowGroupedColumn(false);
view.setEnableNoGroups(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ second = s
ago = {0} ago
meter = m
offline = offline
online = online
idle = Idle
since = since {0}
protocol = Protocol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ second = сек
ago = {0} назад
meter = м
offline = не в сети
online = онлайн
idle = Стоит
since = с {0}
protocol = Протокол
Expand Down

0 comments on commit c039f94

Please sign in to comment.